assembler-aarch32.cc revision c0ee83fd133e93d3967d8347ad2bf2a218524348
1// Copyright 2015, VIXL authors
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7//   * Redistributions of source code must retain the above copyright notice,
8//     this list of conditions and the following disclaimer.
9//   * Redistributions in binary form must reproduce the above copyright notice,
10//     this list of conditions and the following disclaimer in the documentation
11//     and/or other materials provided with the distribution.
12//   * Neither the name of ARM Limited nor the names of its contributors may be
13//     used to endorse or promote products derived from this software without
14//     specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27extern "C" {
28#include <stdint.h>
29}
30
31#include <cassert>
32#include <cstdio>
33#include <cstdlib>
34#include <cstring>
35#include <iostream>
36
37#include "utils-vixl.h"
38#include "aarch32/constants-aarch32.h"
39#include "aarch32/instructions-aarch32.h"
40#include "aarch32/operand-aarch32.h"
41#include "aarch32/assembler-aarch32.h"
42
43namespace vixl {
44namespace aarch32 {
45
46void Assembler::EmitT32_16(uint16_t instr) {
47  VIXL_ASSERT(buffer_.Is16bitAligned());
48  buffer_.Emit16(instr);
49}
50
51
52void 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
59void Assembler::EmitA32(uint32_t instr) {
60  VIXL_ASSERT(buffer_.Is32bitAligned());
61  buffer_.Emit32(instr);
62}
63
64
65#ifdef VIXL_DEBUG
66void Assembler::PerformCheckIT(Condition condition) {
67  if (it_mask_ == 0) {
68    VIXL_ASSERT(IsUsingA32() || condition.Is(al));
69  } else {
70    VIXL_ASSERT(condition.Is(first_condition_));
71    first_condition_ =
72        Condition((first_condition_.GetCondition() & 0xe) | (it_mask_ >> 3));
73    // For A32, AdavanceIT() is not called by the assembler. We must call it
74    // in order to check that IT instructions are used consistently with
75    // the following conditional instructions.
76    if (IsUsingA32()) AdvanceIT();
77  }
78}
79#endif
80
81
82void Assembler::BindHelper(Label* label) {
83  VIXL_ASSERT(!label->IsBound());
84  label->Bind(GetCursorOffset(), IsUsingT32());
85
86  for (Label::ForwardRefList::iterator ref = label->GetFirstForwardRef();
87       ref != label->GetEndForwardRef();
88       ref++) {
89    EncodeLabelFor(*ref, label);
90  }
91  if (label->IsInVeneerPool()) {
92    label->GetVeneerPoolManager()->RemoveLabel(label);
93  }
94}
95
96
97uint32_t Assembler::Link(uint32_t instr,
98                         Label* label,
99                         const Label::LabelEmitOperator& op) {
100  if (label->IsBound()) {
101    return op.Encode(instr,
102                     GetCursorOffset() + GetArchitectureStatePCOffset(),
103                     label);
104  }
105  label->AddForwardRef(GetCursorOffset(), IsUsingT32(), op);
106  return instr;
107}
108
109
110void Assembler::EncodeLabelFor(const Label::ForwardReference& forward,
111                               Label* label) {
112  const uint32_t location = forward.GetLocation();
113  const uint32_t from = location + forward.GetStatePCOffset();
114  const Label::LabelEmitOperator& encoder = forward.GetEmitOperator();
115  if (forward.IsUsingT32()) {
116    uint16_t* instr_ptr = buffer_.GetOffsetAddress<uint16_t*>(location);
117    if (Is16BitEncoding(instr_ptr[0])) {
118      // The Encode methods always deals with uint32_t types so we need
119      // to explicitely cast it.
120      uint32_t instr = static_cast<uint32_t>(instr_ptr[0]);
121      instr = encoder.Encode(instr, from, label);
122      // The Encode method should not ever set the top 16 bits.
123      VIXL_ASSERT((instr & ~0xffff) == 0);
124      instr_ptr[0] = static_cast<uint16_t>(instr);
125    } else {
126      uint32_t instr =
127          instr_ptr[1] | (static_cast<uint32_t>(instr_ptr[0]) << 16);
128      instr = encoder.Encode(instr, from, label);
129      instr_ptr[0] = static_cast<uint16_t>(instr >> 16);
130      instr_ptr[1] = static_cast<uint16_t>(instr);
131    }
132  } else {
133    uint32_t* instr_ptr = buffer_.GetOffsetAddress<uint32_t*>(location);
134    instr_ptr[0] = encoder.Encode(instr_ptr[0], from, label);
135  }
136}
137
138
139// Start of generated code.
140class Dt_L_imm6_1 : public EncodingValue {
141  uint32_t type_;
142
143 public:
144  explicit Dt_L_imm6_1(DataType dt);
145  uint32_t GetTypeEncodingValue() const { return type_; }
146};
147
148Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) {
149  switch (dt.GetValue()) {
150    case S8:
151      type_ = 0x0;
152      SetEncodingValue(0x1);
153      break;
154    case U8:
155      type_ = 0x1;
156      SetEncodingValue(0x1);
157      break;
158    case S16:
159      type_ = 0x0;
160      SetEncodingValue(0x2);
161      break;
162    case U16:
163      type_ = 0x1;
164      SetEncodingValue(0x2);
165      break;
166    case S32:
167      type_ = 0x0;
168      SetEncodingValue(0x4);
169      break;
170    case U32:
171      type_ = 0x1;
172      SetEncodingValue(0x4);
173      break;
174    case S64:
175      type_ = 0x0;
176      SetEncodingValue(0x8);
177      break;
178    case U64:
179      type_ = 0x1;
180      SetEncodingValue(0x8);
181      break;
182    default:
183      VIXL_UNREACHABLE();
184      type_ = 0x0;
185      break;
186  }
187}
188
189class Dt_L_imm6_2 : public EncodingValue {
190  uint32_t type_;
191
192 public:
193  explicit Dt_L_imm6_2(DataType dt);
194  uint32_t GetTypeEncodingValue() const { return type_; }
195};
196
197Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) {
198  switch (dt.GetValue()) {
199    case S8:
200      type_ = 0x1;
201      SetEncodingValue(0x1);
202      break;
203    case S16:
204      type_ = 0x1;
205      SetEncodingValue(0x2);
206      break;
207    case S32:
208      type_ = 0x1;
209      SetEncodingValue(0x4);
210      break;
211    case S64:
212      type_ = 0x1;
213      SetEncodingValue(0x8);
214      break;
215    default:
216      VIXL_UNREACHABLE();
217      type_ = 0x0;
218      break;
219  }
220}
221
222class Dt_L_imm6_3 : public EncodingValue {
223 public:
224  explicit Dt_L_imm6_3(DataType dt);
225};
226
227Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) {
228  switch (dt.GetValue()) {
229    case I8:
230      SetEncodingValue(0x1);
231      break;
232    case I16:
233      SetEncodingValue(0x2);
234      break;
235    case I32:
236      SetEncodingValue(0x4);
237      break;
238    case I64:
239      SetEncodingValue(0x8);
240      break;
241    default:
242      break;
243  }
244}
245
246class Dt_L_imm6_4 : public EncodingValue {
247 public:
248  explicit Dt_L_imm6_4(DataType dt);
249};
250
251Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) {
252  switch (dt.GetValue()) {
253    case Untyped8:
254      SetEncodingValue(0x1);
255      break;
256    case Untyped16:
257      SetEncodingValue(0x2);
258      break;
259    case Untyped32:
260      SetEncodingValue(0x4);
261      break;
262    case Untyped64:
263      SetEncodingValue(0x8);
264      break;
265    default:
266      break;
267  }
268}
269
270class Dt_imm6_1 : public EncodingValue {
271  uint32_t type_;
272
273 public:
274  explicit Dt_imm6_1(DataType dt);
275  uint32_t GetTypeEncodingValue() const { return type_; }
276};
277
278Dt_imm6_1::Dt_imm6_1(DataType dt) {
279  switch (dt.GetValue()) {
280    case S16:
281      type_ = 0x0;
282      SetEncodingValue(0x1);
283      break;
284    case U16:
285      type_ = 0x1;
286      SetEncodingValue(0x1);
287      break;
288    case S32:
289      type_ = 0x0;
290      SetEncodingValue(0x2);
291      break;
292    case U32:
293      type_ = 0x1;
294      SetEncodingValue(0x2);
295      break;
296    case S64:
297      type_ = 0x0;
298      SetEncodingValue(0x4);
299      break;
300    case U64:
301      type_ = 0x1;
302      SetEncodingValue(0x4);
303      break;
304    default:
305      VIXL_UNREACHABLE();
306      type_ = 0x0;
307      break;
308  }
309}
310
311class Dt_imm6_2 : public EncodingValue {
312  uint32_t type_;
313
314 public:
315  explicit Dt_imm6_2(DataType dt);
316  uint32_t GetTypeEncodingValue() const { return type_; }
317};
318
319Dt_imm6_2::Dt_imm6_2(DataType dt) {
320  switch (dt.GetValue()) {
321    case S16:
322      type_ = 0x1;
323      SetEncodingValue(0x1);
324      break;
325    case S32:
326      type_ = 0x1;
327      SetEncodingValue(0x2);
328      break;
329    case S64:
330      type_ = 0x1;
331      SetEncodingValue(0x4);
332      break;
333    default:
334      VIXL_UNREACHABLE();
335      type_ = 0x0;
336      break;
337  }
338}
339
340class Dt_imm6_3 : public EncodingValue {
341 public:
342  explicit Dt_imm6_3(DataType dt);
343};
344
345Dt_imm6_3::Dt_imm6_3(DataType dt) {
346  switch (dt.GetValue()) {
347    case I16:
348      SetEncodingValue(0x1);
349      break;
350    case I32:
351      SetEncodingValue(0x2);
352      break;
353    case I64:
354      SetEncodingValue(0x4);
355      break;
356    default:
357      break;
358  }
359}
360
361class Dt_imm6_4 : public EncodingValue {
362  uint32_t type_;
363
364 public:
365  explicit Dt_imm6_4(DataType dt);
366  uint32_t GetTypeEncodingValue() const { return type_; }
367};
368
369Dt_imm6_4::Dt_imm6_4(DataType dt) {
370  switch (dt.GetValue()) {
371    case S8:
372      type_ = 0x0;
373      SetEncodingValue(0x1);
374      break;
375    case U8:
376      type_ = 0x1;
377      SetEncodingValue(0x1);
378      break;
379    case S16:
380      type_ = 0x0;
381      SetEncodingValue(0x2);
382      break;
383    case U16:
384      type_ = 0x1;
385      SetEncodingValue(0x2);
386      break;
387    case S32:
388      type_ = 0x0;
389      SetEncodingValue(0x4);
390      break;
391    case U32:
392      type_ = 0x1;
393      SetEncodingValue(0x4);
394      break;
395    default:
396      VIXL_UNREACHABLE();
397      type_ = 0x0;
398      break;
399  }
400}
401
402class Dt_op_U_size_1 : public EncodingValue {
403 public:
404  explicit Dt_op_U_size_1(DataType dt);
405};
406
407Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) {
408  switch (dt.GetValue()) {
409    case S8:
410      SetEncodingValue(0x0);
411      break;
412    case S16:
413      SetEncodingValue(0x1);
414      break;
415    case S32:
416      SetEncodingValue(0x2);
417      break;
418    case U8:
419      SetEncodingValue(0x4);
420      break;
421    case U16:
422      SetEncodingValue(0x5);
423      break;
424    case U32:
425      SetEncodingValue(0x6);
426      break;
427    case P8:
428      SetEncodingValue(0x8);
429      break;
430    case P64:
431      SetEncodingValue(0xa);
432      break;
433    default:
434      break;
435  }
436}
437
438class Dt_op_size_1 : public EncodingValue {
439 public:
440  explicit Dt_op_size_1(DataType dt);
441};
442
443Dt_op_size_1::Dt_op_size_1(DataType dt) {
444  switch (dt.GetValue()) {
445    case I8:
446      SetEncodingValue(0x0);
447      break;
448    case I16:
449      SetEncodingValue(0x1);
450      break;
451    case I32:
452      SetEncodingValue(0x2);
453      break;
454    case P8:
455      SetEncodingValue(0x4);
456      break;
457    default:
458      break;
459  }
460}
461
462class Dt_op_size_2 : public EncodingValue {
463 public:
464  explicit Dt_op_size_2(DataType dt);
465};
466
467Dt_op_size_2::Dt_op_size_2(DataType dt) {
468  switch (dt.GetValue()) {
469    case S8:
470      SetEncodingValue(0x0);
471      break;
472    case S16:
473      SetEncodingValue(0x1);
474      break;
475    case S32:
476      SetEncodingValue(0x2);
477      break;
478    case U8:
479      SetEncodingValue(0x4);
480      break;
481    case U16:
482      SetEncodingValue(0x5);
483      break;
484    case U32:
485      SetEncodingValue(0x6);
486      break;
487    default:
488      break;
489  }
490}
491
492class Dt_op_size_3 : public EncodingValue {
493 public:
494  explicit Dt_op_size_3(DataType dt);
495};
496
497Dt_op_size_3::Dt_op_size_3(DataType dt) {
498  switch (dt.GetValue()) {
499    case S16:
500      SetEncodingValue(0x0);
501      break;
502    case S32:
503      SetEncodingValue(0x1);
504      break;
505    case S64:
506      SetEncodingValue(0x2);
507      break;
508    case U16:
509      SetEncodingValue(0x4);
510      break;
511    case U32:
512      SetEncodingValue(0x5);
513      break;
514    case U64:
515      SetEncodingValue(0x6);
516      break;
517    default:
518      break;
519  }
520}
521
522class Dt_U_imm3H_1 : public EncodingValue {
523 public:
524  explicit Dt_U_imm3H_1(DataType dt);
525};
526
527Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) {
528  switch (dt.GetValue()) {
529    case S8:
530      SetEncodingValue(0x1);
531      break;
532    case S16:
533      SetEncodingValue(0x2);
534      break;
535    case S32:
536      SetEncodingValue(0x4);
537      break;
538    case U8:
539      SetEncodingValue(0x9);
540      break;
541    case U16:
542      SetEncodingValue(0xa);
543      break;
544    case U32:
545      SetEncodingValue(0xc);
546      break;
547    default:
548      break;
549  }
550}
551
552class Dt_U_opc1_opc2_1 : public EncodingValue {
553 public:
554  explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
555};
556
557Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
558  switch (dt.GetValue()) {
559    case S8:
560      if ((lane.GetLane() & 7) != lane.GetLane()) {
561        return;
562      }
563      SetEncodingValue(0x8 | lane.GetLane());
564      break;
565    case S16:
566      if ((lane.GetLane() & 3) != lane.GetLane()) {
567        return;
568      }
569      SetEncodingValue(0x1 | (lane.GetLane() << 1));
570      break;
571    case U8:
572      if ((lane.GetLane() & 7) != lane.GetLane()) {
573        return;
574      }
575      SetEncodingValue(0x18 | lane.GetLane());
576      break;
577    case U16:
578      if ((lane.GetLane() & 3) != lane.GetLane()) {
579        return;
580      }
581      SetEncodingValue(0x11 | (lane.GetLane() << 1));
582      break;
583    case Untyped32:
584      if ((lane.GetLane() & 1) != lane.GetLane()) {
585        return;
586      }
587      SetEncodingValue(0x0 | (lane.GetLane() << 2));
588      break;
589    case kDataTypeValueNone:
590      if ((lane.GetLane() & 1) != lane.GetLane()) {
591        return;
592      }
593      SetEncodingValue(0x0 | (lane.GetLane() << 2));
594      break;
595    default:
596      break;
597  }
598}
599
600class Dt_opc1_opc2_1 : public EncodingValue {
601 public:
602  explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
603};
604
605Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
606  switch (dt.GetValue()) {
607    case Untyped8:
608      if ((lane.GetLane() & 7) != lane.GetLane()) {
609        return;
610      }
611      SetEncodingValue(0x8 | lane.GetLane());
612      break;
613    case Untyped16:
614      if ((lane.GetLane() & 3) != lane.GetLane()) {
615        return;
616      }
617      SetEncodingValue(0x1 | (lane.GetLane() << 1));
618      break;
619    case Untyped32:
620      if ((lane.GetLane() & 1) != lane.GetLane()) {
621        return;
622      }
623      SetEncodingValue(0x0 | (lane.GetLane() << 2));
624      break;
625    case kDataTypeValueNone:
626      if ((lane.GetLane() & 1) != lane.GetLane()) {
627        return;
628      }
629      SetEncodingValue(0x0 | (lane.GetLane() << 2));
630      break;
631    default:
632      break;
633  }
634}
635
636class Dt_imm4_1 : public EncodingValue {
637 public:
638  explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane);
639};
640
641Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) {
642  switch (dt.GetValue()) {
643    case Untyped8:
644      if ((lane.GetLane() & 7) != lane.GetLane()) {
645        return;
646      }
647      SetEncodingValue(0x1 | (lane.GetLane() << 1));
648      break;
649    case Untyped16:
650      if ((lane.GetLane() & 3) != lane.GetLane()) {
651        return;
652      }
653      SetEncodingValue(0x2 | (lane.GetLane() << 2));
654      break;
655    case Untyped32:
656      if ((lane.GetLane() & 1) != lane.GetLane()) {
657        return;
658      }
659      SetEncodingValue(0x4 | (lane.GetLane() << 3));
660      break;
661    default:
662      break;
663  }
664}
665
666class Dt_B_E_1 : public EncodingValue {
667 public:
668  explicit Dt_B_E_1(DataType dt);
669};
670
671Dt_B_E_1::Dt_B_E_1(DataType dt) {
672  switch (dt.GetValue()) {
673    case Untyped8:
674      SetEncodingValue(0x2);
675      break;
676    case Untyped16:
677      SetEncodingValue(0x1);
678      break;
679    case Untyped32:
680      SetEncodingValue(0x0);
681      break;
682    default:
683      break;
684  }
685}
686
687class Dt_op_1 : public EncodingValue {
688 public:
689  Dt_op_1(DataType dt1, DataType dt2);
690};
691
692Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) {
693  if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
694    SetEncodingValue(0x0);
695    return;
696  }
697  if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
698    SetEncodingValue(0x1);
699    return;
700  }
701  if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
702    SetEncodingValue(0x2);
703    return;
704  }
705  if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
706    SetEncodingValue(0x3);
707    return;
708  }
709}
710
711class Dt_op_2 : public EncodingValue {
712 public:
713  explicit Dt_op_2(DataType dt);
714};
715
716Dt_op_2::Dt_op_2(DataType dt) {
717  switch (dt.GetValue()) {
718    case U32:
719      SetEncodingValue(0x0);
720      break;
721    case S32:
722      SetEncodingValue(0x1);
723      break;
724    default:
725      break;
726  }
727}
728
729class Dt_op_3 : public EncodingValue {
730 public:
731  explicit Dt_op_3(DataType dt);
732};
733
734Dt_op_3::Dt_op_3(DataType dt) {
735  switch (dt.GetValue()) {
736    case S32:
737      SetEncodingValue(0x0);
738      break;
739    case U32:
740      SetEncodingValue(0x1);
741      break;
742    default:
743      break;
744  }
745}
746
747class Dt_U_sx_1 : public EncodingValue {
748 public:
749  explicit Dt_U_sx_1(DataType dt);
750};
751
752Dt_U_sx_1::Dt_U_sx_1(DataType dt) {
753  switch (dt.GetValue()) {
754    case S16:
755      SetEncodingValue(0x0);
756      break;
757    case S32:
758      SetEncodingValue(0x1);
759      break;
760    case U16:
761      SetEncodingValue(0x2);
762      break;
763    case U32:
764      SetEncodingValue(0x3);
765      break;
766    default:
767      break;
768  }
769}
770
771class Dt_op_U_1 : public EncodingValue {
772 public:
773  Dt_op_U_1(DataType dt1, DataType dt2);
774};
775
776Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) {
777  if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
778    SetEncodingValue(0x0);
779    return;
780  }
781  if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
782    SetEncodingValue(0x1);
783    return;
784  }
785  if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
786    SetEncodingValue(0x2);
787    return;
788  }
789  if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
790    SetEncodingValue(0x3);
791    return;
792  }
793}
794
795class Dt_sz_1 : public EncodingValue {
796 public:
797  explicit Dt_sz_1(DataType dt);
798};
799
800Dt_sz_1::Dt_sz_1(DataType dt) {
801  switch (dt.GetValue()) {
802    case F32:
803      SetEncodingValue(0x0);
804      break;
805    default:
806      break;
807  }
808}
809
810class Dt_F_size_1 : public EncodingValue {
811 public:
812  explicit Dt_F_size_1(DataType dt);
813};
814
815Dt_F_size_1::Dt_F_size_1(DataType dt) {
816  switch (dt.GetValue()) {
817    case S8:
818      SetEncodingValue(0x0);
819      break;
820    case S16:
821      SetEncodingValue(0x1);
822      break;
823    case S32:
824      SetEncodingValue(0x2);
825      break;
826    case F32:
827      SetEncodingValue(0x6);
828      break;
829    default:
830      break;
831  }
832}
833
834class Dt_F_size_2 : public EncodingValue {
835 public:
836  explicit Dt_F_size_2(DataType dt);
837};
838
839Dt_F_size_2::Dt_F_size_2(DataType dt) {
840  switch (dt.GetValue()) {
841    case I8:
842      SetEncodingValue(0x0);
843      break;
844    case I16:
845      SetEncodingValue(0x1);
846      break;
847    case I32:
848      SetEncodingValue(0x2);
849      break;
850    case F32:
851      SetEncodingValue(0x6);
852      break;
853    default:
854      break;
855  }
856}
857
858class Dt_F_size_3 : public EncodingValue {
859 public:
860  explicit Dt_F_size_3(DataType dt);
861};
862
863Dt_F_size_3::Dt_F_size_3(DataType dt) {
864  switch (dt.GetValue()) {
865    case I16:
866      SetEncodingValue(0x1);
867      break;
868    case I32:
869      SetEncodingValue(0x2);
870      break;
871    case F32:
872      SetEncodingValue(0x6);
873      break;
874    default:
875      break;
876  }
877}
878
879class Dt_F_size_4 : public EncodingValue {
880 public:
881  explicit Dt_F_size_4(DataType dt);
882};
883
884Dt_F_size_4::Dt_F_size_4(DataType dt) {
885  switch (dt.GetValue()) {
886    case U32:
887      SetEncodingValue(0x2);
888      break;
889    case F32:
890      SetEncodingValue(0x6);
891      break;
892    default:
893      break;
894  }
895}
896
897class Dt_U_size_1 : public EncodingValue {
898 public:
899  explicit Dt_U_size_1(DataType dt);
900};
901
902Dt_U_size_1::Dt_U_size_1(DataType dt) {
903  switch (dt.GetValue()) {
904    case S8:
905      SetEncodingValue(0x0);
906      break;
907    case S16:
908      SetEncodingValue(0x1);
909      break;
910    case S32:
911      SetEncodingValue(0x2);
912      break;
913    case U8:
914      SetEncodingValue(0x4);
915      break;
916    case U16:
917      SetEncodingValue(0x5);
918      break;
919    case U32:
920      SetEncodingValue(0x6);
921      break;
922    default:
923      break;
924  }
925}
926
927class Dt_U_size_2 : public EncodingValue {
928 public:
929  explicit Dt_U_size_2(DataType dt);
930};
931
932Dt_U_size_2::Dt_U_size_2(DataType dt) {
933  switch (dt.GetValue()) {
934    case S16:
935      SetEncodingValue(0x1);
936      break;
937    case S32:
938      SetEncodingValue(0x2);
939      break;
940    case U16:
941      SetEncodingValue(0x5);
942      break;
943    case U32:
944      SetEncodingValue(0x6);
945      break;
946    default:
947      break;
948  }
949}
950
951class Dt_U_size_3 : public EncodingValue {
952 public:
953  explicit Dt_U_size_3(DataType dt);
954};
955
956Dt_U_size_3::Dt_U_size_3(DataType dt) {
957  switch (dt.GetValue()) {
958    case S8:
959      SetEncodingValue(0x0);
960      break;
961    case S16:
962      SetEncodingValue(0x1);
963      break;
964    case S32:
965      SetEncodingValue(0x2);
966      break;
967    case S64:
968      SetEncodingValue(0x3);
969      break;
970    case U8:
971      SetEncodingValue(0x4);
972      break;
973    case U16:
974      SetEncodingValue(0x5);
975      break;
976    case U32:
977      SetEncodingValue(0x6);
978      break;
979    case U64:
980      SetEncodingValue(0x7);
981      break;
982    default:
983      break;
984  }
985}
986
987class Dt_size_1 : public EncodingValue {
988 public:
989  explicit Dt_size_1(DataType dt);
990};
991
992Dt_size_1::Dt_size_1(DataType dt) {
993  switch (dt.GetValue()) {
994    case Untyped8:
995      SetEncodingValue(0x0);
996      break;
997    default:
998      break;
999  }
1000}
1001
1002class Dt_size_2 : public EncodingValue {
1003 public:
1004  explicit Dt_size_2(DataType dt);
1005};
1006
1007Dt_size_2::Dt_size_2(DataType dt) {
1008  switch (dt.GetValue()) {
1009    case I8:
1010      SetEncodingValue(0x0);
1011      break;
1012    case I16:
1013      SetEncodingValue(0x1);
1014      break;
1015    case I32:
1016      SetEncodingValue(0x2);
1017      break;
1018    case I64:
1019      SetEncodingValue(0x3);
1020      break;
1021    default:
1022      break;
1023  }
1024}
1025
1026class Dt_size_3 : public EncodingValue {
1027 public:
1028  explicit Dt_size_3(DataType dt);
1029};
1030
1031Dt_size_3::Dt_size_3(DataType dt) {
1032  switch (dt.GetValue()) {
1033    case I16:
1034      SetEncodingValue(0x0);
1035      break;
1036    case I32:
1037      SetEncodingValue(0x1);
1038      break;
1039    case I64:
1040      SetEncodingValue(0x2);
1041      break;
1042    default:
1043      break;
1044  }
1045}
1046
1047class Dt_size_4 : public EncodingValue {
1048 public:
1049  explicit Dt_size_4(DataType dt);
1050};
1051
1052Dt_size_4::Dt_size_4(DataType dt) {
1053  switch (dt.GetValue()) {
1054    case I8:
1055      SetEncodingValue(0x0);
1056      break;
1057    case I16:
1058      SetEncodingValue(0x1);
1059      break;
1060    case I32:
1061      SetEncodingValue(0x2);
1062      break;
1063    default:
1064      break;
1065  }
1066}
1067
1068class Dt_size_5 : public EncodingValue {
1069 public:
1070  explicit Dt_size_5(DataType dt);
1071};
1072
1073Dt_size_5::Dt_size_5(DataType dt) {
1074  switch (dt.GetValue()) {
1075    case S8:
1076      SetEncodingValue(0x0);
1077      break;
1078    case S16:
1079      SetEncodingValue(0x1);
1080      break;
1081    case S32:
1082      SetEncodingValue(0x2);
1083      break;
1084    default:
1085      break;
1086  }
1087}
1088
1089class Dt_size_6 : public EncodingValue {
1090 public:
1091  explicit Dt_size_6(DataType dt);
1092};
1093
1094Dt_size_6::Dt_size_6(DataType dt) {
1095  switch (dt.GetValue()) {
1096    case Untyped8:
1097      SetEncodingValue(0x0);
1098      break;
1099    case Untyped16:
1100      SetEncodingValue(0x1);
1101      break;
1102    case Untyped32:
1103      SetEncodingValue(0x2);
1104      break;
1105    case Untyped64:
1106      SetEncodingValue(0x3);
1107      break;
1108    default:
1109      break;
1110  }
1111}
1112
1113class Dt_size_7 : public EncodingValue {
1114 public:
1115  explicit Dt_size_7(DataType dt);
1116};
1117
1118Dt_size_7::Dt_size_7(DataType dt) {
1119  switch (dt.GetValue()) {
1120    case Untyped8:
1121      SetEncodingValue(0x0);
1122      break;
1123    case Untyped16:
1124      SetEncodingValue(0x1);
1125      break;
1126    case Untyped32:
1127      SetEncodingValue(0x2);
1128      break;
1129    default:
1130      break;
1131  }
1132}
1133
1134class Dt_size_8 : public EncodingValue {
1135 public:
1136  Dt_size_8(DataType dt, Alignment align);
1137};
1138
1139Dt_size_8::Dt_size_8(DataType dt, Alignment align) {
1140  switch (dt.GetValue()) {
1141    case Untyped8:
1142      SetEncodingValue(0x0);
1143      break;
1144    case Untyped16:
1145      SetEncodingValue(0x1);
1146      break;
1147    case Untyped32:
1148      if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) {
1149        SetEncodingValue(0x2);
1150      } else if (align.Is(k128BitAlign)) {
1151        SetEncodingValue(0x3);
1152      }
1153      break;
1154    default:
1155      break;
1156  }
1157}
1158
1159class Dt_size_9 : public EncodingValue {
1160  uint32_t type_;
1161
1162 public:
1163  explicit Dt_size_9(DataType dt);
1164  uint32_t GetTypeEncodingValue() const { return type_; }
1165};
1166
1167Dt_size_9::Dt_size_9(DataType dt) {
1168  switch (dt.GetValue()) {
1169    case I16:
1170      type_ = 0x0;
1171      SetEncodingValue(0x1);
1172      break;
1173    case I32:
1174      type_ = 0x0;
1175      SetEncodingValue(0x2);
1176      break;
1177    case F32:
1178      type_ = 0x1;
1179      SetEncodingValue(0x2);
1180      break;
1181    default:
1182      VIXL_UNREACHABLE();
1183      type_ = 0x0;
1184      break;
1185  }
1186}
1187
1188class Dt_size_10 : public EncodingValue {
1189 public:
1190  explicit Dt_size_10(DataType dt);
1191};
1192
1193Dt_size_10::Dt_size_10(DataType dt) {
1194  switch (dt.GetValue()) {
1195    case S8:
1196    case U8:
1197    case I8:
1198      SetEncodingValue(0x0);
1199      break;
1200    case S16:
1201    case U16:
1202    case I16:
1203      SetEncodingValue(0x1);
1204      break;
1205    case S32:
1206    case U32:
1207    case I32:
1208      SetEncodingValue(0x2);
1209      break;
1210    default:
1211      break;
1212  }
1213}
1214
1215class Dt_size_11 : public EncodingValue {
1216  uint32_t type_;
1217
1218 public:
1219  explicit Dt_size_11(DataType dt);
1220  uint32_t GetTypeEncodingValue() const { return type_; }
1221};
1222
1223Dt_size_11::Dt_size_11(DataType dt) {
1224  switch (dt.GetValue()) {
1225    case S16:
1226      type_ = 0x0;
1227      SetEncodingValue(0x1);
1228      break;
1229    case U16:
1230      type_ = 0x1;
1231      SetEncodingValue(0x1);
1232      break;
1233    case S32:
1234      type_ = 0x0;
1235      SetEncodingValue(0x2);
1236      break;
1237    case U32:
1238      type_ = 0x1;
1239      SetEncodingValue(0x2);
1240      break;
1241    default:
1242      VIXL_UNREACHABLE();
1243      type_ = 0x0;
1244      break;
1245  }
1246}
1247
1248class Dt_size_12 : public EncodingValue {
1249  uint32_t type_;
1250
1251 public:
1252  explicit Dt_size_12(DataType dt);
1253  uint32_t GetTypeEncodingValue() const { return type_; }
1254};
1255
1256Dt_size_12::Dt_size_12(DataType dt) {
1257  switch (dt.GetValue()) {
1258    case S8:
1259      type_ = 0x0;
1260      SetEncodingValue(0x0);
1261      break;
1262    case U8:
1263      type_ = 0x1;
1264      SetEncodingValue(0x0);
1265      break;
1266    case S16:
1267      type_ = 0x0;
1268      SetEncodingValue(0x1);
1269      break;
1270    case U16:
1271      type_ = 0x1;
1272      SetEncodingValue(0x1);
1273      break;
1274    case S32:
1275      type_ = 0x0;
1276      SetEncodingValue(0x2);
1277      break;
1278    case U32:
1279      type_ = 0x1;
1280      SetEncodingValue(0x2);
1281      break;
1282    default:
1283      VIXL_UNREACHABLE();
1284      type_ = 0x0;
1285      break;
1286  }
1287}
1288
1289class Dt_size_13 : public EncodingValue {
1290 public:
1291  explicit Dt_size_13(DataType dt);
1292};
1293
1294Dt_size_13::Dt_size_13(DataType dt) {
1295  switch (dt.GetValue()) {
1296    case S16:
1297      SetEncodingValue(0x1);
1298      break;
1299    case S32:
1300      SetEncodingValue(0x2);
1301      break;
1302    default:
1303      break;
1304  }
1305}
1306
1307class Dt_size_14 : public EncodingValue {
1308 public:
1309  explicit Dt_size_14(DataType dt);
1310};
1311
1312Dt_size_14::Dt_size_14(DataType dt) {
1313  switch (dt.GetValue()) {
1314    case S16:
1315      SetEncodingValue(0x0);
1316      break;
1317    case S32:
1318      SetEncodingValue(0x1);
1319      break;
1320    case S64:
1321      SetEncodingValue(0x2);
1322      break;
1323    default:
1324      break;
1325  }
1326}
1327
1328class Dt_size_15 : public EncodingValue {
1329 public:
1330  explicit Dt_size_15(DataType dt);
1331};
1332
1333Dt_size_15::Dt_size_15(DataType dt) {
1334  switch (dt.GetValue()) {
1335    case Untyped8:
1336      SetEncodingValue(0x0);
1337      break;
1338    case Untyped16:
1339      SetEncodingValue(0x1);
1340      break;
1341    default:
1342      break;
1343  }
1344}
1345
1346class Dt_size_16 : public EncodingValue {
1347 public:
1348  explicit Dt_size_16(DataType dt);
1349};
1350
1351Dt_size_16::Dt_size_16(DataType dt) {
1352  switch (dt.GetValue()) {
1353    case I8:
1354      SetEncodingValue(0x0);
1355      break;
1356    case I16:
1357      SetEncodingValue(0x1);
1358      break;
1359    case I32:
1360      SetEncodingValue(0x2);
1361      break;
1362    default:
1363      break;
1364  }
1365}
1366
1367class Index_1 : public EncodingValue {
1368 public:
1369  Index_1(const NeonRegisterList& nreglist, DataType dt);
1370};
1371
1372Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) {
1373  switch (dt.GetValue()) {
1374    case Untyped8: {
1375      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1376        return;
1377      }
1378      uint32_t value = nreglist.GetTransferLane() << 1;
1379      if (!nreglist.IsSingleSpaced()) return;
1380      SetEncodingValue(value);
1381      break;
1382    }
1383    case Untyped16: {
1384      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1385        return;
1386      }
1387      uint32_t value = nreglist.GetTransferLane() << 2;
1388      if (nreglist.IsDoubleSpaced()) value |= 2;
1389      SetEncodingValue(value);
1390      break;
1391    }
1392    case Untyped32: {
1393      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1394        return;
1395      }
1396      uint32_t value = nreglist.GetTransferLane() << 3;
1397      if (nreglist.IsDoubleSpaced()) value |= 4;
1398      SetEncodingValue(value);
1399      break;
1400    }
1401    default:
1402      break;
1403  }
1404}
1405
1406class Align_index_align_1 : public EncodingValue {
1407 public:
1408  Align_index_align_1(Alignment align,
1409                      const NeonRegisterList& nreglist,
1410                      DataType dt);
1411};
1412
1413Align_index_align_1::Align_index_align_1(Alignment align,
1414                                         const NeonRegisterList& nreglist,
1415                                         DataType dt) {
1416  switch (dt.GetValue()) {
1417    case Untyped8: {
1418      uint32_t value;
1419      if (align.GetType() == kNoAlignment) {
1420        value = 0;
1421      } else {
1422        return;
1423      }
1424      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1425        return;
1426      }
1427      value |= nreglist.GetTransferLane() << 1;
1428      SetEncodingValue(value);
1429      break;
1430    }
1431    case Untyped16: {
1432      uint32_t value;
1433      if (align.GetType() == k16BitAlign) {
1434        value = 1;
1435      } else if (align.GetType() == kNoAlignment) {
1436        value = 0;
1437      } else {
1438        return;
1439      }
1440      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1441        return;
1442      }
1443      value |= nreglist.GetTransferLane() << 2;
1444      SetEncodingValue(value);
1445      break;
1446    }
1447    case Untyped32: {
1448      uint32_t value;
1449      if (align.GetType() == k32BitAlign) {
1450        value = 3;
1451      } else if (align.GetType() == kNoAlignment) {
1452        value = 0;
1453      } else {
1454        return;
1455      }
1456      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1457        return;
1458      }
1459      value |= nreglist.GetTransferLane() << 3;
1460      SetEncodingValue(value);
1461      break;
1462    }
1463    default:
1464      break;
1465  }
1466}
1467
1468class Align_index_align_2 : public EncodingValue {
1469 public:
1470  Align_index_align_2(Alignment align,
1471                      const NeonRegisterList& nreglist,
1472                      DataType dt);
1473};
1474
1475Align_index_align_2::Align_index_align_2(Alignment align,
1476                                         const NeonRegisterList& nreglist,
1477                                         DataType dt) {
1478  switch (dt.GetValue()) {
1479    case Untyped8: {
1480      uint32_t value;
1481      if (align.GetType() == k16BitAlign) {
1482        value = 1;
1483      } else if (align.GetType() == kNoAlignment) {
1484        value = 0;
1485      } else {
1486        return;
1487      }
1488      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1489        return;
1490      }
1491      value |= nreglist.GetTransferLane() << 1;
1492      if (!nreglist.IsSingleSpaced()) return;
1493      SetEncodingValue(value);
1494      break;
1495    }
1496    case Untyped16: {
1497      uint32_t value;
1498      if (align.GetType() == k32BitAlign) {
1499        value = 1;
1500      } else if (align.GetType() == kNoAlignment) {
1501        value = 0;
1502      } else {
1503        return;
1504      }
1505      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1506        return;
1507      }
1508      value |= nreglist.GetTransferLane() << 2;
1509      if (nreglist.IsDoubleSpaced()) value |= 2;
1510      SetEncodingValue(value);
1511      break;
1512    }
1513    case Untyped32: {
1514      uint32_t value;
1515      if (align.GetType() == k64BitAlign) {
1516        value = 1;
1517      } else if (align.GetType() == kNoAlignment) {
1518        value = 0;
1519      } else {
1520        return;
1521      }
1522      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1523        return;
1524      }
1525      value |= nreglist.GetTransferLane() << 3;
1526      if (nreglist.IsDoubleSpaced()) value |= 4;
1527      SetEncodingValue(value);
1528      break;
1529    }
1530    default:
1531      break;
1532  }
1533}
1534
1535class Align_index_align_3 : public EncodingValue {
1536 public:
1537  Align_index_align_3(Alignment align,
1538                      const NeonRegisterList& nreglist,
1539                      DataType dt);
1540};
1541
1542Align_index_align_3::Align_index_align_3(Alignment align,
1543                                         const NeonRegisterList& nreglist,
1544                                         DataType dt) {
1545  switch (dt.GetValue()) {
1546    case Untyped8: {
1547      uint32_t value;
1548      if (align.GetType() == k32BitAlign) {
1549        value = 1;
1550      } else if (align.GetType() == kNoAlignment) {
1551        value = 0;
1552      } else {
1553        return;
1554      }
1555      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1556        return;
1557      }
1558      value |= nreglist.GetTransferLane() << 1;
1559      if (!nreglist.IsSingleSpaced()) return;
1560      SetEncodingValue(value);
1561      break;
1562    }
1563    case Untyped16: {
1564      uint32_t value;
1565      if (align.GetType() == k64BitAlign) {
1566        value = 1;
1567      } else if (align.GetType() == kNoAlignment) {
1568        value = 0;
1569      } else {
1570        return;
1571      }
1572      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1573        return;
1574      }
1575      value |= nreglist.GetTransferLane() << 2;
1576      if (nreglist.IsDoubleSpaced()) value |= 2;
1577      SetEncodingValue(value);
1578      break;
1579    }
1580    case Untyped32: {
1581      uint32_t value;
1582      if (align.GetType() == k64BitAlign) {
1583        value = 1;
1584      } else if (align.GetType() == k128BitAlign) {
1585        value = 2;
1586      } else if (align.GetType() == kNoAlignment) {
1587        value = 0;
1588      } else {
1589        return;
1590      }
1591      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1592        return;
1593      }
1594      value |= nreglist.GetTransferLane() << 3;
1595      if (nreglist.IsDoubleSpaced()) value |= 4;
1596      SetEncodingValue(value);
1597      break;
1598    }
1599    default:
1600      break;
1601  }
1602}
1603
1604class Align_a_1 : public EncodingValue {
1605 public:
1606  Align_a_1(Alignment align, DataType dt);
1607};
1608
1609Align_a_1::Align_a_1(Alignment align, DataType dt) {
1610  switch (align.GetType()) {
1611    case k16BitAlign:
1612      if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1613      break;
1614    case k32BitAlign:
1615      if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1616      break;
1617    case kNoAlignment:
1618      SetEncodingValue(0x0);
1619      break;
1620    default:
1621      break;
1622  }
1623}
1624
1625class Align_a_2 : public EncodingValue {
1626 public:
1627  Align_a_2(Alignment align, DataType dt);
1628};
1629
1630Align_a_2::Align_a_2(Alignment align, DataType dt) {
1631  switch (align.GetType()) {
1632    case k16BitAlign:
1633      if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1634      break;
1635    case k32BitAlign:
1636      if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1637      break;
1638    case k64BitAlign:
1639      if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1640      break;
1641    case kNoAlignment:
1642      SetEncodingValue(0x0);
1643      break;
1644    default:
1645      break;
1646  }
1647}
1648
1649class Align_a_3 : public EncodingValue {
1650 public:
1651  Align_a_3(Alignment align, DataType dt);
1652};
1653
1654Align_a_3::Align_a_3(Alignment align, DataType dt) {
1655  switch (align.GetType()) {
1656    case k32BitAlign:
1657      if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1658      break;
1659    case k64BitAlign:
1660      if (dt.Is(Untyped16))
1661        SetEncodingValue(0x1);
1662      else if (dt.Is(Untyped32))
1663        SetEncodingValue(0x1);
1664      break;
1665    case k128BitAlign:
1666      if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1667      break;
1668    case kNoAlignment:
1669      SetEncodingValue(0x0);
1670      break;
1671    default:
1672      break;
1673  }
1674}
1675
1676class Align_align_1 : public EncodingValue {
1677 public:
1678  Align_align_1(Alignment align, const NeonRegisterList& nreglist);
1679};
1680
1681Align_align_1::Align_align_1(Alignment align,
1682                             const NeonRegisterList& nreglist) {
1683  switch (align.GetType()) {
1684    case k64BitAlign:
1685      SetEncodingValue(0x1);
1686      break;
1687    case k128BitAlign:
1688      if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1689        SetEncodingValue(0x2);
1690      break;
1691    case k256BitAlign:
1692      if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1693        SetEncodingValue(0x3);
1694      break;
1695    case kNoAlignment:
1696      SetEncodingValue(0x0);
1697      break;
1698    default:
1699      break;
1700  }
1701}
1702
1703class Align_align_2 : public EncodingValue {
1704 public:
1705  Align_align_2(Alignment align, const NeonRegisterList& nreglist);
1706};
1707
1708Align_align_2::Align_align_2(Alignment align,
1709                             const NeonRegisterList& nreglist) {
1710  switch (align.GetType()) {
1711    case k64BitAlign:
1712      SetEncodingValue(0x1);
1713      break;
1714    case k128BitAlign:
1715      SetEncodingValue(0x2);
1716      break;
1717    case k256BitAlign:
1718      if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1719      break;
1720    case kNoAlignment:
1721      SetEncodingValue(0x0);
1722      break;
1723    default:
1724      break;
1725  }
1726}
1727
1728class Align_align_3 : public EncodingValue {
1729 public:
1730  explicit Align_align_3(Alignment align);
1731};
1732
1733Align_align_3::Align_align_3(Alignment align) {
1734  switch (align.GetType()) {
1735    case k64BitAlign:
1736      SetEncodingValue(0x1);
1737      break;
1738    case kNoAlignment:
1739      SetEncodingValue(0x0);
1740      break;
1741    default:
1742      break;
1743  }
1744}
1745
1746class Align_align_4 : public EncodingValue {
1747 public:
1748  explicit Align_align_4(Alignment align);
1749};
1750
1751Align_align_4::Align_align_4(Alignment align) {
1752  switch (align.GetType()) {
1753    case k64BitAlign:
1754      SetEncodingValue(0x1);
1755      break;
1756    case k128BitAlign:
1757      SetEncodingValue(0x2);
1758      break;
1759    case k256BitAlign:
1760      SetEncodingValue(0x3);
1761      break;
1762    case kNoAlignment:
1763      SetEncodingValue(0x0);
1764      break;
1765    default:
1766      break;
1767  }
1768}
1769
1770class Align_align_5 : public EncodingValue {
1771 public:
1772  Align_align_5(Alignment align, const NeonRegisterList& nreglist);
1773};
1774
1775Align_align_5::Align_align_5(Alignment align,
1776                             const NeonRegisterList& nreglist) {
1777  switch (align.GetType()) {
1778    case k64BitAlign:
1779      SetEncodingValue(0x1);
1780      break;
1781    case k128BitAlign:
1782      if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1783        SetEncodingValue(0x2);
1784      break;
1785    case k256BitAlign:
1786      if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1787      break;
1788    case kNoAlignment:
1789      SetEncodingValue(0x0);
1790      break;
1791    default:
1792      break;
1793  }
1794}
1795
1796
1797void Assembler::adc(Condition cond,
1798                    EncodingSize size,
1799                    Register rd,
1800                    Register rn,
1801                    const Operand& operand) {
1802  VIXL_ASSERT(AllowAssembler());
1803  CheckIT(cond);
1804  if (operand.IsImmediate()) {
1805    uint32_t imm = operand.GetImmediate();
1806    if (IsUsingT32()) {
1807      ImmediateT32 immediate_t32(imm);
1808      // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
1809      if (!size.IsNarrow() && immediate_t32.IsValid()) {
1810        EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1811                   (immediate_t32.GetEncodingValue() & 0xff) |
1812                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
1813                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
1814        AdvanceIT();
1815        return;
1816      }
1817    } else {
1818      ImmediateA32 immediate_a32(imm);
1819      // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
1820      if (immediate_a32.IsValid() && cond.IsNotNever()) {
1821        EmitA32(0x02a00000U | (cond.GetCondition() << 28) |
1822                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
1823                immediate_a32.GetEncodingValue());
1824        return;
1825      }
1826    }
1827  }
1828  if (operand.IsImmediateShiftedRegister()) {
1829    Register rm = operand.GetBaseRegister();
1830    if (operand.IsPlainRegister()) {
1831      if (IsUsingT32()) {
1832        // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
1833        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1834            rm.IsLow()) {
1835          EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
1836          AdvanceIT();
1837          return;
1838        }
1839      }
1840    }
1841    Shift shift = operand.GetShift();
1842    uint32_t amount = operand.GetShiftAmount();
1843    if (IsUsingT32()) {
1844      // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
1845      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
1846        uint32_t amount_ = amount % 32;
1847        EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1848                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
1849                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
1850        AdvanceIT();
1851        return;
1852      }
1853    } else {
1854      // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
1855      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
1856        uint32_t amount_ = amount % 32;
1857        EmitA32(0x00a00000U | (cond.GetCondition() << 28) |
1858                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1859                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
1860        return;
1861      }
1862    }
1863  }
1864  if (operand.IsRegisterShiftedRegister()) {
1865    Register rm = operand.GetBaseRegister();
1866    Shift shift = operand.GetShift();
1867    if (IsUsingA32()) {
1868      // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
1869      if (cond.IsNotNever()) {
1870        EmitA32(0x00a00010U | (cond.GetCondition() << 28) |
1871                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1872                (shift.GetType() << 5) |
1873                (operand.GetShiftRegister().GetCode() << 8));
1874        return;
1875      }
1876    }
1877  }
1878  Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand);
1879}
1880
1881void Assembler::adcs(Condition cond,
1882                     EncodingSize size,
1883                     Register rd,
1884                     Register rn,
1885                     const Operand& operand) {
1886  VIXL_ASSERT(AllowAssembler());
1887  CheckIT(cond);
1888  if (operand.IsImmediate()) {
1889    uint32_t imm = operand.GetImmediate();
1890    if (IsUsingT32()) {
1891      ImmediateT32 immediate_t32(imm);
1892      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
1893      if (!size.IsNarrow() && immediate_t32.IsValid()) {
1894        EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1895                   (immediate_t32.GetEncodingValue() & 0xff) |
1896                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
1897                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
1898        AdvanceIT();
1899        return;
1900      }
1901    } else {
1902      ImmediateA32 immediate_a32(imm);
1903      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
1904      if (immediate_a32.IsValid() && cond.IsNotNever()) {
1905        EmitA32(0x02b00000U | (cond.GetCondition() << 28) |
1906                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
1907                immediate_a32.GetEncodingValue());
1908        return;
1909      }
1910    }
1911  }
1912  if (operand.IsImmediateShiftedRegister()) {
1913    Register rm = operand.GetBaseRegister();
1914    if (operand.IsPlainRegister()) {
1915      if (IsUsingT32()) {
1916        // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
1917        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1918            rm.IsLow()) {
1919          EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
1920          AdvanceIT();
1921          return;
1922        }
1923      }
1924    }
1925    Shift shift = operand.GetShift();
1926    uint32_t amount = operand.GetShiftAmount();
1927    if (IsUsingT32()) {
1928      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
1929      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
1930        uint32_t amount_ = amount % 32;
1931        EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1932                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
1933                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
1934        AdvanceIT();
1935        return;
1936      }
1937    } else {
1938      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
1939      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
1940        uint32_t amount_ = amount % 32;
1941        EmitA32(0x00b00000U | (cond.GetCondition() << 28) |
1942                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1943                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
1944        return;
1945      }
1946    }
1947  }
1948  if (operand.IsRegisterShiftedRegister()) {
1949    Register rm = operand.GetBaseRegister();
1950    Shift shift = operand.GetShift();
1951    if (IsUsingA32()) {
1952      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
1953      if (cond.IsNotNever()) {
1954        EmitA32(0x00b00010U | (cond.GetCondition() << 28) |
1955                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1956                (shift.GetType() << 5) |
1957                (operand.GetShiftRegister().GetCode() << 8));
1958        return;
1959      }
1960    }
1961  }
1962  Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand);
1963}
1964
1965void Assembler::add(Condition cond,
1966                    EncodingSize size,
1967                    Register rd,
1968                    Register rn,
1969                    const Operand& operand) {
1970  VIXL_ASSERT(AllowAssembler());
1971  CheckIT(cond);
1972  if (operand.IsImmediate()) {
1973    uint32_t imm = operand.GetImmediate();
1974    if (IsUsingT32()) {
1975      ImmediateT32 immediate_t32(imm);
1976      // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1
1977      if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) &&
1978          ((imm % 4) == 0)) {
1979        uint32_t imm_ = imm >> 2;
1980        EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_);
1981        AdvanceIT();
1982        return;
1983      }
1984      // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
1985      if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
1986          (imm <= 7)) {
1987        EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
1988        AdvanceIT();
1989        return;
1990      }
1991      // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
1992      if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1993          (imm <= 255)) {
1994        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
1995        AdvanceIT();
1996        return;
1997      }
1998      // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1
1999      if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) &&
2000          ((imm % 4) == 0)) {
2001        uint32_t imm_ = imm >> 2;
2002        EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_);
2003        AdvanceIT();
2004        return;
2005      }
2006      // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2
2007      if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
2008          ((imm % 4) == 0)) {
2009        uint32_t imm_ = imm >> 2;
2010        EmitT32_16(0xb000 | imm_);
2011        AdvanceIT();
2012        return;
2013      }
2014      // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2015      if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095)) {
2016        EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2017                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2018        AdvanceIT();
2019        return;
2020      }
2021      // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2022      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp)) {
2023        EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2024                   (immediate_t32.GetEncodingValue() & 0xff) |
2025                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2026                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2027        AdvanceIT();
2028        return;
2029      }
2030      // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2031      if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
2032        EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2033                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2034        AdvanceIT();
2035        return;
2036      }
2037      // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2038      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid()) {
2039        EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) |
2040                   (immediate_t32.GetEncodingValue() & 0xff) |
2041                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2042                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2043        AdvanceIT();
2044        return;
2045      }
2046      // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2047      if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095)) {
2048        EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2049                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2050        AdvanceIT();
2051        return;
2052      }
2053    } else {
2054      ImmediateA32 immediate_a32(imm);
2055      // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1
2056      if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
2057        EmitA32(0x028f0000U | (cond.GetCondition() << 28) |
2058                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2059        return;
2060      }
2061      // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2062      if (immediate_a32.IsValid() && cond.IsNotNever() &&
2063          ((rn.GetCode() & 0xd) != 0xd)) {
2064        EmitA32(0x02800000U | (cond.GetCondition() << 28) |
2065                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2066                immediate_a32.GetEncodingValue());
2067        return;
2068      }
2069      // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2070      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2071        EmitA32(0x028d0000U | (cond.GetCondition() << 28) |
2072                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2073        return;
2074      }
2075    }
2076  }
2077  if (operand.IsImmediateShiftedRegister()) {
2078    Register rm = operand.GetBaseRegister();
2079    if (operand.IsPlainRegister()) {
2080      if (IsUsingT32()) {
2081        // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
2082        if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2083            rm.IsLow()) {
2084          EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2085                     (rm.GetCode() << 6));
2086          AdvanceIT();
2087          return;
2088        }
2089        // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2
2090        if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp)) {
2091          EmitT32_16(0x4400 | (rd.GetCode() & 0x7) |
2092                     ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
2093          AdvanceIT();
2094          return;
2095        }
2096        // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1
2097        if (!size.IsWide() && rd.Is(rm) && rn.Is(sp)) {
2098          EmitT32_16(0x4468 | (rd.GetCode() & 0x7) |
2099                     ((rd.GetCode() & 0x8) << 4));
2100          AdvanceIT();
2101          return;
2102        }
2103        // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2
2104        if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) {
2105          EmitT32_16(0x4485 | (rm.GetCode() << 3));
2106          AdvanceIT();
2107          return;
2108        }
2109      }
2110    }
2111    Shift shift = operand.GetShift();
2112    uint32_t amount = operand.GetShiftAmount();
2113    if (IsUsingT32()) {
2114      // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2115      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp)) {
2116        uint32_t amount_ = amount % 32;
2117        EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2118                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2119                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2120        AdvanceIT();
2121        return;
2122      }
2123      // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2124      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount)) {
2125        uint32_t amount_ = amount % 32;
2126        EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2127                   (operand.GetTypeEncodingValue() << 4) |
2128                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2129        AdvanceIT();
2130        return;
2131      }
2132    } else {
2133      // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2134      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2135        uint32_t amount_ = amount % 32;
2136        EmitA32(0x00800000U | (cond.GetCondition() << 28) |
2137                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2138                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2139        return;
2140      }
2141      // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2142      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2143        uint32_t amount_ = amount % 32;
2144        EmitA32(0x008d0000U | (cond.GetCondition() << 28) |
2145                (rd.GetCode() << 12) | rm.GetCode() |
2146                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2147        return;
2148      }
2149    }
2150  }
2151  if (operand.IsRegisterShiftedRegister()) {
2152    Register rm = operand.GetBaseRegister();
2153    Shift shift = operand.GetShift();
2154    if (IsUsingA32()) {
2155      // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2156      if (cond.IsNotNever()) {
2157        EmitA32(0x00800010U | (cond.GetCondition() << 28) |
2158                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2159                (shift.GetType() << 5) |
2160                (operand.GetShiftRegister().GetCode() << 8));
2161        return;
2162      }
2163    }
2164  }
2165  Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand);
2166}
2167
2168void Assembler::add(Condition cond, Register rd, const Operand& operand) {
2169  VIXL_ASSERT(AllowAssembler());
2170  CheckIT(cond);
2171  if (operand.IsImmediate()) {
2172    uint32_t imm = operand.GetImmediate();
2173    if (IsUsingT32()) {
2174      // ADD<c>{<q>} <Rdn>, #<imm8> ; T2
2175      if (InITBlock() && rd.IsLow() && (imm <= 255)) {
2176        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2177        AdvanceIT();
2178        return;
2179      }
2180    }
2181  }
2182  if (operand.IsPlainRegister()) {
2183    Register rm = operand.GetBaseRegister();
2184    if (IsUsingT32()) {
2185      // ADD<c>{<q>} <Rdn>, <Rm> ; T2
2186      if (InITBlock() && !rm.Is(sp)) {
2187        EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) |
2188                   (rm.GetCode() << 3));
2189        AdvanceIT();
2190        return;
2191      }
2192    }
2193  }
2194  Delegate(kAdd, &Assembler::add, cond, rd, operand);
2195}
2196
2197void Assembler::adds(Condition cond,
2198                     EncodingSize size,
2199                     Register rd,
2200                     Register rn,
2201                     const Operand& operand) {
2202  VIXL_ASSERT(AllowAssembler());
2203  CheckIT(cond);
2204  if (operand.IsImmediate()) {
2205    uint32_t imm = operand.GetImmediate();
2206    if (IsUsingT32()) {
2207      ImmediateT32 immediate_t32(imm);
2208      // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1
2209      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2210          (imm <= 7)) {
2211        EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
2212        AdvanceIT();
2213        return;
2214      }
2215      // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
2216      if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2217          (imm <= 255)) {
2218        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2219        AdvanceIT();
2220        return;
2221      }
2222      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2223      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
2224          !rd.Is(pc)) {
2225        EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2226                   (immediate_t32.GetEncodingValue() & 0xff) |
2227                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2228                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2229        AdvanceIT();
2230        return;
2231      }
2232      // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2233      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
2234          !rd.Is(pc)) {
2235        EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) |
2236                   (immediate_t32.GetEncodingValue() & 0xff) |
2237                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2238                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2239        AdvanceIT();
2240        return;
2241      }
2242    } else {
2243      ImmediateA32 immediate_a32(imm);
2244      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2245      if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
2246        EmitA32(0x02900000U | (cond.GetCondition() << 28) |
2247                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2248                immediate_a32.GetEncodingValue());
2249        return;
2250      }
2251      // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2252      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2253        EmitA32(0x029d0000U | (cond.GetCondition() << 28) |
2254                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2255        return;
2256      }
2257    }
2258  }
2259  if (operand.IsImmediateShiftedRegister()) {
2260    Register rm = operand.GetBaseRegister();
2261    if (operand.IsPlainRegister()) {
2262      if (IsUsingT32()) {
2263        // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
2264        if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2265            rm.IsLow()) {
2266          EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2267                     (rm.GetCode() << 6));
2268          AdvanceIT();
2269          return;
2270        }
2271      }
2272    }
2273    Shift shift = operand.GetShift();
2274    uint32_t amount = operand.GetShiftAmount();
2275    if (IsUsingT32()) {
2276      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2277      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
2278          !rd.Is(pc)) {
2279        uint32_t amount_ = amount % 32;
2280        EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2281                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2282                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2283        AdvanceIT();
2284        return;
2285      }
2286      // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2287      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
2288          !rd.Is(pc)) {
2289        uint32_t amount_ = amount % 32;
2290        EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2291                   (operand.GetTypeEncodingValue() << 4) |
2292                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2293        AdvanceIT();
2294        return;
2295      }
2296    } else {
2297      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2298      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2299        uint32_t amount_ = amount % 32;
2300        EmitA32(0x00900000U | (cond.GetCondition() << 28) |
2301                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2302                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2303        return;
2304      }
2305      // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2306      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2307        uint32_t amount_ = amount % 32;
2308        EmitA32(0x009d0000U | (cond.GetCondition() << 28) |
2309                (rd.GetCode() << 12) | rm.GetCode() |
2310                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2311        return;
2312      }
2313    }
2314  }
2315  if (operand.IsRegisterShiftedRegister()) {
2316    Register rm = operand.GetBaseRegister();
2317    Shift shift = operand.GetShift();
2318    if (IsUsingA32()) {
2319      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2320      if (cond.IsNotNever()) {
2321        EmitA32(0x00900010U | (cond.GetCondition() << 28) |
2322                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2323                (shift.GetType() << 5) |
2324                (operand.GetShiftRegister().GetCode() << 8));
2325        return;
2326      }
2327    }
2328  }
2329  Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand);
2330}
2331
2332void Assembler::adds(Register rd, const Operand& operand) {
2333  VIXL_ASSERT(AllowAssembler());
2334  CheckIT(al);
2335  if (operand.IsImmediate()) {
2336    uint32_t imm = operand.GetImmediate();
2337    if (IsUsingT32()) {
2338      // ADDS{<q>} <Rdn>, #<imm8> ; T2
2339      if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
2340        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2341        AdvanceIT();
2342        return;
2343      }
2344    }
2345  }
2346  Delegate(kAdds, &Assembler::adds, rd, operand);
2347}
2348
2349void Assembler::addw(Condition cond,
2350                     Register rd,
2351                     Register rn,
2352                     const Operand& operand) {
2353  VIXL_ASSERT(AllowAssembler());
2354  CheckIT(cond);
2355  if (operand.IsImmediate()) {
2356    uint32_t imm = operand.GetImmediate();
2357    if (IsUsingT32()) {
2358      // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2359      if (rn.Is(pc) && (imm <= 4095)) {
2360        EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2361                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2362        AdvanceIT();
2363        return;
2364      }
2365      // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2366      if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
2367        EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2368                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2369        AdvanceIT();
2370        return;
2371      }
2372      // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2373      if (rn.Is(sp) && (imm <= 4095)) {
2374        EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2375                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2376        AdvanceIT();
2377        return;
2378      }
2379    }
2380  }
2381  Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand);
2382}
2383
2384void Assembler::adr(Condition cond,
2385                    EncodingSize size,
2386                    Register rd,
2387                    Label* label) {
2388  VIXL_ASSERT(AllowAssembler());
2389  CheckIT(cond);
2390  Label::Offset offset =
2391      label->IsBound()
2392          ? label->GetLocation() -
2393                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
2394          : 0;
2395  if (IsUsingT32()) {
2396    int32_t neg_offset = -offset;
2397    // ADR{<c>}{<q>} <Rd>, <label> ; T1
2398    if (!size.IsWide() && rd.IsLow() &&
2399        ((label->IsBound() && (offset >= 0) && (offset <= 1020) &&
2400          ((offset & 0x3) == 0)) ||
2401         (!label->IsBound() && size.IsNarrow()))) {
2402      static class EmitOp : public Label::LabelEmitOperator {
2403       public:
2404        EmitOp() : Label::LabelEmitOperator(0, 1020) {}
2405        virtual uint32_t Encode(uint32_t instr,
2406                                Label::Offset pc,
2407                                const Label* label) const VIXL_OVERRIDE {
2408          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2409          VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
2410                      ((offset & 0x3) == 0));
2411          const int32_t target = offset >> 2;
2412          return instr | (target & 0xff);
2413        }
2414      } immop;
2415      EmitT32_16(Link(0xa000 | (rd.GetCode() << 8), label, immop));
2416      AdvanceIT();
2417      return;
2418    }
2419    // ADR{<c>}{<q>} <Rd>, <label> ; T2
2420    if (!size.IsNarrow() && label->IsBound() && (neg_offset > 0) &&
2421        (neg_offset <= 4095)) {
2422      EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) |
2423                 ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15));
2424      AdvanceIT();
2425      return;
2426    }
2427    // ADR{<c>}{<q>} <Rd>, <label> ; T3
2428    if (!size.IsNarrow() &&
2429        (!label->IsBound() || ((offset >= 0) && (offset <= 4095)))) {
2430      static class EmitOp : public Label::LabelEmitOperator {
2431       public:
2432        EmitOp() : Label::LabelEmitOperator(0, 4095) {}
2433        virtual uint32_t Encode(uint32_t instr,
2434                                Label::Offset pc,
2435                                const Label* label) const VIXL_OVERRIDE {
2436          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2437          int32_t target;
2438          if ((offset >= 0) && (offset <= 4095) && !label->IsMinusZero()) {
2439            target = offset;
2440          } else {
2441            target = -offset;
2442            VIXL_ASSERT((target >= 0) && (target <= 4095));
2443            // Emit the T2 encoding.
2444            instr |= 0x00a00000;
2445          }
2446          return instr | (target & 0xff) | ((target & 0x700) << 4) |
2447                 ((target & 0x800) << 15);
2448        }
2449      } immop;
2450      EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8), label, immop));
2451      AdvanceIT();
2452      return;
2453    }
2454  } else {
2455    ImmediateA32 positive_immediate_a32(offset);
2456    ImmediateA32 negative_immediate_a32(-offset);
2457    // ADR{<c>}{<q>} <Rd>, <label> ; A1
2458    if ((!label->IsBound() || positive_immediate_a32.IsValid()) &&
2459        cond.IsNotNever()) {
2460      static class EmitOp : public Label::LabelEmitOperator {
2461       public:
2462        EmitOp() : Label::LabelEmitOperator(0, 255) {}
2463        virtual uint32_t Encode(uint32_t instr,
2464                                Label::Offset pc,
2465                                const Label* label) const VIXL_OVERRIDE {
2466          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2467          int32_t target;
2468          ImmediateA32 positive_immediate_a32(offset);
2469          if (positive_immediate_a32.IsValid()) {
2470            target = positive_immediate_a32.GetEncodingValue();
2471          } else {
2472            ImmediateA32 negative_immediate_a32(-offset);
2473            VIXL_ASSERT(negative_immediate_a32.IsValid());
2474            // Emit the A2 encoding.
2475            target = negative_immediate_a32.GetEncodingValue();
2476            instr = (instr & ~0x00f00000) | 0x00400000;
2477          }
2478          return instr | (target & 0xfff);
2479        }
2480      } immop;
2481      EmitA32(
2482          Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12),
2483               label,
2484               immop));
2485      return;
2486    }
2487    // ADR{<c>}{<q>} <Rd>, <label> ; A2
2488    if (label->IsBound() && negative_immediate_a32.IsValid() &&
2489        cond.IsNotNever()) {
2490      EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
2491              negative_immediate_a32.GetEncodingValue());
2492      return;
2493    }
2494  }
2495  Delegate(kAdr, &Assembler::adr, cond, size, rd, label);
2496}
2497
2498void Assembler::and_(Condition cond,
2499                     EncodingSize size,
2500                     Register rd,
2501                     Register rn,
2502                     const Operand& operand) {
2503  VIXL_ASSERT(AllowAssembler());
2504  CheckIT(cond);
2505  if (operand.IsImmediate()) {
2506    uint32_t imm = operand.GetImmediate();
2507    if (IsUsingT32()) {
2508      ImmediateT32 immediate_t32(imm);
2509      // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2510      if (!size.IsNarrow() && immediate_t32.IsValid()) {
2511        EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2512                   (immediate_t32.GetEncodingValue() & 0xff) |
2513                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2514                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2515        AdvanceIT();
2516        return;
2517      }
2518    } else {
2519      ImmediateA32 immediate_a32(imm);
2520      // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2521      if (immediate_a32.IsValid() && cond.IsNotNever()) {
2522        EmitA32(0x02000000U | (cond.GetCondition() << 28) |
2523                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2524                immediate_a32.GetEncodingValue());
2525        return;
2526      }
2527    }
2528  }
2529  if (operand.IsImmediateShiftedRegister()) {
2530    Register rm = operand.GetBaseRegister();
2531    if (operand.IsPlainRegister()) {
2532      if (IsUsingT32()) {
2533        // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2534        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2535            rm.IsLow()) {
2536          EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2537          AdvanceIT();
2538          return;
2539        }
2540      }
2541    }
2542    Shift shift = operand.GetShift();
2543    uint32_t amount = operand.GetShiftAmount();
2544    if (IsUsingT32()) {
2545      // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2546      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
2547        uint32_t amount_ = amount % 32;
2548        EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2549                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2550                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2551        AdvanceIT();
2552        return;
2553      }
2554    } else {
2555      // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2556      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2557        uint32_t amount_ = amount % 32;
2558        EmitA32(0x00000000U | (cond.GetCondition() << 28) |
2559                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2560                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2561        return;
2562      }
2563    }
2564  }
2565  if (operand.IsRegisterShiftedRegister()) {
2566    Register rm = operand.GetBaseRegister();
2567    Shift shift = operand.GetShift();
2568    if (IsUsingA32()) {
2569      // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2570      if (cond.IsNotNever()) {
2571        EmitA32(0x00000010U | (cond.GetCondition() << 28) |
2572                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2573                (shift.GetType() << 5) |
2574                (operand.GetShiftRegister().GetCode() << 8));
2575        return;
2576      }
2577    }
2578  }
2579  Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand);
2580}
2581
2582void Assembler::ands(Condition cond,
2583                     EncodingSize size,
2584                     Register rd,
2585                     Register rn,
2586                     const Operand& operand) {
2587  VIXL_ASSERT(AllowAssembler());
2588  CheckIT(cond);
2589  if (operand.IsImmediate()) {
2590    uint32_t imm = operand.GetImmediate();
2591    if (IsUsingT32()) {
2592      ImmediateT32 immediate_t32(imm);
2593      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2594      if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) {
2595        EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2596                   (immediate_t32.GetEncodingValue() & 0xff) |
2597                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2598                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2599        AdvanceIT();
2600        return;
2601      }
2602    } else {
2603      ImmediateA32 immediate_a32(imm);
2604      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2605      if (immediate_a32.IsValid() && cond.IsNotNever()) {
2606        EmitA32(0x02100000U | (cond.GetCondition() << 28) |
2607                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2608                immediate_a32.GetEncodingValue());
2609        return;
2610      }
2611    }
2612  }
2613  if (operand.IsImmediateShiftedRegister()) {
2614    Register rm = operand.GetBaseRegister();
2615    if (operand.IsPlainRegister()) {
2616      if (IsUsingT32()) {
2617        // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2618        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2619            rm.IsLow()) {
2620          EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2621          AdvanceIT();
2622          return;
2623        }
2624      }
2625    }
2626    Shift shift = operand.GetShift();
2627    uint32_t amount = operand.GetShiftAmount();
2628    if (IsUsingT32()) {
2629      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2630      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) {
2631        uint32_t amount_ = amount % 32;
2632        EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2633                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2634                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2635        AdvanceIT();
2636        return;
2637      }
2638    } else {
2639      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2640      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2641        uint32_t amount_ = amount % 32;
2642        EmitA32(0x00100000U | (cond.GetCondition() << 28) |
2643                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2644                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2645        return;
2646      }
2647    }
2648  }
2649  if (operand.IsRegisterShiftedRegister()) {
2650    Register rm = operand.GetBaseRegister();
2651    Shift shift = operand.GetShift();
2652    if (IsUsingA32()) {
2653      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2654      if (cond.IsNotNever()) {
2655        EmitA32(0x00100010U | (cond.GetCondition() << 28) |
2656                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2657                (shift.GetType() << 5) |
2658                (operand.GetShiftRegister().GetCode() << 8));
2659        return;
2660      }
2661    }
2662  }
2663  Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand);
2664}
2665
2666void Assembler::asr(Condition cond,
2667                    EncodingSize size,
2668                    Register rd,
2669                    Register rm,
2670                    const Operand& operand) {
2671  VIXL_ASSERT(AllowAssembler());
2672  CheckIT(cond);
2673  if (operand.IsImmediate()) {
2674    uint32_t imm = operand.GetImmediate();
2675    if (IsUsingT32()) {
2676      // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2677      if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2678          (imm >= 1) && (imm <= 32)) {
2679        uint32_t amount_ = imm % 32;
2680        EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2681                   (amount_ << 6));
2682        AdvanceIT();
2683        return;
2684      }
2685      // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2686      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
2687        uint32_t amount_ = imm % 32;
2688        EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2689                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2690        AdvanceIT();
2691        return;
2692      }
2693    } else {
2694      // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2695      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2696        uint32_t amount_ = imm % 32;
2697        EmitA32(0x01a00040U | (cond.GetCondition() << 28) |
2698                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2699        return;
2700      }
2701    }
2702  }
2703  if (operand.IsPlainRegister()) {
2704    Register rs = operand.GetBaseRegister();
2705    if (IsUsingT32()) {
2706      // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2707      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2708          rs.IsLow()) {
2709        EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2710        AdvanceIT();
2711        return;
2712      }
2713      // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2714      if (!size.IsNarrow()) {
2715        EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2716                   rs.GetCode());
2717        AdvanceIT();
2718        return;
2719      }
2720    } else {
2721      // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
2722      if (cond.IsNotNever()) {
2723        EmitA32(0x01a00050U | (cond.GetCondition() << 28) |
2724                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
2725        return;
2726      }
2727    }
2728  }
2729  Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand);
2730}
2731
2732void Assembler::asrs(Condition cond,
2733                     EncodingSize size,
2734                     Register rd,
2735                     Register rm,
2736                     const Operand& operand) {
2737  VIXL_ASSERT(AllowAssembler());
2738  CheckIT(cond);
2739  if (operand.IsImmediate()) {
2740    uint32_t imm = operand.GetImmediate();
2741    if (IsUsingT32()) {
2742      // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2743      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2744          (imm >= 1) && (imm <= 32)) {
2745        uint32_t amount_ = imm % 32;
2746        EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2747                   (amount_ << 6));
2748        AdvanceIT();
2749        return;
2750      }
2751      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2752      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
2753        uint32_t amount_ = imm % 32;
2754        EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2755                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2756        AdvanceIT();
2757        return;
2758      }
2759    } else {
2760      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2761      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2762        uint32_t amount_ = imm % 32;
2763        EmitA32(0x01b00040U | (cond.GetCondition() << 28) |
2764                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2765        return;
2766      }
2767    }
2768  }
2769  if (operand.IsPlainRegister()) {
2770    Register rs = operand.GetBaseRegister();
2771    if (IsUsingT32()) {
2772      // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2773      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2774          rs.IsLow()) {
2775        EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2776        AdvanceIT();
2777        return;
2778      }
2779      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2780      if (!size.IsNarrow()) {
2781        EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2782                   rs.GetCode());
2783        AdvanceIT();
2784        return;
2785      }
2786    } else {
2787      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
2788      if (cond.IsNotNever()) {
2789        EmitA32(0x01b00050U | (cond.GetCondition() << 28) |
2790                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
2791        return;
2792      }
2793    }
2794  }
2795  Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand);
2796}
2797
2798void Assembler::b(Condition cond, EncodingSize size, Label* label) {
2799  VIXL_ASSERT(AllowAssembler());
2800  Label::Offset offset =
2801      label->IsBound()
2802          ? label->GetLocation() -
2803                (GetCursorOffset() + GetArchitectureStatePCOffset())
2804          : 0;
2805  if (IsUsingT32()) {
2806    // B<c>{<q>} <label> ; T1
2807    if (OutsideITBlock() && !size.IsWide() &&
2808        ((label->IsBound() && (offset >= -256) && (offset <= 254) &&
2809          ((offset & 0x1) == 0)) ||
2810         (!label->IsBound() && size.IsNarrow())) &&
2811        !cond.Is(al) && cond.IsNotNever()) {
2812      static class EmitOp : public Label::LabelEmitOperator {
2813       public:
2814        EmitOp() : Label::LabelEmitOperator(-256, 254) {}
2815        virtual uint32_t Encode(uint32_t instr,
2816                                Label::Offset pc,
2817                                const Label* label) const VIXL_OVERRIDE {
2818          Label::Offset offset = label->GetLocation() - pc;
2819          VIXL_ASSERT((offset >= -256) && (offset <= 254) &&
2820                      ((offset & 0x1) == 0));
2821          const int32_t target = offset >> 1;
2822          return instr | (target & 0xff);
2823        }
2824      } immop;
2825      EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8), label, immop));
2826      AdvanceIT();
2827      return;
2828    }
2829    // B{<c>}{<q>} <label> ; T2
2830    if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() &&
2831        ((label->IsBound() && (offset >= -2048) && (offset <= 2046) &&
2832          ((offset & 0x1) == 0)) ||
2833         (!label->IsBound() && size.IsNarrow()))) {
2834      CheckIT(cond);
2835      static class EmitOp : public Label::LabelEmitOperator {
2836       public:
2837        EmitOp() : Label::LabelEmitOperator(-2048, 2046) {}
2838        virtual uint32_t Encode(uint32_t instr,
2839                                Label::Offset pc,
2840                                const Label* label) const VIXL_OVERRIDE {
2841          Label::Offset offset = label->GetLocation() - pc;
2842          VIXL_ASSERT((offset >= -2048) && (offset <= 2046) &&
2843                      ((offset & 0x1) == 0));
2844          const int32_t target = offset >> 1;
2845          return instr | (target & 0x7ff);
2846        }
2847      } immop;
2848      EmitT32_16(Link(0xe000, label, immop));
2849      AdvanceIT();
2850      return;
2851    }
2852    // B<c>{<q>} <label> ; T3
2853    if (OutsideITBlock() && !size.IsNarrow() &&
2854        ((label->IsBound() && (offset >= -1048576) && (offset <= 1048574) &&
2855          ((offset & 0x1) == 0)) ||
2856         !label->IsBound()) &&
2857        !cond.Is(al) && cond.IsNotNever()) {
2858      static class EmitOp : public Label::LabelEmitOperator {
2859       public:
2860        EmitOp() : Label::LabelEmitOperator(-1048576, 1048574) {}
2861        virtual uint32_t Encode(uint32_t instr,
2862                                Label::Offset pc,
2863                                const Label* label) const VIXL_OVERRIDE {
2864          Label::Offset offset = label->GetLocation() - pc;
2865          VIXL_ASSERT((offset >= -1048576) && (offset <= 1048574) &&
2866                      ((offset & 0x1) == 0));
2867          const int32_t target = offset >> 1;
2868          return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) |
2869                 ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) |
2870                 ((target & 0x80000) << 7);
2871        }
2872      } immop;
2873      EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22), label, immop));
2874      AdvanceIT();
2875      return;
2876    }
2877    // B{<c>}{<q>} <label> ; T4
2878    if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() &&
2879        ((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) &&
2880          ((offset & 0x1) == 0)) ||
2881         !label->IsBound())) {
2882      CheckIT(cond);
2883      static class EmitOp : public Label::LabelEmitOperator {
2884       public:
2885        EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {}
2886        virtual uint32_t Encode(uint32_t instr,
2887                                Label::Offset pc,
2888                                const Label* label) const VIXL_OVERRIDE {
2889          Label::Offset offset = label->GetLocation() - pc;
2890          VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
2891                      ((offset & 0x1) == 0));
2892          int32_t target = offset >> 1;
2893          uint32_t S = target & (1 << 23);
2894          target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
2895          return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
2896                 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
2897                 ((target & 0x800000) << 3);
2898        }
2899      } immop;
2900      EmitT32_32(Link(0xf0009000U, label, immop));
2901      AdvanceIT();
2902      return;
2903    }
2904  } else {
2905    // B{<c>}{<q>} <label> ; A1
2906    if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) &&
2907          ((offset & 0x3) == 0)) ||
2908         !label->IsBound()) &&
2909        cond.IsNotNever()) {
2910      static class EmitOp : public Label::LabelEmitOperator {
2911       public:
2912        EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {}
2913        virtual uint32_t Encode(uint32_t instr,
2914                                Label::Offset pc,
2915                                const Label* label) const VIXL_OVERRIDE {
2916          Label::Offset offset = label->GetLocation() - pc;
2917          VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
2918                      ((offset & 0x3) == 0));
2919          const int32_t target = offset >> 2;
2920          return instr | (target & 0xffffff);
2921        }
2922      } immop;
2923      EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28), label, immop));
2924      return;
2925    }
2926  }
2927  Delegate(kB, &Assembler::b, cond, size, label);
2928}
2929
2930void Assembler::bfc(Condition cond,
2931                    Register rd,
2932                    uint32_t lsb,
2933                    const Operand& operand) {
2934  VIXL_ASSERT(AllowAssembler());
2935  CheckIT(cond);
2936  if (operand.IsImmediate()) {
2937    uint32_t width = operand.GetImmediate();
2938    if (IsUsingT32()) {
2939      // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1
2940      if ((lsb <= 31) &&
2941          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2942        uint32_t msb = lsb + width - 1;
2943        EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) |
2944                   ((lsb & 0x1c) << 10) | msb);
2945        AdvanceIT();
2946        return;
2947      }
2948    } else {
2949      // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1
2950      if ((lsb <= 31) && cond.IsNotNever() &&
2951          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2952        uint32_t msb = lsb + width - 1;
2953        EmitA32(0x07c0001fU | (cond.GetCondition() << 28) |
2954                (rd.GetCode() << 12) | (lsb << 7) | (msb << 16));
2955        return;
2956      }
2957    }
2958  }
2959  Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, operand);
2960}
2961
2962void Assembler::bfi(Condition cond,
2963                    Register rd,
2964                    Register rn,
2965                    uint32_t lsb,
2966                    const Operand& operand) {
2967  VIXL_ASSERT(AllowAssembler());
2968  CheckIT(cond);
2969  if (operand.IsImmediate()) {
2970    uint32_t width = operand.GetImmediate();
2971    if (IsUsingT32()) {
2972      // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
2973      if ((lsb <= 31) && !rn.Is(pc) &&
2974          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2975        uint32_t msb = lsb + width - 1;
2976        EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2977                   ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb);
2978        AdvanceIT();
2979        return;
2980      }
2981    } else {
2982      // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
2983      if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) &&
2984          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2985        uint32_t msb = lsb + width - 1;
2986        EmitA32(0x07c00010U | (cond.GetCondition() << 28) |
2987                (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) | (msb << 16));
2988        return;
2989      }
2990    }
2991  }
2992  Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, operand);
2993}
2994
2995void Assembler::bic(Condition cond,
2996                    EncodingSize size,
2997                    Register rd,
2998                    Register rn,
2999                    const Operand& operand) {
3000  VIXL_ASSERT(AllowAssembler());
3001  CheckIT(cond);
3002  if (operand.IsImmediate()) {
3003    uint32_t imm = operand.GetImmediate();
3004    if (IsUsingT32()) {
3005      ImmediateT32 immediate_t32(imm);
3006      // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3007      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3008        EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3009                   (immediate_t32.GetEncodingValue() & 0xff) |
3010                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3011                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3012        AdvanceIT();
3013        return;
3014      }
3015    } else {
3016      ImmediateA32 immediate_a32(imm);
3017      // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3018      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3019        EmitA32(0x03c00000U | (cond.GetCondition() << 28) |
3020                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3021                immediate_a32.GetEncodingValue());
3022        return;
3023      }
3024    }
3025  }
3026  if (operand.IsImmediateShiftedRegister()) {
3027    Register rm = operand.GetBaseRegister();
3028    if (operand.IsPlainRegister()) {
3029      if (IsUsingT32()) {
3030        // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3031        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3032            rm.IsLow()) {
3033          EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3034          AdvanceIT();
3035          return;
3036        }
3037      }
3038    }
3039    Shift shift = operand.GetShift();
3040    uint32_t amount = operand.GetShiftAmount();
3041    if (IsUsingT32()) {
3042      // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3043      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3044        uint32_t amount_ = amount % 32;
3045        EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3046                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3047                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3048        AdvanceIT();
3049        return;
3050      }
3051    } else {
3052      // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3053      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3054        uint32_t amount_ = amount % 32;
3055        EmitA32(0x01c00000U | (cond.GetCondition() << 28) |
3056                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3057                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3058        return;
3059      }
3060    }
3061  }
3062  if (operand.IsRegisterShiftedRegister()) {
3063    Register rm = operand.GetBaseRegister();
3064    Shift shift = operand.GetShift();
3065    if (IsUsingA32()) {
3066      // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3067      if (cond.IsNotNever()) {
3068        EmitA32(0x01c00010U | (cond.GetCondition() << 28) |
3069                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3070                (shift.GetType() << 5) |
3071                (operand.GetShiftRegister().GetCode() << 8));
3072        return;
3073      }
3074    }
3075  }
3076  Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand);
3077}
3078
3079void Assembler::bics(Condition cond,
3080                     EncodingSize size,
3081                     Register rd,
3082                     Register rn,
3083                     const Operand& operand) {
3084  VIXL_ASSERT(AllowAssembler());
3085  CheckIT(cond);
3086  if (operand.IsImmediate()) {
3087    uint32_t imm = operand.GetImmediate();
3088    if (IsUsingT32()) {
3089      ImmediateT32 immediate_t32(imm);
3090      // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3091      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3092        EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3093                   (immediate_t32.GetEncodingValue() & 0xff) |
3094                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3095                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3096        AdvanceIT();
3097        return;
3098      }
3099    } else {
3100      ImmediateA32 immediate_a32(imm);
3101      // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3102      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3103        EmitA32(0x03d00000U | (cond.GetCondition() << 28) |
3104                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3105                immediate_a32.GetEncodingValue());
3106        return;
3107      }
3108    }
3109  }
3110  if (operand.IsImmediateShiftedRegister()) {
3111    Register rm = operand.GetBaseRegister();
3112    if (operand.IsPlainRegister()) {
3113      if (IsUsingT32()) {
3114        // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3115        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3116            rm.IsLow()) {
3117          EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3118          AdvanceIT();
3119          return;
3120        }
3121      }
3122    }
3123    Shift shift = operand.GetShift();
3124    uint32_t amount = operand.GetShiftAmount();
3125    if (IsUsingT32()) {
3126      // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3127      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3128        uint32_t amount_ = amount % 32;
3129        EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3130                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3131                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3132        AdvanceIT();
3133        return;
3134      }
3135    } else {
3136      // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3137      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3138        uint32_t amount_ = amount % 32;
3139        EmitA32(0x01d00000U | (cond.GetCondition() << 28) |
3140                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3141                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3142        return;
3143      }
3144    }
3145  }
3146  if (operand.IsRegisterShiftedRegister()) {
3147    Register rm = operand.GetBaseRegister();
3148    Shift shift = operand.GetShift();
3149    if (IsUsingA32()) {
3150      // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3151      if (cond.IsNotNever()) {
3152        EmitA32(0x01d00010U | (cond.GetCondition() << 28) |
3153                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3154                (shift.GetType() << 5) |
3155                (operand.GetShiftRegister().GetCode() << 8));
3156        return;
3157      }
3158    }
3159  }
3160  Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand);
3161}
3162
3163void Assembler::bkpt(Condition cond, uint32_t imm) {
3164  VIXL_ASSERT(AllowAssembler());
3165  CheckIT(cond);
3166  if (IsUsingT32()) {
3167    // BKPT{<q>} {#}<imm> ; T1
3168    if ((imm <= 255)) {
3169      EmitT32_16(0xbe00 | imm);
3170      AdvanceIT();
3171      return;
3172    }
3173  } else {
3174    // BKPT{<q>} {#}<imm> ; A1
3175    if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
3176      EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) |
3177              ((imm & 0xfff0) << 4));
3178      return;
3179    }
3180  }
3181  Delegate(kBkpt, &Assembler::bkpt, cond, imm);
3182}
3183
3184void Assembler::bl(Condition cond, Label* label) {
3185  VIXL_ASSERT(AllowAssembler());
3186  CheckIT(cond);
3187  Label::Offset offset =
3188      label->IsBound()
3189          ? label->GetLocation() -
3190                (GetCursorOffset() + GetArchitectureStatePCOffset())
3191          : 0;
3192  if (IsUsingT32()) {
3193    // BL{<c>}{<q>} <label> ; T1
3194    if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) &&
3195          ((offset & 0x1) == 0)) ||
3196         !label->IsBound())) {
3197      static class EmitOp : public Label::LabelEmitOperator {
3198       public:
3199        EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {}
3200        virtual uint32_t Encode(uint32_t instr,
3201                                Label::Offset pc,
3202                                const Label* label) const VIXL_OVERRIDE {
3203          Label::Offset offset = label->GetLocation() - pc;
3204          VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
3205                      ((offset & 0x1) == 0));
3206          int32_t target = offset >> 1;
3207          uint32_t S = target & (1 << 23);
3208          target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
3209          return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
3210                 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
3211                 ((target & 0x800000) << 3);
3212        }
3213      } immop;
3214      EmitT32_32(Link(0xf000d000U, label, immop));
3215      AdvanceIT();
3216      return;
3217    }
3218  } else {
3219    // BL{<c>}{<q>} <label> ; A1
3220    if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) &&
3221          ((offset & 0x3) == 0)) ||
3222         !label->IsBound()) &&
3223        cond.IsNotNever()) {
3224      static class EmitOp : public Label::LabelEmitOperator {
3225       public:
3226        EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {}
3227        virtual uint32_t Encode(uint32_t instr,
3228                                Label::Offset pc,
3229                                const Label* label) const VIXL_OVERRIDE {
3230          Label::Offset offset = label->GetLocation() - pc;
3231          VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
3232                      ((offset & 0x3) == 0));
3233          const int32_t target = offset >> 2;
3234          return instr | (target & 0xffffff);
3235        }
3236      } immop;
3237      EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28), label, immop));
3238      return;
3239    }
3240  }
3241  Delegate(kBl, &Assembler::bl, cond, label);
3242}
3243
3244void Assembler::blx(Condition cond, Label* label) {
3245  VIXL_ASSERT(AllowAssembler());
3246  CheckIT(cond);
3247  Label::Offset offset =
3248      label->IsBound()
3249          ? label->GetLocation() -
3250                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
3251          : 0;
3252  if (IsUsingT32()) {
3253    // BLX{<c>}{<q>} <label> ; T2
3254    if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777212) &&
3255          ((offset & 0x3) == 0)) ||
3256         !label->IsBound())) {
3257      static class EmitOp : public Label::LabelEmitOperator {
3258       public:
3259        EmitOp() : Label::LabelEmitOperator(-16777216, 16777212) {}
3260        virtual uint32_t Encode(uint32_t instr,
3261                                Label::Offset pc,
3262                                const Label* label) const VIXL_OVERRIDE {
3263          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
3264          VIXL_ASSERT((offset >= -16777216) && (offset <= 16777212) &&
3265                      ((offset & 0x3) == 0));
3266          int32_t target = offset >> 2;
3267          uint32_t S = target & (1 << 22);
3268          target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20);
3269          return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) |
3270                 ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) |
3271                 ((target & 0x400000) << 4);
3272        }
3273      } immop;
3274      EmitT32_32(Link(0xf000c000U, label, immop));
3275      AdvanceIT();
3276      return;
3277    }
3278  } else {
3279    // BLX{<c>}{<q>} <label> ; A2
3280    if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554430) &&
3281          ((offset & 0x1) == 0)) ||
3282         !label->IsBound())) {
3283      if (cond.Is(al) || AllowStronglyDiscouraged()) {
3284        static class EmitOp : public Label::LabelEmitOperator {
3285         public:
3286          EmitOp() : Label::LabelEmitOperator(-33554432, 33554430) {}
3287          virtual uint32_t Encode(uint32_t instr,
3288                                  Label::Offset pc,
3289                                  const Label* label) const VIXL_OVERRIDE {
3290            Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
3291            VIXL_ASSERT((offset >= -33554432) && (offset <= 33554430) &&
3292                        ((offset & 0x1) == 0));
3293            const int32_t target = offset >> 1;
3294            return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1);
3295          }
3296        } immop;
3297        EmitA32(Link(0xfa000000U, label, immop));
3298        return;
3299      }
3300    }
3301  }
3302  Delegate(kBlx, &Assembler::blx, cond, label);
3303}
3304
3305void Assembler::blx(Condition cond, Register rm) {
3306  VIXL_ASSERT(AllowAssembler());
3307  CheckIT(cond);
3308  if (IsUsingT32()) {
3309    // BLX{<c>}{<q>} <Rm> ; T1
3310    EmitT32_16(0x4780 | (rm.GetCode() << 3));
3311    AdvanceIT();
3312    return;
3313  } else {
3314    // BLX{<c>}{<q>} <Rm> ; A1
3315    if (cond.IsNotNever()) {
3316      EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode());
3317      return;
3318    }
3319  }
3320  Delegate(kBlx, &Assembler::blx, cond, rm);
3321}
3322
3323void Assembler::bx(Condition cond, Register rm) {
3324  VIXL_ASSERT(AllowAssembler());
3325  CheckIT(cond);
3326  if (IsUsingT32()) {
3327    // BX{<c>}{<q>} <Rm> ; T1
3328    EmitT32_16(0x4700 | (rm.GetCode() << 3));
3329    AdvanceIT();
3330    return;
3331  } else {
3332    // BX{<c>}{<q>} <Rm> ; A1
3333    if (cond.IsNotNever()) {
3334      EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode());
3335      return;
3336    }
3337  }
3338  Delegate(kBx, &Assembler::bx, cond, rm);
3339}
3340
3341void Assembler::bxj(Condition cond, Register rm) {
3342  VIXL_ASSERT(AllowAssembler());
3343  CheckIT(cond);
3344  if (IsUsingT32()) {
3345    // BXJ{<c>}{<q>} <Rm> ; T1
3346    EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16));
3347    AdvanceIT();
3348    return;
3349  } else {
3350    // BXJ{<c>}{<q>} <Rm> ; A1
3351    if (cond.IsNotNever()) {
3352      EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode());
3353      return;
3354    }
3355  }
3356  Delegate(kBxj, &Assembler::bxj, cond, rm);
3357}
3358
3359void Assembler::cbnz(Register rn, Label* label) {
3360  VIXL_ASSERT(AllowAssembler());
3361  CheckIT(al);
3362  Label::Offset offset =
3363      label->IsBound()
3364          ? label->GetLocation() -
3365                (GetCursorOffset() + GetArchitectureStatePCOffset())
3366          : 0;
3367  if (IsUsingT32()) {
3368    // CBNZ{<q>} <Rn>, <label> ; T1
3369    if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) &&
3370                        ((offset & 0x1) == 0)) ||
3371                       !label->IsBound())) {
3372      static class EmitOp : public Label::LabelEmitOperator {
3373       public:
3374        EmitOp() : Label::LabelEmitOperator(0, 126) {}
3375        virtual uint32_t Encode(uint32_t instr,
3376                                Label::Offset pc,
3377                                const Label* label) const VIXL_OVERRIDE {
3378          Label::Offset offset = label->GetLocation() - pc;
3379          VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
3380                      ((offset & 0x1) == 0));
3381          const int32_t target = offset >> 1;
3382          return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3383        }
3384      } immop;
3385      EmitT32_16(Link(0xb900 | rn.GetCode(), label, immop));
3386      AdvanceIT();
3387      return;
3388    }
3389  }
3390  Delegate(kCbnz, &Assembler::cbnz, rn, label);
3391}
3392
3393void Assembler::cbz(Register rn, Label* label) {
3394  VIXL_ASSERT(AllowAssembler());
3395  CheckIT(al);
3396  Label::Offset offset =
3397      label->IsBound()
3398          ? label->GetLocation() -
3399                (GetCursorOffset() + GetArchitectureStatePCOffset())
3400          : 0;
3401  if (IsUsingT32()) {
3402    // CBZ{<q>} <Rn>, <label> ; T1
3403    if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) &&
3404                        ((offset & 0x1) == 0)) ||
3405                       !label->IsBound())) {
3406      static class EmitOp : public Label::LabelEmitOperator {
3407       public:
3408        EmitOp() : Label::LabelEmitOperator(0, 126) {}
3409        virtual uint32_t Encode(uint32_t instr,
3410                                Label::Offset pc,
3411                                const Label* label) const VIXL_OVERRIDE {
3412          Label::Offset offset = label->GetLocation() - pc;
3413          VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
3414                      ((offset & 0x1) == 0));
3415          const int32_t target = offset >> 1;
3416          return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3417        }
3418      } immop;
3419      EmitT32_16(Link(0xb100 | rn.GetCode(), label, immop));
3420      AdvanceIT();
3421      return;
3422    }
3423  }
3424  Delegate(kCbz, &Assembler::cbz, rn, label);
3425}
3426
3427void Assembler::clrex(Condition cond) {
3428  VIXL_ASSERT(AllowAssembler());
3429  CheckIT(cond);
3430  if (IsUsingT32()) {
3431    // CLREX{<c>}{<q>} ; T1
3432    EmitT32_32(0xf3bf8f2fU);
3433    AdvanceIT();
3434    return;
3435  } else {
3436    // CLREX{<c>}{<q>} ; A1
3437    if (cond.Is(al)) {
3438      EmitA32(0xf57ff01fU);
3439      return;
3440    }
3441  }
3442  Delegate(kClrex, &Assembler::clrex, cond);
3443}
3444
3445void Assembler::clz(Condition cond, Register rd, Register rm) {
3446  VIXL_ASSERT(AllowAssembler());
3447  CheckIT(cond);
3448  if (IsUsingT32()) {
3449    // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1
3450    EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() |
3451               (rm.GetCode() << 16));
3452    AdvanceIT();
3453    return;
3454  } else {
3455    // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1
3456    if (cond.IsNotNever()) {
3457      EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3458              rm.GetCode());
3459      return;
3460    }
3461  }
3462  Delegate(kClz, &Assembler::clz, cond, rd, rm);
3463}
3464
3465void Assembler::cmn(Condition cond,
3466                    EncodingSize size,
3467                    Register rn,
3468                    const Operand& operand) {
3469  VIXL_ASSERT(AllowAssembler());
3470  CheckIT(cond);
3471  if (operand.IsImmediate()) {
3472    uint32_t imm = operand.GetImmediate();
3473    if (IsUsingT32()) {
3474      ImmediateT32 immediate_t32(imm);
3475      // CMN{<c>}{<q>} <Rn>, #<const> ; T1
3476      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3477        EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) |
3478                   (immediate_t32.GetEncodingValue() & 0xff) |
3479                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3480                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3481        AdvanceIT();
3482        return;
3483      }
3484    } else {
3485      ImmediateA32 immediate_a32(imm);
3486      // CMN{<c>}{<q>} <Rn>, #<const> ; A1
3487      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3488        EmitA32(0x03700000U | (cond.GetCondition() << 28) |
3489                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3490        return;
3491      }
3492    }
3493  }
3494  if (operand.IsImmediateShiftedRegister()) {
3495    Register rm = operand.GetBaseRegister();
3496    if (operand.IsPlainRegister()) {
3497      if (IsUsingT32()) {
3498        // CMN{<c>}{<q>} <Rn>, <Rm> ; T1
3499        if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3500          EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3));
3501          AdvanceIT();
3502          return;
3503        }
3504      }
3505    }
3506    Shift shift = operand.GetShift();
3507    uint32_t amount = operand.GetShiftAmount();
3508    if (IsUsingT32()) {
3509      // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
3510      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3511        uint32_t amount_ = amount % 32;
3512        EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() |
3513                   (operand.GetTypeEncodingValue() << 4) |
3514                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3515        AdvanceIT();
3516        return;
3517      }
3518    } else {
3519      // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3520      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3521        uint32_t amount_ = amount % 32;
3522        EmitA32(0x01700000U | (cond.GetCondition() << 28) |
3523                (rn.GetCode() << 16) | rm.GetCode() |
3524                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3525        return;
3526      }
3527    }
3528  }
3529  if (operand.IsRegisterShiftedRegister()) {
3530    Register rm = operand.GetBaseRegister();
3531    Shift shift = operand.GetShift();
3532    if (IsUsingA32()) {
3533      // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3534      if (cond.IsNotNever()) {
3535        EmitA32(0x01700010U | (cond.GetCondition() << 28) |
3536                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3537                (operand.GetShiftRegister().GetCode() << 8));
3538        return;
3539      }
3540    }
3541  }
3542  Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand);
3543}
3544
3545void Assembler::cmp(Condition cond,
3546                    EncodingSize size,
3547                    Register rn,
3548                    const Operand& operand) {
3549  VIXL_ASSERT(AllowAssembler());
3550  CheckIT(cond);
3551  if (operand.IsImmediate()) {
3552    uint32_t imm = operand.GetImmediate();
3553    if (IsUsingT32()) {
3554      ImmediateT32 immediate_t32(imm);
3555      // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1
3556      if (!size.IsWide() && rn.IsLow() && (imm <= 255)) {
3557        EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm);
3558        AdvanceIT();
3559        return;
3560      }
3561      // CMP{<c>}{<q>} <Rn>, #<const> ; T2
3562      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3563        EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) |
3564                   (immediate_t32.GetEncodingValue() & 0xff) |
3565                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3566                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3567        AdvanceIT();
3568        return;
3569      }
3570    } else {
3571      ImmediateA32 immediate_a32(imm);
3572      // CMP{<c>}{<q>} <Rn>, #<const> ; A1
3573      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3574        EmitA32(0x03500000U | (cond.GetCondition() << 28) |
3575                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3576        return;
3577      }
3578    }
3579  }
3580  if (operand.IsImmediateShiftedRegister()) {
3581    Register rm = operand.GetBaseRegister();
3582    if (operand.IsPlainRegister()) {
3583      if (IsUsingT32()) {
3584        // CMP{<c>}{<q>} <Rn>, <Rm> ; T1
3585        if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3586          EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3));
3587          AdvanceIT();
3588          return;
3589        }
3590        // CMP{<c>}{<q>} <Rn>, <Rm> ; T2
3591        if (!size.IsWide()) {
3592          EmitT32_16(0x4500 | (rn.GetCode() & 0x7) |
3593                     ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
3594          AdvanceIT();
3595          return;
3596        }
3597      }
3598    }
3599    Shift shift = operand.GetShift();
3600    uint32_t amount = operand.GetShiftAmount();
3601    if (IsUsingT32()) {
3602      // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3
3603      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3604        uint32_t amount_ = amount % 32;
3605        EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() |
3606                   (operand.GetTypeEncodingValue() << 4) |
3607                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3608        AdvanceIT();
3609        return;
3610      }
3611    } else {
3612      // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3613      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3614        uint32_t amount_ = amount % 32;
3615        EmitA32(0x01500000U | (cond.GetCondition() << 28) |
3616                (rn.GetCode() << 16) | rm.GetCode() |
3617                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3618        return;
3619      }
3620    }
3621  }
3622  if (operand.IsRegisterShiftedRegister()) {
3623    Register rm = operand.GetBaseRegister();
3624    Shift shift = operand.GetShift();
3625    if (IsUsingA32()) {
3626      // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3627      if (cond.IsNotNever()) {
3628        EmitA32(0x01500010U | (cond.GetCondition() << 28) |
3629                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3630                (operand.GetShiftRegister().GetCode() << 8));
3631        return;
3632      }
3633    }
3634  }
3635  Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand);
3636}
3637
3638void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) {
3639  VIXL_ASSERT(AllowAssembler());
3640  CheckIT(cond);
3641  if (IsUsingT32()) {
3642    // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1
3643    EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3644               rm.GetCode());
3645    AdvanceIT();
3646    return;
3647  } else {
3648    // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1
3649    if ((cond.Is(al) || AllowUnpredictable())) {
3650      EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3651              (rn.GetCode() << 16) | rm.GetCode());
3652      return;
3653    }
3654  }
3655  Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm);
3656}
3657
3658void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) {
3659  VIXL_ASSERT(AllowAssembler());
3660  CheckIT(cond);
3661  if (IsUsingT32()) {
3662    // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1
3663    EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3664               rm.GetCode());
3665    AdvanceIT();
3666    return;
3667  } else {
3668    // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1
3669    if ((cond.Is(al) || AllowUnpredictable())) {
3670      EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3671              (rn.GetCode() << 16) | rm.GetCode());
3672      return;
3673    }
3674  }
3675  Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm);
3676}
3677
3678void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) {
3679  VIXL_ASSERT(AllowAssembler());
3680  CheckIT(cond);
3681  if (IsUsingT32()) {
3682    // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1
3683    EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3684               rm.GetCode());
3685    AdvanceIT();
3686    return;
3687  } else {
3688    // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1
3689    if ((cond.Is(al) || AllowUnpredictable())) {
3690      EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3691              (rn.GetCode() << 16) | rm.GetCode());
3692      return;
3693    }
3694  }
3695  Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm);
3696}
3697
3698void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) {
3699  VIXL_ASSERT(AllowAssembler());
3700  CheckIT(cond);
3701  if (IsUsingT32()) {
3702    // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1
3703    EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3704               rm.GetCode());
3705    AdvanceIT();
3706    return;
3707  } else {
3708    // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1
3709    if ((cond.Is(al) || AllowUnpredictable())) {
3710      EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3711              (rn.GetCode() << 16) | rm.GetCode());
3712      return;
3713    }
3714  }
3715  Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm);
3716}
3717
3718void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) {
3719  VIXL_ASSERT(AllowAssembler());
3720  CheckIT(cond);
3721  if (IsUsingT32()) {
3722    // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1
3723    EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3724               rm.GetCode());
3725    AdvanceIT();
3726    return;
3727  } else {
3728    // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1
3729    if ((cond.Is(al) || AllowUnpredictable())) {
3730      EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3731              (rn.GetCode() << 16) | rm.GetCode());
3732      return;
3733    }
3734  }
3735  Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm);
3736}
3737
3738void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) {
3739  VIXL_ASSERT(AllowAssembler());
3740  CheckIT(cond);
3741  if (IsUsingT32()) {
3742    // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1
3743    EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3744               rm.GetCode());
3745    AdvanceIT();
3746    return;
3747  } else {
3748    // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1
3749    if ((cond.Is(al) || AllowUnpredictable())) {
3750      EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3751              (rn.GetCode() << 16) | rm.GetCode());
3752      return;
3753    }
3754  }
3755  Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm);
3756}
3757
3758void Assembler::dmb(Condition cond, MemoryBarrier option) {
3759  VIXL_ASSERT(AllowAssembler());
3760  CheckIT(cond);
3761  if (IsUsingT32()) {
3762    // DMB{<c>}{<q>} {<option>} ; T1
3763    EmitT32_32(0xf3bf8f50U | option.GetType());
3764    AdvanceIT();
3765    return;
3766  } else {
3767    // DMB{<c>}{<q>} {<option>} ; A1
3768    if (cond.Is(al)) {
3769      EmitA32(0xf57ff050U | option.GetType());
3770      return;
3771    }
3772  }
3773  Delegate(kDmb, &Assembler::dmb, cond, option);
3774}
3775
3776void Assembler::dsb(Condition cond, MemoryBarrier option) {
3777  VIXL_ASSERT(AllowAssembler());
3778  CheckIT(cond);
3779  if (IsUsingT32()) {
3780    // DSB{<c>}{<q>} {<option>} ; T1
3781    EmitT32_32(0xf3bf8f40U | option.GetType());
3782    AdvanceIT();
3783    return;
3784  } else {
3785    // DSB{<c>}{<q>} {<option>} ; A1
3786    if (cond.Is(al)) {
3787      EmitA32(0xf57ff040U | option.GetType());
3788      return;
3789    }
3790  }
3791  Delegate(kDsb, &Assembler::dsb, cond, option);
3792}
3793
3794void Assembler::eor(Condition cond,
3795                    EncodingSize size,
3796                    Register rd,
3797                    Register rn,
3798                    const Operand& operand) {
3799  VIXL_ASSERT(AllowAssembler());
3800  CheckIT(cond);
3801  if (operand.IsImmediate()) {
3802    uint32_t imm = operand.GetImmediate();
3803    if (IsUsingT32()) {
3804      ImmediateT32 immediate_t32(imm);
3805      // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3806      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3807        EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3808                   (immediate_t32.GetEncodingValue() & 0xff) |
3809                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3810                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3811        AdvanceIT();
3812        return;
3813      }
3814    } else {
3815      ImmediateA32 immediate_a32(imm);
3816      // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3817      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3818        EmitA32(0x02200000U | (cond.GetCondition() << 28) |
3819                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3820                immediate_a32.GetEncodingValue());
3821        return;
3822      }
3823    }
3824  }
3825  if (operand.IsImmediateShiftedRegister()) {
3826    Register rm = operand.GetBaseRegister();
3827    if (operand.IsPlainRegister()) {
3828      if (IsUsingT32()) {
3829        // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3830        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3831            rm.IsLow()) {
3832          EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
3833          AdvanceIT();
3834          return;
3835        }
3836      }
3837    }
3838    Shift shift = operand.GetShift();
3839    uint32_t amount = operand.GetShiftAmount();
3840    if (IsUsingT32()) {
3841      // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3842      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3843        uint32_t amount_ = amount % 32;
3844        EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3845                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3846                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3847        AdvanceIT();
3848        return;
3849      }
3850    } else {
3851      // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3852      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3853        uint32_t amount_ = amount % 32;
3854        EmitA32(0x00200000U | (cond.GetCondition() << 28) |
3855                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3856                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3857        return;
3858      }
3859    }
3860  }
3861  if (operand.IsRegisterShiftedRegister()) {
3862    Register rm = operand.GetBaseRegister();
3863    Shift shift = operand.GetShift();
3864    if (IsUsingA32()) {
3865      // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3866      if (cond.IsNotNever()) {
3867        EmitA32(0x00200010U | (cond.GetCondition() << 28) |
3868                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3869                (shift.GetType() << 5) |
3870                (operand.GetShiftRegister().GetCode() << 8));
3871        return;
3872      }
3873    }
3874  }
3875  Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand);
3876}
3877
3878void Assembler::eors(Condition cond,
3879                     EncodingSize size,
3880                     Register rd,
3881                     Register rn,
3882                     const Operand& operand) {
3883  VIXL_ASSERT(AllowAssembler());
3884  CheckIT(cond);
3885  if (operand.IsImmediate()) {
3886    uint32_t imm = operand.GetImmediate();
3887    if (IsUsingT32()) {
3888      ImmediateT32 immediate_t32(imm);
3889      // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3890      if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) {
3891        EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3892                   (immediate_t32.GetEncodingValue() & 0xff) |
3893                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3894                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3895        AdvanceIT();
3896        return;
3897      }
3898    } else {
3899      ImmediateA32 immediate_a32(imm);
3900      // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3901      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3902        EmitA32(0x02300000U | (cond.GetCondition() << 28) |
3903                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3904                immediate_a32.GetEncodingValue());
3905        return;
3906      }
3907    }
3908  }
3909  if (operand.IsImmediateShiftedRegister()) {
3910    Register rm = operand.GetBaseRegister();
3911    if (operand.IsPlainRegister()) {
3912      if (IsUsingT32()) {
3913        // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3914        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3915            rm.IsLow()) {
3916          EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
3917          AdvanceIT();
3918          return;
3919        }
3920      }
3921    }
3922    Shift shift = operand.GetShift();
3923    uint32_t amount = operand.GetShiftAmount();
3924    if (IsUsingT32()) {
3925      // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3926      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) {
3927        uint32_t amount_ = amount % 32;
3928        EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3929                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3930                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3931        AdvanceIT();
3932        return;
3933      }
3934    } else {
3935      // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3936      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3937        uint32_t amount_ = amount % 32;
3938        EmitA32(0x00300000U | (cond.GetCondition() << 28) |
3939                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3940                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3941        return;
3942      }
3943    }
3944  }
3945  if (operand.IsRegisterShiftedRegister()) {
3946    Register rm = operand.GetBaseRegister();
3947    Shift shift = operand.GetShift();
3948    if (IsUsingA32()) {
3949      // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3950      if (cond.IsNotNever()) {
3951        EmitA32(0x00300010U | (cond.GetCondition() << 28) |
3952                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3953                (shift.GetType() << 5) |
3954                (operand.GetShiftRegister().GetCode() << 8));
3955        return;
3956      }
3957    }
3958  }
3959  Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand);
3960}
3961
3962void Assembler::fldmdbx(Condition cond,
3963                        Register rn,
3964                        WriteBack write_back,
3965                        DRegisterList dreglist) {
3966  VIXL_ASSERT(AllowAssembler());
3967  CheckIT(cond);
3968  if (IsUsingT32()) {
3969    // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
3970    if (write_back.DoesWriteBack() &&
3971        (((dreglist.GetLength() <= 16) &&
3972          (dreglist.GetLastDRegister().GetCode() < 16)) ||
3973         AllowUnpredictable())) {
3974      const DRegister& dreg = dreglist.GetFirstDRegister();
3975      unsigned len = dreglist.GetLength() * 2;
3976      EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
3977                 (len & 0xff));
3978      AdvanceIT();
3979      return;
3980    }
3981  } else {
3982    // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
3983    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
3984        (((dreglist.GetLength() <= 16) &&
3985          (dreglist.GetLastDRegister().GetCode() < 16)) ||
3986         AllowUnpredictable())) {
3987      const DRegister& dreg = dreglist.GetFirstDRegister();
3988      unsigned len = dreglist.GetLength() * 2;
3989      EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
3990              dreg.Encode(22, 12) | (len & 0xff));
3991      return;
3992    }
3993  }
3994  Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist);
3995}
3996
3997void Assembler::fldmiax(Condition cond,
3998                        Register rn,
3999                        WriteBack write_back,
4000                        DRegisterList dreglist) {
4001  VIXL_ASSERT(AllowAssembler());
4002  CheckIT(cond);
4003  if (IsUsingT32()) {
4004    // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
4005    if ((((dreglist.GetLength() <= 16) &&
4006          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4007         AllowUnpredictable())) {
4008      const DRegister& dreg = dreglist.GetFirstDRegister();
4009      unsigned len = dreglist.GetLength() * 2;
4010      EmitT32_32(0xec900b01U | (rn.GetCode() << 16) |
4011                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4012                 (len & 0xff));
4013      AdvanceIT();
4014      return;
4015    }
4016  } else {
4017    // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
4018    if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
4019                               (dreglist.GetLastDRegister().GetCode() < 16)) ||
4020                              AllowUnpredictable())) {
4021      const DRegister& dreg = dreglist.GetFirstDRegister();
4022      unsigned len = dreglist.GetLength() * 2;
4023      EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4024              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4025              (len & 0xff));
4026      return;
4027    }
4028  }
4029  Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist);
4030}
4031
4032void Assembler::fstmdbx(Condition cond,
4033                        Register rn,
4034                        WriteBack write_back,
4035                        DRegisterList dreglist) {
4036  VIXL_ASSERT(AllowAssembler());
4037  CheckIT(cond);
4038  if (IsUsingT32()) {
4039    // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
4040    if (write_back.DoesWriteBack() &&
4041        (((dreglist.GetLength() <= 16) &&
4042          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4043         AllowUnpredictable())) {
4044      const DRegister& dreg = dreglist.GetFirstDRegister();
4045      unsigned len = dreglist.GetLength() * 2;
4046      EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
4047                 (len & 0xff));
4048      AdvanceIT();
4049      return;
4050    }
4051  } else {
4052    // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
4053    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
4054        (((dreglist.GetLength() <= 16) &&
4055          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4056         AllowUnpredictable())) {
4057      const DRegister& dreg = dreglist.GetFirstDRegister();
4058      unsigned len = dreglist.GetLength() * 2;
4059      EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4060              dreg.Encode(22, 12) | (len & 0xff));
4061      return;
4062    }
4063  }
4064  Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist);
4065}
4066
4067void Assembler::fstmiax(Condition cond,
4068                        Register rn,
4069                        WriteBack write_back,
4070                        DRegisterList dreglist) {
4071  VIXL_ASSERT(AllowAssembler());
4072  CheckIT(cond);
4073  if (IsUsingT32()) {
4074    // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
4075    if ((((dreglist.GetLength() <= 16) &&
4076          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4077         AllowUnpredictable())) {
4078      const DRegister& dreg = dreglist.GetFirstDRegister();
4079      unsigned len = dreglist.GetLength() * 2;
4080      EmitT32_32(0xec800b01U | (rn.GetCode() << 16) |
4081                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4082                 (len & 0xff));
4083      AdvanceIT();
4084      return;
4085    }
4086  } else {
4087    // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
4088    if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
4089                               (dreglist.GetLastDRegister().GetCode() < 16)) ||
4090                              AllowUnpredictable())) {
4091      const DRegister& dreg = dreglist.GetFirstDRegister();
4092      unsigned len = dreglist.GetLength() * 2;
4093      EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4094              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4095              (len & 0xff));
4096      return;
4097    }
4098  }
4099  Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist);
4100}
4101
4102void Assembler::hlt(Condition cond, uint32_t imm) {
4103  VIXL_ASSERT(AllowAssembler());
4104  CheckIT(cond);
4105  if (IsUsingT32()) {
4106    // HLT{<q>} {#}<imm> ; T1
4107    if ((imm <= 63)) {
4108      EmitT32_16(0xba80 | imm);
4109      AdvanceIT();
4110      return;
4111    }
4112  } else {
4113    // HLT{<q>} {#}<imm> ; A1
4114    if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4115      EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4116              ((imm & 0xfff0) << 4));
4117      return;
4118    }
4119  }
4120  Delegate(kHlt, &Assembler::hlt, cond, imm);
4121}
4122
4123void Assembler::hvc(Condition cond, uint32_t imm) {
4124  VIXL_ASSERT(AllowAssembler());
4125  CheckIT(cond);
4126  if (IsUsingT32()) {
4127    // HVC{<q>} {#}<imm16> ; T1
4128    if ((imm <= 65535)) {
4129      EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
4130      AdvanceIT();
4131      return;
4132    }
4133  } else {
4134    // HVC{<q>} {#}<imm16> ; A1
4135    if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4136      EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4137              ((imm & 0xfff0) << 4));
4138      return;
4139    }
4140  }
4141  Delegate(kHvc, &Assembler::hvc, cond, imm);
4142}
4143
4144void Assembler::isb(Condition cond, MemoryBarrier option) {
4145  VIXL_ASSERT(AllowAssembler());
4146  CheckIT(cond);
4147  if (IsUsingT32()) {
4148    // ISB{<c>}{<q>} {<option>} ; T1
4149    EmitT32_32(0xf3bf8f60U | option.GetType());
4150    AdvanceIT();
4151    return;
4152  } else {
4153    // ISB{<c>}{<q>} {<option>} ; A1
4154    if (cond.Is(al)) {
4155      EmitA32(0xf57ff060U | option.GetType());
4156      return;
4157    }
4158  }
4159  Delegate(kIsb, &Assembler::isb, cond, option);
4160}
4161
4162void Assembler::it(Condition cond, uint16_t mask) {
4163  VIXL_ASSERT(AllowAssembler());
4164  CheckNotIT();
4165  if (mask != 0) {
4166    if ((cond.GetCondition() & 0x1) != 0) {
4167      if ((mask & 0x1) != 0) {
4168        mask ^= 0xE;
4169      } else if ((mask & 0x2) != 0) {
4170        mask ^= 0xC;
4171      } else if ((mask & 0x4) != 0) {
4172        mask ^= 0x8;
4173      }
4174    }
4175    if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask);
4176    SetIT(cond, mask);
4177    return;
4178  }
4179  DelegateIt(cond, mask);
4180}
4181
4182void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) {
4183  VIXL_ASSERT(AllowAssembler());
4184  CheckIT(cond);
4185  if (operand.IsImmediateZero()) {
4186    Register rn = operand.GetBaseRegister();
4187    if (IsUsingT32()) {
4188      // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1
4189      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
4190        EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4191        AdvanceIT();
4192        return;
4193      }
4194    } else {
4195      // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1
4196      if (operand.IsOffset() && cond.IsNotNever() &&
4197          ((!rn.IsPC()) || AllowUnpredictable())) {
4198        EmitA32(0x01900c9fU | (cond.GetCondition() << 28) |
4199                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4200        return;
4201      }
4202    }
4203  }
4204  Delegate(kLda, &Assembler::lda, cond, rt, operand);
4205}
4206
4207void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) {
4208  VIXL_ASSERT(AllowAssembler());
4209  CheckIT(cond);
4210  if (operand.IsImmediateZero()) {
4211    Register rn = operand.GetBaseRegister();
4212    if (IsUsingT32()) {
4213      // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4214      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
4215        EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4216        AdvanceIT();
4217        return;
4218      }
4219    } else {
4220      // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4221      if (operand.IsOffset() && cond.IsNotNever() &&
4222          ((!rn.IsPC()) || AllowUnpredictable())) {
4223        EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) |
4224                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4225        return;
4226      }
4227    }
4228  }
4229  Delegate(kLdab, &Assembler::ldab, cond, rt, operand);
4230}
4231
4232void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) {
4233  VIXL_ASSERT(AllowAssembler());
4234  CheckIT(cond);
4235  if (operand.IsImmediateZero()) {
4236    Register rn = operand.GetBaseRegister();
4237    if (IsUsingT32()) {
4238      // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1
4239      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
4240        EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4241        AdvanceIT();
4242        return;
4243      }
4244    } else {
4245      // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1
4246      if (operand.IsOffset() && cond.IsNotNever() &&
4247          ((!rn.IsPC()) || AllowUnpredictable())) {
4248        EmitA32(0x01900e9fU | (cond.GetCondition() << 28) |
4249                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4250        return;
4251      }
4252    }
4253  }
4254  Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand);
4255}
4256
4257void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) {
4258  VIXL_ASSERT(AllowAssembler());
4259  CheckIT(cond);
4260  if (operand.IsImmediateZero()) {
4261    Register rn = operand.GetBaseRegister();
4262    if (IsUsingT32()) {
4263      // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4264      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
4265        EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4266        AdvanceIT();
4267        return;
4268      }
4269    } else {
4270      // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4271      if (operand.IsOffset() && cond.IsNotNever() &&
4272          ((!rn.IsPC()) || AllowUnpredictable())) {
4273        EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) |
4274                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4275        return;
4276      }
4277    }
4278  }
4279  Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand);
4280}
4281
4282void Assembler::ldaexd(Condition cond,
4283                       Register rt,
4284                       Register rt2,
4285                       const MemOperand& operand) {
4286  VIXL_ASSERT(AllowAssembler());
4287  CheckIT(cond);
4288  if (operand.IsImmediateZero()) {
4289    Register rn = operand.GetBaseRegister();
4290    if (IsUsingT32()) {
4291      // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
4292      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
4293        EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
4294                   (rn.GetCode() << 16));
4295        AdvanceIT();
4296        return;
4297      }
4298    } else {
4299      // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
4300      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
4301          operand.IsOffset() && cond.IsNotNever() &&
4302          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
4303           AllowUnpredictable())) {
4304        EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) |
4305                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4306        return;
4307      }
4308    }
4309  }
4310  Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand);
4311}
4312
4313void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) {
4314  VIXL_ASSERT(AllowAssembler());
4315  CheckIT(cond);
4316  if (operand.IsImmediateZero()) {
4317    Register rn = operand.GetBaseRegister();
4318    if (IsUsingT32()) {
4319      // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4320      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
4321        EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4322        AdvanceIT();
4323        return;
4324      }
4325    } else {
4326      // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4327      if (operand.IsOffset() && cond.IsNotNever() &&
4328          ((!rn.IsPC()) || AllowUnpredictable())) {
4329        EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) |
4330                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4331        return;
4332      }
4333    }
4334  }
4335  Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand);
4336}
4337
4338void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) {
4339  VIXL_ASSERT(AllowAssembler());
4340  CheckIT(cond);
4341  if (operand.IsImmediateZero()) {
4342    Register rn = operand.GetBaseRegister();
4343    if (IsUsingT32()) {
4344      // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4345      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
4346        EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4347        AdvanceIT();
4348        return;
4349      }
4350    } else {
4351      // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4352      if (operand.IsOffset() && cond.IsNotNever() &&
4353          ((!rn.IsPC()) || AllowUnpredictable())) {
4354        EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) |
4355                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4356        return;
4357      }
4358    }
4359  }
4360  Delegate(kLdah, &Assembler::ldah, cond, rt, operand);
4361}
4362
4363void Assembler::ldm(Condition cond,
4364                    EncodingSize size,
4365                    Register rn,
4366                    WriteBack write_back,
4367                    RegisterList registers) {
4368  VIXL_ASSERT(AllowAssembler());
4369  CheckIT(cond);
4370  if (IsUsingT32()) {
4371    // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1
4372    if (!size.IsWide() && rn.IsLow() &&
4373        (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4374         write_back.DoesWriteBack()) &&
4375        ((registers.GetList() & ~0xff) == 0)) {
4376      EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4377                 GetRegisterListEncoding(registers, 0, 8));
4378      AdvanceIT();
4379      return;
4380    }
4381    // LDM{<c>}{<q>} SP!, <registers> ; T1
4382    if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
4383        ((registers.GetList() & ~0x80ff) == 0)) {
4384      EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
4385                 GetRegisterListEncoding(registers, 0, 8));
4386      AdvanceIT();
4387      return;
4388    }
4389    // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2
4390    if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
4391      EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4392                 (write_back.GetWriteBackUint32() << 21) |
4393                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4394                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4395                 GetRegisterListEncoding(registers, 0, 13));
4396      AdvanceIT();
4397      return;
4398    }
4399  } else {
4400    // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1
4401    if (cond.IsNotNever()) {
4402      EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4403              (write_back.GetWriteBackUint32() << 21) |
4404              GetRegisterListEncoding(registers, 0, 16));
4405      return;
4406    }
4407  }
4408  Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers);
4409}
4410
4411void Assembler::ldmda(Condition cond,
4412                      Register rn,
4413                      WriteBack write_back,
4414                      RegisterList registers) {
4415  VIXL_ASSERT(AllowAssembler());
4416  CheckIT(cond);
4417  if (IsUsingA32()) {
4418    // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4419    if (cond.IsNotNever()) {
4420      EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4421              (write_back.GetWriteBackUint32() << 21) |
4422              GetRegisterListEncoding(registers, 0, 16));
4423      return;
4424    }
4425  }
4426  Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers);
4427}
4428
4429void Assembler::ldmdb(Condition cond,
4430                      Register rn,
4431                      WriteBack write_back,
4432                      RegisterList registers) {
4433  VIXL_ASSERT(AllowAssembler());
4434  CheckIT(cond);
4435  if (IsUsingT32()) {
4436    // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
4437    if (((registers.GetList() & ~0xdfff) == 0)) {
4438      EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4439                 (write_back.GetWriteBackUint32() << 21) |
4440                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4441                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4442                 GetRegisterListEncoding(registers, 0, 13));
4443      AdvanceIT();
4444      return;
4445    }
4446  } else {
4447    // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4448    if (cond.IsNotNever()) {
4449      EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4450              (write_back.GetWriteBackUint32() << 21) |
4451              GetRegisterListEncoding(registers, 0, 16));
4452      return;
4453    }
4454  }
4455  Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers);
4456}
4457
4458void Assembler::ldmea(Condition cond,
4459                      Register rn,
4460                      WriteBack write_back,
4461                      RegisterList registers) {
4462  VIXL_ASSERT(AllowAssembler());
4463  CheckIT(cond);
4464  if (IsUsingT32()) {
4465    // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1
4466    if (((registers.GetList() & ~0xdfff) == 0)) {
4467      EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4468                 (write_back.GetWriteBackUint32() << 21) |
4469                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4470                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4471                 GetRegisterListEncoding(registers, 0, 13));
4472      AdvanceIT();
4473      return;
4474    }
4475  } else {
4476    // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4477    if (cond.IsNotNever()) {
4478      EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4479              (write_back.GetWriteBackUint32() << 21) |
4480              GetRegisterListEncoding(registers, 0, 16));
4481      return;
4482    }
4483  }
4484  Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers);
4485}
4486
4487void Assembler::ldmed(Condition cond,
4488                      Register rn,
4489                      WriteBack write_back,
4490                      RegisterList registers) {
4491  VIXL_ASSERT(AllowAssembler());
4492  CheckIT(cond);
4493  if (IsUsingA32()) {
4494    // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
4495    if (cond.IsNotNever()) {
4496      EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4497              (write_back.GetWriteBackUint32() << 21) |
4498              GetRegisterListEncoding(registers, 0, 16));
4499      return;
4500    }
4501  }
4502  Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers);
4503}
4504
4505void Assembler::ldmfa(Condition cond,
4506                      Register rn,
4507                      WriteBack write_back,
4508                      RegisterList registers) {
4509  VIXL_ASSERT(AllowAssembler());
4510  CheckIT(cond);
4511  if (IsUsingA32()) {
4512    // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4513    if (cond.IsNotNever()) {
4514      EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4515              (write_back.GetWriteBackUint32() << 21) |
4516              GetRegisterListEncoding(registers, 0, 16));
4517      return;
4518    }
4519  }
4520  Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers);
4521}
4522
4523void Assembler::ldmfd(Condition cond,
4524                      EncodingSize size,
4525                      Register rn,
4526                      WriteBack write_back,
4527                      RegisterList registers) {
4528  VIXL_ASSERT(AllowAssembler());
4529  CheckIT(cond);
4530  if (IsUsingT32()) {
4531    // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
4532    if (!size.IsWide() && rn.IsLow() &&
4533        (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4534         write_back.DoesWriteBack()) &&
4535        ((registers.GetList() & ~0xff) == 0)) {
4536      EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4537                 GetRegisterListEncoding(registers, 0, 8));
4538      AdvanceIT();
4539      return;
4540    }
4541    // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2
4542    if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
4543      EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4544                 (write_back.GetWriteBackUint32() << 21) |
4545                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4546                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4547                 GetRegisterListEncoding(registers, 0, 13));
4548      AdvanceIT();
4549      return;
4550    }
4551  } else {
4552    // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
4553    if (cond.IsNotNever()) {
4554      EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4555              (write_back.GetWriteBackUint32() << 21) |
4556              GetRegisterListEncoding(registers, 0, 16));
4557      return;
4558    }
4559  }
4560  Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers);
4561}
4562
4563void Assembler::ldmib(Condition cond,
4564                      Register rn,
4565                      WriteBack write_back,
4566                      RegisterList registers) {
4567  VIXL_ASSERT(AllowAssembler());
4568  CheckIT(cond);
4569  if (IsUsingA32()) {
4570    // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4571    if (cond.IsNotNever()) {
4572      EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4573              (write_back.GetWriteBackUint32() << 21) |
4574              GetRegisterListEncoding(registers, 0, 16));
4575      return;
4576    }
4577  }
4578  Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers);
4579}
4580
4581void Assembler::ldr(Condition cond,
4582                    EncodingSize size,
4583                    Register rt,
4584                    const MemOperand& operand) {
4585  VIXL_ASSERT(AllowAssembler());
4586  CheckIT(cond);
4587  if (operand.IsImmediate()) {
4588    Register rn = operand.GetBaseRegister();
4589    int32_t offset = operand.GetOffsetImmediate();
4590    if (IsUsingT32()) {
4591      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
4592      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
4593          (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
4594        int32_t offset_ = offset >> 2;
4595        EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) |
4596                   ((offset_ & 0x1f) << 6));
4597        AdvanceIT();
4598        return;
4599      }
4600      // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
4601      if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
4602          ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
4603        int32_t offset_ = offset >> 2;
4604        EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff));
4605        AdvanceIT();
4606        return;
4607      }
4608      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
4609      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
4610          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
4611        EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4612                   (offset & 0xfff));
4613        AdvanceIT();
4614        return;
4615      }
4616      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
4617      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
4618          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
4619        EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4620                   (-offset & 0xff));
4621        AdvanceIT();
4622        return;
4623      }
4624      // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
4625      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4626          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4627        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4628        uint32_t offset_ = abs(offset);
4629        EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4630                   offset_ | (sign << 9));
4631        AdvanceIT();
4632        return;
4633      }
4634      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
4635      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4636          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4637        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4638        uint32_t offset_ = abs(offset);
4639        EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4640                   offset_ | (sign << 9));
4641        AdvanceIT();
4642        return;
4643      }
4644      // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2
4645      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
4646          rn.Is(pc) && operand.IsOffset()) {
4647        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4648        uint32_t offset_ = abs(offset);
4649        EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
4650        AdvanceIT();
4651        return;
4652      }
4653    } else {
4654      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
4655      if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
4656          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4657        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4658        uint32_t offset_ = abs(offset);
4659        EmitA32(0x05100000U | (cond.GetCondition() << 28) |
4660                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4661                (sign << 23));
4662        return;
4663      }
4664      // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
4665      if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
4666          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4667        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4668        uint32_t offset_ = abs(offset);
4669        EmitA32(0x04100000U | (cond.GetCondition() << 28) |
4670                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4671                (sign << 23));
4672        return;
4673      }
4674      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
4675      if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
4676          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4677        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4678        uint32_t offset_ = abs(offset);
4679        EmitA32(0x05300000U | (cond.GetCondition() << 28) |
4680                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4681                (sign << 23));
4682        return;
4683      }
4684      // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
4685      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
4686          operand.IsOffset() && cond.IsNotNever()) {
4687        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4688        uint32_t offset_ = abs(offset);
4689        EmitA32(0x051f0000U | (cond.GetCondition() << 28) |
4690                (rt.GetCode() << 12) | offset_ | (sign << 23));
4691        return;
4692      }
4693    }
4694  }
4695  if (operand.IsPlainRegister()) {
4696    Register rn = operand.GetBaseRegister();
4697    Sign sign = operand.GetSign();
4698    Register rm = operand.GetOffsetRegister();
4699    if (IsUsingT32()) {
4700      // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
4701      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
4702          sign.IsPlus() && operand.IsOffset()) {
4703        EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) |
4704                   (rm.GetCode() << 6));
4705        AdvanceIT();
4706        return;
4707      }
4708    }
4709  }
4710  if (operand.IsShiftedRegister()) {
4711    Register rn = operand.GetBaseRegister();
4712    Sign sign = operand.GetSign();
4713    Register rm = operand.GetOffsetRegister();
4714    Shift shift = operand.GetShift();
4715    uint32_t amount = operand.GetShiftAmount();
4716    if (IsUsingT32()) {
4717      // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
4718      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
4719          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
4720        EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4721                   rm.GetCode() | (amount << 4));
4722        AdvanceIT();
4723        return;
4724      }
4725    } else {
4726      // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
4727      if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
4728        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4729        uint32_t shift_ = TypeEncodingValue(shift);
4730        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4731        EmitA32(0x07100000U | (cond.GetCondition() << 28) |
4732                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4733                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4734        return;
4735      }
4736      // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
4737      if (operand.IsShiftValid() && operand.IsPostIndex() &&
4738          cond.IsNotNever()) {
4739        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4740        uint32_t shift_ = TypeEncodingValue(shift);
4741        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4742        EmitA32(0x06100000U | (cond.GetCondition() << 28) |
4743                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4744                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4745        return;
4746      }
4747      // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
4748      if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
4749        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4750        uint32_t shift_ = TypeEncodingValue(shift);
4751        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4752        EmitA32(0x07300000U | (cond.GetCondition() << 28) |
4753                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4754                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4755        return;
4756      }
4757    }
4758  }
4759  Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand);
4760}
4761
4762void Assembler::ldr(Condition cond,
4763                    EncodingSize size,
4764                    Register rt,
4765                    Label* label) {
4766  VIXL_ASSERT(AllowAssembler());
4767  CheckIT(cond);
4768  Label::Offset offset =
4769      label->IsBound()
4770          ? label->GetLocation() -
4771                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
4772          : 0;
4773  if (IsUsingT32()) {
4774    // LDR{<c>}{<q>} <Rt>, <label> ; T1
4775    if (!size.IsWide() && rt.IsLow() &&
4776        ((label->IsBound() && (offset >= 0) && (offset <= 1020) &&
4777          ((offset & 0x3) == 0)) ||
4778         (!label->IsBound() && size.IsNarrow()))) {
4779      static class EmitOp : public Label::LabelEmitOperator {
4780       public:
4781        EmitOp() : Label::LabelEmitOperator(0, 1020) {}
4782        virtual uint32_t Encode(uint32_t instr,
4783                                Label::Offset pc,
4784                                const Label* label) const VIXL_OVERRIDE {
4785          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4786          VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
4787                      ((offset & 0x3) == 0));
4788          const int32_t target = offset >> 2;
4789          return instr | (target & 0xff);
4790        }
4791      } immop;
4792      EmitT32_16(Link(0x4800 | (rt.GetCode() << 8), label, immop));
4793      AdvanceIT();
4794      return;
4795    }
4796    // LDR{<c>}{<q>} <Rt>, <label> ; T2
4797    if (!size.IsNarrow() &&
4798        ((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
4799         !label->IsBound())) {
4800      static class EmitOp : public Label::LabelEmitOperator {
4801       public:
4802        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
4803        virtual uint32_t Encode(uint32_t instr,
4804                                Label::Offset pc,
4805                                const Label* label) const VIXL_OVERRIDE {
4806          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4807          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
4808          uint32_t U = (offset >= 0) && !label->IsMinusZero();
4809          int32_t target = abs(offset) | (U << 12);
4810          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
4811        }
4812      } immop;
4813      EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12), label, immop));
4814      AdvanceIT();
4815      return;
4816    }
4817  } else {
4818    // LDR{<c>}{<q>} <Rt>, <label> ; A1
4819    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
4820         !label->IsBound()) &&
4821        cond.IsNotNever()) {
4822      static class EmitOp : public Label::LabelEmitOperator {
4823       public:
4824        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
4825        virtual uint32_t Encode(uint32_t instr,
4826                                Label::Offset pc,
4827                                const Label* label) const VIXL_OVERRIDE {
4828          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4829          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
4830          uint32_t U = (offset >= 0) && !label->IsMinusZero();
4831          int32_t target = abs(offset) | (U << 12);
4832          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
4833        }
4834      } immop;
4835      EmitA32(
4836          Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
4837               label,
4838               immop));
4839      return;
4840    }
4841  }
4842  Delegate(kLdr, &Assembler::ldr, cond, size, rt, label);
4843}
4844
4845void Assembler::ldrb(Condition cond,
4846                     EncodingSize size,
4847                     Register rt,
4848                     const MemOperand& operand) {
4849  VIXL_ASSERT(AllowAssembler());
4850  CheckIT(cond);
4851  if (operand.IsImmediate()) {
4852    Register rn = operand.GetBaseRegister();
4853    int32_t offset = operand.GetOffsetImmediate();
4854    if (IsUsingT32()) {
4855      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
4856      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
4857          (offset <= 31) && operand.IsOffset()) {
4858        EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) |
4859                   ((offset & 0x1f) << 6));
4860        AdvanceIT();
4861        return;
4862      }
4863      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
4864      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
4865          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
4866        EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4867                   (offset & 0xfff));
4868        AdvanceIT();
4869        return;
4870      }
4871      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
4872      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
4873          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
4874        EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4875                   (-offset & 0xff));
4876        AdvanceIT();
4877        return;
4878      }
4879      // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
4880      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4881          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4882        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4883        uint32_t offset_ = abs(offset);
4884        EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4885                   offset_ | (sign << 9));
4886        AdvanceIT();
4887        return;
4888      }
4889      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
4890      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4891          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4892        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4893        uint32_t offset_ = abs(offset);
4894        EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4895                   offset_ | (sign << 9));
4896        AdvanceIT();
4897        return;
4898      }
4899      // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
4900      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
4901          rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
4902        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4903        uint32_t offset_ = abs(offset);
4904        EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
4905        AdvanceIT();
4906        return;
4907      }
4908    } else {
4909      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
4910      if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
4911          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4912        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4913        uint32_t offset_ = abs(offset);
4914        EmitA32(0x05500000U | (cond.GetCondition() << 28) |
4915                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4916                (sign << 23));
4917        return;
4918      }
4919      // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
4920      if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
4921          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4922        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4923        uint32_t offset_ = abs(offset);
4924        EmitA32(0x04500000U | (cond.GetCondition() << 28) |
4925                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4926                (sign << 23));
4927        return;
4928      }
4929      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
4930      if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
4931          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4932        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4933        uint32_t offset_ = abs(offset);
4934        EmitA32(0x05700000U | (cond.GetCondition() << 28) |
4935                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4936                (sign << 23));
4937        return;
4938      }
4939      // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
4940      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
4941          operand.IsOffset() && cond.IsNotNever()) {
4942        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4943        uint32_t offset_ = abs(offset);
4944        EmitA32(0x055f0000U | (cond.GetCondition() << 28) |
4945                (rt.GetCode() << 12) | offset_ | (sign << 23));
4946        return;
4947      }
4948    }
4949  }
4950  if (operand.IsPlainRegister()) {
4951    Register rn = operand.GetBaseRegister();
4952    Sign sign = operand.GetSign();
4953    Register rm = operand.GetOffsetRegister();
4954    if (IsUsingT32()) {
4955      // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
4956      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
4957          sign.IsPlus() && operand.IsOffset()) {
4958        EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) |
4959                   (rm.GetCode() << 6));
4960        AdvanceIT();
4961        return;
4962      }
4963    }
4964  }
4965  if (operand.IsShiftedRegister()) {
4966    Register rn = operand.GetBaseRegister();
4967    Sign sign = operand.GetSign();
4968    Register rm = operand.GetOffsetRegister();
4969    Shift shift = operand.GetShift();
4970    uint32_t amount = operand.GetShiftAmount();
4971    if (IsUsingT32()) {
4972      // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
4973      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
4974          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
4975        EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4976                   rm.GetCode() | (amount << 4));
4977        AdvanceIT();
4978        return;
4979      }
4980    } else {
4981      // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
4982      if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
4983        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4984        uint32_t shift_ = TypeEncodingValue(shift);
4985        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4986        EmitA32(0x07500000U | (cond.GetCondition() << 28) |
4987                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4988                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4989        return;
4990      }
4991      // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
4992      if (operand.IsShiftValid() && operand.IsPostIndex() &&
4993          cond.IsNotNever()) {
4994        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4995        uint32_t shift_ = TypeEncodingValue(shift);
4996        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4997        EmitA32(0x06500000U | (cond.GetCondition() << 28) |
4998                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4999                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5000        return;
5001      }
5002      // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
5003      if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
5004        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5005        uint32_t shift_ = TypeEncodingValue(shift);
5006        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5007        EmitA32(0x07700000U | (cond.GetCondition() << 28) |
5008                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5009                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5010        return;
5011      }
5012    }
5013  }
5014  Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand);
5015}
5016
5017void Assembler::ldrb(Condition cond, Register rt, Label* label) {
5018  VIXL_ASSERT(AllowAssembler());
5019  CheckIT(cond);
5020  Label::Offset offset =
5021      label->IsBound()
5022          ? label->GetLocation() -
5023                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5024          : 0;
5025  if (IsUsingT32()) {
5026    // LDRB{<c>}{<q>} <Rt>, <label> ; T1
5027    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5028         !label->IsBound()) &&
5029        !rt.Is(pc)) {
5030      static class EmitOp : public Label::LabelEmitOperator {
5031       public:
5032        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5033        virtual uint32_t Encode(uint32_t instr,
5034                                Label::Offset pc,
5035                                const Label* label) const VIXL_OVERRIDE {
5036          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5037          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5038          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5039          int32_t target = abs(offset) | (U << 12);
5040          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5041        }
5042      } immop;
5043      EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12), label, immop));
5044      AdvanceIT();
5045      return;
5046    }
5047  } else {
5048    // LDRB{<c>}{<q>} <Rt>, <label> ; A1
5049    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5050         !label->IsBound()) &&
5051        cond.IsNotNever()) {
5052      static class EmitOp : public Label::LabelEmitOperator {
5053       public:
5054        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5055        virtual uint32_t Encode(uint32_t instr,
5056                                Label::Offset pc,
5057                                const Label* label) const VIXL_OVERRIDE {
5058          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5059          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5060          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5061          int32_t target = abs(offset) | (U << 12);
5062          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5063        }
5064      } immop;
5065      EmitA32(
5066          Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5067               label,
5068               immop));
5069      return;
5070    }
5071  }
5072  Delegate(kLdrb, &Assembler::ldrb, cond, rt, label);
5073}
5074
5075void Assembler::ldrd(Condition cond,
5076                     Register rt,
5077                     Register rt2,
5078                     const MemOperand& operand) {
5079  VIXL_ASSERT(AllowAssembler());
5080  CheckIT(cond);
5081  if (operand.IsImmediate()) {
5082    Register rn = operand.GetBaseRegister();
5083    int32_t offset = operand.GetOffsetImmediate();
5084    if (IsUsingT32()) {
5085      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
5086      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5087          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
5088        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5089        uint32_t offset_ = abs(offset) >> 2;
5090        EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5091                   (rn.GetCode() << 16) | offset_ | (sign << 23));
5092        AdvanceIT();
5093        return;
5094      }
5095      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
5096      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5097          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5098        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5099        uint32_t offset_ = abs(offset) >> 2;
5100        EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5101                   (rn.GetCode() << 16) | offset_ | (sign << 23));
5102        AdvanceIT();
5103        return;
5104      }
5105      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
5106      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5107          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5108        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5109        uint32_t offset_ = abs(offset) >> 2;
5110        EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5111                   (rn.GetCode() << 16) | offset_ | (sign << 23));
5112        AdvanceIT();
5113        return;
5114      }
5115      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1
5116      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5117          operand.IsOffset()) {
5118        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5119        uint32_t offset_ = abs(offset);
5120        EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5121                   offset_ | (sign << 23));
5122        AdvanceIT();
5123        return;
5124      }
5125    } else {
5126      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
5127      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5128          (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5129          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5130          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5131        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5132        uint32_t offset_ = abs(offset);
5133        EmitA32(0x014000d0U | (cond.GetCondition() << 28) |
5134                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5135                ((offset_ & 0xf0) << 4) | (sign << 23));
5136        return;
5137      }
5138      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
5139      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5140          (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5141          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5142          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5143        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5144        uint32_t offset_ = abs(offset);
5145        EmitA32(0x004000d0U | (cond.GetCondition() << 28) |
5146                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5147                ((offset_ & 0xf0) << 4) | (sign << 23));
5148        return;
5149      }
5150      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
5151      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5152          (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5153          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5154          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5155        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5156        uint32_t offset_ = abs(offset);
5157        EmitA32(0x016000d0U | (cond.GetCondition() << 28) |
5158                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5159                ((offset_ & 0xf0) << 4) | (sign << 23));
5160        return;
5161      }
5162      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1
5163      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5164          (offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5165          operand.IsOffset() && cond.IsNotNever() &&
5166          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5167        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5168        uint32_t offset_ = abs(offset);
5169        EmitA32(0x014f00d0U | (cond.GetCondition() << 28) |
5170                (rt.GetCode() << 12) | (offset_ & 0xf) |
5171                ((offset_ & 0xf0) << 4) | (sign << 23));
5172        return;
5173      }
5174    }
5175  }
5176  if (operand.IsPlainRegister()) {
5177    Register rn = operand.GetBaseRegister();
5178    Sign sign = operand.GetSign();
5179    Register rm = operand.GetOffsetRegister();
5180    if (IsUsingA32()) {
5181      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
5182      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5183          operand.IsOffset() && cond.IsNotNever() &&
5184          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5185        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5186        EmitA32(0x010000d0U | (cond.GetCondition() << 28) |
5187                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5188                (sign_ << 23));
5189        return;
5190      }
5191      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
5192      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5193          operand.IsPostIndex() && cond.IsNotNever() &&
5194          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5195        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5196        EmitA32(0x000000d0U | (cond.GetCondition() << 28) |
5197                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5198                (sign_ << 23));
5199        return;
5200      }
5201      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
5202      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5203          operand.IsPreIndex() && cond.IsNotNever() &&
5204          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5205        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5206        EmitA32(0x012000d0U | (cond.GetCondition() << 28) |
5207                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5208                (sign_ << 23));
5209        return;
5210      }
5211    }
5212  }
5213  Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand);
5214}
5215
5216void Assembler::ldrd(Condition cond, Register rt, Register rt2, Label* label) {
5217  VIXL_ASSERT(AllowAssembler());
5218  CheckIT(cond);
5219  Label::Offset offset =
5220      label->IsBound()
5221          ? label->GetLocation() -
5222                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5223          : 0;
5224  if (IsUsingT32()) {
5225    // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
5226    if (((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
5227          ((offset & 0x3) == 0)) ||
5228         !label->IsBound())) {
5229      static class EmitOp : public Label::LabelEmitOperator {
5230       public:
5231        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
5232        virtual uint32_t Encode(uint32_t instr,
5233                                Label::Offset pc,
5234                                const Label* label) const VIXL_OVERRIDE {
5235          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5236          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
5237                      ((offset & 0x3) == 0));
5238          int32_t target = offset >> 2;
5239          uint32_t U = (target >= 0) && !label->IsMinusZero();
5240          target = abs(target) | (U << 8);
5241          return instr | (target & 0xff) | ((target & 0x100) << 15);
5242        }
5243      } immop;
5244      EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8),
5245                      label,
5246                      immop));
5247      AdvanceIT();
5248      return;
5249    }
5250  } else {
5251    // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
5252    if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5253        ((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5254         !label->IsBound()) &&
5255        cond.IsNotNever() &&
5256        ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5257      static class EmitOp : public Label::LabelEmitOperator {
5258       public:
5259        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5260        virtual uint32_t Encode(uint32_t instr,
5261                                Label::Offset pc,
5262                                const Label* label) const VIXL_OVERRIDE {
5263          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5264          VIXL_ASSERT((offset >= -255) && (offset <= 255));
5265          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5266          int32_t target = abs(offset) | (U << 8);
5267          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5268                 ((target & 0x100) << 15);
5269        }
5270      } immop;
5271      EmitA32(
5272          Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5273               label,
5274               immop));
5275      return;
5276    }
5277  }
5278  Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, label);
5279}
5280
5281void Assembler::ldrex(Condition cond, Register rt, const MemOperand& operand) {
5282  VIXL_ASSERT(AllowAssembler());
5283  CheckIT(cond);
5284  if (operand.IsImmediate()) {
5285    Register rn = operand.GetBaseRegister();
5286    int32_t offset = operand.GetOffsetImmediate();
5287    if (IsUsingT32()) {
5288      // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1
5289      if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
5290          operand.IsOffset()) {
5291        int32_t offset_ = offset >> 2;
5292        EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5293                   (offset_ & 0xff));
5294        AdvanceIT();
5295        return;
5296      }
5297    } else {
5298      // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1
5299      if ((offset == 0) && operand.IsOffset() && cond.IsNotNever()) {
5300        EmitA32(0x01900f9fU | (cond.GetCondition() << 28) |
5301                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5302        return;
5303      }
5304    }
5305  }
5306  Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand);
5307}
5308
5309void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) {
5310  VIXL_ASSERT(AllowAssembler());
5311  CheckIT(cond);
5312  if (operand.IsImmediateZero()) {
5313    Register rn = operand.GetBaseRegister();
5314    if (IsUsingT32()) {
5315      // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
5316      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
5317        EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5318        AdvanceIT();
5319        return;
5320      }
5321    } else {
5322      // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
5323      if (operand.IsOffset() && cond.IsNotNever() &&
5324          ((!rn.IsPC()) || AllowUnpredictable())) {
5325        EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) |
5326                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5327        return;
5328      }
5329    }
5330  }
5331  Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand);
5332}
5333
5334void Assembler::ldrexd(Condition cond,
5335                       Register rt,
5336                       Register rt2,
5337                       const MemOperand& operand) {
5338  VIXL_ASSERT(AllowAssembler());
5339  CheckIT(cond);
5340  if (operand.IsImmediateZero()) {
5341    Register rn = operand.GetBaseRegister();
5342    if (IsUsingT32()) {
5343      // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
5344      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
5345        EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5346                   (rn.GetCode() << 16));
5347        AdvanceIT();
5348        return;
5349      }
5350    } else {
5351      // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
5352      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5353          operand.IsOffset() && cond.IsNotNever() &&
5354          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
5355           AllowUnpredictable())) {
5356        EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) |
5357                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5358        return;
5359      }
5360    }
5361  }
5362  Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand);
5363}
5364
5365void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) {
5366  VIXL_ASSERT(AllowAssembler());
5367  CheckIT(cond);
5368  if (operand.IsImmediateZero()) {
5369    Register rn = operand.GetBaseRegister();
5370    if (IsUsingT32()) {
5371      // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
5372      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
5373        EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5374        AdvanceIT();
5375        return;
5376      }
5377    } else {
5378      // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
5379      if (operand.IsOffset() && cond.IsNotNever() &&
5380          ((!rn.IsPC()) || AllowUnpredictable())) {
5381        EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) |
5382                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5383        return;
5384      }
5385    }
5386  }
5387  Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand);
5388}
5389
5390void Assembler::ldrh(Condition cond,
5391                     EncodingSize size,
5392                     Register rt,
5393                     const MemOperand& operand) {
5394  VIXL_ASSERT(AllowAssembler());
5395  CheckIT(cond);
5396  if (operand.IsImmediate()) {
5397    Register rn = operand.GetBaseRegister();
5398    int32_t offset = operand.GetOffsetImmediate();
5399    if (IsUsingT32()) {
5400      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5401      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
5402          (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
5403        int32_t offset_ = offset >> 1;
5404        EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) |
5405                   ((offset_ & 0x1f) << 6));
5406        AdvanceIT();
5407        return;
5408      }
5409      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
5410      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5411          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5412        EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5413                   (offset & 0xfff));
5414        AdvanceIT();
5415        return;
5416      }
5417      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
5418      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5419          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5420        EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5421                   (-offset & 0xff));
5422        AdvanceIT();
5423        return;
5424      }
5425      // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
5426      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5427          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5428        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5429        uint32_t offset_ = abs(offset);
5430        EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5431                   offset_ | (sign << 9));
5432        AdvanceIT();
5433        return;
5434      }
5435      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
5436      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5437          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5438        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5439        uint32_t offset_ = abs(offset);
5440        EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5441                   offset_ | (sign << 9));
5442        AdvanceIT();
5443        return;
5444      }
5445      // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5446      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5447          rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5448        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5449        uint32_t offset_ = abs(offset);
5450        EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5451        AdvanceIT();
5452        return;
5453      }
5454    } else {
5455      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
5456      if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5457          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5458        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5459        uint32_t offset_ = abs(offset);
5460        EmitA32(0x015000b0U | (cond.GetCondition() << 28) |
5461                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5462                ((offset_ & 0xf0) << 4) | (sign << 23));
5463        return;
5464      }
5465      // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
5466      if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5467          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5468        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5469        uint32_t offset_ = abs(offset);
5470        EmitA32(0x005000b0U | (cond.GetCondition() << 28) |
5471                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5472                ((offset_ & 0xf0) << 4) | (sign << 23));
5473        return;
5474      }
5475      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
5476      if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5477          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5478        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5479        uint32_t offset_ = abs(offset);
5480        EmitA32(0x017000b0U | (cond.GetCondition() << 28) |
5481                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5482                ((offset_ & 0xf0) << 4) | (sign << 23));
5483        return;
5484      }
5485      // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5486      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5487          operand.IsOffset() && cond.IsNotNever()) {
5488        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5489        uint32_t offset_ = abs(offset);
5490        EmitA32(0x015f00b0U | (cond.GetCondition() << 28) |
5491                (rt.GetCode() << 12) | (offset_ & 0xf) |
5492                ((offset_ & 0xf0) << 4) | (sign << 23));
5493        return;
5494      }
5495    }
5496  }
5497  if (operand.IsPlainRegister()) {
5498    Register rn = operand.GetBaseRegister();
5499    Sign sign = operand.GetSign();
5500    Register rm = operand.GetOffsetRegister();
5501    if (IsUsingT32()) {
5502      // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5503      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5504          sign.IsPlus() && operand.IsOffset()) {
5505        EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) |
5506                   (rm.GetCode() << 6));
5507        AdvanceIT();
5508        return;
5509      }
5510    } else {
5511      // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5512      if (operand.IsOffset() && cond.IsNotNever()) {
5513        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5514        EmitA32(0x011000b0U | (cond.GetCondition() << 28) |
5515                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5516                (sign_ << 23));
5517        return;
5518      }
5519      // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5520      if (operand.IsPostIndex() && cond.IsNotNever()) {
5521        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5522        EmitA32(0x001000b0U | (cond.GetCondition() << 28) |
5523                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5524                (sign_ << 23));
5525        return;
5526      }
5527      // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5528      if (operand.IsPreIndex() && cond.IsNotNever()) {
5529        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5530        EmitA32(0x013000b0U | (cond.GetCondition() << 28) |
5531                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5532                (sign_ << 23));
5533        return;
5534      }
5535    }
5536  }
5537  if (operand.IsShiftedRegister()) {
5538    Register rn = operand.GetBaseRegister();
5539    Sign sign = operand.GetSign();
5540    Register rm = operand.GetOffsetRegister();
5541    Shift shift = operand.GetShift();
5542    uint32_t amount = operand.GetShiftAmount();
5543    if (IsUsingT32()) {
5544      // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5545      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5546          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5547        EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5548                   rm.GetCode() | (amount << 4));
5549        AdvanceIT();
5550        return;
5551      }
5552    }
5553  }
5554  Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand);
5555}
5556
5557void Assembler::ldrh(Condition cond, Register rt, Label* label) {
5558  VIXL_ASSERT(AllowAssembler());
5559  CheckIT(cond);
5560  Label::Offset offset =
5561      label->IsBound()
5562          ? label->GetLocation() -
5563                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5564          : 0;
5565  if (IsUsingT32()) {
5566    // LDRH{<c>}{<q>} <Rt>, <label> ; T1
5567    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5568         !label->IsBound()) &&
5569        !rt.Is(pc)) {
5570      static class EmitOp : public Label::LabelEmitOperator {
5571       public:
5572        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5573        virtual uint32_t Encode(uint32_t instr,
5574                                Label::Offset pc,
5575                                const Label* label) const VIXL_OVERRIDE {
5576          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5577          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5578          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5579          int32_t target = abs(offset) | (U << 12);
5580          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5581        }
5582      } immop;
5583      EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12), label, immop));
5584      AdvanceIT();
5585      return;
5586    }
5587  } else {
5588    // LDRH{<c>}{<q>} <Rt>, <label> ; A1
5589    if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5590         !label->IsBound()) &&
5591        cond.IsNotNever()) {
5592      static class EmitOp : public Label::LabelEmitOperator {
5593       public:
5594        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5595        virtual uint32_t Encode(uint32_t instr,
5596                                Label::Offset pc,
5597                                const Label* label) const VIXL_OVERRIDE {
5598          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5599          VIXL_ASSERT((offset >= -255) && (offset <= 255));
5600          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5601          int32_t target = abs(offset) | (U << 8);
5602          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5603                 ((target & 0x100) << 15);
5604        }
5605      } immop;
5606      EmitA32(
5607          Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5608               label,
5609               immop));
5610      return;
5611    }
5612  }
5613  Delegate(kLdrh, &Assembler::ldrh, cond, rt, label);
5614}
5615
5616void Assembler::ldrsb(Condition cond,
5617                      EncodingSize size,
5618                      Register rt,
5619                      const MemOperand& operand) {
5620  VIXL_ASSERT(AllowAssembler());
5621  CheckIT(cond);
5622  if (operand.IsImmediate()) {
5623    Register rn = operand.GetBaseRegister();
5624    int32_t offset = operand.GetOffsetImmediate();
5625    if (IsUsingT32()) {
5626      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5627      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5628          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5629        EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5630                   (offset & 0xfff));
5631        AdvanceIT();
5632        return;
5633      }
5634      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
5635      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5636          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5637        EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5638                   (-offset & 0xff));
5639        AdvanceIT();
5640        return;
5641      }
5642      // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
5643      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5644          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5645        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5646        uint32_t offset_ = abs(offset);
5647        EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5648                   offset_ | (sign << 9));
5649        AdvanceIT();
5650        return;
5651      }
5652      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
5653      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5654          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5655        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5656        uint32_t offset_ = abs(offset);
5657        EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5658                   offset_ | (sign << 9));
5659        AdvanceIT();
5660        return;
5661      }
5662      // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5663      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5664          rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5665        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5666        uint32_t offset_ = abs(offset);
5667        EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5668        AdvanceIT();
5669        return;
5670      }
5671    } else {
5672      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
5673      if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5674          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5675        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5676        uint32_t offset_ = abs(offset);
5677        EmitA32(0x015000d0U | (cond.GetCondition() << 28) |
5678                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5679                ((offset_ & 0xf0) << 4) | (sign << 23));
5680        return;
5681      }
5682      // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
5683      if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5684          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5685        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5686        uint32_t offset_ = abs(offset);
5687        EmitA32(0x005000d0U | (cond.GetCondition() << 28) |
5688                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5689                ((offset_ & 0xf0) << 4) | (sign << 23));
5690        return;
5691      }
5692      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
5693      if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5694          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5695        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5696        uint32_t offset_ = abs(offset);
5697        EmitA32(0x017000d0U | (cond.GetCondition() << 28) |
5698                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5699                ((offset_ & 0xf0) << 4) | (sign << 23));
5700        return;
5701      }
5702      // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5703      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5704          operand.IsOffset() && cond.IsNotNever()) {
5705        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5706        uint32_t offset_ = abs(offset);
5707        EmitA32(0x015f00d0U | (cond.GetCondition() << 28) |
5708                (rt.GetCode() << 12) | (offset_ & 0xf) |
5709                ((offset_ & 0xf0) << 4) | (sign << 23));
5710        return;
5711      }
5712    }
5713  }
5714  if (operand.IsPlainRegister()) {
5715    Register rn = operand.GetBaseRegister();
5716    Sign sign = operand.GetSign();
5717    Register rm = operand.GetOffsetRegister();
5718    if (IsUsingT32()) {
5719      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5720      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5721          sign.IsPlus() && operand.IsOffset()) {
5722        EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) |
5723                   (rm.GetCode() << 6));
5724        AdvanceIT();
5725        return;
5726      }
5727    } else {
5728      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5729      if (operand.IsOffset() && cond.IsNotNever()) {
5730        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5731        EmitA32(0x011000d0U | (cond.GetCondition() << 28) |
5732                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5733                (sign_ << 23));
5734        return;
5735      }
5736      // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5737      if (operand.IsPostIndex() && cond.IsNotNever()) {
5738        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5739        EmitA32(0x001000d0U | (cond.GetCondition() << 28) |
5740                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5741                (sign_ << 23));
5742        return;
5743      }
5744      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5745      if (operand.IsPreIndex() && cond.IsNotNever()) {
5746        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5747        EmitA32(0x013000d0U | (cond.GetCondition() << 28) |
5748                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5749                (sign_ << 23));
5750        return;
5751      }
5752    }
5753  }
5754  if (operand.IsShiftedRegister()) {
5755    Register rn = operand.GetBaseRegister();
5756    Sign sign = operand.GetSign();
5757    Register rm = operand.GetOffsetRegister();
5758    Shift shift = operand.GetShift();
5759    uint32_t amount = operand.GetShiftAmount();
5760    if (IsUsingT32()) {
5761      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5762      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5763          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5764        EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5765                   rm.GetCode() | (amount << 4));
5766        AdvanceIT();
5767        return;
5768      }
5769    }
5770  }
5771  Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand);
5772}
5773
5774void Assembler::ldrsb(Condition cond, Register rt, Label* label) {
5775  VIXL_ASSERT(AllowAssembler());
5776  CheckIT(cond);
5777  Label::Offset offset =
5778      label->IsBound()
5779          ? label->GetLocation() -
5780                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5781          : 0;
5782  if (IsUsingT32()) {
5783    // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
5784    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5785         !label->IsBound()) &&
5786        !rt.Is(pc)) {
5787      static class EmitOp : public Label::LabelEmitOperator {
5788       public:
5789        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5790        virtual uint32_t Encode(uint32_t instr,
5791                                Label::Offset pc,
5792                                const Label* label) const VIXL_OVERRIDE {
5793          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5794          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5795          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5796          int32_t target = abs(offset) | (U << 12);
5797          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5798        }
5799      } immop;
5800      EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12), label, immop));
5801      AdvanceIT();
5802      return;
5803    }
5804  } else {
5805    // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
5806    if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5807         !label->IsBound()) &&
5808        cond.IsNotNever()) {
5809      static class EmitOp : public Label::LabelEmitOperator {
5810       public:
5811        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5812        virtual uint32_t Encode(uint32_t instr,
5813                                Label::Offset pc,
5814                                const Label* label) const VIXL_OVERRIDE {
5815          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5816          VIXL_ASSERT((offset >= -255) && (offset <= 255));
5817          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5818          int32_t target = abs(offset) | (U << 8);
5819          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5820                 ((target & 0x100) << 15);
5821        }
5822      } immop;
5823      EmitA32(
5824          Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5825               label,
5826               immop));
5827      return;
5828    }
5829  }
5830  Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, label);
5831}
5832
5833void Assembler::ldrsh(Condition cond,
5834                      EncodingSize size,
5835                      Register rt,
5836                      const MemOperand& operand) {
5837  VIXL_ASSERT(AllowAssembler());
5838  CheckIT(cond);
5839  if (operand.IsImmediate()) {
5840    Register rn = operand.GetBaseRegister();
5841    int32_t offset = operand.GetOffsetImmediate();
5842    if (IsUsingT32()) {
5843      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5844      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5845          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5846        EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5847                   (offset & 0xfff));
5848        AdvanceIT();
5849        return;
5850      }
5851      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
5852      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5853          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5854        EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5855                   (-offset & 0xff));
5856        AdvanceIT();
5857        return;
5858      }
5859      // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
5860      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5861          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5862        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5863        uint32_t offset_ = abs(offset);
5864        EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5865                   offset_ | (sign << 9));
5866        AdvanceIT();
5867        return;
5868      }
5869      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
5870      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5871          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5872        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5873        uint32_t offset_ = abs(offset);
5874        EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5875                   offset_ | (sign << 9));
5876        AdvanceIT();
5877        return;
5878      }
5879      // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5880      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5881          rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5882        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5883        uint32_t offset_ = abs(offset);
5884        EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5885        AdvanceIT();
5886        return;
5887      }
5888    } else {
5889      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
5890      if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5891          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5892        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5893        uint32_t offset_ = abs(offset);
5894        EmitA32(0x015000f0U | (cond.GetCondition() << 28) |
5895                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5896                ((offset_ & 0xf0) << 4) | (sign << 23));
5897        return;
5898      }
5899      // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
5900      if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5901          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5902        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5903        uint32_t offset_ = abs(offset);
5904        EmitA32(0x005000f0U | (cond.GetCondition() << 28) |
5905                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5906                ((offset_ & 0xf0) << 4) | (sign << 23));
5907        return;
5908      }
5909      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
5910      if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5911          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5912        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5913        uint32_t offset_ = abs(offset);
5914        EmitA32(0x017000f0U | (cond.GetCondition() << 28) |
5915                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5916                ((offset_ & 0xf0) << 4) | (sign << 23));
5917        return;
5918      }
5919      // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5920      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5921          operand.IsOffset() && cond.IsNotNever()) {
5922        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5923        uint32_t offset_ = abs(offset);
5924        EmitA32(0x015f00f0U | (cond.GetCondition() << 28) |
5925                (rt.GetCode() << 12) | (offset_ & 0xf) |
5926                ((offset_ & 0xf0) << 4) | (sign << 23));
5927        return;
5928      }
5929    }
5930  }
5931  if (operand.IsPlainRegister()) {
5932    Register rn = operand.GetBaseRegister();
5933    Sign sign = operand.GetSign();
5934    Register rm = operand.GetOffsetRegister();
5935    if (IsUsingT32()) {
5936      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5937      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5938          sign.IsPlus() && operand.IsOffset()) {
5939        EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) |
5940                   (rm.GetCode() << 6));
5941        AdvanceIT();
5942        return;
5943      }
5944    } else {
5945      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5946      if (operand.IsOffset() && cond.IsNotNever()) {
5947        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5948        EmitA32(0x011000f0U | (cond.GetCondition() << 28) |
5949                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5950                (sign_ << 23));
5951        return;
5952      }
5953      // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5954      if (operand.IsPostIndex() && cond.IsNotNever()) {
5955        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5956        EmitA32(0x001000f0U | (cond.GetCondition() << 28) |
5957                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5958                (sign_ << 23));
5959        return;
5960      }
5961      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5962      if (operand.IsPreIndex() && cond.IsNotNever()) {
5963        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5964        EmitA32(0x013000f0U | (cond.GetCondition() << 28) |
5965                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5966                (sign_ << 23));
5967        return;
5968      }
5969    }
5970  }
5971  if (operand.IsShiftedRegister()) {
5972    Register rn = operand.GetBaseRegister();
5973    Sign sign = operand.GetSign();
5974    Register rm = operand.GetOffsetRegister();
5975    Shift shift = operand.GetShift();
5976    uint32_t amount = operand.GetShiftAmount();
5977    if (IsUsingT32()) {
5978      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5979      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5980          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5981        EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5982                   rm.GetCode() | (amount << 4));
5983        AdvanceIT();
5984        return;
5985      }
5986    }
5987  }
5988  Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand);
5989}
5990
5991void Assembler::ldrsh(Condition cond, Register rt, Label* label) {
5992  VIXL_ASSERT(AllowAssembler());
5993  CheckIT(cond);
5994  Label::Offset offset =
5995      label->IsBound()
5996          ? label->GetLocation() -
5997                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5998          : 0;
5999  if (IsUsingT32()) {
6000    // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
6001    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
6002         !label->IsBound()) &&
6003        !rt.Is(pc)) {
6004      static class EmitOp : public Label::LabelEmitOperator {
6005       public:
6006        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
6007        virtual uint32_t Encode(uint32_t instr,
6008                                Label::Offset pc,
6009                                const Label* label) const VIXL_OVERRIDE {
6010          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
6011          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
6012          uint32_t U = (offset >= 0) && !label->IsMinusZero();
6013          int32_t target = abs(offset) | (U << 12);
6014          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
6015        }
6016      } immop;
6017      EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12), label, immop));
6018      AdvanceIT();
6019      return;
6020    }
6021  } else {
6022    // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
6023    if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
6024         !label->IsBound()) &&
6025        cond.IsNotNever()) {
6026      static class EmitOp : public Label::LabelEmitOperator {
6027       public:
6028        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
6029        virtual uint32_t Encode(uint32_t instr,
6030                                Label::Offset pc,
6031                                const Label* label) const VIXL_OVERRIDE {
6032          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
6033          VIXL_ASSERT((offset >= -255) && (offset <= 255));
6034          uint32_t U = (offset >= 0) && !label->IsMinusZero();
6035          int32_t target = abs(offset) | (U << 8);
6036          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
6037                 ((target & 0x100) << 15);
6038        }
6039      } immop;
6040      EmitA32(
6041          Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
6042               label,
6043               immop));
6044      return;
6045    }
6046  }
6047  Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, label);
6048}
6049
6050void Assembler::lsl(Condition cond,
6051                    EncodingSize size,
6052                    Register rd,
6053                    Register rm,
6054                    const Operand& operand) {
6055  VIXL_ASSERT(AllowAssembler());
6056  CheckIT(cond);
6057  if (operand.IsImmediate()) {
6058    uint32_t imm = operand.GetImmediate();
6059    if (IsUsingT32()) {
6060      // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6061      if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6062          (imm >= 1) && (imm <= 31)) {
6063        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6064        AdvanceIT();
6065        return;
6066      }
6067      // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6068      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
6069        EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6070                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6071        AdvanceIT();
6072        return;
6073      }
6074    } else {
6075      // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6076      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6077        EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
6078                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6079        return;
6080      }
6081    }
6082  }
6083  if (operand.IsPlainRegister()) {
6084    Register rs = operand.GetBaseRegister();
6085    if (IsUsingT32()) {
6086      // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6087      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6088          rs.IsLow()) {
6089        EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6090        AdvanceIT();
6091        return;
6092      }
6093      // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6094      if (!size.IsNarrow()) {
6095        EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6096                   rs.GetCode());
6097        AdvanceIT();
6098        return;
6099      }
6100    } else {
6101      // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6102      if (cond.IsNotNever()) {
6103        EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
6104                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6105        return;
6106      }
6107    }
6108  }
6109  Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand);
6110}
6111
6112void Assembler::lsls(Condition cond,
6113                     EncodingSize size,
6114                     Register rd,
6115                     Register rm,
6116                     const Operand& operand) {
6117  VIXL_ASSERT(AllowAssembler());
6118  CheckIT(cond);
6119  if (operand.IsImmediate()) {
6120    uint32_t imm = operand.GetImmediate();
6121    if (IsUsingT32()) {
6122      // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6123      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6124          (imm >= 1) && (imm <= 31)) {
6125        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6126        AdvanceIT();
6127        return;
6128      }
6129      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6130      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
6131        EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6132                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6133        AdvanceIT();
6134        return;
6135      }
6136    } else {
6137      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6138      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6139        EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
6140                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6141        return;
6142      }
6143    }
6144  }
6145  if (operand.IsPlainRegister()) {
6146    Register rs = operand.GetBaseRegister();
6147    if (IsUsingT32()) {
6148      // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6149      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6150          rs.IsLow()) {
6151        EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6152        AdvanceIT();
6153        return;
6154      }
6155      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6156      if (!size.IsNarrow()) {
6157        EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6158                   rs.GetCode());
6159        AdvanceIT();
6160        return;
6161      }
6162    } else {
6163      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6164      if (cond.IsNotNever()) {
6165        EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
6166                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6167        return;
6168      }
6169    }
6170  }
6171  Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand);
6172}
6173
6174void Assembler::lsr(Condition cond,
6175                    EncodingSize size,
6176                    Register rd,
6177                    Register rm,
6178                    const Operand& operand) {
6179  VIXL_ASSERT(AllowAssembler());
6180  CheckIT(cond);
6181  if (operand.IsImmediate()) {
6182    uint32_t imm = operand.GetImmediate();
6183    if (IsUsingT32()) {
6184      // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6185      if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6186          (imm >= 1) && (imm <= 32)) {
6187        uint32_t amount_ = imm % 32;
6188        EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6189                   (amount_ << 6));
6190        AdvanceIT();
6191        return;
6192      }
6193      // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6194      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
6195        uint32_t amount_ = imm % 32;
6196        EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6197                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6198        AdvanceIT();
6199        return;
6200      }
6201    } else {
6202      // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6203      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6204        uint32_t amount_ = imm % 32;
6205        EmitA32(0x01a00020U | (cond.GetCondition() << 28) |
6206                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6207        return;
6208      }
6209    }
6210  }
6211  if (operand.IsPlainRegister()) {
6212    Register rs = operand.GetBaseRegister();
6213    if (IsUsingT32()) {
6214      // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6215      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6216          rs.IsLow()) {
6217        EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6218        AdvanceIT();
6219        return;
6220      }
6221      // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6222      if (!size.IsNarrow()) {
6223        EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6224                   rs.GetCode());
6225        AdvanceIT();
6226        return;
6227      }
6228    } else {
6229      // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6230      if (cond.IsNotNever()) {
6231        EmitA32(0x01a00030U | (cond.GetCondition() << 28) |
6232                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6233        return;
6234      }
6235    }
6236  }
6237  Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand);
6238}
6239
6240void Assembler::lsrs(Condition cond,
6241                     EncodingSize size,
6242                     Register rd,
6243                     Register rm,
6244                     const Operand& operand) {
6245  VIXL_ASSERT(AllowAssembler());
6246  CheckIT(cond);
6247  if (operand.IsImmediate()) {
6248    uint32_t imm = operand.GetImmediate();
6249    if (IsUsingT32()) {
6250      // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6251      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6252          (imm >= 1) && (imm <= 32)) {
6253        uint32_t amount_ = imm % 32;
6254        EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6255                   (amount_ << 6));
6256        AdvanceIT();
6257        return;
6258      }
6259      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6260      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
6261        uint32_t amount_ = imm % 32;
6262        EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6263                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6264        AdvanceIT();
6265        return;
6266      }
6267    } else {
6268      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6269      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6270        uint32_t amount_ = imm % 32;
6271        EmitA32(0x01b00020U | (cond.GetCondition() << 28) |
6272                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6273        return;
6274      }
6275    }
6276  }
6277  if (operand.IsPlainRegister()) {
6278    Register rs = operand.GetBaseRegister();
6279    if (IsUsingT32()) {
6280      // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6281      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6282          rs.IsLow()) {
6283        EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6284        AdvanceIT();
6285        return;
6286      }
6287      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6288      if (!size.IsNarrow()) {
6289        EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6290                   rs.GetCode());
6291        AdvanceIT();
6292        return;
6293      }
6294    } else {
6295      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6296      if (cond.IsNotNever()) {
6297        EmitA32(0x01b00030U | (cond.GetCondition() << 28) |
6298                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6299        return;
6300      }
6301    }
6302  }
6303  Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand);
6304}
6305
6306void Assembler::mla(
6307    Condition cond, Register rd, Register rn, Register rm, Register ra) {
6308  VIXL_ASSERT(AllowAssembler());
6309  CheckIT(cond);
6310  if (IsUsingT32()) {
6311    // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
6312    if (!ra.Is(pc)) {
6313      EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6314                 rm.GetCode() | (ra.GetCode() << 12));
6315      AdvanceIT();
6316      return;
6317    }
6318  } else {
6319    // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6320    if (cond.IsNotNever()) {
6321      EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6322              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6323      return;
6324    }
6325  }
6326  Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra);
6327}
6328
6329void Assembler::mlas(
6330    Condition cond, Register rd, Register rn, Register rm, Register ra) {
6331  VIXL_ASSERT(AllowAssembler());
6332  CheckIT(cond);
6333  if (IsUsingA32()) {
6334    // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6335    if (cond.IsNotNever()) {
6336      EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6337              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6338      return;
6339    }
6340  }
6341  Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra);
6342}
6343
6344void Assembler::mls(
6345    Condition cond, Register rd, Register rn, Register rm, Register ra) {
6346  VIXL_ASSERT(AllowAssembler());
6347  CheckIT(cond);
6348  if (IsUsingT32()) {
6349    // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
6350    EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6351               rm.GetCode() | (ra.GetCode() << 12));
6352    AdvanceIT();
6353    return;
6354  } else {
6355    // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6356    if (cond.IsNotNever()) {
6357      EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6358              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6359      return;
6360    }
6361  }
6362  Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra);
6363}
6364
6365void Assembler::mov(Condition cond,
6366                    EncodingSize size,
6367                    Register rd,
6368                    const Operand& operand) {
6369  VIXL_ASSERT(AllowAssembler());
6370  CheckIT(cond);
6371  if (operand.IsImmediateShiftedRegister()) {
6372    Register rm = operand.GetBaseRegister();
6373    if (operand.IsPlainRegister()) {
6374      if (IsUsingT32()) {
6375        // MOV{<c>}{<q>} <Rd>, <Rm> ; T1
6376        if (!size.IsWide()) {
6377          EmitT32_16(0x4600 | (rd.GetCode() & 0x7) |
6378                     ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
6379          AdvanceIT();
6380          return;
6381        }
6382      }
6383    }
6384    Shift shift = operand.GetShift();
6385    uint32_t amount = operand.GetShiftAmount();
6386    if (IsUsingT32()) {
6387      // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6388      if (InITBlock() && !size.IsWide() && rd.IsLow() &&
6389          shift.IsValidAmount(amount) && rm.IsLow() &&
6390          (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) {
6391        uint32_t amount_ = amount % 32;
6392        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
6393                   (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
6394        AdvanceIT();
6395        return;
6396      }
6397      // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
6398      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6399        uint32_t amount_ = amount % 32;
6400        EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6401                   (operand.GetTypeEncodingValue() << 4) |
6402                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6403        AdvanceIT();
6404        return;
6405      }
6406    } else {
6407      // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6408      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6409        uint32_t amount_ = amount % 32;
6410        EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
6411                (rd.GetCode() << 12) | rm.GetCode() |
6412                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6413        return;
6414      }
6415    }
6416  }
6417  if (operand.IsRegisterShiftedRegister()) {
6418    Register rm = operand.GetBaseRegister();
6419    Shift shift = operand.GetShift();
6420    if (IsUsingT32()) {
6421      // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
6422      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6423          shift.IsASR() && operand.GetShiftRegister().IsLow()) {
6424        EmitT32_16(0x4100 | rd.GetCode() |
6425                   (operand.GetShiftRegister().GetCode() << 3));
6426        AdvanceIT();
6427        return;
6428      }
6429      // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
6430      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6431          shift.IsLSL() && operand.GetShiftRegister().IsLow()) {
6432        EmitT32_16(0x4080 | rd.GetCode() |
6433                   (operand.GetShiftRegister().GetCode() << 3));
6434        AdvanceIT();
6435        return;
6436      }
6437      // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
6438      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6439          shift.IsLSR() && operand.GetShiftRegister().IsLow()) {
6440        EmitT32_16(0x40c0 | rd.GetCode() |
6441                   (operand.GetShiftRegister().GetCode() << 3));
6442        AdvanceIT();
6443        return;
6444      }
6445      // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
6446      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6447          shift.IsROR() && operand.GetShiftRegister().IsLow()) {
6448        EmitT32_16(0x41c0 | rd.GetCode() |
6449                   (operand.GetShiftRegister().GetCode() << 3));
6450        AdvanceIT();
6451        return;
6452      }
6453      // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
6454      if (!size.IsNarrow()) {
6455        EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6456                   (shift.GetType() << 21) |
6457                   operand.GetShiftRegister().GetCode());
6458        AdvanceIT();
6459        return;
6460      }
6461    } else {
6462      // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6463      if (cond.IsNotNever()) {
6464        EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
6465                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6466                (operand.GetShiftRegister().GetCode() << 8));
6467        return;
6468      }
6469    }
6470  }
6471  if (operand.IsImmediate()) {
6472    uint32_t imm = operand.GetImmediate();
6473    if (IsUsingT32()) {
6474      ImmediateT32 immediate_t32(imm);
6475      // MOV<c>{<q>} <Rd>, #<imm8> ; T1
6476      if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
6477        EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
6478        AdvanceIT();
6479        return;
6480      }
6481      // MOV{<c>}{<q>} <Rd>, #<const> ; T2
6482      if (!size.IsNarrow() && immediate_t32.IsValid()) {
6483        EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) |
6484                   (immediate_t32.GetEncodingValue() & 0xff) |
6485                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6486                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6487        AdvanceIT();
6488        return;
6489      }
6490      // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3
6491      if (!size.IsNarrow() && (imm <= 65535)) {
6492        EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
6493                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6494                   ((imm & 0xf000) << 4));
6495        AdvanceIT();
6496        return;
6497      }
6498    } else {
6499      ImmediateA32 immediate_a32(imm);
6500      // MOV{<c>}{<q>} <Rd>, #<const> ; A1
6501      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6502        EmitA32(0x03a00000U | (cond.GetCondition() << 28) |
6503                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6504        return;
6505      }
6506      // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2
6507      if ((imm <= 65535) && cond.IsNotNever()) {
6508        EmitA32(0x03000000U | (cond.GetCondition() << 28) |
6509                (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6510        return;
6511      }
6512    }
6513  }
6514  Delegate(kMov, &Assembler::mov, cond, size, rd, operand);
6515}
6516
6517void Assembler::movs(Condition cond,
6518                     EncodingSize size,
6519                     Register rd,
6520                     const Operand& operand) {
6521  VIXL_ASSERT(AllowAssembler());
6522  CheckIT(cond);
6523  if (operand.IsImmediateShiftedRegister()) {
6524    Register rm = operand.GetBaseRegister();
6525    Shift shift = operand.GetShift();
6526    uint32_t amount = operand.GetShiftAmount();
6527    if (IsUsingT32()) {
6528      // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6529      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() &&
6530          shift.IsValidAmount(amount) && rm.IsLow() &&
6531          (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) {
6532        uint32_t amount_ = amount % 32;
6533        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
6534                   (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
6535        AdvanceIT();
6536        return;
6537      }
6538      // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
6539      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6540        uint32_t amount_ = amount % 32;
6541        EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6542                   (operand.GetTypeEncodingValue() << 4) |
6543                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6544        AdvanceIT();
6545        return;
6546      }
6547    } else {
6548      // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6549      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6550        uint32_t amount_ = amount % 32;
6551        EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
6552                (rd.GetCode() << 12) | rm.GetCode() |
6553                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6554        return;
6555      }
6556    }
6557  }
6558  if (operand.IsRegisterShiftedRegister()) {
6559    Register rm = operand.GetBaseRegister();
6560    Shift shift = operand.GetShift();
6561    if (IsUsingT32()) {
6562      // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
6563      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6564          shift.IsASR() && operand.GetShiftRegister().IsLow()) {
6565        EmitT32_16(0x4100 | rd.GetCode() |
6566                   (operand.GetShiftRegister().GetCode() << 3));
6567        AdvanceIT();
6568        return;
6569      }
6570      // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
6571      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6572          shift.IsLSL() && operand.GetShiftRegister().IsLow()) {
6573        EmitT32_16(0x4080 | rd.GetCode() |
6574                   (operand.GetShiftRegister().GetCode() << 3));
6575        AdvanceIT();
6576        return;
6577      }
6578      // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
6579      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6580          shift.IsLSR() && operand.GetShiftRegister().IsLow()) {
6581        EmitT32_16(0x40c0 | rd.GetCode() |
6582                   (operand.GetShiftRegister().GetCode() << 3));
6583        AdvanceIT();
6584        return;
6585      }
6586      // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
6587      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6588          shift.IsROR() && operand.GetShiftRegister().IsLow()) {
6589        EmitT32_16(0x41c0 | rd.GetCode() |
6590                   (operand.GetShiftRegister().GetCode() << 3));
6591        AdvanceIT();
6592        return;
6593      }
6594      // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
6595      if (!size.IsNarrow()) {
6596        EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6597                   (shift.GetType() << 21) |
6598                   operand.GetShiftRegister().GetCode());
6599        AdvanceIT();
6600        return;
6601      }
6602    } else {
6603      // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6604      if (cond.IsNotNever()) {
6605        EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
6606                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6607                (operand.GetShiftRegister().GetCode() << 8));
6608        return;
6609      }
6610    }
6611  }
6612  if (operand.IsImmediate()) {
6613    uint32_t imm = operand.GetImmediate();
6614    if (IsUsingT32()) {
6615      ImmediateT32 immediate_t32(imm);
6616      // MOVS{<q>} <Rd>, #<imm8> ; T1
6617      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
6618        EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
6619        AdvanceIT();
6620        return;
6621      }
6622      // MOVS{<c>}{<q>} <Rd>, #<const> ; T2
6623      if (!size.IsNarrow() && immediate_t32.IsValid()) {
6624        EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) |
6625                   (immediate_t32.GetEncodingValue() & 0xff) |
6626                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6627                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6628        AdvanceIT();
6629        return;
6630      }
6631    } else {
6632      ImmediateA32 immediate_a32(imm);
6633      // MOVS{<c>}{<q>} <Rd>, #<const> ; A1
6634      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6635        EmitA32(0x03b00000U | (cond.GetCondition() << 28) |
6636                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6637        return;
6638      }
6639    }
6640  }
6641  Delegate(kMovs, &Assembler::movs, cond, size, rd, operand);
6642}
6643
6644void Assembler::movt(Condition cond, Register rd, const Operand& operand) {
6645  VIXL_ASSERT(AllowAssembler());
6646  CheckIT(cond);
6647  if (operand.IsImmediate()) {
6648    uint32_t imm = operand.GetImmediate();
6649    if (IsUsingT32()) {
6650      // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1
6651      if ((imm <= 65535)) {
6652        EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) |
6653                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6654                   ((imm & 0xf000) << 4));
6655        AdvanceIT();
6656        return;
6657      }
6658    } else {
6659      // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1
6660      if ((imm <= 65535) && cond.IsNotNever()) {
6661        EmitA32(0x03400000U | (cond.GetCondition() << 28) |
6662                (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6663        return;
6664      }
6665    }
6666  }
6667  Delegate(kMovt, &Assembler::movt, cond, rd, operand);
6668}
6669
6670void Assembler::movw(Condition cond, Register rd, const Operand& operand) {
6671  VIXL_ASSERT(AllowAssembler());
6672  CheckIT(cond);
6673  if (operand.IsImmediate()) {
6674    uint32_t imm = operand.GetImmediate();
6675    if (IsUsingT32()) {
6676      // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3
6677      if ((imm <= 65535)) {
6678        EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
6679                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6680                   ((imm & 0xf000) << 4));
6681        AdvanceIT();
6682        return;
6683      }
6684    } else {
6685      // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2
6686      if ((imm <= 65535) && cond.IsNotNever()) {
6687        EmitA32(0x03000000U | (cond.GetCondition() << 28) |
6688                (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6689        return;
6690      }
6691    }
6692  }
6693  Delegate(kMovw, &Assembler::movw, cond, rd, operand);
6694}
6695
6696void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) {
6697  VIXL_ASSERT(AllowAssembler());
6698  CheckIT(cond);
6699  if (IsUsingT32()) {
6700    // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1
6701    EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20));
6702    AdvanceIT();
6703    return;
6704  } else {
6705    // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1
6706    if (cond.IsNotNever()) {
6707      EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
6708              (spec_reg.GetReg() << 22));
6709      return;
6710    }
6711  }
6712  Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg);
6713}
6714
6715void Assembler::msr(Condition cond,
6716                    MaskedSpecialRegister spec_reg,
6717                    const Operand& operand) {
6718  VIXL_ASSERT(AllowAssembler());
6719  CheckIT(cond);
6720  if (operand.IsImmediate()) {
6721    uint32_t imm = operand.GetImmediate();
6722    if (IsUsingA32()) {
6723      ImmediateA32 immediate_a32(imm);
6724      // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1
6725      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6726        EmitA32(0x0320f000U | (cond.GetCondition() << 28) |
6727                ((spec_reg.GetReg() & 0xf) << 16) |
6728                ((spec_reg.GetReg() & 0x10) << 18) |
6729                immediate_a32.GetEncodingValue());
6730        return;
6731      }
6732    }
6733  }
6734  if (operand.IsPlainRegister()) {
6735    Register rn = operand.GetBaseRegister();
6736    if (IsUsingT32()) {
6737      // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1
6738      EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) |
6739                 ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16));
6740      AdvanceIT();
6741      return;
6742    } else {
6743      // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1
6744      if (cond.IsNotNever()) {
6745        EmitA32(0x0120f000U | (cond.GetCondition() << 28) |
6746                ((spec_reg.GetReg() & 0xf) << 16) |
6747                ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode());
6748        return;
6749      }
6750    }
6751  }
6752  Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand);
6753}
6754
6755void Assembler::mul(
6756    Condition cond, EncodingSize size, Register rd, Register rn, Register rm) {
6757  VIXL_ASSERT(AllowAssembler());
6758  CheckIT(cond);
6759  if (IsUsingT32()) {
6760    // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
6761    if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() &&
6762        rm.IsLow()) {
6763      EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
6764      AdvanceIT();
6765      return;
6766    }
6767    // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2
6768    if (!size.IsNarrow()) {
6769      EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6770                 rm.GetCode());
6771      AdvanceIT();
6772      return;
6773    }
6774  } else {
6775    // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
6776    if (cond.IsNotNever()) {
6777      EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6778              rn.GetCode() | (rm.GetCode() << 8));
6779      return;
6780    }
6781  }
6782  Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm);
6783}
6784
6785void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) {
6786  VIXL_ASSERT(AllowAssembler());
6787  CheckIT(cond);
6788  if (IsUsingT32()) {
6789    // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
6790    if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) {
6791      EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
6792      AdvanceIT();
6793      return;
6794    }
6795  } else {
6796    // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
6797    if (cond.IsNotNever()) {
6798      EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6799              rn.GetCode() | (rm.GetCode() << 8));
6800      return;
6801    }
6802  }
6803  Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm);
6804}
6805
6806void Assembler::mvn(Condition cond,
6807                    EncodingSize size,
6808                    Register rd,
6809                    const Operand& operand) {
6810  VIXL_ASSERT(AllowAssembler());
6811  CheckIT(cond);
6812  if (operand.IsImmediate()) {
6813    uint32_t imm = operand.GetImmediate();
6814    if (IsUsingT32()) {
6815      ImmediateT32 immediate_t32(imm);
6816      // MVN{<c>}{<q>} <Rd>, #<const> ; T1
6817      if (!size.IsNarrow() && immediate_t32.IsValid()) {
6818        EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) |
6819                   (immediate_t32.GetEncodingValue() & 0xff) |
6820                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6821                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6822        AdvanceIT();
6823        return;
6824      }
6825    } else {
6826      ImmediateA32 immediate_a32(imm);
6827      // MVN{<c>}{<q>} <Rd>, #<const> ; A1
6828      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6829        EmitA32(0x03e00000U | (cond.GetCondition() << 28) |
6830                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6831        return;
6832      }
6833    }
6834  }
6835  if (operand.IsImmediateShiftedRegister()) {
6836    Register rm = operand.GetBaseRegister();
6837    if (operand.IsPlainRegister()) {
6838      if (IsUsingT32()) {
6839        // MVN<c>{<q>} <Rd>, <Rm> ; T1
6840        if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
6841          EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
6842          AdvanceIT();
6843          return;
6844        }
6845      }
6846    }
6847    Shift shift = operand.GetShift();
6848    uint32_t amount = operand.GetShiftAmount();
6849    if (IsUsingT32()) {
6850      // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6851      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6852        uint32_t amount_ = amount % 32;
6853        EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6854                   (operand.GetTypeEncodingValue() << 4) |
6855                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6856        AdvanceIT();
6857        return;
6858      }
6859    } else {
6860      // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6861      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6862        uint32_t amount_ = amount % 32;
6863        EmitA32(0x01e00000U | (cond.GetCondition() << 28) |
6864                (rd.GetCode() << 12) | rm.GetCode() |
6865                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6866        return;
6867      }
6868    }
6869  }
6870  if (operand.IsRegisterShiftedRegister()) {
6871    Register rm = operand.GetBaseRegister();
6872    Shift shift = operand.GetShift();
6873    if (IsUsingA32()) {
6874      // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6875      if (cond.IsNotNever()) {
6876        EmitA32(0x01e00010U | (cond.GetCondition() << 28) |
6877                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6878                (operand.GetShiftRegister().GetCode() << 8));
6879        return;
6880      }
6881    }
6882  }
6883  Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand);
6884}
6885
6886void Assembler::mvns(Condition cond,
6887                     EncodingSize size,
6888                     Register rd,
6889                     const Operand& operand) {
6890  VIXL_ASSERT(AllowAssembler());
6891  CheckIT(cond);
6892  if (operand.IsImmediate()) {
6893    uint32_t imm = operand.GetImmediate();
6894    if (IsUsingT32()) {
6895      ImmediateT32 immediate_t32(imm);
6896      // MVNS{<c>}{<q>} <Rd>, #<const> ; T1
6897      if (!size.IsNarrow() && immediate_t32.IsValid()) {
6898        EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) |
6899                   (immediate_t32.GetEncodingValue() & 0xff) |
6900                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6901                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6902        AdvanceIT();
6903        return;
6904      }
6905    } else {
6906      ImmediateA32 immediate_a32(imm);
6907      // MVNS{<c>}{<q>} <Rd>, #<const> ; A1
6908      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6909        EmitA32(0x03f00000U | (cond.GetCondition() << 28) |
6910                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6911        return;
6912      }
6913    }
6914  }
6915  if (operand.IsImmediateShiftedRegister()) {
6916    Register rm = operand.GetBaseRegister();
6917    if (operand.IsPlainRegister()) {
6918      if (IsUsingT32()) {
6919        // MVNS{<q>} <Rd>, <Rm> ; T1
6920        if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
6921          EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
6922          AdvanceIT();
6923          return;
6924        }
6925      }
6926    }
6927    Shift shift = operand.GetShift();
6928    uint32_t amount = operand.GetShiftAmount();
6929    if (IsUsingT32()) {
6930      // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6931      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6932        uint32_t amount_ = amount % 32;
6933        EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6934                   (operand.GetTypeEncodingValue() << 4) |
6935                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6936        AdvanceIT();
6937        return;
6938      }
6939    } else {
6940      // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6941      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6942        uint32_t amount_ = amount % 32;
6943        EmitA32(0x01f00000U | (cond.GetCondition() << 28) |
6944                (rd.GetCode() << 12) | rm.GetCode() |
6945                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6946        return;
6947      }
6948    }
6949  }
6950  if (operand.IsRegisterShiftedRegister()) {
6951    Register rm = operand.GetBaseRegister();
6952    Shift shift = operand.GetShift();
6953    if (IsUsingA32()) {
6954      // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6955      if (cond.IsNotNever()) {
6956        EmitA32(0x01f00010U | (cond.GetCondition() << 28) |
6957                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6958                (operand.GetShiftRegister().GetCode() << 8));
6959        return;
6960      }
6961    }
6962  }
6963  Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand);
6964}
6965
6966void Assembler::nop(Condition cond, EncodingSize size) {
6967  VIXL_ASSERT(AllowAssembler());
6968  CheckIT(cond);
6969  if (IsUsingT32()) {
6970    // NOP{<c>}{<q>} ; T1
6971    if (!size.IsWide()) {
6972      EmitT32_16(0xbf00);
6973      AdvanceIT();
6974      return;
6975    }
6976    // NOP{<c>}.W ; T2
6977    if (!size.IsNarrow()) {
6978      EmitT32_32(0xf3af8000U);
6979      AdvanceIT();
6980      return;
6981    }
6982  } else {
6983    // NOP{<c>}{<q>} ; A1
6984    if (cond.IsNotNever()) {
6985      EmitA32(0x0320f000U | (cond.GetCondition() << 28));
6986      return;
6987    }
6988  }
6989  Delegate(kNop, &Assembler::nop, cond, size);
6990}
6991
6992void Assembler::orn(Condition cond,
6993                    Register rd,
6994                    Register rn,
6995                    const Operand& operand) {
6996  VIXL_ASSERT(AllowAssembler());
6997  CheckIT(cond);
6998  if (operand.IsImmediate()) {
6999    uint32_t imm = operand.GetImmediate();
7000    if (IsUsingT32()) {
7001      ImmediateT32 immediate_t32(imm);
7002      // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7003      if (immediate_t32.IsValid() && !rn.Is(pc)) {
7004        EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7005                   (immediate_t32.GetEncodingValue() & 0xff) |
7006                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7007                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7008        AdvanceIT();
7009        return;
7010      }
7011    }
7012  }
7013  if (operand.IsImmediateShiftedRegister()) {
7014    Register rm = operand.GetBaseRegister();
7015    Shift shift = operand.GetShift();
7016    uint32_t amount = operand.GetShiftAmount();
7017    if (IsUsingT32()) {
7018      // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
7019      if (shift.IsValidAmount(amount) && !rn.Is(pc)) {
7020        uint32_t amount_ = amount % 32;
7021        EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7022                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7023                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7024        AdvanceIT();
7025        return;
7026      }
7027    }
7028  }
7029  Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand);
7030}
7031
7032void Assembler::orns(Condition cond,
7033                     Register rd,
7034                     Register rn,
7035                     const Operand& operand) {
7036  VIXL_ASSERT(AllowAssembler());
7037  CheckIT(cond);
7038  if (operand.IsImmediate()) {
7039    uint32_t imm = operand.GetImmediate();
7040    if (IsUsingT32()) {
7041      ImmediateT32 immediate_t32(imm);
7042      // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7043      if (immediate_t32.IsValid() && !rn.Is(pc)) {
7044        EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7045                   (immediate_t32.GetEncodingValue() & 0xff) |
7046                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7047                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7048        AdvanceIT();
7049        return;
7050      }
7051    }
7052  }
7053  if (operand.IsImmediateShiftedRegister()) {
7054    Register rm = operand.GetBaseRegister();
7055    Shift shift = operand.GetShift();
7056    uint32_t amount = operand.GetShiftAmount();
7057    if (IsUsingT32()) {
7058      // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
7059      if (shift.IsValidAmount(amount) && !rn.Is(pc)) {
7060        uint32_t amount_ = amount % 32;
7061        EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7062                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7063                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7064        AdvanceIT();
7065        return;
7066      }
7067    }
7068  }
7069  Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand);
7070}
7071
7072void Assembler::orr(Condition cond,
7073                    EncodingSize size,
7074                    Register rd,
7075                    Register rn,
7076                    const Operand& operand) {
7077  VIXL_ASSERT(AllowAssembler());
7078  CheckIT(cond);
7079  if (operand.IsImmediate()) {
7080    uint32_t imm = operand.GetImmediate();
7081    if (IsUsingT32()) {
7082      ImmediateT32 immediate_t32(imm);
7083      // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7084      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) {
7085        EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7086                   (immediate_t32.GetEncodingValue() & 0xff) |
7087                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7088                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7089        AdvanceIT();
7090        return;
7091      }
7092    } else {
7093      ImmediateA32 immediate_a32(imm);
7094      // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7095      if (immediate_a32.IsValid() && cond.IsNotNever()) {
7096        EmitA32(0x03800000U | (cond.GetCondition() << 28) |
7097                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7098                immediate_a32.GetEncodingValue());
7099        return;
7100      }
7101    }
7102  }
7103  if (operand.IsImmediateShiftedRegister()) {
7104    Register rm = operand.GetBaseRegister();
7105    if (operand.IsPlainRegister()) {
7106      if (IsUsingT32()) {
7107        // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7108        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7109            rm.IsLow()) {
7110          EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7111          AdvanceIT();
7112          return;
7113        }
7114      }
7115    }
7116    Shift shift = operand.GetShift();
7117    uint32_t amount = operand.GetShiftAmount();
7118    if (IsUsingT32()) {
7119      // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7120      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) {
7121        uint32_t amount_ = amount % 32;
7122        EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7123                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7124                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7125        AdvanceIT();
7126        return;
7127      }
7128    } else {
7129      // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7130      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7131        uint32_t amount_ = amount % 32;
7132        EmitA32(0x01800000U | (cond.GetCondition() << 28) |
7133                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7134                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7135        return;
7136      }
7137    }
7138  }
7139  if (operand.IsRegisterShiftedRegister()) {
7140    Register rm = operand.GetBaseRegister();
7141    Shift shift = operand.GetShift();
7142    if (IsUsingA32()) {
7143      // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7144      if (cond.IsNotNever()) {
7145        EmitA32(0x01800010U | (cond.GetCondition() << 28) |
7146                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7147                (shift.GetType() << 5) |
7148                (operand.GetShiftRegister().GetCode() << 8));
7149        return;
7150      }
7151    }
7152  }
7153  Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand);
7154}
7155
7156void Assembler::orrs(Condition cond,
7157                     EncodingSize size,
7158                     Register rd,
7159                     Register rn,
7160                     const Operand& operand) {
7161  VIXL_ASSERT(AllowAssembler());
7162  CheckIT(cond);
7163  if (operand.IsImmediate()) {
7164    uint32_t imm = operand.GetImmediate();
7165    if (IsUsingT32()) {
7166      ImmediateT32 immediate_t32(imm);
7167      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7168      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) {
7169        EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7170                   (immediate_t32.GetEncodingValue() & 0xff) |
7171                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7172                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7173        AdvanceIT();
7174        return;
7175      }
7176    } else {
7177      ImmediateA32 immediate_a32(imm);
7178      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7179      if (immediate_a32.IsValid() && cond.IsNotNever()) {
7180        EmitA32(0x03900000U | (cond.GetCondition() << 28) |
7181                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7182                immediate_a32.GetEncodingValue());
7183        return;
7184      }
7185    }
7186  }
7187  if (operand.IsImmediateShiftedRegister()) {
7188    Register rm = operand.GetBaseRegister();
7189    if (operand.IsPlainRegister()) {
7190      if (IsUsingT32()) {
7191        // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7192        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7193            rm.IsLow()) {
7194          EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7195          AdvanceIT();
7196          return;
7197        }
7198      }
7199    }
7200    Shift shift = operand.GetShift();
7201    uint32_t amount = operand.GetShiftAmount();
7202    if (IsUsingT32()) {
7203      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7204      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) {
7205        uint32_t amount_ = amount % 32;
7206        EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7207                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7208                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7209        AdvanceIT();
7210        return;
7211      }
7212    } else {
7213      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7214      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7215        uint32_t amount_ = amount % 32;
7216        EmitA32(0x01900000U | (cond.GetCondition() << 28) |
7217                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7218                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7219        return;
7220      }
7221    }
7222  }
7223  if (operand.IsRegisterShiftedRegister()) {
7224    Register rm = operand.GetBaseRegister();
7225    Shift shift = operand.GetShift();
7226    if (IsUsingA32()) {
7227      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7228      if (cond.IsNotNever()) {
7229        EmitA32(0x01900010U | (cond.GetCondition() << 28) |
7230                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7231                (shift.GetType() << 5) |
7232                (operand.GetShiftRegister().GetCode() << 8));
7233        return;
7234      }
7235    }
7236  }
7237  Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand);
7238}
7239
7240void Assembler::pkhbt(Condition cond,
7241                      Register rd,
7242                      Register rn,
7243                      const Operand& operand) {
7244  VIXL_ASSERT(AllowAssembler());
7245  CheckIT(cond);
7246  if (operand.IsImmediateShiftedRegister()) {
7247    Register rm = operand.GetBaseRegister();
7248    Shift shift = operand.GetShift();
7249    uint32_t amount = operand.GetShiftAmount();
7250    if (IsUsingT32()) {
7251      // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1
7252      if (shift.IsLSL() && shift.IsValidAmount(amount)) {
7253        EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7254                   rm.GetCode() | ((amount & 0x3) << 6) |
7255                   ((amount & 0x1c) << 10));
7256        AdvanceIT();
7257        return;
7258      }
7259    } else {
7260      // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1
7261      if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever()) {
7262        EmitA32(0x06800010U | (cond.GetCondition() << 28) |
7263                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7264                (amount << 7));
7265        return;
7266      }
7267    }
7268  }
7269  Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand);
7270}
7271
7272void Assembler::pkhtb(Condition cond,
7273                      Register rd,
7274                      Register rn,
7275                      const Operand& operand) {
7276  VIXL_ASSERT(AllowAssembler());
7277  CheckIT(cond);
7278  if (operand.IsImmediateShiftedRegister()) {
7279    Register rm = operand.GetBaseRegister();
7280    Shift shift = operand.GetShift();
7281    uint32_t amount = operand.GetShiftAmount();
7282    if (IsUsingT32()) {
7283      // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1
7284      if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount)) {
7285        uint32_t amount_ = amount % 32;
7286        EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7287                   rm.GetCode() | ((amount_ & 0x3) << 6) |
7288                   ((amount_ & 0x1c) << 10));
7289        AdvanceIT();
7290        return;
7291      }
7292    } else {
7293      // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1
7294      if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
7295          cond.IsNotNever()) {
7296        uint32_t amount_ = amount % 32;
7297        EmitA32(0x06800050U | (cond.GetCondition() << 28) |
7298                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7299                (amount_ << 7));
7300        return;
7301      }
7302    }
7303  }
7304  Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand);
7305}
7306
7307void Assembler::pld(Condition cond, Label* label) {
7308  VIXL_ASSERT(AllowAssembler());
7309  CheckIT(cond);
7310  Label::Offset offset =
7311      label->IsBound()
7312          ? label->GetLocation() -
7313                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
7314          : 0;
7315  if (IsUsingT32()) {
7316    // PLD{<c>}{<q>} <label> ; T1
7317    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7318         !label->IsBound())) {
7319      static class EmitOp : public Label::LabelEmitOperator {
7320       public:
7321        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7322        virtual uint32_t Encode(uint32_t instr,
7323                                Label::Offset pc,
7324                                const Label* label) const VIXL_OVERRIDE {
7325          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7326          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7327          uint32_t U = (offset >= 0) && !label->IsMinusZero();
7328          int32_t target = abs(offset) | (U << 12);
7329          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7330        }
7331      } immop;
7332      EmitT32_32(Link(0xf81ff000U, label, immop));
7333      AdvanceIT();
7334      return;
7335    }
7336  } else {
7337    // PLD{<c>}{<q>} <label> ; A1
7338    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7339         !label->IsBound())) {
7340      if (cond.Is(al)) {
7341        static class EmitOp : public Label::LabelEmitOperator {
7342         public:
7343          EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7344          virtual uint32_t Encode(uint32_t instr,
7345                                  Label::Offset pc,
7346                                  const Label* label) const VIXL_OVERRIDE {
7347            Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7348            VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7349            uint32_t U = (offset >= 0) && !label->IsMinusZero();
7350            int32_t target = abs(offset) | (U << 12);
7351            return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7352          }
7353        } immop;
7354        EmitA32(Link(0xf55ff000U, label, immop));
7355        return;
7356      }
7357    }
7358  }
7359  Delegate(kPld, &Assembler::pld, cond, label);
7360}
7361
7362void Assembler::pld(Condition cond, const MemOperand& operand) {
7363  VIXL_ASSERT(AllowAssembler());
7364  CheckIT(cond);
7365  if (operand.IsImmediate()) {
7366    Register rn = operand.GetBaseRegister();
7367    int32_t offset = operand.GetOffsetImmediate();
7368    if (IsUsingT32()) {
7369      // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1
7370      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc)) {
7371        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7372        uint32_t offset_ = abs(offset);
7373        EmitT32_32(0xf81ff000U | offset_ | (sign << 23));
7374        AdvanceIT();
7375        return;
7376      }
7377    } else {
7378      // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1
7379      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc)) {
7380        if (cond.Is(al)) {
7381          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7382          uint32_t offset_ = abs(offset);
7383          EmitA32(0xf55ff000U | offset_ | (sign << 23));
7384          return;
7385        }
7386      }
7387    }
7388  }
7389  if (operand.IsImmediate()) {
7390    Register rn = operand.GetBaseRegister();
7391    int32_t offset = operand.GetOffsetImmediate();
7392    if (IsUsingT32()) {
7393      // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7394      if ((offset >= 0) && (offset <= 4095) && ((rn.GetCode() & 0xf) != 0xf)) {
7395        EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7396        AdvanceIT();
7397        return;
7398      }
7399      // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7400      if ((-offset >= 0) && (-offset <= 255) && ((rn.GetCode() & 0xf) != 0xf)) {
7401        EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7402        AdvanceIT();
7403        return;
7404      }
7405    } else {
7406      // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
7407      if ((offset >= -4095) && (offset <= 4095) &&
7408          ((rn.GetCode() & 0xf) != 0xf)) {
7409        if (cond.Is(al)) {
7410          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7411          uint32_t offset_ = abs(offset);
7412          EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7413          return;
7414        }
7415      }
7416    }
7417  }
7418  if (operand.IsShiftedRegister()) {
7419    Register rn = operand.GetBaseRegister();
7420    Sign sign = operand.GetSign();
7421    Register rm = operand.GetOffsetRegister();
7422    Shift shift = operand.GetShift();
7423    uint32_t amount = operand.GetShiftAmount();
7424    if (IsUsingT32()) {
7425      // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7426      if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
7427          ((rn.GetCode() & 0xf) != 0xf)) {
7428        EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() |
7429                   (amount << 4));
7430        AdvanceIT();
7431        return;
7432      }
7433    } else {
7434      // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7435      if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
7436        if (cond.Is(al)) {
7437          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7438          uint32_t amount_ = amount % 32;
7439          EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() |
7440                  (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7441          return;
7442        }
7443      }
7444      // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7445      if (shift.IsRRX() && operand.IsOffset()) {
7446        if (cond.Is(al)) {
7447          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7448          EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() |
7449                  (sign_ << 23));
7450          return;
7451        }
7452      }
7453    }
7454  }
7455  Delegate(kPld, &Assembler::pld, cond, operand);
7456}
7457
7458void Assembler::pldw(Condition cond, const MemOperand& operand) {
7459  VIXL_ASSERT(AllowAssembler());
7460  CheckIT(cond);
7461  if (operand.IsImmediate()) {
7462    Register rn = operand.GetBaseRegister();
7463    int32_t offset = operand.GetOffsetImmediate();
7464    if (IsUsingT32()) {
7465      // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7466      if ((offset >= 0) && (offset <= 4095) && ((rn.GetCode() & 0xf) != 0xf)) {
7467        EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7468        AdvanceIT();
7469        return;
7470      }
7471      // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7472      if ((-offset >= 0) && (-offset <= 255) && ((rn.GetCode() & 0xf) != 0xf)) {
7473        EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7474        AdvanceIT();
7475        return;
7476      }
7477    } else {
7478      // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
7479      if ((offset >= -4095) && (offset <= 4095) &&
7480          ((rn.GetCode() & 0xf) != 0xf)) {
7481        if (cond.Is(al)) {
7482          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7483          uint32_t offset_ = abs(offset);
7484          EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7485          return;
7486        }
7487      }
7488    }
7489  }
7490  if (operand.IsShiftedRegister()) {
7491    Register rn = operand.GetBaseRegister();
7492    Sign sign = operand.GetSign();
7493    Register rm = operand.GetOffsetRegister();
7494    Shift shift = operand.GetShift();
7495    uint32_t amount = operand.GetShiftAmount();
7496    if (IsUsingT32()) {
7497      // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7498      if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
7499          ((rn.GetCode() & 0xf) != 0xf)) {
7500        EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() |
7501                   (amount << 4));
7502        AdvanceIT();
7503        return;
7504      }
7505    } else {
7506      // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7507      if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
7508        if (cond.Is(al)) {
7509          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7510          uint32_t amount_ = amount % 32;
7511          EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() |
7512                  (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7513          return;
7514        }
7515      }
7516      // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7517      if (shift.IsRRX() && operand.IsOffset()) {
7518        if (cond.Is(al)) {
7519          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7520          EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() |
7521                  (sign_ << 23));
7522          return;
7523        }
7524      }
7525    }
7526  }
7527  Delegate(kPldw, &Assembler::pldw, cond, operand);
7528}
7529
7530void Assembler::pli(Condition cond, const MemOperand& operand) {
7531  VIXL_ASSERT(AllowAssembler());
7532  CheckIT(cond);
7533  if (operand.IsImmediate()) {
7534    Register rn = operand.GetBaseRegister();
7535    int32_t offset = operand.GetOffsetImmediate();
7536    if (IsUsingT32()) {
7537      // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7538      if ((offset >= 0) && (offset <= 4095) && ((rn.GetCode() & 0xf) != 0xf)) {
7539        EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7540        AdvanceIT();
7541        return;
7542      }
7543      // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7544      if ((-offset >= 0) && (-offset <= 255) && ((rn.GetCode() & 0xf) != 0xf)) {
7545        EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7546        AdvanceIT();
7547        return;
7548      }
7549    } else {
7550      // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1
7551      if ((offset >= -4095) && (offset <= 4095) &&
7552          ((rn.GetCode() & 0xf) != 0xf)) {
7553        if (cond.Is(al)) {
7554          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7555          uint32_t offset_ = abs(offset);
7556          EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7557          return;
7558        }
7559      }
7560    }
7561  }
7562  if (operand.IsImmediate()) {
7563    Register rn = operand.GetBaseRegister();
7564    int32_t offset = operand.GetOffsetImmediate();
7565    if (IsUsingT32()) {
7566      // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3
7567      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc)) {
7568        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7569        uint32_t offset_ = abs(offset);
7570        EmitT32_32(0xf91ff000U | offset_ | (sign << 23));
7571        AdvanceIT();
7572        return;
7573      }
7574    } else {
7575      // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1
7576      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc)) {
7577        if (cond.Is(al)) {
7578          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7579          uint32_t offset_ = abs(offset);
7580          EmitA32(0xf45ff000U | offset_ | (sign << 23));
7581          return;
7582        }
7583      }
7584    }
7585  }
7586  if (operand.IsShiftedRegister()) {
7587    Register rn = operand.GetBaseRegister();
7588    Sign sign = operand.GetSign();
7589    Register rm = operand.GetOffsetRegister();
7590    Shift shift = operand.GetShift();
7591    uint32_t amount = operand.GetShiftAmount();
7592    if (IsUsingT32()) {
7593      // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7594      if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
7595          ((rn.GetCode() & 0xf) != 0xf)) {
7596        EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() |
7597                   (amount << 4));
7598        AdvanceIT();
7599        return;
7600      }
7601    } else {
7602      // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7603      if (shift.IsRRX() && operand.IsOffset()) {
7604        if (cond.Is(al)) {
7605          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7606          EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() |
7607                  (sign_ << 23));
7608          return;
7609        }
7610      }
7611      // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7612      if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
7613        if (cond.Is(al)) {
7614          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7615          uint32_t amount_ = amount % 32;
7616          EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() |
7617                  (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7618          return;
7619        }
7620      }
7621    }
7622  }
7623  Delegate(kPli, &Assembler::pli, cond, operand);
7624}
7625
7626void Assembler::pli(Condition cond, Label* label) {
7627  VIXL_ASSERT(AllowAssembler());
7628  CheckIT(cond);
7629  Label::Offset offset =
7630      label->IsBound()
7631          ? label->GetLocation() -
7632                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
7633          : 0;
7634  if (IsUsingT32()) {
7635    // PLI{<c>}{<q>} <label> ; T3
7636    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7637         !label->IsBound())) {
7638      static class EmitOp : public Label::LabelEmitOperator {
7639       public:
7640        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7641        virtual uint32_t Encode(uint32_t instr,
7642                                Label::Offset pc,
7643                                const Label* label) const VIXL_OVERRIDE {
7644          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7645          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7646          uint32_t U = (offset >= 0) && !label->IsMinusZero();
7647          int32_t target = abs(offset) | (U << 12);
7648          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7649        }
7650      } immop;
7651      EmitT32_32(Link(0xf91ff000U, label, immop));
7652      AdvanceIT();
7653      return;
7654    }
7655  } else {
7656    // PLI{<c>}{<q>} <label> ; A1
7657    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7658         !label->IsBound())) {
7659      if (cond.Is(al)) {
7660        static class EmitOp : public Label::LabelEmitOperator {
7661         public:
7662          EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7663          virtual uint32_t Encode(uint32_t instr,
7664                                  Label::Offset pc,
7665                                  const Label* label) const VIXL_OVERRIDE {
7666            Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7667            VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7668            uint32_t U = (offset >= 0) && !label->IsMinusZero();
7669            int32_t target = abs(offset) | (U << 12);
7670            return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7671          }
7672        } immop;
7673        EmitA32(Link(0xf45ff000U, label, immop));
7674        return;
7675      }
7676    }
7677  }
7678  Delegate(kPli, &Assembler::pli, cond, label);
7679}
7680
7681void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) {
7682  VIXL_ASSERT(AllowAssembler());
7683  CheckIT(cond);
7684  if (IsUsingT32()) {
7685    // POP{<c>}{<q>} <registers> ; T1
7686    if (!size.IsWide() && ((registers.GetList() & ~0x80ff) == 0)) {
7687      EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
7688                 GetRegisterListEncoding(registers, 0, 8));
7689      AdvanceIT();
7690      return;
7691    }
7692    // POP{<c>}{<q>} <registers> ; T2
7693    if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
7694      EmitT32_32(0xe8bd0000U |
7695                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
7696                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
7697                 GetRegisterListEncoding(registers, 0, 13));
7698      AdvanceIT();
7699      return;
7700    }
7701  } else {
7702    // POP{<c>}{<q>} <registers> ; A1
7703    if (cond.IsNotNever()) {
7704      EmitA32(0x08bd0000U | (cond.GetCondition() << 28) |
7705              GetRegisterListEncoding(registers, 0, 16));
7706      return;
7707    }
7708  }
7709  Delegate(kPop, &Assembler::pop, cond, size, registers);
7710}
7711
7712void Assembler::pop(Condition cond, EncodingSize size, Register rt) {
7713  VIXL_ASSERT(AllowAssembler());
7714  CheckIT(cond);
7715  if (IsUsingT32()) {
7716    // POP{<c>}{<q>} <single_register_list> ; T4
7717    if (!size.IsNarrow() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) {
7718      EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12));
7719      AdvanceIT();
7720      return;
7721    }
7722  } else {
7723    // POP{<c>}{<q>} <single_register_list> ; A1
7724    if (cond.IsNotNever()) {
7725      EmitA32(0x049d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
7726      return;
7727    }
7728  }
7729  Delegate(kPop, &Assembler::pop, cond, size, rt);
7730}
7731
7732void Assembler::push(Condition cond,
7733                     EncodingSize size,
7734                     RegisterList registers) {
7735  VIXL_ASSERT(AllowAssembler());
7736  CheckIT(cond);
7737  if (IsUsingT32()) {
7738    // PUSH{<c>}{<q>} <registers> ; T1
7739    if (!size.IsWide() && ((registers.GetList() & ~0x40ff) == 0)) {
7740      EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
7741                 GetRegisterListEncoding(registers, 0, 8));
7742      AdvanceIT();
7743      return;
7744    }
7745    // PUSH{<c>}{<q>} <registers> ; T1
7746    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
7747      EmitT32_32(0xe92d0000U |
7748                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
7749                 GetRegisterListEncoding(registers, 0, 13));
7750      AdvanceIT();
7751      return;
7752    }
7753  } else {
7754    // PUSH{<c>}{<q>} <registers> ; A1
7755    if (cond.IsNotNever()) {
7756      EmitA32(0x092d0000U | (cond.GetCondition() << 28) |
7757              GetRegisterListEncoding(registers, 0, 16));
7758      return;
7759    }
7760  }
7761  Delegate(kPush, &Assembler::push, cond, size, registers);
7762}
7763
7764void Assembler::push(Condition cond, EncodingSize size, Register rt) {
7765  VIXL_ASSERT(AllowAssembler());
7766  CheckIT(cond);
7767  if (IsUsingT32()) {
7768    // PUSH{<c>}{<q>} <single_register_list> ; T4
7769    if (!size.IsNarrow()) {
7770      EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12));
7771      AdvanceIT();
7772      return;
7773    }
7774  } else {
7775    // PUSH{<c>}{<q>} <single_register_list> ; A1
7776    if (cond.IsNotNever() && ((!rt.IsPC()) || AllowUnpredictable())) {
7777      EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
7778      return;
7779    }
7780  }
7781  Delegate(kPush, &Assembler::push, cond, size, rt);
7782}
7783
7784void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) {
7785  VIXL_ASSERT(AllowAssembler());
7786  CheckIT(cond);
7787  if (IsUsingT32()) {
7788    // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7789    EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() |
7790               (rn.GetCode() << 16));
7791    AdvanceIT();
7792    return;
7793  } else {
7794    // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7795    if (cond.IsNotNever()) {
7796      EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7797              rm.GetCode() | (rn.GetCode() << 16));
7798      return;
7799    }
7800  }
7801  Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn);
7802}
7803
7804void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) {
7805  VIXL_ASSERT(AllowAssembler());
7806  CheckIT(cond);
7807  if (IsUsingT32()) {
7808    // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7809    EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7810               rm.GetCode());
7811    AdvanceIT();
7812    return;
7813  } else {
7814    // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7815    if (cond.IsNotNever()) {
7816      EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7817              (rn.GetCode() << 16) | rm.GetCode());
7818      return;
7819    }
7820  }
7821  Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm);
7822}
7823
7824void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) {
7825  VIXL_ASSERT(AllowAssembler());
7826  CheckIT(cond);
7827  if (IsUsingT32()) {
7828    // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7829    EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7830               rm.GetCode());
7831    AdvanceIT();
7832    return;
7833  } else {
7834    // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7835    if (cond.IsNotNever()) {
7836      EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7837              (rn.GetCode() << 16) | rm.GetCode());
7838      return;
7839    }
7840  }
7841  Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm);
7842}
7843
7844void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) {
7845  VIXL_ASSERT(AllowAssembler());
7846  CheckIT(cond);
7847  if (IsUsingT32()) {
7848    // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7849    EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7850               rm.GetCode());
7851    AdvanceIT();
7852    return;
7853  } else {
7854    // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7855    if (cond.IsNotNever()) {
7856      EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7857              (rn.GetCode() << 16) | rm.GetCode());
7858      return;
7859    }
7860  }
7861  Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm);
7862}
7863
7864void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) {
7865  VIXL_ASSERT(AllowAssembler());
7866  CheckIT(cond);
7867  if (IsUsingT32()) {
7868    // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7869    EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() |
7870               (rn.GetCode() << 16));
7871    AdvanceIT();
7872    return;
7873  } else {
7874    // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7875    if (cond.IsNotNever()) {
7876      EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7877              rm.GetCode() | (rn.GetCode() << 16));
7878      return;
7879    }
7880  }
7881  Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn);
7882}
7883
7884void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) {
7885  VIXL_ASSERT(AllowAssembler());
7886  CheckIT(cond);
7887  if (IsUsingT32()) {
7888    // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7889    EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
7890               (rn.GetCode() << 16));
7891    AdvanceIT();
7892    return;
7893  } else {
7894    // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7895    if (cond.IsNotNever()) {
7896      EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7897              rm.GetCode() | (rn.GetCode() << 16));
7898      return;
7899    }
7900  }
7901  Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn);
7902}
7903
7904void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) {
7905  VIXL_ASSERT(AllowAssembler());
7906  CheckIT(cond);
7907  if (IsUsingT32()) {
7908    // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7909    EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7910               rm.GetCode());
7911    AdvanceIT();
7912    return;
7913  } else {
7914    // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7915    if (cond.IsNotNever()) {
7916      EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7917              (rn.GetCode() << 16) | rm.GetCode());
7918      return;
7919    }
7920  }
7921  Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm);
7922}
7923
7924void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) {
7925  VIXL_ASSERT(AllowAssembler());
7926  CheckIT(cond);
7927  if (IsUsingT32()) {
7928    // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7929    EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
7930               (rn.GetCode() << 16));
7931    AdvanceIT();
7932    return;
7933  } else {
7934    // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7935    if (cond.IsNotNever()) {
7936      EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7937              rm.GetCode() | (rn.GetCode() << 16));
7938      return;
7939    }
7940  }
7941  Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn);
7942}
7943
7944void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) {
7945  VIXL_ASSERT(AllowAssembler());
7946  CheckIT(cond);
7947  if (IsUsingT32()) {
7948    // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7949    EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7950               rm.GetCode());
7951    AdvanceIT();
7952    return;
7953  } else {
7954    // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7955    if (cond.IsNotNever()) {
7956      EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7957              (rn.GetCode() << 16) | rm.GetCode());
7958      return;
7959    }
7960  }
7961  Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm);
7962}
7963
7964void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) {
7965  VIXL_ASSERT(AllowAssembler());
7966  CheckIT(cond);
7967  if (IsUsingT32()) {
7968    // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7969    EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7970               rm.GetCode());
7971    AdvanceIT();
7972    return;
7973  } else {
7974    // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7975    if (cond.IsNotNever()) {
7976      EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7977              (rn.GetCode() << 16) | rm.GetCode());
7978      return;
7979    }
7980  }
7981  Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm);
7982}
7983
7984void Assembler::rbit(Condition cond, Register rd, Register rm) {
7985  VIXL_ASSERT(AllowAssembler());
7986  CheckIT(cond);
7987  if (IsUsingT32()) {
7988    // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1
7989    EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
7990               (rm.GetCode() << 16));
7991    AdvanceIT();
7992    return;
7993  } else {
7994    // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1
7995    if (cond.IsNotNever()) {
7996      EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7997              rm.GetCode());
7998      return;
7999    }
8000  }
8001  Delegate(kRbit, &Assembler::rbit, cond, rd, rm);
8002}
8003
8004void Assembler::rev(Condition cond,
8005                    EncodingSize size,
8006                    Register rd,
8007                    Register rm) {
8008  VIXL_ASSERT(AllowAssembler());
8009  CheckIT(cond);
8010  if (IsUsingT32()) {
8011    // REV{<c>}{<q>} <Rd>, <Rm> ; T1
8012    if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8013      EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3));
8014      AdvanceIT();
8015      return;
8016    }
8017    // REV{<c>}{<q>} <Rd>, <Rm> ; T2
8018    if (!size.IsNarrow()) {
8019      EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() |
8020                 (rm.GetCode() << 16));
8021      AdvanceIT();
8022      return;
8023    }
8024  } else {
8025    // REV{<c>}{<q>} <Rd>, <Rm> ; A1
8026    if (cond.IsNotNever()) {
8027      EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8028              rm.GetCode());
8029      return;
8030    }
8031  }
8032  Delegate(kRev, &Assembler::rev, cond, size, rd, rm);
8033}
8034
8035void Assembler::rev16(Condition cond,
8036                      EncodingSize size,
8037                      Register rd,
8038                      Register rm) {
8039  VIXL_ASSERT(AllowAssembler());
8040  CheckIT(cond);
8041  if (IsUsingT32()) {
8042    // REV16{<c>}{<q>} <Rd>, <Rm> ; T1
8043    if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8044      EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3));
8045      AdvanceIT();
8046      return;
8047    }
8048    // REV16{<c>}{<q>} <Rd>, <Rm> ; T2
8049    if (!size.IsNarrow()) {
8050      EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() |
8051                 (rm.GetCode() << 16));
8052      AdvanceIT();
8053      return;
8054    }
8055  } else {
8056    // REV16{<c>}{<q>} <Rd>, <Rm> ; A1
8057    if (cond.IsNotNever()) {
8058      EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8059              rm.GetCode());
8060      return;
8061    }
8062  }
8063  Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm);
8064}
8065
8066void Assembler::revsh(Condition cond,
8067                      EncodingSize size,
8068                      Register rd,
8069                      Register rm) {
8070  VIXL_ASSERT(AllowAssembler());
8071  CheckIT(cond);
8072  if (IsUsingT32()) {
8073    // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1
8074    if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8075      EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3));
8076      AdvanceIT();
8077      return;
8078    }
8079    // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2
8080    if (!size.IsNarrow()) {
8081      EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
8082                 (rm.GetCode() << 16));
8083      AdvanceIT();
8084      return;
8085    }
8086  } else {
8087    // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1
8088    if (cond.IsNotNever()) {
8089      EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8090              rm.GetCode());
8091      return;
8092    }
8093  }
8094  Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm);
8095}
8096
8097void Assembler::ror(Condition cond,
8098                    EncodingSize size,
8099                    Register rd,
8100                    Register rm,
8101                    const Operand& operand) {
8102  VIXL_ASSERT(AllowAssembler());
8103  CheckIT(cond);
8104  if (operand.IsImmediate()) {
8105    uint32_t imm = operand.GetImmediate();
8106    if (IsUsingT32()) {
8107      // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
8108      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
8109        EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() |
8110                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
8111        AdvanceIT();
8112        return;
8113      }
8114    } else {
8115      // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
8116      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
8117        EmitA32(0x01a00060U | (cond.GetCondition() << 28) |
8118                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
8119        return;
8120      }
8121    }
8122  }
8123  if (operand.IsPlainRegister()) {
8124    Register rs = operand.GetBaseRegister();
8125    if (IsUsingT32()) {
8126      // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
8127      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
8128          rs.IsLow()) {
8129        EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
8130        AdvanceIT();
8131        return;
8132      }
8133      // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
8134      if (!size.IsNarrow()) {
8135        EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
8136                   rs.GetCode());
8137        AdvanceIT();
8138        return;
8139      }
8140    } else {
8141      // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
8142      if (cond.IsNotNever()) {
8143        EmitA32(0x01a00070U | (cond.GetCondition() << 28) |
8144                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
8145        return;
8146      }
8147    }
8148  }
8149  Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand);
8150}
8151
8152void Assembler::rors(Condition cond,
8153                     EncodingSize size,
8154                     Register rd,
8155                     Register rm,
8156                     const Operand& operand) {
8157  VIXL_ASSERT(AllowAssembler());
8158  CheckIT(cond);
8159  if (operand.IsImmediate()) {
8160    uint32_t imm = operand.GetImmediate();
8161    if (IsUsingT32()) {
8162      // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
8163      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
8164        EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() |
8165                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
8166        AdvanceIT();
8167        return;
8168      }
8169    } else {
8170      // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
8171      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
8172        EmitA32(0x01b00060U | (cond.GetCondition() << 28) |
8173                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
8174        return;
8175      }
8176    }
8177  }
8178  if (operand.IsPlainRegister()) {
8179    Register rs = operand.GetBaseRegister();
8180    if (IsUsingT32()) {
8181      // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
8182      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
8183          rs.IsLow()) {
8184        EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
8185        AdvanceIT();
8186        return;
8187      }
8188      // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
8189      if (!size.IsNarrow()) {
8190        EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
8191                   rs.GetCode());
8192        AdvanceIT();
8193        return;
8194      }
8195    } else {
8196      // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
8197      if (cond.IsNotNever()) {
8198        EmitA32(0x01b00070U | (cond.GetCondition() << 28) |
8199                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
8200        return;
8201      }
8202    }
8203  }
8204  Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand);
8205}
8206
8207void Assembler::rrx(Condition cond, Register rd, Register rm) {
8208  VIXL_ASSERT(AllowAssembler());
8209  CheckIT(cond);
8210  if (IsUsingT32()) {
8211    // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3
8212    EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode());
8213    AdvanceIT();
8214    return;
8215  } else {
8216    // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1
8217    if (cond.IsNotNever()) {
8218      EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8219              rm.GetCode());
8220      return;
8221    }
8222  }
8223  Delegate(kRrx, &Assembler::rrx, cond, rd, rm);
8224}
8225
8226void Assembler::rrxs(Condition cond, Register rd, Register rm) {
8227  VIXL_ASSERT(AllowAssembler());
8228  CheckIT(cond);
8229  if (IsUsingT32()) {
8230    // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3
8231    EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode());
8232    AdvanceIT();
8233    return;
8234  } else {
8235    // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1
8236    if (cond.IsNotNever()) {
8237      EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8238              rm.GetCode());
8239      return;
8240    }
8241  }
8242  Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm);
8243}
8244
8245void Assembler::rsb(Condition cond,
8246                    EncodingSize size,
8247                    Register rd,
8248                    Register rn,
8249                    const Operand& operand) {
8250  VIXL_ASSERT(AllowAssembler());
8251  CheckIT(cond);
8252  if (operand.IsImmediate()) {
8253    uint32_t imm = operand.GetImmediate();
8254    if (IsUsingT32()) {
8255      ImmediateT32 immediate_t32(imm);
8256      // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1
8257      if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
8258          (imm == 0)) {
8259        EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
8260        AdvanceIT();
8261        return;
8262      }
8263      // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
8264      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8265        EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8266                   (immediate_t32.GetEncodingValue() & 0xff) |
8267                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8268                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8269        AdvanceIT();
8270        return;
8271      }
8272    } else {
8273      ImmediateA32 immediate_a32(imm);
8274      // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8275      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8276        EmitA32(0x02600000U | (cond.GetCondition() << 28) |
8277                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8278                immediate_a32.GetEncodingValue());
8279        return;
8280      }
8281    }
8282  }
8283  if (operand.IsImmediateShiftedRegister()) {
8284    Register rm = operand.GetBaseRegister();
8285    Shift shift = operand.GetShift();
8286    uint32_t amount = operand.GetShiftAmount();
8287    if (IsUsingT32()) {
8288      // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
8289      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8290        uint32_t amount_ = amount % 32;
8291        EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8292                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8293                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8294        AdvanceIT();
8295        return;
8296      }
8297    } else {
8298      // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8299      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8300        uint32_t amount_ = amount % 32;
8301        EmitA32(0x00600000U | (cond.GetCondition() << 28) |
8302                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8303                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8304        return;
8305      }
8306    }
8307  }
8308  if (operand.IsRegisterShiftedRegister()) {
8309    Register rm = operand.GetBaseRegister();
8310    Shift shift = operand.GetShift();
8311    if (IsUsingA32()) {
8312      // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8313      if (cond.IsNotNever()) {
8314        EmitA32(0x00600010U | (cond.GetCondition() << 28) |
8315                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8316                (shift.GetType() << 5) |
8317                (operand.GetShiftRegister().GetCode() << 8));
8318        return;
8319      }
8320    }
8321  }
8322  Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand);
8323}
8324
8325void Assembler::rsbs(Condition cond,
8326                     EncodingSize size,
8327                     Register rd,
8328                     Register rn,
8329                     const Operand& operand) {
8330  VIXL_ASSERT(AllowAssembler());
8331  CheckIT(cond);
8332  if (operand.IsImmediate()) {
8333    uint32_t imm = operand.GetImmediate();
8334    if (IsUsingT32()) {
8335      ImmediateT32 immediate_t32(imm);
8336      // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1
8337      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
8338          (imm == 0)) {
8339        EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
8340        AdvanceIT();
8341        return;
8342      }
8343      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
8344      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8345        EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8346                   (immediate_t32.GetEncodingValue() & 0xff) |
8347                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8348                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8349        AdvanceIT();
8350        return;
8351      }
8352    } else {
8353      ImmediateA32 immediate_a32(imm);
8354      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8355      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8356        EmitA32(0x02700000U | (cond.GetCondition() << 28) |
8357                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8358                immediate_a32.GetEncodingValue());
8359        return;
8360      }
8361    }
8362  }
8363  if (operand.IsImmediateShiftedRegister()) {
8364    Register rm = operand.GetBaseRegister();
8365    Shift shift = operand.GetShift();
8366    uint32_t amount = operand.GetShiftAmount();
8367    if (IsUsingT32()) {
8368      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
8369      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8370        uint32_t amount_ = amount % 32;
8371        EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8372                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8373                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8374        AdvanceIT();
8375        return;
8376      }
8377    } else {
8378      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8379      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8380        uint32_t amount_ = amount % 32;
8381        EmitA32(0x00700000U | (cond.GetCondition() << 28) |
8382                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8383                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8384        return;
8385      }
8386    }
8387  }
8388  if (operand.IsRegisterShiftedRegister()) {
8389    Register rm = operand.GetBaseRegister();
8390    Shift shift = operand.GetShift();
8391    if (IsUsingA32()) {
8392      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8393      if (cond.IsNotNever()) {
8394        EmitA32(0x00700010U | (cond.GetCondition() << 28) |
8395                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8396                (shift.GetType() << 5) |
8397                (operand.GetShiftRegister().GetCode() << 8));
8398        return;
8399      }
8400    }
8401  }
8402  Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand);
8403}
8404
8405void Assembler::rsc(Condition cond,
8406                    Register rd,
8407                    Register rn,
8408                    const Operand& operand) {
8409  VIXL_ASSERT(AllowAssembler());
8410  CheckIT(cond);
8411  if (operand.IsImmediate()) {
8412    uint32_t imm = operand.GetImmediate();
8413    if (IsUsingA32()) {
8414      ImmediateA32 immediate_a32(imm);
8415      // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8416      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8417        EmitA32(0x02e00000U | (cond.GetCondition() << 28) |
8418                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8419                immediate_a32.GetEncodingValue());
8420        return;
8421      }
8422    }
8423  }
8424  if (operand.IsImmediateShiftedRegister()) {
8425    Register rm = operand.GetBaseRegister();
8426    Shift shift = operand.GetShift();
8427    uint32_t amount = operand.GetShiftAmount();
8428    if (IsUsingA32()) {
8429      // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8430      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8431        uint32_t amount_ = amount % 32;
8432        EmitA32(0x00e00000U | (cond.GetCondition() << 28) |
8433                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8434                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8435        return;
8436      }
8437    }
8438  }
8439  if (operand.IsRegisterShiftedRegister()) {
8440    Register rm = operand.GetBaseRegister();
8441    Shift shift = operand.GetShift();
8442    if (IsUsingA32()) {
8443      // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8444      if (cond.IsNotNever()) {
8445        EmitA32(0x00e00010U | (cond.GetCondition() << 28) |
8446                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8447                (shift.GetType() << 5) |
8448                (operand.GetShiftRegister().GetCode() << 8));
8449        return;
8450      }
8451    }
8452  }
8453  Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand);
8454}
8455
8456void Assembler::rscs(Condition cond,
8457                     Register rd,
8458                     Register rn,
8459                     const Operand& operand) {
8460  VIXL_ASSERT(AllowAssembler());
8461  CheckIT(cond);
8462  if (operand.IsImmediate()) {
8463    uint32_t imm = operand.GetImmediate();
8464    if (IsUsingA32()) {
8465      ImmediateA32 immediate_a32(imm);
8466      // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8467      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8468        EmitA32(0x02f00000U | (cond.GetCondition() << 28) |
8469                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8470                immediate_a32.GetEncodingValue());
8471        return;
8472      }
8473    }
8474  }
8475  if (operand.IsImmediateShiftedRegister()) {
8476    Register rm = operand.GetBaseRegister();
8477    Shift shift = operand.GetShift();
8478    uint32_t amount = operand.GetShiftAmount();
8479    if (IsUsingA32()) {
8480      // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8481      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8482        uint32_t amount_ = amount % 32;
8483        EmitA32(0x00f00000U | (cond.GetCondition() << 28) |
8484                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8485                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8486        return;
8487      }
8488    }
8489  }
8490  if (operand.IsRegisterShiftedRegister()) {
8491    Register rm = operand.GetBaseRegister();
8492    Shift shift = operand.GetShift();
8493    if (IsUsingA32()) {
8494      // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8495      if (cond.IsNotNever()) {
8496        EmitA32(0x00f00010U | (cond.GetCondition() << 28) |
8497                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8498                (shift.GetType() << 5) |
8499                (operand.GetShiftRegister().GetCode() << 8));
8500        return;
8501      }
8502    }
8503  }
8504  Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand);
8505}
8506
8507void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) {
8508  VIXL_ASSERT(AllowAssembler());
8509  CheckIT(cond);
8510  if (IsUsingT32()) {
8511    // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8512    EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8513               rm.GetCode());
8514    AdvanceIT();
8515    return;
8516  } else {
8517    // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8518    if (cond.IsNotNever()) {
8519      EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8520              (rn.GetCode() << 16) | rm.GetCode());
8521      return;
8522    }
8523  }
8524  Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm);
8525}
8526
8527void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) {
8528  VIXL_ASSERT(AllowAssembler());
8529  CheckIT(cond);
8530  if (IsUsingT32()) {
8531    // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8532    EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8533               rm.GetCode());
8534    AdvanceIT();
8535    return;
8536  } else {
8537    // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8538    if (cond.IsNotNever()) {
8539      EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8540              (rn.GetCode() << 16) | rm.GetCode());
8541      return;
8542    }
8543  }
8544  Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm);
8545}
8546
8547void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) {
8548  VIXL_ASSERT(AllowAssembler());
8549  CheckIT(cond);
8550  if (IsUsingT32()) {
8551    // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8552    EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8553               rm.GetCode());
8554    AdvanceIT();
8555    return;
8556  } else {
8557    // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8558    if (cond.IsNotNever()) {
8559      EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8560              (rn.GetCode() << 16) | rm.GetCode());
8561      return;
8562    }
8563  }
8564  Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm);
8565}
8566
8567void Assembler::sbc(Condition cond,
8568                    EncodingSize size,
8569                    Register rd,
8570                    Register rn,
8571                    const Operand& operand) {
8572  VIXL_ASSERT(AllowAssembler());
8573  CheckIT(cond);
8574  if (operand.IsImmediate()) {
8575    uint32_t imm = operand.GetImmediate();
8576    if (IsUsingT32()) {
8577      ImmediateT32 immediate_t32(imm);
8578      // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
8579      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8580        EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8581                   (immediate_t32.GetEncodingValue() & 0xff) |
8582                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8583                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8584        AdvanceIT();
8585        return;
8586      }
8587    } else {
8588      ImmediateA32 immediate_a32(imm);
8589      // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8590      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8591        EmitA32(0x02c00000U | (cond.GetCondition() << 28) |
8592                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8593                immediate_a32.GetEncodingValue());
8594        return;
8595      }
8596    }
8597  }
8598  if (operand.IsImmediateShiftedRegister()) {
8599    Register rm = operand.GetBaseRegister();
8600    if (operand.IsPlainRegister()) {
8601      if (IsUsingT32()) {
8602        // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
8603        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
8604            rm.IsLow()) {
8605          EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
8606          AdvanceIT();
8607          return;
8608        }
8609      }
8610    }
8611    Shift shift = operand.GetShift();
8612    uint32_t amount = operand.GetShiftAmount();
8613    if (IsUsingT32()) {
8614      // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
8615      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8616        uint32_t amount_ = amount % 32;
8617        EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8618                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8619                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8620        AdvanceIT();
8621        return;
8622      }
8623    } else {
8624      // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8625      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8626        uint32_t amount_ = amount % 32;
8627        EmitA32(0x00c00000U | (cond.GetCondition() << 28) |
8628                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8629                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8630        return;
8631      }
8632    }
8633  }
8634  if (operand.IsRegisterShiftedRegister()) {
8635    Register rm = operand.GetBaseRegister();
8636    Shift shift = operand.GetShift();
8637    if (IsUsingA32()) {
8638      // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8639      if (cond.IsNotNever()) {
8640        EmitA32(0x00c00010U | (cond.GetCondition() << 28) |
8641                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8642                (shift.GetType() << 5) |
8643                (operand.GetShiftRegister().GetCode() << 8));
8644        return;
8645      }
8646    }
8647  }
8648  Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand);
8649}
8650
8651void Assembler::sbcs(Condition cond,
8652                     EncodingSize size,
8653                     Register rd,
8654                     Register rn,
8655                     const Operand& operand) {
8656  VIXL_ASSERT(AllowAssembler());
8657  CheckIT(cond);
8658  if (operand.IsImmediate()) {
8659    uint32_t imm = operand.GetImmediate();
8660    if (IsUsingT32()) {
8661      ImmediateT32 immediate_t32(imm);
8662      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
8663      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8664        EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8665                   (immediate_t32.GetEncodingValue() & 0xff) |
8666                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8667                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8668        AdvanceIT();
8669        return;
8670      }
8671    } else {
8672      ImmediateA32 immediate_a32(imm);
8673      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8674      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8675        EmitA32(0x02d00000U | (cond.GetCondition() << 28) |
8676                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8677                immediate_a32.GetEncodingValue());
8678        return;
8679      }
8680    }
8681  }
8682  if (operand.IsImmediateShiftedRegister()) {
8683    Register rm = operand.GetBaseRegister();
8684    if (operand.IsPlainRegister()) {
8685      if (IsUsingT32()) {
8686        // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
8687        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
8688            rm.IsLow()) {
8689          EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
8690          AdvanceIT();
8691          return;
8692        }
8693      }
8694    }
8695    Shift shift = operand.GetShift();
8696    uint32_t amount = operand.GetShiftAmount();
8697    if (IsUsingT32()) {
8698      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
8699      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8700        uint32_t amount_ = amount % 32;
8701        EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8702                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8703                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8704        AdvanceIT();
8705        return;
8706      }
8707    } else {
8708      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8709      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8710        uint32_t amount_ = amount % 32;
8711        EmitA32(0x00d00000U | (cond.GetCondition() << 28) |
8712                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8713                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8714        return;
8715      }
8716    }
8717  }
8718  if (operand.IsRegisterShiftedRegister()) {
8719    Register rm = operand.GetBaseRegister();
8720    Shift shift = operand.GetShift();
8721    if (IsUsingA32()) {
8722      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8723      if (cond.IsNotNever()) {
8724        EmitA32(0x00d00010U | (cond.GetCondition() << 28) |
8725                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8726                (shift.GetType() << 5) |
8727                (operand.GetShiftRegister().GetCode() << 8));
8728        return;
8729      }
8730    }
8731  }
8732  Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand);
8733}
8734
8735void Assembler::sbfx(Condition cond,
8736                     Register rd,
8737                     Register rn,
8738                     uint32_t lsb,
8739                     const Operand& operand) {
8740  VIXL_ASSERT(AllowAssembler());
8741  CheckIT(cond);
8742  if (operand.IsImmediate()) {
8743    uint32_t width = operand.GetImmediate();
8744    if (IsUsingT32()) {
8745      // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
8746      if ((lsb <= 31) &&
8747          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
8748        uint32_t widthm1 = width - 1;
8749        EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8750                   ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
8751        AdvanceIT();
8752        return;
8753      }
8754    } else {
8755      // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
8756      if ((lsb <= 31) && cond.IsNotNever() &&
8757          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
8758        uint32_t widthm1 = width - 1;
8759        EmitA32(0x07a00050U | (cond.GetCondition() << 28) |
8760                (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) |
8761                (widthm1 << 16));
8762        return;
8763      }
8764    }
8765  }
8766  Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, operand);
8767}
8768
8769void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) {
8770  VIXL_ASSERT(AllowAssembler());
8771  CheckIT(cond);
8772  if (IsUsingT32()) {
8773    // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8774    EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8775               rm.GetCode());
8776    AdvanceIT();
8777    return;
8778  } else {
8779    // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8780    if (cond.IsNotNever()) {
8781      EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
8782              rn.GetCode() | (rm.GetCode() << 8));
8783      return;
8784    }
8785  }
8786  Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm);
8787}
8788
8789void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) {
8790  VIXL_ASSERT(AllowAssembler());
8791  CheckIT(cond);
8792  if (IsUsingT32()) {
8793    // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8794    EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8795               rm.GetCode());
8796    AdvanceIT();
8797    return;
8798  } else {
8799    // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8800    if (cond.IsNotNever()) {
8801      EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8802              (rn.GetCode() << 16) | rm.GetCode());
8803      return;
8804    }
8805  }
8806  Delegate(kSel, &Assembler::sel, cond, rd, rn, rm);
8807}
8808
8809void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) {
8810  VIXL_ASSERT(AllowAssembler());
8811  CheckIT(cond);
8812  if (IsUsingT32()) {
8813    // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8814    EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8815               rm.GetCode());
8816    AdvanceIT();
8817    return;
8818  } else {
8819    // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8820    if (cond.IsNotNever()) {
8821      EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8822              (rn.GetCode() << 16) | rm.GetCode());
8823      return;
8824    }
8825  }
8826  Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm);
8827}
8828
8829void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) {
8830  VIXL_ASSERT(AllowAssembler());
8831  CheckIT(cond);
8832  if (IsUsingT32()) {
8833    // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8834    EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8835               rm.GetCode());
8836    AdvanceIT();
8837    return;
8838  } else {
8839    // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8840    if (cond.IsNotNever()) {
8841      EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8842              (rn.GetCode() << 16) | rm.GetCode());
8843      return;
8844    }
8845  }
8846  Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm);
8847}
8848
8849void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) {
8850  VIXL_ASSERT(AllowAssembler());
8851  CheckIT(cond);
8852  if (IsUsingT32()) {
8853    // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8854    EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8855               rm.GetCode());
8856    AdvanceIT();
8857    return;
8858  } else {
8859    // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8860    if (cond.IsNotNever()) {
8861      EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8862              (rn.GetCode() << 16) | rm.GetCode());
8863      return;
8864    }
8865  }
8866  Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm);
8867}
8868
8869void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) {
8870  VIXL_ASSERT(AllowAssembler());
8871  CheckIT(cond);
8872  if (IsUsingT32()) {
8873    // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8874    EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8875               rm.GetCode());
8876    AdvanceIT();
8877    return;
8878  } else {
8879    // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8880    if (cond.IsNotNever()) {
8881      EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8882              (rn.GetCode() << 16) | rm.GetCode());
8883      return;
8884    }
8885  }
8886  Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm);
8887}
8888
8889void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) {
8890  VIXL_ASSERT(AllowAssembler());
8891  CheckIT(cond);
8892  if (IsUsingT32()) {
8893    // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8894    EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8895               rm.GetCode());
8896    AdvanceIT();
8897    return;
8898  } else {
8899    // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8900    if (cond.IsNotNever()) {
8901      EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8902              (rn.GetCode() << 16) | rm.GetCode());
8903      return;
8904    }
8905  }
8906  Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm);
8907}
8908
8909void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) {
8910  VIXL_ASSERT(AllowAssembler());
8911  CheckIT(cond);
8912  if (IsUsingT32()) {
8913    // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8914    EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8915               rm.GetCode());
8916    AdvanceIT();
8917    return;
8918  } else {
8919    // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8920    if (cond.IsNotNever()) {
8921      EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8922              (rn.GetCode() << 16) | rm.GetCode());
8923      return;
8924    }
8925  }
8926  Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm);
8927}
8928
8929void Assembler::smlabb(
8930    Condition cond, Register rd, Register rn, Register rm, Register ra) {
8931  VIXL_ASSERT(AllowAssembler());
8932  CheckIT(cond);
8933  if (IsUsingT32()) {
8934    // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
8935    if (!ra.Is(pc)) {
8936      EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8937                 rm.GetCode() | (ra.GetCode() << 12));
8938      AdvanceIT();
8939      return;
8940    }
8941  } else {
8942    // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
8943    if (cond.IsNotNever()) {
8944      EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
8945              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
8946      return;
8947    }
8948  }
8949  Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra);
8950}
8951
8952void Assembler::smlabt(
8953    Condition cond, Register rd, Register rn, Register rm, Register ra) {
8954  VIXL_ASSERT(AllowAssembler());
8955  CheckIT(cond);
8956  if (IsUsingT32()) {
8957    // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
8958    if (!ra.Is(pc)) {
8959      EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8960                 rm.GetCode() | (ra.GetCode() << 12));
8961      AdvanceIT();
8962      return;
8963    }
8964  } else {
8965    // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
8966    if (cond.IsNotNever()) {
8967      EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
8968              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
8969      return;
8970    }
8971  }
8972  Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra);
8973}
8974
8975void Assembler::smlad(
8976    Condition cond, Register rd, Register rn, Register rm, Register ra) {
8977  VIXL_ASSERT(AllowAssembler());
8978  CheckIT(cond);
8979  if (IsUsingT32()) {
8980    // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
8981    if (!ra.Is(pc)) {
8982      EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8983                 rm.GetCode() | (ra.GetCode() << 12));
8984      AdvanceIT();
8985      return;
8986    }
8987  } else {
8988    // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
8989    if (cond.IsNotNever() && !ra.Is(pc)) {
8990      EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
8991              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
8992      return;
8993    }
8994  }
8995  Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra);
8996}
8997
8998void Assembler::smladx(
8999    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9000  VIXL_ASSERT(AllowAssembler());
9001  CheckIT(cond);
9002  if (IsUsingT32()) {
9003    // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9004    if (!ra.Is(pc)) {
9005      EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9006                 rm.GetCode() | (ra.GetCode() << 12));
9007      AdvanceIT();
9008      return;
9009    }
9010  } else {
9011    // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9012    if (cond.IsNotNever() && !ra.Is(pc)) {
9013      EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9014              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9015      return;
9016    }
9017  }
9018  Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra);
9019}
9020
9021void Assembler::smlal(
9022    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9023  VIXL_ASSERT(AllowAssembler());
9024  CheckIT(cond);
9025  if (IsUsingT32()) {
9026    // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9027    EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9028               (rn.GetCode() << 16) | rm.GetCode());
9029    AdvanceIT();
9030    return;
9031  } else {
9032    // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9033    if (cond.IsNotNever()) {
9034      EmitA32(0x00e00090U | (cond.GetCondition() << 28) |
9035              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9036              (rm.GetCode() << 8));
9037      return;
9038    }
9039  }
9040  Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm);
9041}
9042
9043void Assembler::smlalbb(
9044    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9045  VIXL_ASSERT(AllowAssembler());
9046  CheckIT(cond);
9047  if (IsUsingT32()) {
9048    // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9049    EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9050               (rn.GetCode() << 16) | rm.GetCode());
9051    AdvanceIT();
9052    return;
9053  } else {
9054    // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9055    if (cond.IsNotNever()) {
9056      EmitA32(0x01400080U | (cond.GetCondition() << 28) |
9057              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9058              (rm.GetCode() << 8));
9059      return;
9060    }
9061  }
9062  Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm);
9063}
9064
9065void Assembler::smlalbt(
9066    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9067  VIXL_ASSERT(AllowAssembler());
9068  CheckIT(cond);
9069  if (IsUsingT32()) {
9070    // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9071    EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9072               (rn.GetCode() << 16) | rm.GetCode());
9073    AdvanceIT();
9074    return;
9075  } else {
9076    // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9077    if (cond.IsNotNever()) {
9078      EmitA32(0x014000c0U | (cond.GetCondition() << 28) |
9079              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9080              (rm.GetCode() << 8));
9081      return;
9082    }
9083  }
9084  Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm);
9085}
9086
9087void Assembler::smlald(
9088    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9089  VIXL_ASSERT(AllowAssembler());
9090  CheckIT(cond);
9091  if (IsUsingT32()) {
9092    // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9093    EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9094               (rn.GetCode() << 16) | rm.GetCode());
9095    AdvanceIT();
9096    return;
9097  } else {
9098    // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9099    if (cond.IsNotNever()) {
9100      EmitA32(0x07400010U | (cond.GetCondition() << 28) |
9101              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9102              (rm.GetCode() << 8));
9103      return;
9104    }
9105  }
9106  Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm);
9107}
9108
9109void Assembler::smlaldx(
9110    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9111  VIXL_ASSERT(AllowAssembler());
9112  CheckIT(cond);
9113  if (IsUsingT32()) {
9114    // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9115    EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9116               (rn.GetCode() << 16) | rm.GetCode());
9117    AdvanceIT();
9118    return;
9119  } else {
9120    // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9121    if (cond.IsNotNever()) {
9122      EmitA32(0x07400030U | (cond.GetCondition() << 28) |
9123              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9124              (rm.GetCode() << 8));
9125      return;
9126    }
9127  }
9128  Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm);
9129}
9130
9131void Assembler::smlals(
9132    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9133  VIXL_ASSERT(AllowAssembler());
9134  CheckIT(cond);
9135  if (IsUsingA32()) {
9136    // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9137    if (cond.IsNotNever()) {
9138      EmitA32(0x00f00090U | (cond.GetCondition() << 28) |
9139              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9140              (rm.GetCode() << 8));
9141      return;
9142    }
9143  }
9144  Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm);
9145}
9146
9147void Assembler::smlaltb(
9148    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9149  VIXL_ASSERT(AllowAssembler());
9150  CheckIT(cond);
9151  if (IsUsingT32()) {
9152    // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9153    EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9154               (rn.GetCode() << 16) | rm.GetCode());
9155    AdvanceIT();
9156    return;
9157  } else {
9158    // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9159    if (cond.IsNotNever()) {
9160      EmitA32(0x014000a0U | (cond.GetCondition() << 28) |
9161              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9162              (rm.GetCode() << 8));
9163      return;
9164    }
9165  }
9166  Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm);
9167}
9168
9169void Assembler::smlaltt(
9170    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9171  VIXL_ASSERT(AllowAssembler());
9172  CheckIT(cond);
9173  if (IsUsingT32()) {
9174    // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9175    EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9176               (rn.GetCode() << 16) | rm.GetCode());
9177    AdvanceIT();
9178    return;
9179  } else {
9180    // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9181    if (cond.IsNotNever()) {
9182      EmitA32(0x014000e0U | (cond.GetCondition() << 28) |
9183              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9184              (rm.GetCode() << 8));
9185      return;
9186    }
9187  }
9188  Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm);
9189}
9190
9191void Assembler::smlatb(
9192    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9193  VIXL_ASSERT(AllowAssembler());
9194  CheckIT(cond);
9195  if (IsUsingT32()) {
9196    // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9197    if (!ra.Is(pc)) {
9198      EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9199                 rm.GetCode() | (ra.GetCode() << 12));
9200      AdvanceIT();
9201      return;
9202    }
9203  } else {
9204    // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9205    if (cond.IsNotNever()) {
9206      EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9207              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9208      return;
9209    }
9210  }
9211  Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra);
9212}
9213
9214void Assembler::smlatt(
9215    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9216  VIXL_ASSERT(AllowAssembler());
9217  CheckIT(cond);
9218  if (IsUsingT32()) {
9219    // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9220    if (!ra.Is(pc)) {
9221      EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9222                 rm.GetCode() | (ra.GetCode() << 12));
9223      AdvanceIT();
9224      return;
9225    }
9226  } else {
9227    // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9228    if (cond.IsNotNever()) {
9229      EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9230              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9231      return;
9232    }
9233  }
9234  Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra);
9235}
9236
9237void Assembler::smlawb(
9238    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9239  VIXL_ASSERT(AllowAssembler());
9240  CheckIT(cond);
9241  if (IsUsingT32()) {
9242    // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9243    if (!ra.Is(pc)) {
9244      EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9245                 rm.GetCode() | (ra.GetCode() << 12));
9246      AdvanceIT();
9247      return;
9248    }
9249  } else {
9250    // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9251    if (cond.IsNotNever()) {
9252      EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9253              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9254      return;
9255    }
9256  }
9257  Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra);
9258}
9259
9260void Assembler::smlawt(
9261    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9262  VIXL_ASSERT(AllowAssembler());
9263  CheckIT(cond);
9264  if (IsUsingT32()) {
9265    // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9266    if (!ra.Is(pc)) {
9267      EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9268                 rm.GetCode() | (ra.GetCode() << 12));
9269      AdvanceIT();
9270      return;
9271    }
9272  } else {
9273    // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9274    if (cond.IsNotNever()) {
9275      EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9276              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9277      return;
9278    }
9279  }
9280  Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra);
9281}
9282
9283void Assembler::smlsd(
9284    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9285  VIXL_ASSERT(AllowAssembler());
9286  CheckIT(cond);
9287  if (IsUsingT32()) {
9288    // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9289    if (!ra.Is(pc)) {
9290      EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9291                 rm.GetCode() | (ra.GetCode() << 12));
9292      AdvanceIT();
9293      return;
9294    }
9295  } else {
9296    // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9297    if (cond.IsNotNever() && !ra.Is(pc)) {
9298      EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9299              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9300      return;
9301    }
9302  }
9303  Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra);
9304}
9305
9306void Assembler::smlsdx(
9307    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9308  VIXL_ASSERT(AllowAssembler());
9309  CheckIT(cond);
9310  if (IsUsingT32()) {
9311    // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9312    if (!ra.Is(pc)) {
9313      EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9314                 rm.GetCode() | (ra.GetCode() << 12));
9315      AdvanceIT();
9316      return;
9317    }
9318  } else {
9319    // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9320    if (cond.IsNotNever() && !ra.Is(pc)) {
9321      EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9322              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9323      return;
9324    }
9325  }
9326  Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra);
9327}
9328
9329void Assembler::smlsld(
9330    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9331  VIXL_ASSERT(AllowAssembler());
9332  CheckIT(cond);
9333  if (IsUsingT32()) {
9334    // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9335    EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9336               (rn.GetCode() << 16) | rm.GetCode());
9337    AdvanceIT();
9338    return;
9339  } else {
9340    // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9341    if (cond.IsNotNever()) {
9342      EmitA32(0x07400050U | (cond.GetCondition() << 28) |
9343              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9344              (rm.GetCode() << 8));
9345      return;
9346    }
9347  }
9348  Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm);
9349}
9350
9351void Assembler::smlsldx(
9352    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9353  VIXL_ASSERT(AllowAssembler());
9354  CheckIT(cond);
9355  if (IsUsingT32()) {
9356    // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9357    EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9358               (rn.GetCode() << 16) | rm.GetCode());
9359    AdvanceIT();
9360    return;
9361  } else {
9362    // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9363    if (cond.IsNotNever()) {
9364      EmitA32(0x07400070U | (cond.GetCondition() << 28) |
9365              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9366              (rm.GetCode() << 8));
9367      return;
9368    }
9369  }
9370  Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm);
9371}
9372
9373void Assembler::smmla(
9374    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9375  VIXL_ASSERT(AllowAssembler());
9376  CheckIT(cond);
9377  if (IsUsingT32()) {
9378    // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9379    if (!ra.Is(pc)) {
9380      EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9381                 rm.GetCode() | (ra.GetCode() << 12));
9382      AdvanceIT();
9383      return;
9384    }
9385  } else {
9386    // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9387    if (cond.IsNotNever() && !ra.Is(pc)) {
9388      EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9389              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9390      return;
9391    }
9392  }
9393  Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra);
9394}
9395
9396void Assembler::smmlar(
9397    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9398  VIXL_ASSERT(AllowAssembler());
9399  CheckIT(cond);
9400  if (IsUsingT32()) {
9401    // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9402    if (!ra.Is(pc)) {
9403      EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9404                 rm.GetCode() | (ra.GetCode() << 12));
9405      AdvanceIT();
9406      return;
9407    }
9408  } else {
9409    // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9410    if (cond.IsNotNever() && !ra.Is(pc)) {
9411      EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9412              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9413      return;
9414    }
9415  }
9416  Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra);
9417}
9418
9419void Assembler::smmls(
9420    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9421  VIXL_ASSERT(AllowAssembler());
9422  CheckIT(cond);
9423  if (IsUsingT32()) {
9424    // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9425    EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9426               rm.GetCode() | (ra.GetCode() << 12));
9427    AdvanceIT();
9428    return;
9429  } else {
9430    // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9431    if (cond.IsNotNever()) {
9432      EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9433              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9434      return;
9435    }
9436  }
9437  Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra);
9438}
9439
9440void Assembler::smmlsr(
9441    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9442  VIXL_ASSERT(AllowAssembler());
9443  CheckIT(cond);
9444  if (IsUsingT32()) {
9445    // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9446    EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9447               rm.GetCode() | (ra.GetCode() << 12));
9448    AdvanceIT();
9449    return;
9450  } else {
9451    // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9452    if (cond.IsNotNever()) {
9453      EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9454              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9455      return;
9456    }
9457  }
9458  Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra);
9459}
9460
9461void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) {
9462  VIXL_ASSERT(AllowAssembler());
9463  CheckIT(cond);
9464  if (IsUsingT32()) {
9465    // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9466    EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9467               rm.GetCode());
9468    AdvanceIT();
9469    return;
9470  } else {
9471    // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9472    if (cond.IsNotNever()) {
9473      EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9474              rn.GetCode() | (rm.GetCode() << 8));
9475      return;
9476    }
9477  }
9478  Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm);
9479}
9480
9481void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) {
9482  VIXL_ASSERT(AllowAssembler());
9483  CheckIT(cond);
9484  if (IsUsingT32()) {
9485    // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9486    EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9487               rm.GetCode());
9488    AdvanceIT();
9489    return;
9490  } else {
9491    // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9492    if (cond.IsNotNever()) {
9493      EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9494              rn.GetCode() | (rm.GetCode() << 8));
9495      return;
9496    }
9497  }
9498  Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm);
9499}
9500
9501void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) {
9502  VIXL_ASSERT(AllowAssembler());
9503  CheckIT(cond);
9504  if (IsUsingT32()) {
9505    // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9506    EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9507               rm.GetCode());
9508    AdvanceIT();
9509    return;
9510  } else {
9511    // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9512    if (cond.IsNotNever()) {
9513      EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9514              rn.GetCode() | (rm.GetCode() << 8));
9515      return;
9516    }
9517  }
9518  Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm);
9519}
9520
9521void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) {
9522  VIXL_ASSERT(AllowAssembler());
9523  CheckIT(cond);
9524  if (IsUsingT32()) {
9525    // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9526    EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9527               rm.GetCode());
9528    AdvanceIT();
9529    return;
9530  } else {
9531    // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9532    if (cond.IsNotNever()) {
9533      EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9534              rn.GetCode() | (rm.GetCode() << 8));
9535      return;
9536    }
9537  }
9538  Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm);
9539}
9540
9541void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) {
9542  VIXL_ASSERT(AllowAssembler());
9543  CheckIT(cond);
9544  if (IsUsingT32()) {
9545    // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9546    EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9547               rm.GetCode());
9548    AdvanceIT();
9549    return;
9550  } else {
9551    // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9552    if (cond.IsNotNever()) {
9553      EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9554              rn.GetCode() | (rm.GetCode() << 8));
9555      return;
9556    }
9557  }
9558  Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm);
9559}
9560
9561void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) {
9562  VIXL_ASSERT(AllowAssembler());
9563  CheckIT(cond);
9564  if (IsUsingT32()) {
9565    // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9566    EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9567               rm.GetCode());
9568    AdvanceIT();
9569    return;
9570  } else {
9571    // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9572    if (cond.IsNotNever()) {
9573      EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9574              rn.GetCode() | (rm.GetCode() << 8));
9575      return;
9576    }
9577  }
9578  Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm);
9579}
9580
9581void Assembler::smull(
9582    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9583  VIXL_ASSERT(AllowAssembler());
9584  CheckIT(cond);
9585  if (IsUsingT32()) {
9586    // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9587    EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9588               (rn.GetCode() << 16) | rm.GetCode());
9589    AdvanceIT();
9590    return;
9591  } else {
9592    // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9593    if (cond.IsNotNever()) {
9594      EmitA32(0x00c00090U | (cond.GetCondition() << 28) |
9595              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9596              (rm.GetCode() << 8));
9597      return;
9598    }
9599  }
9600  Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm);
9601}
9602
9603void Assembler::smulls(
9604    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9605  VIXL_ASSERT(AllowAssembler());
9606  CheckIT(cond);
9607  if (IsUsingA32()) {
9608    // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9609    if (cond.IsNotNever()) {
9610      EmitA32(0x00d00090U | (cond.GetCondition() << 28) |
9611              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9612              (rm.GetCode() << 8));
9613      return;
9614    }
9615  }
9616  Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm);
9617}
9618
9619void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) {
9620  VIXL_ASSERT(AllowAssembler());
9621  CheckIT(cond);
9622  if (IsUsingT32()) {
9623    // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9624    EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9625               rm.GetCode());
9626    AdvanceIT();
9627    return;
9628  } else {
9629    // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9630    if (cond.IsNotNever()) {
9631      EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9632              rn.GetCode() | (rm.GetCode() << 8));
9633      return;
9634    }
9635  }
9636  Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm);
9637}
9638
9639void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) {
9640  VIXL_ASSERT(AllowAssembler());
9641  CheckIT(cond);
9642  if (IsUsingT32()) {
9643    // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9644    EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9645               rm.GetCode());
9646    AdvanceIT();
9647    return;
9648  } else {
9649    // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9650    if (cond.IsNotNever()) {
9651      EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9652              rn.GetCode() | (rm.GetCode() << 8));
9653      return;
9654    }
9655  }
9656  Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm);
9657}
9658
9659void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) {
9660  VIXL_ASSERT(AllowAssembler());
9661  CheckIT(cond);
9662  if (IsUsingT32()) {
9663    // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9664    EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9665               rm.GetCode());
9666    AdvanceIT();
9667    return;
9668  } else {
9669    // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9670    if (cond.IsNotNever()) {
9671      EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9672              rn.GetCode() | (rm.GetCode() << 8));
9673      return;
9674    }
9675  }
9676  Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm);
9677}
9678
9679void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) {
9680  VIXL_ASSERT(AllowAssembler());
9681  CheckIT(cond);
9682  if (IsUsingT32()) {
9683    // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9684    EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9685               rm.GetCode());
9686    AdvanceIT();
9687    return;
9688  } else {
9689    // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9690    if (cond.IsNotNever()) {
9691      EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9692              rn.GetCode() | (rm.GetCode() << 8));
9693      return;
9694    }
9695  }
9696  Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm);
9697}
9698
9699void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) {
9700  VIXL_ASSERT(AllowAssembler());
9701  CheckIT(cond);
9702  if (IsUsingT32()) {
9703    // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9704    EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9705               rm.GetCode());
9706    AdvanceIT();
9707    return;
9708  } else {
9709    // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9710    if (cond.IsNotNever()) {
9711      EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9712              rn.GetCode() | (rm.GetCode() << 8));
9713      return;
9714    }
9715  }
9716  Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm);
9717}
9718
9719void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) {
9720  VIXL_ASSERT(AllowAssembler());
9721  CheckIT(cond);
9722  if (IsUsingT32()) {
9723    // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9724    EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9725               rm.GetCode());
9726    AdvanceIT();
9727    return;
9728  } else {
9729    // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9730    if (cond.IsNotNever()) {
9731      EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9732              rn.GetCode() | (rm.GetCode() << 8));
9733      return;
9734    }
9735  }
9736  Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm);
9737}
9738
9739void Assembler::ssat(Condition cond,
9740                     Register rd,
9741                     uint32_t imm,
9742                     const Operand& operand) {
9743  VIXL_ASSERT(AllowAssembler());
9744  CheckIT(cond);
9745  if (operand.IsImmediateShiftedRegister()) {
9746    Register rn = operand.GetBaseRegister();
9747    Shift shift = operand.GetShift();
9748    uint32_t amount = operand.GetShiftAmount();
9749    if (IsUsingT32()) {
9750      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
9751      if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
9752          (amount <= 31)) {
9753        uint32_t imm_ = imm - 1;
9754        EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
9755                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
9756                   ((amount & 0x1c) << 10));
9757        AdvanceIT();
9758        return;
9759      }
9760      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
9761      if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31)) {
9762        uint32_t imm_ = imm - 1;
9763        EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ |
9764                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
9765                   ((amount & 0x1c) << 10));
9766        AdvanceIT();
9767        return;
9768      }
9769    } else {
9770      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
9771      if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
9772          (amount <= 32) && cond.IsNotNever()) {
9773        uint32_t imm_ = imm - 1;
9774        uint32_t amount_ = amount % 32;
9775        EmitA32(0x06a00050U | (cond.GetCondition() << 28) |
9776                (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
9777                (amount_ << 7));
9778        return;
9779      }
9780      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
9781      if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
9782          cond.IsNotNever()) {
9783        uint32_t imm_ = imm - 1;
9784        EmitA32(0x06a00010U | (cond.GetCondition() << 28) |
9785                (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
9786                (amount << 7));
9787        return;
9788      }
9789    }
9790  }
9791  Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand);
9792}
9793
9794void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) {
9795  VIXL_ASSERT(AllowAssembler());
9796  CheckIT(cond);
9797  if (IsUsingT32()) {
9798    // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
9799    if ((imm >= 1) && (imm <= 16)) {
9800      uint32_t imm_ = imm - 1;
9801      EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
9802                 (rn.GetCode() << 16));
9803      AdvanceIT();
9804      return;
9805    }
9806  } else {
9807    // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
9808    if ((imm >= 1) && (imm <= 16) && cond.IsNotNever()) {
9809      uint32_t imm_ = imm - 1;
9810      EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9811              (imm_ << 16) | rn.GetCode());
9812      return;
9813    }
9814  }
9815  Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn);
9816}
9817
9818void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) {
9819  VIXL_ASSERT(AllowAssembler());
9820  CheckIT(cond);
9821  if (IsUsingT32()) {
9822    // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9823    EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9824               rm.GetCode());
9825    AdvanceIT();
9826    return;
9827  } else {
9828    // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9829    if (cond.IsNotNever()) {
9830      EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9831              (rn.GetCode() << 16) | rm.GetCode());
9832      return;
9833    }
9834  }
9835  Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm);
9836}
9837
9838void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) {
9839  VIXL_ASSERT(AllowAssembler());
9840  CheckIT(cond);
9841  if (IsUsingT32()) {
9842    // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9843    EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9844               rm.GetCode());
9845    AdvanceIT();
9846    return;
9847  } else {
9848    // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9849    if (cond.IsNotNever()) {
9850      EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9851              (rn.GetCode() << 16) | rm.GetCode());
9852      return;
9853    }
9854  }
9855  Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm);
9856}
9857
9858void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) {
9859  VIXL_ASSERT(AllowAssembler());
9860  CheckIT(cond);
9861  if (IsUsingT32()) {
9862    // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9863    EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9864               rm.GetCode());
9865    AdvanceIT();
9866    return;
9867  } else {
9868    // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9869    if (cond.IsNotNever()) {
9870      EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9871              (rn.GetCode() << 16) | rm.GetCode());
9872      return;
9873    }
9874  }
9875  Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm);
9876}
9877
9878void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) {
9879  VIXL_ASSERT(AllowAssembler());
9880  CheckIT(cond);
9881  if (operand.IsImmediateZero()) {
9882    Register rn = operand.GetBaseRegister();
9883    if (IsUsingT32()) {
9884      // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1
9885      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
9886        EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
9887        AdvanceIT();
9888        return;
9889      }
9890    } else {
9891      // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1
9892      if (operand.IsOffset() && cond.IsNotNever() &&
9893          ((!rn.IsPC()) || AllowUnpredictable())) {
9894        EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
9895                (rn.GetCode() << 16));
9896        return;
9897      }
9898    }
9899  }
9900  Delegate(kStl, &Assembler::stl, cond, rt, operand);
9901}
9902
9903void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) {
9904  VIXL_ASSERT(AllowAssembler());
9905  CheckIT(cond);
9906  if (operand.IsImmediateZero()) {
9907    Register rn = operand.GetBaseRegister();
9908    if (IsUsingT32()) {
9909      // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1
9910      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
9911        EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
9912        AdvanceIT();
9913        return;
9914      }
9915    } else {
9916      // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1
9917      if (operand.IsOffset() && cond.IsNotNever() &&
9918          ((!rn.IsPC()) || AllowUnpredictable())) {
9919        EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
9920                (rn.GetCode() << 16));
9921        return;
9922      }
9923    }
9924  }
9925  Delegate(kStlb, &Assembler::stlb, cond, rt, operand);
9926}
9927
9928void Assembler::stlex(Condition cond,
9929                      Register rd,
9930                      Register rt,
9931                      const MemOperand& operand) {
9932  VIXL_ASSERT(AllowAssembler());
9933  CheckIT(cond);
9934  if (operand.IsImmediateZero()) {
9935    Register rn = operand.GetBaseRegister();
9936    if (IsUsingT32()) {
9937      // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
9938      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
9939        EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) |
9940                   (rn.GetCode() << 16));
9941        AdvanceIT();
9942        return;
9943      }
9944    } else {
9945      // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
9946      if (operand.IsOffset() && cond.IsNotNever() &&
9947          ((!rn.IsPC()) || AllowUnpredictable())) {
9948        EmitA32(0x01800e90U | (cond.GetCondition() << 28) |
9949                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
9950        return;
9951      }
9952    }
9953  }
9954  Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand);
9955}
9956
9957void Assembler::stlexb(Condition cond,
9958                       Register rd,
9959                       Register rt,
9960                       const MemOperand& operand) {
9961  VIXL_ASSERT(AllowAssembler());
9962  CheckIT(cond);
9963  if (operand.IsImmediateZero()) {
9964    Register rn = operand.GetBaseRegister();
9965    if (IsUsingT32()) {
9966      // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
9967      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
9968        EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) |
9969                   (rn.GetCode() << 16));
9970        AdvanceIT();
9971        return;
9972      }
9973    } else {
9974      // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
9975      if (operand.IsOffset() && cond.IsNotNever() &&
9976          ((!rn.IsPC()) || AllowUnpredictable())) {
9977        EmitA32(0x01c00e90U | (cond.GetCondition() << 28) |
9978                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
9979        return;
9980      }
9981    }
9982  }
9983  Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand);
9984}
9985
9986void Assembler::stlexd(Condition cond,
9987                       Register rd,
9988                       Register rt,
9989                       Register rt2,
9990                       const MemOperand& operand) {
9991  VIXL_ASSERT(AllowAssembler());
9992  CheckIT(cond);
9993  if (operand.IsImmediateZero()) {
9994    Register rn = operand.GetBaseRegister();
9995    if (IsUsingT32()) {
9996      // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
9997      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
9998        EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) |
9999                   (rt2.GetCode() << 8) | (rn.GetCode() << 16));
10000        AdvanceIT();
10001        return;
10002      }
10003    } else {
10004      // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
10005      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10006          operand.IsOffset() && cond.IsNotNever() &&
10007          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
10008           AllowUnpredictable())) {
10009        EmitA32(0x01a00e90U | (cond.GetCondition() << 28) |
10010                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10011        return;
10012      }
10013    }
10014  }
10015  Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand);
10016}
10017
10018void Assembler::stlexh(Condition cond,
10019                       Register rd,
10020                       Register rt,
10021                       const MemOperand& operand) {
10022  VIXL_ASSERT(AllowAssembler());
10023  CheckIT(cond);
10024  if (operand.IsImmediateZero()) {
10025    Register rn = operand.GetBaseRegister();
10026    if (IsUsingT32()) {
10027      // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10028      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
10029        EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) |
10030                   (rn.GetCode() << 16));
10031        AdvanceIT();
10032        return;
10033      }
10034    } else {
10035      // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10036      if (operand.IsOffset() && cond.IsNotNever() &&
10037          ((!rn.IsPC()) || AllowUnpredictable())) {
10038        EmitA32(0x01e00e90U | (cond.GetCondition() << 28) |
10039                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10040        return;
10041      }
10042    }
10043  }
10044  Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand);
10045}
10046
10047void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) {
10048  VIXL_ASSERT(AllowAssembler());
10049  CheckIT(cond);
10050  if (operand.IsImmediateZero()) {
10051    Register rn = operand.GetBaseRegister();
10052    if (IsUsingT32()) {
10053      // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1
10054      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
10055        EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
10056        AdvanceIT();
10057        return;
10058      }
10059    } else {
10060      // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1
10061      if (operand.IsOffset() && cond.IsNotNever() &&
10062          ((!rn.IsPC()) || AllowUnpredictable())) {
10063        EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
10064                (rn.GetCode() << 16));
10065        return;
10066      }
10067    }
10068  }
10069  Delegate(kStlh, &Assembler::stlh, cond, rt, operand);
10070}
10071
10072void Assembler::stm(Condition cond,
10073                    EncodingSize size,
10074                    Register rn,
10075                    WriteBack write_back,
10076                    RegisterList registers) {
10077  VIXL_ASSERT(AllowAssembler());
10078  CheckIT(cond);
10079  if (IsUsingT32()) {
10080    // STM{<c>}{<q>} <Rn>!, <registers> ; T1
10081    if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
10082        ((registers.GetList() & ~0xff) == 0)) {
10083      EmitT32_16(0xc000 | (rn.GetCode() << 8) |
10084                 GetRegisterListEncoding(registers, 0, 8));
10085      AdvanceIT();
10086      return;
10087    }
10088    // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2
10089    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10090      EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
10091                 (write_back.GetWriteBackUint32() << 21) |
10092                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10093                 GetRegisterListEncoding(registers, 0, 13));
10094      AdvanceIT();
10095      return;
10096    }
10097  } else {
10098    // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1
10099    if (cond.IsNotNever()) {
10100      EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10101              (write_back.GetWriteBackUint32() << 21) |
10102              GetRegisterListEncoding(registers, 0, 16));
10103      return;
10104    }
10105  }
10106  Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers);
10107}
10108
10109void Assembler::stmda(Condition cond,
10110                      Register rn,
10111                      WriteBack write_back,
10112                      RegisterList registers) {
10113  VIXL_ASSERT(AllowAssembler());
10114  CheckIT(cond);
10115  if (IsUsingA32()) {
10116    // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
10117    if (cond.IsNotNever()) {
10118      EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10119              (write_back.GetWriteBackUint32() << 21) |
10120              GetRegisterListEncoding(registers, 0, 16));
10121      return;
10122    }
10123  }
10124  Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers);
10125}
10126
10127void Assembler::stmdb(Condition cond,
10128                      EncodingSize size,
10129                      Register rn,
10130                      WriteBack write_back,
10131                      RegisterList registers) {
10132  VIXL_ASSERT(AllowAssembler());
10133  CheckIT(cond);
10134  if (IsUsingT32()) {
10135    // STMDB{<c>}{<q>} SP!, <registers> ; T1
10136    if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
10137        ((registers.GetList() & ~0x40ff) == 0)) {
10138      EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
10139                 GetRegisterListEncoding(registers, 0, 8));
10140      AdvanceIT();
10141      return;
10142    }
10143    // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
10144    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10145      EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
10146                 (write_back.GetWriteBackUint32() << 21) |
10147                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10148                 GetRegisterListEncoding(registers, 0, 13));
10149      AdvanceIT();
10150      return;
10151    }
10152  } else {
10153    // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
10154    if (cond.IsNotNever()) {
10155      EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10156              (write_back.GetWriteBackUint32() << 21) |
10157              GetRegisterListEncoding(registers, 0, 16));
10158      return;
10159    }
10160  }
10161  Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers);
10162}
10163
10164void Assembler::stmea(Condition cond,
10165                      EncodingSize size,
10166                      Register rn,
10167                      WriteBack write_back,
10168                      RegisterList registers) {
10169  VIXL_ASSERT(AllowAssembler());
10170  CheckIT(cond);
10171  if (IsUsingT32()) {
10172    // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1
10173    if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
10174        ((registers.GetList() & ~0xff) == 0)) {
10175      EmitT32_16(0xc000 | (rn.GetCode() << 8) |
10176                 GetRegisterListEncoding(registers, 0, 8));
10177      AdvanceIT();
10178      return;
10179    }
10180    // STMEA{<c>}.W <Rn>{!}, <registers> ; T2
10181    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10182      EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
10183                 (write_back.GetWriteBackUint32() << 21) |
10184                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10185                 GetRegisterListEncoding(registers, 0, 13));
10186      AdvanceIT();
10187      return;
10188    }
10189    // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2
10190    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10191      EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
10192                 (write_back.GetWriteBackUint32() << 21) |
10193                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10194                 GetRegisterListEncoding(registers, 0, 13));
10195      AdvanceIT();
10196      return;
10197    }
10198  } else {
10199    // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
10200    if (cond.IsNotNever()) {
10201      EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10202              (write_back.GetWriteBackUint32() << 21) |
10203              GetRegisterListEncoding(registers, 0, 16));
10204      return;
10205    }
10206  }
10207  Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers);
10208}
10209
10210void Assembler::stmed(Condition cond,
10211                      Register rn,
10212                      WriteBack write_back,
10213                      RegisterList registers) {
10214  VIXL_ASSERT(AllowAssembler());
10215  CheckIT(cond);
10216  if (IsUsingA32()) {
10217    // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
10218    if (cond.IsNotNever()) {
10219      EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10220              (write_back.GetWriteBackUint32() << 21) |
10221              GetRegisterListEncoding(registers, 0, 16));
10222      return;
10223    }
10224  }
10225  Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers);
10226}
10227
10228void Assembler::stmfa(Condition cond,
10229                      Register rn,
10230                      WriteBack write_back,
10231                      RegisterList registers) {
10232  VIXL_ASSERT(AllowAssembler());
10233  CheckIT(cond);
10234  if (IsUsingA32()) {
10235    // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
10236    if (cond.IsNotNever()) {
10237      EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10238              (write_back.GetWriteBackUint32() << 21) |
10239              GetRegisterListEncoding(registers, 0, 16));
10240      return;
10241    }
10242  }
10243  Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers);
10244}
10245
10246void Assembler::stmfd(Condition cond,
10247                      Register rn,
10248                      WriteBack write_back,
10249                      RegisterList registers) {
10250  VIXL_ASSERT(AllowAssembler());
10251  CheckIT(cond);
10252  if (IsUsingT32()) {
10253    // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
10254    if (((registers.GetList() & ~0x5fff) == 0)) {
10255      EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
10256                 (write_back.GetWriteBackUint32() << 21) |
10257                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10258                 GetRegisterListEncoding(registers, 0, 13));
10259      AdvanceIT();
10260      return;
10261    }
10262  } else {
10263    // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
10264    if (cond.IsNotNever()) {
10265      EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10266              (write_back.GetWriteBackUint32() << 21) |
10267              GetRegisterListEncoding(registers, 0, 16));
10268      return;
10269    }
10270  }
10271  Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers);
10272}
10273
10274void Assembler::stmib(Condition cond,
10275                      Register rn,
10276                      WriteBack write_back,
10277                      RegisterList registers) {
10278  VIXL_ASSERT(AllowAssembler());
10279  CheckIT(cond);
10280  if (IsUsingA32()) {
10281    // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
10282    if (cond.IsNotNever()) {
10283      EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10284              (write_back.GetWriteBackUint32() << 21) |
10285              GetRegisterListEncoding(registers, 0, 16));
10286      return;
10287    }
10288  }
10289  Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers);
10290}
10291
10292void Assembler::str(Condition cond,
10293                    EncodingSize size,
10294                    Register rt,
10295                    const MemOperand& operand) {
10296  VIXL_ASSERT(AllowAssembler());
10297  CheckIT(cond);
10298  if (operand.IsImmediate()) {
10299    Register rn = operand.GetBaseRegister();
10300    int32_t offset = operand.GetOffsetImmediate();
10301    if (IsUsingT32()) {
10302      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10303      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10304          (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
10305        int32_t offset_ = offset >> 2;
10306        EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) |
10307                   ((offset_ & 0x1f) << 6));
10308        AdvanceIT();
10309        return;
10310      }
10311      // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
10312      if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
10313          ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
10314        int32_t offset_ = offset >> 2;
10315        EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff));
10316        AdvanceIT();
10317        return;
10318      }
10319      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
10320      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10321          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10322        EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10323                   (offset & 0xfff));
10324        AdvanceIT();
10325        return;
10326      }
10327      // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
10328      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10329          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10330        EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10331                   (-offset & 0xff));
10332        AdvanceIT();
10333        return;
10334      }
10335      // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
10336      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10337          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10338        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10339        uint32_t offset_ = abs(offset);
10340        EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10341                   offset_ | (sign << 9));
10342        AdvanceIT();
10343        return;
10344      }
10345      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
10346      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10347          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10348        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10349        uint32_t offset_ = abs(offset);
10350        EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10351                   offset_ | (sign << 9));
10352        AdvanceIT();
10353        return;
10354      }
10355    } else {
10356      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10357      if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
10358          cond.IsNotNever()) {
10359        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10360        uint32_t offset_ = abs(offset);
10361        EmitA32(0x05000000U | (cond.GetCondition() << 28) |
10362                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10363                (sign << 23));
10364        return;
10365      }
10366      // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10367      if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
10368          cond.IsNotNever()) {
10369        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10370        uint32_t offset_ = abs(offset);
10371        EmitA32(0x04000000U | (cond.GetCondition() << 28) |
10372                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10373                (sign << 23));
10374        return;
10375      }
10376      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10377      if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
10378          cond.IsNotNever()) {
10379        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10380        uint32_t offset_ = abs(offset);
10381        EmitA32(0x05200000U | (cond.GetCondition() << 28) |
10382                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10383                (sign << 23));
10384        return;
10385      }
10386    }
10387  }
10388  if (operand.IsPlainRegister()) {
10389    Register rn = operand.GetBaseRegister();
10390    Sign sign = operand.GetSign();
10391    Register rm = operand.GetOffsetRegister();
10392    if (IsUsingT32()) {
10393      // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
10394      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
10395          sign.IsPlus() && operand.IsOffset()) {
10396        EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) |
10397                   (rm.GetCode() << 6));
10398        AdvanceIT();
10399        return;
10400      }
10401    }
10402  }
10403  if (operand.IsShiftedRegister()) {
10404    Register rn = operand.GetBaseRegister();
10405    Sign sign = operand.GetSign();
10406    Register rm = operand.GetOffsetRegister();
10407    Shift shift = operand.GetShift();
10408    uint32_t amount = operand.GetShiftAmount();
10409    if (IsUsingT32()) {
10410      // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
10411      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
10412          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10413        EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10414                   rm.GetCode() | (amount << 4));
10415        AdvanceIT();
10416        return;
10417      }
10418    } else {
10419      // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
10420      if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
10421        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10422        uint32_t shift_ = TypeEncodingValue(shift);
10423        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10424        EmitA32(0x07000000U | (cond.GetCondition() << 28) |
10425                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10426                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10427        return;
10428      }
10429      // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
10430      if (operand.IsShiftValid() && operand.IsPostIndex() &&
10431          cond.IsNotNever()) {
10432        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10433        uint32_t shift_ = TypeEncodingValue(shift);
10434        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10435        EmitA32(0x06000000U | (cond.GetCondition() << 28) |
10436                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10437                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10438        return;
10439      }
10440      // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
10441      if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
10442        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10443        uint32_t shift_ = TypeEncodingValue(shift);
10444        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10445        EmitA32(0x07200000U | (cond.GetCondition() << 28) |
10446                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10447                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10448        return;
10449      }
10450    }
10451  }
10452  Delegate(kStr, &Assembler::str, cond, size, rt, operand);
10453}
10454
10455void Assembler::strb(Condition cond,
10456                     EncodingSize size,
10457                     Register rt,
10458                     const MemOperand& operand) {
10459  VIXL_ASSERT(AllowAssembler());
10460  CheckIT(cond);
10461  if (operand.IsImmediate()) {
10462    Register rn = operand.GetBaseRegister();
10463    int32_t offset = operand.GetOffsetImmediate();
10464    if (IsUsingT32()) {
10465      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10466      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10467          (offset <= 31) && operand.IsOffset()) {
10468        EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) |
10469                   ((offset & 0x1f) << 6));
10470        AdvanceIT();
10471        return;
10472      }
10473      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
10474      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10475          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10476        EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10477                   (offset & 0xfff));
10478        AdvanceIT();
10479        return;
10480      }
10481      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
10482      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10483          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10484        EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10485                   (-offset & 0xff));
10486        AdvanceIT();
10487        return;
10488      }
10489      // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
10490      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10491          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10492        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10493        uint32_t offset_ = abs(offset);
10494        EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10495                   offset_ | (sign << 9));
10496        AdvanceIT();
10497        return;
10498      }
10499      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
10500      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10501          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10502        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10503        uint32_t offset_ = abs(offset);
10504        EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10505                   offset_ | (sign << 9));
10506        AdvanceIT();
10507        return;
10508      }
10509    } else {
10510      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10511      if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
10512          cond.IsNotNever()) {
10513        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10514        uint32_t offset_ = abs(offset);
10515        EmitA32(0x05400000U | (cond.GetCondition() << 28) |
10516                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10517                (sign << 23));
10518        return;
10519      }
10520      // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10521      if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
10522          cond.IsNotNever()) {
10523        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10524        uint32_t offset_ = abs(offset);
10525        EmitA32(0x04400000U | (cond.GetCondition() << 28) |
10526                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10527                (sign << 23));
10528        return;
10529      }
10530      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10531      if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
10532          cond.IsNotNever()) {
10533        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10534        uint32_t offset_ = abs(offset);
10535        EmitA32(0x05600000U | (cond.GetCondition() << 28) |
10536                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10537                (sign << 23));
10538        return;
10539      }
10540    }
10541  }
10542  if (operand.IsPlainRegister()) {
10543    Register rn = operand.GetBaseRegister();
10544    Sign sign = operand.GetSign();
10545    Register rm = operand.GetOffsetRegister();
10546    if (IsUsingT32()) {
10547      // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
10548      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
10549          sign.IsPlus() && operand.IsOffset()) {
10550        EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) |
10551                   (rm.GetCode() << 6));
10552        AdvanceIT();
10553        return;
10554      }
10555    }
10556  }
10557  if (operand.IsShiftedRegister()) {
10558    Register rn = operand.GetBaseRegister();
10559    Sign sign = operand.GetSign();
10560    Register rm = operand.GetOffsetRegister();
10561    Shift shift = operand.GetShift();
10562    uint32_t amount = operand.GetShiftAmount();
10563    if (IsUsingT32()) {
10564      // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
10565      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
10566          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10567        EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10568                   rm.GetCode() | (amount << 4));
10569        AdvanceIT();
10570        return;
10571      }
10572    } else {
10573      // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
10574      if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
10575        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10576        uint32_t shift_ = TypeEncodingValue(shift);
10577        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10578        EmitA32(0x07400000U | (cond.GetCondition() << 28) |
10579                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10580                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10581        return;
10582      }
10583      // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
10584      if (operand.IsShiftValid() && operand.IsPostIndex() &&
10585          cond.IsNotNever()) {
10586        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10587        uint32_t shift_ = TypeEncodingValue(shift);
10588        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10589        EmitA32(0x06400000U | (cond.GetCondition() << 28) |
10590                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10591                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10592        return;
10593      }
10594      // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
10595      if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
10596        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10597        uint32_t shift_ = TypeEncodingValue(shift);
10598        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10599        EmitA32(0x07600000U | (cond.GetCondition() << 28) |
10600                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10601                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10602        return;
10603      }
10604    }
10605  }
10606  Delegate(kStrb, &Assembler::strb, cond, size, rt, operand);
10607}
10608
10609void Assembler::strd(Condition cond,
10610                     Register rt,
10611                     Register rt2,
10612                     const MemOperand& operand) {
10613  VIXL_ASSERT(AllowAssembler());
10614  CheckIT(cond);
10615  if (operand.IsImmediate()) {
10616    Register rn = operand.GetBaseRegister();
10617    int32_t offset = operand.GetOffsetImmediate();
10618    if (IsUsingT32()) {
10619      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
10620      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10621          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10622        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10623        uint32_t offset_ = abs(offset) >> 2;
10624        EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10625                   (rn.GetCode() << 16) | offset_ | (sign << 23));
10626        AdvanceIT();
10627        return;
10628      }
10629      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
10630      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10631          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10632        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10633        uint32_t offset_ = abs(offset) >> 2;
10634        EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10635                   (rn.GetCode() << 16) | offset_ | (sign << 23));
10636        AdvanceIT();
10637        return;
10638      }
10639      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
10640      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10641          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10642        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10643        uint32_t offset_ = abs(offset) >> 2;
10644        EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10645                   (rn.GetCode() << 16) | offset_ | (sign << 23));
10646        AdvanceIT();
10647        return;
10648      }
10649    } else {
10650      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
10651      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10652          (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
10653          cond.IsNotNever() &&
10654          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10655        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10656        uint32_t offset_ = abs(offset);
10657        EmitA32(0x014000f0U | (cond.GetCondition() << 28) |
10658                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10659                ((offset_ & 0xf0) << 4) | (sign << 23));
10660        return;
10661      }
10662      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
10663      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10664          (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
10665          cond.IsNotNever() &&
10666          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10667        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10668        uint32_t offset_ = abs(offset);
10669        EmitA32(0x004000f0U | (cond.GetCondition() << 28) |
10670                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10671                ((offset_ & 0xf0) << 4) | (sign << 23));
10672        return;
10673      }
10674      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
10675      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10676          (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
10677          cond.IsNotNever() &&
10678          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10679        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10680        uint32_t offset_ = abs(offset);
10681        EmitA32(0x016000f0U | (cond.GetCondition() << 28) |
10682                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10683                ((offset_ & 0xf0) << 4) | (sign << 23));
10684        return;
10685      }
10686    }
10687  }
10688  if (operand.IsPlainRegister()) {
10689    Register rn = operand.GetBaseRegister();
10690    Sign sign = operand.GetSign();
10691    Register rm = operand.GetOffsetRegister();
10692    if (IsUsingA32()) {
10693      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
10694      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10695          operand.IsOffset() && cond.IsNotNever() &&
10696          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10697        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10698        EmitA32(0x010000f0U | (cond.GetCondition() << 28) |
10699                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10700                (sign_ << 23));
10701        return;
10702      }
10703      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
10704      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10705          operand.IsPostIndex() && cond.IsNotNever() &&
10706          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10707        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10708        EmitA32(0x000000f0U | (cond.GetCondition() << 28) |
10709                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10710                (sign_ << 23));
10711        return;
10712      }
10713      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
10714      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10715          operand.IsPreIndex() && cond.IsNotNever() &&
10716          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10717        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10718        EmitA32(0x012000f0U | (cond.GetCondition() << 28) |
10719                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10720                (sign_ << 23));
10721        return;
10722      }
10723    }
10724  }
10725  Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand);
10726}
10727
10728void Assembler::strex(Condition cond,
10729                      Register rd,
10730                      Register rt,
10731                      const MemOperand& operand) {
10732  VIXL_ASSERT(AllowAssembler());
10733  CheckIT(cond);
10734  if (operand.IsImmediate()) {
10735    Register rn = operand.GetBaseRegister();
10736    int32_t offset = operand.GetOffsetImmediate();
10737    if (IsUsingT32()) {
10738      // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1
10739      if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
10740          operand.IsOffset()) {
10741        int32_t offset_ = offset >> 2;
10742        EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) |
10743                   (rn.GetCode() << 16) | (offset_ & 0xff));
10744        AdvanceIT();
10745        return;
10746      }
10747    } else {
10748      // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1
10749      if ((offset == 0) && operand.IsOffset() && cond.IsNotNever()) {
10750        EmitA32(0x01800f90U | (cond.GetCondition() << 28) |
10751                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10752        return;
10753      }
10754    }
10755  }
10756  Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand);
10757}
10758
10759void Assembler::strexb(Condition cond,
10760                       Register rd,
10761                       Register rt,
10762                       const MemOperand& operand) {
10763  VIXL_ASSERT(AllowAssembler());
10764  CheckIT(cond);
10765  if (operand.IsImmediateZero()) {
10766    Register rn = operand.GetBaseRegister();
10767    if (IsUsingT32()) {
10768      // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10769      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
10770        EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) |
10771                   (rn.GetCode() << 16));
10772        AdvanceIT();
10773        return;
10774      }
10775    } else {
10776      // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10777      if (operand.IsOffset() && cond.IsNotNever() &&
10778          ((!rn.IsPC()) || AllowUnpredictable())) {
10779        EmitA32(0x01c00f90U | (cond.GetCondition() << 28) |
10780                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10781        return;
10782      }
10783    }
10784  }
10785  Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand);
10786}
10787
10788void Assembler::strexd(Condition cond,
10789                       Register rd,
10790                       Register rt,
10791                       Register rt2,
10792                       const MemOperand& operand) {
10793  VIXL_ASSERT(AllowAssembler());
10794  CheckIT(cond);
10795  if (operand.IsImmediateZero()) {
10796    Register rn = operand.GetBaseRegister();
10797    if (IsUsingT32()) {
10798      // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
10799      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
10800        EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) |
10801                   (rt2.GetCode() << 8) | (rn.GetCode() << 16));
10802        AdvanceIT();
10803        return;
10804      }
10805    } else {
10806      // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
10807      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10808          operand.IsOffset() && cond.IsNotNever() &&
10809          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
10810           AllowUnpredictable())) {
10811        EmitA32(0x01a00f90U | (cond.GetCondition() << 28) |
10812                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10813        return;
10814      }
10815    }
10816  }
10817  Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand);
10818}
10819
10820void Assembler::strexh(Condition cond,
10821                       Register rd,
10822                       Register rt,
10823                       const MemOperand& operand) {
10824  VIXL_ASSERT(AllowAssembler());
10825  CheckIT(cond);
10826  if (operand.IsImmediateZero()) {
10827    Register rn = operand.GetBaseRegister();
10828    if (IsUsingT32()) {
10829      // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10830      if (operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
10831        EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) |
10832                   (rn.GetCode() << 16));
10833        AdvanceIT();
10834        return;
10835      }
10836    } else {
10837      // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10838      if (operand.IsOffset() && cond.IsNotNever() &&
10839          ((!rn.IsPC()) || AllowUnpredictable())) {
10840        EmitA32(0x01e00f90U | (cond.GetCondition() << 28) |
10841                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10842        return;
10843      }
10844    }
10845  }
10846  Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand);
10847}
10848
10849void Assembler::strh(Condition cond,
10850                     EncodingSize size,
10851                     Register rt,
10852                     const MemOperand& operand) {
10853  VIXL_ASSERT(AllowAssembler());
10854  CheckIT(cond);
10855  if (operand.IsImmediate()) {
10856    Register rn = operand.GetBaseRegister();
10857    int32_t offset = operand.GetOffsetImmediate();
10858    if (IsUsingT32()) {
10859      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10860      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10861          (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
10862        int32_t offset_ = offset >> 1;
10863        EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) |
10864                   ((offset_ & 0x1f) << 6));
10865        AdvanceIT();
10866        return;
10867      }
10868      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
10869      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10870          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10871        EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10872                   (offset & 0xfff));
10873        AdvanceIT();
10874        return;
10875      }
10876      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
10877      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10878          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10879        EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10880                   (-offset & 0xff));
10881        AdvanceIT();
10882        return;
10883      }
10884      // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
10885      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10886          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10887        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10888        uint32_t offset_ = abs(offset);
10889        EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10890                   offset_ | (sign << 9));
10891        AdvanceIT();
10892        return;
10893      }
10894      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
10895      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10896          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10897        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10898        uint32_t offset_ = abs(offset);
10899        EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10900                   offset_ | (sign << 9));
10901        AdvanceIT();
10902        return;
10903      }
10904    } else {
10905      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10906      if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
10907          cond.IsNotNever()) {
10908        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10909        uint32_t offset_ = abs(offset);
10910        EmitA32(0x014000b0U | (cond.GetCondition() << 28) |
10911                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10912                ((offset_ & 0xf0) << 4) | (sign << 23));
10913        return;
10914      }
10915      // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10916      if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
10917          cond.IsNotNever()) {
10918        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10919        uint32_t offset_ = abs(offset);
10920        EmitA32(0x004000b0U | (cond.GetCondition() << 28) |
10921                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10922                ((offset_ & 0xf0) << 4) | (sign << 23));
10923        return;
10924      }
10925      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10926      if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
10927          cond.IsNotNever()) {
10928        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10929        uint32_t offset_ = abs(offset);
10930        EmitA32(0x016000b0U | (cond.GetCondition() << 28) |
10931                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10932                ((offset_ & 0xf0) << 4) | (sign << 23));
10933        return;
10934      }
10935    }
10936  }
10937  if (operand.IsPlainRegister()) {
10938    Register rn = operand.GetBaseRegister();
10939    Sign sign = operand.GetSign();
10940    Register rm = operand.GetOffsetRegister();
10941    if (IsUsingT32()) {
10942      // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
10943      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
10944          sign.IsPlus() && operand.IsOffset()) {
10945        EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) |
10946                   (rm.GetCode() << 6));
10947        AdvanceIT();
10948        return;
10949      }
10950    } else {
10951      // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
10952      if (operand.IsOffset() && cond.IsNotNever()) {
10953        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10954        EmitA32(0x010000b0U | (cond.GetCondition() << 28) |
10955                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10956                (sign_ << 23));
10957        return;
10958      }
10959      // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
10960      if (operand.IsPostIndex() && cond.IsNotNever()) {
10961        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10962        EmitA32(0x000000b0U | (cond.GetCondition() << 28) |
10963                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10964                (sign_ << 23));
10965        return;
10966      }
10967      // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
10968      if (operand.IsPreIndex() && cond.IsNotNever()) {
10969        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10970        EmitA32(0x012000b0U | (cond.GetCondition() << 28) |
10971                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10972                (sign_ << 23));
10973        return;
10974      }
10975    }
10976  }
10977  if (operand.IsShiftedRegister()) {
10978    Register rn = operand.GetBaseRegister();
10979    Sign sign = operand.GetSign();
10980    Register rm = operand.GetOffsetRegister();
10981    Shift shift = operand.GetShift();
10982    uint32_t amount = operand.GetShiftAmount();
10983    if (IsUsingT32()) {
10984      // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
10985      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
10986          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10987        EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10988                   rm.GetCode() | (amount << 4));
10989        AdvanceIT();
10990        return;
10991      }
10992    }
10993  }
10994  Delegate(kStrh, &Assembler::strh, cond, size, rt, operand);
10995}
10996
10997void Assembler::sub(Condition cond,
10998                    EncodingSize size,
10999                    Register rd,
11000                    Register rn,
11001                    const Operand& operand) {
11002  VIXL_ASSERT(AllowAssembler());
11003  CheckIT(cond);
11004  if (operand.IsImmediate()) {
11005    uint32_t imm = operand.GetImmediate();
11006    if (IsUsingT32()) {
11007      ImmediateT32 immediate_t32(imm);
11008      // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
11009      if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11010          (imm <= 7)) {
11011        EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
11012        AdvanceIT();
11013        return;
11014      }
11015      // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
11016      if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
11017          (imm <= 255)) {
11018        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11019        AdvanceIT();
11020        return;
11021      }
11022      // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1
11023      if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
11024          ((imm % 4) == 0)) {
11025        uint32_t imm_ = imm >> 2;
11026        EmitT32_16(0xb080 | imm_);
11027        AdvanceIT();
11028        return;
11029      }
11030      // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2
11031      if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095)) {
11032        EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) |
11033                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11034        AdvanceIT();
11035        return;
11036      }
11037      // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
11038      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp)) {
11039        EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11040                   (immediate_t32.GetEncodingValue() & 0xff) |
11041                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11042                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11043        AdvanceIT();
11044        return;
11045      }
11046      // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
11047      if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
11048        EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11049                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11050        AdvanceIT();
11051        return;
11052      }
11053      // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
11054      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid()) {
11055        EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) |
11056                   (immediate_t32.GetEncodingValue() & 0xff) |
11057                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11058                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11059        AdvanceIT();
11060        return;
11061      }
11062      // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
11063      if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095)) {
11064        EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
11065                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11066        AdvanceIT();
11067        return;
11068      }
11069    } else {
11070      ImmediateA32 immediate_a32(imm);
11071      // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2
11072      if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
11073        EmitA32(0x024f0000U | (cond.GetCondition() << 28) |
11074                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
11075        return;
11076      }
11077      // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
11078      if (immediate_a32.IsValid() && cond.IsNotNever() &&
11079          ((rn.GetCode() & 0xd) != 0xd)) {
11080        EmitA32(0x02400000U | (cond.GetCondition() << 28) |
11081                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
11082                immediate_a32.GetEncodingValue());
11083        return;
11084      }
11085      // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
11086      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
11087        EmitA32(0x024d0000U | (cond.GetCondition() << 28) |
11088                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
11089        return;
11090      }
11091    }
11092  }
11093  if (operand.IsImmediateShiftedRegister()) {
11094    Register rm = operand.GetBaseRegister();
11095    if (operand.IsPlainRegister()) {
11096      if (IsUsingT32()) {
11097        // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
11098        if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11099            rm.IsLow()) {
11100          EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
11101                     (rm.GetCode() << 6));
11102          AdvanceIT();
11103          return;
11104        }
11105        // SUB{<c>} {<Rd>}, SP, <Rm> ; T1
11106        if (rn.Is(sp)) {
11107          EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode());
11108          AdvanceIT();
11109          return;
11110        }
11111      }
11112    }
11113    Shift shift = operand.GetShift();
11114    uint32_t amount = operand.GetShiftAmount();
11115    if (IsUsingT32()) {
11116      // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
11117      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp)) {
11118        uint32_t amount_ = amount % 32;
11119        EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11120                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
11121                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11122        AdvanceIT();
11123        return;
11124      }
11125      // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
11126      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount)) {
11127        uint32_t amount_ = amount % 32;
11128        EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() |
11129                   (operand.GetTypeEncodingValue() << 4) |
11130                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11131        AdvanceIT();
11132        return;
11133      }
11134    } else {
11135      // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
11136      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
11137        uint32_t amount_ = amount % 32;
11138        EmitA32(0x00400000U | (cond.GetCondition() << 28) |
11139                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11140                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11141        return;
11142      }
11143      // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
11144      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
11145        uint32_t amount_ = amount % 32;
11146        EmitA32(0x004d0000U | (cond.GetCondition() << 28) |
11147                (rd.GetCode() << 12) | rm.GetCode() |
11148                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11149        return;
11150      }
11151    }
11152  }
11153  if (operand.IsRegisterShiftedRegister()) {
11154    Register rm = operand.GetBaseRegister();
11155    Shift shift = operand.GetShift();
11156    if (IsUsingA32()) {
11157      // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
11158      if (cond.IsNotNever()) {
11159        EmitA32(0x00400010U | (cond.GetCondition() << 28) |
11160                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11161                (shift.GetType() << 5) |
11162                (operand.GetShiftRegister().GetCode() << 8));
11163        return;
11164      }
11165    }
11166  }
11167  Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand);
11168}
11169
11170void Assembler::sub(Condition cond, Register rd, const Operand& operand) {
11171  VIXL_ASSERT(AllowAssembler());
11172  CheckIT(cond);
11173  if (operand.IsImmediate()) {
11174    uint32_t imm = operand.GetImmediate();
11175    if (IsUsingT32()) {
11176      // SUB<c>{<q>} <Rdn>, #<imm8> ; T2
11177      if (InITBlock() && rd.IsLow() && (imm <= 255)) {
11178        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11179        AdvanceIT();
11180        return;
11181      }
11182    }
11183  }
11184  Delegate(kSub, &Assembler::sub, cond, rd, operand);
11185}
11186
11187void Assembler::subs(Condition cond,
11188                     EncodingSize size,
11189                     Register rd,
11190                     Register rn,
11191                     const Operand& operand) {
11192  VIXL_ASSERT(AllowAssembler());
11193  CheckIT(cond);
11194  if (operand.IsImmediate()) {
11195    uint32_t imm = operand.GetImmediate();
11196    if (IsUsingT32()) {
11197      ImmediateT32 immediate_t32(imm);
11198      // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1
11199      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11200          (imm <= 7)) {
11201        EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
11202        AdvanceIT();
11203        return;
11204      }
11205      // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
11206      if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
11207          (imm <= 255)) {
11208        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11209        AdvanceIT();
11210        return;
11211      }
11212      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
11213      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
11214          !rd.Is(pc)) {
11215        EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11216                   (immediate_t32.GetEncodingValue() & 0xff) |
11217                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11218                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11219        AdvanceIT();
11220        return;
11221      }
11222      // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5
11223      if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255)) {
11224        EmitT32_32(0xf3de8f00U | imm);
11225        AdvanceIT();
11226        return;
11227      }
11228      // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
11229      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
11230          !rd.Is(pc)) {
11231        EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) |
11232                   (immediate_t32.GetEncodingValue() & 0xff) |
11233                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11234                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11235        AdvanceIT();
11236        return;
11237      }
11238    } else {
11239      ImmediateA32 immediate_a32(imm);
11240      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
11241      if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
11242        EmitA32(0x02500000U | (cond.GetCondition() << 28) |
11243                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
11244                immediate_a32.GetEncodingValue());
11245        return;
11246      }
11247      // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
11248      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
11249        EmitA32(0x025d0000U | (cond.GetCondition() << 28) |
11250                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
11251        return;
11252      }
11253    }
11254  }
11255  if (operand.IsImmediateShiftedRegister()) {
11256    Register rm = operand.GetBaseRegister();
11257    if (operand.IsPlainRegister()) {
11258      if (IsUsingT32()) {
11259        // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11260        if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11261            rm.IsLow()) {
11262          EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
11263                     (rm.GetCode() << 6));
11264          AdvanceIT();
11265          return;
11266        }
11267      }
11268    }
11269    Shift shift = operand.GetShift();
11270    uint32_t amount = operand.GetShiftAmount();
11271    if (IsUsingT32()) {
11272      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
11273      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
11274          !rd.Is(pc)) {
11275        uint32_t amount_ = amount % 32;
11276        EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11277                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
11278                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11279        AdvanceIT();
11280        return;
11281      }
11282      // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
11283      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
11284          !rd.Is(pc)) {
11285        uint32_t amount_ = amount % 32;
11286        EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() |
11287                   (operand.GetTypeEncodingValue() << 4) |
11288                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11289        AdvanceIT();
11290        return;
11291      }
11292    } else {
11293      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
11294      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
11295        uint32_t amount_ = amount % 32;
11296        EmitA32(0x00500000U | (cond.GetCondition() << 28) |
11297                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11298                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11299        return;
11300      }
11301      // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
11302      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
11303        uint32_t amount_ = amount % 32;
11304        EmitA32(0x005d0000U | (cond.GetCondition() << 28) |
11305                (rd.GetCode() << 12) | rm.GetCode() |
11306                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11307        return;
11308      }
11309    }
11310  }
11311  if (operand.IsRegisterShiftedRegister()) {
11312    Register rm = operand.GetBaseRegister();
11313    Shift shift = operand.GetShift();
11314    if (IsUsingA32()) {
11315      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
11316      if (cond.IsNotNever()) {
11317        EmitA32(0x00500010U | (cond.GetCondition() << 28) |
11318                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11319                (shift.GetType() << 5) |
11320                (operand.GetShiftRegister().GetCode() << 8));
11321        return;
11322      }
11323    }
11324  }
11325  Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand);
11326}
11327
11328void Assembler::subs(Register rd, const Operand& operand) {
11329  VIXL_ASSERT(AllowAssembler());
11330  CheckIT(al);
11331  if (operand.IsImmediate()) {
11332    uint32_t imm = operand.GetImmediate();
11333    if (IsUsingT32()) {
11334      // SUBS{<q>} <Rdn>, #<imm8> ; T2
11335      if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
11336        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11337        AdvanceIT();
11338        return;
11339      }
11340    }
11341  }
11342  Delegate(kSubs, &Assembler::subs, rd, operand);
11343}
11344
11345void Assembler::subw(Condition cond,
11346                     Register rd,
11347                     Register rn,
11348                     const Operand& operand) {
11349  VIXL_ASSERT(AllowAssembler());
11350  CheckIT(cond);
11351  if (operand.IsImmediate()) {
11352    uint32_t imm = operand.GetImmediate();
11353    if (IsUsingT32()) {
11354      // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
11355      if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
11356        EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11357                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11358        AdvanceIT();
11359        return;
11360      }
11361      // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
11362      if (rn.Is(sp) && (imm <= 4095)) {
11363        EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
11364                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11365        AdvanceIT();
11366        return;
11367      }
11368    }
11369  }
11370  Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand);
11371}
11372
11373void Assembler::svc(Condition cond, uint32_t imm) {
11374  VIXL_ASSERT(AllowAssembler());
11375  CheckIT(cond);
11376  if (IsUsingT32()) {
11377    // SVC{<c>}{<q>} {#}<imm> ; T1
11378    if ((imm <= 255)) {
11379      EmitT32_16(0xdf00 | imm);
11380      AdvanceIT();
11381      return;
11382    }
11383  } else {
11384    // SVC{<c>}{<q>} {#}<imm> ; A1
11385    if ((imm <= 16777215) && cond.IsNotNever()) {
11386      EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm);
11387      return;
11388    }
11389  }
11390  Delegate(kSvc, &Assembler::svc, cond, imm);
11391}
11392
11393void Assembler::sxtab(Condition cond,
11394                      Register rd,
11395                      Register rn,
11396                      const Operand& operand) {
11397  VIXL_ASSERT(AllowAssembler());
11398  CheckIT(cond);
11399  if (operand.IsImmediateShiftedRegister()) {
11400    Register rm = operand.GetBaseRegister();
11401    Shift shift = operand.GetShift();
11402    uint32_t amount = operand.GetShiftAmount();
11403    if (IsUsingT32()) {
11404      // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11405      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11406          ((amount % 8) == 0) && !rn.Is(pc)) {
11407        uint32_t amount_ = amount / 8;
11408        EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11409                   rm.GetCode() | (amount_ << 4));
11410        AdvanceIT();
11411        return;
11412      }
11413    } else {
11414      // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11415      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11416          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11417        uint32_t amount_ = amount / 8;
11418        EmitA32(0x06a00070U | (cond.GetCondition() << 28) |
11419                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11420                (amount_ << 10));
11421        return;
11422      }
11423    }
11424  }
11425  Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand);
11426}
11427
11428void Assembler::sxtab16(Condition cond,
11429                        Register rd,
11430                        Register rn,
11431                        const Operand& operand) {
11432  VIXL_ASSERT(AllowAssembler());
11433  CheckIT(cond);
11434  if (operand.IsImmediateShiftedRegister()) {
11435    Register rm = operand.GetBaseRegister();
11436    Shift shift = operand.GetShift();
11437    uint32_t amount = operand.GetShiftAmount();
11438    if (IsUsingT32()) {
11439      // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11440      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11441          ((amount % 8) == 0) && !rn.Is(pc)) {
11442        uint32_t amount_ = amount / 8;
11443        EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11444                   rm.GetCode() | (amount_ << 4));
11445        AdvanceIT();
11446        return;
11447      }
11448    } else {
11449      // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11450      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11451          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11452        uint32_t amount_ = amount / 8;
11453        EmitA32(0x06800070U | (cond.GetCondition() << 28) |
11454                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11455                (amount_ << 10));
11456        return;
11457      }
11458    }
11459  }
11460  Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand);
11461}
11462
11463void Assembler::sxtah(Condition cond,
11464                      Register rd,
11465                      Register rn,
11466                      const Operand& operand) {
11467  VIXL_ASSERT(AllowAssembler());
11468  CheckIT(cond);
11469  if (operand.IsImmediateShiftedRegister()) {
11470    Register rm = operand.GetBaseRegister();
11471    Shift shift = operand.GetShift();
11472    uint32_t amount = operand.GetShiftAmount();
11473    if (IsUsingT32()) {
11474      // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11475      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11476          ((amount % 8) == 0) && !rn.Is(pc)) {
11477        uint32_t amount_ = amount / 8;
11478        EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11479                   rm.GetCode() | (amount_ << 4));
11480        AdvanceIT();
11481        return;
11482      }
11483    } else {
11484      // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11485      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11486          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11487        uint32_t amount_ = amount / 8;
11488        EmitA32(0x06b00070U | (cond.GetCondition() << 28) |
11489                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11490                (amount_ << 10));
11491        return;
11492      }
11493    }
11494  }
11495  Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand);
11496}
11497
11498void Assembler::sxtb(Condition cond,
11499                     EncodingSize size,
11500                     Register rd,
11501                     const Operand& operand) {
11502  VIXL_ASSERT(AllowAssembler());
11503  CheckIT(cond);
11504  if (operand.IsImmediateShiftedRegister()) {
11505    Register rm = operand.GetBaseRegister();
11506    if (operand.IsPlainRegister()) {
11507      if (IsUsingT32()) {
11508        // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
11509        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
11510          EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3));
11511          AdvanceIT();
11512          return;
11513        }
11514      }
11515    }
11516    Shift shift = operand.GetShift();
11517    uint32_t amount = operand.GetShiftAmount();
11518    if (IsUsingT32()) {
11519      // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
11520      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
11521          (amount <= 24) && ((amount % 8) == 0)) {
11522        uint32_t amount_ = amount / 8;
11523        EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11524                   (amount_ << 4));
11525        AdvanceIT();
11526        return;
11527      }
11528    } else {
11529      // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11530      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11531          ((amount % 8) == 0) && cond.IsNotNever()) {
11532        uint32_t amount_ = amount / 8;
11533        EmitA32(0x06af0070U | (cond.GetCondition() << 28) |
11534                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11535        return;
11536      }
11537    }
11538  }
11539  Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand);
11540}
11541
11542void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) {
11543  VIXL_ASSERT(AllowAssembler());
11544  CheckIT(cond);
11545  if (operand.IsImmediateShiftedRegister()) {
11546    Register rm = operand.GetBaseRegister();
11547    Shift shift = operand.GetShift();
11548    uint32_t amount = operand.GetShiftAmount();
11549    if (IsUsingT32()) {
11550      // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
11551      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11552          ((amount % 8) == 0)) {
11553        uint32_t amount_ = amount / 8;
11554        EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11555                   (amount_ << 4));
11556        AdvanceIT();
11557        return;
11558      }
11559    } else {
11560      // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11561      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11562          ((amount % 8) == 0) && cond.IsNotNever()) {
11563        uint32_t amount_ = amount / 8;
11564        EmitA32(0x068f0070U | (cond.GetCondition() << 28) |
11565                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11566        return;
11567      }
11568    }
11569  }
11570  Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand);
11571}
11572
11573void Assembler::sxth(Condition cond,
11574                     EncodingSize size,
11575                     Register rd,
11576                     const Operand& operand) {
11577  VIXL_ASSERT(AllowAssembler());
11578  CheckIT(cond);
11579  if (operand.IsImmediateShiftedRegister()) {
11580    Register rm = operand.GetBaseRegister();
11581    if (operand.IsPlainRegister()) {
11582      if (IsUsingT32()) {
11583        // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
11584        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
11585          EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3));
11586          AdvanceIT();
11587          return;
11588        }
11589      }
11590    }
11591    Shift shift = operand.GetShift();
11592    uint32_t amount = operand.GetShiftAmount();
11593    if (IsUsingT32()) {
11594      // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
11595      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
11596          (amount <= 24) && ((amount % 8) == 0)) {
11597        uint32_t amount_ = amount / 8;
11598        EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11599                   (amount_ << 4));
11600        AdvanceIT();
11601        return;
11602      }
11603    } else {
11604      // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11605      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11606          ((amount % 8) == 0) && cond.IsNotNever()) {
11607        uint32_t amount_ = amount / 8;
11608        EmitA32(0x06bf0070U | (cond.GetCondition() << 28) |
11609                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11610        return;
11611      }
11612    }
11613  }
11614  Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand);
11615}
11616
11617void Assembler::tbb(Condition cond, Register rn, Register rm) {
11618  VIXL_ASSERT(AllowAssembler());
11619  CheckIT(cond);
11620  if (IsUsingT32()) {
11621    // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1
11622    if (OutsideITBlockAndAlOrLast(cond) &&
11623        ((!rm.IsPC()) || AllowUnpredictable())) {
11624      EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode());
11625      AdvanceIT();
11626      return;
11627    }
11628  }
11629  Delegate(kTbb, &Assembler::tbb, cond, rn, rm);
11630}
11631
11632void Assembler::tbh(Condition cond, Register rn, Register rm) {
11633  VIXL_ASSERT(AllowAssembler());
11634  CheckIT(cond);
11635  if (IsUsingT32()) {
11636    // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1
11637    if (OutsideITBlockAndAlOrLast(cond) &&
11638        ((!rm.IsPC()) || AllowUnpredictable())) {
11639      EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode());
11640      AdvanceIT();
11641      return;
11642    }
11643  }
11644  Delegate(kTbh, &Assembler::tbh, cond, rn, rm);
11645}
11646
11647void Assembler::teq(Condition cond, Register rn, const Operand& operand) {
11648  VIXL_ASSERT(AllowAssembler());
11649  CheckIT(cond);
11650  if (operand.IsImmediate()) {
11651    uint32_t imm = operand.GetImmediate();
11652    if (IsUsingT32()) {
11653      ImmediateT32 immediate_t32(imm);
11654      // TEQ{<c>}{<q>} <Rn>, #<const> ; T1
11655      if (immediate_t32.IsValid()) {
11656        EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) |
11657                   (immediate_t32.GetEncodingValue() & 0xff) |
11658                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11659                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11660        AdvanceIT();
11661        return;
11662      }
11663    } else {
11664      ImmediateA32 immediate_a32(imm);
11665      // TEQ{<c>}{<q>} <Rn>, #<const> ; A1
11666      if (immediate_a32.IsValid() && cond.IsNotNever()) {
11667        EmitA32(0x03300000U | (cond.GetCondition() << 28) |
11668                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
11669        return;
11670      }
11671    }
11672  }
11673  if (operand.IsImmediateShiftedRegister()) {
11674    Register rm = operand.GetBaseRegister();
11675    Shift shift = operand.GetShift();
11676    uint32_t amount = operand.GetShiftAmount();
11677    if (IsUsingT32()) {
11678      // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1
11679      if (shift.IsValidAmount(amount)) {
11680        uint32_t amount_ = amount % 32;
11681        EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() |
11682                   (operand.GetTypeEncodingValue() << 4) |
11683                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11684        AdvanceIT();
11685        return;
11686      }
11687    } else {
11688      // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
11689      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
11690        uint32_t amount_ = amount % 32;
11691        EmitA32(0x01300000U | (cond.GetCondition() << 28) |
11692                (rn.GetCode() << 16) | rm.GetCode() |
11693                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11694        return;
11695      }
11696    }
11697  }
11698  if (operand.IsRegisterShiftedRegister()) {
11699    Register rm = operand.GetBaseRegister();
11700    Shift shift = operand.GetShift();
11701    if (IsUsingA32()) {
11702      // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
11703      if (cond.IsNotNever()) {
11704        EmitA32(0x01300010U | (cond.GetCondition() << 28) |
11705                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
11706                (operand.GetShiftRegister().GetCode() << 8));
11707        return;
11708      }
11709    }
11710  }
11711  Delegate(kTeq, &Assembler::teq, cond, rn, operand);
11712}
11713
11714void Assembler::tst(Condition cond,
11715                    EncodingSize size,
11716                    Register rn,
11717                    const Operand& operand) {
11718  VIXL_ASSERT(AllowAssembler());
11719  CheckIT(cond);
11720  if (operand.IsImmediate()) {
11721    uint32_t imm = operand.GetImmediate();
11722    if (IsUsingT32()) {
11723      ImmediateT32 immediate_t32(imm);
11724      // TST{<c>}{<q>} <Rn>, #<const> ; T1
11725      if (!size.IsNarrow() && immediate_t32.IsValid()) {
11726        EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) |
11727                   (immediate_t32.GetEncodingValue() & 0xff) |
11728                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11729                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11730        AdvanceIT();
11731        return;
11732      }
11733    } else {
11734      ImmediateA32 immediate_a32(imm);
11735      // TST{<c>}{<q>} <Rn>, #<const> ; A1
11736      if (immediate_a32.IsValid() && cond.IsNotNever()) {
11737        EmitA32(0x03100000U | (cond.GetCondition() << 28) |
11738                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
11739        return;
11740      }
11741    }
11742  }
11743  if (operand.IsImmediateShiftedRegister()) {
11744    Register rm = operand.GetBaseRegister();
11745    if (operand.IsPlainRegister()) {
11746      if (IsUsingT32()) {
11747        // TST{<c>}{<q>} <Rn>, <Rm> ; T1
11748        if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
11749          EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3));
11750          AdvanceIT();
11751          return;
11752        }
11753      }
11754    }
11755    Shift shift = operand.GetShift();
11756    uint32_t amount = operand.GetShiftAmount();
11757    if (IsUsingT32()) {
11758      // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
11759      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
11760        uint32_t amount_ = amount % 32;
11761        EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() |
11762                   (operand.GetTypeEncodingValue() << 4) |
11763                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11764        AdvanceIT();
11765        return;
11766      }
11767    } else {
11768      // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
11769      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
11770        uint32_t amount_ = amount % 32;
11771        EmitA32(0x01100000U | (cond.GetCondition() << 28) |
11772                (rn.GetCode() << 16) | rm.GetCode() |
11773                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11774        return;
11775      }
11776    }
11777  }
11778  if (operand.IsRegisterShiftedRegister()) {
11779    Register rm = operand.GetBaseRegister();
11780    Shift shift = operand.GetShift();
11781    if (IsUsingA32()) {
11782      // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
11783      if (cond.IsNotNever()) {
11784        EmitA32(0x01100010U | (cond.GetCondition() << 28) |
11785                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
11786                (operand.GetShiftRegister().GetCode() << 8));
11787        return;
11788      }
11789    }
11790  }
11791  Delegate(kTst, &Assembler::tst, cond, size, rn, operand);
11792}
11793
11794void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) {
11795  VIXL_ASSERT(AllowAssembler());
11796  CheckIT(cond);
11797  if (IsUsingT32()) {
11798    // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11799    EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11800               rm.GetCode());
11801    AdvanceIT();
11802    return;
11803  } else {
11804    // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11805    if (cond.IsNotNever()) {
11806      EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11807              (rn.GetCode() << 16) | rm.GetCode());
11808      return;
11809    }
11810  }
11811  Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm);
11812}
11813
11814void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) {
11815  VIXL_ASSERT(AllowAssembler());
11816  CheckIT(cond);
11817  if (IsUsingT32()) {
11818    // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11819    EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11820               rm.GetCode());
11821    AdvanceIT();
11822    return;
11823  } else {
11824    // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11825    if (cond.IsNotNever()) {
11826      EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11827              (rn.GetCode() << 16) | rm.GetCode());
11828      return;
11829    }
11830  }
11831  Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm);
11832}
11833
11834void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) {
11835  VIXL_ASSERT(AllowAssembler());
11836  CheckIT(cond);
11837  if (IsUsingT32()) {
11838    // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11839    EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11840               rm.GetCode());
11841    AdvanceIT();
11842    return;
11843  } else {
11844    // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11845    if (cond.IsNotNever()) {
11846      EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11847              (rn.GetCode() << 16) | rm.GetCode());
11848      return;
11849    }
11850  }
11851  Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm);
11852}
11853
11854void Assembler::ubfx(Condition cond,
11855                     Register rd,
11856                     Register rn,
11857                     uint32_t lsb,
11858                     const Operand& operand) {
11859  VIXL_ASSERT(AllowAssembler());
11860  CheckIT(cond);
11861  if (operand.IsImmediate()) {
11862    uint32_t width = operand.GetImmediate();
11863    if (IsUsingT32()) {
11864      // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
11865      if ((lsb <= 31) &&
11866          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
11867        uint32_t widthm1 = width - 1;
11868        EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11869                   ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
11870        AdvanceIT();
11871        return;
11872      }
11873    } else {
11874      // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
11875      if ((lsb <= 31) && cond.IsNotNever() &&
11876          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
11877        uint32_t widthm1 = width - 1;
11878        EmitA32(0x07e00050U | (cond.GetCondition() << 28) |
11879                (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) |
11880                (widthm1 << 16));
11881        return;
11882      }
11883    }
11884  }
11885  Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, operand);
11886}
11887
11888void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) {
11889  VIXL_ASSERT(AllowAssembler());
11890  CheckIT(cond);
11891  if (IsUsingT32()) {
11892    // UDF{<c>}{<q>} {#}<imm> ; T1
11893    if (!size.IsWide() && (imm <= 255)) {
11894      if (cond.Is(al) || AllowStronglyDiscouraged()) {
11895        EmitT32_16(0xde00 | imm);
11896        AdvanceIT();
11897        return;
11898      }
11899    }
11900    // UDF{<c>}{<q>} {#}<imm> ; T2
11901    if (!size.IsNarrow() && (imm <= 65535)) {
11902      if (cond.Is(al) || AllowStronglyDiscouraged()) {
11903        EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
11904        AdvanceIT();
11905        return;
11906      }
11907    }
11908  } else {
11909    // UDF{<c>}{<q>} {#}<imm> ; A1
11910    if ((imm <= 65535)) {
11911      if (cond.Is(al) || AllowStronglyDiscouraged()) {
11912        EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4));
11913        return;
11914      }
11915    }
11916  }
11917  Delegate(kUdf, &Assembler::udf, cond, size, imm);
11918}
11919
11920void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) {
11921  VIXL_ASSERT(AllowAssembler());
11922  CheckIT(cond);
11923  if (IsUsingT32()) {
11924    // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11925    EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11926               rm.GetCode());
11927    AdvanceIT();
11928    return;
11929  } else {
11930    // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11931    if (cond.IsNotNever()) {
11932      EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
11933              rn.GetCode() | (rm.GetCode() << 8));
11934      return;
11935    }
11936  }
11937  Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm);
11938}
11939
11940void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) {
11941  VIXL_ASSERT(AllowAssembler());
11942  CheckIT(cond);
11943  if (IsUsingT32()) {
11944    // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11945    EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11946               rm.GetCode());
11947    AdvanceIT();
11948    return;
11949  } else {
11950    // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11951    if (cond.IsNotNever()) {
11952      EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11953              (rn.GetCode() << 16) | rm.GetCode());
11954      return;
11955    }
11956  }
11957  Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm);
11958}
11959
11960void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) {
11961  VIXL_ASSERT(AllowAssembler());
11962  CheckIT(cond);
11963  if (IsUsingT32()) {
11964    // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11965    EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11966               rm.GetCode());
11967    AdvanceIT();
11968    return;
11969  } else {
11970    // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11971    if (cond.IsNotNever()) {
11972      EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11973              (rn.GetCode() << 16) | rm.GetCode());
11974      return;
11975    }
11976  }
11977  Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm);
11978}
11979
11980void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) {
11981  VIXL_ASSERT(AllowAssembler());
11982  CheckIT(cond);
11983  if (IsUsingT32()) {
11984    // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11985    EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11986               rm.GetCode());
11987    AdvanceIT();
11988    return;
11989  } else {
11990    // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11991    if (cond.IsNotNever()) {
11992      EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11993              (rn.GetCode() << 16) | rm.GetCode());
11994      return;
11995    }
11996  }
11997  Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm);
11998}
11999
12000void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) {
12001  VIXL_ASSERT(AllowAssembler());
12002  CheckIT(cond);
12003  if (IsUsingT32()) {
12004    // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12005    EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12006               rm.GetCode());
12007    AdvanceIT();
12008    return;
12009  } else {
12010    // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12011    if (cond.IsNotNever()) {
12012      EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12013              (rn.GetCode() << 16) | rm.GetCode());
12014      return;
12015    }
12016  }
12017  Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm);
12018}
12019
12020void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) {
12021  VIXL_ASSERT(AllowAssembler());
12022  CheckIT(cond);
12023  if (IsUsingT32()) {
12024    // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12025    EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12026               rm.GetCode());
12027    AdvanceIT();
12028    return;
12029  } else {
12030    // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12031    if (cond.IsNotNever()) {
12032      EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12033              (rn.GetCode() << 16) | rm.GetCode());
12034      return;
12035    }
12036  }
12037  Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm);
12038}
12039
12040void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) {
12041  VIXL_ASSERT(AllowAssembler());
12042  CheckIT(cond);
12043  if (IsUsingT32()) {
12044    // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12045    EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12046               rm.GetCode());
12047    AdvanceIT();
12048    return;
12049  } else {
12050    // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12051    if (cond.IsNotNever()) {
12052      EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12053              (rn.GetCode() << 16) | rm.GetCode());
12054      return;
12055    }
12056  }
12057  Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm);
12058}
12059
12060void Assembler::umaal(
12061    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12062  VIXL_ASSERT(AllowAssembler());
12063  CheckIT(cond);
12064  if (IsUsingT32()) {
12065    // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
12066    EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
12067               (rn.GetCode() << 16) | rm.GetCode());
12068    AdvanceIT();
12069    return;
12070  } else {
12071    // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12072    if (cond.IsNotNever()) {
12073      EmitA32(0x00400090U | (cond.GetCondition() << 28) |
12074              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12075              (rm.GetCode() << 8));
12076      return;
12077    }
12078  }
12079  Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm);
12080}
12081
12082void Assembler::umlal(
12083    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12084  VIXL_ASSERT(AllowAssembler());
12085  CheckIT(cond);
12086  if (IsUsingT32()) {
12087    // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
12088    EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
12089               (rn.GetCode() << 16) | rm.GetCode());
12090    AdvanceIT();
12091    return;
12092  } else {
12093    // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12094    if (cond.IsNotNever()) {
12095      EmitA32(0x00a00090U | (cond.GetCondition() << 28) |
12096              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12097              (rm.GetCode() << 8));
12098      return;
12099    }
12100  }
12101  Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm);
12102}
12103
12104void Assembler::umlals(
12105    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12106  VIXL_ASSERT(AllowAssembler());
12107  CheckIT(cond);
12108  if (IsUsingA32()) {
12109    // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12110    if (cond.IsNotNever()) {
12111      EmitA32(0x00b00090U | (cond.GetCondition() << 28) |
12112              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12113              (rm.GetCode() << 8));
12114      return;
12115    }
12116  }
12117  Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm);
12118}
12119
12120void Assembler::umull(
12121    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12122  VIXL_ASSERT(AllowAssembler());
12123  CheckIT(cond);
12124  if (IsUsingT32()) {
12125    // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
12126    EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
12127               (rn.GetCode() << 16) | rm.GetCode());
12128    AdvanceIT();
12129    return;
12130  } else {
12131    // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12132    if (cond.IsNotNever()) {
12133      EmitA32(0x00800090U | (cond.GetCondition() << 28) |
12134              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12135              (rm.GetCode() << 8));
12136      return;
12137    }
12138  }
12139  Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm);
12140}
12141
12142void Assembler::umulls(
12143    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12144  VIXL_ASSERT(AllowAssembler());
12145  CheckIT(cond);
12146  if (IsUsingA32()) {
12147    // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12148    if (cond.IsNotNever()) {
12149      EmitA32(0x00900090U | (cond.GetCondition() << 28) |
12150              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12151              (rm.GetCode() << 8));
12152      return;
12153    }
12154  }
12155  Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm);
12156}
12157
12158void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) {
12159  VIXL_ASSERT(AllowAssembler());
12160  CheckIT(cond);
12161  if (IsUsingT32()) {
12162    // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12163    EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12164               rm.GetCode());
12165    AdvanceIT();
12166    return;
12167  } else {
12168    // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12169    if (cond.IsNotNever()) {
12170      EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12171              (rn.GetCode() << 16) | rm.GetCode());
12172      return;
12173    }
12174  }
12175  Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm);
12176}
12177
12178void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) {
12179  VIXL_ASSERT(AllowAssembler());
12180  CheckIT(cond);
12181  if (IsUsingT32()) {
12182    // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12183    EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12184               rm.GetCode());
12185    AdvanceIT();
12186    return;
12187  } else {
12188    // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12189    if (cond.IsNotNever()) {
12190      EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12191              (rn.GetCode() << 16) | rm.GetCode());
12192      return;
12193    }
12194  }
12195  Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm);
12196}
12197
12198void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) {
12199  VIXL_ASSERT(AllowAssembler());
12200  CheckIT(cond);
12201  if (IsUsingT32()) {
12202    // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12203    EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12204               rm.GetCode());
12205    AdvanceIT();
12206    return;
12207  } else {
12208    // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12209    if (cond.IsNotNever()) {
12210      EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12211              (rn.GetCode() << 16) | rm.GetCode());
12212      return;
12213    }
12214  }
12215  Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm);
12216}
12217
12218void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) {
12219  VIXL_ASSERT(AllowAssembler());
12220  CheckIT(cond);
12221  if (IsUsingT32()) {
12222    // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12223    EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12224               rm.GetCode());
12225    AdvanceIT();
12226    return;
12227  } else {
12228    // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12229    if (cond.IsNotNever()) {
12230      EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12231              (rn.GetCode() << 16) | rm.GetCode());
12232      return;
12233    }
12234  }
12235  Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm);
12236}
12237
12238void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) {
12239  VIXL_ASSERT(AllowAssembler());
12240  CheckIT(cond);
12241  if (IsUsingT32()) {
12242    // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12243    EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12244               rm.GetCode());
12245    AdvanceIT();
12246    return;
12247  } else {
12248    // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12249    if (cond.IsNotNever()) {
12250      EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12251              (rn.GetCode() << 16) | rm.GetCode());
12252      return;
12253    }
12254  }
12255  Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm);
12256}
12257
12258void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) {
12259  VIXL_ASSERT(AllowAssembler());
12260  CheckIT(cond);
12261  if (IsUsingT32()) {
12262    // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12263    EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12264               rm.GetCode());
12265    AdvanceIT();
12266    return;
12267  } else {
12268    // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12269    if (cond.IsNotNever()) {
12270      EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12271              (rn.GetCode() << 16) | rm.GetCode());
12272      return;
12273    }
12274  }
12275  Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm);
12276}
12277
12278void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) {
12279  VIXL_ASSERT(AllowAssembler());
12280  CheckIT(cond);
12281  if (IsUsingT32()) {
12282    // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12283    EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12284               rm.GetCode());
12285    AdvanceIT();
12286    return;
12287  } else {
12288    // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12289    if (cond.IsNotNever()) {
12290      EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
12291              rn.GetCode() | (rm.GetCode() << 8));
12292      return;
12293    }
12294  }
12295  Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm);
12296}
12297
12298void Assembler::usada8(
12299    Condition cond, Register rd, Register rn, Register rm, Register ra) {
12300  VIXL_ASSERT(AllowAssembler());
12301  CheckIT(cond);
12302  if (IsUsingT32()) {
12303    // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
12304    if (!ra.Is(pc)) {
12305      EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12306                 rm.GetCode() | (ra.GetCode() << 12));
12307      AdvanceIT();
12308      return;
12309    }
12310  } else {
12311    // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
12312    if (cond.IsNotNever() && !ra.Is(pc)) {
12313      EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
12314              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
12315      return;
12316    }
12317  }
12318  Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra);
12319}
12320
12321void Assembler::usat(Condition cond,
12322                     Register rd,
12323                     uint32_t imm,
12324                     const Operand& operand) {
12325  VIXL_ASSERT(AllowAssembler());
12326  CheckIT(cond);
12327  if (operand.IsImmediateShiftedRegister()) {
12328    Register rn = operand.GetBaseRegister();
12329    Shift shift = operand.GetShift();
12330    uint32_t amount = operand.GetShiftAmount();
12331    if (IsUsingT32()) {
12332      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
12333      if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31)) {
12334        EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
12335                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
12336                   ((amount & 0x1c) << 10));
12337        AdvanceIT();
12338        return;
12339      }
12340      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
12341      if ((imm <= 31) && shift.IsLSL() && (amount <= 31)) {
12342        EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm |
12343                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
12344                   ((amount & 0x1c) << 10));
12345        AdvanceIT();
12346        return;
12347      }
12348    } else {
12349      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
12350      if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) &&
12351          cond.IsNotNever()) {
12352        uint32_t amount_ = amount % 32;
12353        EmitA32(0x06e00050U | (cond.GetCondition() << 28) |
12354                (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
12355                (amount_ << 7));
12356        return;
12357      }
12358      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
12359      if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever()) {
12360        EmitA32(0x06e00010U | (cond.GetCondition() << 28) |
12361                (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
12362                (amount << 7));
12363        return;
12364      }
12365    }
12366  }
12367  Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand);
12368}
12369
12370void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) {
12371  VIXL_ASSERT(AllowAssembler());
12372  CheckIT(cond);
12373  if (IsUsingT32()) {
12374    // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
12375    if ((imm <= 15)) {
12376      EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
12377                 (rn.GetCode() << 16));
12378      AdvanceIT();
12379      return;
12380    }
12381  } else {
12382    // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
12383    if ((imm <= 15) && cond.IsNotNever()) {
12384      EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12385              (imm << 16) | rn.GetCode());
12386      return;
12387    }
12388  }
12389  Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn);
12390}
12391
12392void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) {
12393  VIXL_ASSERT(AllowAssembler());
12394  CheckIT(cond);
12395  if (IsUsingT32()) {
12396    // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12397    EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12398               rm.GetCode());
12399    AdvanceIT();
12400    return;
12401  } else {
12402    // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12403    if (cond.IsNotNever()) {
12404      EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12405              (rn.GetCode() << 16) | rm.GetCode());
12406      return;
12407    }
12408  }
12409  Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm);
12410}
12411
12412void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) {
12413  VIXL_ASSERT(AllowAssembler());
12414  CheckIT(cond);
12415  if (IsUsingT32()) {
12416    // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12417    EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12418               rm.GetCode());
12419    AdvanceIT();
12420    return;
12421  } else {
12422    // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12423    if (cond.IsNotNever()) {
12424      EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12425              (rn.GetCode() << 16) | rm.GetCode());
12426      return;
12427    }
12428  }
12429  Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm);
12430}
12431
12432void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) {
12433  VIXL_ASSERT(AllowAssembler());
12434  CheckIT(cond);
12435  if (IsUsingT32()) {
12436    // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12437    EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12438               rm.GetCode());
12439    AdvanceIT();
12440    return;
12441  } else {
12442    // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12443    if (cond.IsNotNever()) {
12444      EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12445              (rn.GetCode() << 16) | rm.GetCode());
12446      return;
12447    }
12448  }
12449  Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm);
12450}
12451
12452void Assembler::uxtab(Condition cond,
12453                      Register rd,
12454                      Register rn,
12455                      const Operand& operand) {
12456  VIXL_ASSERT(AllowAssembler());
12457  CheckIT(cond);
12458  if (operand.IsImmediateShiftedRegister()) {
12459    Register rm = operand.GetBaseRegister();
12460    Shift shift = operand.GetShift();
12461    uint32_t amount = operand.GetShiftAmount();
12462    if (IsUsingT32()) {
12463      // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12464      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12465          ((amount % 8) == 0) && !rn.Is(pc)) {
12466        uint32_t amount_ = amount / 8;
12467        EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12468                   rm.GetCode() | (amount_ << 4));
12469        AdvanceIT();
12470        return;
12471      }
12472    } else {
12473      // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12474      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12475          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12476        uint32_t amount_ = amount / 8;
12477        EmitA32(0x06e00070U | (cond.GetCondition() << 28) |
12478                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12479                (amount_ << 10));
12480        return;
12481      }
12482    }
12483  }
12484  Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand);
12485}
12486
12487void Assembler::uxtab16(Condition cond,
12488                        Register rd,
12489                        Register rn,
12490                        const Operand& operand) {
12491  VIXL_ASSERT(AllowAssembler());
12492  CheckIT(cond);
12493  if (operand.IsImmediateShiftedRegister()) {
12494    Register rm = operand.GetBaseRegister();
12495    Shift shift = operand.GetShift();
12496    uint32_t amount = operand.GetShiftAmount();
12497    if (IsUsingT32()) {
12498      // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12499      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12500          ((amount % 8) == 0) && !rn.Is(pc)) {
12501        uint32_t amount_ = amount / 8;
12502        EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12503                   rm.GetCode() | (amount_ << 4));
12504        AdvanceIT();
12505        return;
12506      }
12507    } else {
12508      // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12509      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12510          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12511        uint32_t amount_ = amount / 8;
12512        EmitA32(0x06c00070U | (cond.GetCondition() << 28) |
12513                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12514                (amount_ << 10));
12515        return;
12516      }
12517    }
12518  }
12519  Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand);
12520}
12521
12522void Assembler::uxtah(Condition cond,
12523                      Register rd,
12524                      Register rn,
12525                      const Operand& operand) {
12526  VIXL_ASSERT(AllowAssembler());
12527  CheckIT(cond);
12528  if (operand.IsImmediateShiftedRegister()) {
12529    Register rm = operand.GetBaseRegister();
12530    Shift shift = operand.GetShift();
12531    uint32_t amount = operand.GetShiftAmount();
12532    if (IsUsingT32()) {
12533      // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12534      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12535          ((amount % 8) == 0) && !rn.Is(pc)) {
12536        uint32_t amount_ = amount / 8;
12537        EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12538                   rm.GetCode() | (amount_ << 4));
12539        AdvanceIT();
12540        return;
12541      }
12542    } else {
12543      // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12544      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12545          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12546        uint32_t amount_ = amount / 8;
12547        EmitA32(0x06f00070U | (cond.GetCondition() << 28) |
12548                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12549                (amount_ << 10));
12550        return;
12551      }
12552    }
12553  }
12554  Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand);
12555}
12556
12557void Assembler::uxtb(Condition cond,
12558                     EncodingSize size,
12559                     Register rd,
12560                     const Operand& operand) {
12561  VIXL_ASSERT(AllowAssembler());
12562  CheckIT(cond);
12563  if (operand.IsImmediateShiftedRegister()) {
12564    Register rm = operand.GetBaseRegister();
12565    if (operand.IsPlainRegister()) {
12566      if (IsUsingT32()) {
12567        // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
12568        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12569          EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3));
12570          AdvanceIT();
12571          return;
12572        }
12573      }
12574    }
12575    Shift shift = operand.GetShift();
12576    uint32_t amount = operand.GetShiftAmount();
12577    if (IsUsingT32()) {
12578      // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12579      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12580          (amount <= 24) && ((amount % 8) == 0)) {
12581        uint32_t amount_ = amount / 8;
12582        EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12583                   (amount_ << 4));
12584        AdvanceIT();
12585        return;
12586      }
12587    } else {
12588      // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12589      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12590          ((amount % 8) == 0) && cond.IsNotNever()) {
12591        uint32_t amount_ = amount / 8;
12592        EmitA32(0x06ef0070U | (cond.GetCondition() << 28) |
12593                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12594        return;
12595      }
12596    }
12597  }
12598  Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand);
12599}
12600
12601void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) {
12602  VIXL_ASSERT(AllowAssembler());
12603  CheckIT(cond);
12604  if (operand.IsImmediateShiftedRegister()) {
12605    Register rm = operand.GetBaseRegister();
12606    Shift shift = operand.GetShift();
12607    uint32_t amount = operand.GetShiftAmount();
12608    if (IsUsingT32()) {
12609      // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
12610      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12611          ((amount % 8) == 0)) {
12612        uint32_t amount_ = amount / 8;
12613        EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12614                   (amount_ << 4));
12615        AdvanceIT();
12616        return;
12617      }
12618    } else {
12619      // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12620      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12621          ((amount % 8) == 0) && cond.IsNotNever()) {
12622        uint32_t amount_ = amount / 8;
12623        EmitA32(0x06cf0070U | (cond.GetCondition() << 28) |
12624                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12625        return;
12626      }
12627    }
12628  }
12629  Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand);
12630}
12631
12632void Assembler::uxth(Condition cond,
12633                     EncodingSize size,
12634                     Register rd,
12635                     const Operand& operand) {
12636  VIXL_ASSERT(AllowAssembler());
12637  CheckIT(cond);
12638  if (operand.IsImmediateShiftedRegister()) {
12639    Register rm = operand.GetBaseRegister();
12640    if (operand.IsPlainRegister()) {
12641      if (IsUsingT32()) {
12642        // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
12643        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12644          EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3));
12645          AdvanceIT();
12646          return;
12647        }
12648      }
12649    }
12650    Shift shift = operand.GetShift();
12651    uint32_t amount = operand.GetShiftAmount();
12652    if (IsUsingT32()) {
12653      // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12654      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12655          (amount <= 24) && ((amount % 8) == 0)) {
12656        uint32_t amount_ = amount / 8;
12657        EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12658                   (amount_ << 4));
12659        AdvanceIT();
12660        return;
12661      }
12662    } else {
12663      // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12664      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12665          ((amount % 8) == 0) && cond.IsNotNever()) {
12666        uint32_t amount_ = amount / 8;
12667        EmitA32(0x06ff0070U | (cond.GetCondition() << 28) |
12668                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12669        return;
12670      }
12671    }
12672  }
12673  Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand);
12674}
12675
12676void Assembler::vaba(
12677    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12678  VIXL_ASSERT(AllowAssembler());
12679  CheckIT(cond);
12680  Dt_U_size_1 encoded_dt(dt);
12681  if (IsUsingT32()) {
12682    // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1
12683    if (encoded_dt.IsValid()) {
12684      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12685        EmitT32_32(0xef000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12686                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12687                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12688        AdvanceIT();
12689        return;
12690      }
12691    }
12692  } else {
12693    // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1
12694    if (encoded_dt.IsValid()) {
12695      if (cond.Is(al)) {
12696        EmitA32(0xf2000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12697                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12698                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12699        return;
12700      }
12701    }
12702  }
12703  Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
12704}
12705
12706void Assembler::vaba(
12707    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12708  VIXL_ASSERT(AllowAssembler());
12709  CheckIT(cond);
12710  Dt_U_size_1 encoded_dt(dt);
12711  if (IsUsingT32()) {
12712    // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1
12713    if (encoded_dt.IsValid()) {
12714      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12715        EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12716                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12717                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12718        AdvanceIT();
12719        return;
12720      }
12721    }
12722  } else {
12723    // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1
12724    if (encoded_dt.IsValid()) {
12725      if (cond.Is(al)) {
12726        EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12727                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12728                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12729        return;
12730      }
12731    }
12732  }
12733  Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
12734}
12735
12736void Assembler::vabal(
12737    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
12738  VIXL_ASSERT(AllowAssembler());
12739  CheckIT(cond);
12740  Dt_U_size_1 encoded_dt(dt);
12741  if (IsUsingT32()) {
12742    // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
12743    if (encoded_dt.IsValid()) {
12744      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12745        EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12746                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12747                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12748        AdvanceIT();
12749        return;
12750      }
12751    }
12752  } else {
12753    // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
12754    if (encoded_dt.IsValid()) {
12755      if (cond.Is(al)) {
12756        EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12757                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12758                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12759        return;
12760      }
12761    }
12762  }
12763  Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm);
12764}
12765
12766void Assembler::vabd(
12767    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12768  VIXL_ASSERT(AllowAssembler());
12769  CheckIT(cond);
12770  Dt_U_size_1 encoded_dt(dt);
12771  if (IsUsingT32()) {
12772    // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
12773    if (dt.Is(F32)) {
12774      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12775        EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12776                   rm.Encode(5, 0));
12777        AdvanceIT();
12778        return;
12779      }
12780    }
12781    // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
12782    if (encoded_dt.IsValid()) {
12783      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12784        EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12785                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12786                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12787        AdvanceIT();
12788        return;
12789      }
12790    }
12791  } else {
12792    // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
12793    if (dt.Is(F32)) {
12794      if (cond.Is(al)) {
12795        EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12796                rm.Encode(5, 0));
12797        return;
12798      }
12799    }
12800    // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
12801    if (encoded_dt.IsValid()) {
12802      if (cond.Is(al)) {
12803        EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12804                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12805                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12806        return;
12807      }
12808    }
12809  }
12810  Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
12811}
12812
12813void Assembler::vabd(
12814    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12815  VIXL_ASSERT(AllowAssembler());
12816  CheckIT(cond);
12817  Dt_U_size_1 encoded_dt(dt);
12818  if (IsUsingT32()) {
12819    // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
12820    if (dt.Is(F32)) {
12821      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12822        EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12823                   rm.Encode(5, 0));
12824        AdvanceIT();
12825        return;
12826      }
12827    }
12828    // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
12829    if (encoded_dt.IsValid()) {
12830      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12831        EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12832                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12833                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12834        AdvanceIT();
12835        return;
12836      }
12837    }
12838  } else {
12839    // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
12840    if (dt.Is(F32)) {
12841      if (cond.Is(al)) {
12842        EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12843                rm.Encode(5, 0));
12844        return;
12845      }
12846    }
12847    // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
12848    if (encoded_dt.IsValid()) {
12849      if (cond.Is(al)) {
12850        EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12851                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12852                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12853        return;
12854      }
12855    }
12856  }
12857  Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
12858}
12859
12860void Assembler::vabdl(
12861    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
12862  VIXL_ASSERT(AllowAssembler());
12863  CheckIT(cond);
12864  Dt_U_size_1 encoded_dt(dt);
12865  if (IsUsingT32()) {
12866    // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
12867    if (encoded_dt.IsValid()) {
12868      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12869        EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12870                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12871                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12872        AdvanceIT();
12873        return;
12874      }
12875    }
12876  } else {
12877    // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
12878    if (encoded_dt.IsValid()) {
12879      if (cond.Is(al)) {
12880        EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12881                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12882                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12883        return;
12884      }
12885    }
12886  }
12887  Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm);
12888}
12889
12890void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
12891  VIXL_ASSERT(AllowAssembler());
12892  CheckIT(cond);
12893  Dt_F_size_1 encoded_dt(dt);
12894  if (IsUsingT32()) {
12895    // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
12896    if (encoded_dt.IsValid()) {
12897      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12898        EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12899                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12900                   rd.Encode(22, 12) | rm.Encode(5, 0));
12901        AdvanceIT();
12902        return;
12903      }
12904    }
12905    // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
12906    if (dt.Is(F64)) {
12907      EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
12908      AdvanceIT();
12909      return;
12910    }
12911  } else {
12912    // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
12913    if (encoded_dt.IsValid()) {
12914      if (cond.Is(al)) {
12915        EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12916                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12917                rd.Encode(22, 12) | rm.Encode(5, 0));
12918        return;
12919      }
12920    }
12921    // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
12922    if (dt.Is(F64) && cond.IsNotNever()) {
12923      EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
12924              rm.Encode(5, 0));
12925      return;
12926    }
12927  }
12928  Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
12929}
12930
12931void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
12932  VIXL_ASSERT(AllowAssembler());
12933  CheckIT(cond);
12934  Dt_F_size_1 encoded_dt(dt);
12935  if (IsUsingT32()) {
12936    // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
12937    if (encoded_dt.IsValid()) {
12938      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12939        EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12940                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12941                   rd.Encode(22, 12) | rm.Encode(5, 0));
12942        AdvanceIT();
12943        return;
12944      }
12945    }
12946  } else {
12947    // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
12948    if (encoded_dt.IsValid()) {
12949      if (cond.Is(al)) {
12950        EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12951                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12952                rd.Encode(22, 12) | rm.Encode(5, 0));
12953        return;
12954      }
12955    }
12956  }
12957  Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
12958}
12959
12960void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) {
12961  VIXL_ASSERT(AllowAssembler());
12962  CheckIT(cond);
12963  if (IsUsingT32()) {
12964    // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
12965    if (dt.Is(F32)) {
12966      EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
12967      AdvanceIT();
12968      return;
12969    }
12970  } else {
12971    // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
12972    if (dt.Is(F32) && cond.IsNotNever()) {
12973      EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
12974              rm.Encode(5, 0));
12975      return;
12976    }
12977  }
12978  Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
12979}
12980
12981void Assembler::vacge(
12982    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12983  VIXL_ASSERT(AllowAssembler());
12984  CheckIT(cond);
12985  if (IsUsingT32()) {
12986    // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
12987    if (dt.Is(F32)) {
12988      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12989        EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12990                   rm.Encode(5, 0));
12991        AdvanceIT();
12992        return;
12993      }
12994    }
12995  } else {
12996    // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
12997    if (dt.Is(F32)) {
12998      if (cond.Is(al)) {
12999        EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13000                rm.Encode(5, 0));
13001        return;
13002      }
13003    }
13004  }
13005  Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
13006}
13007
13008void Assembler::vacge(
13009    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13010  VIXL_ASSERT(AllowAssembler());
13011  CheckIT(cond);
13012  if (IsUsingT32()) {
13013    // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13014    if (dt.Is(F32)) {
13015      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13016        EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13017                   rm.Encode(5, 0));
13018        AdvanceIT();
13019        return;
13020      }
13021    }
13022  } else {
13023    // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13024    if (dt.Is(F32)) {
13025      if (cond.Is(al)) {
13026        EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13027                rm.Encode(5, 0));
13028        return;
13029      }
13030    }
13031  }
13032  Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
13033}
13034
13035void Assembler::vacgt(
13036    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13037  VIXL_ASSERT(AllowAssembler());
13038  CheckIT(cond);
13039  if (IsUsingT32()) {
13040    // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13041    if (dt.Is(F32)) {
13042      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13043        EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13044                   rm.Encode(5, 0));
13045        AdvanceIT();
13046        return;
13047      }
13048    }
13049  } else {
13050    // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13051    if (dt.Is(F32)) {
13052      if (cond.Is(al)) {
13053        EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13054                rm.Encode(5, 0));
13055        return;
13056      }
13057    }
13058  }
13059  Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
13060}
13061
13062void Assembler::vacgt(
13063    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13064  VIXL_ASSERT(AllowAssembler());
13065  CheckIT(cond);
13066  if (IsUsingT32()) {
13067    // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13068    if (dt.Is(F32)) {
13069      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13070        EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13071                   rm.Encode(5, 0));
13072        AdvanceIT();
13073        return;
13074      }
13075    }
13076  } else {
13077    // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13078    if (dt.Is(F32)) {
13079      if (cond.Is(al)) {
13080        EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13081                rm.Encode(5, 0));
13082        return;
13083      }
13084    }
13085  }
13086  Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
13087}
13088
13089void Assembler::vacle(
13090    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13091  VIXL_ASSERT(AllowAssembler());
13092  CheckIT(cond);
13093  if (IsUsingT32()) {
13094    // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13095    if (dt.Is(F32)) {
13096      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13097        EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13098                   rm.Encode(5, 0));
13099        AdvanceIT();
13100        return;
13101      }
13102    }
13103  } else {
13104    // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13105    if (dt.Is(F32)) {
13106      if (cond.Is(al)) {
13107        EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13108                rm.Encode(5, 0));
13109        return;
13110      }
13111    }
13112  }
13113  Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
13114}
13115
13116void Assembler::vacle(
13117    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13118  VIXL_ASSERT(AllowAssembler());
13119  CheckIT(cond);
13120  if (IsUsingT32()) {
13121    // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13122    if (dt.Is(F32)) {
13123      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13124        EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13125                   rm.Encode(5, 0));
13126        AdvanceIT();
13127        return;
13128      }
13129    }
13130  } else {
13131    // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13132    if (dt.Is(F32)) {
13133      if (cond.Is(al)) {
13134        EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13135                rm.Encode(5, 0));
13136        return;
13137      }
13138    }
13139  }
13140  Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
13141}
13142
13143void Assembler::vaclt(
13144    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13145  VIXL_ASSERT(AllowAssembler());
13146  CheckIT(cond);
13147  if (IsUsingT32()) {
13148    // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13149    if (dt.Is(F32)) {
13150      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13151        EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13152                   rm.Encode(5, 0));
13153        AdvanceIT();
13154        return;
13155      }
13156    }
13157  } else {
13158    // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13159    if (dt.Is(F32)) {
13160      if (cond.Is(al)) {
13161        EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13162                rm.Encode(5, 0));
13163        return;
13164      }
13165    }
13166  }
13167  Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
13168}
13169
13170void Assembler::vaclt(
13171    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13172  VIXL_ASSERT(AllowAssembler());
13173  CheckIT(cond);
13174  if (IsUsingT32()) {
13175    // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13176    if (dt.Is(F32)) {
13177      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13178        EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13179                   rm.Encode(5, 0));
13180        AdvanceIT();
13181        return;
13182      }
13183    }
13184  } else {
13185    // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13186    if (dt.Is(F32)) {
13187      if (cond.Is(al)) {
13188        EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13189                rm.Encode(5, 0));
13190        return;
13191      }
13192    }
13193  }
13194  Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
13195}
13196
13197void Assembler::vadd(
13198    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13199  VIXL_ASSERT(AllowAssembler());
13200  CheckIT(cond);
13201  Dt_size_2 encoded_dt(dt);
13202  if (IsUsingT32()) {
13203    // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13204    if (dt.Is(F32)) {
13205      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13206        EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13207                   rm.Encode(5, 0));
13208        AdvanceIT();
13209        return;
13210      }
13211    }
13212    // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
13213    if (dt.Is(F64)) {
13214      EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13215                 rm.Encode(5, 0));
13216      AdvanceIT();
13217      return;
13218    }
13219    // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
13220    if (encoded_dt.IsValid()) {
13221      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13222        EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) |
13223                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13224        AdvanceIT();
13225        return;
13226      }
13227    }
13228  } else {
13229    // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13230    if (dt.Is(F32)) {
13231      if (cond.Is(al)) {
13232        EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13233                rm.Encode(5, 0));
13234        return;
13235      }
13236    }
13237    // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
13238    if (dt.Is(F64) && cond.IsNotNever()) {
13239      EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
13240              rn.Encode(7, 16) | rm.Encode(5, 0));
13241      return;
13242    }
13243    // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
13244    if (encoded_dt.IsValid()) {
13245      if (cond.Is(al)) {
13246        EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) |
13247                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13248        return;
13249      }
13250    }
13251  }
13252  Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13253}
13254
13255void Assembler::vadd(
13256    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13257  VIXL_ASSERT(AllowAssembler());
13258  CheckIT(cond);
13259  Dt_size_2 encoded_dt(dt);
13260  if (IsUsingT32()) {
13261    // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13262    if (dt.Is(F32)) {
13263      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13264        EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13265                   rm.Encode(5, 0));
13266        AdvanceIT();
13267        return;
13268      }
13269    }
13270    // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
13271    if (encoded_dt.IsValid()) {
13272      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13273        EmitT32_32(0xef000840U | (encoded_dt.GetEncodingValue() << 20) |
13274                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13275        AdvanceIT();
13276        return;
13277      }
13278    }
13279  } else {
13280    // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13281    if (dt.Is(F32)) {
13282      if (cond.Is(al)) {
13283        EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13284                rm.Encode(5, 0));
13285        return;
13286      }
13287    }
13288    // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
13289    if (encoded_dt.IsValid()) {
13290      if (cond.Is(al)) {
13291        EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) |
13292                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13293        return;
13294      }
13295    }
13296  }
13297  Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13298}
13299
13300void Assembler::vadd(
13301    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
13302  VIXL_ASSERT(AllowAssembler());
13303  CheckIT(cond);
13304  if (IsUsingT32()) {
13305    // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
13306    if (dt.Is(F32)) {
13307      EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13308                 rm.Encode(5, 0));
13309      AdvanceIT();
13310      return;
13311    }
13312  } else {
13313    // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
13314    if (dt.Is(F32) && cond.IsNotNever()) {
13315      EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
13316              rn.Encode(7, 16) | rm.Encode(5, 0));
13317      return;
13318    }
13319  }
13320  Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13321}
13322
13323void Assembler::vaddhn(
13324    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
13325  VIXL_ASSERT(AllowAssembler());
13326  CheckIT(cond);
13327  Dt_size_3 encoded_dt(dt);
13328  if (IsUsingT32()) {
13329    // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
13330    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
13331      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13332        EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) |
13333                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13334        AdvanceIT();
13335        return;
13336      }
13337    }
13338  } else {
13339    // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
13340    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
13341      if (cond.Is(al)) {
13342        EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) |
13343                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13344        return;
13345      }
13346    }
13347  }
13348  Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm);
13349}
13350
13351void Assembler::vaddl(
13352    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
13353  VIXL_ASSERT(AllowAssembler());
13354  CheckIT(cond);
13355  Dt_U_size_1 encoded_dt(dt);
13356  if (IsUsingT32()) {
13357    // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
13358    if (encoded_dt.IsValid()) {
13359      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13360        EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13361                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13362                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13363        AdvanceIT();
13364        return;
13365      }
13366    }
13367  } else {
13368    // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
13369    if (encoded_dt.IsValid()) {
13370      if (cond.Is(al)) {
13371        EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13372                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13373                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13374        return;
13375      }
13376    }
13377  }
13378  Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm);
13379}
13380
13381void Assembler::vaddw(
13382    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
13383  VIXL_ASSERT(AllowAssembler());
13384  CheckIT(cond);
13385  Dt_U_size_1 encoded_dt(dt);
13386  if (IsUsingT32()) {
13387    // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
13388    if (encoded_dt.IsValid()) {
13389      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13390        EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13391                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13392                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13393        AdvanceIT();
13394        return;
13395      }
13396    }
13397  } else {
13398    // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
13399    if (encoded_dt.IsValid()) {
13400      if (cond.Is(al)) {
13401        EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13402                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13403                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13404        return;
13405      }
13406    }
13407  }
13408  Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm);
13409}
13410
13411void Assembler::vand(Condition cond,
13412                     DataType dt,
13413                     DRegister rd,
13414                     DRegister rn,
13415                     const DOperand& operand) {
13416  VIXL_ASSERT(AllowAssembler());
13417  CheckIT(cond);
13418  if (operand.IsImmediate()) {
13419    ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
13420    if (IsUsingT32()) {
13421      // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
13422      if (encoded_dt.IsValid() && rd.Is(rn)) {
13423        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13424          EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
13425                     rd.Encode(22, 12) |
13426                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13427                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13428                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13429          AdvanceIT();
13430          return;
13431        }
13432      }
13433    } else {
13434      // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
13435      if (encoded_dt.IsValid() && rd.Is(rn)) {
13436        if (cond.Is(al)) {
13437          EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
13438                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13439                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13440                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13441          return;
13442        }
13443      }
13444    }
13445  }
13446  if (operand.IsRegister()) {
13447    DRegister rm = operand.GetRegister();
13448    USE(dt);
13449    if (IsUsingT32()) {
13450      // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13451      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13452        EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13453                   rm.Encode(5, 0));
13454        AdvanceIT();
13455        return;
13456      }
13457    } else {
13458      // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13459      if (cond.Is(al)) {
13460        EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13461                rm.Encode(5, 0));
13462        return;
13463      }
13464    }
13465  }
13466  Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
13467}
13468
13469void Assembler::vand(Condition cond,
13470                     DataType dt,
13471                     QRegister rd,
13472                     QRegister rn,
13473                     const QOperand& operand) {
13474  VIXL_ASSERT(AllowAssembler());
13475  CheckIT(cond);
13476  if (operand.IsImmediate()) {
13477    ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
13478    if (IsUsingT32()) {
13479      // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
13480      if (encoded_dt.IsValid() && rd.Is(rn)) {
13481        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13482          EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
13483                     rd.Encode(22, 12) |
13484                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13485                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13486                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13487          AdvanceIT();
13488          return;
13489        }
13490      }
13491    } else {
13492      // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
13493      if (encoded_dt.IsValid() && rd.Is(rn)) {
13494        if (cond.Is(al)) {
13495          EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
13496                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13497                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13498                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13499          return;
13500        }
13501      }
13502    }
13503  }
13504  if (operand.IsRegister()) {
13505    QRegister rm = operand.GetRegister();
13506    USE(dt);
13507    if (IsUsingT32()) {
13508      // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13509      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13510        EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13511                   rm.Encode(5, 0));
13512        AdvanceIT();
13513        return;
13514      }
13515    } else {
13516      // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13517      if (cond.Is(al)) {
13518        EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13519                rm.Encode(5, 0));
13520        return;
13521      }
13522    }
13523  }
13524  Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
13525}
13526
13527void Assembler::vbic(Condition cond,
13528                     DataType dt,
13529                     DRegister rd,
13530                     DRegister rn,
13531                     const DOperand& operand) {
13532  VIXL_ASSERT(AllowAssembler());
13533  CheckIT(cond);
13534  if (operand.IsImmediate()) {
13535    ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
13536    if (IsUsingT32()) {
13537      // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
13538      if (encoded_dt.IsValid() && rd.Is(rn)) {
13539        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13540          EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
13541                     rd.Encode(22, 12) |
13542                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13543                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13544                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13545          AdvanceIT();
13546          return;
13547        }
13548      }
13549    } else {
13550      // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
13551      if (encoded_dt.IsValid() && rd.Is(rn)) {
13552        if (cond.Is(al)) {
13553          EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
13554                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13555                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13556                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13557          return;
13558        }
13559      }
13560    }
13561  }
13562  if (operand.IsRegister()) {
13563    DRegister rm = operand.GetRegister();
13564    USE(dt);
13565    if (IsUsingT32()) {
13566      // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13567      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13568        EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13569                   rm.Encode(5, 0));
13570        AdvanceIT();
13571        return;
13572      }
13573    } else {
13574      // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13575      if (cond.Is(al)) {
13576        EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13577                rm.Encode(5, 0));
13578        return;
13579      }
13580    }
13581  }
13582  Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
13583}
13584
13585void Assembler::vbic(Condition cond,
13586                     DataType dt,
13587                     QRegister rd,
13588                     QRegister rn,
13589                     const QOperand& operand) {
13590  VIXL_ASSERT(AllowAssembler());
13591  CheckIT(cond);
13592  if (operand.IsImmediate()) {
13593    ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
13594    if (IsUsingT32()) {
13595      // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
13596      if (encoded_dt.IsValid() && rd.Is(rn)) {
13597        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13598          EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
13599                     rd.Encode(22, 12) |
13600                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13601                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13602                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13603          AdvanceIT();
13604          return;
13605        }
13606      }
13607    } else {
13608      // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
13609      if (encoded_dt.IsValid() && rd.Is(rn)) {
13610        if (cond.Is(al)) {
13611          EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
13612                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13613                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13614                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13615          return;
13616        }
13617      }
13618    }
13619  }
13620  if (operand.IsRegister()) {
13621    QRegister rm = operand.GetRegister();
13622    USE(dt);
13623    if (IsUsingT32()) {
13624      // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13625      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13626        EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13627                   rm.Encode(5, 0));
13628        AdvanceIT();
13629        return;
13630      }
13631    } else {
13632      // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13633      if (cond.Is(al)) {
13634        EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13635                rm.Encode(5, 0));
13636        return;
13637      }
13638    }
13639  }
13640  Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
13641}
13642
13643void Assembler::vbif(
13644    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13645  VIXL_ASSERT(AllowAssembler());
13646  CheckIT(cond);
13647  USE(dt);
13648  if (IsUsingT32()) {
13649    // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13650    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13651      EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13652                 rm.Encode(5, 0));
13653      AdvanceIT();
13654      return;
13655    }
13656  } else {
13657    // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13658    if (cond.Is(al)) {
13659      EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13660              rm.Encode(5, 0));
13661      return;
13662    }
13663  }
13664  Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
13665}
13666
13667void Assembler::vbif(
13668    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13669  VIXL_ASSERT(AllowAssembler());
13670  CheckIT(cond);
13671  USE(dt);
13672  if (IsUsingT32()) {
13673    // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13674    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13675      EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13676                 rm.Encode(5, 0));
13677      AdvanceIT();
13678      return;
13679    }
13680  } else {
13681    // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13682    if (cond.Is(al)) {
13683      EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13684              rm.Encode(5, 0));
13685      return;
13686    }
13687  }
13688  Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
13689}
13690
13691void Assembler::vbit(
13692    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13693  VIXL_ASSERT(AllowAssembler());
13694  CheckIT(cond);
13695  USE(dt);
13696  if (IsUsingT32()) {
13697    // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13698    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13699      EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13700                 rm.Encode(5, 0));
13701      AdvanceIT();
13702      return;
13703    }
13704  } else {
13705    // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13706    if (cond.Is(al)) {
13707      EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13708              rm.Encode(5, 0));
13709      return;
13710    }
13711  }
13712  Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
13713}
13714
13715void Assembler::vbit(
13716    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13717  VIXL_ASSERT(AllowAssembler());
13718  CheckIT(cond);
13719  USE(dt);
13720  if (IsUsingT32()) {
13721    // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13722    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13723      EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13724                 rm.Encode(5, 0));
13725      AdvanceIT();
13726      return;
13727    }
13728  } else {
13729    // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13730    if (cond.Is(al)) {
13731      EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13732              rm.Encode(5, 0));
13733      return;
13734    }
13735  }
13736  Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
13737}
13738
13739void Assembler::vbsl(
13740    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13741  VIXL_ASSERT(AllowAssembler());
13742  CheckIT(cond);
13743  USE(dt);
13744  if (IsUsingT32()) {
13745    // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13746    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13747      EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13748                 rm.Encode(5, 0));
13749      AdvanceIT();
13750      return;
13751    }
13752  } else {
13753    // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13754    if (cond.Is(al)) {
13755      EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13756              rm.Encode(5, 0));
13757      return;
13758    }
13759  }
13760  Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
13761}
13762
13763void Assembler::vbsl(
13764    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13765  VIXL_ASSERT(AllowAssembler());
13766  CheckIT(cond);
13767  USE(dt);
13768  if (IsUsingT32()) {
13769    // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13770    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13771      EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13772                 rm.Encode(5, 0));
13773      AdvanceIT();
13774      return;
13775    }
13776  } else {
13777    // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13778    if (cond.Is(al)) {
13779      EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13780              rm.Encode(5, 0));
13781      return;
13782    }
13783  }
13784  Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
13785}
13786
13787void Assembler::vceq(Condition cond,
13788                     DataType dt,
13789                     DRegister rd,
13790                     DRegister rm,
13791                     const DOperand& operand) {
13792  VIXL_ASSERT(AllowAssembler());
13793  CheckIT(cond);
13794  if (operand.IsImmediate()) {
13795    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13796      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13797      Dt_F_size_2 encoded_dt(dt);
13798      if (IsUsingT32()) {
13799        // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
13800        if (encoded_dt.IsValid() && (imm == 0)) {
13801          if (cond.Is(al) || AllowStronglyDiscouraged()) {
13802            EmitT32_32(0xffb10100U |
13803                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13804                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13805                       rd.Encode(22, 12) | rm.Encode(5, 0));
13806            AdvanceIT();
13807            return;
13808          }
13809        }
13810      } else {
13811        // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
13812        if (encoded_dt.IsValid() && (imm == 0)) {
13813          if (cond.Is(al)) {
13814            EmitA32(0xf3b10100U |
13815                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13816                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13817                    rd.Encode(22, 12) | rm.Encode(5, 0));
13818            return;
13819          }
13820        }
13821      }
13822    }
13823  }
13824  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
13825}
13826
13827void Assembler::vceq(Condition cond,
13828                     DataType dt,
13829                     QRegister rd,
13830                     QRegister rm,
13831                     const QOperand& operand) {
13832  VIXL_ASSERT(AllowAssembler());
13833  CheckIT(cond);
13834  if (operand.IsImmediate()) {
13835    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13836      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13837      Dt_F_size_2 encoded_dt(dt);
13838      if (IsUsingT32()) {
13839        // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
13840        if (encoded_dt.IsValid() && (imm == 0)) {
13841          if (cond.Is(al) || AllowStronglyDiscouraged()) {
13842            EmitT32_32(0xffb10140U |
13843                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13844                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13845                       rd.Encode(22, 12) | rm.Encode(5, 0));
13846            AdvanceIT();
13847            return;
13848          }
13849        }
13850      } else {
13851        // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
13852        if (encoded_dt.IsValid() && (imm == 0)) {
13853          if (cond.Is(al)) {
13854            EmitA32(0xf3b10140U |
13855                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13856                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13857                    rd.Encode(22, 12) | rm.Encode(5, 0));
13858            return;
13859          }
13860        }
13861      }
13862    }
13863  }
13864  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
13865}
13866
13867void Assembler::vceq(
13868    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13869  VIXL_ASSERT(AllowAssembler());
13870  CheckIT(cond);
13871  Dt_size_4 encoded_dt(dt);
13872  Dt_sz_1 encoded_dt_2(dt);
13873  if (IsUsingT32()) {
13874    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
13875    if (encoded_dt.IsValid()) {
13876      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13877        EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) |
13878                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13879        AdvanceIT();
13880        return;
13881      }
13882    }
13883    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2
13884    if (encoded_dt_2.IsValid()) {
13885      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13886        EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
13887                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13888        AdvanceIT();
13889        return;
13890      }
13891    }
13892  } else {
13893    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
13894    if (encoded_dt.IsValid()) {
13895      if (cond.Is(al)) {
13896        EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) |
13897                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13898        return;
13899      }
13900    }
13901    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2
13902    if (encoded_dt_2.IsValid()) {
13903      if (cond.Is(al)) {
13904        EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
13905                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13906        return;
13907      }
13908    }
13909  }
13910  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
13911}
13912
13913void Assembler::vceq(
13914    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13915  VIXL_ASSERT(AllowAssembler());
13916  CheckIT(cond);
13917  Dt_size_4 encoded_dt(dt);
13918  Dt_sz_1 encoded_dt_2(dt);
13919  if (IsUsingT32()) {
13920    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
13921    if (encoded_dt.IsValid()) {
13922      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13923        EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) |
13924                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13925        AdvanceIT();
13926        return;
13927      }
13928    }
13929    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2
13930    if (encoded_dt_2.IsValid()) {
13931      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13932        EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
13933                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13934        AdvanceIT();
13935        return;
13936      }
13937    }
13938  } else {
13939    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
13940    if (encoded_dt.IsValid()) {
13941      if (cond.Is(al)) {
13942        EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) |
13943                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13944        return;
13945      }
13946    }
13947    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2
13948    if (encoded_dt_2.IsValid()) {
13949      if (cond.Is(al)) {
13950        EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
13951                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13952        return;
13953      }
13954    }
13955  }
13956  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
13957}
13958
13959void Assembler::vcge(Condition cond,
13960                     DataType dt,
13961                     DRegister rd,
13962                     DRegister rm,
13963                     const DOperand& operand) {
13964  VIXL_ASSERT(AllowAssembler());
13965  CheckIT(cond);
13966  if (operand.IsImmediate()) {
13967    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13968      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13969      Dt_F_size_1 encoded_dt(dt);
13970      if (IsUsingT32()) {
13971        // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
13972        if (encoded_dt.IsValid() && (imm == 0)) {
13973          if (cond.Is(al) || AllowStronglyDiscouraged()) {
13974            EmitT32_32(0xffb10080U |
13975                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13976                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13977                       rd.Encode(22, 12) | rm.Encode(5, 0));
13978            AdvanceIT();
13979            return;
13980          }
13981        }
13982      } else {
13983        // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
13984        if (encoded_dt.IsValid() && (imm == 0)) {
13985          if (cond.Is(al)) {
13986            EmitA32(0xf3b10080U |
13987                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13988                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13989                    rd.Encode(22, 12) | rm.Encode(5, 0));
13990            return;
13991          }
13992        }
13993      }
13994    }
13995  }
13996  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
13997}
13998
13999void Assembler::vcge(Condition cond,
14000                     DataType dt,
14001                     QRegister rd,
14002                     QRegister rm,
14003                     const QOperand& operand) {
14004  VIXL_ASSERT(AllowAssembler());
14005  CheckIT(cond);
14006  if (operand.IsImmediate()) {
14007    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14008      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14009      Dt_F_size_1 encoded_dt(dt);
14010      if (IsUsingT32()) {
14011        // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14012        if (encoded_dt.IsValid() && (imm == 0)) {
14013          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14014            EmitT32_32(0xffb100c0U |
14015                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14016                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14017                       rd.Encode(22, 12) | rm.Encode(5, 0));
14018            AdvanceIT();
14019            return;
14020          }
14021        }
14022      } else {
14023        // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14024        if (encoded_dt.IsValid() && (imm == 0)) {
14025          if (cond.Is(al)) {
14026            EmitA32(0xf3b100c0U |
14027                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14028                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14029                    rd.Encode(22, 12) | rm.Encode(5, 0));
14030            return;
14031          }
14032        }
14033      }
14034    }
14035  }
14036  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
14037}
14038
14039void Assembler::vcge(
14040    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14041  VIXL_ASSERT(AllowAssembler());
14042  CheckIT(cond);
14043  Dt_U_size_1 encoded_dt(dt);
14044  if (IsUsingT32()) {
14045    // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14046    if (encoded_dt.IsValid()) {
14047      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14048        EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14049                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14050                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14051        AdvanceIT();
14052        return;
14053      }
14054    }
14055    // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14056    if (dt.Is(F32)) {
14057      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14058        EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14059                   rm.Encode(5, 0));
14060        AdvanceIT();
14061        return;
14062      }
14063    }
14064  } else {
14065    // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14066    if (encoded_dt.IsValid()) {
14067      if (cond.Is(al)) {
14068        EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14069                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14070                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14071        return;
14072      }
14073    }
14074    // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14075    if (dt.Is(F32)) {
14076      if (cond.Is(al)) {
14077        EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14078                rm.Encode(5, 0));
14079        return;
14080      }
14081    }
14082  }
14083  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
14084}
14085
14086void Assembler::vcge(
14087    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14088  VIXL_ASSERT(AllowAssembler());
14089  CheckIT(cond);
14090  Dt_U_size_1 encoded_dt(dt);
14091  if (IsUsingT32()) {
14092    // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14093    if (encoded_dt.IsValid()) {
14094      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14095        EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14096                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14097                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14098        AdvanceIT();
14099        return;
14100      }
14101    }
14102    // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14103    if (dt.Is(F32)) {
14104      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14105        EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14106                   rm.Encode(5, 0));
14107        AdvanceIT();
14108        return;
14109      }
14110    }
14111  } else {
14112    // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14113    if (encoded_dt.IsValid()) {
14114      if (cond.Is(al)) {
14115        EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14116                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14117                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14118        return;
14119      }
14120    }
14121    // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14122    if (dt.Is(F32)) {
14123      if (cond.Is(al)) {
14124        EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14125                rm.Encode(5, 0));
14126        return;
14127      }
14128    }
14129  }
14130  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
14131}
14132
14133void Assembler::vcgt(Condition cond,
14134                     DataType dt,
14135                     DRegister rd,
14136                     DRegister rm,
14137                     const DOperand& operand) {
14138  VIXL_ASSERT(AllowAssembler());
14139  CheckIT(cond);
14140  if (operand.IsImmediate()) {
14141    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14142      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14143      Dt_F_size_1 encoded_dt(dt);
14144      if (IsUsingT32()) {
14145        // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14146        if (encoded_dt.IsValid() && (imm == 0)) {
14147          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14148            EmitT32_32(0xffb10000U |
14149                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14150                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14151                       rd.Encode(22, 12) | rm.Encode(5, 0));
14152            AdvanceIT();
14153            return;
14154          }
14155        }
14156      } else {
14157        // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14158        if (encoded_dt.IsValid() && (imm == 0)) {
14159          if (cond.Is(al)) {
14160            EmitA32(0xf3b10000U |
14161                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14162                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14163                    rd.Encode(22, 12) | rm.Encode(5, 0));
14164            return;
14165          }
14166        }
14167      }
14168    }
14169  }
14170  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
14171}
14172
14173void Assembler::vcgt(Condition cond,
14174                     DataType dt,
14175                     QRegister rd,
14176                     QRegister rm,
14177                     const QOperand& operand) {
14178  VIXL_ASSERT(AllowAssembler());
14179  CheckIT(cond);
14180  if (operand.IsImmediate()) {
14181    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14182      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14183      Dt_F_size_1 encoded_dt(dt);
14184      if (IsUsingT32()) {
14185        // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14186        if (encoded_dt.IsValid() && (imm == 0)) {
14187          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14188            EmitT32_32(0xffb10040U |
14189                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14190                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14191                       rd.Encode(22, 12) | rm.Encode(5, 0));
14192            AdvanceIT();
14193            return;
14194          }
14195        }
14196      } else {
14197        // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14198        if (encoded_dt.IsValid() && (imm == 0)) {
14199          if (cond.Is(al)) {
14200            EmitA32(0xf3b10040U |
14201                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14202                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14203                    rd.Encode(22, 12) | rm.Encode(5, 0));
14204            return;
14205          }
14206        }
14207      }
14208    }
14209  }
14210  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
14211}
14212
14213void Assembler::vcgt(
14214    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14215  VIXL_ASSERT(AllowAssembler());
14216  CheckIT(cond);
14217  Dt_U_size_1 encoded_dt(dt);
14218  if (IsUsingT32()) {
14219    // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14220    if (encoded_dt.IsValid()) {
14221      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14222        EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14223                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14224                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14225        AdvanceIT();
14226        return;
14227      }
14228    }
14229    // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14230    if (dt.Is(F32)) {
14231      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14232        EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14233                   rm.Encode(5, 0));
14234        AdvanceIT();
14235        return;
14236      }
14237    }
14238  } else {
14239    // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14240    if (encoded_dt.IsValid()) {
14241      if (cond.Is(al)) {
14242        EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14243                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14244                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14245        return;
14246      }
14247    }
14248    // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14249    if (dt.Is(F32)) {
14250      if (cond.Is(al)) {
14251        EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14252                rm.Encode(5, 0));
14253        return;
14254      }
14255    }
14256  }
14257  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
14258}
14259
14260void Assembler::vcgt(
14261    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14262  VIXL_ASSERT(AllowAssembler());
14263  CheckIT(cond);
14264  Dt_U_size_1 encoded_dt(dt);
14265  if (IsUsingT32()) {
14266    // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14267    if (encoded_dt.IsValid()) {
14268      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14269        EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14270                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14271                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14272        AdvanceIT();
14273        return;
14274      }
14275    }
14276    // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14277    if (dt.Is(F32)) {
14278      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14279        EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14280                   rm.Encode(5, 0));
14281        AdvanceIT();
14282        return;
14283      }
14284    }
14285  } else {
14286    // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14287    if (encoded_dt.IsValid()) {
14288      if (cond.Is(al)) {
14289        EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14290                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14291                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14292        return;
14293      }
14294    }
14295    // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14296    if (dt.Is(F32)) {
14297      if (cond.Is(al)) {
14298        EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14299                rm.Encode(5, 0));
14300        return;
14301      }
14302    }
14303  }
14304  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
14305}
14306
14307void Assembler::vcle(Condition cond,
14308                     DataType dt,
14309                     DRegister rd,
14310                     DRegister rm,
14311                     const DOperand& operand) {
14312  VIXL_ASSERT(AllowAssembler());
14313  CheckIT(cond);
14314  if (operand.IsImmediate()) {
14315    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14316      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14317      Dt_F_size_1 encoded_dt(dt);
14318      if (IsUsingT32()) {
14319        // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14320        if (encoded_dt.IsValid() && (imm == 0)) {
14321          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14322            EmitT32_32(0xffb10180U |
14323                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14324                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14325                       rd.Encode(22, 12) | rm.Encode(5, 0));
14326            AdvanceIT();
14327            return;
14328          }
14329        }
14330      } else {
14331        // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14332        if (encoded_dt.IsValid() && (imm == 0)) {
14333          if (cond.Is(al)) {
14334            EmitA32(0xf3b10180U |
14335                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14336                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14337                    rd.Encode(22, 12) | rm.Encode(5, 0));
14338            return;
14339          }
14340        }
14341      }
14342    }
14343  }
14344  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
14345}
14346
14347void Assembler::vcle(Condition cond,
14348                     DataType dt,
14349                     QRegister rd,
14350                     QRegister rm,
14351                     const QOperand& operand) {
14352  VIXL_ASSERT(AllowAssembler());
14353  CheckIT(cond);
14354  if (operand.IsImmediate()) {
14355    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14356      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14357      Dt_F_size_1 encoded_dt(dt);
14358      if (IsUsingT32()) {
14359        // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14360        if (encoded_dt.IsValid() && (imm == 0)) {
14361          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14362            EmitT32_32(0xffb101c0U |
14363                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14364                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14365                       rd.Encode(22, 12) | rm.Encode(5, 0));
14366            AdvanceIT();
14367            return;
14368          }
14369        }
14370      } else {
14371        // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14372        if (encoded_dt.IsValid() && (imm == 0)) {
14373          if (cond.Is(al)) {
14374            EmitA32(0xf3b101c0U |
14375                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14376                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14377                    rd.Encode(22, 12) | rm.Encode(5, 0));
14378            return;
14379          }
14380        }
14381      }
14382    }
14383  }
14384  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
14385}
14386
14387void Assembler::vcle(
14388    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14389  VIXL_ASSERT(AllowAssembler());
14390  CheckIT(cond);
14391  Dt_U_size_1 encoded_dt(dt);
14392  if (IsUsingT32()) {
14393    // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14394    if (encoded_dt.IsValid()) {
14395      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14396        EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14397                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14398                   rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14399        AdvanceIT();
14400        return;
14401      }
14402    }
14403    // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14404    if (dt.Is(F32)) {
14405      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14406        EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14407                   rm.Encode(7, 16));
14408        AdvanceIT();
14409        return;
14410      }
14411    }
14412  } else {
14413    // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14414    if (encoded_dt.IsValid()) {
14415      if (cond.Is(al)) {
14416        EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14417                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14418                rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14419        return;
14420      }
14421    }
14422    // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14423    if (dt.Is(F32)) {
14424      if (cond.Is(al)) {
14425        EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14426                rm.Encode(7, 16));
14427        return;
14428      }
14429    }
14430  }
14431  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
14432}
14433
14434void Assembler::vcle(
14435    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14436  VIXL_ASSERT(AllowAssembler());
14437  CheckIT(cond);
14438  Dt_U_size_1 encoded_dt(dt);
14439  if (IsUsingT32()) {
14440    // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14441    if (encoded_dt.IsValid()) {
14442      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14443        EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14444                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14445                   rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14446        AdvanceIT();
14447        return;
14448      }
14449    }
14450    // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14451    if (dt.Is(F32)) {
14452      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14453        EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14454                   rm.Encode(7, 16));
14455        AdvanceIT();
14456        return;
14457      }
14458    }
14459  } else {
14460    // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14461    if (encoded_dt.IsValid()) {
14462      if (cond.Is(al)) {
14463        EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14464                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14465                rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14466        return;
14467      }
14468    }
14469    // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14470    if (dt.Is(F32)) {
14471      if (cond.Is(al)) {
14472        EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14473                rm.Encode(7, 16));
14474        return;
14475      }
14476    }
14477  }
14478  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
14479}
14480
14481void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14482  VIXL_ASSERT(AllowAssembler());
14483  CheckIT(cond);
14484  Dt_size_5 encoded_dt(dt);
14485  if (IsUsingT32()) {
14486    // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
14487    if (encoded_dt.IsValid()) {
14488      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14489        EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) |
14490                   rd.Encode(22, 12) | rm.Encode(5, 0));
14491        AdvanceIT();
14492        return;
14493      }
14494    }
14495  } else {
14496    // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
14497    if (encoded_dt.IsValid()) {
14498      if (cond.Is(al)) {
14499        EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) |
14500                rd.Encode(22, 12) | rm.Encode(5, 0));
14501        return;
14502      }
14503    }
14504  }
14505  Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
14506}
14507
14508void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14509  VIXL_ASSERT(AllowAssembler());
14510  CheckIT(cond);
14511  Dt_size_5 encoded_dt(dt);
14512  if (IsUsingT32()) {
14513    // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
14514    if (encoded_dt.IsValid()) {
14515      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14516        EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) |
14517                   rd.Encode(22, 12) | rm.Encode(5, 0));
14518        AdvanceIT();
14519        return;
14520      }
14521    }
14522  } else {
14523    // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
14524    if (encoded_dt.IsValid()) {
14525      if (cond.Is(al)) {
14526        EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) |
14527                rd.Encode(22, 12) | rm.Encode(5, 0));
14528        return;
14529      }
14530    }
14531  }
14532  Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
14533}
14534
14535void Assembler::vclt(Condition cond,
14536                     DataType dt,
14537                     DRegister rd,
14538                     DRegister rm,
14539                     const DOperand& operand) {
14540  VIXL_ASSERT(AllowAssembler());
14541  CheckIT(cond);
14542  if (operand.IsImmediate()) {
14543    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14544      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14545      Dt_F_size_1 encoded_dt(dt);
14546      if (IsUsingT32()) {
14547        // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14548        if (encoded_dt.IsValid() && (imm == 0)) {
14549          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14550            EmitT32_32(0xffb10200U |
14551                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14552                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14553                       rd.Encode(22, 12) | rm.Encode(5, 0));
14554            AdvanceIT();
14555            return;
14556          }
14557        }
14558      } else {
14559        // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14560        if (encoded_dt.IsValid() && (imm == 0)) {
14561          if (cond.Is(al)) {
14562            EmitA32(0xf3b10200U |
14563                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14564                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14565                    rd.Encode(22, 12) | rm.Encode(5, 0));
14566            return;
14567          }
14568        }
14569      }
14570    }
14571  }
14572  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
14573}
14574
14575void Assembler::vclt(Condition cond,
14576                     DataType dt,
14577                     QRegister rd,
14578                     QRegister rm,
14579                     const QOperand& operand) {
14580  VIXL_ASSERT(AllowAssembler());
14581  CheckIT(cond);
14582  if (operand.IsImmediate()) {
14583    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14584      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14585      Dt_F_size_1 encoded_dt(dt);
14586      if (IsUsingT32()) {
14587        // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14588        if (encoded_dt.IsValid() && (imm == 0)) {
14589          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14590            EmitT32_32(0xffb10240U |
14591                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14592                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14593                       rd.Encode(22, 12) | rm.Encode(5, 0));
14594            AdvanceIT();
14595            return;
14596          }
14597        }
14598      } else {
14599        // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14600        if (encoded_dt.IsValid() && (imm == 0)) {
14601          if (cond.Is(al)) {
14602            EmitA32(0xf3b10240U |
14603                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14604                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14605                    rd.Encode(22, 12) | rm.Encode(5, 0));
14606            return;
14607          }
14608        }
14609      }
14610    }
14611  }
14612  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
14613}
14614
14615void Assembler::vclt(
14616    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14617  VIXL_ASSERT(AllowAssembler());
14618  CheckIT(cond);
14619  Dt_U_size_1 encoded_dt(dt);
14620  if (IsUsingT32()) {
14621    // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14622    if (encoded_dt.IsValid()) {
14623      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14624        EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14625                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14626                   rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14627        AdvanceIT();
14628        return;
14629      }
14630    }
14631    // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14632    if (dt.Is(F32)) {
14633      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14634        EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14635                   rm.Encode(7, 16));
14636        AdvanceIT();
14637        return;
14638      }
14639    }
14640  } else {
14641    // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14642    if (encoded_dt.IsValid()) {
14643      if (cond.Is(al)) {
14644        EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14645                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14646                rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14647        return;
14648      }
14649    }
14650    // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14651    if (dt.Is(F32)) {
14652      if (cond.Is(al)) {
14653        EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14654                rm.Encode(7, 16));
14655        return;
14656      }
14657    }
14658  }
14659  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
14660}
14661
14662void Assembler::vclt(
14663    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14664  VIXL_ASSERT(AllowAssembler());
14665  CheckIT(cond);
14666  Dt_U_size_1 encoded_dt(dt);
14667  if (IsUsingT32()) {
14668    // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14669    if (encoded_dt.IsValid()) {
14670      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14671        EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14672                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14673                   rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14674        AdvanceIT();
14675        return;
14676      }
14677    }
14678    // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14679    if (dt.Is(F32)) {
14680      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14681        EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14682                   rm.Encode(7, 16));
14683        AdvanceIT();
14684        return;
14685      }
14686    }
14687  } else {
14688    // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14689    if (encoded_dt.IsValid()) {
14690      if (cond.Is(al)) {
14691        EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14692                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14693                rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14694        return;
14695      }
14696    }
14697    // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14698    if (dt.Is(F32)) {
14699      if (cond.Is(al)) {
14700        EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14701                rm.Encode(7, 16));
14702        return;
14703      }
14704    }
14705  }
14706  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
14707}
14708
14709void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14710  VIXL_ASSERT(AllowAssembler());
14711  CheckIT(cond);
14712  Dt_size_4 encoded_dt(dt);
14713  if (IsUsingT32()) {
14714    // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
14715    if (encoded_dt.IsValid()) {
14716      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14717        EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) |
14718                   rd.Encode(22, 12) | rm.Encode(5, 0));
14719        AdvanceIT();
14720        return;
14721      }
14722    }
14723  } else {
14724    // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
14725    if (encoded_dt.IsValid()) {
14726      if (cond.Is(al)) {
14727        EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) |
14728                rd.Encode(22, 12) | rm.Encode(5, 0));
14729        return;
14730      }
14731    }
14732  }
14733  Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
14734}
14735
14736void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14737  VIXL_ASSERT(AllowAssembler());
14738  CheckIT(cond);
14739  Dt_size_4 encoded_dt(dt);
14740  if (IsUsingT32()) {
14741    // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
14742    if (encoded_dt.IsValid()) {
14743      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14744        EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) |
14745                   rd.Encode(22, 12) | rm.Encode(5, 0));
14746        AdvanceIT();
14747        return;
14748      }
14749    }
14750  } else {
14751    // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
14752    if (encoded_dt.IsValid()) {
14753      if (cond.Is(al)) {
14754        EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) |
14755                rd.Encode(22, 12) | rm.Encode(5, 0));
14756        return;
14757      }
14758    }
14759  }
14760  Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
14761}
14762
14763void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, SRegister rm) {
14764  VIXL_ASSERT(AllowAssembler());
14765  CheckIT(cond);
14766  if (IsUsingT32()) {
14767    // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
14768    if (dt.Is(F32)) {
14769      EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
14770      AdvanceIT();
14771      return;
14772    }
14773  } else {
14774    // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
14775    if (dt.Is(F32) && cond.IsNotNever()) {
14776      EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14777              rm.Encode(5, 0));
14778      return;
14779    }
14780  }
14781  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm);
14782}
14783
14784void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14785  VIXL_ASSERT(AllowAssembler());
14786  CheckIT(cond);
14787  if (IsUsingT32()) {
14788    // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
14789    if (dt.Is(F64)) {
14790      EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
14791      AdvanceIT();
14792      return;
14793    }
14794  } else {
14795    // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
14796    if (dt.Is(F64) && cond.IsNotNever()) {
14797      EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14798              rm.Encode(5, 0));
14799      return;
14800    }
14801  }
14802  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm);
14803}
14804
14805void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, double imm) {
14806  VIXL_ASSERT(AllowAssembler());
14807  CheckIT(cond);
14808  if (IsUsingT32()) {
14809    // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
14810    if (dt.Is(F32) && (imm == 0.0)) {
14811      EmitT32_32(0xeeb50a40U | rd.Encode(22, 12));
14812      AdvanceIT();
14813      return;
14814    }
14815  } else {
14816    // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
14817    if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) {
14818      EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14819      return;
14820    }
14821  }
14822  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm);
14823}
14824
14825void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, double imm) {
14826  VIXL_ASSERT(AllowAssembler());
14827  CheckIT(cond);
14828  if (IsUsingT32()) {
14829    // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
14830    if (dt.Is(F64) && (imm == 0.0)) {
14831      EmitT32_32(0xeeb50b40U | rd.Encode(22, 12));
14832      AdvanceIT();
14833      return;
14834    }
14835  } else {
14836    // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
14837    if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) {
14838      EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14839      return;
14840    }
14841  }
14842  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm);
14843}
14844
14845void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, SRegister rm) {
14846  VIXL_ASSERT(AllowAssembler());
14847  CheckIT(cond);
14848  if (IsUsingT32()) {
14849    // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
14850    if (dt.Is(F32)) {
14851      EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14852      AdvanceIT();
14853      return;
14854    }
14855  } else {
14856    // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
14857    if (dt.Is(F32) && cond.IsNotNever()) {
14858      EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14859              rm.Encode(5, 0));
14860      return;
14861    }
14862  }
14863  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm);
14864}
14865
14866void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14867  VIXL_ASSERT(AllowAssembler());
14868  CheckIT(cond);
14869  if (IsUsingT32()) {
14870    // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
14871    if (dt.Is(F64)) {
14872      EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14873      AdvanceIT();
14874      return;
14875    }
14876  } else {
14877    // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
14878    if (dt.Is(F64) && cond.IsNotNever()) {
14879      EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14880              rm.Encode(5, 0));
14881      return;
14882    }
14883  }
14884  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm);
14885}
14886
14887void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, double imm) {
14888  VIXL_ASSERT(AllowAssembler());
14889  CheckIT(cond);
14890  if (IsUsingT32()) {
14891    // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
14892    if (dt.Is(F32) && (imm == 0.0)) {
14893      EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12));
14894      AdvanceIT();
14895      return;
14896    }
14897  } else {
14898    // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
14899    if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) {
14900      EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14901      return;
14902    }
14903  }
14904  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm);
14905}
14906
14907void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, double imm) {
14908  VIXL_ASSERT(AllowAssembler());
14909  CheckIT(cond);
14910  if (IsUsingT32()) {
14911    // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
14912    if (dt.Is(F64) && (imm == 0.0)) {
14913      EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12));
14914      AdvanceIT();
14915      return;
14916    }
14917  } else {
14918    // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
14919    if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) {
14920      EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14921      return;
14922    }
14923  }
14924  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm);
14925}
14926
14927void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14928  VIXL_ASSERT(AllowAssembler());
14929  CheckIT(cond);
14930  if (IsUsingT32()) {
14931    // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1
14932    if (dt.Is(Untyped8)) {
14933      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14934        EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
14935        AdvanceIT();
14936        return;
14937      }
14938    }
14939  } else {
14940    // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1
14941    if (dt.Is(Untyped8)) {
14942      if (cond.Is(al)) {
14943        EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
14944        return;
14945      }
14946    }
14947  }
14948  Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
14949}
14950
14951void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14952  VIXL_ASSERT(AllowAssembler());
14953  CheckIT(cond);
14954  if (IsUsingT32()) {
14955    // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1
14956    if (dt.Is(Untyped8)) {
14957      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14958        EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
14959        AdvanceIT();
14960        return;
14961      }
14962    }
14963  } else {
14964    // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1
14965    if (dt.Is(Untyped8)) {
14966      if (cond.Is(al)) {
14967        EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
14968        return;
14969      }
14970    }
14971  }
14972  Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
14973}
14974
14975void Assembler::vcvt(
14976    Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
14977  VIXL_ASSERT(AllowAssembler());
14978  CheckIT(cond);
14979  Dt_op_2 encoded_dt(dt2);
14980  if (IsUsingT32()) {
14981    // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1
14982    if (dt1.Is(F64) && dt2.Is(F32)) {
14983      EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14984      AdvanceIT();
14985      return;
14986    }
14987    // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1
14988    if (dt1.Is(F64) && encoded_dt.IsValid()) {
14989      EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) |
14990                 rd.Encode(22, 12) | rm.Encode(5, 0));
14991      AdvanceIT();
14992      return;
14993    }
14994  } else {
14995    // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1
14996    if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) {
14997      EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14998              rm.Encode(5, 0));
14999      return;
15000    }
15001    // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1
15002    if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) {
15003      EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) |
15004              (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
15005              rm.Encode(5, 0));
15006      return;
15007    }
15008  }
15009  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15010}
15011
15012void Assembler::vcvt(
15013    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15014  VIXL_ASSERT(AllowAssembler());
15015  CheckIT(cond);
15016  if (IsUsingT32()) {
15017    // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1
15018    if (dt1.Is(F32) && dt2.Is(F64)) {
15019      EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15020      AdvanceIT();
15021      return;
15022    }
15023    // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
15024    if (dt1.Is(U32) && dt2.Is(F64)) {
15025      EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15026      AdvanceIT();
15027      return;
15028    }
15029    // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
15030    if (dt1.Is(S32) && dt2.Is(F64)) {
15031      EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15032      AdvanceIT();
15033      return;
15034    }
15035  } else {
15036    // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1
15037    if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) {
15038      EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15039              rm.Encode(5, 0));
15040      return;
15041    }
15042    // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
15043    if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
15044      EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15045              rm.Encode(5, 0));
15046      return;
15047    }
15048    // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
15049    if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
15050      EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15051              rm.Encode(5, 0));
15052      return;
15053    }
15054  }
15055  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15056}
15057
15058void Assembler::vcvt(Condition cond,
15059                     DataType dt1,
15060                     DataType dt2,
15061                     DRegister rd,
15062                     DRegister rm,
15063                     int32_t fbits) {
15064  VIXL_ASSERT(AllowAssembler());
15065  CheckIT(cond);
15066  Dt_op_U_1 encoded_dt(dt1, dt2);
15067  Dt_U_sx_1 encoded_dt_2(dt2);
15068  Dt_U_sx_1 encoded_dt_3(dt1);
15069  if (IsUsingT32()) {
15070    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1
15071    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15072      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15073        uint32_t fbits_ = 64 - fbits;
15074        EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
15075                   ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15076                   rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15077        AdvanceIT();
15078        return;
15079      }
15080    }
15081    // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1
15082    if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
15083        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15084         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15085      unsigned offset = 32;
15086      if (dt2.Is(S16) || dt2.Is(U16)) {
15087        offset = 16;
15088      }
15089      uint32_t fbits_ = offset - fbits;
15090      EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15091                 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15092                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15093                 ((fbits_ & 0x1e) >> 1));
15094      AdvanceIT();
15095      return;
15096    }
15097    // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1
15098    if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
15099        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15100         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15101      unsigned offset = 32;
15102      if (dt1.Is(S16) || dt1.Is(U16)) {
15103        offset = 16;
15104      }
15105      uint32_t fbits_ = offset - fbits;
15106      EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
15107                 ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
15108                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15109                 ((fbits_ & 0x1e) >> 1));
15110      AdvanceIT();
15111      return;
15112    }
15113  } else {
15114    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1
15115    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15116      if (cond.Is(al)) {
15117        uint32_t fbits_ = 64 - fbits;
15118        EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
15119                ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15120                rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15121        return;
15122      }
15123    }
15124    // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1
15125    if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
15126        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15127         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15128        cond.IsNotNever()) {
15129      unsigned offset = 32;
15130      if (dt2.Is(S16) || dt2.Is(U16)) {
15131        offset = 16;
15132      }
15133      uint32_t fbits_ = offset - fbits;
15134      EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) |
15135              ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15136              ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15137              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15138              ((fbits_ & 0x1e) >> 1));
15139      return;
15140    }
15141    // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1
15142    if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
15143        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15144         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15145        cond.IsNotNever()) {
15146      unsigned offset = 32;
15147      if (dt1.Is(S16) || dt1.Is(U16)) {
15148        offset = 16;
15149      }
15150      uint32_t fbits_ = offset - fbits;
15151      EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) |
15152              ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
15153              ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
15154              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15155              ((fbits_ & 0x1e) >> 1));
15156      return;
15157    }
15158  }
15159  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
15160}
15161
15162void Assembler::vcvt(Condition cond,
15163                     DataType dt1,
15164                     DataType dt2,
15165                     QRegister rd,
15166                     QRegister rm,
15167                     int32_t fbits) {
15168  VIXL_ASSERT(AllowAssembler());
15169  CheckIT(cond);
15170  Dt_op_U_1 encoded_dt(dt1, dt2);
15171  if (IsUsingT32()) {
15172    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1
15173    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15174      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15175        uint32_t fbits_ = 64 - fbits;
15176        EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
15177                   ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15178                   rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15179        AdvanceIT();
15180        return;
15181      }
15182    }
15183  } else {
15184    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1
15185    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15186      if (cond.Is(al)) {
15187        uint32_t fbits_ = 64 - fbits;
15188        EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
15189                ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15190                rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15191        return;
15192      }
15193    }
15194  }
15195  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
15196}
15197
15198void Assembler::vcvt(Condition cond,
15199                     DataType dt1,
15200                     DataType dt2,
15201                     SRegister rd,
15202                     SRegister rm,
15203                     int32_t fbits) {
15204  VIXL_ASSERT(AllowAssembler());
15205  CheckIT(cond);
15206  Dt_U_sx_1 encoded_dt(dt2);
15207  Dt_U_sx_1 encoded_dt_2(dt1);
15208  if (IsUsingT32()) {
15209    // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1
15210    if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
15211        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15212         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15213      unsigned offset = 32;
15214      if (dt2.Is(S16) || dt2.Is(U16)) {
15215        offset = 16;
15216      }
15217      uint32_t fbits_ = offset - fbits;
15218      EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
15219                 ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
15220                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15221                 ((fbits_ & 0x1e) >> 1));
15222      AdvanceIT();
15223      return;
15224    }
15225    // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1
15226    if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
15227        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15228         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15229      unsigned offset = 32;
15230      if (dt1.Is(S16) || dt1.Is(U16)) {
15231        offset = 16;
15232      }
15233      uint32_t fbits_ = offset - fbits;
15234      EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15235                 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15236                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15237                 ((fbits_ & 0x1e) >> 1));
15238      AdvanceIT();
15239      return;
15240    }
15241  } else {
15242    // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1
15243    if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
15244        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15245         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15246        cond.IsNotNever()) {
15247      unsigned offset = 32;
15248      if (dt2.Is(S16) || dt2.Is(U16)) {
15249        offset = 16;
15250      }
15251      uint32_t fbits_ = offset - fbits;
15252      EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) |
15253              ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
15254              ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
15255              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15256              ((fbits_ & 0x1e) >> 1));
15257      return;
15258    }
15259    // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1
15260    if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
15261        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15262         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15263        cond.IsNotNever()) {
15264      unsigned offset = 32;
15265      if (dt1.Is(S16) || dt1.Is(U16)) {
15266        offset = 16;
15267      }
15268      uint32_t fbits_ = offset - fbits;
15269      EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) |
15270              ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15271              ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15272              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15273              ((fbits_ & 0x1e) >> 1));
15274      return;
15275    }
15276  }
15277  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
15278}
15279
15280void Assembler::vcvt(
15281    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15282  VIXL_ASSERT(AllowAssembler());
15283  CheckIT(cond);
15284  Dt_op_1 encoded_dt(dt1, dt2);
15285  if (IsUsingT32()) {
15286    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1
15287    if (encoded_dt.IsValid()) {
15288      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15289        EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) |
15290                   rd.Encode(22, 12) | rm.Encode(5, 0));
15291        AdvanceIT();
15292        return;
15293      }
15294    }
15295  } else {
15296    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1
15297    if (encoded_dt.IsValid()) {
15298      if (cond.Is(al)) {
15299        EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) |
15300                rd.Encode(22, 12) | rm.Encode(5, 0));
15301        return;
15302      }
15303    }
15304  }
15305  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15306}
15307
15308void Assembler::vcvt(
15309    Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15310  VIXL_ASSERT(AllowAssembler());
15311  CheckIT(cond);
15312  Dt_op_1 encoded_dt(dt1, dt2);
15313  if (IsUsingT32()) {
15314    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1
15315    if (encoded_dt.IsValid()) {
15316      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15317        EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) |
15318                   rd.Encode(22, 12) | rm.Encode(5, 0));
15319        AdvanceIT();
15320        return;
15321      }
15322    }
15323  } else {
15324    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1
15325    if (encoded_dt.IsValid()) {
15326      if (cond.Is(al)) {
15327        EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) |
15328                rd.Encode(22, 12) | rm.Encode(5, 0));
15329        return;
15330      }
15331    }
15332  }
15333  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15334}
15335
15336void Assembler::vcvt(
15337    Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) {
15338  VIXL_ASSERT(AllowAssembler());
15339  CheckIT(cond);
15340  if (IsUsingT32()) {
15341    // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1
15342    if (dt1.Is(F16) && dt2.Is(F32)) {
15343      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15344        EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
15345        AdvanceIT();
15346        return;
15347      }
15348    }
15349  } else {
15350    // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1
15351    if (dt1.Is(F16) && dt2.Is(F32)) {
15352      if (cond.Is(al)) {
15353        EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
15354        return;
15355      }
15356    }
15357  }
15358  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15359}
15360
15361void Assembler::vcvt(
15362    Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) {
15363  VIXL_ASSERT(AllowAssembler());
15364  CheckIT(cond);
15365  if (IsUsingT32()) {
15366    // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1
15367    if (dt1.Is(F32) && dt2.Is(F16)) {
15368      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15369        EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
15370        AdvanceIT();
15371        return;
15372      }
15373    }
15374  } else {
15375    // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1
15376    if (dt1.Is(F32) && dt2.Is(F16)) {
15377      if (cond.Is(al)) {
15378        EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
15379        return;
15380      }
15381    }
15382  }
15383  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15384}
15385
15386void Assembler::vcvt(
15387    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15388  VIXL_ASSERT(AllowAssembler());
15389  CheckIT(cond);
15390  Dt_op_2 encoded_dt(dt2);
15391  if (IsUsingT32()) {
15392    // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
15393    if (dt1.Is(U32) && dt2.Is(F32)) {
15394      EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15395      AdvanceIT();
15396      return;
15397    }
15398    // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
15399    if (dt1.Is(S32) && dt2.Is(F32)) {
15400      EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15401      AdvanceIT();
15402      return;
15403    }
15404    // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1
15405    if (dt1.Is(F32) && encoded_dt.IsValid()) {
15406      EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) |
15407                 rd.Encode(22, 12) | rm.Encode(5, 0));
15408      AdvanceIT();
15409      return;
15410    }
15411  } else {
15412    // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
15413    if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
15414      EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15415              rm.Encode(5, 0));
15416      return;
15417    }
15418    // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
15419    if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
15420      EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15421              rm.Encode(5, 0));
15422      return;
15423    }
15424    // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1
15425    if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) {
15426      EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) |
15427              (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
15428              rm.Encode(5, 0));
15429      return;
15430    }
15431  }
15432  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15433}
15434
15435void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15436  VIXL_ASSERT(AllowAssembler());
15437  CheckIT(al);
15438  Dt_op_3 encoded_dt(dt1);
15439  if (IsUsingT32()) {
15440    // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15441    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15442      EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) |
15443                 rd.Encode(22, 12) | rm.Encode(5, 0));
15444      AdvanceIT();
15445      return;
15446    }
15447  } else {
15448    // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15449    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15450      EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) |
15451              rd.Encode(22, 12) | rm.Encode(5, 0));
15452      return;
15453    }
15454  }
15455  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15456}
15457
15458void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15459  VIXL_ASSERT(AllowAssembler());
15460  CheckIT(al);
15461  Dt_op_3 encoded_dt(dt1);
15462  if (IsUsingT32()) {
15463    // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15464    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15465      EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) |
15466                 rd.Encode(22, 12) | rm.Encode(5, 0));
15467      AdvanceIT();
15468      return;
15469    }
15470  } else {
15471    // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15472    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15473      EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) |
15474              rd.Encode(22, 12) | rm.Encode(5, 0));
15475      return;
15476    }
15477  }
15478  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15479}
15480
15481void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15482  VIXL_ASSERT(AllowAssembler());
15483  CheckIT(al);
15484  Dt_op_2 encoded_dt(dt1);
15485  if (IsUsingT32()) {
15486    // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15487    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15488      EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
15489                 rd.Encode(22, 12) | rm.Encode(5, 0));
15490      AdvanceIT();
15491      return;
15492    }
15493  } else {
15494    // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15495    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15496      EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
15497              rd.Encode(22, 12) | rm.Encode(5, 0));
15498      return;
15499    }
15500  }
15501  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15502}
15503
15504void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15505  VIXL_ASSERT(AllowAssembler());
15506  CheckIT(al);
15507  Dt_op_2 encoded_dt(dt1);
15508  if (IsUsingT32()) {
15509    // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15510    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15511      EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
15512                 rd.Encode(22, 12) | rm.Encode(5, 0));
15513      AdvanceIT();
15514      return;
15515    }
15516  } else {
15517    // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15518    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15519      EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
15520              rd.Encode(22, 12) | rm.Encode(5, 0));
15521      return;
15522    }
15523  }
15524  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15525}
15526
15527void Assembler::vcvtb(
15528    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15529  VIXL_ASSERT(AllowAssembler());
15530  CheckIT(cond);
15531  if (IsUsingT32()) {
15532    // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
15533    if (dt1.Is(F32) && dt2.Is(F16)) {
15534      EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15535      AdvanceIT();
15536      return;
15537    }
15538    // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
15539    if (dt1.Is(F16) && dt2.Is(F32)) {
15540      EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15541      AdvanceIT();
15542      return;
15543    }
15544  } else {
15545    // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
15546    if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
15547      EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15548              rm.Encode(5, 0));
15549      return;
15550    }
15551    // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
15552    if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
15553      EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15554              rm.Encode(5, 0));
15555      return;
15556    }
15557  }
15558  Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15559}
15560
15561void Assembler::vcvtb(
15562    Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
15563  VIXL_ASSERT(AllowAssembler());
15564  CheckIT(cond);
15565  if (IsUsingT32()) {
15566    // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
15567    if (dt1.Is(F64) && dt2.Is(F16)) {
15568      EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15569      AdvanceIT();
15570      return;
15571    }
15572  } else {
15573    // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
15574    if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
15575      EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15576              rm.Encode(5, 0));
15577      return;
15578    }
15579  }
15580  Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15581}
15582
15583void Assembler::vcvtb(
15584    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15585  VIXL_ASSERT(AllowAssembler());
15586  CheckIT(cond);
15587  if (IsUsingT32()) {
15588    // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
15589    if (dt1.Is(F16) && dt2.Is(F64)) {
15590      EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15591      AdvanceIT();
15592      return;
15593    }
15594  } else {
15595    // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
15596    if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
15597      EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15598              rm.Encode(5, 0));
15599      return;
15600    }
15601  }
15602  Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15603}
15604
15605void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15606  VIXL_ASSERT(AllowAssembler());
15607  CheckIT(al);
15608  Dt_op_3 encoded_dt(dt1);
15609  if (IsUsingT32()) {
15610    // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15611    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15612      EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) |
15613                 rd.Encode(22, 12) | rm.Encode(5, 0));
15614      AdvanceIT();
15615      return;
15616    }
15617  } else {
15618    // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15619    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15620      EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) |
15621              rd.Encode(22, 12) | rm.Encode(5, 0));
15622      return;
15623    }
15624  }
15625  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15626}
15627
15628void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15629  VIXL_ASSERT(AllowAssembler());
15630  CheckIT(al);
15631  Dt_op_3 encoded_dt(dt1);
15632  if (IsUsingT32()) {
15633    // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15634    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15635      EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) |
15636                 rd.Encode(22, 12) | rm.Encode(5, 0));
15637      AdvanceIT();
15638      return;
15639    }
15640  } else {
15641    // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15642    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15643      EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) |
15644              rd.Encode(22, 12) | rm.Encode(5, 0));
15645      return;
15646    }
15647  }
15648  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15649}
15650
15651void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15652  VIXL_ASSERT(AllowAssembler());
15653  CheckIT(al);
15654  Dt_op_2 encoded_dt(dt1);
15655  if (IsUsingT32()) {
15656    // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15657    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15658      EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
15659                 rd.Encode(22, 12) | rm.Encode(5, 0));
15660      AdvanceIT();
15661      return;
15662    }
15663  } else {
15664    // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15665    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15666      EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
15667              rd.Encode(22, 12) | rm.Encode(5, 0));
15668      return;
15669    }
15670  }
15671  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15672}
15673
15674void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15675  VIXL_ASSERT(AllowAssembler());
15676  CheckIT(al);
15677  Dt_op_2 encoded_dt(dt1);
15678  if (IsUsingT32()) {
15679    // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15680    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15681      EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
15682                 rd.Encode(22, 12) | rm.Encode(5, 0));
15683      AdvanceIT();
15684      return;
15685    }
15686  } else {
15687    // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15688    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15689      EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
15690              rd.Encode(22, 12) | rm.Encode(5, 0));
15691      return;
15692    }
15693  }
15694  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15695}
15696
15697void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15698  VIXL_ASSERT(AllowAssembler());
15699  CheckIT(al);
15700  Dt_op_3 encoded_dt(dt1);
15701  if (IsUsingT32()) {
15702    // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15703    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15704      EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) |
15705                 rd.Encode(22, 12) | rm.Encode(5, 0));
15706      AdvanceIT();
15707      return;
15708    }
15709  } else {
15710    // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15711    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15712      EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) |
15713              rd.Encode(22, 12) | rm.Encode(5, 0));
15714      return;
15715    }
15716  }
15717  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15718}
15719
15720void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15721  VIXL_ASSERT(AllowAssembler());
15722  CheckIT(al);
15723  Dt_op_3 encoded_dt(dt1);
15724  if (IsUsingT32()) {
15725    // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15726    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15727      EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) |
15728                 rd.Encode(22, 12) | rm.Encode(5, 0));
15729      AdvanceIT();
15730      return;
15731    }
15732  } else {
15733    // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15734    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15735      EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) |
15736              rd.Encode(22, 12) | rm.Encode(5, 0));
15737      return;
15738    }
15739  }
15740  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15741}
15742
15743void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15744  VIXL_ASSERT(AllowAssembler());
15745  CheckIT(al);
15746  Dt_op_2 encoded_dt(dt1);
15747  if (IsUsingT32()) {
15748    // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15749    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15750      EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
15751                 rd.Encode(22, 12) | rm.Encode(5, 0));
15752      AdvanceIT();
15753      return;
15754    }
15755  } else {
15756    // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15757    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15758      EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
15759              rd.Encode(22, 12) | rm.Encode(5, 0));
15760      return;
15761    }
15762  }
15763  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15764}
15765
15766void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15767  VIXL_ASSERT(AllowAssembler());
15768  CheckIT(al);
15769  Dt_op_2 encoded_dt(dt1);
15770  if (IsUsingT32()) {
15771    // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15772    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15773      EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
15774                 rd.Encode(22, 12) | rm.Encode(5, 0));
15775      AdvanceIT();
15776      return;
15777    }
15778  } else {
15779    // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15780    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15781      EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
15782              rd.Encode(22, 12) | rm.Encode(5, 0));
15783      return;
15784    }
15785  }
15786  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15787}
15788
15789void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15790  VIXL_ASSERT(AllowAssembler());
15791  CheckIT(al);
15792  Dt_op_3 encoded_dt(dt1);
15793  if (IsUsingT32()) {
15794    // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15795    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15796      EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) |
15797                 rd.Encode(22, 12) | rm.Encode(5, 0));
15798      AdvanceIT();
15799      return;
15800    }
15801  } else {
15802    // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15803    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15804      EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) |
15805              rd.Encode(22, 12) | rm.Encode(5, 0));
15806      return;
15807    }
15808  }
15809  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15810}
15811
15812void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15813  VIXL_ASSERT(AllowAssembler());
15814  CheckIT(al);
15815  Dt_op_3 encoded_dt(dt1);
15816  if (IsUsingT32()) {
15817    // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15818    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15819      EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) |
15820                 rd.Encode(22, 12) | rm.Encode(5, 0));
15821      AdvanceIT();
15822      return;
15823    }
15824  } else {
15825    // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15826    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15827      EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) |
15828              rd.Encode(22, 12) | rm.Encode(5, 0));
15829      return;
15830    }
15831  }
15832  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15833}
15834
15835void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15836  VIXL_ASSERT(AllowAssembler());
15837  CheckIT(al);
15838  Dt_op_2 encoded_dt(dt1);
15839  if (IsUsingT32()) {
15840    // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15841    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15842      EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
15843                 rd.Encode(22, 12) | rm.Encode(5, 0));
15844      AdvanceIT();
15845      return;
15846    }
15847  } else {
15848    // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15849    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15850      EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
15851              rd.Encode(22, 12) | rm.Encode(5, 0));
15852      return;
15853    }
15854  }
15855  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15856}
15857
15858void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15859  VIXL_ASSERT(AllowAssembler());
15860  CheckIT(al);
15861  Dt_op_2 encoded_dt(dt1);
15862  if (IsUsingT32()) {
15863    // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15864    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15865      EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
15866                 rd.Encode(22, 12) | rm.Encode(5, 0));
15867      AdvanceIT();
15868      return;
15869    }
15870  } else {
15871    // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15872    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15873      EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
15874              rd.Encode(22, 12) | rm.Encode(5, 0));
15875      return;
15876    }
15877  }
15878  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15879}
15880
15881void Assembler::vcvtr(
15882    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15883  VIXL_ASSERT(AllowAssembler());
15884  CheckIT(cond);
15885  if (IsUsingT32()) {
15886    // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
15887    if (dt1.Is(U32) && dt2.Is(F32)) {
15888      EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15889      AdvanceIT();
15890      return;
15891    }
15892    // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
15893    if (dt1.Is(S32) && dt2.Is(F32)) {
15894      EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15895      AdvanceIT();
15896      return;
15897    }
15898  } else {
15899    // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
15900    if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
15901      EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15902              rm.Encode(5, 0));
15903      return;
15904    }
15905    // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
15906    if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
15907      EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15908              rm.Encode(5, 0));
15909      return;
15910    }
15911  }
15912  Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
15913}
15914
15915void Assembler::vcvtr(
15916    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15917  VIXL_ASSERT(AllowAssembler());
15918  CheckIT(cond);
15919  if (IsUsingT32()) {
15920    // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
15921    if (dt1.Is(U32) && dt2.Is(F64)) {
15922      EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15923      AdvanceIT();
15924      return;
15925    }
15926    // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
15927    if (dt1.Is(S32) && dt2.Is(F64)) {
15928      EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15929      AdvanceIT();
15930      return;
15931    }
15932  } else {
15933    // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
15934    if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
15935      EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15936              rm.Encode(5, 0));
15937      return;
15938    }
15939    // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
15940    if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
15941      EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15942              rm.Encode(5, 0));
15943      return;
15944    }
15945  }
15946  Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
15947}
15948
15949void Assembler::vcvtt(
15950    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15951  VIXL_ASSERT(AllowAssembler());
15952  CheckIT(cond);
15953  if (IsUsingT32()) {
15954    // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
15955    if (dt1.Is(F32) && dt2.Is(F16)) {
15956      EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15957      AdvanceIT();
15958      return;
15959    }
15960    // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
15961    if (dt1.Is(F16) && dt2.Is(F32)) {
15962      EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15963      AdvanceIT();
15964      return;
15965    }
15966  } else {
15967    // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
15968    if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
15969      EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15970              rm.Encode(5, 0));
15971      return;
15972    }
15973    // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
15974    if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
15975      EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15976              rm.Encode(5, 0));
15977      return;
15978    }
15979  }
15980  Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
15981}
15982
15983void Assembler::vcvtt(
15984    Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
15985  VIXL_ASSERT(AllowAssembler());
15986  CheckIT(cond);
15987  if (IsUsingT32()) {
15988    // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
15989    if (dt1.Is(F64) && dt2.Is(F16)) {
15990      EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15991      AdvanceIT();
15992      return;
15993    }
15994  } else {
15995    // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
15996    if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
15997      EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15998              rm.Encode(5, 0));
15999      return;
16000    }
16001  }
16002  Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
16003}
16004
16005void Assembler::vcvtt(
16006    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16007  VIXL_ASSERT(AllowAssembler());
16008  CheckIT(cond);
16009  if (IsUsingT32()) {
16010    // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
16011    if (dt1.Is(F16) && dt2.Is(F64)) {
16012      EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16013      AdvanceIT();
16014      return;
16015    }
16016  } else {
16017    // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
16018    if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
16019      EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16020              rm.Encode(5, 0));
16021      return;
16022    }
16023  }
16024  Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
16025}
16026
16027void Assembler::vdiv(
16028    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16029  VIXL_ASSERT(AllowAssembler());
16030  CheckIT(cond);
16031  if (IsUsingT32()) {
16032    // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
16033    if (dt.Is(F32)) {
16034      EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16035                 rm.Encode(5, 0));
16036      AdvanceIT();
16037      return;
16038    }
16039  } else {
16040    // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
16041    if (dt.Is(F32) && cond.IsNotNever()) {
16042      EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16043              rn.Encode(7, 16) | rm.Encode(5, 0));
16044      return;
16045    }
16046  }
16047  Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
16048}
16049
16050void Assembler::vdiv(
16051    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16052  VIXL_ASSERT(AllowAssembler());
16053  CheckIT(cond);
16054  if (IsUsingT32()) {
16055    // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
16056    if (dt.Is(F64)) {
16057      EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16058                 rm.Encode(5, 0));
16059      AdvanceIT();
16060      return;
16061    }
16062  } else {
16063    // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
16064    if (dt.Is(F64) && cond.IsNotNever()) {
16065      EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16066              rn.Encode(7, 16) | rm.Encode(5, 0));
16067      return;
16068    }
16069  }
16070  Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
16071}
16072
16073void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) {
16074  VIXL_ASSERT(AllowAssembler());
16075  CheckIT(cond);
16076  Dt_B_E_1 encoded_dt(dt);
16077  if (IsUsingT32()) {
16078    // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1
16079    if (encoded_dt.IsValid()) {
16080      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16081        EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16082                   ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16083                   rd.Encode(7, 16) | (rt.GetCode() << 12));
16084        AdvanceIT();
16085        return;
16086      }
16087    }
16088  } else {
16089    // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1
16090    if (encoded_dt.IsValid() && cond.IsNotNever()) {
16091      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16092        EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) |
16093                ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16094                ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16095                rd.Encode(7, 16) | (rt.GetCode() << 12));
16096        return;
16097      }
16098    }
16099  }
16100  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
16101}
16102
16103void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) {
16104  VIXL_ASSERT(AllowAssembler());
16105  CheckIT(cond);
16106  Dt_B_E_1 encoded_dt(dt);
16107  if (IsUsingT32()) {
16108    // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1
16109    if (encoded_dt.IsValid()) {
16110      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16111        EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16112                   ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16113                   rd.Encode(7, 16) | (rt.GetCode() << 12));
16114        AdvanceIT();
16115        return;
16116      }
16117    }
16118  } else {
16119    // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1
16120    if (encoded_dt.IsValid() && cond.IsNotNever()) {
16121      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16122        EmitA32(0x0e800b10U | (cond.GetCondition() << 28) |
16123                ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16124                ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16125                rd.Encode(7, 16) | (rt.GetCode() << 12));
16126        return;
16127      }
16128    }
16129  }
16130  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
16131}
16132
16133void Assembler::vdup(Condition cond,
16134                     DataType dt,
16135                     DRegister rd,
16136                     DRegisterLane rm) {
16137  VIXL_ASSERT(AllowAssembler());
16138  CheckIT(cond);
16139  Dt_imm4_1 encoded_dt(dt, rm);
16140  if (IsUsingT32()) {
16141    // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1
16142    if (encoded_dt.IsValid()) {
16143      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16144        EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) |
16145                   rd.Encode(22, 12) | rm.Encode(5, 0));
16146        AdvanceIT();
16147        return;
16148      }
16149    }
16150  } else {
16151    // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1
16152    if (encoded_dt.IsValid()) {
16153      if (cond.Is(al)) {
16154        EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) |
16155                rd.Encode(22, 12) | rm.Encode(5, 0));
16156        return;
16157      }
16158    }
16159  }
16160  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
16161}
16162
16163void Assembler::vdup(Condition cond,
16164                     DataType dt,
16165                     QRegister rd,
16166                     DRegisterLane rm) {
16167  VIXL_ASSERT(AllowAssembler());
16168  CheckIT(cond);
16169  Dt_imm4_1 encoded_dt(dt, rm);
16170  if (IsUsingT32()) {
16171    // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1
16172    if (encoded_dt.IsValid()) {
16173      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16174        EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) |
16175                   rd.Encode(22, 12) | rm.Encode(5, 0));
16176        AdvanceIT();
16177        return;
16178      }
16179    }
16180  } else {
16181    // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1
16182    if (encoded_dt.IsValid()) {
16183      if (cond.Is(al)) {
16184        EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) |
16185                rd.Encode(22, 12) | rm.Encode(5, 0));
16186        return;
16187      }
16188    }
16189  }
16190  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
16191}
16192
16193void Assembler::veor(
16194    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16195  VIXL_ASSERT(AllowAssembler());
16196  CheckIT(cond);
16197  USE(dt);
16198  if (IsUsingT32()) {
16199    // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
16200    if (cond.Is(al) || AllowStronglyDiscouraged()) {
16201      EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16202                 rm.Encode(5, 0));
16203      AdvanceIT();
16204      return;
16205    }
16206  } else {
16207    // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
16208    if (cond.Is(al)) {
16209      EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16210              rm.Encode(5, 0));
16211      return;
16212    }
16213  }
16214  Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
16215}
16216
16217void Assembler::veor(
16218    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16219  VIXL_ASSERT(AllowAssembler());
16220  CheckIT(cond);
16221  USE(dt);
16222  if (IsUsingT32()) {
16223    // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
16224    if (cond.Is(al) || AllowStronglyDiscouraged()) {
16225      EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16226                 rm.Encode(5, 0));
16227      AdvanceIT();
16228      return;
16229    }
16230  } else {
16231    // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
16232    if (cond.Is(al)) {
16233      EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16234              rm.Encode(5, 0));
16235      return;
16236    }
16237  }
16238  Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
16239}
16240
16241void Assembler::vext(Condition cond,
16242                     DataType dt,
16243                     DRegister rd,
16244                     DRegister rn,
16245                     DRegister rm,
16246                     const DOperand& operand) {
16247  VIXL_ASSERT(AllowAssembler());
16248  CheckIT(cond);
16249  if (operand.IsImmediate()) {
16250    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
16251      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
16252      if (IsUsingT32()) {
16253        // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
16254        if (dt.Is(Untyped8) && (imm <= 7)) {
16255          if (cond.Is(al) || AllowStronglyDiscouraged()) {
16256            EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16257                       rm.Encode(5, 0) | (imm << 8));
16258            AdvanceIT();
16259            return;
16260          }
16261        }
16262        // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
16263        if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
16264            (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16265          if (cond.Is(al) || AllowStronglyDiscouraged()) {
16266            uint32_t imm4 = imm / dt.GetSize();
16267            EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16268                       rm.Encode(5, 0) | (imm4 << 8));
16269            AdvanceIT();
16270            return;
16271          }
16272        }
16273      } else {
16274        // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
16275        if (dt.Is(Untyped8) && (imm <= 7)) {
16276          if (cond.Is(al)) {
16277            EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16278                    rm.Encode(5, 0) | (imm << 8));
16279            return;
16280          }
16281        }
16282        // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
16283        if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
16284            (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16285          if (cond.Is(al)) {
16286            uint32_t imm4 = imm / dt.GetSize();
16287            EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16288                    rm.Encode(5, 0) | (imm4 << 8));
16289            return;
16290          }
16291        }
16292      }
16293    }
16294  }
16295  Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
16296}
16297
16298void Assembler::vext(Condition cond,
16299                     DataType dt,
16300                     QRegister rd,
16301                     QRegister rn,
16302                     QRegister rm,
16303                     const QOperand& operand) {
16304  VIXL_ASSERT(AllowAssembler());
16305  CheckIT(cond);
16306  if (operand.IsImmediate()) {
16307    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
16308      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
16309      if (IsUsingT32()) {
16310        // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
16311        if (dt.Is(Untyped8) && (imm <= 15)) {
16312          if (cond.Is(al) || AllowStronglyDiscouraged()) {
16313            EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16314                       rm.Encode(5, 0) | (imm << 8));
16315            AdvanceIT();
16316            return;
16317          }
16318        }
16319        // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
16320        if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
16321            (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16322          if (cond.Is(al) || AllowStronglyDiscouraged()) {
16323            uint32_t imm4 = imm / dt.GetSize();
16324            EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16325                       rm.Encode(5, 0) | (imm4 << 8));
16326            AdvanceIT();
16327            return;
16328          }
16329        }
16330      } else {
16331        // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
16332        if (dt.Is(Untyped8) && (imm <= 15)) {
16333          if (cond.Is(al)) {
16334            EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16335                    rm.Encode(5, 0) | (imm << 8));
16336            return;
16337          }
16338        }
16339        // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
16340        if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
16341            (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16342          if (cond.Is(al)) {
16343            uint32_t imm4 = imm / dt.GetSize();
16344            EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16345                    rm.Encode(5, 0) | (imm4 << 8));
16346            return;
16347          }
16348        }
16349      }
16350    }
16351  }
16352  Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
16353}
16354
16355void Assembler::vfma(
16356    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16357  VIXL_ASSERT(AllowAssembler());
16358  CheckIT(cond);
16359  if (IsUsingT32()) {
16360    // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
16361    if (dt.Is(F32)) {
16362      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16363        EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16364                   rm.Encode(5, 0));
16365        AdvanceIT();
16366        return;
16367      }
16368    }
16369    // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
16370    if (dt.Is(F64)) {
16371      EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16372                 rm.Encode(5, 0));
16373      AdvanceIT();
16374      return;
16375    }
16376  } else {
16377    // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
16378    if (dt.Is(F32)) {
16379      if (cond.Is(al)) {
16380        EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16381                rm.Encode(5, 0));
16382        return;
16383      }
16384    }
16385    // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
16386    if (dt.Is(F64) && cond.IsNotNever()) {
16387      EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16388              rn.Encode(7, 16) | rm.Encode(5, 0));
16389      return;
16390    }
16391  }
16392  Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16393}
16394
16395void Assembler::vfma(
16396    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16397  VIXL_ASSERT(AllowAssembler());
16398  CheckIT(cond);
16399  if (IsUsingT32()) {
16400    // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
16401    if (dt.Is(F32)) {
16402      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16403        EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16404                   rm.Encode(5, 0));
16405        AdvanceIT();
16406        return;
16407      }
16408    }
16409  } else {
16410    // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
16411    if (dt.Is(F32)) {
16412      if (cond.Is(al)) {
16413        EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16414                rm.Encode(5, 0));
16415        return;
16416      }
16417    }
16418  }
16419  Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16420}
16421
16422void Assembler::vfma(
16423    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16424  VIXL_ASSERT(AllowAssembler());
16425  CheckIT(cond);
16426  if (IsUsingT32()) {
16427    // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
16428    if (dt.Is(F32)) {
16429      EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16430                 rm.Encode(5, 0));
16431      AdvanceIT();
16432      return;
16433    }
16434  } else {
16435    // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
16436    if (dt.Is(F32) && cond.IsNotNever()) {
16437      EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16438              rn.Encode(7, 16) | rm.Encode(5, 0));
16439      return;
16440    }
16441  }
16442  Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16443}
16444
16445void Assembler::vfms(
16446    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16447  VIXL_ASSERT(AllowAssembler());
16448  CheckIT(cond);
16449  if (IsUsingT32()) {
16450    // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
16451    if (dt.Is(F32)) {
16452      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16453        EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16454                   rm.Encode(5, 0));
16455        AdvanceIT();
16456        return;
16457      }
16458    }
16459    // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
16460    if (dt.Is(F64)) {
16461      EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16462                 rm.Encode(5, 0));
16463      AdvanceIT();
16464      return;
16465    }
16466  } else {
16467    // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
16468    if (dt.Is(F32)) {
16469      if (cond.Is(al)) {
16470        EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16471                rm.Encode(5, 0));
16472        return;
16473      }
16474    }
16475    // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
16476    if (dt.Is(F64) && cond.IsNotNever()) {
16477      EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16478              rn.Encode(7, 16) | rm.Encode(5, 0));
16479      return;
16480    }
16481  }
16482  Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16483}
16484
16485void Assembler::vfms(
16486    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16487  VIXL_ASSERT(AllowAssembler());
16488  CheckIT(cond);
16489  if (IsUsingT32()) {
16490    // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
16491    if (dt.Is(F32)) {
16492      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16493        EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16494                   rm.Encode(5, 0));
16495        AdvanceIT();
16496        return;
16497      }
16498    }
16499  } else {
16500    // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
16501    if (dt.Is(F32)) {
16502      if (cond.Is(al)) {
16503        EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16504                rm.Encode(5, 0));
16505        return;
16506      }
16507    }
16508  }
16509  Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16510}
16511
16512void Assembler::vfms(
16513    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16514  VIXL_ASSERT(AllowAssembler());
16515  CheckIT(cond);
16516  if (IsUsingT32()) {
16517    // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
16518    if (dt.Is(F32)) {
16519      EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16520                 rm.Encode(5, 0));
16521      AdvanceIT();
16522      return;
16523    }
16524  } else {
16525    // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
16526    if (dt.Is(F32) && cond.IsNotNever()) {
16527      EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16528              rn.Encode(7, 16) | rm.Encode(5, 0));
16529      return;
16530    }
16531  }
16532  Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16533}
16534
16535void Assembler::vfnma(
16536    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16537  VIXL_ASSERT(AllowAssembler());
16538  CheckIT(cond);
16539  if (IsUsingT32()) {
16540    // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
16541    if (dt.Is(F32)) {
16542      EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16543                 rm.Encode(5, 0));
16544      AdvanceIT();
16545      return;
16546    }
16547  } else {
16548    // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
16549    if (dt.Is(F32) && cond.IsNotNever()) {
16550      EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16551              rn.Encode(7, 16) | rm.Encode(5, 0));
16552      return;
16553    }
16554  }
16555  Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
16556}
16557
16558void Assembler::vfnma(
16559    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16560  VIXL_ASSERT(AllowAssembler());
16561  CheckIT(cond);
16562  if (IsUsingT32()) {
16563    // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
16564    if (dt.Is(F64)) {
16565      EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16566                 rm.Encode(5, 0));
16567      AdvanceIT();
16568      return;
16569    }
16570  } else {
16571    // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
16572    if (dt.Is(F64) && cond.IsNotNever()) {
16573      EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16574              rn.Encode(7, 16) | rm.Encode(5, 0));
16575      return;
16576    }
16577  }
16578  Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
16579}
16580
16581void Assembler::vfnms(
16582    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16583  VIXL_ASSERT(AllowAssembler());
16584  CheckIT(cond);
16585  if (IsUsingT32()) {
16586    // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
16587    if (dt.Is(F32)) {
16588      EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16589                 rm.Encode(5, 0));
16590      AdvanceIT();
16591      return;
16592    }
16593  } else {
16594    // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
16595    if (dt.Is(F32) && cond.IsNotNever()) {
16596      EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16597              rn.Encode(7, 16) | rm.Encode(5, 0));
16598      return;
16599    }
16600  }
16601  Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
16602}
16603
16604void Assembler::vfnms(
16605    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16606  VIXL_ASSERT(AllowAssembler());
16607  CheckIT(cond);
16608  if (IsUsingT32()) {
16609    // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
16610    if (dt.Is(F64)) {
16611      EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16612                 rm.Encode(5, 0));
16613      AdvanceIT();
16614      return;
16615    }
16616  } else {
16617    // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
16618    if (dt.Is(F64) && cond.IsNotNever()) {
16619      EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16620              rn.Encode(7, 16) | rm.Encode(5, 0));
16621      return;
16622    }
16623  }
16624  Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
16625}
16626
16627void Assembler::vhadd(
16628    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16629  VIXL_ASSERT(AllowAssembler());
16630  CheckIT(cond);
16631  Dt_U_size_1 encoded_dt(dt);
16632  if (IsUsingT32()) {
16633    // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
16634    if (encoded_dt.IsValid()) {
16635      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16636        EmitT32_32(0xef000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16637                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16638                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16639        AdvanceIT();
16640        return;
16641      }
16642    }
16643  } else {
16644    // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
16645    if (encoded_dt.IsValid()) {
16646      if (cond.Is(al)) {
16647        EmitA32(0xf2000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16648                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16649                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16650        return;
16651      }
16652    }
16653  }
16654  Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
16655}
16656
16657void Assembler::vhadd(
16658    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16659  VIXL_ASSERT(AllowAssembler());
16660  CheckIT(cond);
16661  Dt_U_size_1 encoded_dt(dt);
16662  if (IsUsingT32()) {
16663    // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
16664    if (encoded_dt.IsValid()) {
16665      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16666        EmitT32_32(0xef000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16667                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16668                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16669        AdvanceIT();
16670        return;
16671      }
16672    }
16673  } else {
16674    // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
16675    if (encoded_dt.IsValid()) {
16676      if (cond.Is(al)) {
16677        EmitA32(0xf2000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16678                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16679                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16680        return;
16681      }
16682    }
16683  }
16684  Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
16685}
16686
16687void Assembler::vhsub(
16688    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16689  VIXL_ASSERT(AllowAssembler());
16690  CheckIT(cond);
16691  Dt_U_size_1 encoded_dt(dt);
16692  if (IsUsingT32()) {
16693    // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
16694    if (encoded_dt.IsValid()) {
16695      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16696        EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16697                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16698                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16699        AdvanceIT();
16700        return;
16701      }
16702    }
16703  } else {
16704    // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
16705    if (encoded_dt.IsValid()) {
16706      if (cond.Is(al)) {
16707        EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16708                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16709                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16710        return;
16711      }
16712    }
16713  }
16714  Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
16715}
16716
16717void Assembler::vhsub(
16718    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16719  VIXL_ASSERT(AllowAssembler());
16720  CheckIT(cond);
16721  Dt_U_size_1 encoded_dt(dt);
16722  if (IsUsingT32()) {
16723    // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
16724    if (encoded_dt.IsValid()) {
16725      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16726        EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16727                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16728                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16729        AdvanceIT();
16730        return;
16731      }
16732    }
16733  } else {
16734    // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
16735    if (encoded_dt.IsValid()) {
16736      if (cond.Is(al)) {
16737        EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16738                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16739                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16740        return;
16741      }
16742    }
16743  }
16744  Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
16745}
16746
16747void Assembler::vld1(Condition cond,
16748                     DataType dt,
16749                     const NeonRegisterList& nreglist,
16750                     const AlignedMemOperand& operand) {
16751  VIXL_ASSERT(AllowAssembler());
16752  CheckIT(cond);
16753  if (operand.IsImmediateZero()) {
16754    Register rn = operand.GetBaseRegister();
16755    Alignment align = operand.GetAlignment();
16756    Dt_size_6 encoded_dt(dt);
16757    Dt_size_7 encoded_dt_2(dt);
16758    Align_align_1 encoded_align_1(align, nreglist);
16759    Align_a_1 encoded_align_2(align, dt);
16760    Align_index_align_1 encoded_align_3(align, nreglist, dt);
16761    if (IsUsingT32()) {
16762      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16763      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16764          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16765          operand.IsOffset() && encoded_align_1.IsValid() &&
16766          ((!rn.IsPC()) || AllowUnpredictable())) {
16767        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16768          const DRegister& first = nreglist.GetFirstDRegister();
16769          uint32_t len_encoding;
16770          switch (nreglist.GetLength()) {
16771            default:
16772              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16773            case 1:
16774              len_encoding = 0x7;
16775              break;
16776            case 2:
16777              len_encoding = 0xa;
16778              break;
16779            case 3:
16780              len_encoding = 0x6;
16781              break;
16782            case 4:
16783              len_encoding = 0x2;
16784              break;
16785          }
16786          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
16787                     (encoded_align_1.GetEncodingValue() << 4) |
16788                     first.Encode(22, 12) | (len_encoding << 8) |
16789                     (rn.GetCode() << 16));
16790          AdvanceIT();
16791          return;
16792        }
16793      }
16794      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16795      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16796          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16797          operand.IsPostIndex() && encoded_align_1.IsValid() &&
16798          ((!rn.IsPC()) || AllowUnpredictable())) {
16799        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16800          const DRegister& first = nreglist.GetFirstDRegister();
16801          uint32_t len_encoding;
16802          switch (nreglist.GetLength()) {
16803            default:
16804              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16805            case 1:
16806              len_encoding = 0x7;
16807              break;
16808            case 2:
16809              len_encoding = 0xa;
16810              break;
16811            case 3:
16812              len_encoding = 0x6;
16813              break;
16814            case 4:
16815              len_encoding = 0x2;
16816              break;
16817          }
16818          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
16819                     (encoded_align_1.GetEncodingValue() << 4) |
16820                     first.Encode(22, 12) | (len_encoding << 8) |
16821                     (rn.GetCode() << 16));
16822          AdvanceIT();
16823          return;
16824        }
16825      }
16826      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16827      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16828          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16829          operand.IsOffset() && encoded_align_2.IsValid() &&
16830          ((!rn.IsPC()) || AllowUnpredictable())) {
16831        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16832          const DRegister& first = nreglist.GetFirstDRegister();
16833          uint32_t len_encoding = nreglist.GetLength() - 1;
16834          EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
16835                     (encoded_align_2.GetEncodingValue() << 4) |
16836                     first.Encode(22, 12) | (len_encoding << 5) |
16837                     (rn.GetCode() << 16));
16838          AdvanceIT();
16839          return;
16840        }
16841      }
16842      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16843      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16844          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16845          operand.IsPostIndex() && encoded_align_2.IsValid() &&
16846          ((!rn.IsPC()) || AllowUnpredictable())) {
16847        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16848          const DRegister& first = nreglist.GetFirstDRegister();
16849          uint32_t len_encoding = nreglist.GetLength() - 1;
16850          EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
16851                     (encoded_align_2.GetEncodingValue() << 4) |
16852                     first.Encode(22, 12) | (len_encoding << 5) |
16853                     (rn.GetCode() << 16));
16854          AdvanceIT();
16855          return;
16856        }
16857      }
16858      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16859      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16860          (nreglist.GetLength() == 1) && operand.IsOffset() &&
16861          encoded_align_3.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
16862        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16863          const DRegister& first = nreglist.GetFirstDRegister();
16864          EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
16865                     (encoded_align_3.GetEncodingValue() << 4) |
16866                     first.Encode(22, 12) | (rn.GetCode() << 16));
16867          AdvanceIT();
16868          return;
16869        }
16870      }
16871      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16872      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16873          (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
16874          encoded_align_3.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
16875        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16876          const DRegister& first = nreglist.GetFirstDRegister();
16877          EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
16878                     (encoded_align_3.GetEncodingValue() << 4) |
16879                     first.Encode(22, 12) | (rn.GetCode() << 16));
16880          AdvanceIT();
16881          return;
16882        }
16883      }
16884    } else {
16885      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
16886      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16887          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16888          operand.IsOffset() && encoded_align_1.IsValid() &&
16889          ((!rn.IsPC()) || AllowUnpredictable())) {
16890        if (cond.Is(al)) {
16891          const DRegister& first = nreglist.GetFirstDRegister();
16892          uint32_t len_encoding;
16893          switch (nreglist.GetLength()) {
16894            default:
16895              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16896            case 1:
16897              len_encoding = 0x7;
16898              break;
16899            case 2:
16900              len_encoding = 0xa;
16901              break;
16902            case 3:
16903              len_encoding = 0x6;
16904              break;
16905            case 4:
16906              len_encoding = 0x2;
16907              break;
16908          }
16909          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
16910                  (encoded_align_1.GetEncodingValue() << 4) |
16911                  first.Encode(22, 12) | (len_encoding << 8) |
16912                  (rn.GetCode() << 16));
16913          return;
16914        }
16915      }
16916      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
16917      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16918          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16919          operand.IsPostIndex() && encoded_align_1.IsValid() &&
16920          ((!rn.IsPC()) || AllowUnpredictable())) {
16921        if (cond.Is(al)) {
16922          const DRegister& first = nreglist.GetFirstDRegister();
16923          uint32_t len_encoding;
16924          switch (nreglist.GetLength()) {
16925            default:
16926              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16927            case 1:
16928              len_encoding = 0x7;
16929              break;
16930            case 2:
16931              len_encoding = 0xa;
16932              break;
16933            case 3:
16934              len_encoding = 0x6;
16935              break;
16936            case 4:
16937              len_encoding = 0x2;
16938              break;
16939          }
16940          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
16941                  (encoded_align_1.GetEncodingValue() << 4) |
16942                  first.Encode(22, 12) | (len_encoding << 8) |
16943                  (rn.GetCode() << 16));
16944          return;
16945        }
16946      }
16947      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
16948      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16949          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16950          operand.IsOffset() && encoded_align_2.IsValid() &&
16951          ((!rn.IsPC()) || AllowUnpredictable())) {
16952        if (cond.Is(al)) {
16953          const DRegister& first = nreglist.GetFirstDRegister();
16954          uint32_t len_encoding = nreglist.GetLength() - 1;
16955          EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
16956                  (encoded_align_2.GetEncodingValue() << 4) |
16957                  first.Encode(22, 12) | (len_encoding << 5) |
16958                  (rn.GetCode() << 16));
16959          return;
16960        }
16961      }
16962      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
16963      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16964          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16965          operand.IsPostIndex() && encoded_align_2.IsValid() &&
16966          ((!rn.IsPC()) || AllowUnpredictable())) {
16967        if (cond.Is(al)) {
16968          const DRegister& first = nreglist.GetFirstDRegister();
16969          uint32_t len_encoding = nreglist.GetLength() - 1;
16970          EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
16971                  (encoded_align_2.GetEncodingValue() << 4) |
16972                  first.Encode(22, 12) | (len_encoding << 5) |
16973                  (rn.GetCode() << 16));
16974          return;
16975        }
16976      }
16977      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
16978      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16979          (nreglist.GetLength() == 1) && operand.IsOffset() &&
16980          encoded_align_3.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
16981        if (cond.Is(al)) {
16982          const DRegister& first = nreglist.GetFirstDRegister();
16983          EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
16984                  (encoded_align_3.GetEncodingValue() << 4) |
16985                  first.Encode(22, 12) | (rn.GetCode() << 16));
16986          return;
16987        }
16988      }
16989      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
16990      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16991          (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
16992          encoded_align_3.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
16993        if (cond.Is(al)) {
16994          const DRegister& first = nreglist.GetFirstDRegister();
16995          EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
16996                  (encoded_align_3.GetEncodingValue() << 4) |
16997                  first.Encode(22, 12) | (rn.GetCode() << 16));
16998          return;
16999        }
17000      }
17001    }
17002  }
17003  if (operand.IsPlainRegister()) {
17004    Register rn = operand.GetBaseRegister();
17005    Alignment align = operand.GetAlignment();
17006    Register rm = operand.GetOffsetRegister();
17007    Dt_size_6 encoded_dt(dt);
17008    Dt_size_7 encoded_dt_2(dt);
17009    Align_align_1 encoded_align_1(align, nreglist);
17010    Align_a_1 encoded_align_2(align, dt);
17011    Align_index_align_1 encoded_align_3(align, nreglist, dt);
17012    if (IsUsingT32()) {
17013      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17014      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17015          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
17016          !rm.IsPC() && !rm.IsSP()) {
17017        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17018          const DRegister& first = nreglist.GetFirstDRegister();
17019          uint32_t len_encoding;
17020          switch (nreglist.GetLength()) {
17021            default:
17022              VIXL_UNREACHABLE_OR_FALLTHROUGH();
17023            case 1:
17024              len_encoding = 0x7;
17025              break;
17026            case 2:
17027              len_encoding = 0xa;
17028              break;
17029            case 3:
17030              len_encoding = 0x6;
17031              break;
17032            case 4:
17033              len_encoding = 0x2;
17034              break;
17035          }
17036          EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
17037                     (encoded_align_1.GetEncodingValue() << 4) |
17038                     first.Encode(22, 12) | (len_encoding << 8) |
17039                     (rn.GetCode() << 16) | rm.GetCode());
17040          AdvanceIT();
17041          return;
17042        }
17043      }
17044      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17045      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17046          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
17047          !rm.IsPC() && !rm.IsSP()) {
17048        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17049          const DRegister& first = nreglist.GetFirstDRegister();
17050          uint32_t len_encoding = nreglist.GetLength() - 1;
17051          EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
17052                     (encoded_align_2.GetEncodingValue() << 4) |
17053                     first.Encode(22, 12) | (len_encoding << 5) |
17054                     (rn.GetCode() << 16) | rm.GetCode());
17055          AdvanceIT();
17056          return;
17057        }
17058      }
17059      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17060      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
17061          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
17062        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17063          const DRegister& first = nreglist.GetFirstDRegister();
17064          EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
17065                     (encoded_align_3.GetEncodingValue() << 4) |
17066                     first.Encode(22, 12) | (rn.GetCode() << 16) |
17067                     rm.GetCode());
17068          AdvanceIT();
17069          return;
17070        }
17071      }
17072    } else {
17073      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17074      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17075          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
17076          !rm.IsPC() && !rm.IsSP()) {
17077        if (cond.Is(al)) {
17078          const DRegister& first = nreglist.GetFirstDRegister();
17079          uint32_t len_encoding;
17080          switch (nreglist.GetLength()) {
17081            default:
17082              VIXL_UNREACHABLE_OR_FALLTHROUGH();
17083            case 1:
17084              len_encoding = 0x7;
17085              break;
17086            case 2:
17087              len_encoding = 0xa;
17088              break;
17089            case 3:
17090              len_encoding = 0x6;
17091              break;
17092            case 4:
17093              len_encoding = 0x2;
17094              break;
17095          }
17096          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17097                  (encoded_align_1.GetEncodingValue() << 4) |
17098                  first.Encode(22, 12) | (len_encoding << 8) |
17099                  (rn.GetCode() << 16) | rm.GetCode());
17100          return;
17101        }
17102      }
17103      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17104      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17105          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
17106          !rm.IsPC() && !rm.IsSP()) {
17107        if (cond.Is(al)) {
17108          const DRegister& first = nreglist.GetFirstDRegister();
17109          uint32_t len_encoding = nreglist.GetLength() - 1;
17110          EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
17111                  (encoded_align_2.GetEncodingValue() << 4) |
17112                  first.Encode(22, 12) | (len_encoding << 5) |
17113                  (rn.GetCode() << 16) | rm.GetCode());
17114          return;
17115        }
17116      }
17117      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17118      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
17119          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
17120        if (cond.Is(al)) {
17121          const DRegister& first = nreglist.GetFirstDRegister();
17122          EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
17123                  (encoded_align_3.GetEncodingValue() << 4) |
17124                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17125          return;
17126        }
17127      }
17128    }
17129  }
17130  Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand);
17131}
17132
17133void Assembler::vld2(Condition cond,
17134                     DataType dt,
17135                     const NeonRegisterList& nreglist,
17136                     const AlignedMemOperand& operand) {
17137  VIXL_ASSERT(AllowAssembler());
17138  CheckIT(cond);
17139  if (operand.IsImmediateZero()) {
17140    Register rn = operand.GetBaseRegister();
17141    Alignment align = operand.GetAlignment();
17142    Dt_size_7 encoded_dt(dt);
17143    Align_align_2 encoded_align_1(align, nreglist);
17144    Align_a_2 encoded_align_2(align, dt);
17145    Align_index_align_2 encoded_align_3(align, nreglist, dt);
17146    if (IsUsingT32()) {
17147      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17148      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17149          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17150           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17151           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17152          operand.IsOffset() && encoded_align_1.IsValid() &&
17153          ((!rn.IsPC()) || AllowUnpredictable())) {
17154        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17155          const DRegister& first = nreglist.GetFirstDRegister();
17156          uint32_t len_encoding;
17157          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17158            len_encoding = 0x8;
17159          }
17160          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17161            len_encoding = 0x9;
17162          }
17163          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17164            len_encoding = 0x3;
17165          }
17166          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
17167                     (encoded_align_1.GetEncodingValue() << 4) |
17168                     first.Encode(22, 12) | (len_encoding << 8) |
17169                     (rn.GetCode() << 16));
17170          AdvanceIT();
17171          return;
17172        }
17173      }
17174      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17175      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17176          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17177           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17178           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17179          operand.IsPostIndex() && encoded_align_1.IsValid() &&
17180          ((!rn.IsPC()) || AllowUnpredictable())) {
17181        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17182          const DRegister& first = nreglist.GetFirstDRegister();
17183          uint32_t len_encoding;
17184          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17185            len_encoding = 0x8;
17186          }
17187          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17188            len_encoding = 0x9;
17189          }
17190          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17191            len_encoding = 0x3;
17192          }
17193          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
17194                     (encoded_align_1.GetEncodingValue() << 4) |
17195                     first.Encode(22, 12) | (len_encoding << 8) |
17196                     (rn.GetCode() << 16));
17197          AdvanceIT();
17198          return;
17199        }
17200      }
17201      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17202      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17203          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17204           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17205          operand.IsOffset() && encoded_align_2.IsValid() &&
17206          ((!rn.IsPC()) || AllowUnpredictable())) {
17207        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17208          const DRegister& first = nreglist.GetFirstDRegister();
17209          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17210          EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
17211                     (encoded_align_2.GetEncodingValue() << 4) |
17212                     first.Encode(22, 12) | (len_encoding << 5) |
17213                     (rn.GetCode() << 16));
17214          AdvanceIT();
17215          return;
17216        }
17217      }
17218      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17219      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17220          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17221           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17222          operand.IsPostIndex() && encoded_align_2.IsValid() &&
17223          ((!rn.IsPC()) || AllowUnpredictable())) {
17224        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17225          const DRegister& first = nreglist.GetFirstDRegister();
17226          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17227          EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
17228                     (encoded_align_2.GetEncodingValue() << 4) |
17229                     first.Encode(22, 12) | (len_encoding << 5) |
17230                     (rn.GetCode() << 16));
17231          AdvanceIT();
17232          return;
17233        }
17234      }
17235      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17236      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17237          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17238           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17239          operand.IsOffset() && encoded_align_3.IsValid() &&
17240          ((!rn.IsPC()) || AllowUnpredictable())) {
17241        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17242          const DRegister& first = nreglist.GetFirstDRegister();
17243          EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) |
17244                     (encoded_align_3.GetEncodingValue() << 4) |
17245                     first.Encode(22, 12) | (rn.GetCode() << 16));
17246          AdvanceIT();
17247          return;
17248        }
17249      }
17250      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17251      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17252          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17253           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17254          operand.IsPostIndex() && encoded_align_3.IsValid() &&
17255          ((!rn.IsPC()) || AllowUnpredictable())) {
17256        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17257          const DRegister& first = nreglist.GetFirstDRegister();
17258          EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) |
17259                     (encoded_align_3.GetEncodingValue() << 4) |
17260                     first.Encode(22, 12) | (rn.GetCode() << 16));
17261          AdvanceIT();
17262          return;
17263        }
17264      }
17265    } else {
17266      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17267      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17268          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17269           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17270           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17271          operand.IsOffset() && encoded_align_1.IsValid() &&
17272          ((!rn.IsPC()) || AllowUnpredictable())) {
17273        if (cond.Is(al)) {
17274          const DRegister& first = nreglist.GetFirstDRegister();
17275          uint32_t len_encoding;
17276          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17277            len_encoding = 0x8;
17278          }
17279          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17280            len_encoding = 0x9;
17281          }
17282          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17283            len_encoding = 0x3;
17284          }
17285          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
17286                  (encoded_align_1.GetEncodingValue() << 4) |
17287                  first.Encode(22, 12) | (len_encoding << 8) |
17288                  (rn.GetCode() << 16));
17289          return;
17290        }
17291      }
17292      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17293      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17294          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17295           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17296           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17297          operand.IsPostIndex() && encoded_align_1.IsValid() &&
17298          ((!rn.IsPC()) || AllowUnpredictable())) {
17299        if (cond.Is(al)) {
17300          const DRegister& first = nreglist.GetFirstDRegister();
17301          uint32_t len_encoding;
17302          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17303            len_encoding = 0x8;
17304          }
17305          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17306            len_encoding = 0x9;
17307          }
17308          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17309            len_encoding = 0x3;
17310          }
17311          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17312                  (encoded_align_1.GetEncodingValue() << 4) |
17313                  first.Encode(22, 12) | (len_encoding << 8) |
17314                  (rn.GetCode() << 16));
17315          return;
17316        }
17317      }
17318      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17319      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17320          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17321           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17322          operand.IsOffset() && encoded_align_2.IsValid() &&
17323          ((!rn.IsPC()) || AllowUnpredictable())) {
17324        if (cond.Is(al)) {
17325          const DRegister& first = nreglist.GetFirstDRegister();
17326          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17327          EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
17328                  (encoded_align_2.GetEncodingValue() << 4) |
17329                  first.Encode(22, 12) | (len_encoding << 5) |
17330                  (rn.GetCode() << 16));
17331          return;
17332        }
17333      }
17334      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17335      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17336          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17337           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17338          operand.IsPostIndex() && encoded_align_2.IsValid() &&
17339          ((!rn.IsPC()) || AllowUnpredictable())) {
17340        if (cond.Is(al)) {
17341          const DRegister& first = nreglist.GetFirstDRegister();
17342          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17343          EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
17344                  (encoded_align_2.GetEncodingValue() << 4) |
17345                  first.Encode(22, 12) | (len_encoding << 5) |
17346                  (rn.GetCode() << 16));
17347          return;
17348        }
17349      }
17350      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17351      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17352          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17353           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17354          operand.IsOffset() && encoded_align_3.IsValid() &&
17355          ((!rn.IsPC()) || AllowUnpredictable())) {
17356        if (cond.Is(al)) {
17357          const DRegister& first = nreglist.GetFirstDRegister();
17358          EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) |
17359                  (encoded_align_3.GetEncodingValue() << 4) |
17360                  first.Encode(22, 12) | (rn.GetCode() << 16));
17361          return;
17362        }
17363      }
17364      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17365      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17366          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17367           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17368          operand.IsPostIndex() && encoded_align_3.IsValid() &&
17369          ((!rn.IsPC()) || AllowUnpredictable())) {
17370        if (cond.Is(al)) {
17371          const DRegister& first = nreglist.GetFirstDRegister();
17372          EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) |
17373                  (encoded_align_3.GetEncodingValue() << 4) |
17374                  first.Encode(22, 12) | (rn.GetCode() << 16));
17375          return;
17376        }
17377      }
17378    }
17379  }
17380  if (operand.IsPlainRegister()) {
17381    Register rn = operand.GetBaseRegister();
17382    Alignment align = operand.GetAlignment();
17383    Register rm = operand.GetOffsetRegister();
17384    Dt_size_7 encoded_dt(dt);
17385    Align_align_2 encoded_align_1(align, nreglist);
17386    Align_a_2 encoded_align_2(align, dt);
17387    Align_index_align_2 encoded_align_3(align, nreglist, dt);
17388    if (IsUsingT32()) {
17389      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17390      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17391          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17392           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17393           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17394          !rm.IsPC() && !rm.IsSP()) {
17395        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17396          const DRegister& first = nreglist.GetFirstDRegister();
17397          uint32_t len_encoding;
17398          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17399            len_encoding = 0x8;
17400          }
17401          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17402            len_encoding = 0x9;
17403          }
17404          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17405            len_encoding = 0x3;
17406          }
17407          EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
17408                     (encoded_align_1.GetEncodingValue() << 4) |
17409                     first.Encode(22, 12) | (len_encoding << 8) |
17410                     (rn.GetCode() << 16) | rm.GetCode());
17411          AdvanceIT();
17412          return;
17413        }
17414      }
17415      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17416      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17417          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17418           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17419          !rm.IsPC() && !rm.IsSP()) {
17420        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17421          const DRegister& first = nreglist.GetFirstDRegister();
17422          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17423          EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) |
17424                     (encoded_align_2.GetEncodingValue() << 4) |
17425                     first.Encode(22, 12) | (len_encoding << 5) |
17426                     (rn.GetCode() << 16) | rm.GetCode());
17427          AdvanceIT();
17428          return;
17429        }
17430      }
17431      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17432      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17433          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17434           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17435          !rm.IsPC() && !rm.IsSP()) {
17436        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17437          const DRegister& first = nreglist.GetFirstDRegister();
17438          EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) |
17439                     (encoded_align_3.GetEncodingValue() << 4) |
17440                     first.Encode(22, 12) | (rn.GetCode() << 16) |
17441                     rm.GetCode());
17442          AdvanceIT();
17443          return;
17444        }
17445      }
17446    } else {
17447      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17448      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17449          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17450           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17451           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17452          !rm.IsPC() && !rm.IsSP()) {
17453        if (cond.Is(al)) {
17454          const DRegister& first = nreglist.GetFirstDRegister();
17455          uint32_t len_encoding;
17456          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17457            len_encoding = 0x8;
17458          }
17459          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17460            len_encoding = 0x9;
17461          }
17462          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17463            len_encoding = 0x3;
17464          }
17465          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17466                  (encoded_align_1.GetEncodingValue() << 4) |
17467                  first.Encode(22, 12) | (len_encoding << 8) |
17468                  (rn.GetCode() << 16) | rm.GetCode());
17469          return;
17470        }
17471      }
17472      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17473      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17474          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17475           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17476          !rm.IsPC() && !rm.IsSP()) {
17477        if (cond.Is(al)) {
17478          const DRegister& first = nreglist.GetFirstDRegister();
17479          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17480          EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) |
17481                  (encoded_align_2.GetEncodingValue() << 4) |
17482                  first.Encode(22, 12) | (len_encoding << 5) |
17483                  (rn.GetCode() << 16) | rm.GetCode());
17484          return;
17485        }
17486      }
17487      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17488      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17489          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17490           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17491          !rm.IsPC() && !rm.IsSP()) {
17492        if (cond.Is(al)) {
17493          const DRegister& first = nreglist.GetFirstDRegister();
17494          EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) |
17495                  (encoded_align_3.GetEncodingValue() << 4) |
17496                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17497          return;
17498        }
17499      }
17500    }
17501  }
17502  Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand);
17503}
17504
17505void Assembler::vld3(Condition cond,
17506                     DataType dt,
17507                     const NeonRegisterList& nreglist,
17508                     const AlignedMemOperand& operand) {
17509  VIXL_ASSERT(AllowAssembler());
17510  CheckIT(cond);
17511  if (operand.IsImmediateZero()) {
17512    Register rn = operand.GetBaseRegister();
17513    Alignment align = operand.GetAlignment();
17514    Dt_size_7 encoded_dt(dt);
17515    Align_align_3 encoded_align_1(align);
17516    if (IsUsingT32()) {
17517      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17518      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17519          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17520           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17521          operand.IsOffset() && encoded_align_1.IsValid() &&
17522          ((!rn.IsPC()) || AllowUnpredictable())) {
17523        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17524          const DRegister& first = nreglist.GetFirstDRegister();
17525          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17526          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
17527                     (encoded_align_1.GetEncodingValue() << 4) |
17528                     first.Encode(22, 12) | (len_encoding << 8) |
17529                     (rn.GetCode() << 16));
17530          AdvanceIT();
17531          return;
17532        }
17533      }
17534      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17535      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17536          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17537           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17538          operand.IsPostIndex() && encoded_align_1.IsValid() &&
17539          ((!rn.IsPC()) || AllowUnpredictable())) {
17540        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17541          const DRegister& first = nreglist.GetFirstDRegister();
17542          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17543          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
17544                     (encoded_align_1.GetEncodingValue() << 4) |
17545                     first.Encode(22, 12) | (len_encoding << 8) |
17546                     (rn.GetCode() << 16));
17547          AdvanceIT();
17548          return;
17549        }
17550      }
17551    } else {
17552      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17553      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17554          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17555           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17556          operand.IsOffset() && encoded_align_1.IsValid() &&
17557          ((!rn.IsPC()) || AllowUnpredictable())) {
17558        if (cond.Is(al)) {
17559          const DRegister& first = nreglist.GetFirstDRegister();
17560          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17561          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
17562                  (encoded_align_1.GetEncodingValue() << 4) |
17563                  first.Encode(22, 12) | (len_encoding << 8) |
17564                  (rn.GetCode() << 16));
17565          return;
17566        }
17567      }
17568      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17569      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17570          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17571           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17572          operand.IsPostIndex() && encoded_align_1.IsValid() &&
17573          ((!rn.IsPC()) || AllowUnpredictable())) {
17574        if (cond.Is(al)) {
17575          const DRegister& first = nreglist.GetFirstDRegister();
17576          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17577          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17578                  (encoded_align_1.GetEncodingValue() << 4) |
17579                  first.Encode(22, 12) | (len_encoding << 8) |
17580                  (rn.GetCode() << 16));
17581          return;
17582        }
17583      }
17584    }
17585  }
17586  if (operand.IsPlainRegister()) {
17587    Register rn = operand.GetBaseRegister();
17588    Alignment align = operand.GetAlignment();
17589    Register rm = operand.GetOffsetRegister();
17590    Dt_size_7 encoded_dt(dt);
17591    Align_align_3 encoded_align_1(align);
17592    if (IsUsingT32()) {
17593      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17594      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17595          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17596           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17597          !rm.IsPC() && !rm.IsSP()) {
17598        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17599          const DRegister& first = nreglist.GetFirstDRegister();
17600          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17601          EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
17602                     (encoded_align_1.GetEncodingValue() << 4) |
17603                     first.Encode(22, 12) | (len_encoding << 8) |
17604                     (rn.GetCode() << 16) | rm.GetCode());
17605          AdvanceIT();
17606          return;
17607        }
17608      }
17609    } else {
17610      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17611      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17612          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17613           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17614          !rm.IsPC() && !rm.IsSP()) {
17615        if (cond.Is(al)) {
17616          const DRegister& first = nreglist.GetFirstDRegister();
17617          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17618          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17619                  (encoded_align_1.GetEncodingValue() << 4) |
17620                  first.Encode(22, 12) | (len_encoding << 8) |
17621                  (rn.GetCode() << 16) | rm.GetCode());
17622          return;
17623        }
17624      }
17625    }
17626  }
17627  Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
17628}
17629
17630void Assembler::vld3(Condition cond,
17631                     DataType dt,
17632                     const NeonRegisterList& nreglist,
17633                     const MemOperand& operand) {
17634  VIXL_ASSERT(AllowAssembler());
17635  CheckIT(cond);
17636  if (operand.IsImmediateZero()) {
17637    Register rn = operand.GetBaseRegister();
17638    Dt_size_7 encoded_dt(dt);
17639    Index_1 encoded_align_1(nreglist, dt);
17640    if (IsUsingT32()) {
17641      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
17642      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17643          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17644           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17645          operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
17646        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17647          const DRegister& first = nreglist.GetFirstDRegister();
17648          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17649          EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
17650                     first.Encode(22, 12) | (len_encoding << 5) |
17651                     (rn.GetCode() << 16));
17652          AdvanceIT();
17653          return;
17654        }
17655      }
17656      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
17657      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17658          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17659           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17660          operand.IsPreIndex() && ((!rn.IsPC()) || AllowUnpredictable())) {
17661        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17662          const DRegister& first = nreglist.GetFirstDRegister();
17663          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17664          EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
17665                     first.Encode(22, 12) | (len_encoding << 5) |
17666                     (rn.GetCode() << 16));
17667          AdvanceIT();
17668          return;
17669        }
17670      }
17671      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
17672      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17673          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17674           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17675          operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
17676        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17677          const DRegister& first = nreglist.GetFirstDRegister();
17678          EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) |
17679                     (encoded_align_1.GetEncodingValue() << 4) |
17680                     first.Encode(22, 12) | (rn.GetCode() << 16));
17681          AdvanceIT();
17682          return;
17683        }
17684      }
17685      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
17686      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17687          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17688           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17689          operand.IsPreIndex() && ((!rn.IsPC()) || AllowUnpredictable())) {
17690        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17691          const DRegister& first = nreglist.GetFirstDRegister();
17692          EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) |
17693                     (encoded_align_1.GetEncodingValue() << 4) |
17694                     first.Encode(22, 12) | (rn.GetCode() << 16));
17695          AdvanceIT();
17696          return;
17697        }
17698      }
17699    } else {
17700      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
17701      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17702          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17703           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17704          operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
17705        if (cond.Is(al)) {
17706          const DRegister& first = nreglist.GetFirstDRegister();
17707          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17708          EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
17709                  first.Encode(22, 12) | (len_encoding << 5) |
17710                  (rn.GetCode() << 16));
17711          return;
17712        }
17713      }
17714      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
17715      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17716          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17717           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17718          operand.IsPreIndex() && ((!rn.IsPC()) || AllowUnpredictable())) {
17719        if (cond.Is(al)) {
17720          const DRegister& first = nreglist.GetFirstDRegister();
17721          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17722          EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
17723                  first.Encode(22, 12) | (len_encoding << 5) |
17724                  (rn.GetCode() << 16));
17725          return;
17726        }
17727      }
17728      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
17729      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17730          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17731           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17732          operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
17733        if (cond.Is(al)) {
17734          const DRegister& first = nreglist.GetFirstDRegister();
17735          EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) |
17736                  (encoded_align_1.GetEncodingValue() << 4) |
17737                  first.Encode(22, 12) | (rn.GetCode() << 16));
17738          return;
17739        }
17740      }
17741      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
17742      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17743          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17744           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17745          operand.IsPreIndex() && ((!rn.IsPC()) || AllowUnpredictable())) {
17746        if (cond.Is(al)) {
17747          const DRegister& first = nreglist.GetFirstDRegister();
17748          EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) |
17749                  (encoded_align_1.GetEncodingValue() << 4) |
17750                  first.Encode(22, 12) | (rn.GetCode() << 16));
17751          return;
17752        }
17753      }
17754    }
17755  }
17756  if (operand.IsPlainRegister()) {
17757    Register rn = operand.GetBaseRegister();
17758    Sign sign = operand.GetSign();
17759    Register rm = operand.GetOffsetRegister();
17760    Dt_size_7 encoded_dt(dt);
17761    Index_1 encoded_align_1(nreglist, dt);
17762    if (IsUsingT32()) {
17763      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
17764      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17765          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17766           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17767          sign.IsPlus() && operand.IsPostIndex()) {
17768        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17769          const DRegister& first = nreglist.GetFirstDRegister();
17770          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17771          EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) |
17772                     first.Encode(22, 12) | (len_encoding << 5) |
17773                     (rn.GetCode() << 16) | rm.GetCode());
17774          AdvanceIT();
17775          return;
17776        }
17777      }
17778      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
17779      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17780          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17781           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17782          sign.IsPlus() && operand.IsPostIndex()) {
17783        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17784          const DRegister& first = nreglist.GetFirstDRegister();
17785          EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) |
17786                     (encoded_align_1.GetEncodingValue() << 4) |
17787                     first.Encode(22, 12) | (rn.GetCode() << 16) |
17788                     rm.GetCode());
17789          AdvanceIT();
17790          return;
17791        }
17792      }
17793    } else {
17794      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
17795      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17796          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17797           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17798          sign.IsPlus() && operand.IsPostIndex()) {
17799        if (cond.Is(al)) {
17800          const DRegister& first = nreglist.GetFirstDRegister();
17801          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17802          EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) |
17803                  first.Encode(22, 12) | (len_encoding << 5) |
17804                  (rn.GetCode() << 16) | rm.GetCode());
17805          return;
17806        }
17807      }
17808      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
17809      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17810          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17811           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17812          sign.IsPlus() && operand.IsPostIndex()) {
17813        if (cond.Is(al)) {
17814          const DRegister& first = nreglist.GetFirstDRegister();
17815          EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) |
17816                  (encoded_align_1.GetEncodingValue() << 4) |
17817                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17818          return;
17819        }
17820      }
17821    }
17822  }
17823  Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
17824}
17825
17826void Assembler::vld4(Condition cond,
17827                     DataType dt,
17828                     const NeonRegisterList& nreglist,
17829                     const AlignedMemOperand& operand) {
17830  VIXL_ASSERT(AllowAssembler());
17831  CheckIT(cond);
17832  if (operand.IsImmediateZero()) {
17833    Register rn = operand.GetBaseRegister();
17834    Alignment align = operand.GetAlignment();
17835    Dt_size_7 encoded_dt(dt);
17836    Dt_size_8 encoded_dt_2(dt, align);
17837    Align_align_4 encoded_align_1(align);
17838    Align_a_3 encoded_align_2(align, dt);
17839    Align_index_align_3 encoded_align_3(align, nreglist, dt);
17840    if (IsUsingT32()) {
17841      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17842      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17843          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17844           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17845          operand.IsOffset() && encoded_align_1.IsValid() &&
17846          ((!rn.IsPC()) || AllowUnpredictable())) {
17847        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17848          const DRegister& first = nreglist.GetFirstDRegister();
17849          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17850          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
17851                     (encoded_align_1.GetEncodingValue() << 4) |
17852                     first.Encode(22, 12) | (len_encoding << 8) |
17853                     (rn.GetCode() << 16));
17854          AdvanceIT();
17855          return;
17856        }
17857      }
17858      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17859      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17860          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17861           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17862          operand.IsPostIndex() && encoded_align_1.IsValid() &&
17863          ((!rn.IsPC()) || AllowUnpredictable())) {
17864        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17865          const DRegister& first = nreglist.GetFirstDRegister();
17866          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17867          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
17868                     (encoded_align_1.GetEncodingValue() << 4) |
17869                     first.Encode(22, 12) | (len_encoding << 8) |
17870                     (rn.GetCode() << 16));
17871          AdvanceIT();
17872          return;
17873        }
17874      }
17875      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17876      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17877          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17878           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17879          operand.IsOffset() && encoded_align_2.IsValid() &&
17880          ((!rn.IsPC()) || AllowUnpredictable())) {
17881        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17882          const DRegister& first = nreglist.GetFirstDRegister();
17883          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17884          EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
17885                     (encoded_align_2.GetEncodingValue() << 4) |
17886                     first.Encode(22, 12) | (len_encoding << 5) |
17887                     (rn.GetCode() << 16));
17888          AdvanceIT();
17889          return;
17890        }
17891      }
17892      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17893      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17894          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17895           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17896          operand.IsPostIndex() && encoded_align_2.IsValid() &&
17897          ((!rn.IsPC()) || AllowUnpredictable())) {
17898        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17899          const DRegister& first = nreglist.GetFirstDRegister();
17900          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17901          EmitT32_32(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
17902                     (encoded_align_2.GetEncodingValue() << 4) |
17903                     first.Encode(22, 12) | (len_encoding << 5) |
17904                     (rn.GetCode() << 16));
17905          AdvanceIT();
17906          return;
17907        }
17908      }
17909      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17910      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17911          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17912           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17913          operand.IsOffset() && encoded_align_3.IsValid() &&
17914          ((!rn.IsPC()) || AllowUnpredictable())) {
17915        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17916          const DRegister& first = nreglist.GetFirstDRegister();
17917          EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) |
17918                     (encoded_align_3.GetEncodingValue() << 4) |
17919                     first.Encode(22, 12) | (rn.GetCode() << 16));
17920          AdvanceIT();
17921          return;
17922        }
17923      }
17924      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17925      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17926          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17927           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17928          operand.IsPostIndex() && encoded_align_3.IsValid() &&
17929          ((!rn.IsPC()) || AllowUnpredictable())) {
17930        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17931          const DRegister& first = nreglist.GetFirstDRegister();
17932          EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) |
17933                     (encoded_align_3.GetEncodingValue() << 4) |
17934                     first.Encode(22, 12) | (rn.GetCode() << 16));
17935          AdvanceIT();
17936          return;
17937        }
17938      }
17939    } else {
17940      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17941      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17942          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17943           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17944          operand.IsOffset() && encoded_align_1.IsValid() &&
17945          ((!rn.IsPC()) || AllowUnpredictable())) {
17946        if (cond.Is(al)) {
17947          const DRegister& first = nreglist.GetFirstDRegister();
17948          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17949          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
17950                  (encoded_align_1.GetEncodingValue() << 4) |
17951                  first.Encode(22, 12) | (len_encoding << 8) |
17952                  (rn.GetCode() << 16));
17953          return;
17954        }
17955      }
17956      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17957      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17958          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17959           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17960          operand.IsPostIndex() && encoded_align_1.IsValid() &&
17961          ((!rn.IsPC()) || AllowUnpredictable())) {
17962        if (cond.Is(al)) {
17963          const DRegister& first = nreglist.GetFirstDRegister();
17964          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17965          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17966                  (encoded_align_1.GetEncodingValue() << 4) |
17967                  first.Encode(22, 12) | (len_encoding << 8) |
17968                  (rn.GetCode() << 16));
17969          return;
17970        }
17971      }
17972      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17973      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17974          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17975           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17976          operand.IsOffset() && encoded_align_2.IsValid() &&
17977          ((!rn.IsPC()) || AllowUnpredictable())) {
17978        if (cond.Is(al)) {
17979          const DRegister& first = nreglist.GetFirstDRegister();
17980          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17981          EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
17982                  (encoded_align_2.GetEncodingValue() << 4) |
17983                  first.Encode(22, 12) | (len_encoding << 5) |
17984                  (rn.GetCode() << 16));
17985          return;
17986        }
17987      }
17988      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17989      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17990          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17991           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17992          operand.IsPostIndex() && encoded_align_2.IsValid() &&
17993          ((!rn.IsPC()) || AllowUnpredictable())) {
17994        if (cond.Is(al)) {
17995          const DRegister& first = nreglist.GetFirstDRegister();
17996          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17997          EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
17998                  (encoded_align_2.GetEncodingValue() << 4) |
17999                  first.Encode(22, 12) | (len_encoding << 5) |
18000                  (rn.GetCode() << 16));
18001          return;
18002        }
18003      }
18004      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18005      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18006          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18007           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18008          operand.IsOffset() && encoded_align_3.IsValid() &&
18009          ((!rn.IsPC()) || AllowUnpredictable())) {
18010        if (cond.Is(al)) {
18011          const DRegister& first = nreglist.GetFirstDRegister();
18012          EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) |
18013                  (encoded_align_3.GetEncodingValue() << 4) |
18014                  first.Encode(22, 12) | (rn.GetCode() << 16));
18015          return;
18016        }
18017      }
18018      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18019      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18020          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18021           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18022          operand.IsPostIndex() && encoded_align_3.IsValid() &&
18023          ((!rn.IsPC()) || AllowUnpredictable())) {
18024        if (cond.Is(al)) {
18025          const DRegister& first = nreglist.GetFirstDRegister();
18026          EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) |
18027                  (encoded_align_3.GetEncodingValue() << 4) |
18028                  first.Encode(22, 12) | (rn.GetCode() << 16));
18029          return;
18030        }
18031      }
18032    }
18033  }
18034  if (operand.IsPlainRegister()) {
18035    Register rn = operand.GetBaseRegister();
18036    Alignment align = operand.GetAlignment();
18037    Register rm = operand.GetOffsetRegister();
18038    Dt_size_7 encoded_dt(dt);
18039    Dt_size_8 encoded_dt_2(dt, align);
18040    Align_align_4 encoded_align_1(align);
18041    Align_a_3 encoded_align_2(align, dt);
18042    Align_index_align_3 encoded_align_3(align, nreglist, dt);
18043    if (IsUsingT32()) {
18044      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18045      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18046          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18047           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18048          !rm.IsPC() && !rm.IsSP()) {
18049        if (cond.Is(al) || AllowStronglyDiscouraged()) {
18050          const DRegister& first = nreglist.GetFirstDRegister();
18051          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18052          EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
18053                     (encoded_align_1.GetEncodingValue() << 4) |
18054                     first.Encode(22, 12) | (len_encoding << 8) |
18055                     (rn.GetCode() << 16) | rm.GetCode());
18056          AdvanceIT();
18057          return;
18058        }
18059      }
18060      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18061      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18062          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18063           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18064          !rm.IsPC() && !rm.IsSP()) {
18065        if (cond.Is(al) || AllowStronglyDiscouraged()) {
18066          const DRegister& first = nreglist.GetFirstDRegister();
18067          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18068          EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
18069                     (encoded_align_2.GetEncodingValue() << 4) |
18070                     first.Encode(22, 12) | (len_encoding << 5) |
18071                     (rn.GetCode() << 16) | rm.GetCode());
18072          AdvanceIT();
18073          return;
18074        }
18075      }
18076      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18077      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18078          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18079           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18080          !rm.IsPC() && !rm.IsSP()) {
18081        if (cond.Is(al) || AllowStronglyDiscouraged()) {
18082          const DRegister& first = nreglist.GetFirstDRegister();
18083          EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) |
18084                     (encoded_align_3.GetEncodingValue() << 4) |
18085                     first.Encode(22, 12) | (rn.GetCode() << 16) |
18086                     rm.GetCode());
18087          AdvanceIT();
18088          return;
18089        }
18090      }
18091    } else {
18092      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18093      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18094          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18095           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18096          !rm.IsPC() && !rm.IsSP()) {
18097        if (cond.Is(al)) {
18098          const DRegister& first = nreglist.GetFirstDRegister();
18099          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18100          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
18101                  (encoded_align_1.GetEncodingValue() << 4) |
18102                  first.Encode(22, 12) | (len_encoding << 8) |
18103                  (rn.GetCode() << 16) | rm.GetCode());
18104          return;
18105        }
18106      }
18107      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18108      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18109          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18110           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18111          !rm.IsPC() && !rm.IsSP()) {
18112        if (cond.Is(al)) {
18113          const DRegister& first = nreglist.GetFirstDRegister();
18114          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18115          EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
18116                  (encoded_align_2.GetEncodingValue() << 4) |
18117                  first.Encode(22, 12) | (len_encoding << 5) |
18118                  (rn.GetCode() << 16) | rm.GetCode());
18119          return;
18120        }
18121      }
18122      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18123      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18124          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18125           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18126          !rm.IsPC() && !rm.IsSP()) {
18127        if (cond.Is(al)) {
18128          const DRegister& first = nreglist.GetFirstDRegister();
18129          EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) |
18130                  (encoded_align_3.GetEncodingValue() << 4) |
18131                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
18132          return;
18133        }
18134      }
18135    }
18136  }
18137  Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand);
18138}
18139
18140void Assembler::vldm(Condition cond,
18141                     DataType dt,
18142                     Register rn,
18143                     WriteBack write_back,
18144                     DRegisterList dreglist) {
18145  VIXL_ASSERT(AllowAssembler());
18146  CheckIT(cond);
18147  USE(dt);
18148  if (IsUsingT32()) {
18149    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
18150    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
18151      const DRegister& dreg = dreglist.GetFirstDRegister();
18152      unsigned len = dreglist.GetLength() * 2;
18153      EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
18154                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18155                 (len & 0xff));
18156      AdvanceIT();
18157      return;
18158    }
18159  } else {
18160    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
18161    if (cond.IsNotNever() &&
18162        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
18163      const DRegister& dreg = dreglist.GetFirstDRegister();
18164      unsigned len = dreglist.GetLength() * 2;
18165      EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18166              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18167              (len & 0xff));
18168      return;
18169    }
18170  }
18171  Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist);
18172}
18173
18174void Assembler::vldm(Condition cond,
18175                     DataType dt,
18176                     Register rn,
18177                     WriteBack write_back,
18178                     SRegisterList sreglist) {
18179  VIXL_ASSERT(AllowAssembler());
18180  CheckIT(cond);
18181  USE(dt);
18182  if (IsUsingT32()) {
18183    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
18184    const SRegister& sreg = sreglist.GetFirstSRegister();
18185    unsigned len = sreglist.GetLength();
18186    EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
18187               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18188               (len & 0xff));
18189    AdvanceIT();
18190    return;
18191  } else {
18192    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
18193    if (cond.IsNotNever()) {
18194      const SRegister& sreg = sreglist.GetFirstSRegister();
18195      unsigned len = sreglist.GetLength();
18196      EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18197              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18198              (len & 0xff));
18199      return;
18200    }
18201  }
18202  Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist);
18203}
18204
18205void Assembler::vldmdb(Condition cond,
18206                       DataType dt,
18207                       Register rn,
18208                       WriteBack write_back,
18209                       DRegisterList dreglist) {
18210  VIXL_ASSERT(AllowAssembler());
18211  CheckIT(cond);
18212  USE(dt);
18213  if (IsUsingT32()) {
18214    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
18215    if (write_back.DoesWriteBack() &&
18216        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
18217      const DRegister& dreg = dreglist.GetFirstDRegister();
18218      unsigned len = dreglist.GetLength() * 2;
18219      EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
18220                 (len & 0xff));
18221      AdvanceIT();
18222      return;
18223    }
18224  } else {
18225    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
18226    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
18227        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
18228      const DRegister& dreg = dreglist.GetFirstDRegister();
18229      unsigned len = dreglist.GetLength() * 2;
18230      EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18231              dreg.Encode(22, 12) | (len & 0xff));
18232      return;
18233    }
18234  }
18235  Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist);
18236}
18237
18238void Assembler::vldmdb(Condition cond,
18239                       DataType dt,
18240                       Register rn,
18241                       WriteBack write_back,
18242                       SRegisterList sreglist) {
18243  VIXL_ASSERT(AllowAssembler());
18244  CheckIT(cond);
18245  USE(dt);
18246  if (IsUsingT32()) {
18247    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
18248    if (write_back.DoesWriteBack()) {
18249      const SRegister& sreg = sreglist.GetFirstSRegister();
18250      unsigned len = sreglist.GetLength();
18251      EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
18252                 (len & 0xff));
18253      AdvanceIT();
18254      return;
18255    }
18256  } else {
18257    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
18258    if (write_back.DoesWriteBack() && cond.IsNotNever()) {
18259      const SRegister& sreg = sreglist.GetFirstSRegister();
18260      unsigned len = sreglist.GetLength();
18261      EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18262              sreg.Encode(22, 12) | (len & 0xff));
18263      return;
18264    }
18265  }
18266  Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist);
18267}
18268
18269void Assembler::vldmia(Condition cond,
18270                       DataType dt,
18271                       Register rn,
18272                       WriteBack write_back,
18273                       DRegisterList dreglist) {
18274  VIXL_ASSERT(AllowAssembler());
18275  CheckIT(cond);
18276  USE(dt);
18277  if (IsUsingT32()) {
18278    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
18279    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
18280      const DRegister& dreg = dreglist.GetFirstDRegister();
18281      unsigned len = dreglist.GetLength() * 2;
18282      EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
18283                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18284                 (len & 0xff));
18285      AdvanceIT();
18286      return;
18287    }
18288  } else {
18289    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
18290    if (cond.IsNotNever() &&
18291        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
18292      const DRegister& dreg = dreglist.GetFirstDRegister();
18293      unsigned len = dreglist.GetLength() * 2;
18294      EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18295              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18296              (len & 0xff));
18297      return;
18298    }
18299  }
18300  Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist);
18301}
18302
18303void Assembler::vldmia(Condition cond,
18304                       DataType dt,
18305                       Register rn,
18306                       WriteBack write_back,
18307                       SRegisterList sreglist) {
18308  VIXL_ASSERT(AllowAssembler());
18309  CheckIT(cond);
18310  USE(dt);
18311  if (IsUsingT32()) {
18312    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
18313    const SRegister& sreg = sreglist.GetFirstSRegister();
18314    unsigned len = sreglist.GetLength();
18315    EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
18316               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18317               (len & 0xff));
18318    AdvanceIT();
18319    return;
18320  } else {
18321    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
18322    if (cond.IsNotNever()) {
18323      const SRegister& sreg = sreglist.GetFirstSRegister();
18324      unsigned len = sreglist.GetLength();
18325      EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18326              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18327              (len & 0xff));
18328      return;
18329    }
18330  }
18331  Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist);
18332}
18333
18334void Assembler::vldr(Condition cond, DataType dt, DRegister rd, Label* label) {
18335  VIXL_ASSERT(AllowAssembler());
18336  CheckIT(cond);
18337  Label::Offset offset =
18338      label->IsBound()
18339          ? label->GetLocation() -
18340                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
18341          : 0;
18342  if (IsUsingT32()) {
18343    // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
18344    if (dt.IsNoneOr(Untyped64) &&
18345        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18346          ((offset & 0x3) == 0)) ||
18347         !label->IsBound())) {
18348      static class EmitOp : public Label::LabelEmitOperator {
18349       public:
18350        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18351        virtual uint32_t Encode(uint32_t instr,
18352                                Label::Offset pc,
18353                                const Label* label) const VIXL_OVERRIDE {
18354          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18355          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18356                      ((offset & 0x3) == 0));
18357          int32_t target = offset >> 2;
18358          uint32_t U = (target >= 0) && !label->IsMinusZero();
18359          target = abs(target) | (U << 8);
18360          return instr | (target & 0xff) | ((target & 0x100) << 15);
18361        }
18362      } immop;
18363      EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12), label, immop));
18364      AdvanceIT();
18365      return;
18366    }
18367  } else {
18368    // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
18369    if (dt.IsNoneOr(Untyped64) &&
18370        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18371          ((offset & 0x3) == 0)) ||
18372         !label->IsBound()) &&
18373        cond.IsNotNever()) {
18374      static class EmitOp : public Label::LabelEmitOperator {
18375       public:
18376        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18377        virtual uint32_t Encode(uint32_t instr,
18378                                Label::Offset pc,
18379                                const Label* label) const VIXL_OVERRIDE {
18380          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18381          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18382                      ((offset & 0x3) == 0));
18383          int32_t target = offset >> 2;
18384          uint32_t U = (target >= 0) && !label->IsMinusZero();
18385          target = abs(target) | (U << 8);
18386          return instr | (target & 0xff) | ((target & 0x100) << 15);
18387        }
18388      } immop;
18389      EmitA32(
18390          Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
18391               label,
18392               immop));
18393      return;
18394    }
18395  }
18396  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label);
18397}
18398
18399void Assembler::vldr(Condition cond,
18400                     DataType dt,
18401                     DRegister rd,
18402                     const MemOperand& operand) {
18403  VIXL_ASSERT(AllowAssembler());
18404  CheckIT(cond);
18405  if (operand.IsImmediate()) {
18406    Register rn = operand.GetBaseRegister();
18407    int32_t offset = operand.GetOffsetImmediate();
18408    if (IsUsingT32()) {
18409      // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1
18410      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18411          ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
18412        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18413        uint32_t offset_ = abs(offset) >> 2;
18414        EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23));
18415        AdvanceIT();
18416        return;
18417      }
18418      // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
18419      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18420          ((offset % 4) == 0) && operand.IsOffset() &&
18421          ((rn.GetCode() & 0xf) != 0xf)) {
18422        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18423        uint32_t offset_ = abs(offset) >> 2;
18424        EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
18425                   offset_ | (sign << 23));
18426        AdvanceIT();
18427        return;
18428      }
18429    } else {
18430      // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1
18431      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18432          ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
18433          cond.IsNotNever()) {
18434        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18435        uint32_t offset_ = abs(offset) >> 2;
18436        EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18437                offset_ | (sign << 23));
18438        return;
18439      }
18440      // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
18441      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18442          ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
18443          ((rn.GetCode() & 0xf) != 0xf)) {
18444        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18445        uint32_t offset_ = abs(offset) >> 2;
18446        EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18447                (rn.GetCode() << 16) | offset_ | (sign << 23));
18448        return;
18449      }
18450    }
18451  }
18452  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
18453}
18454
18455void Assembler::vldr(Condition cond, DataType dt, SRegister rd, Label* label) {
18456  VIXL_ASSERT(AllowAssembler());
18457  CheckIT(cond);
18458  Label::Offset offset =
18459      label->IsBound()
18460          ? label->GetLocation() -
18461                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
18462          : 0;
18463  if (IsUsingT32()) {
18464    // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
18465    if (dt.IsNoneOr(Untyped32) &&
18466        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18467          ((offset & 0x3) == 0)) ||
18468         !label->IsBound())) {
18469      static class EmitOp : public Label::LabelEmitOperator {
18470       public:
18471        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18472        virtual uint32_t Encode(uint32_t instr,
18473                                Label::Offset pc,
18474                                const Label* label) const VIXL_OVERRIDE {
18475          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18476          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18477                      ((offset & 0x3) == 0));
18478          int32_t target = offset >> 2;
18479          uint32_t U = (target >= 0) && !label->IsMinusZero();
18480          target = abs(target) | (U << 8);
18481          return instr | (target & 0xff) | ((target & 0x100) << 15);
18482        }
18483      } immop;
18484      EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12), label, immop));
18485      AdvanceIT();
18486      return;
18487    }
18488  } else {
18489    // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
18490    if (dt.IsNoneOr(Untyped32) &&
18491        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18492          ((offset & 0x3) == 0)) ||
18493         !label->IsBound()) &&
18494        cond.IsNotNever()) {
18495      static class EmitOp : public Label::LabelEmitOperator {
18496       public:
18497        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18498        virtual uint32_t Encode(uint32_t instr,
18499                                Label::Offset pc,
18500                                const Label* label) const VIXL_OVERRIDE {
18501          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18502          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18503                      ((offset & 0x3) == 0));
18504          int32_t target = offset >> 2;
18505          uint32_t U = (target >= 0) && !label->IsMinusZero();
18506          target = abs(target) | (U << 8);
18507          return instr | (target & 0xff) | ((target & 0x100) << 15);
18508        }
18509      } immop;
18510      EmitA32(
18511          Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
18512               label,
18513               immop));
18514      return;
18515    }
18516  }
18517  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label);
18518}
18519
18520void Assembler::vldr(Condition cond,
18521                     DataType dt,
18522                     SRegister rd,
18523                     const MemOperand& operand) {
18524  VIXL_ASSERT(AllowAssembler());
18525  CheckIT(cond);
18526  if (operand.IsImmediate()) {
18527    Register rn = operand.GetBaseRegister();
18528    int32_t offset = operand.GetOffsetImmediate();
18529    if (IsUsingT32()) {
18530      // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2
18531      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18532          ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
18533        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18534        uint32_t offset_ = abs(offset) >> 2;
18535        EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23));
18536        AdvanceIT();
18537        return;
18538      }
18539      // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
18540      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18541          ((offset % 4) == 0) && operand.IsOffset() &&
18542          ((rn.GetCode() & 0xf) != 0xf)) {
18543        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18544        uint32_t offset_ = abs(offset) >> 2;
18545        EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
18546                   offset_ | (sign << 23));
18547        AdvanceIT();
18548        return;
18549      }
18550    } else {
18551      // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2
18552      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18553          ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
18554          cond.IsNotNever()) {
18555        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18556        uint32_t offset_ = abs(offset) >> 2;
18557        EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18558                offset_ | (sign << 23));
18559        return;
18560      }
18561      // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
18562      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18563          ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
18564          ((rn.GetCode() & 0xf) != 0xf)) {
18565        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18566        uint32_t offset_ = abs(offset) >> 2;
18567        EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18568                (rn.GetCode() << 16) | offset_ | (sign << 23));
18569        return;
18570      }
18571    }
18572  }
18573  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
18574}
18575
18576void Assembler::vmax(
18577    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18578  VIXL_ASSERT(AllowAssembler());
18579  CheckIT(cond);
18580  Dt_U_size_1 encoded_dt(dt);
18581  if (IsUsingT32()) {
18582    // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
18583    if (dt.Is(F32)) {
18584      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18585        EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18586                   rm.Encode(5, 0));
18587        AdvanceIT();
18588        return;
18589      }
18590    }
18591    // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
18592    if (encoded_dt.IsValid()) {
18593      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18594        EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18595                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18596                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18597        AdvanceIT();
18598        return;
18599      }
18600    }
18601  } else {
18602    // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
18603    if (dt.Is(F32)) {
18604      if (cond.Is(al)) {
18605        EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18606                rm.Encode(5, 0));
18607        return;
18608      }
18609    }
18610    // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
18611    if (encoded_dt.IsValid()) {
18612      if (cond.Is(al)) {
18613        EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18614                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18615                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18616        return;
18617      }
18618    }
18619  }
18620  Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
18621}
18622
18623void Assembler::vmax(
18624    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18625  VIXL_ASSERT(AllowAssembler());
18626  CheckIT(cond);
18627  Dt_U_size_1 encoded_dt(dt);
18628  if (IsUsingT32()) {
18629    // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
18630    if (dt.Is(F32)) {
18631      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18632        EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18633                   rm.Encode(5, 0));
18634        AdvanceIT();
18635        return;
18636      }
18637    }
18638    // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
18639    if (encoded_dt.IsValid()) {
18640      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18641        EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18642                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18643                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18644        AdvanceIT();
18645        return;
18646      }
18647    }
18648  } else {
18649    // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
18650    if (dt.Is(F32)) {
18651      if (cond.Is(al)) {
18652        EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18653                rm.Encode(5, 0));
18654        return;
18655      }
18656    }
18657    // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
18658    if (encoded_dt.IsValid()) {
18659      if (cond.Is(al)) {
18660        EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18661                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18662                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18663        return;
18664      }
18665    }
18666  }
18667  Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
18668}
18669
18670void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18671  VIXL_ASSERT(AllowAssembler());
18672  CheckIT(al);
18673  if (IsUsingT32()) {
18674    // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
18675    if (OutsideITBlock() && dt.Is(F32)) {
18676      EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18677                 rm.Encode(5, 0));
18678      AdvanceIT();
18679      return;
18680    }
18681    // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
18682    if (OutsideITBlock() && dt.Is(F64)) {
18683      EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18684                 rm.Encode(5, 0));
18685      AdvanceIT();
18686      return;
18687    }
18688  } else {
18689    // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
18690    if (dt.Is(F32)) {
18691      EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18692              rm.Encode(5, 0));
18693      return;
18694    }
18695    // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
18696    if (dt.Is(F64)) {
18697      EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18698              rm.Encode(5, 0));
18699      return;
18700    }
18701  }
18702  Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18703}
18704
18705void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18706  VIXL_ASSERT(AllowAssembler());
18707  CheckIT(al);
18708  if (IsUsingT32()) {
18709    // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
18710    if (OutsideITBlock() && dt.Is(F32)) {
18711      EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18712                 rm.Encode(5, 0));
18713      AdvanceIT();
18714      return;
18715    }
18716  } else {
18717    // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
18718    if (dt.Is(F32)) {
18719      EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18720              rm.Encode(5, 0));
18721      return;
18722    }
18723  }
18724  Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18725}
18726
18727void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
18728  VIXL_ASSERT(AllowAssembler());
18729  CheckIT(al);
18730  if (IsUsingT32()) {
18731    // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
18732    if (OutsideITBlock() && dt.Is(F32)) {
18733      EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18734                 rm.Encode(5, 0));
18735      AdvanceIT();
18736      return;
18737    }
18738  } else {
18739    // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
18740    if (dt.Is(F32)) {
18741      EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18742              rm.Encode(5, 0));
18743      return;
18744    }
18745  }
18746  Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18747}
18748
18749void Assembler::vmin(
18750    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18751  VIXL_ASSERT(AllowAssembler());
18752  CheckIT(cond);
18753  Dt_U_size_1 encoded_dt(dt);
18754  if (IsUsingT32()) {
18755    // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
18756    if (dt.Is(F32)) {
18757      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18758        EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18759                   rm.Encode(5, 0));
18760        AdvanceIT();
18761        return;
18762      }
18763    }
18764    // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
18765    if (encoded_dt.IsValid()) {
18766      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18767        EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18768                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18769                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18770        AdvanceIT();
18771        return;
18772      }
18773    }
18774  } else {
18775    // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
18776    if (dt.Is(F32)) {
18777      if (cond.Is(al)) {
18778        EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18779                rm.Encode(5, 0));
18780        return;
18781      }
18782    }
18783    // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
18784    if (encoded_dt.IsValid()) {
18785      if (cond.Is(al)) {
18786        EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18787                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18788                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18789        return;
18790      }
18791    }
18792  }
18793  Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
18794}
18795
18796void Assembler::vmin(
18797    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18798  VIXL_ASSERT(AllowAssembler());
18799  CheckIT(cond);
18800  Dt_U_size_1 encoded_dt(dt);
18801  if (IsUsingT32()) {
18802    // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
18803    if (dt.Is(F32)) {
18804      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18805        EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18806                   rm.Encode(5, 0));
18807        AdvanceIT();
18808        return;
18809      }
18810    }
18811    // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
18812    if (encoded_dt.IsValid()) {
18813      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18814        EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18815                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18816                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18817        AdvanceIT();
18818        return;
18819      }
18820    }
18821  } else {
18822    // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
18823    if (dt.Is(F32)) {
18824      if (cond.Is(al)) {
18825        EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18826                rm.Encode(5, 0));
18827        return;
18828      }
18829    }
18830    // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
18831    if (encoded_dt.IsValid()) {
18832      if (cond.Is(al)) {
18833        EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18834                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18835                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18836        return;
18837      }
18838    }
18839  }
18840  Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
18841}
18842
18843void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18844  VIXL_ASSERT(AllowAssembler());
18845  CheckIT(al);
18846  if (IsUsingT32()) {
18847    // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
18848    if (OutsideITBlock() && dt.Is(F32)) {
18849      EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18850                 rm.Encode(5, 0));
18851      AdvanceIT();
18852      return;
18853    }
18854    // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
18855    if (OutsideITBlock() && dt.Is(F64)) {
18856      EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18857                 rm.Encode(5, 0));
18858      AdvanceIT();
18859      return;
18860    }
18861  } else {
18862    // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
18863    if (dt.Is(F32)) {
18864      EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18865              rm.Encode(5, 0));
18866      return;
18867    }
18868    // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
18869    if (dt.Is(F64)) {
18870      EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18871              rm.Encode(5, 0));
18872      return;
18873    }
18874  }
18875  Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18876}
18877
18878void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18879  VIXL_ASSERT(AllowAssembler());
18880  CheckIT(al);
18881  if (IsUsingT32()) {
18882    // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
18883    if (OutsideITBlock() && dt.Is(F32)) {
18884      EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18885                 rm.Encode(5, 0));
18886      AdvanceIT();
18887      return;
18888    }
18889  } else {
18890    // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
18891    if (dt.Is(F32)) {
18892      EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18893              rm.Encode(5, 0));
18894      return;
18895    }
18896  }
18897  Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18898}
18899
18900void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
18901  VIXL_ASSERT(AllowAssembler());
18902  CheckIT(al);
18903  if (IsUsingT32()) {
18904    // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
18905    if (OutsideITBlock() && dt.Is(F32)) {
18906      EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18907                 rm.Encode(5, 0));
18908      AdvanceIT();
18909      return;
18910    }
18911  } else {
18912    // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
18913    if (dt.Is(F32)) {
18914      EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18915              rm.Encode(5, 0));
18916      return;
18917    }
18918  }
18919  Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18920}
18921
18922void Assembler::vmla(
18923    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
18924  VIXL_ASSERT(AllowAssembler());
18925  CheckIT(cond);
18926  Dt_size_9 encoded_dt(dt);
18927  if (IsUsingT32()) {
18928    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
18929    if (encoded_dt.IsValid() &&
18930        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18931         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18932          (rm.GetLane() <= 1)))) {
18933      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18934        EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
18935                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18936                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18937        AdvanceIT();
18938        return;
18939      }
18940    }
18941  } else {
18942    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
18943    if (encoded_dt.IsValid() &&
18944        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18945         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18946          (rm.GetLane() <= 1)))) {
18947      if (cond.Is(al)) {
18948        EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
18949                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18950                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18951        return;
18952      }
18953    }
18954  }
18955  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
18956}
18957
18958void Assembler::vmla(
18959    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
18960  VIXL_ASSERT(AllowAssembler());
18961  CheckIT(cond);
18962  Dt_size_9 encoded_dt(dt);
18963  if (IsUsingT32()) {
18964    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
18965    if (encoded_dt.IsValid() &&
18966        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18967         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18968          (rm.GetLane() <= 1)))) {
18969      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18970        EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
18971                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18972                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18973        AdvanceIT();
18974        return;
18975      }
18976    }
18977  } else {
18978    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
18979    if (encoded_dt.IsValid() &&
18980        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18981         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18982          (rm.GetLane() <= 1)))) {
18983      if (cond.Is(al)) {
18984        EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
18985                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18986                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18987        return;
18988      }
18989    }
18990  }
18991  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
18992}
18993
18994void Assembler::vmla(
18995    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18996  VIXL_ASSERT(AllowAssembler());
18997  CheckIT(cond);
18998  Dt_size_10 encoded_dt(dt);
18999  if (IsUsingT32()) {
19000    // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
19001    if (dt.Is(F32)) {
19002      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19003        EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19004                   rm.Encode(5, 0));
19005        AdvanceIT();
19006        return;
19007      }
19008    }
19009    // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
19010    if (dt.Is(F64)) {
19011      EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19012                 rm.Encode(5, 0));
19013      AdvanceIT();
19014      return;
19015    }
19016    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
19017    if (encoded_dt.IsValid()) {
19018      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19019        EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) |
19020                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19021        AdvanceIT();
19022        return;
19023      }
19024    }
19025  } else {
19026    // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
19027    if (dt.Is(F32)) {
19028      if (cond.Is(al)) {
19029        EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19030                rm.Encode(5, 0));
19031        return;
19032      }
19033    }
19034    // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
19035    if (dt.Is(F64) && cond.IsNotNever()) {
19036      EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19037              rn.Encode(7, 16) | rm.Encode(5, 0));
19038      return;
19039    }
19040    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
19041    if (encoded_dt.IsValid()) {
19042      if (cond.Is(al)) {
19043        EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) |
19044                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19045        return;
19046      }
19047    }
19048  }
19049  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19050}
19051
19052void Assembler::vmla(
19053    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
19054  VIXL_ASSERT(AllowAssembler());
19055  CheckIT(cond);
19056  Dt_size_10 encoded_dt(dt);
19057  if (IsUsingT32()) {
19058    // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
19059    if (dt.Is(F32)) {
19060      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19061        EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19062                   rm.Encode(5, 0));
19063        AdvanceIT();
19064        return;
19065      }
19066    }
19067    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
19068    if (encoded_dt.IsValid()) {
19069      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19070        EmitT32_32(0xef000940U | (encoded_dt.GetEncodingValue() << 20) |
19071                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19072        AdvanceIT();
19073        return;
19074      }
19075    }
19076  } else {
19077    // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
19078    if (dt.Is(F32)) {
19079      if (cond.Is(al)) {
19080        EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19081                rm.Encode(5, 0));
19082        return;
19083      }
19084    }
19085    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
19086    if (encoded_dt.IsValid()) {
19087      if (cond.Is(al)) {
19088        EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) |
19089                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19090        return;
19091      }
19092    }
19093  }
19094  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19095}
19096
19097void Assembler::vmla(
19098    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
19099  VIXL_ASSERT(AllowAssembler());
19100  CheckIT(cond);
19101  if (IsUsingT32()) {
19102    // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
19103    if (dt.Is(F32)) {
19104      EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19105                 rm.Encode(5, 0));
19106      AdvanceIT();
19107      return;
19108    }
19109  } else {
19110    // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
19111    if (dt.Is(F32) && cond.IsNotNever()) {
19112      EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19113              rn.Encode(7, 16) | rm.Encode(5, 0));
19114      return;
19115    }
19116  }
19117  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19118}
19119
19120void Assembler::vmlal(
19121    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
19122  VIXL_ASSERT(AllowAssembler());
19123  CheckIT(cond);
19124  Dt_size_11 encoded_dt(dt);
19125  if (IsUsingT32()) {
19126    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
19127    if (encoded_dt.IsValid() &&
19128        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19129         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19130          (rm.GetLane() <= 1)))) {
19131      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19132        EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) |
19133                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19134                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19135        AdvanceIT();
19136        return;
19137      }
19138    }
19139  } else {
19140    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
19141    if (encoded_dt.IsValid() &&
19142        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19143         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19144          (rm.GetLane() <= 1)))) {
19145      if (cond.Is(al)) {
19146        EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) |
19147                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19148                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19149        return;
19150      }
19151    }
19152  }
19153  Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
19154}
19155
19156void Assembler::vmlal(
19157    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
19158  VIXL_ASSERT(AllowAssembler());
19159  CheckIT(cond);
19160  Dt_size_12 encoded_dt(dt);
19161  if (IsUsingT32()) {
19162    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
19163    if (encoded_dt.IsValid()) {
19164      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19165        EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) |
19166                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19167                   rn.Encode(7, 16) | rm.Encode(5, 0));
19168        AdvanceIT();
19169        return;
19170      }
19171    }
19172  } else {
19173    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
19174    if (encoded_dt.IsValid()) {
19175      if (cond.Is(al)) {
19176        EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) |
19177                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19178                rn.Encode(7, 16) | rm.Encode(5, 0));
19179        return;
19180      }
19181    }
19182  }
19183  Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
19184}
19185
19186void Assembler::vmls(
19187    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
19188  VIXL_ASSERT(AllowAssembler());
19189  CheckIT(cond);
19190  Dt_size_9 encoded_dt(dt);
19191  if (IsUsingT32()) {
19192    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
19193    if (encoded_dt.IsValid() &&
19194        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19195         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19196          (rm.GetLane() <= 1)))) {
19197      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19198        EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19199                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19200                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19201        AdvanceIT();
19202        return;
19203      }
19204    }
19205  } else {
19206    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
19207    if (encoded_dt.IsValid() &&
19208        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19209         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19210          (rm.GetLane() <= 1)))) {
19211      if (cond.Is(al)) {
19212        EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19213                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19214                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19215        return;
19216      }
19217    }
19218  }
19219  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19220}
19221
19222void Assembler::vmls(
19223    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
19224  VIXL_ASSERT(AllowAssembler());
19225  CheckIT(cond);
19226  Dt_size_9 encoded_dt(dt);
19227  if (IsUsingT32()) {
19228    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
19229    if (encoded_dt.IsValid() &&
19230        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19231         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19232          (rm.GetLane() <= 1)))) {
19233      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19234        EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19235                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19236                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19237        AdvanceIT();
19238        return;
19239      }
19240    }
19241  } else {
19242    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
19243    if (encoded_dt.IsValid() &&
19244        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19245         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19246          (rm.GetLane() <= 1)))) {
19247      if (cond.Is(al)) {
19248        EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19249                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19250                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19251        return;
19252      }
19253    }
19254  }
19255  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19256}
19257
19258void Assembler::vmls(
19259    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
19260  VIXL_ASSERT(AllowAssembler());
19261  CheckIT(cond);
19262  Dt_size_10 encoded_dt(dt);
19263  if (IsUsingT32()) {
19264    // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
19265    if (dt.Is(F32)) {
19266      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19267        EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19268                   rm.Encode(5, 0));
19269        AdvanceIT();
19270        return;
19271      }
19272    }
19273    // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
19274    if (dt.Is(F64)) {
19275      EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19276                 rm.Encode(5, 0));
19277      AdvanceIT();
19278      return;
19279    }
19280    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
19281    if (encoded_dt.IsValid()) {
19282      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19283        EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) |
19284                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19285        AdvanceIT();
19286        return;
19287      }
19288    }
19289  } else {
19290    // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
19291    if (dt.Is(F32)) {
19292      if (cond.Is(al)) {
19293        EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19294                rm.Encode(5, 0));
19295        return;
19296      }
19297    }
19298    // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
19299    if (dt.Is(F64) && cond.IsNotNever()) {
19300      EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19301              rn.Encode(7, 16) | rm.Encode(5, 0));
19302      return;
19303    }
19304    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
19305    if (encoded_dt.IsValid()) {
19306      if (cond.Is(al)) {
19307        EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) |
19308                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19309        return;
19310      }
19311    }
19312  }
19313  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19314}
19315
19316void Assembler::vmls(
19317    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
19318  VIXL_ASSERT(AllowAssembler());
19319  CheckIT(cond);
19320  Dt_size_10 encoded_dt(dt);
19321  if (IsUsingT32()) {
19322    // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
19323    if (dt.Is(F32)) {
19324      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19325        EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19326                   rm.Encode(5, 0));
19327        AdvanceIT();
19328        return;
19329      }
19330    }
19331    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
19332    if (encoded_dt.IsValid()) {
19333      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19334        EmitT32_32(0xff000940U | (encoded_dt.GetEncodingValue() << 20) |
19335                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19336        AdvanceIT();
19337        return;
19338      }
19339    }
19340  } else {
19341    // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
19342    if (dt.Is(F32)) {
19343      if (cond.Is(al)) {
19344        EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19345                rm.Encode(5, 0));
19346        return;
19347      }
19348    }
19349    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
19350    if (encoded_dt.IsValid()) {
19351      if (cond.Is(al)) {
19352        EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) |
19353                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19354        return;
19355      }
19356    }
19357  }
19358  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19359}
19360
19361void Assembler::vmls(
19362    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
19363  VIXL_ASSERT(AllowAssembler());
19364  CheckIT(cond);
19365  if (IsUsingT32()) {
19366    // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
19367    if (dt.Is(F32)) {
19368      EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19369                 rm.Encode(5, 0));
19370      AdvanceIT();
19371      return;
19372    }
19373  } else {
19374    // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
19375    if (dt.Is(F32) && cond.IsNotNever()) {
19376      EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19377              rn.Encode(7, 16) | rm.Encode(5, 0));
19378      return;
19379    }
19380  }
19381  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19382}
19383
19384void Assembler::vmlsl(
19385    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
19386  VIXL_ASSERT(AllowAssembler());
19387  CheckIT(cond);
19388  Dt_size_11 encoded_dt(dt);
19389  if (IsUsingT32()) {
19390    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
19391    if (encoded_dt.IsValid() &&
19392        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19393         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19394          (rm.GetLane() <= 1)))) {
19395      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19396        EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) |
19397                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19398                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19399        AdvanceIT();
19400        return;
19401      }
19402    }
19403  } else {
19404    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
19405    if (encoded_dt.IsValid() &&
19406        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19407         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19408          (rm.GetLane() <= 1)))) {
19409      if (cond.Is(al)) {
19410        EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) |
19411                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19412                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19413        return;
19414      }
19415    }
19416  }
19417  Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
19418}
19419
19420void Assembler::vmlsl(
19421    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
19422  VIXL_ASSERT(AllowAssembler());
19423  CheckIT(cond);
19424  Dt_size_12 encoded_dt(dt);
19425  if (IsUsingT32()) {
19426    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
19427    if (encoded_dt.IsValid()) {
19428      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19429        EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) |
19430                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19431                   rn.Encode(7, 16) | rm.Encode(5, 0));
19432        AdvanceIT();
19433        return;
19434      }
19435    }
19436  } else {
19437    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
19438    if (encoded_dt.IsValid()) {
19439      if (cond.Is(al)) {
19440        EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) |
19441                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19442                rn.Encode(7, 16) | rm.Encode(5, 0));
19443        return;
19444      }
19445    }
19446  }
19447  Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
19448}
19449
19450void Assembler::vmov(Condition cond, Register rt, SRegister rn) {
19451  VIXL_ASSERT(AllowAssembler());
19452  CheckIT(cond);
19453  if (IsUsingT32()) {
19454    // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1
19455    EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16));
19456    AdvanceIT();
19457    return;
19458  } else {
19459    // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1
19460    if (cond.IsNotNever()) {
19461      EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19462              rn.Encode(7, 16));
19463      return;
19464    }
19465  }
19466  Delegate(kVmov, &Assembler::vmov, cond, rt, rn);
19467}
19468
19469void Assembler::vmov(Condition cond, SRegister rn, Register rt) {
19470  VIXL_ASSERT(AllowAssembler());
19471  CheckIT(cond);
19472  if (IsUsingT32()) {
19473    // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1
19474    EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12));
19475    AdvanceIT();
19476    return;
19477  } else {
19478    // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1
19479    if (cond.IsNotNever()) {
19480      EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) |
19481              (rt.GetCode() << 12));
19482      return;
19483    }
19484  }
19485  Delegate(kVmov, &Assembler::vmov, cond, rn, rt);
19486}
19487
19488void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) {
19489  VIXL_ASSERT(AllowAssembler());
19490  CheckIT(cond);
19491  if (IsUsingT32()) {
19492    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1
19493    EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
19494               rm.Encode(5, 0));
19495    AdvanceIT();
19496    return;
19497  } else {
19498    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1
19499    if (cond.IsNotNever()) {
19500      EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19501              (rt2.GetCode() << 16) | rm.Encode(5, 0));
19502      return;
19503    }
19504  }
19505  Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm);
19506}
19507
19508void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) {
19509  VIXL_ASSERT(AllowAssembler());
19510  CheckIT(cond);
19511  if (IsUsingT32()) {
19512    // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1
19513    EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
19514               (rt2.GetCode() << 16));
19515    AdvanceIT();
19516    return;
19517  } else {
19518    // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1
19519    if (cond.IsNotNever()) {
19520      EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
19521              (rt.GetCode() << 12) | (rt2.GetCode() << 16));
19522      return;
19523    }
19524  }
19525  Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2);
19526}
19527
19528void Assembler::vmov(
19529    Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) {
19530  VIXL_ASSERT(AllowAssembler());
19531  CheckIT(cond);
19532  if (IsUsingT32()) {
19533    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1
19534    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) {
19535      EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
19536                 rm.Encode(5, 0));
19537      AdvanceIT();
19538      return;
19539    }
19540  } else {
19541    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1
19542    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
19543        cond.IsNotNever()) {
19544      EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19545              (rt2.GetCode() << 16) | rm.Encode(5, 0));
19546      return;
19547    }
19548  }
19549  Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1);
19550}
19551
19552void Assembler::vmov(
19553    Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) {
19554  VIXL_ASSERT(AllowAssembler());
19555  CheckIT(cond);
19556  if (IsUsingT32()) {
19557    // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1
19558    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) {
19559      EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
19560                 (rt2.GetCode() << 16));
19561      AdvanceIT();
19562      return;
19563    }
19564  } else {
19565    // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1
19566    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
19567        cond.IsNotNever()) {
19568      EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
19569              (rt.GetCode() << 12) | (rt2.GetCode() << 16));
19570      return;
19571    }
19572  }
19573  Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2);
19574}
19575
19576void Assembler::vmov(Condition cond,
19577                     DataType dt,
19578                     DRegisterLane rd,
19579                     Register rt) {
19580  VIXL_ASSERT(AllowAssembler());
19581  CheckIT(cond);
19582  Dt_opc1_opc2_1 encoded_dt(dt, rd);
19583  if (IsUsingT32()) {
19584    // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1
19585    if (encoded_dt.IsValid()) {
19586      EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19587                 ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19588                 rd.Encode(7, 16) | (rt.GetCode() << 12));
19589      AdvanceIT();
19590      return;
19591    }
19592  } else {
19593    // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1
19594    if (encoded_dt.IsValid() && cond.IsNotNever()) {
19595      EmitA32(0x0e000b10U | (cond.GetCondition() << 28) |
19596              ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19597              ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) |
19598              (rt.GetCode() << 12));
19599      return;
19600    }
19601  }
19602  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt);
19603}
19604
19605void Assembler::vmov(Condition cond,
19606                     DataType dt,
19607                     DRegister rd,
19608                     const DOperand& operand) {
19609  VIXL_ASSERT(AllowAssembler());
19610  CheckIT(cond);
19611  if (operand.IsImmediate()) {
19612    ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
19613    ImmediateVFP vfp(operand.GetNeonImmediate());
19614    if (IsUsingT32()) {
19615      // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
19616      if (encoded_dt.IsValid()) {
19617        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19618          EmitT32_32(
19619              0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19620              ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19621              rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19622              ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19623              ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
19624          AdvanceIT();
19625          return;
19626        }
19627      }
19628      // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2
19629      if (dt.Is(F64) && vfp.IsValid()) {
19630        EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) |
19631                   (vfp.GetEncodingValue() & 0xf) |
19632                   ((vfp.GetEncodingValue() & 0xf0) << 12));
19633        AdvanceIT();
19634        return;
19635      }
19636    } else {
19637      // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
19638      if (encoded_dt.IsValid()) {
19639        if (cond.Is(al)) {
19640          EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19641                  ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19642                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19643                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19644                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
19645          return;
19646        }
19647      }
19648      // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2
19649      if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) {
19650        EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19651                (vfp.GetEncodingValue() & 0xf) |
19652                ((vfp.GetEncodingValue() & 0xf0) << 12));
19653        return;
19654      }
19655    }
19656  }
19657  if (operand.IsRegister()) {
19658    DRegister rm = operand.GetRegister();
19659    if (IsUsingT32()) {
19660      // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
19661      if (dt.Is(F64)) {
19662        EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
19663        AdvanceIT();
19664        return;
19665      }
19666      // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
19667      if (!dt.Is(F64)) {
19668        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19669          EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19670                     rm.Encode(5, 0));
19671          AdvanceIT();
19672          return;
19673        }
19674      }
19675    } else {
19676      // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
19677      if (dt.Is(F64) && cond.IsNotNever()) {
19678        EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19679                rm.Encode(5, 0));
19680        return;
19681      }
19682      // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
19683      if (!dt.Is(F64)) {
19684        if (cond.Is(al)) {
19685          EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19686                  rm.Encode(5, 0));
19687          return;
19688        }
19689      }
19690    }
19691  }
19692  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19693}
19694
19695void Assembler::vmov(Condition cond,
19696                     DataType dt,
19697                     QRegister rd,
19698                     const QOperand& operand) {
19699  VIXL_ASSERT(AllowAssembler());
19700  CheckIT(cond);
19701  if (operand.IsImmediate()) {
19702    ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
19703    if (IsUsingT32()) {
19704      // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
19705      if (encoded_dt.IsValid()) {
19706        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19707          EmitT32_32(
19708              0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19709              ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19710              rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19711              ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19712              ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
19713          AdvanceIT();
19714          return;
19715        }
19716      }
19717    } else {
19718      // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
19719      if (encoded_dt.IsValid()) {
19720        if (cond.Is(al)) {
19721          EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19722                  ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19723                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19724                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19725                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
19726          return;
19727        }
19728      }
19729    }
19730  }
19731  if (operand.IsRegister()) {
19732    QRegister rm = operand.GetRegister();
19733    if (IsUsingT32()) {
19734      // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
19735      if (!dt.Is(F64)) {
19736        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19737          EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19738                     rm.Encode(5, 0));
19739          AdvanceIT();
19740          return;
19741        }
19742      }
19743    } else {
19744      // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
19745      if (!dt.Is(F64)) {
19746        if (cond.Is(al)) {
19747          EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19748                  rm.Encode(5, 0));
19749          return;
19750        }
19751      }
19752    }
19753  }
19754  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19755}
19756
19757void Assembler::vmov(Condition cond,
19758                     DataType dt,
19759                     SRegister rd,
19760                     const SOperand& operand) {
19761  VIXL_ASSERT(AllowAssembler());
19762  CheckIT(cond);
19763  if (operand.IsImmediate()) {
19764    ImmediateVFP vfp(operand.GetNeonImmediate());
19765    if (IsUsingT32()) {
19766      // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2
19767      if (dt.Is(F32) && vfp.IsValid()) {
19768        EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) |
19769                   (vfp.GetEncodingValue() & 0xf) |
19770                   ((vfp.GetEncodingValue() & 0xf0) << 12));
19771        AdvanceIT();
19772        return;
19773      }
19774    } else {
19775      // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2
19776      if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) {
19777        EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19778                (vfp.GetEncodingValue() & 0xf) |
19779                ((vfp.GetEncodingValue() & 0xf0) << 12));
19780        return;
19781      }
19782    }
19783  }
19784  if (operand.IsRegister()) {
19785    SRegister rm = operand.GetRegister();
19786    if (IsUsingT32()) {
19787      // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
19788      if (dt.Is(F32)) {
19789        EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
19790        AdvanceIT();
19791        return;
19792      }
19793    } else {
19794      // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
19795      if (dt.Is(F32) && cond.IsNotNever()) {
19796        EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19797                rm.Encode(5, 0));
19798        return;
19799      }
19800    }
19801  }
19802  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19803}
19804
19805void Assembler::vmov(Condition cond,
19806                     DataType dt,
19807                     Register rt,
19808                     DRegisterLane rn) {
19809  VIXL_ASSERT(AllowAssembler());
19810  CheckIT(cond);
19811  Dt_U_opc1_opc2_1 encoded_dt(dt, rn);
19812  if (IsUsingT32()) {
19813    // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1
19814    if (encoded_dt.IsValid()) {
19815      EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19816                 ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19817                 ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
19818                 (rt.GetCode() << 12) | rn.Encode(7, 16));
19819      AdvanceIT();
19820      return;
19821    }
19822  } else {
19823    // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1
19824    if (encoded_dt.IsValid() && cond.IsNotNever()) {
19825      EmitA32(0x0e100b10U | (cond.GetCondition() << 28) |
19826              ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19827              ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19828              ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
19829              (rt.GetCode() << 12) | rn.Encode(7, 16));
19830      return;
19831    }
19832  }
19833  Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn);
19834}
19835
19836void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) {
19837  VIXL_ASSERT(AllowAssembler());
19838  CheckIT(cond);
19839  Dt_U_imm3H_1 encoded_dt(dt);
19840  if (IsUsingT32()) {
19841    // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1
19842    if (encoded_dt.IsValid()) {
19843      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19844        EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
19845                   ((encoded_dt.GetEncodingValue() & 0x8) << 25) |
19846                   rd.Encode(22, 12) | rm.Encode(5, 0));
19847        AdvanceIT();
19848        return;
19849      }
19850    }
19851  } else {
19852    // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
19853    if (encoded_dt.IsValid()) {
19854      if (cond.Is(al)) {
19855        EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
19856                ((encoded_dt.GetEncodingValue() & 0x8) << 21) |
19857                rd.Encode(22, 12) | rm.Encode(5, 0));
19858        return;
19859      }
19860    }
19861  }
19862  Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm);
19863}
19864
19865void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) {
19866  VIXL_ASSERT(AllowAssembler());
19867  CheckIT(cond);
19868  Dt_size_3 encoded_dt(dt);
19869  if (IsUsingT32()) {
19870    // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
19871    if (encoded_dt.IsValid()) {
19872      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19873        EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) |
19874                   rd.Encode(22, 12) | rm.Encode(5, 0));
19875        AdvanceIT();
19876        return;
19877      }
19878    }
19879  } else {
19880    // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
19881    if (encoded_dt.IsValid()) {
19882      if (cond.Is(al)) {
19883        EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) |
19884                rd.Encode(22, 12) | rm.Encode(5, 0));
19885        return;
19886      }
19887    }
19888  }
19889  Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm);
19890}
19891
19892void Assembler::vmrs(Condition cond,
19893                     RegisterOrAPSR_nzcv rt,
19894                     SpecialFPRegister spec_reg) {
19895  VIXL_ASSERT(AllowAssembler());
19896  CheckIT(cond);
19897  if (IsUsingT32()) {
19898    // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1
19899    EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16));
19900    AdvanceIT();
19901    return;
19902  } else {
19903    // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1
19904    if (cond.IsNotNever()) {
19905      EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19906              (spec_reg.GetReg() << 16));
19907      return;
19908    }
19909  }
19910  Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg);
19911}
19912
19913void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) {
19914  VIXL_ASSERT(AllowAssembler());
19915  CheckIT(cond);
19916  if (IsUsingT32()) {
19917    // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1
19918    EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
19919    AdvanceIT();
19920    return;
19921  } else {
19922    // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1
19923    if (cond.IsNotNever()) {
19924      EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) |
19925              (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
19926      return;
19927    }
19928  }
19929  Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt);
19930}
19931
19932void Assembler::vmul(Condition cond,
19933                     DataType dt,
19934                     DRegister rd,
19935                     DRegister rn,
19936                     DRegister dm,
19937                     unsigned index) {
19938  VIXL_ASSERT(AllowAssembler());
19939  CheckIT(cond);
19940  Dt_F_size_3 encoded_dt(dt);
19941  if (IsUsingT32()) {
19942    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1
19943    if (encoded_dt.IsValid() &&
19944        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
19945         (!dt.Is(I16) && (index <= 1)))) {
19946      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19947        uint32_t shift = 4;
19948        if (dt.Is(I16)) {
19949          shift = 3;
19950        }
19951        uint32_t mvm = dm.GetCode() | index << shift;
19952        EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19953                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
19954                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
19955                   ((mvm & 0x10) << 1));
19956        AdvanceIT();
19957        return;
19958      }
19959    }
19960  } else {
19961    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1
19962    if (encoded_dt.IsValid() &&
19963        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
19964         (!dt.Is(I16) && (index <= 1)))) {
19965      if (cond.Is(al)) {
19966        uint32_t shift = 4;
19967        if (dt.Is(I16)) {
19968          shift = 3;
19969        }
19970        uint32_t mvm = dm.GetCode() | index << shift;
19971        EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19972                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
19973                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
19974                ((mvm & 0x10) << 1));
19975        return;
19976      }
19977    }
19978  }
19979  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
19980}
19981
19982void Assembler::vmul(Condition cond,
19983                     DataType dt,
19984                     QRegister rd,
19985                     QRegister rn,
19986                     DRegister dm,
19987                     unsigned index) {
19988  VIXL_ASSERT(AllowAssembler());
19989  CheckIT(cond);
19990  Dt_F_size_3 encoded_dt(dt);
19991  if (IsUsingT32()) {
19992    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1
19993    if (encoded_dt.IsValid() &&
19994        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
19995         (!dt.Is(I16) && (index <= 1)))) {
19996      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19997        uint32_t shift = 4;
19998        if (dt.Is(I16)) {
19999          shift = 3;
20000        }
20001        uint32_t mvm = dm.GetCode() | index << shift;
20002        EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20003                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
20004                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20005                   ((mvm & 0x10) << 1));
20006        AdvanceIT();
20007        return;
20008      }
20009    }
20010  } else {
20011    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1
20012    if (encoded_dt.IsValid() &&
20013        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
20014         (!dt.Is(I16) && (index <= 1)))) {
20015      if (cond.Is(al)) {
20016        uint32_t shift = 4;
20017        if (dt.Is(I16)) {
20018          shift = 3;
20019        }
20020        uint32_t mvm = dm.GetCode() | index << shift;
20021        EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20022                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
20023                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20024                ((mvm & 0x10) << 1));
20025        return;
20026      }
20027    }
20028  }
20029  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
20030}
20031
20032void Assembler::vmul(
20033    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20034  VIXL_ASSERT(AllowAssembler());
20035  CheckIT(cond);
20036  Dt_op_size_1 encoded_dt(dt);
20037  if (IsUsingT32()) {
20038    // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20039    if (dt.Is(F32)) {
20040      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20041        EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20042                   rm.Encode(5, 0));
20043        AdvanceIT();
20044        return;
20045      }
20046    }
20047    // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
20048    if (dt.Is(F64)) {
20049      EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20050                 rm.Encode(5, 0));
20051      AdvanceIT();
20052      return;
20053    }
20054    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20055    if (encoded_dt.IsValid()) {
20056      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20057        EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20058                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20059                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20060        AdvanceIT();
20061        return;
20062      }
20063    }
20064  } else {
20065    // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
20066    if (dt.Is(F32)) {
20067      if (cond.Is(al)) {
20068        EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20069                rm.Encode(5, 0));
20070        return;
20071      }
20072    }
20073    // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
20074    if (dt.Is(F64) && cond.IsNotNever()) {
20075      EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20076              rn.Encode(7, 16) | rm.Encode(5, 0));
20077      return;
20078    }
20079    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20080    if (encoded_dt.IsValid()) {
20081      if (cond.Is(al)) {
20082        EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20083                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20084                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20085        return;
20086      }
20087    }
20088  }
20089  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
20090}
20091
20092void Assembler::vmul(
20093    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20094  VIXL_ASSERT(AllowAssembler());
20095  CheckIT(cond);
20096  Dt_op_size_1 encoded_dt(dt);
20097  if (IsUsingT32()) {
20098    // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
20099    if (dt.Is(F32)) {
20100      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20101        EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20102                   rm.Encode(5, 0));
20103        AdvanceIT();
20104        return;
20105      }
20106    }
20107    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
20108    if (encoded_dt.IsValid()) {
20109      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20110        EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20111                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20112                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20113        AdvanceIT();
20114        return;
20115      }
20116    }
20117  } else {
20118    // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
20119    if (dt.Is(F32)) {
20120      if (cond.Is(al)) {
20121        EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20122                rm.Encode(5, 0));
20123        return;
20124      }
20125    }
20126    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
20127    if (encoded_dt.IsValid()) {
20128      if (cond.Is(al)) {
20129        EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20130                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20131                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20132        return;
20133      }
20134    }
20135  }
20136  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
20137}
20138
20139void Assembler::vmul(
20140    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20141  VIXL_ASSERT(AllowAssembler());
20142  CheckIT(cond);
20143  if (IsUsingT32()) {
20144    // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
20145    if (dt.Is(F32)) {
20146      EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20147                 rm.Encode(5, 0));
20148      AdvanceIT();
20149      return;
20150    }
20151  } else {
20152    // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
20153    if (dt.Is(F32) && cond.IsNotNever()) {
20154      EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20155              rn.Encode(7, 16) | rm.Encode(5, 0));
20156      return;
20157    }
20158  }
20159  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
20160}
20161
20162void Assembler::vmull(Condition cond,
20163                      DataType dt,
20164                      QRegister rd,
20165                      DRegister rn,
20166                      DRegister dm,
20167                      unsigned index) {
20168  VIXL_ASSERT(AllowAssembler());
20169  CheckIT(cond);
20170  Dt_U_size_2 encoded_dt(dt);
20171  if (IsUsingT32()) {
20172    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1
20173    if (encoded_dt.IsValid() &&
20174        (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
20175         (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) {
20176      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20177        uint32_t shift = 4;
20178        if (dt.Is(S16) || dt.Is(U16)) {
20179          shift = 3;
20180        }
20181        uint32_t mvm = dm.GetCode() | index << shift;
20182        EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20183                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20184                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20185                   ((mvm & 0x10) << 1));
20186        AdvanceIT();
20187        return;
20188      }
20189    }
20190  } else {
20191    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1
20192    if (encoded_dt.IsValid() &&
20193        (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
20194         (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) {
20195      if (cond.Is(al)) {
20196        uint32_t shift = 4;
20197        if (dt.Is(S16) || dt.Is(U16)) {
20198          shift = 3;
20199        }
20200        uint32_t mvm = dm.GetCode() | index << shift;
20201        EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20202                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20203                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20204                ((mvm & 0x10) << 1));
20205        return;
20206      }
20207    }
20208  }
20209  Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index);
20210}
20211
20212void Assembler::vmull(
20213    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
20214  VIXL_ASSERT(AllowAssembler());
20215  CheckIT(cond);
20216  Dt_op_U_size_1 encoded_dt(dt);
20217  if (IsUsingT32()) {
20218    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
20219    if (encoded_dt.IsValid()) {
20220      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20221        EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20222                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20223                   ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
20224                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20225        AdvanceIT();
20226        return;
20227      }
20228    }
20229  } else {
20230    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
20231    if (encoded_dt.IsValid()) {
20232      if (cond.Is(al)) {
20233        EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20234                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20235                ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
20236                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20237        return;
20238      }
20239    }
20240  }
20241  Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm);
20242}
20243
20244void Assembler::vmvn(Condition cond,
20245                     DataType dt,
20246                     DRegister rd,
20247                     const DOperand& operand) {
20248  VIXL_ASSERT(AllowAssembler());
20249  CheckIT(cond);
20250  if (operand.IsImmediate()) {
20251    ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
20252    if (IsUsingT32()) {
20253      // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
20254      if (encoded_dt.IsValid()) {
20255        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20256          EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
20257                     rd.Encode(22, 12) |
20258                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20259                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20260                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20261          AdvanceIT();
20262          return;
20263        }
20264      }
20265    } else {
20266      // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
20267      if (encoded_dt.IsValid()) {
20268        if (cond.Is(al)) {
20269          EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
20270                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20271                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20272                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20273          return;
20274        }
20275      }
20276    }
20277  }
20278  if (operand.IsRegister()) {
20279    DRegister rm = operand.GetRegister();
20280    USE(dt);
20281    if (IsUsingT32()) {
20282      // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
20283      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20284        EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
20285        AdvanceIT();
20286        return;
20287      }
20288    } else {
20289      // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
20290      if (cond.Is(al)) {
20291        EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
20292        return;
20293      }
20294    }
20295  }
20296  Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
20297}
20298
20299void Assembler::vmvn(Condition cond,
20300                     DataType dt,
20301                     QRegister rd,
20302                     const QOperand& operand) {
20303  VIXL_ASSERT(AllowAssembler());
20304  CheckIT(cond);
20305  if (operand.IsImmediate()) {
20306    ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
20307    if (IsUsingT32()) {
20308      // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
20309      if (encoded_dt.IsValid()) {
20310        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20311          EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
20312                     rd.Encode(22, 12) |
20313                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20314                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20315                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20316          AdvanceIT();
20317          return;
20318        }
20319      }
20320    } else {
20321      // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
20322      if (encoded_dt.IsValid()) {
20323        if (cond.Is(al)) {
20324          EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
20325                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20326                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20327                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20328          return;
20329        }
20330      }
20331    }
20332  }
20333  if (operand.IsRegister()) {
20334    QRegister rm = operand.GetRegister();
20335    USE(dt);
20336    if (IsUsingT32()) {
20337      // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
20338      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20339        EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
20340        AdvanceIT();
20341        return;
20342      }
20343    } else {
20344      // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
20345      if (cond.Is(al)) {
20346        EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
20347        return;
20348      }
20349    }
20350  }
20351  Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
20352}
20353
20354void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
20355  VIXL_ASSERT(AllowAssembler());
20356  CheckIT(cond);
20357  Dt_F_size_1 encoded_dt(dt);
20358  if (IsUsingT32()) {
20359    // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20360    if (encoded_dt.IsValid()) {
20361      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20362        EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20363                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20364                   rd.Encode(22, 12) | rm.Encode(5, 0));
20365        AdvanceIT();
20366        return;
20367      }
20368    }
20369    // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
20370    if (dt.Is(F64)) {
20371      EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
20372      AdvanceIT();
20373      return;
20374    }
20375  } else {
20376    // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
20377    if (encoded_dt.IsValid()) {
20378      if (cond.Is(al)) {
20379        EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20380                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20381                rd.Encode(22, 12) | rm.Encode(5, 0));
20382        return;
20383      }
20384    }
20385    // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
20386    if (dt.Is(F64) && cond.IsNotNever()) {
20387      EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20388              rm.Encode(5, 0));
20389      return;
20390    }
20391  }
20392  Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20393}
20394
20395void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
20396  VIXL_ASSERT(AllowAssembler());
20397  CheckIT(cond);
20398  Dt_F_size_1 encoded_dt(dt);
20399  if (IsUsingT32()) {
20400    // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
20401    if (encoded_dt.IsValid()) {
20402      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20403        EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20404                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20405                   rd.Encode(22, 12) | rm.Encode(5, 0));
20406        AdvanceIT();
20407        return;
20408      }
20409    }
20410  } else {
20411    // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
20412    if (encoded_dt.IsValid()) {
20413      if (cond.Is(al)) {
20414        EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20415                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20416                rd.Encode(22, 12) | rm.Encode(5, 0));
20417        return;
20418      }
20419    }
20420  }
20421  Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20422}
20423
20424void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) {
20425  VIXL_ASSERT(AllowAssembler());
20426  CheckIT(cond);
20427  if (IsUsingT32()) {
20428    // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
20429    if (dt.Is(F32)) {
20430      EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
20431      AdvanceIT();
20432      return;
20433    }
20434  } else {
20435    // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
20436    if (dt.Is(F32) && cond.IsNotNever()) {
20437      EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20438              rm.Encode(5, 0));
20439      return;
20440    }
20441  }
20442  Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20443}
20444
20445void Assembler::vnmla(
20446    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20447  VIXL_ASSERT(AllowAssembler());
20448  CheckIT(cond);
20449  if (IsUsingT32()) {
20450    // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
20451    if (dt.Is(F32)) {
20452      EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20453                 rm.Encode(5, 0));
20454      AdvanceIT();
20455      return;
20456    }
20457  } else {
20458    // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
20459    if (dt.Is(F32) && cond.IsNotNever()) {
20460      EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20461              rn.Encode(7, 16) | rm.Encode(5, 0));
20462      return;
20463    }
20464  }
20465  Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
20466}
20467
20468void Assembler::vnmla(
20469    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20470  VIXL_ASSERT(AllowAssembler());
20471  CheckIT(cond);
20472  if (IsUsingT32()) {
20473    // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
20474    if (dt.Is(F64)) {
20475      EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20476                 rm.Encode(5, 0));
20477      AdvanceIT();
20478      return;
20479    }
20480  } else {
20481    // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
20482    if (dt.Is(F64) && cond.IsNotNever()) {
20483      EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20484              rn.Encode(7, 16) | rm.Encode(5, 0));
20485      return;
20486    }
20487  }
20488  Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
20489}
20490
20491void Assembler::vnmls(
20492    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20493  VIXL_ASSERT(AllowAssembler());
20494  CheckIT(cond);
20495  if (IsUsingT32()) {
20496    // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
20497    if (dt.Is(F32)) {
20498      EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20499                 rm.Encode(5, 0));
20500      AdvanceIT();
20501      return;
20502    }
20503  } else {
20504    // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
20505    if (dt.Is(F32) && cond.IsNotNever()) {
20506      EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20507              rn.Encode(7, 16) | rm.Encode(5, 0));
20508      return;
20509    }
20510  }
20511  Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
20512}
20513
20514void Assembler::vnmls(
20515    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20516  VIXL_ASSERT(AllowAssembler());
20517  CheckIT(cond);
20518  if (IsUsingT32()) {
20519    // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
20520    if (dt.Is(F64)) {
20521      EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20522                 rm.Encode(5, 0));
20523      AdvanceIT();
20524      return;
20525    }
20526  } else {
20527    // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
20528    if (dt.Is(F64) && cond.IsNotNever()) {
20529      EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20530              rn.Encode(7, 16) | rm.Encode(5, 0));
20531      return;
20532    }
20533  }
20534  Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
20535}
20536
20537void Assembler::vnmul(
20538    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20539  VIXL_ASSERT(AllowAssembler());
20540  CheckIT(cond);
20541  if (IsUsingT32()) {
20542    // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
20543    if (dt.Is(F32)) {
20544      EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20545                 rm.Encode(5, 0));
20546      AdvanceIT();
20547      return;
20548    }
20549  } else {
20550    // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
20551    if (dt.Is(F32) && cond.IsNotNever()) {
20552      EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20553              rn.Encode(7, 16) | rm.Encode(5, 0));
20554      return;
20555    }
20556  }
20557  Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
20558}
20559
20560void Assembler::vnmul(
20561    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20562  VIXL_ASSERT(AllowAssembler());
20563  CheckIT(cond);
20564  if (IsUsingT32()) {
20565    // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
20566    if (dt.Is(F64)) {
20567      EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20568                 rm.Encode(5, 0));
20569      AdvanceIT();
20570      return;
20571    }
20572  } else {
20573    // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
20574    if (dt.Is(F64) && cond.IsNotNever()) {
20575      EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20576              rn.Encode(7, 16) | rm.Encode(5, 0));
20577      return;
20578    }
20579  }
20580  Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
20581}
20582
20583void Assembler::vorn(Condition cond,
20584                     DataType dt,
20585                     DRegister rd,
20586                     DRegister rn,
20587                     const DOperand& operand) {
20588  VIXL_ASSERT(AllowAssembler());
20589  CheckIT(cond);
20590  if (operand.IsImmediate()) {
20591    ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
20592    if (IsUsingT32()) {
20593      // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
20594      if (encoded_dt.IsValid() && rd.Is(rn)) {
20595        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20596          EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
20597                     rd.Encode(22, 12) |
20598                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20599                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20600                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20601          AdvanceIT();
20602          return;
20603        }
20604      }
20605    } else {
20606      // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
20607      if (encoded_dt.IsValid() && rd.Is(rn)) {
20608        if (cond.Is(al)) {
20609          EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
20610                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20611                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20612                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20613          return;
20614        }
20615      }
20616    }
20617  }
20618  if (operand.IsRegister()) {
20619    DRegister rm = operand.GetRegister();
20620    USE(dt);
20621    if (IsUsingT32()) {
20622      // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
20623      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20624        EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20625                   rm.Encode(5, 0));
20626        AdvanceIT();
20627        return;
20628      }
20629    } else {
20630      // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
20631      if (cond.Is(al)) {
20632        EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20633                rm.Encode(5, 0));
20634        return;
20635      }
20636    }
20637  }
20638  Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
20639}
20640
20641void Assembler::vorn(Condition cond,
20642                     DataType dt,
20643                     QRegister rd,
20644                     QRegister rn,
20645                     const QOperand& operand) {
20646  VIXL_ASSERT(AllowAssembler());
20647  CheckIT(cond);
20648  if (operand.IsImmediate()) {
20649    ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
20650    if (IsUsingT32()) {
20651      // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
20652      if (encoded_dt.IsValid() && rd.Is(rn)) {
20653        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20654          EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
20655                     rd.Encode(22, 12) |
20656                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20657                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20658                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20659          AdvanceIT();
20660          return;
20661        }
20662      }
20663    } else {
20664      // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
20665      if (encoded_dt.IsValid() && rd.Is(rn)) {
20666        if (cond.Is(al)) {
20667          EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
20668                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20669                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20670                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20671          return;
20672        }
20673      }
20674    }
20675  }
20676  if (operand.IsRegister()) {
20677    QRegister rm = operand.GetRegister();
20678    USE(dt);
20679    if (IsUsingT32()) {
20680      // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
20681      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20682        EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20683                   rm.Encode(5, 0));
20684        AdvanceIT();
20685        return;
20686      }
20687    } else {
20688      // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
20689      if (cond.Is(al)) {
20690        EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20691                rm.Encode(5, 0));
20692        return;
20693      }
20694    }
20695  }
20696  Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
20697}
20698
20699void Assembler::vorr(Condition cond,
20700                     DataType dt,
20701                     DRegister rd,
20702                     DRegister rn,
20703                     const DOperand& operand) {
20704  VIXL_ASSERT(AllowAssembler());
20705  CheckIT(cond);
20706  if (operand.IsRegister()) {
20707    DRegister rm = operand.GetRegister();
20708    USE(dt);
20709    if (IsUsingT32()) {
20710      // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
20711      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20712        EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20713                   rm.Encode(5, 0));
20714        AdvanceIT();
20715        return;
20716      }
20717    } else {
20718      // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
20719      if (cond.Is(al)) {
20720        EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20721                rm.Encode(5, 0));
20722        return;
20723      }
20724    }
20725  }
20726  if (operand.IsImmediate()) {
20727    ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
20728    if (IsUsingT32()) {
20729      // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
20730      if (encoded_dt.IsValid() && rd.Is(rn)) {
20731        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20732          EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
20733                     rd.Encode(22, 12) |
20734                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20735                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20736                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20737          AdvanceIT();
20738          return;
20739        }
20740      }
20741    } else {
20742      // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
20743      if (encoded_dt.IsValid() && rd.Is(rn)) {
20744        if (cond.Is(al)) {
20745          EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
20746                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20747                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20748                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20749          return;
20750        }
20751      }
20752    }
20753  }
20754  Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
20755}
20756
20757void Assembler::vorr(Condition cond,
20758                     DataType dt,
20759                     QRegister rd,
20760                     QRegister rn,
20761                     const QOperand& operand) {
20762  VIXL_ASSERT(AllowAssembler());
20763  CheckIT(cond);
20764  if (operand.IsRegister()) {
20765    QRegister rm = operand.GetRegister();
20766    USE(dt);
20767    if (IsUsingT32()) {
20768      // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
20769      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20770        EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20771                   rm.Encode(5, 0));
20772        AdvanceIT();
20773        return;
20774      }
20775    } else {
20776      // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
20777      if (cond.Is(al)) {
20778        EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20779                rm.Encode(5, 0));
20780        return;
20781      }
20782    }
20783  }
20784  if (operand.IsImmediate()) {
20785    ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
20786    if (IsUsingT32()) {
20787      // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
20788      if (encoded_dt.IsValid() && rd.Is(rn)) {
20789        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20790          EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
20791                     rd.Encode(22, 12) |
20792                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20793                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20794                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20795          AdvanceIT();
20796          return;
20797        }
20798      }
20799    } else {
20800      // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
20801      if (encoded_dt.IsValid() && rd.Is(rn)) {
20802        if (cond.Is(al)) {
20803          EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
20804                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20805                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20806                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20807          return;
20808        }
20809      }
20810    }
20811  }
20812  Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
20813}
20814
20815void Assembler::vpadal(Condition cond,
20816                       DataType dt,
20817                       DRegister rd,
20818                       DRegister rm) {
20819  VIXL_ASSERT(AllowAssembler());
20820  CheckIT(cond);
20821  Dt_op_size_2 encoded_dt(dt);
20822  if (IsUsingT32()) {
20823    // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20824    if (encoded_dt.IsValid()) {
20825      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20826        EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20827                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20828                   rd.Encode(22, 12) | rm.Encode(5, 0));
20829        AdvanceIT();
20830        return;
20831      }
20832    }
20833  } else {
20834    // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
20835    if (encoded_dt.IsValid()) {
20836      if (cond.Is(al)) {
20837        EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20838                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20839                rd.Encode(22, 12) | rm.Encode(5, 0));
20840        return;
20841      }
20842    }
20843  }
20844  Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
20845}
20846
20847void Assembler::vpadal(Condition cond,
20848                       DataType dt,
20849                       QRegister rd,
20850                       QRegister rm) {
20851  VIXL_ASSERT(AllowAssembler());
20852  CheckIT(cond);
20853  Dt_op_size_2 encoded_dt(dt);
20854  if (IsUsingT32()) {
20855    // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
20856    if (encoded_dt.IsValid()) {
20857      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20858        EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20859                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20860                   rd.Encode(22, 12) | rm.Encode(5, 0));
20861        AdvanceIT();
20862        return;
20863      }
20864    }
20865  } else {
20866    // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
20867    if (encoded_dt.IsValid()) {
20868      if (cond.Is(al)) {
20869        EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20870                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20871                rd.Encode(22, 12) | rm.Encode(5, 0));
20872        return;
20873      }
20874    }
20875  }
20876  Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
20877}
20878
20879void Assembler::vpadd(
20880    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20881  VIXL_ASSERT(AllowAssembler());
20882  CheckIT(cond);
20883  Dt_size_4 encoded_dt(dt);
20884  if (IsUsingT32()) {
20885    // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20886    if (dt.Is(F32)) {
20887      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20888        EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20889                   rm.Encode(5, 0));
20890        AdvanceIT();
20891        return;
20892      }
20893    }
20894    // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20895    if (encoded_dt.IsValid()) {
20896      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20897        EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) |
20898                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20899        AdvanceIT();
20900        return;
20901      }
20902    }
20903  } else {
20904    // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
20905    if (dt.Is(F32)) {
20906      if (cond.Is(al)) {
20907        EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20908                rm.Encode(5, 0));
20909        return;
20910      }
20911    }
20912    // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20913    if (encoded_dt.IsValid()) {
20914      if (cond.Is(al)) {
20915        EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) |
20916                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20917        return;
20918      }
20919    }
20920  }
20921  Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm);
20922}
20923
20924void Assembler::vpaddl(Condition cond,
20925                       DataType dt,
20926                       DRegister rd,
20927                       DRegister rm) {
20928  VIXL_ASSERT(AllowAssembler());
20929  CheckIT(cond);
20930  Dt_op_size_2 encoded_dt(dt);
20931  if (IsUsingT32()) {
20932    // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20933    if (encoded_dt.IsValid()) {
20934      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20935        EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20936                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20937                   rd.Encode(22, 12) | rm.Encode(5, 0));
20938        AdvanceIT();
20939        return;
20940      }
20941    }
20942  } else {
20943    // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
20944    if (encoded_dt.IsValid()) {
20945      if (cond.Is(al)) {
20946        EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20947                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20948                rd.Encode(22, 12) | rm.Encode(5, 0));
20949        return;
20950      }
20951    }
20952  }
20953  Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
20954}
20955
20956void Assembler::vpaddl(Condition cond,
20957                       DataType dt,
20958                       QRegister rd,
20959                       QRegister rm) {
20960  VIXL_ASSERT(AllowAssembler());
20961  CheckIT(cond);
20962  Dt_op_size_2 encoded_dt(dt);
20963  if (IsUsingT32()) {
20964    // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
20965    if (encoded_dt.IsValid()) {
20966      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20967        EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20968                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20969                   rd.Encode(22, 12) | rm.Encode(5, 0));
20970        AdvanceIT();
20971        return;
20972      }
20973    }
20974  } else {
20975    // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
20976    if (encoded_dt.IsValid()) {
20977      if (cond.Is(al)) {
20978        EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20979                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20980                rd.Encode(22, 12) | rm.Encode(5, 0));
20981        return;
20982      }
20983    }
20984  }
20985  Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
20986}
20987
20988void Assembler::vpmax(
20989    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20990  VIXL_ASSERT(AllowAssembler());
20991  CheckIT(cond);
20992  Dt_U_size_1 encoded_dt(dt);
20993  if (IsUsingT32()) {
20994    // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20995    if (dt.Is(F32)) {
20996      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20997        EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20998                   rm.Encode(5, 0));
20999        AdvanceIT();
21000        return;
21001      }
21002    }
21003    // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21004    if (encoded_dt.IsValid()) {
21005      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21006        EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21007                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21008                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21009        AdvanceIT();
21010        return;
21011      }
21012    }
21013  } else {
21014    // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
21015    if (dt.Is(F32)) {
21016      if (cond.Is(al)) {
21017        EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21018                rm.Encode(5, 0));
21019        return;
21020      }
21021    }
21022    // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21023    if (encoded_dt.IsValid()) {
21024      if (cond.Is(al)) {
21025        EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21026                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21027                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21028        return;
21029      }
21030    }
21031  }
21032  Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm);
21033}
21034
21035void Assembler::vpmin(
21036    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21037  VIXL_ASSERT(AllowAssembler());
21038  CheckIT(cond);
21039  Dt_U_size_1 encoded_dt(dt);
21040  if (IsUsingT32()) {
21041    // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
21042    if (dt.Is(F32)) {
21043      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21044        EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21045                   rm.Encode(5, 0));
21046        AdvanceIT();
21047        return;
21048      }
21049    }
21050    // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21051    if (encoded_dt.IsValid()) {
21052      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21053        EmitT32_32(0xef000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21054                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21055                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21056        AdvanceIT();
21057        return;
21058      }
21059    }
21060  } else {
21061    // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
21062    if (dt.Is(F32)) {
21063      if (cond.Is(al)) {
21064        EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21065                rm.Encode(5, 0));
21066        return;
21067      }
21068    }
21069    // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21070    if (encoded_dt.IsValid()) {
21071      if (cond.Is(al)) {
21072        EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21073                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21074                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21075        return;
21076      }
21077    }
21078  }
21079  Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm);
21080}
21081
21082void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) {
21083  VIXL_ASSERT(AllowAssembler());
21084  CheckIT(cond);
21085  USE(dt);
21086  if (IsUsingT32()) {
21087    // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1
21088    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
21089      const DRegister& dreg = dreglist.GetFirstDRegister();
21090      unsigned len = dreglist.GetLength() * 2;
21091      EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff));
21092      AdvanceIT();
21093      return;
21094    }
21095  } else {
21096    // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1
21097    if (cond.IsNotNever() &&
21098        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
21099      const DRegister& dreg = dreglist.GetFirstDRegister();
21100      unsigned len = dreglist.GetLength() * 2;
21101      EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
21102              (len & 0xff));
21103      return;
21104    }
21105  }
21106  Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist);
21107}
21108
21109void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) {
21110  VIXL_ASSERT(AllowAssembler());
21111  CheckIT(cond);
21112  USE(dt);
21113  if (IsUsingT32()) {
21114    // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2
21115    const SRegister& sreg = sreglist.GetFirstSRegister();
21116    unsigned len = sreglist.GetLength();
21117    EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff));
21118    AdvanceIT();
21119    return;
21120  } else {
21121    // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2
21122    if (cond.IsNotNever()) {
21123      const SRegister& sreg = sreglist.GetFirstSRegister();
21124      unsigned len = sreglist.GetLength();
21125      EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
21126              (len & 0xff));
21127      return;
21128    }
21129  }
21130  Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist);
21131}
21132
21133void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) {
21134  VIXL_ASSERT(AllowAssembler());
21135  CheckIT(cond);
21136  USE(dt);
21137  if (IsUsingT32()) {
21138    // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1
21139    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
21140      const DRegister& dreg = dreglist.GetFirstDRegister();
21141      unsigned len = dreglist.GetLength() * 2;
21142      EmitT32_32(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff));
21143      AdvanceIT();
21144      return;
21145    }
21146  } else {
21147    // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1
21148    if (cond.IsNotNever() &&
21149        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
21150      const DRegister& dreg = dreglist.GetFirstDRegister();
21151      unsigned len = dreglist.GetLength() * 2;
21152      EmitA32(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
21153              (len & 0xff));
21154      return;
21155    }
21156  }
21157  Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist);
21158}
21159
21160void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) {
21161  VIXL_ASSERT(AllowAssembler());
21162  CheckIT(cond);
21163  USE(dt);
21164  if (IsUsingT32()) {
21165    // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2
21166    const SRegister& sreg = sreglist.GetFirstSRegister();
21167    unsigned len = sreglist.GetLength();
21168    EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff));
21169    AdvanceIT();
21170    return;
21171  } else {
21172    // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2
21173    if (cond.IsNotNever()) {
21174      const SRegister& sreg = sreglist.GetFirstSRegister();
21175      unsigned len = sreglist.GetLength();
21176      EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
21177              (len & 0xff));
21178      return;
21179    }
21180  }
21181  Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist);
21182}
21183
21184void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
21185  VIXL_ASSERT(AllowAssembler());
21186  CheckIT(cond);
21187  Dt_size_5 encoded_dt(dt);
21188  if (IsUsingT32()) {
21189    // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
21190    if (encoded_dt.IsValid()) {
21191      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21192        EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) |
21193                   rd.Encode(22, 12) | rm.Encode(5, 0));
21194        AdvanceIT();
21195        return;
21196      }
21197    }
21198  } else {
21199    // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
21200    if (encoded_dt.IsValid()) {
21201      if (cond.Is(al)) {
21202        EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) |
21203                rd.Encode(22, 12) | rm.Encode(5, 0));
21204        return;
21205      }
21206    }
21207  }
21208  Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
21209}
21210
21211void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
21212  VIXL_ASSERT(AllowAssembler());
21213  CheckIT(cond);
21214  Dt_size_5 encoded_dt(dt);
21215  if (IsUsingT32()) {
21216    // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
21217    if (encoded_dt.IsValid()) {
21218      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21219        EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) |
21220                   rd.Encode(22, 12) | rm.Encode(5, 0));
21221        AdvanceIT();
21222        return;
21223      }
21224    }
21225  } else {
21226    // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
21227    if (encoded_dt.IsValid()) {
21228      if (cond.Is(al)) {
21229        EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) |
21230                rd.Encode(22, 12) | rm.Encode(5, 0));
21231        return;
21232      }
21233    }
21234  }
21235  Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
21236}
21237
21238void Assembler::vqadd(
21239    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21240  VIXL_ASSERT(AllowAssembler());
21241  CheckIT(cond);
21242  Dt_U_size_3 encoded_dt(dt);
21243  if (IsUsingT32()) {
21244    // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21245    if (encoded_dt.IsValid()) {
21246      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21247        EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21248                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21249                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21250        AdvanceIT();
21251        return;
21252      }
21253    }
21254  } else {
21255    // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21256    if (encoded_dt.IsValid()) {
21257      if (cond.Is(al)) {
21258        EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21259                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21260                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21261        return;
21262      }
21263    }
21264  }
21265  Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
21266}
21267
21268void Assembler::vqadd(
21269    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21270  VIXL_ASSERT(AllowAssembler());
21271  CheckIT(cond);
21272  Dt_U_size_3 encoded_dt(dt);
21273  if (IsUsingT32()) {
21274    // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21275    if (encoded_dt.IsValid()) {
21276      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21277        EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21278                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21279                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21280        AdvanceIT();
21281        return;
21282      }
21283    }
21284  } else {
21285    // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21286    if (encoded_dt.IsValid()) {
21287      if (cond.Is(al)) {
21288        EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21289                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21290                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21291        return;
21292      }
21293    }
21294  }
21295  Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
21296}
21297
21298void Assembler::vqdmlal(
21299    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21300  VIXL_ASSERT(AllowAssembler());
21301  CheckIT(cond);
21302  Dt_size_13 encoded_dt(dt);
21303  if (IsUsingT32()) {
21304    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21305    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21306      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21307        EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) |
21308                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21309        AdvanceIT();
21310        return;
21311      }
21312    }
21313  } else {
21314    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21315    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21316      if (cond.Is(al)) {
21317        EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) |
21318                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21319        return;
21320      }
21321    }
21322  }
21323  Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm);
21324}
21325
21326void Assembler::vqdmlal(Condition cond,
21327                        DataType dt,
21328                        QRegister rd,
21329                        DRegister rn,
21330                        DRegister dm,
21331                        unsigned index) {
21332  VIXL_ASSERT(AllowAssembler());
21333  CheckIT(cond);
21334  Dt_size_13 encoded_dt(dt);
21335  if (IsUsingT32()) {
21336    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
21337    if (encoded_dt.IsValid() &&
21338        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21339         (!dt.Is(S16) && (index <= 1))) &&
21340        (dt.Is(S16) || dt.Is(S32))) {
21341      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21342        uint32_t shift = 4;
21343        if (dt.Is(S16)) {
21344          shift = 3;
21345        }
21346        uint32_t mvm = dm.GetCode() | index << shift;
21347        EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) |
21348                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21349                   ((mvm & 0x10) << 1));
21350        AdvanceIT();
21351        return;
21352      }
21353    }
21354  } else {
21355    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
21356    if (encoded_dt.IsValid() &&
21357        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21358         (!dt.Is(S16) && (index <= 1))) &&
21359        (dt.Is(S16) || dt.Is(S32))) {
21360      if (cond.Is(al)) {
21361        uint32_t shift = 4;
21362        if (dt.Is(S16)) {
21363          shift = 3;
21364        }
21365        uint32_t mvm = dm.GetCode() | index << shift;
21366        EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) |
21367                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21368                ((mvm & 0x10) << 1));
21369        return;
21370      }
21371    }
21372  }
21373  Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index);
21374}
21375
21376void Assembler::vqdmlsl(
21377    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21378  VIXL_ASSERT(AllowAssembler());
21379  CheckIT(cond);
21380  Dt_size_13 encoded_dt(dt);
21381  if (IsUsingT32()) {
21382    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21383    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21384      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21385        EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) |
21386                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21387        AdvanceIT();
21388        return;
21389      }
21390    }
21391  } else {
21392    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21393    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21394      if (cond.Is(al)) {
21395        EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) |
21396                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21397        return;
21398      }
21399    }
21400  }
21401  Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm);
21402}
21403
21404void Assembler::vqdmlsl(Condition cond,
21405                        DataType dt,
21406                        QRegister rd,
21407                        DRegister rn,
21408                        DRegister dm,
21409                        unsigned index) {
21410  VIXL_ASSERT(AllowAssembler());
21411  CheckIT(cond);
21412  Dt_size_13 encoded_dt(dt);
21413  if (IsUsingT32()) {
21414    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
21415    if (encoded_dt.IsValid() &&
21416        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21417         (!dt.Is(S16) && (index <= 1))) &&
21418        (dt.Is(S16) || dt.Is(S32))) {
21419      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21420        uint32_t shift = 4;
21421        if (dt.Is(S16)) {
21422          shift = 3;
21423        }
21424        uint32_t mvm = dm.GetCode() | index << shift;
21425        EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) |
21426                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21427                   ((mvm & 0x10) << 1));
21428        AdvanceIT();
21429        return;
21430      }
21431    }
21432  } else {
21433    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
21434    if (encoded_dt.IsValid() &&
21435        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21436         (!dt.Is(S16) && (index <= 1))) &&
21437        (dt.Is(S16) || dt.Is(S32))) {
21438      if (cond.Is(al)) {
21439        uint32_t shift = 4;
21440        if (dt.Is(S16)) {
21441          shift = 3;
21442        }
21443        uint32_t mvm = dm.GetCode() | index << shift;
21444        EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) |
21445                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21446                ((mvm & 0x10) << 1));
21447        return;
21448      }
21449    }
21450  }
21451  Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index);
21452}
21453
21454void Assembler::vqdmulh(
21455    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21456  VIXL_ASSERT(AllowAssembler());
21457  CheckIT(cond);
21458  Dt_size_13 encoded_dt(dt);
21459  if (IsUsingT32()) {
21460    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21461    if (encoded_dt.IsValid()) {
21462      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21463        EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) |
21464                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21465        AdvanceIT();
21466        return;
21467      }
21468    }
21469  } else {
21470    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21471    if (encoded_dt.IsValid()) {
21472      if (cond.Is(al)) {
21473        EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) |
21474                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21475        return;
21476      }
21477    }
21478  }
21479  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21480}
21481
21482void Assembler::vqdmulh(
21483    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21484  VIXL_ASSERT(AllowAssembler());
21485  CheckIT(cond);
21486  Dt_size_13 encoded_dt(dt);
21487  if (IsUsingT32()) {
21488    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21489    if (encoded_dt.IsValid()) {
21490      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21491        EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) |
21492                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21493        AdvanceIT();
21494        return;
21495      }
21496    }
21497  } else {
21498    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21499    if (encoded_dt.IsValid()) {
21500      if (cond.Is(al)) {
21501        EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) |
21502                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21503        return;
21504      }
21505    }
21506  }
21507  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21508}
21509
21510void Assembler::vqdmulh(
21511    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
21512  VIXL_ASSERT(AllowAssembler());
21513  CheckIT(cond);
21514  Dt_size_13 encoded_dt(dt);
21515  if (IsUsingT32()) {
21516    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
21517    if (encoded_dt.IsValid() &&
21518        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21519         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21520          (rm.GetLane() <= 1))) &&
21521        (dt.Is(S16) || dt.Is(S32))) {
21522      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21523        EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) |
21524                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21525        AdvanceIT();
21526        return;
21527      }
21528    }
21529  } else {
21530    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
21531    if (encoded_dt.IsValid() &&
21532        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21533         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21534          (rm.GetLane() <= 1))) &&
21535        (dt.Is(S16) || dt.Is(S32))) {
21536      if (cond.Is(al)) {
21537        EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) |
21538                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21539        return;
21540      }
21541    }
21542  }
21543  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21544}
21545
21546void Assembler::vqdmulh(
21547    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
21548  VIXL_ASSERT(AllowAssembler());
21549  CheckIT(cond);
21550  Dt_size_13 encoded_dt(dt);
21551  if (IsUsingT32()) {
21552    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
21553    if (encoded_dt.IsValid() &&
21554        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21555         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21556          (rm.GetLane() <= 1))) &&
21557        (dt.Is(S16) || dt.Is(S32))) {
21558      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21559        EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) |
21560                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21561        AdvanceIT();
21562        return;
21563      }
21564    }
21565  } else {
21566    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
21567    if (encoded_dt.IsValid() &&
21568        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21569         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21570          (rm.GetLane() <= 1))) &&
21571        (dt.Is(S16) || dt.Is(S32))) {
21572      if (cond.Is(al)) {
21573        EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) |
21574                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21575        return;
21576      }
21577    }
21578  }
21579  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21580}
21581
21582void Assembler::vqdmull(
21583    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21584  VIXL_ASSERT(AllowAssembler());
21585  CheckIT(cond);
21586  Dt_size_13 encoded_dt(dt);
21587  if (IsUsingT32()) {
21588    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21589    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21590      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21591        EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) |
21592                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21593        AdvanceIT();
21594        return;
21595      }
21596    }
21597  } else {
21598    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21599    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21600      if (cond.Is(al)) {
21601        EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) |
21602                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21603        return;
21604      }
21605    }
21606  }
21607  Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
21608}
21609
21610void Assembler::vqdmull(
21611    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
21612  VIXL_ASSERT(AllowAssembler());
21613  CheckIT(cond);
21614  Dt_size_13 encoded_dt(dt);
21615  if (IsUsingT32()) {
21616    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2
21617    if (encoded_dt.IsValid() &&
21618        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21619         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21620          (rm.GetLane() <= 1))) &&
21621        (dt.Is(S16) || dt.Is(S32))) {
21622      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21623        EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) |
21624                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21625        AdvanceIT();
21626        return;
21627      }
21628    }
21629  } else {
21630    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2
21631    if (encoded_dt.IsValid() &&
21632        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21633         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21634          (rm.GetLane() <= 1))) &&
21635        (dt.Is(S16) || dt.Is(S32))) {
21636      if (cond.Is(al)) {
21637        EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) |
21638                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21639        return;
21640      }
21641    }
21642  }
21643  Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
21644}
21645
21646void Assembler::vqmovn(Condition cond,
21647                       DataType dt,
21648                       DRegister rd,
21649                       QRegister rm) {
21650  VIXL_ASSERT(AllowAssembler());
21651  CheckIT(cond);
21652  Dt_op_size_3 encoded_dt(dt);
21653  if (IsUsingT32()) {
21654    // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
21655    if (encoded_dt.IsValid()) {
21656      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21657        EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21658                   ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21659                   rd.Encode(22, 12) | rm.Encode(5, 0));
21660        AdvanceIT();
21661        return;
21662      }
21663    }
21664  } else {
21665    // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
21666    if (encoded_dt.IsValid()) {
21667      if (cond.Is(al)) {
21668        EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21669                ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21670                rd.Encode(22, 12) | rm.Encode(5, 0));
21671        return;
21672      }
21673    }
21674  }
21675  Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm);
21676}
21677
21678void Assembler::vqmovun(Condition cond,
21679                        DataType dt,
21680                        DRegister rd,
21681                        QRegister rm) {
21682  VIXL_ASSERT(AllowAssembler());
21683  CheckIT(cond);
21684  Dt_size_14 encoded_dt(dt);
21685  if (IsUsingT32()) {
21686    // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
21687    if (encoded_dt.IsValid()) {
21688      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21689        EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) |
21690                   rd.Encode(22, 12) | rm.Encode(5, 0));
21691        AdvanceIT();
21692        return;
21693      }
21694    }
21695  } else {
21696    // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
21697    if (encoded_dt.IsValid()) {
21698      if (cond.Is(al)) {
21699        EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) |
21700                rd.Encode(22, 12) | rm.Encode(5, 0));
21701        return;
21702      }
21703    }
21704  }
21705  Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm);
21706}
21707
21708void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
21709  VIXL_ASSERT(AllowAssembler());
21710  CheckIT(cond);
21711  Dt_size_5 encoded_dt(dt);
21712  if (IsUsingT32()) {
21713    // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
21714    if (encoded_dt.IsValid()) {
21715      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21716        EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) |
21717                   rd.Encode(22, 12) | rm.Encode(5, 0));
21718        AdvanceIT();
21719        return;
21720      }
21721    }
21722  } else {
21723    // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
21724    if (encoded_dt.IsValid()) {
21725      if (cond.Is(al)) {
21726        EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) |
21727                rd.Encode(22, 12) | rm.Encode(5, 0));
21728        return;
21729      }
21730    }
21731  }
21732  Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
21733}
21734
21735void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
21736  VIXL_ASSERT(AllowAssembler());
21737  CheckIT(cond);
21738  Dt_size_5 encoded_dt(dt);
21739  if (IsUsingT32()) {
21740    // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
21741    if (encoded_dt.IsValid()) {
21742      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21743        EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) |
21744                   rd.Encode(22, 12) | rm.Encode(5, 0));
21745        AdvanceIT();
21746        return;
21747      }
21748    }
21749  } else {
21750    // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
21751    if (encoded_dt.IsValid()) {
21752      if (cond.Is(al)) {
21753        EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) |
21754                rd.Encode(22, 12) | rm.Encode(5, 0));
21755        return;
21756      }
21757    }
21758  }
21759  Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
21760}
21761
21762void Assembler::vqrdmulh(
21763    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21764  VIXL_ASSERT(AllowAssembler());
21765  CheckIT(cond);
21766  Dt_size_13 encoded_dt(dt);
21767  if (IsUsingT32()) {
21768    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21769    if (encoded_dt.IsValid()) {
21770      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21771        EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) |
21772                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21773        AdvanceIT();
21774        return;
21775      }
21776    }
21777  } else {
21778    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21779    if (encoded_dt.IsValid()) {
21780      if (cond.Is(al)) {
21781        EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) |
21782                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21783        return;
21784      }
21785    }
21786  }
21787  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21788}
21789
21790void Assembler::vqrdmulh(
21791    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21792  VIXL_ASSERT(AllowAssembler());
21793  CheckIT(cond);
21794  Dt_size_13 encoded_dt(dt);
21795  if (IsUsingT32()) {
21796    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21797    if (encoded_dt.IsValid()) {
21798      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21799        EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) |
21800                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21801        AdvanceIT();
21802        return;
21803      }
21804    }
21805  } else {
21806    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21807    if (encoded_dt.IsValid()) {
21808      if (cond.Is(al)) {
21809        EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) |
21810                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21811        return;
21812      }
21813    }
21814  }
21815  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21816}
21817
21818void Assembler::vqrdmulh(
21819    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
21820  VIXL_ASSERT(AllowAssembler());
21821  CheckIT(cond);
21822  Dt_size_13 encoded_dt(dt);
21823  if (IsUsingT32()) {
21824    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
21825    if (encoded_dt.IsValid() &&
21826        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21827         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21828          (rm.GetLane() <= 1))) &&
21829        (dt.Is(S16) || dt.Is(S32))) {
21830      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21831        EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) |
21832                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21833        AdvanceIT();
21834        return;
21835      }
21836    }
21837  } else {
21838    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
21839    if (encoded_dt.IsValid() &&
21840        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21841         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21842          (rm.GetLane() <= 1))) &&
21843        (dt.Is(S16) || dt.Is(S32))) {
21844      if (cond.Is(al)) {
21845        EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) |
21846                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21847        return;
21848      }
21849    }
21850  }
21851  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21852}
21853
21854void Assembler::vqrdmulh(
21855    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
21856  VIXL_ASSERT(AllowAssembler());
21857  CheckIT(cond);
21858  Dt_size_13 encoded_dt(dt);
21859  if (IsUsingT32()) {
21860    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
21861    if (encoded_dt.IsValid() &&
21862        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21863         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21864          (rm.GetLane() <= 1))) &&
21865        (dt.Is(S16) || dt.Is(S32))) {
21866      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21867        EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) |
21868                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21869        AdvanceIT();
21870        return;
21871      }
21872    }
21873  } else {
21874    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
21875    if (encoded_dt.IsValid() &&
21876        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21877         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21878          (rm.GetLane() <= 1))) &&
21879        (dt.Is(S16) || dt.Is(S32))) {
21880      if (cond.Is(al)) {
21881        EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) |
21882                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21883        return;
21884      }
21885    }
21886  }
21887  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21888}
21889
21890void Assembler::vqrshl(
21891    Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
21892  VIXL_ASSERT(AllowAssembler());
21893  CheckIT(cond);
21894  Dt_U_size_3 encoded_dt(dt);
21895  if (IsUsingT32()) {
21896    // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
21897    if (encoded_dt.IsValid()) {
21898      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21899        EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21900                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21901                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21902        AdvanceIT();
21903        return;
21904      }
21905    }
21906  } else {
21907    // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
21908    if (encoded_dt.IsValid()) {
21909      if (cond.Is(al)) {
21910        EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21911                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21912                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21913        return;
21914      }
21915    }
21916  }
21917  Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
21918}
21919
21920void Assembler::vqrshl(
21921    Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
21922  VIXL_ASSERT(AllowAssembler());
21923  CheckIT(cond);
21924  Dt_U_size_3 encoded_dt(dt);
21925  if (IsUsingT32()) {
21926    // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
21927    if (encoded_dt.IsValid()) {
21928      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21929        EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21930                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21931                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21932        AdvanceIT();
21933        return;
21934      }
21935    }
21936  } else {
21937    // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
21938    if (encoded_dt.IsValid()) {
21939      if (cond.Is(al)) {
21940        EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21941                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21942                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21943        return;
21944      }
21945    }
21946  }
21947  Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
21948}
21949
21950void Assembler::vqrshrn(Condition cond,
21951                        DataType dt,
21952                        DRegister rd,
21953                        QRegister rm,
21954                        const QOperand& operand) {
21955  VIXL_ASSERT(AllowAssembler());
21956  CheckIT(cond);
21957  if (operand.IsImmediate()) {
21958    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
21959      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
21960      Dt_op_size_3 encoded_dt(dt);
21961      Dt_imm6_1 encoded_dt_2(dt);
21962      if (IsUsingT32()) {
21963        // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
21964        if (encoded_dt.IsValid() && (imm == 0)) {
21965          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21966            EmitT32_32(0xffb20280U |
21967                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21968                       ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21969                       rd.Encode(22, 12) | rm.Encode(5, 0));
21970            AdvanceIT();
21971            return;
21972          }
21973        }
21974        // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
21975        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
21976          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21977            uint32_t imm6 = dt.GetSize() / 2 - imm;
21978            EmitT32_32(0xef800950U |
21979                       (encoded_dt_2.GetTypeEncodingValue() << 28) |
21980                       ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
21981                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21982            AdvanceIT();
21983            return;
21984          }
21985        }
21986      } else {
21987        // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
21988        if (encoded_dt.IsValid() && (imm == 0)) {
21989          if (cond.Is(al)) {
21990            EmitA32(0xf3b20280U |
21991                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21992                    ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21993                    rd.Encode(22, 12) | rm.Encode(5, 0));
21994            return;
21995          }
21996        }
21997        // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
21998        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
21999          if (cond.Is(al)) {
22000            uint32_t imm6 = dt.GetSize() / 2 - imm;
22001            EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
22002                    ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
22003                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22004            return;
22005          }
22006        }
22007      }
22008    }
22009  }
22010  Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand);
22011}
22012
22013void Assembler::vqrshrun(Condition cond,
22014                         DataType dt,
22015                         DRegister rd,
22016                         QRegister rm,
22017                         const QOperand& operand) {
22018  VIXL_ASSERT(AllowAssembler());
22019  CheckIT(cond);
22020  if (operand.IsImmediate()) {
22021    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22022      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22023      Dt_imm6_2 encoded_dt(dt);
22024      Dt_size_14 encoded_dt_2(dt);
22025      if (IsUsingT32()) {
22026        // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
22027        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22028          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22029            uint32_t imm6 = dt.GetSize() / 2 - imm;
22030            EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) |
22031                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22032                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22033            AdvanceIT();
22034            return;
22035          }
22036        }
22037        // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
22038        if (encoded_dt_2.IsValid() && (imm == 0)) {
22039          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22040            EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22041                       rd.Encode(22, 12) | rm.Encode(5, 0));
22042            AdvanceIT();
22043            return;
22044          }
22045        }
22046      } else {
22047        // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
22048        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22049          if (cond.Is(al)) {
22050            uint32_t imm6 = dt.GetSize() / 2 - imm;
22051            EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) |
22052                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22053                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22054            return;
22055          }
22056        }
22057        // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
22058        if (encoded_dt_2.IsValid() && (imm == 0)) {
22059          if (cond.Is(al)) {
22060            EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22061                    rd.Encode(22, 12) | rm.Encode(5, 0));
22062            return;
22063          }
22064        }
22065      }
22066    }
22067  }
22068  Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand);
22069}
22070
22071void Assembler::vqshl(Condition cond,
22072                      DataType dt,
22073                      DRegister rd,
22074                      DRegister rm,
22075                      const DOperand& operand) {
22076  VIXL_ASSERT(AllowAssembler());
22077  CheckIT(cond);
22078  if (operand.IsRegister()) {
22079    DRegister rn = operand.GetRegister();
22080    Dt_U_size_3 encoded_dt(dt);
22081    if (IsUsingT32()) {
22082      // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
22083      if (encoded_dt.IsValid()) {
22084        if (cond.Is(al) || AllowStronglyDiscouraged()) {
22085          EmitT32_32(0xef000410U |
22086                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22087                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22088                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22089          AdvanceIT();
22090          return;
22091        }
22092      }
22093    } else {
22094      // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
22095      if (encoded_dt.IsValid()) {
22096        if (cond.Is(al)) {
22097          EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22098                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22099                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22100          return;
22101        }
22102      }
22103    }
22104  }
22105  if (operand.IsImmediate()) {
22106    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22107      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22108      Dt_L_imm6_1 encoded_dt(dt);
22109      if (IsUsingT32()) {
22110        // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
22111        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22112          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22113            uint32_t imm6 = imm;
22114            EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) |
22115                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22116                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22117                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22118            AdvanceIT();
22119            return;
22120          }
22121        }
22122      } else {
22123        // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
22124        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22125          if (cond.Is(al)) {
22126            uint32_t imm6 = imm;
22127            EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) |
22128                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22129                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22130                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22131            return;
22132          }
22133        }
22134      }
22135    }
22136  }
22137  Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
22138}
22139
22140void Assembler::vqshl(Condition cond,
22141                      DataType dt,
22142                      QRegister rd,
22143                      QRegister rm,
22144                      const QOperand& operand) {
22145  VIXL_ASSERT(AllowAssembler());
22146  CheckIT(cond);
22147  if (operand.IsRegister()) {
22148    QRegister rn = operand.GetRegister();
22149    Dt_U_size_3 encoded_dt(dt);
22150    if (IsUsingT32()) {
22151      // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
22152      if (encoded_dt.IsValid()) {
22153        if (cond.Is(al) || AllowStronglyDiscouraged()) {
22154          EmitT32_32(0xef000450U |
22155                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22156                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22157                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22158          AdvanceIT();
22159          return;
22160        }
22161      }
22162    } else {
22163      // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
22164      if (encoded_dt.IsValid()) {
22165        if (cond.Is(al)) {
22166          EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22167                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22168                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22169          return;
22170        }
22171      }
22172    }
22173  }
22174  if (operand.IsImmediate()) {
22175    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22176      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22177      Dt_L_imm6_1 encoded_dt(dt);
22178      if (IsUsingT32()) {
22179        // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
22180        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22181          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22182            uint32_t imm6 = imm;
22183            EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) |
22184                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22185                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22186                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22187            AdvanceIT();
22188            return;
22189          }
22190        }
22191      } else {
22192        // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
22193        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22194          if (cond.Is(al)) {
22195            uint32_t imm6 = imm;
22196            EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) |
22197                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22198                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22199                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22200            return;
22201          }
22202        }
22203      }
22204    }
22205  }
22206  Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
22207}
22208
22209void Assembler::vqshlu(Condition cond,
22210                       DataType dt,
22211                       DRegister rd,
22212                       DRegister rm,
22213                       const DOperand& operand) {
22214  VIXL_ASSERT(AllowAssembler());
22215  CheckIT(cond);
22216  if (operand.IsImmediate()) {
22217    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22218      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22219      Dt_L_imm6_2 encoded_dt(dt);
22220      if (IsUsingT32()) {
22221        // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
22222        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22223          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22224            uint32_t imm6 = imm;
22225            EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) |
22226                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22227                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22228                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22229            AdvanceIT();
22230            return;
22231          }
22232        }
22233      } else {
22234        // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
22235        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22236          if (cond.Is(al)) {
22237            uint32_t imm6 = imm;
22238            EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) |
22239                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22240                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22241                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22242            return;
22243          }
22244        }
22245      }
22246    }
22247  }
22248  Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
22249}
22250
22251void Assembler::vqshlu(Condition cond,
22252                       DataType dt,
22253                       QRegister rd,
22254                       QRegister rm,
22255                       const QOperand& operand) {
22256  VIXL_ASSERT(AllowAssembler());
22257  CheckIT(cond);
22258  if (operand.IsImmediate()) {
22259    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22260      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22261      Dt_L_imm6_2 encoded_dt(dt);
22262      if (IsUsingT32()) {
22263        // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
22264        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22265          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22266            uint32_t imm6 = imm;
22267            EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) |
22268                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22269                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22270                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22271            AdvanceIT();
22272            return;
22273          }
22274        }
22275      } else {
22276        // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
22277        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22278          if (cond.Is(al)) {
22279            uint32_t imm6 = imm;
22280            EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) |
22281                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22282                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22283                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22284            return;
22285          }
22286        }
22287      }
22288    }
22289  }
22290  Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
22291}
22292
22293void Assembler::vqshrn(Condition cond,
22294                       DataType dt,
22295                       DRegister rd,
22296                       QRegister rm,
22297                       const QOperand& operand) {
22298  VIXL_ASSERT(AllowAssembler());
22299  CheckIT(cond);
22300  if (operand.IsImmediate()) {
22301    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22302      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22303      Dt_op_size_3 encoded_dt(dt);
22304      Dt_imm6_1 encoded_dt_2(dt);
22305      if (IsUsingT32()) {
22306        // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
22307        if (encoded_dt.IsValid() && (imm == 0)) {
22308          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22309            EmitT32_32(0xffb20280U |
22310                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22311                       ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22312                       rd.Encode(22, 12) | rm.Encode(5, 0));
22313            AdvanceIT();
22314            return;
22315          }
22316        }
22317        // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
22318        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22319          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22320            uint32_t imm6 = dt.GetSize() / 2 - imm;
22321            EmitT32_32(0xef800910U |
22322                       (encoded_dt_2.GetTypeEncodingValue() << 28) |
22323                       ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
22324                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22325            AdvanceIT();
22326            return;
22327          }
22328        }
22329      } else {
22330        // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
22331        if (encoded_dt.IsValid() && (imm == 0)) {
22332          if (cond.Is(al)) {
22333            EmitA32(0xf3b20280U |
22334                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22335                    ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22336                    rd.Encode(22, 12) | rm.Encode(5, 0));
22337            return;
22338          }
22339        }
22340        // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
22341        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22342          if (cond.Is(al)) {
22343            uint32_t imm6 = dt.GetSize() / 2 - imm;
22344            EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
22345                    ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
22346                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22347            return;
22348          }
22349        }
22350      }
22351    }
22352  }
22353  Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand);
22354}
22355
22356void Assembler::vqshrun(Condition cond,
22357                        DataType dt,
22358                        DRegister rd,
22359                        QRegister rm,
22360                        const QOperand& operand) {
22361  VIXL_ASSERT(AllowAssembler());
22362  CheckIT(cond);
22363  if (operand.IsImmediate()) {
22364    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22365      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22366      Dt_imm6_2 encoded_dt(dt);
22367      Dt_size_14 encoded_dt_2(dt);
22368      if (IsUsingT32()) {
22369        // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
22370        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22371          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22372            uint32_t imm6 = dt.GetSize() / 2 - imm;
22373            EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) |
22374                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22375                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22376            AdvanceIT();
22377            return;
22378          }
22379        }
22380        // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
22381        if (encoded_dt_2.IsValid() && (imm == 0)) {
22382          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22383            EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22384                       rd.Encode(22, 12) | rm.Encode(5, 0));
22385            AdvanceIT();
22386            return;
22387          }
22388        }
22389      } else {
22390        // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
22391        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22392          if (cond.Is(al)) {
22393            uint32_t imm6 = dt.GetSize() / 2 - imm;
22394            EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) |
22395                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22396                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22397            return;
22398          }
22399        }
22400        // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
22401        if (encoded_dt_2.IsValid() && (imm == 0)) {
22402          if (cond.Is(al)) {
22403            EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22404                    rd.Encode(22, 12) | rm.Encode(5, 0));
22405            return;
22406          }
22407        }
22408      }
22409    }
22410  }
22411  Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand);
22412}
22413
22414void Assembler::vqsub(
22415    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22416  VIXL_ASSERT(AllowAssembler());
22417  CheckIT(cond);
22418  Dt_U_size_3 encoded_dt(dt);
22419  if (IsUsingT32()) {
22420    // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22421    if (encoded_dt.IsValid()) {
22422      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22423        EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22424                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22425                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22426        AdvanceIT();
22427        return;
22428      }
22429    }
22430  } else {
22431    // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22432    if (encoded_dt.IsValid()) {
22433      if (cond.Is(al)) {
22434        EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22435                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22436                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22437        return;
22438      }
22439    }
22440  }
22441  Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
22442}
22443
22444void Assembler::vqsub(
22445    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22446  VIXL_ASSERT(AllowAssembler());
22447  CheckIT(cond);
22448  Dt_U_size_3 encoded_dt(dt);
22449  if (IsUsingT32()) {
22450    // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22451    if (encoded_dt.IsValid()) {
22452      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22453        EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22454                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22455                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22456        AdvanceIT();
22457        return;
22458      }
22459    }
22460  } else {
22461    // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22462    if (encoded_dt.IsValid()) {
22463      if (cond.Is(al)) {
22464        EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22465                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22466                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22467        return;
22468      }
22469    }
22470  }
22471  Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
22472}
22473
22474void Assembler::vraddhn(
22475    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
22476  VIXL_ASSERT(AllowAssembler());
22477  CheckIT(cond);
22478  Dt_size_3 encoded_dt(dt);
22479  if (IsUsingT32()) {
22480    // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
22481    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
22482      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22483        EmitT32_32(0xff800400U | (encoded_dt.GetEncodingValue() << 20) |
22484                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22485        AdvanceIT();
22486        return;
22487      }
22488    }
22489  } else {
22490    // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
22491    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
22492      if (cond.Is(al)) {
22493        EmitA32(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) |
22494                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22495        return;
22496      }
22497    }
22498  }
22499  Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm);
22500}
22501
22502void Assembler::vrecpe(Condition cond,
22503                       DataType dt,
22504                       DRegister rd,
22505                       DRegister rm) {
22506  VIXL_ASSERT(AllowAssembler());
22507  CheckIT(cond);
22508  Dt_F_size_4 encoded_dt(dt);
22509  if (IsUsingT32()) {
22510    // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22511    if (encoded_dt.IsValid()) {
22512      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22513        EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22514                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22515                   rd.Encode(22, 12) | rm.Encode(5, 0));
22516        AdvanceIT();
22517        return;
22518      }
22519    }
22520  } else {
22521    // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22522    if (encoded_dt.IsValid()) {
22523      if (cond.Is(al)) {
22524        EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22525                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22526                rd.Encode(22, 12) | rm.Encode(5, 0));
22527        return;
22528      }
22529    }
22530  }
22531  Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
22532}
22533
22534void Assembler::vrecpe(Condition cond,
22535                       DataType dt,
22536                       QRegister rd,
22537                       QRegister rm) {
22538  VIXL_ASSERT(AllowAssembler());
22539  CheckIT(cond);
22540  Dt_F_size_4 encoded_dt(dt);
22541  if (IsUsingT32()) {
22542    // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22543    if (encoded_dt.IsValid()) {
22544      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22545        EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22546                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22547                   rd.Encode(22, 12) | rm.Encode(5, 0));
22548        AdvanceIT();
22549        return;
22550      }
22551    }
22552  } else {
22553    // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22554    if (encoded_dt.IsValid()) {
22555      if (cond.Is(al)) {
22556        EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22557                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22558                rd.Encode(22, 12) | rm.Encode(5, 0));
22559        return;
22560      }
22561    }
22562  }
22563  Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
22564}
22565
22566void Assembler::vrecps(
22567    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22568  VIXL_ASSERT(AllowAssembler());
22569  CheckIT(cond);
22570  if (IsUsingT32()) {
22571    // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
22572    if (dt.Is(F32)) {
22573      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22574        EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22575                   rm.Encode(5, 0));
22576        AdvanceIT();
22577        return;
22578      }
22579    }
22580  } else {
22581    // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
22582    if (dt.Is(F32)) {
22583      if (cond.Is(al)) {
22584        EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22585                rm.Encode(5, 0));
22586        return;
22587      }
22588    }
22589  }
22590  Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
22591}
22592
22593void Assembler::vrecps(
22594    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22595  VIXL_ASSERT(AllowAssembler());
22596  CheckIT(cond);
22597  if (IsUsingT32()) {
22598    // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
22599    if (dt.Is(F32)) {
22600      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22601        EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22602                   rm.Encode(5, 0));
22603        AdvanceIT();
22604        return;
22605      }
22606    }
22607  } else {
22608    // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
22609    if (dt.Is(F32)) {
22610      if (cond.Is(al)) {
22611        EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22612                rm.Encode(5, 0));
22613        return;
22614      }
22615    }
22616  }
22617  Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
22618}
22619
22620void Assembler::vrev16(Condition cond,
22621                       DataType dt,
22622                       DRegister rd,
22623                       DRegister rm) {
22624  VIXL_ASSERT(AllowAssembler());
22625  CheckIT(cond);
22626  Dt_size_1 encoded_dt(dt);
22627  if (IsUsingT32()) {
22628    // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22629    if (encoded_dt.IsValid()) {
22630      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22631        EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) |
22632                   rd.Encode(22, 12) | rm.Encode(5, 0));
22633        AdvanceIT();
22634        return;
22635      }
22636    }
22637  } else {
22638    // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22639    if (encoded_dt.IsValid()) {
22640      if (cond.Is(al)) {
22641        EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) |
22642                rd.Encode(22, 12) | rm.Encode(5, 0));
22643        return;
22644      }
22645    }
22646  }
22647  Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
22648}
22649
22650void Assembler::vrev16(Condition cond,
22651                       DataType dt,
22652                       QRegister rd,
22653                       QRegister rm) {
22654  VIXL_ASSERT(AllowAssembler());
22655  CheckIT(cond);
22656  Dt_size_1 encoded_dt(dt);
22657  if (IsUsingT32()) {
22658    // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22659    if (encoded_dt.IsValid()) {
22660      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22661        EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) |
22662                   rd.Encode(22, 12) | rm.Encode(5, 0));
22663        AdvanceIT();
22664        return;
22665      }
22666    }
22667  } else {
22668    // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22669    if (encoded_dt.IsValid()) {
22670      if (cond.Is(al)) {
22671        EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) |
22672                rd.Encode(22, 12) | rm.Encode(5, 0));
22673        return;
22674      }
22675    }
22676  }
22677  Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
22678}
22679
22680void Assembler::vrev32(Condition cond,
22681                       DataType dt,
22682                       DRegister rd,
22683                       DRegister rm) {
22684  VIXL_ASSERT(AllowAssembler());
22685  CheckIT(cond);
22686  Dt_size_15 encoded_dt(dt);
22687  if (IsUsingT32()) {
22688    // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22689    if (encoded_dt.IsValid()) {
22690      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22691        EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) |
22692                   rd.Encode(22, 12) | rm.Encode(5, 0));
22693        AdvanceIT();
22694        return;
22695      }
22696    }
22697  } else {
22698    // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22699    if (encoded_dt.IsValid()) {
22700      if (cond.Is(al)) {
22701        EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) |
22702                rd.Encode(22, 12) | rm.Encode(5, 0));
22703        return;
22704      }
22705    }
22706  }
22707  Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
22708}
22709
22710void Assembler::vrev32(Condition cond,
22711                       DataType dt,
22712                       QRegister rd,
22713                       QRegister rm) {
22714  VIXL_ASSERT(AllowAssembler());
22715  CheckIT(cond);
22716  Dt_size_15 encoded_dt(dt);
22717  if (IsUsingT32()) {
22718    // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22719    if (encoded_dt.IsValid()) {
22720      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22721        EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) |
22722                   rd.Encode(22, 12) | rm.Encode(5, 0));
22723        AdvanceIT();
22724        return;
22725      }
22726    }
22727  } else {
22728    // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22729    if (encoded_dt.IsValid()) {
22730      if (cond.Is(al)) {
22731        EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) |
22732                rd.Encode(22, 12) | rm.Encode(5, 0));
22733        return;
22734      }
22735    }
22736  }
22737  Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
22738}
22739
22740void Assembler::vrev64(Condition cond,
22741                       DataType dt,
22742                       DRegister rd,
22743                       DRegister rm) {
22744  VIXL_ASSERT(AllowAssembler());
22745  CheckIT(cond);
22746  Dt_size_7 encoded_dt(dt);
22747  if (IsUsingT32()) {
22748    // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22749    if (encoded_dt.IsValid()) {
22750      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22751        EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) |
22752                   rd.Encode(22, 12) | rm.Encode(5, 0));
22753        AdvanceIT();
22754        return;
22755      }
22756    }
22757  } else {
22758    // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22759    if (encoded_dt.IsValid()) {
22760      if (cond.Is(al)) {
22761        EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) |
22762                rd.Encode(22, 12) | rm.Encode(5, 0));
22763        return;
22764      }
22765    }
22766  }
22767  Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
22768}
22769
22770void Assembler::vrev64(Condition cond,
22771                       DataType dt,
22772                       QRegister rd,
22773                       QRegister rm) {
22774  VIXL_ASSERT(AllowAssembler());
22775  CheckIT(cond);
22776  Dt_size_7 encoded_dt(dt);
22777  if (IsUsingT32()) {
22778    // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22779    if (encoded_dt.IsValid()) {
22780      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22781        EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) |
22782                   rd.Encode(22, 12) | rm.Encode(5, 0));
22783        AdvanceIT();
22784        return;
22785      }
22786    }
22787  } else {
22788    // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22789    if (encoded_dt.IsValid()) {
22790      if (cond.Is(al)) {
22791        EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) |
22792                rd.Encode(22, 12) | rm.Encode(5, 0));
22793        return;
22794      }
22795    }
22796  }
22797  Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
22798}
22799
22800void Assembler::vrhadd(
22801    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22802  VIXL_ASSERT(AllowAssembler());
22803  CheckIT(cond);
22804  Dt_U_size_1 encoded_dt(dt);
22805  if (IsUsingT32()) {
22806    // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22807    if (encoded_dt.IsValid()) {
22808      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22809        EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22810                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22811                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22812        AdvanceIT();
22813        return;
22814      }
22815    }
22816  } else {
22817    // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22818    if (encoded_dt.IsValid()) {
22819      if (cond.Is(al)) {
22820        EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22821                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22822                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22823        return;
22824      }
22825    }
22826  }
22827  Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
22828}
22829
22830void Assembler::vrhadd(
22831    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22832  VIXL_ASSERT(AllowAssembler());
22833  CheckIT(cond);
22834  Dt_U_size_1 encoded_dt(dt);
22835  if (IsUsingT32()) {
22836    // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22837    if (encoded_dt.IsValid()) {
22838      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22839        EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22840                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22841                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22842        AdvanceIT();
22843        return;
22844      }
22845    }
22846  } else {
22847    // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22848    if (encoded_dt.IsValid()) {
22849      if (cond.Is(al)) {
22850        EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22851                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22852                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22853        return;
22854      }
22855    }
22856  }
22857  Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
22858}
22859
22860void Assembler::vrinta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22861  VIXL_ASSERT(AllowAssembler());
22862  CheckIT(al);
22863  if (IsUsingT32()) {
22864    // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; T1
22865    if (dt1.Is(F32) && dt2.Is(F32)) {
22866      EmitT32_32(0xffba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
22867      AdvanceIT();
22868      return;
22869    }
22870    // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; T1
22871    if (dt1.Is(F64) && dt2.Is(F64)) {
22872      EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22873      AdvanceIT();
22874      return;
22875    }
22876  } else {
22877    // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; A1
22878    if (dt1.Is(F32) && dt2.Is(F32)) {
22879      EmitA32(0xf3ba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
22880      return;
22881    }
22882    // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; A1
22883    if (dt1.Is(F64) && dt2.Is(F64)) {
22884      EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22885      return;
22886    }
22887  }
22888  Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22889}
22890
22891void Assembler::vrinta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
22892  VIXL_ASSERT(AllowAssembler());
22893  CheckIT(al);
22894  if (IsUsingT32()) {
22895    // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; T1
22896    if (dt1.Is(F32) && dt2.Is(F32)) {
22897      EmitT32_32(0xffba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
22898      AdvanceIT();
22899      return;
22900    }
22901  } else {
22902    // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; A1
22903    if (dt1.Is(F32) && dt2.Is(F32)) {
22904      EmitA32(0xf3ba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
22905      return;
22906    }
22907  }
22908  Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22909}
22910
22911void Assembler::vrinta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
22912  VIXL_ASSERT(AllowAssembler());
22913  CheckIT(al);
22914  if (IsUsingT32()) {
22915    // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; T1
22916    if (dt1.Is(F32) && dt2.Is(F32)) {
22917      EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22918      AdvanceIT();
22919      return;
22920    }
22921  } else {
22922    // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; A1
22923    if (dt1.Is(F32) && dt2.Is(F32)) {
22924      EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22925      return;
22926    }
22927  }
22928  Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22929}
22930
22931void Assembler::vrintm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22932  VIXL_ASSERT(AllowAssembler());
22933  CheckIT(al);
22934  if (IsUsingT32()) {
22935    // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; T1
22936    if (dt1.Is(F32) && dt2.Is(F32)) {
22937      EmitT32_32(0xffba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
22938      AdvanceIT();
22939      return;
22940    }
22941    // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; T1
22942    if (dt1.Is(F64) && dt2.Is(F64)) {
22943      EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22944      AdvanceIT();
22945      return;
22946    }
22947  } else {
22948    // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; A1
22949    if (dt1.Is(F32) && dt2.Is(F32)) {
22950      EmitA32(0xf3ba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
22951      return;
22952    }
22953    // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; A1
22954    if (dt1.Is(F64) && dt2.Is(F64)) {
22955      EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22956      return;
22957    }
22958  }
22959  Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
22960}
22961
22962void Assembler::vrintm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
22963  VIXL_ASSERT(AllowAssembler());
22964  CheckIT(al);
22965  if (IsUsingT32()) {
22966    // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; T1
22967    if (dt1.Is(F32) && dt2.Is(F32)) {
22968      EmitT32_32(0xffba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22969      AdvanceIT();
22970      return;
22971    }
22972  } else {
22973    // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; A1
22974    if (dt1.Is(F32) && dt2.Is(F32)) {
22975      EmitA32(0xf3ba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22976      return;
22977    }
22978  }
22979  Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
22980}
22981
22982void Assembler::vrintm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
22983  VIXL_ASSERT(AllowAssembler());
22984  CheckIT(al);
22985  if (IsUsingT32()) {
22986    // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; T1
22987    if (dt1.Is(F32) && dt2.Is(F32)) {
22988      EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22989      AdvanceIT();
22990      return;
22991    }
22992  } else {
22993    // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; A1
22994    if (dt1.Is(F32) && dt2.Is(F32)) {
22995      EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22996      return;
22997    }
22998  }
22999  Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
23000}
23001
23002void Assembler::vrintn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23003  VIXL_ASSERT(AllowAssembler());
23004  CheckIT(al);
23005  if (IsUsingT32()) {
23006    // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; T1
23007    if (dt1.Is(F32) && dt2.Is(F32)) {
23008      EmitT32_32(0xffba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
23009      AdvanceIT();
23010      return;
23011    }
23012    // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; T1
23013    if (dt1.Is(F64) && dt2.Is(F64)) {
23014      EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23015      AdvanceIT();
23016      return;
23017    }
23018  } else {
23019    // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; A1
23020    if (dt1.Is(F32) && dt2.Is(F32)) {
23021      EmitA32(0xf3ba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
23022      return;
23023    }
23024    // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; A1
23025    if (dt1.Is(F64) && dt2.Is(F64)) {
23026      EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23027      return;
23028    }
23029  }
23030  Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
23031}
23032
23033void Assembler::vrintn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23034  VIXL_ASSERT(AllowAssembler());
23035  CheckIT(al);
23036  if (IsUsingT32()) {
23037    // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; T1
23038    if (dt1.Is(F32) && dt2.Is(F32)) {
23039      EmitT32_32(0xffba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
23040      AdvanceIT();
23041      return;
23042    }
23043  } else {
23044    // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; A1
23045    if (dt1.Is(F32) && dt2.Is(F32)) {
23046      EmitA32(0xf3ba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
23047      return;
23048    }
23049  }
23050  Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
23051}
23052
23053void Assembler::vrintn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23054  VIXL_ASSERT(AllowAssembler());
23055  CheckIT(al);
23056  if (IsUsingT32()) {
23057    // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; T1
23058    if (dt1.Is(F32) && dt2.Is(F32)) {
23059      EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23060      AdvanceIT();
23061      return;
23062    }
23063  } else {
23064    // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; A1
23065    if (dt1.Is(F32) && dt2.Is(F32)) {
23066      EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23067      return;
23068    }
23069  }
23070  Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
23071}
23072
23073void Assembler::vrintp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23074  VIXL_ASSERT(AllowAssembler());
23075  CheckIT(al);
23076  if (IsUsingT32()) {
23077    // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; T1
23078    if (dt1.Is(F32) && dt2.Is(F32)) {
23079      EmitT32_32(0xffba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
23080      AdvanceIT();
23081      return;
23082    }
23083    // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; T1
23084    if (dt1.Is(F64) && dt2.Is(F64)) {
23085      EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23086      AdvanceIT();
23087      return;
23088    }
23089  } else {
23090    // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; A1
23091    if (dt1.Is(F32) && dt2.Is(F32)) {
23092      EmitA32(0xf3ba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
23093      return;
23094    }
23095    // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; A1
23096    if (dt1.Is(F64) && dt2.Is(F64)) {
23097      EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23098      return;
23099    }
23100  }
23101  Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
23102}
23103
23104void Assembler::vrintp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23105  VIXL_ASSERT(AllowAssembler());
23106  CheckIT(al);
23107  if (IsUsingT32()) {
23108    // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; T1
23109    if (dt1.Is(F32) && dt2.Is(F32)) {
23110      EmitT32_32(0xffba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23111      AdvanceIT();
23112      return;
23113    }
23114  } else {
23115    // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; A1
23116    if (dt1.Is(F32) && dt2.Is(F32)) {
23117      EmitA32(0xf3ba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23118      return;
23119    }
23120  }
23121  Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
23122}
23123
23124void Assembler::vrintp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23125  VIXL_ASSERT(AllowAssembler());
23126  CheckIT(al);
23127  if (IsUsingT32()) {
23128    // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; T1
23129    if (dt1.Is(F32) && dt2.Is(F32)) {
23130      EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23131      AdvanceIT();
23132      return;
23133    }
23134  } else {
23135    // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; A1
23136    if (dt1.Is(F32) && dt2.Is(F32)) {
23137      EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23138      return;
23139    }
23140  }
23141  Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
23142}
23143
23144void Assembler::vrintr(
23145    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23146  VIXL_ASSERT(AllowAssembler());
23147  CheckIT(cond);
23148  if (IsUsingT32()) {
23149    // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
23150    if (dt1.Is(F32) && dt2.Is(F32)) {
23151      EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23152      AdvanceIT();
23153      return;
23154    }
23155  } else {
23156    // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
23157    if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
23158      EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23159              rm.Encode(5, 0));
23160      return;
23161    }
23162  }
23163  Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
23164}
23165
23166void Assembler::vrintr(
23167    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23168  VIXL_ASSERT(AllowAssembler());
23169  CheckIT(cond);
23170  if (IsUsingT32()) {
23171    // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
23172    if (dt1.Is(F64) && dt2.Is(F64)) {
23173      EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23174      AdvanceIT();
23175      return;
23176    }
23177  } else {
23178    // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
23179    if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
23180      EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23181              rm.Encode(5, 0));
23182      return;
23183    }
23184  }
23185  Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
23186}
23187
23188void Assembler::vrintx(
23189    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23190  VIXL_ASSERT(AllowAssembler());
23191  CheckIT(cond);
23192  if (IsUsingT32()) {
23193    // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; T1
23194    if (dt1.Is(F32) && dt2.Is(F32)) {
23195      EmitT32_32(0xffba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
23196      AdvanceIT();
23197      return;
23198    }
23199    // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
23200    if (dt1.Is(F64) && dt2.Is(F64)) {
23201      EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23202      AdvanceIT();
23203      return;
23204    }
23205  } else {
23206    // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; A1
23207    if (dt1.Is(F32) && dt2.Is(F32)) {
23208      EmitA32(0xf3ba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
23209      return;
23210    }
23211    // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
23212    if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
23213      EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23214              rm.Encode(5, 0));
23215      return;
23216    }
23217  }
23218  Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
23219}
23220
23221void Assembler::vrintx(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23222  VIXL_ASSERT(AllowAssembler());
23223  CheckIT(al);
23224  if (IsUsingT32()) {
23225    // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; T1
23226    if (dt1.Is(F32) && dt2.Is(F32)) {
23227      EmitT32_32(0xffba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23228      AdvanceIT();
23229      return;
23230    }
23231  } else {
23232    // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; A1
23233    if (dt1.Is(F32) && dt2.Is(F32)) {
23234      EmitA32(0xf3ba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23235      return;
23236    }
23237  }
23238  Delegate(kVrintx, &Assembler::vrintx, dt1, dt2, rd, rm);
23239}
23240
23241void Assembler::vrintx(
23242    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23243  VIXL_ASSERT(AllowAssembler());
23244  CheckIT(cond);
23245  if (IsUsingT32()) {
23246    // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
23247    if (dt1.Is(F32) && dt2.Is(F32)) {
23248      EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23249      AdvanceIT();
23250      return;
23251    }
23252  } else {
23253    // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
23254    if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
23255      EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23256              rm.Encode(5, 0));
23257      return;
23258    }
23259  }
23260  Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
23261}
23262
23263void Assembler::vrintz(
23264    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23265  VIXL_ASSERT(AllowAssembler());
23266  CheckIT(cond);
23267  if (IsUsingT32()) {
23268    // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; T1
23269    if (dt1.Is(F32) && dt2.Is(F32)) {
23270      EmitT32_32(0xffba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
23271      AdvanceIT();
23272      return;
23273    }
23274    // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
23275    if (dt1.Is(F64) && dt2.Is(F64)) {
23276      EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23277      AdvanceIT();
23278      return;
23279    }
23280  } else {
23281    // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; A1
23282    if (dt1.Is(F32) && dt2.Is(F32)) {
23283      EmitA32(0xf3ba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
23284      return;
23285    }
23286    // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
23287    if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
23288      EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23289              rm.Encode(5, 0));
23290      return;
23291    }
23292  }
23293  Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
23294}
23295
23296void Assembler::vrintz(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23297  VIXL_ASSERT(AllowAssembler());
23298  CheckIT(al);
23299  if (IsUsingT32()) {
23300    // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; T1
23301    if (dt1.Is(F32) && dt2.Is(F32)) {
23302      EmitT32_32(0xffba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23303      AdvanceIT();
23304      return;
23305    }
23306  } else {
23307    // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; A1
23308    if (dt1.Is(F32) && dt2.Is(F32)) {
23309      EmitA32(0xf3ba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23310      return;
23311    }
23312  }
23313  Delegate(kVrintz, &Assembler::vrintz, dt1, dt2, rd, rm);
23314}
23315
23316void Assembler::vrintz(
23317    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23318  VIXL_ASSERT(AllowAssembler());
23319  CheckIT(cond);
23320  if (IsUsingT32()) {
23321    // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
23322    if (dt1.Is(F32) && dt2.Is(F32)) {
23323      EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23324      AdvanceIT();
23325      return;
23326    }
23327  } else {
23328    // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
23329    if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
23330      EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23331              rm.Encode(5, 0));
23332      return;
23333    }
23334  }
23335  Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
23336}
23337
23338void Assembler::vrshl(
23339    Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
23340  VIXL_ASSERT(AllowAssembler());
23341  CheckIT(cond);
23342  Dt_U_size_3 encoded_dt(dt);
23343  if (IsUsingT32()) {
23344    // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
23345    if (encoded_dt.IsValid()) {
23346      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23347        EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23348                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23349                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23350        AdvanceIT();
23351        return;
23352      }
23353    }
23354  } else {
23355    // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
23356    if (encoded_dt.IsValid()) {
23357      if (cond.Is(al)) {
23358        EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23359                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23360                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23361        return;
23362      }
23363    }
23364  }
23365  Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
23366}
23367
23368void Assembler::vrshl(
23369    Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
23370  VIXL_ASSERT(AllowAssembler());
23371  CheckIT(cond);
23372  Dt_U_size_3 encoded_dt(dt);
23373  if (IsUsingT32()) {
23374    // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
23375    if (encoded_dt.IsValid()) {
23376      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23377        EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23378                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23379                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23380        AdvanceIT();
23381        return;
23382      }
23383    }
23384  } else {
23385    // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
23386    if (encoded_dt.IsValid()) {
23387      if (cond.Is(al)) {
23388        EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23389                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23390                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23391        return;
23392      }
23393    }
23394  }
23395  Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
23396}
23397
23398void Assembler::vrshr(Condition cond,
23399                      DataType dt,
23400                      DRegister rd,
23401                      DRegister rm,
23402                      const DOperand& operand) {
23403  VIXL_ASSERT(AllowAssembler());
23404  CheckIT(cond);
23405  if (operand.IsImmediate()) {
23406    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23407      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23408      Dt_L_imm6_1 encoded_dt(dt);
23409      if (IsUsingT32()) {
23410        // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23411        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23412          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23413            uint32_t imm6 = dt.GetSize() - imm;
23414            EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) |
23415                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23416                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23417                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23418            AdvanceIT();
23419            return;
23420          }
23421        }
23422        // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
23423        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23424          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23425            EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23426                       rm.Encode(5, 0));
23427            AdvanceIT();
23428            return;
23429          }
23430        }
23431      } else {
23432        // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23433        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23434          if (cond.Is(al)) {
23435            uint32_t imm6 = dt.GetSize() - imm;
23436            EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) |
23437                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23438                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23439                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23440            return;
23441          }
23442        }
23443        // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
23444        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23445          if (cond.Is(al)) {
23446            EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23447                    rm.Encode(5, 0));
23448            return;
23449          }
23450        }
23451      }
23452    }
23453  }
23454  Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
23455}
23456
23457void Assembler::vrshr(Condition cond,
23458                      DataType dt,
23459                      QRegister rd,
23460                      QRegister rm,
23461                      const QOperand& operand) {
23462  VIXL_ASSERT(AllowAssembler());
23463  CheckIT(cond);
23464  if (operand.IsImmediate()) {
23465    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23466      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23467      Dt_L_imm6_1 encoded_dt(dt);
23468      if (IsUsingT32()) {
23469        // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23470        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23471          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23472            uint32_t imm6 = dt.GetSize() - imm;
23473            EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) |
23474                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23475                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23476                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23477            AdvanceIT();
23478            return;
23479          }
23480        }
23481        // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
23482        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23483          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23484            EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23485                       rm.Encode(5, 0));
23486            AdvanceIT();
23487            return;
23488          }
23489        }
23490      } else {
23491        // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23492        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23493          if (cond.Is(al)) {
23494            uint32_t imm6 = dt.GetSize() - imm;
23495            EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) |
23496                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23497                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23498                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23499            return;
23500          }
23501        }
23502        // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
23503        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23504          if (cond.Is(al)) {
23505            EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23506                    rm.Encode(5, 0));
23507            return;
23508          }
23509        }
23510      }
23511    }
23512  }
23513  Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
23514}
23515
23516void Assembler::vrshrn(Condition cond,
23517                       DataType dt,
23518                       DRegister rd,
23519                       QRegister rm,
23520                       const QOperand& operand) {
23521  VIXL_ASSERT(AllowAssembler());
23522  CheckIT(cond);
23523  if (operand.IsImmediate()) {
23524    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23525      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23526      Dt_imm6_3 encoded_dt(dt);
23527      Dt_size_3 encoded_dt_2(dt);
23528      if (IsUsingT32()) {
23529        // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
23530        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23531          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23532            uint32_t imm6 = dt.GetSize() / 2 - imm;
23533            EmitT32_32(0xef800850U |
23534                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23535                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23536            AdvanceIT();
23537            return;
23538          }
23539        }
23540        // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23541        if (encoded_dt_2.IsValid() && (imm == 0)) {
23542          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23543            EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
23544                       rd.Encode(22, 12) | rm.Encode(5, 0));
23545            AdvanceIT();
23546            return;
23547          }
23548        }
23549      } else {
23550        // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
23551        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23552          if (cond.Is(al)) {
23553            uint32_t imm6 = dt.GetSize() / 2 - imm;
23554            EmitA32(0xf2800850U |
23555                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23556                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23557            return;
23558          }
23559        }
23560        // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23561        if (encoded_dt_2.IsValid() && (imm == 0)) {
23562          if (cond.Is(al)) {
23563            EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
23564                    rd.Encode(22, 12) | rm.Encode(5, 0));
23565            return;
23566          }
23567        }
23568      }
23569    }
23570  }
23571  Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand);
23572}
23573
23574void Assembler::vrsqrte(Condition cond,
23575                        DataType dt,
23576                        DRegister rd,
23577                        DRegister rm) {
23578  VIXL_ASSERT(AllowAssembler());
23579  CheckIT(cond);
23580  Dt_F_size_4 encoded_dt(dt);
23581  if (IsUsingT32()) {
23582    // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
23583    if (encoded_dt.IsValid()) {
23584      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23585        EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23586                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23587                   rd.Encode(22, 12) | rm.Encode(5, 0));
23588        AdvanceIT();
23589        return;
23590      }
23591    }
23592  } else {
23593    // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
23594    if (encoded_dt.IsValid()) {
23595      if (cond.Is(al)) {
23596        EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23597                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23598                rd.Encode(22, 12) | rm.Encode(5, 0));
23599        return;
23600      }
23601    }
23602  }
23603  Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
23604}
23605
23606void Assembler::vrsqrte(Condition cond,
23607                        DataType dt,
23608                        QRegister rd,
23609                        QRegister rm) {
23610  VIXL_ASSERT(AllowAssembler());
23611  CheckIT(cond);
23612  Dt_F_size_4 encoded_dt(dt);
23613  if (IsUsingT32()) {
23614    // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
23615    if (encoded_dt.IsValid()) {
23616      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23617        EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23618                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23619                   rd.Encode(22, 12) | rm.Encode(5, 0));
23620        AdvanceIT();
23621        return;
23622      }
23623    }
23624  } else {
23625    // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
23626    if (encoded_dt.IsValid()) {
23627      if (cond.Is(al)) {
23628        EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23629                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23630                rd.Encode(22, 12) | rm.Encode(5, 0));
23631        return;
23632      }
23633    }
23634  }
23635  Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
23636}
23637
23638void Assembler::vrsqrts(
23639    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23640  VIXL_ASSERT(AllowAssembler());
23641  CheckIT(cond);
23642  if (IsUsingT32()) {
23643    // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
23644    if (dt.Is(F32)) {
23645      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23646        EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23647                   rm.Encode(5, 0));
23648        AdvanceIT();
23649        return;
23650      }
23651    }
23652  } else {
23653    // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
23654    if (dt.Is(F32)) {
23655      if (cond.Is(al)) {
23656        EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23657                rm.Encode(5, 0));
23658        return;
23659      }
23660    }
23661  }
23662  Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
23663}
23664
23665void Assembler::vrsqrts(
23666    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
23667  VIXL_ASSERT(AllowAssembler());
23668  CheckIT(cond);
23669  if (IsUsingT32()) {
23670    // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
23671    if (dt.Is(F32)) {
23672      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23673        EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23674                   rm.Encode(5, 0));
23675        AdvanceIT();
23676        return;
23677      }
23678    }
23679  } else {
23680    // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
23681    if (dt.Is(F32)) {
23682      if (cond.Is(al)) {
23683        EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23684                rm.Encode(5, 0));
23685        return;
23686      }
23687    }
23688  }
23689  Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
23690}
23691
23692void Assembler::vrsra(Condition cond,
23693                      DataType dt,
23694                      DRegister rd,
23695                      DRegister rm,
23696                      const DOperand& operand) {
23697  VIXL_ASSERT(AllowAssembler());
23698  CheckIT(cond);
23699  if (operand.IsImmediate()) {
23700    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23701      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23702      Dt_L_imm6_1 encoded_dt(dt);
23703      if (IsUsingT32()) {
23704        // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23705        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23706          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23707            uint32_t imm6 = dt.GetSize() - imm;
23708            EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) |
23709                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23710                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23711                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23712            AdvanceIT();
23713            return;
23714          }
23715        }
23716      } else {
23717        // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23718        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23719          if (cond.Is(al)) {
23720            uint32_t imm6 = dt.GetSize() - imm;
23721            EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) |
23722                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23723                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23724                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23725            return;
23726          }
23727        }
23728      }
23729    }
23730  }
23731  Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
23732}
23733
23734void Assembler::vrsra(Condition cond,
23735                      DataType dt,
23736                      QRegister rd,
23737                      QRegister rm,
23738                      const QOperand& operand) {
23739  VIXL_ASSERT(AllowAssembler());
23740  CheckIT(cond);
23741  if (operand.IsImmediate()) {
23742    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23743      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23744      Dt_L_imm6_1 encoded_dt(dt);
23745      if (IsUsingT32()) {
23746        // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23747        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23748          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23749            uint32_t imm6 = dt.GetSize() - imm;
23750            EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) |
23751                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23752                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23753                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23754            AdvanceIT();
23755            return;
23756          }
23757        }
23758      } else {
23759        // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23760        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23761          if (cond.Is(al)) {
23762            uint32_t imm6 = dt.GetSize() - imm;
23763            EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) |
23764                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23765                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23766                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23767            return;
23768          }
23769        }
23770      }
23771    }
23772  }
23773  Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
23774}
23775
23776void Assembler::vrsubhn(
23777    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
23778  VIXL_ASSERT(AllowAssembler());
23779  CheckIT(cond);
23780  Dt_size_3 encoded_dt(dt);
23781  if (IsUsingT32()) {
23782    // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
23783    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
23784      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23785        EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) |
23786                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23787        AdvanceIT();
23788        return;
23789      }
23790    }
23791  } else {
23792    // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
23793    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
23794      if (cond.Is(al)) {
23795        EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) |
23796                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23797        return;
23798      }
23799    }
23800  }
23801  Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm);
23802}
23803
23804void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23805  VIXL_ASSERT(AllowAssembler());
23806  CheckIT(al);
23807  if (IsUsingT32()) {
23808    // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1
23809    if (OutsideITBlock() && dt.Is(F64)) {
23810      EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23811                 rm.Encode(5, 0));
23812      AdvanceIT();
23813      return;
23814    }
23815  } else {
23816    // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1
23817    if (dt.Is(F64)) {
23818      EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23819              rm.Encode(5, 0));
23820      return;
23821    }
23822  }
23823  Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
23824}
23825
23826void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23827  VIXL_ASSERT(AllowAssembler());
23828  CheckIT(al);
23829  if (IsUsingT32()) {
23830    // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1
23831    if (OutsideITBlock() && dt.Is(F32)) {
23832      EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23833                 rm.Encode(5, 0));
23834      AdvanceIT();
23835      return;
23836    }
23837  } else {
23838    // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1
23839    if (dt.Is(F32)) {
23840      EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23841              rm.Encode(5, 0));
23842      return;
23843    }
23844  }
23845  Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
23846}
23847
23848void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23849  VIXL_ASSERT(AllowAssembler());
23850  CheckIT(al);
23851  if (IsUsingT32()) {
23852    // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1
23853    if (OutsideITBlock() && dt.Is(F64)) {
23854      EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23855                 rm.Encode(5, 0));
23856      AdvanceIT();
23857      return;
23858    }
23859  } else {
23860    // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1
23861    if (dt.Is(F64)) {
23862      EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23863              rm.Encode(5, 0));
23864      return;
23865    }
23866  }
23867  Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
23868}
23869
23870void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23871  VIXL_ASSERT(AllowAssembler());
23872  CheckIT(al);
23873  if (IsUsingT32()) {
23874    // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1
23875    if (OutsideITBlock() && dt.Is(F32)) {
23876      EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23877                 rm.Encode(5, 0));
23878      AdvanceIT();
23879      return;
23880    }
23881  } else {
23882    // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1
23883    if (dt.Is(F32)) {
23884      EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23885              rm.Encode(5, 0));
23886      return;
23887    }
23888  }
23889  Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
23890}
23891
23892void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23893  VIXL_ASSERT(AllowAssembler());
23894  CheckIT(al);
23895  if (IsUsingT32()) {
23896    // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1
23897    if (OutsideITBlock() && dt.Is(F64)) {
23898      EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23899                 rm.Encode(5, 0));
23900      AdvanceIT();
23901      return;
23902    }
23903  } else {
23904    // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1
23905    if (dt.Is(F64)) {
23906      EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23907              rm.Encode(5, 0));
23908      return;
23909    }
23910  }
23911  Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
23912}
23913
23914void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23915  VIXL_ASSERT(AllowAssembler());
23916  CheckIT(al);
23917  if (IsUsingT32()) {
23918    // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1
23919    if (OutsideITBlock() && dt.Is(F32)) {
23920      EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23921                 rm.Encode(5, 0));
23922      AdvanceIT();
23923      return;
23924    }
23925  } else {
23926    // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1
23927    if (dt.Is(F32)) {
23928      EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23929              rm.Encode(5, 0));
23930      return;
23931    }
23932  }
23933  Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
23934}
23935
23936void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23937  VIXL_ASSERT(AllowAssembler());
23938  CheckIT(al);
23939  if (IsUsingT32()) {
23940    // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1
23941    if (OutsideITBlock() && dt.Is(F64)) {
23942      EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23943                 rm.Encode(5, 0));
23944      AdvanceIT();
23945      return;
23946    }
23947  } else {
23948    // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1
23949    if (dt.Is(F64)) {
23950      EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23951              rm.Encode(5, 0));
23952      return;
23953    }
23954  }
23955  Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
23956}
23957
23958void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23959  VIXL_ASSERT(AllowAssembler());
23960  CheckIT(al);
23961  if (IsUsingT32()) {
23962    // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1
23963    if (OutsideITBlock() && dt.Is(F32)) {
23964      EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23965                 rm.Encode(5, 0));
23966      AdvanceIT();
23967      return;
23968    }
23969  } else {
23970    // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1
23971    if (dt.Is(F32)) {
23972      EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23973              rm.Encode(5, 0));
23974      return;
23975    }
23976  }
23977  Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
23978}
23979
23980void Assembler::vshl(Condition cond,
23981                     DataType dt,
23982                     DRegister rd,
23983                     DRegister rm,
23984                     const DOperand& operand) {
23985  VIXL_ASSERT(AllowAssembler());
23986  CheckIT(cond);
23987  if (operand.IsImmediate()) {
23988    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23989      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23990      Dt_L_imm6_3 encoded_dt(dt);
23991      if (IsUsingT32()) {
23992        // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1
23993        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23994          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23995            uint32_t imm6 = imm;
23996            EmitT32_32(0xef800510U |
23997                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23998                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23999                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24000            AdvanceIT();
24001            return;
24002          }
24003        }
24004      } else {
24005        // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1
24006        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24007          if (cond.Is(al)) {
24008            uint32_t imm6 = imm;
24009            EmitA32(0xf2800510U |
24010                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24011                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24012                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24013            return;
24014          }
24015        }
24016      }
24017    }
24018  }
24019  if (operand.IsRegister()) {
24020    DRegister rn = operand.GetRegister();
24021    Dt_U_size_3 encoded_dt(dt);
24022    if (IsUsingT32()) {
24023      // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
24024      if (encoded_dt.IsValid()) {
24025        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24026          EmitT32_32(0xef000400U |
24027                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24028                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24029                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24030          AdvanceIT();
24031          return;
24032        }
24033      }
24034    } else {
24035      // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
24036      if (encoded_dt.IsValid()) {
24037        if (cond.Is(al)) {
24038          EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24039                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24040                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24041          return;
24042        }
24043      }
24044    }
24045  }
24046  Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
24047}
24048
24049void Assembler::vshl(Condition cond,
24050                     DataType dt,
24051                     QRegister rd,
24052                     QRegister rm,
24053                     const QOperand& operand) {
24054  VIXL_ASSERT(AllowAssembler());
24055  CheckIT(cond);
24056  if (operand.IsImmediate()) {
24057    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24058      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24059      Dt_L_imm6_3 encoded_dt(dt);
24060      if (IsUsingT32()) {
24061        // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1
24062        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24063          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24064            uint32_t imm6 = imm;
24065            EmitT32_32(0xef800550U |
24066                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24067                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24068                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24069            AdvanceIT();
24070            return;
24071          }
24072        }
24073      } else {
24074        // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1
24075        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24076          if (cond.Is(al)) {
24077            uint32_t imm6 = imm;
24078            EmitA32(0xf2800550U |
24079                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24080                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24081                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24082            return;
24083          }
24084        }
24085      }
24086    }
24087  }
24088  if (operand.IsRegister()) {
24089    QRegister rn = operand.GetRegister();
24090    Dt_U_size_3 encoded_dt(dt);
24091    if (IsUsingT32()) {
24092      // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
24093      if (encoded_dt.IsValid()) {
24094        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24095          EmitT32_32(0xef000440U |
24096                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24097                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24098                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24099          AdvanceIT();
24100          return;
24101        }
24102      }
24103    } else {
24104      // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
24105      if (encoded_dt.IsValid()) {
24106        if (cond.Is(al)) {
24107          EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24108                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24109                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24110          return;
24111        }
24112      }
24113    }
24114  }
24115  Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
24116}
24117
24118void Assembler::vshll(Condition cond,
24119                      DataType dt,
24120                      QRegister rd,
24121                      DRegister rm,
24122                      const DOperand& operand) {
24123  VIXL_ASSERT(AllowAssembler());
24124  CheckIT(cond);
24125  if (operand.IsImmediate()) {
24126    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24127      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24128      Dt_imm6_4 encoded_dt(dt);
24129      Dt_size_16 encoded_dt_2(dt);
24130      if (IsUsingT32()) {
24131        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1
24132        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
24133          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24134            uint32_t imm6 = dt.GetSize() + imm;
24135            EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) |
24136                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24137                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24138            AdvanceIT();
24139            return;
24140          }
24141        }
24142        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2
24143        if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
24144          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24145            EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) |
24146                       rd.Encode(22, 12) | rm.Encode(5, 0));
24147            AdvanceIT();
24148            return;
24149          }
24150        }
24151      } else {
24152        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1
24153        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
24154          if (cond.Is(al)) {
24155            uint32_t imm6 = dt.GetSize() + imm;
24156            EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) |
24157                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24158                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24159            return;
24160          }
24161        }
24162        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2
24163        if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
24164          if (cond.Is(al)) {
24165            EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) |
24166                    rd.Encode(22, 12) | rm.Encode(5, 0));
24167            return;
24168          }
24169        }
24170      }
24171    }
24172  }
24173  Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand);
24174}
24175
24176void Assembler::vshr(Condition cond,
24177                     DataType dt,
24178                     DRegister rd,
24179                     DRegister rm,
24180                     const DOperand& operand) {
24181  VIXL_ASSERT(AllowAssembler());
24182  CheckIT(cond);
24183  if (operand.IsImmediate()) {
24184    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24185      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24186      Dt_L_imm6_1 encoded_dt(dt);
24187      if (IsUsingT32()) {
24188        // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
24189        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24190          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24191            uint32_t imm6 = dt.GetSize() - imm;
24192            EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) |
24193                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24194                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24195                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24196            AdvanceIT();
24197            return;
24198          }
24199        }
24200        // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
24201        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24202          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24203            EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24204                       rm.Encode(5, 0));
24205            AdvanceIT();
24206            return;
24207          }
24208        }
24209      } else {
24210        // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
24211        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24212          if (cond.Is(al)) {
24213            uint32_t imm6 = dt.GetSize() - imm;
24214            EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) |
24215                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24216                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24217                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24218            return;
24219          }
24220        }
24221        // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
24222        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24223          if (cond.Is(al)) {
24224            EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24225                    rm.Encode(5, 0));
24226            return;
24227          }
24228        }
24229      }
24230    }
24231  }
24232  Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
24233}
24234
24235void Assembler::vshr(Condition cond,
24236                     DataType dt,
24237                     QRegister rd,
24238                     QRegister rm,
24239                     const QOperand& operand) {
24240  VIXL_ASSERT(AllowAssembler());
24241  CheckIT(cond);
24242  if (operand.IsImmediate()) {
24243    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24244      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24245      Dt_L_imm6_1 encoded_dt(dt);
24246      if (IsUsingT32()) {
24247        // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
24248        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24249          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24250            uint32_t imm6 = dt.GetSize() - imm;
24251            EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) |
24252                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24253                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24254                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24255            AdvanceIT();
24256            return;
24257          }
24258        }
24259        // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
24260        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24261          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24262            EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24263                       rm.Encode(5, 0));
24264            AdvanceIT();
24265            return;
24266          }
24267        }
24268      } else {
24269        // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
24270        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24271          if (cond.Is(al)) {
24272            uint32_t imm6 = dt.GetSize() - imm;
24273            EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) |
24274                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24275                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24276                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24277            return;
24278          }
24279        }
24280        // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
24281        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24282          if (cond.Is(al)) {
24283            EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24284                    rm.Encode(5, 0));
24285            return;
24286          }
24287        }
24288      }
24289    }
24290  }
24291  Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
24292}
24293
24294void Assembler::vshrn(Condition cond,
24295                      DataType dt,
24296                      DRegister rd,
24297                      QRegister rm,
24298                      const QOperand& operand) {
24299  VIXL_ASSERT(AllowAssembler());
24300  CheckIT(cond);
24301  if (operand.IsImmediate()) {
24302    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24303      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24304      Dt_imm6_3 encoded_dt(dt);
24305      Dt_size_3 encoded_dt_2(dt);
24306      if (IsUsingT32()) {
24307        // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
24308        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
24309          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24310            uint32_t imm6 = dt.GetSize() / 2 - imm;
24311            EmitT32_32(0xef800810U |
24312                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24313                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24314            AdvanceIT();
24315            return;
24316          }
24317        }
24318        // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
24319        if (encoded_dt_2.IsValid() && (imm == 0)) {
24320          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24321            EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
24322                       rd.Encode(22, 12) | rm.Encode(5, 0));
24323            AdvanceIT();
24324            return;
24325          }
24326        }
24327      } else {
24328        // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
24329        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
24330          if (cond.Is(al)) {
24331            uint32_t imm6 = dt.GetSize() / 2 - imm;
24332            EmitA32(0xf2800810U |
24333                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24334                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24335            return;
24336          }
24337        }
24338        // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
24339        if (encoded_dt_2.IsValid() && (imm == 0)) {
24340          if (cond.Is(al)) {
24341            EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
24342                    rd.Encode(22, 12) | rm.Encode(5, 0));
24343            return;
24344          }
24345        }
24346      }
24347    }
24348  }
24349  Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand);
24350}
24351
24352void Assembler::vsli(Condition cond,
24353                     DataType dt,
24354                     DRegister rd,
24355                     DRegister rm,
24356                     const DOperand& operand) {
24357  VIXL_ASSERT(AllowAssembler());
24358  CheckIT(cond);
24359  if (operand.IsImmediate()) {
24360    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24361      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24362      Dt_L_imm6_4 encoded_dt(dt);
24363      if (IsUsingT32()) {
24364        // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
24365        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24366          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24367            uint32_t imm6 = imm;
24368            EmitT32_32(0xff800510U |
24369                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24370                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24371                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24372            AdvanceIT();
24373            return;
24374          }
24375        }
24376      } else {
24377        // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
24378        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24379          if (cond.Is(al)) {
24380            uint32_t imm6 = imm;
24381            EmitA32(0xf3800510U |
24382                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24383                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24384                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24385            return;
24386          }
24387        }
24388      }
24389    }
24390  }
24391  Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
24392}
24393
24394void Assembler::vsli(Condition cond,
24395                     DataType dt,
24396                     QRegister rd,
24397                     QRegister rm,
24398                     const QOperand& operand) {
24399  VIXL_ASSERT(AllowAssembler());
24400  CheckIT(cond);
24401  if (operand.IsImmediate()) {
24402    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24403      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24404      Dt_L_imm6_4 encoded_dt(dt);
24405      if (IsUsingT32()) {
24406        // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
24407        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24408          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24409            uint32_t imm6 = imm;
24410            EmitT32_32(0xff800550U |
24411                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24412                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24413                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24414            AdvanceIT();
24415            return;
24416          }
24417        }
24418      } else {
24419        // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
24420        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24421          if (cond.Is(al)) {
24422            uint32_t imm6 = imm;
24423            EmitA32(0xf3800550U |
24424                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24425                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24426                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24427            return;
24428          }
24429        }
24430      }
24431    }
24432  }
24433  Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
24434}
24435
24436void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) {
24437  VIXL_ASSERT(AllowAssembler());
24438  CheckIT(cond);
24439  if (IsUsingT32()) {
24440    // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
24441    if (dt.Is(F32)) {
24442      EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
24443      AdvanceIT();
24444      return;
24445    }
24446  } else {
24447    // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
24448    if (dt.Is(F32) && cond.IsNotNever()) {
24449      EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24450              rm.Encode(5, 0));
24451      return;
24452    }
24453  }
24454  Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
24455}
24456
24457void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
24458  VIXL_ASSERT(AllowAssembler());
24459  CheckIT(cond);
24460  if (IsUsingT32()) {
24461    // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
24462    if (dt.Is(F64)) {
24463      EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
24464      AdvanceIT();
24465      return;
24466    }
24467  } else {
24468    // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
24469    if (dt.Is(F64) && cond.IsNotNever()) {
24470      EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24471              rm.Encode(5, 0));
24472      return;
24473    }
24474  }
24475  Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
24476}
24477
24478void Assembler::vsra(Condition cond,
24479                     DataType dt,
24480                     DRegister rd,
24481                     DRegister rm,
24482                     const DOperand& operand) {
24483  VIXL_ASSERT(AllowAssembler());
24484  CheckIT(cond);
24485  if (operand.IsImmediate()) {
24486    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24487      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24488      Dt_L_imm6_1 encoded_dt(dt);
24489      if (IsUsingT32()) {
24490        // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
24491        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24492          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24493            uint32_t imm6 = dt.GetSize() - imm;
24494            EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) |
24495                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24496                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24497                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24498            AdvanceIT();
24499            return;
24500          }
24501        }
24502      } else {
24503        // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
24504        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24505          if (cond.Is(al)) {
24506            uint32_t imm6 = dt.GetSize() - imm;
24507            EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) |
24508                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24509                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24510                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24511            return;
24512          }
24513        }
24514      }
24515    }
24516  }
24517  Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
24518}
24519
24520void Assembler::vsra(Condition cond,
24521                     DataType dt,
24522                     QRegister rd,
24523                     QRegister rm,
24524                     const QOperand& operand) {
24525  VIXL_ASSERT(AllowAssembler());
24526  CheckIT(cond);
24527  if (operand.IsImmediate()) {
24528    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24529      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24530      Dt_L_imm6_1 encoded_dt(dt);
24531      if (IsUsingT32()) {
24532        // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
24533        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24534          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24535            uint32_t imm6 = dt.GetSize() - imm;
24536            EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) |
24537                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24538                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24539                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24540            AdvanceIT();
24541            return;
24542          }
24543        }
24544      } else {
24545        // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
24546        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24547          if (cond.Is(al)) {
24548            uint32_t imm6 = dt.GetSize() - imm;
24549            EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) |
24550                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24551                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24552                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24553            return;
24554          }
24555        }
24556      }
24557    }
24558  }
24559  Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
24560}
24561
24562void Assembler::vsri(Condition cond,
24563                     DataType dt,
24564                     DRegister rd,
24565                     DRegister rm,
24566                     const DOperand& operand) {
24567  VIXL_ASSERT(AllowAssembler());
24568  CheckIT(cond);
24569  if (operand.IsImmediate()) {
24570    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24571      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24572      Dt_L_imm6_4 encoded_dt(dt);
24573      if (IsUsingT32()) {
24574        // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
24575        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24576          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24577            uint32_t imm6 = dt.GetSize() - imm;
24578            EmitT32_32(0xff800410U |
24579                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24580                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24581                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24582            AdvanceIT();
24583            return;
24584          }
24585        }
24586      } else {
24587        // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
24588        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24589          if (cond.Is(al)) {
24590            uint32_t imm6 = dt.GetSize() - imm;
24591            EmitA32(0xf3800410U |
24592                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24593                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24594                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24595            return;
24596          }
24597        }
24598      }
24599    }
24600  }
24601  Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
24602}
24603
24604void Assembler::vsri(Condition cond,
24605                     DataType dt,
24606                     QRegister rd,
24607                     QRegister rm,
24608                     const QOperand& operand) {
24609  VIXL_ASSERT(AllowAssembler());
24610  CheckIT(cond);
24611  if (operand.IsImmediate()) {
24612    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24613      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24614      Dt_L_imm6_4 encoded_dt(dt);
24615      if (IsUsingT32()) {
24616        // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
24617        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24618          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24619            uint32_t imm6 = dt.GetSize() - imm;
24620            EmitT32_32(0xff800450U |
24621                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24622                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24623                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24624            AdvanceIT();
24625            return;
24626          }
24627        }
24628      } else {
24629        // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
24630        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24631          if (cond.Is(al)) {
24632            uint32_t imm6 = dt.GetSize() - imm;
24633            EmitA32(0xf3800450U |
24634                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24635                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24636                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24637            return;
24638          }
24639        }
24640      }
24641    }
24642  }
24643  Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
24644}
24645
24646void Assembler::vst1(Condition cond,
24647                     DataType dt,
24648                     const NeonRegisterList& nreglist,
24649                     const AlignedMemOperand& operand) {
24650  VIXL_ASSERT(AllowAssembler());
24651  CheckIT(cond);
24652  if (operand.IsImmediateZero()) {
24653    Register rn = operand.GetBaseRegister();
24654    Alignment align = operand.GetAlignment();
24655    Dt_size_6 encoded_dt(dt);
24656    Dt_size_7 encoded_dt_2(dt);
24657    Align_align_5 encoded_align_1(align, nreglist);
24658    Align_index_align_1 encoded_align_2(align, nreglist, dt);
24659    if (IsUsingT32()) {
24660      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24661      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24662          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24663          operand.IsOffset() && encoded_align_1.IsValid() &&
24664          ((!rn.IsPC()) || AllowUnpredictable())) {
24665        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24666          const DRegister& first = nreglist.GetFirstDRegister();
24667          uint32_t len_encoding;
24668          switch (nreglist.GetLength()) {
24669            default:
24670              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24671            case 1:
24672              len_encoding = 0x7;
24673              break;
24674            case 2:
24675              len_encoding = 0xa;
24676              break;
24677            case 3:
24678              len_encoding = 0x6;
24679              break;
24680            case 4:
24681              len_encoding = 0x2;
24682              break;
24683          }
24684          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
24685                     (encoded_align_1.GetEncodingValue() << 4) |
24686                     first.Encode(22, 12) | (len_encoding << 8) |
24687                     (rn.GetCode() << 16));
24688          AdvanceIT();
24689          return;
24690        }
24691      }
24692      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24693      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24694          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24695          operand.IsPostIndex() && encoded_align_1.IsValid() &&
24696          ((!rn.IsPC()) || AllowUnpredictable())) {
24697        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24698          const DRegister& first = nreglist.GetFirstDRegister();
24699          uint32_t len_encoding;
24700          switch (nreglist.GetLength()) {
24701            default:
24702              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24703            case 1:
24704              len_encoding = 0x7;
24705              break;
24706            case 2:
24707              len_encoding = 0xa;
24708              break;
24709            case 3:
24710              len_encoding = 0x6;
24711              break;
24712            case 4:
24713              len_encoding = 0x2;
24714              break;
24715          }
24716          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
24717                     (encoded_align_1.GetEncodingValue() << 4) |
24718                     first.Encode(22, 12) | (len_encoding << 8) |
24719                     (rn.GetCode() << 16));
24720          AdvanceIT();
24721          return;
24722        }
24723      }
24724      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24725      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24726          (nreglist.GetLength() == 1) && operand.IsOffset() &&
24727          encoded_align_2.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
24728        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24729          const DRegister& first = nreglist.GetFirstDRegister();
24730          EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) |
24731                     (encoded_align_2.GetEncodingValue() << 4) |
24732                     first.Encode(22, 12) | (rn.GetCode() << 16));
24733          AdvanceIT();
24734          return;
24735        }
24736      }
24737      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24738      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24739          (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
24740          encoded_align_2.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
24741        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24742          const DRegister& first = nreglist.GetFirstDRegister();
24743          EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) |
24744                     (encoded_align_2.GetEncodingValue() << 4) |
24745                     first.Encode(22, 12) | (rn.GetCode() << 16));
24746          AdvanceIT();
24747          return;
24748        }
24749      }
24750    } else {
24751      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
24752      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24753          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24754          operand.IsOffset() && encoded_align_1.IsValid() &&
24755          ((!rn.IsPC()) || AllowUnpredictable())) {
24756        if (cond.Is(al)) {
24757          const DRegister& first = nreglist.GetFirstDRegister();
24758          uint32_t len_encoding;
24759          switch (nreglist.GetLength()) {
24760            default:
24761              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24762            case 1:
24763              len_encoding = 0x7;
24764              break;
24765            case 2:
24766              len_encoding = 0xa;
24767              break;
24768            case 3:
24769              len_encoding = 0x6;
24770              break;
24771            case 4:
24772              len_encoding = 0x2;
24773              break;
24774          }
24775          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
24776                  (encoded_align_1.GetEncodingValue() << 4) |
24777                  first.Encode(22, 12) | (len_encoding << 8) |
24778                  (rn.GetCode() << 16));
24779          return;
24780        }
24781      }
24782      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
24783      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24784          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24785          operand.IsPostIndex() && encoded_align_1.IsValid() &&
24786          ((!rn.IsPC()) || AllowUnpredictable())) {
24787        if (cond.Is(al)) {
24788          const DRegister& first = nreglist.GetFirstDRegister();
24789          uint32_t len_encoding;
24790          switch (nreglist.GetLength()) {
24791            default:
24792              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24793            case 1:
24794              len_encoding = 0x7;
24795              break;
24796            case 2:
24797              len_encoding = 0xa;
24798              break;
24799            case 3:
24800              len_encoding = 0x6;
24801              break;
24802            case 4:
24803              len_encoding = 0x2;
24804              break;
24805          }
24806          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
24807                  (encoded_align_1.GetEncodingValue() << 4) |
24808                  first.Encode(22, 12) | (len_encoding << 8) |
24809                  (rn.GetCode() << 16));
24810          return;
24811        }
24812      }
24813      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
24814      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24815          (nreglist.GetLength() == 1) && operand.IsOffset() &&
24816          encoded_align_2.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
24817        if (cond.Is(al)) {
24818          const DRegister& first = nreglist.GetFirstDRegister();
24819          EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) |
24820                  (encoded_align_2.GetEncodingValue() << 4) |
24821                  first.Encode(22, 12) | (rn.GetCode() << 16));
24822          return;
24823        }
24824      }
24825      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
24826      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24827          (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
24828          encoded_align_2.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
24829        if (cond.Is(al)) {
24830          const DRegister& first = nreglist.GetFirstDRegister();
24831          EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) |
24832                  (encoded_align_2.GetEncodingValue() << 4) |
24833                  first.Encode(22, 12) | (rn.GetCode() << 16));
24834          return;
24835        }
24836      }
24837    }
24838  }
24839  if (operand.IsPlainRegister()) {
24840    Register rn = operand.GetBaseRegister();
24841    Alignment align = operand.GetAlignment();
24842    Register rm = operand.GetOffsetRegister();
24843    Dt_size_6 encoded_dt(dt);
24844    Dt_size_7 encoded_dt_2(dt);
24845    Align_align_5 encoded_align_1(align, nreglist);
24846    Align_index_align_1 encoded_align_2(align, nreglist, dt);
24847    if (IsUsingT32()) {
24848      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
24849      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24850          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24851          !rm.IsPC() && !rm.IsSP()) {
24852        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24853          const DRegister& first = nreglist.GetFirstDRegister();
24854          uint32_t len_encoding;
24855          switch (nreglist.GetLength()) {
24856            default:
24857              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24858            case 1:
24859              len_encoding = 0x7;
24860              break;
24861            case 2:
24862              len_encoding = 0xa;
24863              break;
24864            case 3:
24865              len_encoding = 0x6;
24866              break;
24867            case 4:
24868              len_encoding = 0x2;
24869              break;
24870          }
24871          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
24872                     (encoded_align_1.GetEncodingValue() << 4) |
24873                     first.Encode(22, 12) | (len_encoding << 8) |
24874                     (rn.GetCode() << 16) | rm.GetCode());
24875          AdvanceIT();
24876          return;
24877        }
24878      }
24879      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
24880      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24881          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
24882        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24883          const DRegister& first = nreglist.GetFirstDRegister();
24884          EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) |
24885                     (encoded_align_2.GetEncodingValue() << 4) |
24886                     first.Encode(22, 12) | (rn.GetCode() << 16) |
24887                     rm.GetCode());
24888          AdvanceIT();
24889          return;
24890        }
24891      }
24892    } else {
24893      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
24894      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24895          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24896          !rm.IsPC() && !rm.IsSP()) {
24897        if (cond.Is(al)) {
24898          const DRegister& first = nreglist.GetFirstDRegister();
24899          uint32_t len_encoding;
24900          switch (nreglist.GetLength()) {
24901            default:
24902              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24903            case 1:
24904              len_encoding = 0x7;
24905              break;
24906            case 2:
24907              len_encoding = 0xa;
24908              break;
24909            case 3:
24910              len_encoding = 0x6;
24911              break;
24912            case 4:
24913              len_encoding = 0x2;
24914              break;
24915          }
24916          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
24917                  (encoded_align_1.GetEncodingValue() << 4) |
24918                  first.Encode(22, 12) | (len_encoding << 8) |
24919                  (rn.GetCode() << 16) | rm.GetCode());
24920          return;
24921        }
24922      }
24923      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
24924      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24925          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
24926        if (cond.Is(al)) {
24927          const DRegister& first = nreglist.GetFirstDRegister();
24928          EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) |
24929                  (encoded_align_2.GetEncodingValue() << 4) |
24930                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
24931          return;
24932        }
24933      }
24934    }
24935  }
24936  Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand);
24937}
24938
24939void Assembler::vst2(Condition cond,
24940                     DataType dt,
24941                     const NeonRegisterList& nreglist,
24942                     const AlignedMemOperand& operand) {
24943  VIXL_ASSERT(AllowAssembler());
24944  CheckIT(cond);
24945  if (operand.IsImmediateZero()) {
24946    Register rn = operand.GetBaseRegister();
24947    Alignment align = operand.GetAlignment();
24948    Dt_size_7 encoded_dt(dt);
24949    Align_align_2 encoded_align_1(align, nreglist);
24950    Align_index_align_2 encoded_align_2(align, nreglist, dt);
24951    if (IsUsingT32()) {
24952      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24953      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24954          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24955           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
24956           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
24957          operand.IsOffset() && encoded_align_1.IsValid() &&
24958          ((!rn.IsPC()) || AllowUnpredictable())) {
24959        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24960          const DRegister& first = nreglist.GetFirstDRegister();
24961          uint32_t len_encoding;
24962          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
24963            len_encoding = 0x8;
24964          }
24965          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
24966            len_encoding = 0x9;
24967          }
24968          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
24969            len_encoding = 0x3;
24970          }
24971          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
24972                     (encoded_align_1.GetEncodingValue() << 4) |
24973                     first.Encode(22, 12) | (len_encoding << 8) |
24974                     (rn.GetCode() << 16));
24975          AdvanceIT();
24976          return;
24977        }
24978      }
24979      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24980      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24981          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24982           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
24983           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
24984          operand.IsPostIndex() && encoded_align_1.IsValid() &&
24985          ((!rn.IsPC()) || AllowUnpredictable())) {
24986        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24987          const DRegister& first = nreglist.GetFirstDRegister();
24988          uint32_t len_encoding;
24989          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
24990            len_encoding = 0x8;
24991          }
24992          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
24993            len_encoding = 0x9;
24994          }
24995          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
24996            len_encoding = 0x3;
24997          }
24998          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
24999                     (encoded_align_1.GetEncodingValue() << 4) |
25000                     first.Encode(22, 12) | (len_encoding << 8) |
25001                     (rn.GetCode() << 16));
25002          AdvanceIT();
25003          return;
25004        }
25005      }
25006      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25007      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25008          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25009           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25010          operand.IsOffset() && encoded_align_2.IsValid() &&
25011          ((!rn.IsPC()) || AllowUnpredictable())) {
25012        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25013          const DRegister& first = nreglist.GetFirstDRegister();
25014          EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) |
25015                     (encoded_align_2.GetEncodingValue() << 4) |
25016                     first.Encode(22, 12) | (rn.GetCode() << 16));
25017          AdvanceIT();
25018          return;
25019        }
25020      }
25021      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25022      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25023          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25024           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25025          operand.IsPostIndex() && encoded_align_2.IsValid() &&
25026          ((!rn.IsPC()) || AllowUnpredictable())) {
25027        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25028          const DRegister& first = nreglist.GetFirstDRegister();
25029          EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) |
25030                     (encoded_align_2.GetEncodingValue() << 4) |
25031                     first.Encode(22, 12) | (rn.GetCode() << 16));
25032          AdvanceIT();
25033          return;
25034        }
25035      }
25036    } else {
25037      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25038      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25039          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25040           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25041           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25042          operand.IsOffset() && encoded_align_1.IsValid() &&
25043          ((!rn.IsPC()) || AllowUnpredictable())) {
25044        if (cond.Is(al)) {
25045          const DRegister& first = nreglist.GetFirstDRegister();
25046          uint32_t len_encoding;
25047          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25048            len_encoding = 0x8;
25049          }
25050          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25051            len_encoding = 0x9;
25052          }
25053          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25054            len_encoding = 0x3;
25055          }
25056          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
25057                  (encoded_align_1.GetEncodingValue() << 4) |
25058                  first.Encode(22, 12) | (len_encoding << 8) |
25059                  (rn.GetCode() << 16));
25060          return;
25061        }
25062      }
25063      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25064      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25065          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25066           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25067           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25068          operand.IsPostIndex() && encoded_align_1.IsValid() &&
25069          ((!rn.IsPC()) || AllowUnpredictable())) {
25070        if (cond.Is(al)) {
25071          const DRegister& first = nreglist.GetFirstDRegister();
25072          uint32_t len_encoding;
25073          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25074            len_encoding = 0x8;
25075          }
25076          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25077            len_encoding = 0x9;
25078          }
25079          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25080            len_encoding = 0x3;
25081          }
25082          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
25083                  (encoded_align_1.GetEncodingValue() << 4) |
25084                  first.Encode(22, 12) | (len_encoding << 8) |
25085                  (rn.GetCode() << 16));
25086          return;
25087        }
25088      }
25089      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25090      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25091          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25092           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25093          operand.IsOffset() && encoded_align_2.IsValid() &&
25094          ((!rn.IsPC()) || AllowUnpredictable())) {
25095        if (cond.Is(al)) {
25096          const DRegister& first = nreglist.GetFirstDRegister();
25097          EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) |
25098                  (encoded_align_2.GetEncodingValue() << 4) |
25099                  first.Encode(22, 12) | (rn.GetCode() << 16));
25100          return;
25101        }
25102      }
25103      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25104      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25105          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25106           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25107          operand.IsPostIndex() && encoded_align_2.IsValid() &&
25108          ((!rn.IsPC()) || AllowUnpredictable())) {
25109        if (cond.Is(al)) {
25110          const DRegister& first = nreglist.GetFirstDRegister();
25111          EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) |
25112                  (encoded_align_2.GetEncodingValue() << 4) |
25113                  first.Encode(22, 12) | (rn.GetCode() << 16));
25114          return;
25115        }
25116      }
25117    }
25118  }
25119  if (operand.IsPlainRegister()) {
25120    Register rn = operand.GetBaseRegister();
25121    Alignment align = operand.GetAlignment();
25122    Register rm = operand.GetOffsetRegister();
25123    Dt_size_7 encoded_dt(dt);
25124    Align_align_2 encoded_align_1(align, nreglist);
25125    Align_index_align_2 encoded_align_2(align, nreglist, dt);
25126    if (IsUsingT32()) {
25127      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25128      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25129          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25130           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25131           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25132          !rm.IsPC() && !rm.IsSP()) {
25133        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25134          const DRegister& first = nreglist.GetFirstDRegister();
25135          uint32_t len_encoding;
25136          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25137            len_encoding = 0x8;
25138          }
25139          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25140            len_encoding = 0x9;
25141          }
25142          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25143            len_encoding = 0x3;
25144          }
25145          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
25146                     (encoded_align_1.GetEncodingValue() << 4) |
25147                     first.Encode(22, 12) | (len_encoding << 8) |
25148                     (rn.GetCode() << 16) | rm.GetCode());
25149          AdvanceIT();
25150          return;
25151        }
25152      }
25153      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25154      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25155          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25156           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25157          !rm.IsPC() && !rm.IsSP()) {
25158        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25159          const DRegister& first = nreglist.GetFirstDRegister();
25160          EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) |
25161                     (encoded_align_2.GetEncodingValue() << 4) |
25162                     first.Encode(22, 12) | (rn.GetCode() << 16) |
25163                     rm.GetCode());
25164          AdvanceIT();
25165          return;
25166        }
25167      }
25168    } else {
25169      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25170      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25171          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25172           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25173           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25174          !rm.IsPC() && !rm.IsSP()) {
25175        if (cond.Is(al)) {
25176          const DRegister& first = nreglist.GetFirstDRegister();
25177          uint32_t len_encoding;
25178          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25179            len_encoding = 0x8;
25180          }
25181          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25182            len_encoding = 0x9;
25183          }
25184          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25185            len_encoding = 0x3;
25186          }
25187          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
25188                  (encoded_align_1.GetEncodingValue() << 4) |
25189                  first.Encode(22, 12) | (len_encoding << 8) |
25190                  (rn.GetCode() << 16) | rm.GetCode());
25191          return;
25192        }
25193      }
25194      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25195      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25196          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25197           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25198          !rm.IsPC() && !rm.IsSP()) {
25199        if (cond.Is(al)) {
25200          const DRegister& first = nreglist.GetFirstDRegister();
25201          EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) |
25202                  (encoded_align_2.GetEncodingValue() << 4) |
25203                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
25204          return;
25205        }
25206      }
25207    }
25208  }
25209  Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand);
25210}
25211
25212void Assembler::vst3(Condition cond,
25213                     DataType dt,
25214                     const NeonRegisterList& nreglist,
25215                     const AlignedMemOperand& operand) {
25216  VIXL_ASSERT(AllowAssembler());
25217  CheckIT(cond);
25218  if (operand.IsImmediateZero()) {
25219    Register rn = operand.GetBaseRegister();
25220    Alignment align = operand.GetAlignment();
25221    Dt_size_7 encoded_dt(dt);
25222    Align_align_3 encoded_align_1(align);
25223    if (IsUsingT32()) {
25224      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25225      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25226          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25227           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25228          operand.IsOffset() && encoded_align_1.IsValid() &&
25229          ((!rn.IsPC()) || AllowUnpredictable())) {
25230        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25231          const DRegister& first = nreglist.GetFirstDRegister();
25232          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25233          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
25234                     (encoded_align_1.GetEncodingValue() << 4) |
25235                     first.Encode(22, 12) | (len_encoding << 8) |
25236                     (rn.GetCode() << 16));
25237          AdvanceIT();
25238          return;
25239        }
25240      }
25241      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25242      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25243          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25244           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25245          operand.IsPostIndex() && encoded_align_1.IsValid() &&
25246          ((!rn.IsPC()) || AllowUnpredictable())) {
25247        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25248          const DRegister& first = nreglist.GetFirstDRegister();
25249          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25250          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
25251                     (encoded_align_1.GetEncodingValue() << 4) |
25252                     first.Encode(22, 12) | (len_encoding << 8) |
25253                     (rn.GetCode() << 16));
25254          AdvanceIT();
25255          return;
25256        }
25257      }
25258    } else {
25259      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25260      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25261          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25262           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25263          operand.IsOffset() && encoded_align_1.IsValid() &&
25264          ((!rn.IsPC()) || AllowUnpredictable())) {
25265        if (cond.Is(al)) {
25266          const DRegister& first = nreglist.GetFirstDRegister();
25267          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25268          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
25269                  (encoded_align_1.GetEncodingValue() << 4) |
25270                  first.Encode(22, 12) | (len_encoding << 8) |
25271                  (rn.GetCode() << 16));
25272          return;
25273        }
25274      }
25275      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25276      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25277          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25278           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25279          operand.IsPostIndex() && encoded_align_1.IsValid() &&
25280          ((!rn.IsPC()) || AllowUnpredictable())) {
25281        if (cond.Is(al)) {
25282          const DRegister& first = nreglist.GetFirstDRegister();
25283          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25284          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
25285                  (encoded_align_1.GetEncodingValue() << 4) |
25286                  first.Encode(22, 12) | (len_encoding << 8) |
25287                  (rn.GetCode() << 16));
25288          return;
25289        }
25290      }
25291    }
25292  }
25293  if (operand.IsPlainRegister()) {
25294    Register rn = operand.GetBaseRegister();
25295    Alignment align = operand.GetAlignment();
25296    Register rm = operand.GetOffsetRegister();
25297    Dt_size_7 encoded_dt(dt);
25298    Align_align_3 encoded_align_1(align);
25299    if (IsUsingT32()) {
25300      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25301      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25302          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25303           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25304          !rm.IsPC() && !rm.IsSP()) {
25305        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25306          const DRegister& first = nreglist.GetFirstDRegister();
25307          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25308          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
25309                     (encoded_align_1.GetEncodingValue() << 4) |
25310                     first.Encode(22, 12) | (len_encoding << 8) |
25311                     (rn.GetCode() << 16) | rm.GetCode());
25312          AdvanceIT();
25313          return;
25314        }
25315      }
25316    } else {
25317      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25318      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25319          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25320           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25321          !rm.IsPC() && !rm.IsSP()) {
25322        if (cond.Is(al)) {
25323          const DRegister& first = nreglist.GetFirstDRegister();
25324          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25325          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
25326                  (encoded_align_1.GetEncodingValue() << 4) |
25327                  first.Encode(22, 12) | (len_encoding << 8) |
25328                  (rn.GetCode() << 16) | rm.GetCode());
25329          return;
25330        }
25331      }
25332    }
25333  }
25334  Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
25335}
25336
25337void Assembler::vst3(Condition cond,
25338                     DataType dt,
25339                     const NeonRegisterList& nreglist,
25340                     const MemOperand& operand) {
25341  VIXL_ASSERT(AllowAssembler());
25342  CheckIT(cond);
25343  if (operand.IsImmediateZero()) {
25344    Register rn = operand.GetBaseRegister();
25345    Dt_size_7 encoded_dt(dt);
25346    Index_1 encoded_align_1(nreglist, dt);
25347    if (IsUsingT32()) {
25348      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
25349      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25350          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25351           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25352          operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
25353        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25354          const DRegister& first = nreglist.GetFirstDRegister();
25355          EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) |
25356                     (encoded_align_1.GetEncodingValue() << 4) |
25357                     first.Encode(22, 12) | (rn.GetCode() << 16));
25358          AdvanceIT();
25359          return;
25360        }
25361      }
25362      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
25363      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25364          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25365           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25366          operand.IsPreIndex() && ((!rn.IsPC()) || AllowUnpredictable())) {
25367        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25368          const DRegister& first = nreglist.GetFirstDRegister();
25369          EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) |
25370                     (encoded_align_1.GetEncodingValue() << 4) |
25371                     first.Encode(22, 12) | (rn.GetCode() << 16));
25372          AdvanceIT();
25373          return;
25374        }
25375      }
25376    } else {
25377      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
25378      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25379          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25380           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25381          operand.IsOffset() && ((!rn.IsPC()) || AllowUnpredictable())) {
25382        if (cond.Is(al)) {
25383          const DRegister& first = nreglist.GetFirstDRegister();
25384          EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) |
25385                  (encoded_align_1.GetEncodingValue() << 4) |
25386                  first.Encode(22, 12) | (rn.GetCode() << 16));
25387          return;
25388        }
25389      }
25390      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
25391      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25392          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25393           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25394          operand.IsPreIndex() && ((!rn.IsPC()) || AllowUnpredictable())) {
25395        if (cond.Is(al)) {
25396          const DRegister& first = nreglist.GetFirstDRegister();
25397          EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) |
25398                  (encoded_align_1.GetEncodingValue() << 4) |
25399                  first.Encode(22, 12) | (rn.GetCode() << 16));
25400          return;
25401        }
25402      }
25403    }
25404  }
25405  if (operand.IsPlainRegister()) {
25406    Register rn = operand.GetBaseRegister();
25407    Sign sign = operand.GetSign();
25408    Register rm = operand.GetOffsetRegister();
25409    Dt_size_7 encoded_dt(dt);
25410    Index_1 encoded_align_1(nreglist, dt);
25411    if (IsUsingT32()) {
25412      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
25413      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25414          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25415           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25416          sign.IsPlus() && operand.IsPostIndex()) {
25417        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25418          const DRegister& first = nreglist.GetFirstDRegister();
25419          EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) |
25420                     (encoded_align_1.GetEncodingValue() << 4) |
25421                     first.Encode(22, 12) | (rn.GetCode() << 16) |
25422                     rm.GetCode());
25423          AdvanceIT();
25424          return;
25425        }
25426      }
25427    } else {
25428      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
25429      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25430          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25431           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25432          sign.IsPlus() && operand.IsPostIndex()) {
25433        if (cond.Is(al)) {
25434          const DRegister& first = nreglist.GetFirstDRegister();
25435          EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) |
25436                  (encoded_align_1.GetEncodingValue() << 4) |
25437                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
25438          return;
25439        }
25440      }
25441    }
25442  }
25443  Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
25444}
25445
25446void Assembler::vst4(Condition cond,
25447                     DataType dt,
25448                     const NeonRegisterList& nreglist,
25449                     const AlignedMemOperand& operand) {
25450  VIXL_ASSERT(AllowAssembler());
25451  CheckIT(cond);
25452  if (operand.IsImmediateZero()) {
25453    Register rn = operand.GetBaseRegister();
25454    Alignment align = operand.GetAlignment();
25455    Dt_size_7 encoded_dt(dt);
25456    Align_align_4 encoded_align_1(align);
25457    Align_index_align_3 encoded_align_2(align, nreglist, dt);
25458    if (IsUsingT32()) {
25459      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25460      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25461          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25462           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25463          operand.IsOffset() && encoded_align_1.IsValid() &&
25464          ((!rn.IsPC()) || AllowUnpredictable())) {
25465        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25466          const DRegister& first = nreglist.GetFirstDRegister();
25467          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25468          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
25469                     (encoded_align_1.GetEncodingValue() << 4) |
25470                     first.Encode(22, 12) | (len_encoding << 8) |
25471                     (rn.GetCode() << 16));
25472          AdvanceIT();
25473          return;
25474        }
25475      }
25476      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25477      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25478          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25479           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25480          operand.IsPostIndex() && encoded_align_1.IsValid() &&
25481          ((!rn.IsPC()) || AllowUnpredictable())) {
25482        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25483          const DRegister& first = nreglist.GetFirstDRegister();
25484          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25485          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
25486                     (encoded_align_1.GetEncodingValue() << 4) |
25487                     first.Encode(22, 12) | (len_encoding << 8) |
25488                     (rn.GetCode() << 16));
25489          AdvanceIT();
25490          return;
25491        }
25492      }
25493      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25494      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25495          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25496           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25497          operand.IsOffset() && encoded_align_2.IsValid() &&
25498          ((!rn.IsPC()) || AllowUnpredictable())) {
25499        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25500          const DRegister& first = nreglist.GetFirstDRegister();
25501          EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) |
25502                     (encoded_align_2.GetEncodingValue() << 4) |
25503                     first.Encode(22, 12) | (rn.GetCode() << 16));
25504          AdvanceIT();
25505          return;
25506        }
25507      }
25508      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25509      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25510          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25511           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25512          operand.IsPostIndex() && encoded_align_2.IsValid() &&
25513          ((!rn.IsPC()) || AllowUnpredictable())) {
25514        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25515          const DRegister& first = nreglist.GetFirstDRegister();
25516          EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) |
25517                     (encoded_align_2.GetEncodingValue() << 4) |
25518                     first.Encode(22, 12) | (rn.GetCode() << 16));
25519          AdvanceIT();
25520          return;
25521        }
25522      }
25523    } else {
25524      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25525      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25526          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25527           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25528          operand.IsOffset() && encoded_align_1.IsValid() &&
25529          ((!rn.IsPC()) || AllowUnpredictable())) {
25530        if (cond.Is(al)) {
25531          const DRegister& first = nreglist.GetFirstDRegister();
25532          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25533          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
25534                  (encoded_align_1.GetEncodingValue() << 4) |
25535                  first.Encode(22, 12) | (len_encoding << 8) |
25536                  (rn.GetCode() << 16));
25537          return;
25538        }
25539      }
25540      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25541      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25542          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25543           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25544          operand.IsPostIndex() && encoded_align_1.IsValid() &&
25545          ((!rn.IsPC()) || AllowUnpredictable())) {
25546        if (cond.Is(al)) {
25547          const DRegister& first = nreglist.GetFirstDRegister();
25548          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25549          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
25550                  (encoded_align_1.GetEncodingValue() << 4) |
25551                  first.Encode(22, 12) | (len_encoding << 8) |
25552                  (rn.GetCode() << 16));
25553          return;
25554        }
25555      }
25556      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25557      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25558          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25559           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25560          operand.IsOffset() && encoded_align_2.IsValid() &&
25561          ((!rn.IsPC()) || AllowUnpredictable())) {
25562        if (cond.Is(al)) {
25563          const DRegister& first = nreglist.GetFirstDRegister();
25564          EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) |
25565                  (encoded_align_2.GetEncodingValue() << 4) |
25566                  first.Encode(22, 12) | (rn.GetCode() << 16));
25567          return;
25568        }
25569      }
25570      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25571      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25572          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25573           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25574          operand.IsPostIndex() && encoded_align_2.IsValid() &&
25575          ((!rn.IsPC()) || AllowUnpredictable())) {
25576        if (cond.Is(al)) {
25577          const DRegister& first = nreglist.GetFirstDRegister();
25578          EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) |
25579                  (encoded_align_2.GetEncodingValue() << 4) |
25580                  first.Encode(22, 12) | (rn.GetCode() << 16));
25581          return;
25582        }
25583      }
25584    }
25585  }
25586  if (operand.IsPlainRegister()) {
25587    Register rn = operand.GetBaseRegister();
25588    Alignment align = operand.GetAlignment();
25589    Register rm = operand.GetOffsetRegister();
25590    Dt_size_7 encoded_dt(dt);
25591    Align_align_4 encoded_align_1(align);
25592    Align_index_align_3 encoded_align_2(align, nreglist, dt);
25593    if (IsUsingT32()) {
25594      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25595      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25596          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25597           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25598          !rm.IsPC() && !rm.IsSP()) {
25599        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25600          const DRegister& first = nreglist.GetFirstDRegister();
25601          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25602          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
25603                     (encoded_align_1.GetEncodingValue() << 4) |
25604                     first.Encode(22, 12) | (len_encoding << 8) |
25605                     (rn.GetCode() << 16) | rm.GetCode());
25606          AdvanceIT();
25607          return;
25608        }
25609      }
25610      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25611      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25612          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25613           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25614          !rm.IsPC() && !rm.IsSP()) {
25615        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25616          const DRegister& first = nreglist.GetFirstDRegister();
25617          EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) |
25618                     (encoded_align_2.GetEncodingValue() << 4) |
25619                     first.Encode(22, 12) | (rn.GetCode() << 16) |
25620                     rm.GetCode());
25621          AdvanceIT();
25622          return;
25623        }
25624      }
25625    } else {
25626      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25627      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25628          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25629           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25630          !rm.IsPC() && !rm.IsSP()) {
25631        if (cond.Is(al)) {
25632          const DRegister& first = nreglist.GetFirstDRegister();
25633          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25634          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
25635                  (encoded_align_1.GetEncodingValue() << 4) |
25636                  first.Encode(22, 12) | (len_encoding << 8) |
25637                  (rn.GetCode() << 16) | rm.GetCode());
25638          return;
25639        }
25640      }
25641      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25642      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25643          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25644           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25645          !rm.IsPC() && !rm.IsSP()) {
25646        if (cond.Is(al)) {
25647          const DRegister& first = nreglist.GetFirstDRegister();
25648          EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) |
25649                  (encoded_align_2.GetEncodingValue() << 4) |
25650                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
25651          return;
25652        }
25653      }
25654    }
25655  }
25656  Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand);
25657}
25658
25659void Assembler::vstm(Condition cond,
25660                     DataType dt,
25661                     Register rn,
25662                     WriteBack write_back,
25663                     DRegisterList dreglist) {
25664  VIXL_ASSERT(AllowAssembler());
25665  CheckIT(cond);
25666  USE(dt);
25667  if (IsUsingT32()) {
25668    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
25669    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25670      const DRegister& dreg = dreglist.GetFirstDRegister();
25671      unsigned len = dreglist.GetLength() * 2;
25672      EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
25673                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25674                 (len & 0xff));
25675      AdvanceIT();
25676      return;
25677    }
25678  } else {
25679    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
25680    if (cond.IsNotNever() &&
25681        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25682      const DRegister& dreg = dreglist.GetFirstDRegister();
25683      unsigned len = dreglist.GetLength() * 2;
25684      EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25685              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25686              (len & 0xff));
25687      return;
25688    }
25689  }
25690  Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist);
25691}
25692
25693void Assembler::vstm(Condition cond,
25694                     DataType dt,
25695                     Register rn,
25696                     WriteBack write_back,
25697                     SRegisterList sreglist) {
25698  VIXL_ASSERT(AllowAssembler());
25699  CheckIT(cond);
25700  USE(dt);
25701  if (IsUsingT32()) {
25702    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
25703    const SRegister& sreg = sreglist.GetFirstSRegister();
25704    unsigned len = sreglist.GetLength();
25705    EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
25706               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25707               (len & 0xff));
25708    AdvanceIT();
25709    return;
25710  } else {
25711    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
25712    if (cond.IsNotNever()) {
25713      const SRegister& sreg = sreglist.GetFirstSRegister();
25714      unsigned len = sreglist.GetLength();
25715      EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25716              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25717              (len & 0xff));
25718      return;
25719    }
25720  }
25721  Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist);
25722}
25723
25724void Assembler::vstmdb(Condition cond,
25725                       DataType dt,
25726                       Register rn,
25727                       WriteBack write_back,
25728                       DRegisterList dreglist) {
25729  VIXL_ASSERT(AllowAssembler());
25730  CheckIT(cond);
25731  USE(dt);
25732  if (IsUsingT32()) {
25733    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
25734    if (write_back.DoesWriteBack() &&
25735        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25736      const DRegister& dreg = dreglist.GetFirstDRegister();
25737      unsigned len = dreglist.GetLength() * 2;
25738      EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
25739                 (len & 0xff));
25740      AdvanceIT();
25741      return;
25742    }
25743  } else {
25744    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
25745    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
25746        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25747      const DRegister& dreg = dreglist.GetFirstDRegister();
25748      unsigned len = dreglist.GetLength() * 2;
25749      EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25750              dreg.Encode(22, 12) | (len & 0xff));
25751      return;
25752    }
25753  }
25754  Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist);
25755}
25756
25757void Assembler::vstmdb(Condition cond,
25758                       DataType dt,
25759                       Register rn,
25760                       WriteBack write_back,
25761                       SRegisterList sreglist) {
25762  VIXL_ASSERT(AllowAssembler());
25763  CheckIT(cond);
25764  USE(dt);
25765  if (IsUsingT32()) {
25766    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
25767    if (write_back.DoesWriteBack()) {
25768      const SRegister& sreg = sreglist.GetFirstSRegister();
25769      unsigned len = sreglist.GetLength();
25770      EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
25771                 (len & 0xff));
25772      AdvanceIT();
25773      return;
25774    }
25775  } else {
25776    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
25777    if (write_back.DoesWriteBack() && cond.IsNotNever()) {
25778      const SRegister& sreg = sreglist.GetFirstSRegister();
25779      unsigned len = sreglist.GetLength();
25780      EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25781              sreg.Encode(22, 12) | (len & 0xff));
25782      return;
25783    }
25784  }
25785  Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist);
25786}
25787
25788void Assembler::vstmia(Condition cond,
25789                       DataType dt,
25790                       Register rn,
25791                       WriteBack write_back,
25792                       DRegisterList dreglist) {
25793  VIXL_ASSERT(AllowAssembler());
25794  CheckIT(cond);
25795  USE(dt);
25796  if (IsUsingT32()) {
25797    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
25798    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25799      const DRegister& dreg = dreglist.GetFirstDRegister();
25800      unsigned len = dreglist.GetLength() * 2;
25801      EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
25802                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25803                 (len & 0xff));
25804      AdvanceIT();
25805      return;
25806    }
25807  } else {
25808    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
25809    if (cond.IsNotNever() &&
25810        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25811      const DRegister& dreg = dreglist.GetFirstDRegister();
25812      unsigned len = dreglist.GetLength() * 2;
25813      EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25814              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25815              (len & 0xff));
25816      return;
25817    }
25818  }
25819  Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist);
25820}
25821
25822void Assembler::vstmia(Condition cond,
25823                       DataType dt,
25824                       Register rn,
25825                       WriteBack write_back,
25826                       SRegisterList sreglist) {
25827  VIXL_ASSERT(AllowAssembler());
25828  CheckIT(cond);
25829  USE(dt);
25830  if (IsUsingT32()) {
25831    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
25832    const SRegister& sreg = sreglist.GetFirstSRegister();
25833    unsigned len = sreglist.GetLength();
25834    EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
25835               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25836               (len & 0xff));
25837    AdvanceIT();
25838    return;
25839  } else {
25840    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
25841    if (cond.IsNotNever()) {
25842      const SRegister& sreg = sreglist.GetFirstSRegister();
25843      unsigned len = sreglist.GetLength();
25844      EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25845              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25846              (len & 0xff));
25847      return;
25848    }
25849  }
25850  Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist);
25851}
25852
25853void Assembler::vstr(Condition cond,
25854                     DataType dt,
25855                     DRegister rd,
25856                     const MemOperand& operand) {
25857  VIXL_ASSERT(AllowAssembler());
25858  CheckIT(cond);
25859  if (operand.IsImmediate()) {
25860    Register rn = operand.GetBaseRegister();
25861    int32_t offset = operand.GetOffsetImmediate();
25862    if (IsUsingT32()) {
25863      // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
25864      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
25865          ((offset % 4) == 0) && operand.IsOffset()) {
25866        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25867        uint32_t offset_ = abs(offset) >> 2;
25868        EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
25869                   offset_ | (sign << 23));
25870        AdvanceIT();
25871        return;
25872      }
25873    } else {
25874      // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
25875      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
25876          ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
25877        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25878        uint32_t offset_ = abs(offset) >> 2;
25879        EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25880                (rn.GetCode() << 16) | offset_ | (sign << 23));
25881        return;
25882      }
25883    }
25884  }
25885  Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
25886}
25887
25888void Assembler::vstr(Condition cond,
25889                     DataType dt,
25890                     SRegister rd,
25891                     const MemOperand& operand) {
25892  VIXL_ASSERT(AllowAssembler());
25893  CheckIT(cond);
25894  if (operand.IsImmediate()) {
25895    Register rn = operand.GetBaseRegister();
25896    int32_t offset = operand.GetOffsetImmediate();
25897    if (IsUsingT32()) {
25898      // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
25899      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
25900          ((offset % 4) == 0) && operand.IsOffset()) {
25901        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25902        uint32_t offset_ = abs(offset) >> 2;
25903        EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
25904                   offset_ | (sign << 23));
25905        AdvanceIT();
25906        return;
25907      }
25908    } else {
25909      // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
25910      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
25911          ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
25912        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25913        uint32_t offset_ = abs(offset) >> 2;
25914        EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25915                (rn.GetCode() << 16) | offset_ | (sign << 23));
25916        return;
25917      }
25918    }
25919  }
25920  Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
25921}
25922
25923void Assembler::vsub(
25924    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25925  VIXL_ASSERT(AllowAssembler());
25926  CheckIT(cond);
25927  Dt_size_2 encoded_dt(dt);
25928  if (IsUsingT32()) {
25929    // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
25930    if (dt.Is(F32)) {
25931      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25932        EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25933                   rm.Encode(5, 0));
25934        AdvanceIT();
25935        return;
25936      }
25937    }
25938    // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
25939    if (dt.Is(F64)) {
25940      EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25941                 rm.Encode(5, 0));
25942      AdvanceIT();
25943      return;
25944    }
25945    // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
25946    if (encoded_dt.IsValid()) {
25947      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25948        EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) |
25949                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25950        AdvanceIT();
25951        return;
25952      }
25953    }
25954  } else {
25955    // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
25956    if (dt.Is(F32)) {
25957      if (cond.Is(al)) {
25958        EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25959                rm.Encode(5, 0));
25960        return;
25961      }
25962    }
25963    // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
25964    if (dt.Is(F64) && cond.IsNotNever()) {
25965      EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25966              rn.Encode(7, 16) | rm.Encode(5, 0));
25967      return;
25968    }
25969    // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
25970    if (encoded_dt.IsValid()) {
25971      if (cond.Is(al)) {
25972        EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) |
25973                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25974        return;
25975      }
25976    }
25977  }
25978  Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
25979}
25980
25981void Assembler::vsub(
25982    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
25983  VIXL_ASSERT(AllowAssembler());
25984  CheckIT(cond);
25985  Dt_size_2 encoded_dt(dt);
25986  if (IsUsingT32()) {
25987    // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
25988    if (dt.Is(F32)) {
25989      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25990        EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25991                   rm.Encode(5, 0));
25992        AdvanceIT();
25993        return;
25994      }
25995    }
25996    // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
25997    if (encoded_dt.IsValid()) {
25998      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25999        EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) |
26000                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26001        AdvanceIT();
26002        return;
26003      }
26004    }
26005  } else {
26006    // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
26007    if (dt.Is(F32)) {
26008      if (cond.Is(al)) {
26009        EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26010                rm.Encode(5, 0));
26011        return;
26012      }
26013    }
26014    // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
26015    if (encoded_dt.IsValid()) {
26016      if (cond.Is(al)) {
26017        EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) |
26018                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26019        return;
26020      }
26021    }
26022  }
26023  Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
26024}
26025
26026void Assembler::vsub(
26027    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
26028  VIXL_ASSERT(AllowAssembler());
26029  CheckIT(cond);
26030  if (IsUsingT32()) {
26031    // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
26032    if (dt.Is(F32)) {
26033      EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26034                 rm.Encode(5, 0));
26035      AdvanceIT();
26036      return;
26037    }
26038  } else {
26039    // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
26040    if (dt.Is(F32) && cond.IsNotNever()) {
26041      EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
26042              rn.Encode(7, 16) | rm.Encode(5, 0));
26043      return;
26044    }
26045  }
26046  Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
26047}
26048
26049void Assembler::vsubhn(
26050    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
26051  VIXL_ASSERT(AllowAssembler());
26052  CheckIT(cond);
26053  Dt_size_3 encoded_dt(dt);
26054  if (IsUsingT32()) {
26055    // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
26056    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
26057      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26058        EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) |
26059                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26060        AdvanceIT();
26061        return;
26062      }
26063    }
26064  } else {
26065    // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
26066    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
26067      if (cond.Is(al)) {
26068        EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) |
26069                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26070        return;
26071      }
26072    }
26073  }
26074  Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm);
26075}
26076
26077void Assembler::vsubl(
26078    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
26079  VIXL_ASSERT(AllowAssembler());
26080  CheckIT(cond);
26081  Dt_U_size_1 encoded_dt(dt);
26082  if (IsUsingT32()) {
26083    // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
26084    if (encoded_dt.IsValid()) {
26085      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26086        EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26087                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
26088                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26089        AdvanceIT();
26090        return;
26091      }
26092    }
26093  } else {
26094    // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
26095    if (encoded_dt.IsValid()) {
26096      if (cond.Is(al)) {
26097        EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26098                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
26099                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26100        return;
26101      }
26102    }
26103  }
26104  Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm);
26105}
26106
26107void Assembler::vsubw(
26108    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
26109  VIXL_ASSERT(AllowAssembler());
26110  CheckIT(cond);
26111  Dt_U_size_1 encoded_dt(dt);
26112  if (IsUsingT32()) {
26113    // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
26114    if (encoded_dt.IsValid()) {
26115      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26116        EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26117                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
26118                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26119        AdvanceIT();
26120        return;
26121      }
26122    }
26123  } else {
26124    // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
26125    if (encoded_dt.IsValid()) {
26126      if (cond.Is(al)) {
26127        EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26128                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
26129                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26130        return;
26131      }
26132    }
26133  }
26134  Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm);
26135}
26136
26137void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26138  VIXL_ASSERT(AllowAssembler());
26139  CheckIT(cond);
26140  USE(dt);
26141  if (IsUsingT32()) {
26142    // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
26143    if (cond.Is(al) || AllowStronglyDiscouraged()) {
26144      EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
26145      AdvanceIT();
26146      return;
26147    }
26148  } else {
26149    // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
26150    if (cond.Is(al)) {
26151      EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
26152      return;
26153    }
26154  }
26155  Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
26156}
26157
26158void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26159  VIXL_ASSERT(AllowAssembler());
26160  CheckIT(cond);
26161  USE(dt);
26162  if (IsUsingT32()) {
26163    // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
26164    if (cond.Is(al) || AllowStronglyDiscouraged()) {
26165      EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
26166      AdvanceIT();
26167      return;
26168    }
26169  } else {
26170    // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
26171    if (cond.Is(al)) {
26172      EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
26173      return;
26174    }
26175  }
26176  Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
26177}
26178
26179void Assembler::vtbl(Condition cond,
26180                     DataType dt,
26181                     DRegister rd,
26182                     const NeonRegisterList& nreglist,
26183                     DRegister rm) {
26184  VIXL_ASSERT(AllowAssembler());
26185  CheckIT(cond);
26186  if (IsUsingT32()) {
26187    // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
26188    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26189        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26190      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26191        const DRegister& first = nreglist.GetFirstDRegister();
26192        uint32_t len_encoding = nreglist.GetLength() - 1;
26193        EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
26194                   (len_encoding << 8) | rm.Encode(5, 0));
26195        AdvanceIT();
26196        return;
26197      }
26198    }
26199  } else {
26200    // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
26201    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26202        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26203      if (cond.Is(al)) {
26204        const DRegister& first = nreglist.GetFirstDRegister();
26205        uint32_t len_encoding = nreglist.GetLength() - 1;
26206        EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
26207                (len_encoding << 8) | rm.Encode(5, 0));
26208        return;
26209      }
26210    }
26211  }
26212  Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm);
26213}
26214
26215void Assembler::vtbx(Condition cond,
26216                     DataType dt,
26217                     DRegister rd,
26218                     const NeonRegisterList& nreglist,
26219                     DRegister rm) {
26220  VIXL_ASSERT(AllowAssembler());
26221  CheckIT(cond);
26222  if (IsUsingT32()) {
26223    // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
26224    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26225        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26226      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26227        const DRegister& first = nreglist.GetFirstDRegister();
26228        uint32_t len_encoding = nreglist.GetLength() - 1;
26229        EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
26230                   (len_encoding << 8) | rm.Encode(5, 0));
26231        AdvanceIT();
26232        return;
26233      }
26234    }
26235  } else {
26236    // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
26237    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26238        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26239      if (cond.Is(al)) {
26240        const DRegister& first = nreglist.GetFirstDRegister();
26241        uint32_t len_encoding = nreglist.GetLength() - 1;
26242        EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
26243                (len_encoding << 8) | rm.Encode(5, 0));
26244        return;
26245      }
26246    }
26247  }
26248  Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm);
26249}
26250
26251void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26252  VIXL_ASSERT(AllowAssembler());
26253  CheckIT(cond);
26254  Dt_size_7 encoded_dt(dt);
26255  if (IsUsingT32()) {
26256    // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
26257    if (encoded_dt.IsValid()) {
26258      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26259        EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) |
26260                   rd.Encode(22, 12) | rm.Encode(5, 0));
26261        AdvanceIT();
26262        return;
26263      }
26264    }
26265  } else {
26266    // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
26267    if (encoded_dt.IsValid()) {
26268      if (cond.Is(al)) {
26269        EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) |
26270                rd.Encode(22, 12) | rm.Encode(5, 0));
26271        return;
26272      }
26273    }
26274  }
26275  Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
26276}
26277
26278void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26279  VIXL_ASSERT(AllowAssembler());
26280  CheckIT(cond);
26281  Dt_size_7 encoded_dt(dt);
26282  if (IsUsingT32()) {
26283    // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
26284    if (encoded_dt.IsValid()) {
26285      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26286        EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) |
26287                   rd.Encode(22, 12) | rm.Encode(5, 0));
26288        AdvanceIT();
26289        return;
26290      }
26291    }
26292  } else {
26293    // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
26294    if (encoded_dt.IsValid()) {
26295      if (cond.Is(al)) {
26296        EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) |
26297                rd.Encode(22, 12) | rm.Encode(5, 0));
26298        return;
26299      }
26300    }
26301  }
26302  Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
26303}
26304
26305void Assembler::vtst(
26306    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
26307  VIXL_ASSERT(AllowAssembler());
26308  CheckIT(cond);
26309  Dt_size_7 encoded_dt(dt);
26310  if (IsUsingT32()) {
26311    // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
26312    if (encoded_dt.IsValid()) {
26313      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26314        EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) |
26315                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26316        AdvanceIT();
26317        return;
26318      }
26319    }
26320  } else {
26321    // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
26322    if (encoded_dt.IsValid()) {
26323      if (cond.Is(al)) {
26324        EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) |
26325                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26326        return;
26327      }
26328    }
26329  }
26330  Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
26331}
26332
26333void Assembler::vtst(
26334    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
26335  VIXL_ASSERT(AllowAssembler());
26336  CheckIT(cond);
26337  Dt_size_7 encoded_dt(dt);
26338  if (IsUsingT32()) {
26339    // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
26340    if (encoded_dt.IsValid()) {
26341      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26342        EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) |
26343                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26344        AdvanceIT();
26345        return;
26346      }
26347    }
26348  } else {
26349    // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
26350    if (encoded_dt.IsValid()) {
26351      if (cond.Is(al)) {
26352        EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) |
26353                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26354        return;
26355      }
26356    }
26357  }
26358  Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
26359}
26360
26361void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26362  VIXL_ASSERT(AllowAssembler());
26363  CheckIT(cond);
26364  Dt_size_15 encoded_dt(dt);
26365  if (IsUsingT32()) {
26366    // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
26367    if (encoded_dt.IsValid()) {
26368      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26369        EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) |
26370                   rd.Encode(22, 12) | rm.Encode(5, 0));
26371        AdvanceIT();
26372        return;
26373      }
26374    }
26375    // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
26376    if (dt.Is(Untyped32)) {
26377      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26378        EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26379        AdvanceIT();
26380        return;
26381      }
26382    }
26383  } else {
26384    // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
26385    if (encoded_dt.IsValid()) {
26386      if (cond.Is(al)) {
26387        EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) |
26388                rd.Encode(22, 12) | rm.Encode(5, 0));
26389        return;
26390      }
26391    }
26392    // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
26393    if (dt.Is(Untyped32)) {
26394      if (cond.Is(al)) {
26395        EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26396        return;
26397      }
26398    }
26399  }
26400  Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
26401}
26402
26403void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26404  VIXL_ASSERT(AllowAssembler());
26405  CheckIT(cond);
26406  Dt_size_7 encoded_dt(dt);
26407  if (IsUsingT32()) {
26408    // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
26409    if (encoded_dt.IsValid()) {
26410      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26411        EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) |
26412                   rd.Encode(22, 12) | rm.Encode(5, 0));
26413        AdvanceIT();
26414        return;
26415      }
26416    }
26417  } else {
26418    // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
26419    if (encoded_dt.IsValid()) {
26420      if (cond.Is(al)) {
26421        EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) |
26422                rd.Encode(22, 12) | rm.Encode(5, 0));
26423        return;
26424      }
26425    }
26426  }
26427  Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
26428}
26429
26430void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26431  VIXL_ASSERT(AllowAssembler());
26432  CheckIT(cond);
26433  Dt_size_15 encoded_dt(dt);
26434  if (IsUsingT32()) {
26435    // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
26436    if (encoded_dt.IsValid()) {
26437      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26438        EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) |
26439                   rd.Encode(22, 12) | rm.Encode(5, 0));
26440        AdvanceIT();
26441        return;
26442      }
26443    }
26444    // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
26445    if (dt.Is(Untyped32)) {
26446      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26447        EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26448        AdvanceIT();
26449        return;
26450      }
26451    }
26452  } else {
26453    // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
26454    if (encoded_dt.IsValid()) {
26455      if (cond.Is(al)) {
26456        EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) |
26457                rd.Encode(22, 12) | rm.Encode(5, 0));
26458        return;
26459      }
26460    }
26461    // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
26462    if (dt.Is(Untyped32)) {
26463      if (cond.Is(al)) {
26464        EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26465        return;
26466      }
26467    }
26468  }
26469  Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
26470}
26471
26472void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26473  VIXL_ASSERT(AllowAssembler());
26474  CheckIT(cond);
26475  Dt_size_7 encoded_dt(dt);
26476  if (IsUsingT32()) {
26477    // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
26478    if (encoded_dt.IsValid()) {
26479      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26480        EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) |
26481                   rd.Encode(22, 12) | rm.Encode(5, 0));
26482        AdvanceIT();
26483        return;
26484      }
26485    }
26486  } else {
26487    // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
26488    if (encoded_dt.IsValid()) {
26489      if (cond.Is(al)) {
26490        EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) |
26491                rd.Encode(22, 12) | rm.Encode(5, 0));
26492        return;
26493      }
26494    }
26495  }
26496  Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
26497}
26498
26499void Assembler::yield(Condition cond, EncodingSize size) {
26500  VIXL_ASSERT(AllowAssembler());
26501  CheckIT(cond);
26502  if (IsUsingT32()) {
26503    // YIELD{<c>}{<q>} ; T1
26504    if (!size.IsWide()) {
26505      EmitT32_16(0xbf10);
26506      AdvanceIT();
26507      return;
26508    }
26509    // YIELD{<c>}.W ; T2
26510    if (!size.IsNarrow()) {
26511      EmitT32_32(0xf3af8001U);
26512      AdvanceIT();
26513      return;
26514    }
26515  } else {
26516    // YIELD{<c>}{<q>} ; A1
26517    if (cond.IsNotNever()) {
26518      EmitA32(0x0320f001U | (cond.GetCondition() << 28));
26519      return;
26520    }
26521  }
26522  Delegate(kYield, &Assembler::yield, cond, size);
26523}
26524// End of generated code.
26525
26526}  // namespace aarch32
26527}  // namespace vixl
26528