assembler-aarch32.cc revision 942e3b7b1d381454c8f17c31c8a3ccbe568512f7
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/operands-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  label->SetReferenced();
101  if (label->IsBound()) {
102    return op.Encode(instr,
103                     GetCursorOffset() + GetArchitectureStatePCOffset(),
104                     label);
105  }
106  label->AddForwardRef(GetCursorOffset(), IsUsingT32(), op);
107  return instr;
108}
109
110
111void Assembler::EncodeLabelFor(const Label::ForwardReference& forward,
112                               Label* label) {
113  const uint32_t location = forward.GetLocation();
114  const uint32_t from = location + forward.GetStatePCOffset();
115  const Label::LabelEmitOperator& encoder = forward.GetEmitOperator();
116  if (forward.IsUsingT32()) {
117    uint16_t* instr_ptr = buffer_.GetOffsetAddress<uint16_t*>(location);
118    if (Is16BitEncoding(instr_ptr[0])) {
119      // The Encode methods always deals with uint32_t types so we need
120      // to explicitely cast it.
121      uint32_t instr = static_cast<uint32_t>(instr_ptr[0]);
122      instr = encoder.Encode(instr, from, label);
123      // The Encode method should not ever set the top 16 bits.
124      VIXL_ASSERT((instr & ~0xffff) == 0);
125      instr_ptr[0] = static_cast<uint16_t>(instr);
126    } else {
127      uint32_t instr =
128          instr_ptr[1] | (static_cast<uint32_t>(instr_ptr[0]) << 16);
129      instr = encoder.Encode(instr, from, label);
130      instr_ptr[0] = static_cast<uint16_t>(instr >> 16);
131      instr_ptr[1] = static_cast<uint16_t>(instr);
132    }
133  } else {
134    uint32_t* instr_ptr = buffer_.GetOffsetAddress<uint32_t*>(location);
135    instr_ptr[0] = encoder.Encode(instr_ptr[0], from, label);
136  }
137}
138
139
140// Start of generated code.
141class Dt_L_imm6_1 : public EncodingValue {
142  uint32_t type_;
143
144 public:
145  explicit Dt_L_imm6_1(DataType dt);
146  uint32_t GetTypeEncodingValue() const { return type_; }
147};
148
149Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) {
150  switch (dt.GetValue()) {
151    case S8:
152      type_ = 0x0;
153      SetEncodingValue(0x1);
154      break;
155    case U8:
156      type_ = 0x1;
157      SetEncodingValue(0x1);
158      break;
159    case S16:
160      type_ = 0x0;
161      SetEncodingValue(0x2);
162      break;
163    case U16:
164      type_ = 0x1;
165      SetEncodingValue(0x2);
166      break;
167    case S32:
168      type_ = 0x0;
169      SetEncodingValue(0x4);
170      break;
171    case U32:
172      type_ = 0x1;
173      SetEncodingValue(0x4);
174      break;
175    case S64:
176      type_ = 0x0;
177      SetEncodingValue(0x8);
178      break;
179    case U64:
180      type_ = 0x1;
181      SetEncodingValue(0x8);
182      break;
183    default:
184      VIXL_UNREACHABLE();
185      type_ = 0x0;
186      break;
187  }
188}
189
190class Dt_L_imm6_2 : public EncodingValue {
191  uint32_t type_;
192
193 public:
194  explicit Dt_L_imm6_2(DataType dt);
195  uint32_t GetTypeEncodingValue() const { return type_; }
196};
197
198Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) {
199  switch (dt.GetValue()) {
200    case S8:
201      type_ = 0x1;
202      SetEncodingValue(0x1);
203      break;
204    case S16:
205      type_ = 0x1;
206      SetEncodingValue(0x2);
207      break;
208    case S32:
209      type_ = 0x1;
210      SetEncodingValue(0x4);
211      break;
212    case S64:
213      type_ = 0x1;
214      SetEncodingValue(0x8);
215      break;
216    default:
217      VIXL_UNREACHABLE();
218      type_ = 0x0;
219      break;
220  }
221}
222
223class Dt_L_imm6_3 : public EncodingValue {
224 public:
225  explicit Dt_L_imm6_3(DataType dt);
226};
227
228Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) {
229  switch (dt.GetValue()) {
230    case I8:
231      SetEncodingValue(0x1);
232      break;
233    case I16:
234      SetEncodingValue(0x2);
235      break;
236    case I32:
237      SetEncodingValue(0x4);
238      break;
239    case I64:
240      SetEncodingValue(0x8);
241      break;
242    default:
243      break;
244  }
245}
246
247class Dt_L_imm6_4 : public EncodingValue {
248 public:
249  explicit Dt_L_imm6_4(DataType dt);
250};
251
252Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) {
253  switch (dt.GetValue()) {
254    case Untyped8:
255      SetEncodingValue(0x1);
256      break;
257    case Untyped16:
258      SetEncodingValue(0x2);
259      break;
260    case Untyped32:
261      SetEncodingValue(0x4);
262      break;
263    case Untyped64:
264      SetEncodingValue(0x8);
265      break;
266    default:
267      break;
268  }
269}
270
271class Dt_imm6_1 : public EncodingValue {
272  uint32_t type_;
273
274 public:
275  explicit Dt_imm6_1(DataType dt);
276  uint32_t GetTypeEncodingValue() const { return type_; }
277};
278
279Dt_imm6_1::Dt_imm6_1(DataType dt) {
280  switch (dt.GetValue()) {
281    case S16:
282      type_ = 0x0;
283      SetEncodingValue(0x1);
284      break;
285    case U16:
286      type_ = 0x1;
287      SetEncodingValue(0x1);
288      break;
289    case S32:
290      type_ = 0x0;
291      SetEncodingValue(0x2);
292      break;
293    case U32:
294      type_ = 0x1;
295      SetEncodingValue(0x2);
296      break;
297    case S64:
298      type_ = 0x0;
299      SetEncodingValue(0x4);
300      break;
301    case U64:
302      type_ = 0x1;
303      SetEncodingValue(0x4);
304      break;
305    default:
306      VIXL_UNREACHABLE();
307      type_ = 0x0;
308      break;
309  }
310}
311
312class Dt_imm6_2 : public EncodingValue {
313  uint32_t type_;
314
315 public:
316  explicit Dt_imm6_2(DataType dt);
317  uint32_t GetTypeEncodingValue() const { return type_; }
318};
319
320Dt_imm6_2::Dt_imm6_2(DataType dt) {
321  switch (dt.GetValue()) {
322    case S16:
323      type_ = 0x1;
324      SetEncodingValue(0x1);
325      break;
326    case S32:
327      type_ = 0x1;
328      SetEncodingValue(0x2);
329      break;
330    case S64:
331      type_ = 0x1;
332      SetEncodingValue(0x4);
333      break;
334    default:
335      VIXL_UNREACHABLE();
336      type_ = 0x0;
337      break;
338  }
339}
340
341class Dt_imm6_3 : public EncodingValue {
342 public:
343  explicit Dt_imm6_3(DataType dt);
344};
345
346Dt_imm6_3::Dt_imm6_3(DataType dt) {
347  switch (dt.GetValue()) {
348    case I16:
349      SetEncodingValue(0x1);
350      break;
351    case I32:
352      SetEncodingValue(0x2);
353      break;
354    case I64:
355      SetEncodingValue(0x4);
356      break;
357    default:
358      break;
359  }
360}
361
362class Dt_imm6_4 : public EncodingValue {
363  uint32_t type_;
364
365 public:
366  explicit Dt_imm6_4(DataType dt);
367  uint32_t GetTypeEncodingValue() const { return type_; }
368};
369
370Dt_imm6_4::Dt_imm6_4(DataType dt) {
371  switch (dt.GetValue()) {
372    case S8:
373      type_ = 0x0;
374      SetEncodingValue(0x1);
375      break;
376    case U8:
377      type_ = 0x1;
378      SetEncodingValue(0x1);
379      break;
380    case S16:
381      type_ = 0x0;
382      SetEncodingValue(0x2);
383      break;
384    case U16:
385      type_ = 0x1;
386      SetEncodingValue(0x2);
387      break;
388    case S32:
389      type_ = 0x0;
390      SetEncodingValue(0x4);
391      break;
392    case U32:
393      type_ = 0x1;
394      SetEncodingValue(0x4);
395      break;
396    default:
397      VIXL_UNREACHABLE();
398      type_ = 0x0;
399      break;
400  }
401}
402
403class Dt_op_U_size_1 : public EncodingValue {
404 public:
405  explicit Dt_op_U_size_1(DataType dt);
406};
407
408Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) {
409  switch (dt.GetValue()) {
410    case S8:
411      SetEncodingValue(0x0);
412      break;
413    case S16:
414      SetEncodingValue(0x1);
415      break;
416    case S32:
417      SetEncodingValue(0x2);
418      break;
419    case U8:
420      SetEncodingValue(0x4);
421      break;
422    case U16:
423      SetEncodingValue(0x5);
424      break;
425    case U32:
426      SetEncodingValue(0x6);
427      break;
428    case P8:
429      SetEncodingValue(0x8);
430      break;
431    case P64:
432      SetEncodingValue(0xa);
433      break;
434    default:
435      break;
436  }
437}
438
439class Dt_op_size_1 : public EncodingValue {
440 public:
441  explicit Dt_op_size_1(DataType dt);
442};
443
444Dt_op_size_1::Dt_op_size_1(DataType dt) {
445  switch (dt.GetValue()) {
446    case I8:
447      SetEncodingValue(0x0);
448      break;
449    case I16:
450      SetEncodingValue(0x1);
451      break;
452    case I32:
453      SetEncodingValue(0x2);
454      break;
455    case P8:
456      SetEncodingValue(0x4);
457      break;
458    default:
459      break;
460  }
461}
462
463class Dt_op_size_2 : public EncodingValue {
464 public:
465  explicit Dt_op_size_2(DataType dt);
466};
467
468Dt_op_size_2::Dt_op_size_2(DataType dt) {
469  switch (dt.GetValue()) {
470    case S8:
471      SetEncodingValue(0x0);
472      break;
473    case S16:
474      SetEncodingValue(0x1);
475      break;
476    case S32:
477      SetEncodingValue(0x2);
478      break;
479    case U8:
480      SetEncodingValue(0x4);
481      break;
482    case U16:
483      SetEncodingValue(0x5);
484      break;
485    case U32:
486      SetEncodingValue(0x6);
487      break;
488    default:
489      break;
490  }
491}
492
493class Dt_op_size_3 : public EncodingValue {
494 public:
495  explicit Dt_op_size_3(DataType dt);
496};
497
498Dt_op_size_3::Dt_op_size_3(DataType dt) {
499  switch (dt.GetValue()) {
500    case S16:
501      SetEncodingValue(0x0);
502      break;
503    case S32:
504      SetEncodingValue(0x1);
505      break;
506    case S64:
507      SetEncodingValue(0x2);
508      break;
509    case U16:
510      SetEncodingValue(0x4);
511      break;
512    case U32:
513      SetEncodingValue(0x5);
514      break;
515    case U64:
516      SetEncodingValue(0x6);
517      break;
518    default:
519      break;
520  }
521}
522
523class Dt_U_imm3H_1 : public EncodingValue {
524 public:
525  explicit Dt_U_imm3H_1(DataType dt);
526};
527
528Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) {
529  switch (dt.GetValue()) {
530    case S8:
531      SetEncodingValue(0x1);
532      break;
533    case S16:
534      SetEncodingValue(0x2);
535      break;
536    case S32:
537      SetEncodingValue(0x4);
538      break;
539    case U8:
540      SetEncodingValue(0x9);
541      break;
542    case U16:
543      SetEncodingValue(0xa);
544      break;
545    case U32:
546      SetEncodingValue(0xc);
547      break;
548    default:
549      break;
550  }
551}
552
553class Dt_U_opc1_opc2_1 : public EncodingValue {
554 public:
555  explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
556};
557
558Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
559  switch (dt.GetValue()) {
560    case S8:
561      if ((lane.GetLane() & 7) != lane.GetLane()) {
562        return;
563      }
564      SetEncodingValue(0x8 | lane.GetLane());
565      break;
566    case S16:
567      if ((lane.GetLane() & 3) != lane.GetLane()) {
568        return;
569      }
570      SetEncodingValue(0x1 | (lane.GetLane() << 1));
571      break;
572    case U8:
573      if ((lane.GetLane() & 7) != lane.GetLane()) {
574        return;
575      }
576      SetEncodingValue(0x18 | lane.GetLane());
577      break;
578    case U16:
579      if ((lane.GetLane() & 3) != lane.GetLane()) {
580        return;
581      }
582      SetEncodingValue(0x11 | (lane.GetLane() << 1));
583      break;
584    case Untyped32:
585      if ((lane.GetLane() & 1) != lane.GetLane()) {
586        return;
587      }
588      SetEncodingValue(0x0 | (lane.GetLane() << 2));
589      break;
590    case kDataTypeValueNone:
591      if ((lane.GetLane() & 1) != lane.GetLane()) {
592        return;
593      }
594      SetEncodingValue(0x0 | (lane.GetLane() << 2));
595      break;
596    default:
597      break;
598  }
599}
600
601class Dt_opc1_opc2_1 : public EncodingValue {
602 public:
603  explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
604};
605
606Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
607  switch (dt.GetValue()) {
608    case Untyped8:
609      if ((lane.GetLane() & 7) != lane.GetLane()) {
610        return;
611      }
612      SetEncodingValue(0x8 | lane.GetLane());
613      break;
614    case Untyped16:
615      if ((lane.GetLane() & 3) != lane.GetLane()) {
616        return;
617      }
618      SetEncodingValue(0x1 | (lane.GetLane() << 1));
619      break;
620    case Untyped32:
621      if ((lane.GetLane() & 1) != lane.GetLane()) {
622        return;
623      }
624      SetEncodingValue(0x0 | (lane.GetLane() << 2));
625      break;
626    case kDataTypeValueNone:
627      if ((lane.GetLane() & 1) != lane.GetLane()) {
628        return;
629      }
630      SetEncodingValue(0x0 | (lane.GetLane() << 2));
631      break;
632    default:
633      break;
634  }
635}
636
637class Dt_imm4_1 : public EncodingValue {
638 public:
639  explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane);
640};
641
642Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) {
643  switch (dt.GetValue()) {
644    case Untyped8:
645      if ((lane.GetLane() & 7) != lane.GetLane()) {
646        return;
647      }
648      SetEncodingValue(0x1 | (lane.GetLane() << 1));
649      break;
650    case Untyped16:
651      if ((lane.GetLane() & 3) != lane.GetLane()) {
652        return;
653      }
654      SetEncodingValue(0x2 | (lane.GetLane() << 2));
655      break;
656    case Untyped32:
657      if ((lane.GetLane() & 1) != lane.GetLane()) {
658        return;
659      }
660      SetEncodingValue(0x4 | (lane.GetLane() << 3));
661      break;
662    default:
663      break;
664  }
665}
666
667class Dt_B_E_1 : public EncodingValue {
668 public:
669  explicit Dt_B_E_1(DataType dt);
670};
671
672Dt_B_E_1::Dt_B_E_1(DataType dt) {
673  switch (dt.GetValue()) {
674    case Untyped8:
675      SetEncodingValue(0x2);
676      break;
677    case Untyped16:
678      SetEncodingValue(0x1);
679      break;
680    case Untyped32:
681      SetEncodingValue(0x0);
682      break;
683    default:
684      break;
685  }
686}
687
688class Dt_op_1 : public EncodingValue {
689 public:
690  Dt_op_1(DataType dt1, DataType dt2);
691};
692
693Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) {
694  if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
695    SetEncodingValue(0x0);
696    return;
697  }
698  if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
699    SetEncodingValue(0x1);
700    return;
701  }
702  if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
703    SetEncodingValue(0x2);
704    return;
705  }
706  if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
707    SetEncodingValue(0x3);
708    return;
709  }
710}
711
712class Dt_op_2 : public EncodingValue {
713 public:
714  explicit Dt_op_2(DataType dt);
715};
716
717Dt_op_2::Dt_op_2(DataType dt) {
718  switch (dt.GetValue()) {
719    case U32:
720      SetEncodingValue(0x0);
721      break;
722    case S32:
723      SetEncodingValue(0x1);
724      break;
725    default:
726      break;
727  }
728}
729
730class Dt_op_3 : public EncodingValue {
731 public:
732  explicit Dt_op_3(DataType dt);
733};
734
735Dt_op_3::Dt_op_3(DataType dt) {
736  switch (dt.GetValue()) {
737    case S32:
738      SetEncodingValue(0x0);
739      break;
740    case U32:
741      SetEncodingValue(0x1);
742      break;
743    default:
744      break;
745  }
746}
747
748class Dt_U_sx_1 : public EncodingValue {
749 public:
750  explicit Dt_U_sx_1(DataType dt);
751};
752
753Dt_U_sx_1::Dt_U_sx_1(DataType dt) {
754  switch (dt.GetValue()) {
755    case S16:
756      SetEncodingValue(0x0);
757      break;
758    case S32:
759      SetEncodingValue(0x1);
760      break;
761    case U16:
762      SetEncodingValue(0x2);
763      break;
764    case U32:
765      SetEncodingValue(0x3);
766      break;
767    default:
768      break;
769  }
770}
771
772class Dt_op_U_1 : public EncodingValue {
773 public:
774  Dt_op_U_1(DataType dt1, DataType dt2);
775};
776
777Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) {
778  if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
779    SetEncodingValue(0x0);
780    return;
781  }
782  if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
783    SetEncodingValue(0x1);
784    return;
785  }
786  if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
787    SetEncodingValue(0x2);
788    return;
789  }
790  if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
791    SetEncodingValue(0x3);
792    return;
793  }
794}
795
796class Dt_sz_1 : public EncodingValue {
797 public:
798  explicit Dt_sz_1(DataType dt);
799};
800
801Dt_sz_1::Dt_sz_1(DataType dt) {
802  switch (dt.GetValue()) {
803    case F32:
804      SetEncodingValue(0x0);
805      break;
806    default:
807      break;
808  }
809}
810
811class Dt_F_size_1 : public EncodingValue {
812 public:
813  explicit Dt_F_size_1(DataType dt);
814};
815
816Dt_F_size_1::Dt_F_size_1(DataType dt) {
817  switch (dt.GetValue()) {
818    case S8:
819      SetEncodingValue(0x0);
820      break;
821    case S16:
822      SetEncodingValue(0x1);
823      break;
824    case S32:
825      SetEncodingValue(0x2);
826      break;
827    case F32:
828      SetEncodingValue(0x6);
829      break;
830    default:
831      break;
832  }
833}
834
835class Dt_F_size_2 : public EncodingValue {
836 public:
837  explicit Dt_F_size_2(DataType dt);
838};
839
840Dt_F_size_2::Dt_F_size_2(DataType dt) {
841  switch (dt.GetValue()) {
842    case I8:
843      SetEncodingValue(0x0);
844      break;
845    case I16:
846      SetEncodingValue(0x1);
847      break;
848    case I32:
849      SetEncodingValue(0x2);
850      break;
851    case F32:
852      SetEncodingValue(0x6);
853      break;
854    default:
855      break;
856  }
857}
858
859class Dt_F_size_3 : public EncodingValue {
860 public:
861  explicit Dt_F_size_3(DataType dt);
862};
863
864Dt_F_size_3::Dt_F_size_3(DataType dt) {
865  switch (dt.GetValue()) {
866    case I16:
867      SetEncodingValue(0x1);
868      break;
869    case I32:
870      SetEncodingValue(0x2);
871      break;
872    case F32:
873      SetEncodingValue(0x6);
874      break;
875    default:
876      break;
877  }
878}
879
880class Dt_F_size_4 : public EncodingValue {
881 public:
882  explicit Dt_F_size_4(DataType dt);
883};
884
885Dt_F_size_4::Dt_F_size_4(DataType dt) {
886  switch (dt.GetValue()) {
887    case U32:
888      SetEncodingValue(0x2);
889      break;
890    case F32:
891      SetEncodingValue(0x6);
892      break;
893    default:
894      break;
895  }
896}
897
898class Dt_U_size_1 : public EncodingValue {
899 public:
900  explicit Dt_U_size_1(DataType dt);
901};
902
903Dt_U_size_1::Dt_U_size_1(DataType dt) {
904  switch (dt.GetValue()) {
905    case S8:
906      SetEncodingValue(0x0);
907      break;
908    case S16:
909      SetEncodingValue(0x1);
910      break;
911    case S32:
912      SetEncodingValue(0x2);
913      break;
914    case U8:
915      SetEncodingValue(0x4);
916      break;
917    case U16:
918      SetEncodingValue(0x5);
919      break;
920    case U32:
921      SetEncodingValue(0x6);
922      break;
923    default:
924      break;
925  }
926}
927
928class Dt_U_size_2 : public EncodingValue {
929 public:
930  explicit Dt_U_size_2(DataType dt);
931};
932
933Dt_U_size_2::Dt_U_size_2(DataType dt) {
934  switch (dt.GetValue()) {
935    case S16:
936      SetEncodingValue(0x1);
937      break;
938    case S32:
939      SetEncodingValue(0x2);
940      break;
941    case U16:
942      SetEncodingValue(0x5);
943      break;
944    case U32:
945      SetEncodingValue(0x6);
946      break;
947    default:
948      break;
949  }
950}
951
952class Dt_U_size_3 : public EncodingValue {
953 public:
954  explicit Dt_U_size_3(DataType dt);
955};
956
957Dt_U_size_3::Dt_U_size_3(DataType dt) {
958  switch (dt.GetValue()) {
959    case S8:
960      SetEncodingValue(0x0);
961      break;
962    case S16:
963      SetEncodingValue(0x1);
964      break;
965    case S32:
966      SetEncodingValue(0x2);
967      break;
968    case S64:
969      SetEncodingValue(0x3);
970      break;
971    case U8:
972      SetEncodingValue(0x4);
973      break;
974    case U16:
975      SetEncodingValue(0x5);
976      break;
977    case U32:
978      SetEncodingValue(0x6);
979      break;
980    case U64:
981      SetEncodingValue(0x7);
982      break;
983    default:
984      break;
985  }
986}
987
988class Dt_size_1 : public EncodingValue {
989 public:
990  explicit Dt_size_1(DataType dt);
991};
992
993Dt_size_1::Dt_size_1(DataType dt) {
994  switch (dt.GetValue()) {
995    case Untyped8:
996      SetEncodingValue(0x0);
997      break;
998    default:
999      break;
1000  }
1001}
1002
1003class Dt_size_2 : public EncodingValue {
1004 public:
1005  explicit Dt_size_2(DataType dt);
1006};
1007
1008Dt_size_2::Dt_size_2(DataType dt) {
1009  switch (dt.GetValue()) {
1010    case I8:
1011      SetEncodingValue(0x0);
1012      break;
1013    case I16:
1014      SetEncodingValue(0x1);
1015      break;
1016    case I32:
1017      SetEncodingValue(0x2);
1018      break;
1019    case I64:
1020      SetEncodingValue(0x3);
1021      break;
1022    default:
1023      break;
1024  }
1025}
1026
1027class Dt_size_3 : public EncodingValue {
1028 public:
1029  explicit Dt_size_3(DataType dt);
1030};
1031
1032Dt_size_3::Dt_size_3(DataType dt) {
1033  switch (dt.GetValue()) {
1034    case I16:
1035      SetEncodingValue(0x0);
1036      break;
1037    case I32:
1038      SetEncodingValue(0x1);
1039      break;
1040    case I64:
1041      SetEncodingValue(0x2);
1042      break;
1043    default:
1044      break;
1045  }
1046}
1047
1048class Dt_size_4 : public EncodingValue {
1049 public:
1050  explicit Dt_size_4(DataType dt);
1051};
1052
1053Dt_size_4::Dt_size_4(DataType dt) {
1054  switch (dt.GetValue()) {
1055    case I8:
1056      SetEncodingValue(0x0);
1057      break;
1058    case I16:
1059      SetEncodingValue(0x1);
1060      break;
1061    case I32:
1062      SetEncodingValue(0x2);
1063      break;
1064    default:
1065      break;
1066  }
1067}
1068
1069class Dt_size_5 : public EncodingValue {
1070 public:
1071  explicit Dt_size_5(DataType dt);
1072};
1073
1074Dt_size_5::Dt_size_5(DataType dt) {
1075  switch (dt.GetValue()) {
1076    case S8:
1077      SetEncodingValue(0x0);
1078      break;
1079    case S16:
1080      SetEncodingValue(0x1);
1081      break;
1082    case S32:
1083      SetEncodingValue(0x2);
1084      break;
1085    default:
1086      break;
1087  }
1088}
1089
1090class Dt_size_6 : public EncodingValue {
1091 public:
1092  explicit Dt_size_6(DataType dt);
1093};
1094
1095Dt_size_6::Dt_size_6(DataType dt) {
1096  switch (dt.GetValue()) {
1097    case Untyped8:
1098      SetEncodingValue(0x0);
1099      break;
1100    case Untyped16:
1101      SetEncodingValue(0x1);
1102      break;
1103    case Untyped32:
1104      SetEncodingValue(0x2);
1105      break;
1106    case Untyped64:
1107      SetEncodingValue(0x3);
1108      break;
1109    default:
1110      break;
1111  }
1112}
1113
1114class Dt_size_7 : public EncodingValue {
1115 public:
1116  explicit Dt_size_7(DataType dt);
1117};
1118
1119Dt_size_7::Dt_size_7(DataType dt) {
1120  switch (dt.GetValue()) {
1121    case Untyped8:
1122      SetEncodingValue(0x0);
1123      break;
1124    case Untyped16:
1125      SetEncodingValue(0x1);
1126      break;
1127    case Untyped32:
1128      SetEncodingValue(0x2);
1129      break;
1130    default:
1131      break;
1132  }
1133}
1134
1135class Dt_size_8 : public EncodingValue {
1136 public:
1137  Dt_size_8(DataType dt, Alignment align);
1138};
1139
1140Dt_size_8::Dt_size_8(DataType dt, Alignment align) {
1141  switch (dt.GetValue()) {
1142    case Untyped8:
1143      SetEncodingValue(0x0);
1144      break;
1145    case Untyped16:
1146      SetEncodingValue(0x1);
1147      break;
1148    case Untyped32:
1149      if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) {
1150        SetEncodingValue(0x2);
1151      } else if (align.Is(k128BitAlign)) {
1152        SetEncodingValue(0x3);
1153      }
1154      break;
1155    default:
1156      break;
1157  }
1158}
1159
1160class Dt_size_9 : public EncodingValue {
1161  uint32_t type_;
1162
1163 public:
1164  explicit Dt_size_9(DataType dt);
1165  uint32_t GetTypeEncodingValue() const { return type_; }
1166};
1167
1168Dt_size_9::Dt_size_9(DataType dt) {
1169  switch (dt.GetValue()) {
1170    case I16:
1171      type_ = 0x0;
1172      SetEncodingValue(0x1);
1173      break;
1174    case I32:
1175      type_ = 0x0;
1176      SetEncodingValue(0x2);
1177      break;
1178    case F32:
1179      type_ = 0x1;
1180      SetEncodingValue(0x2);
1181      break;
1182    default:
1183      VIXL_UNREACHABLE();
1184      type_ = 0x0;
1185      break;
1186  }
1187}
1188
1189class Dt_size_10 : public EncodingValue {
1190 public:
1191  explicit Dt_size_10(DataType dt);
1192};
1193
1194Dt_size_10::Dt_size_10(DataType dt) {
1195  switch (dt.GetValue()) {
1196    case S8:
1197    case U8:
1198    case I8:
1199      SetEncodingValue(0x0);
1200      break;
1201    case S16:
1202    case U16:
1203    case I16:
1204      SetEncodingValue(0x1);
1205      break;
1206    case S32:
1207    case U32:
1208    case I32:
1209      SetEncodingValue(0x2);
1210      break;
1211    default:
1212      break;
1213  }
1214}
1215
1216class Dt_size_11 : public EncodingValue {
1217  uint32_t type_;
1218
1219 public:
1220  explicit Dt_size_11(DataType dt);
1221  uint32_t GetTypeEncodingValue() const { return type_; }
1222};
1223
1224Dt_size_11::Dt_size_11(DataType dt) {
1225  switch (dt.GetValue()) {
1226    case S16:
1227      type_ = 0x0;
1228      SetEncodingValue(0x1);
1229      break;
1230    case U16:
1231      type_ = 0x1;
1232      SetEncodingValue(0x1);
1233      break;
1234    case S32:
1235      type_ = 0x0;
1236      SetEncodingValue(0x2);
1237      break;
1238    case U32:
1239      type_ = 0x1;
1240      SetEncodingValue(0x2);
1241      break;
1242    default:
1243      VIXL_UNREACHABLE();
1244      type_ = 0x0;
1245      break;
1246  }
1247}
1248
1249class Dt_size_12 : public EncodingValue {
1250  uint32_t type_;
1251
1252 public:
1253  explicit Dt_size_12(DataType dt);
1254  uint32_t GetTypeEncodingValue() const { return type_; }
1255};
1256
1257Dt_size_12::Dt_size_12(DataType dt) {
1258  switch (dt.GetValue()) {
1259    case S8:
1260      type_ = 0x0;
1261      SetEncodingValue(0x0);
1262      break;
1263    case U8:
1264      type_ = 0x1;
1265      SetEncodingValue(0x0);
1266      break;
1267    case S16:
1268      type_ = 0x0;
1269      SetEncodingValue(0x1);
1270      break;
1271    case U16:
1272      type_ = 0x1;
1273      SetEncodingValue(0x1);
1274      break;
1275    case S32:
1276      type_ = 0x0;
1277      SetEncodingValue(0x2);
1278      break;
1279    case U32:
1280      type_ = 0x1;
1281      SetEncodingValue(0x2);
1282      break;
1283    default:
1284      VIXL_UNREACHABLE();
1285      type_ = 0x0;
1286      break;
1287  }
1288}
1289
1290class Dt_size_13 : public EncodingValue {
1291 public:
1292  explicit Dt_size_13(DataType dt);
1293};
1294
1295Dt_size_13::Dt_size_13(DataType dt) {
1296  switch (dt.GetValue()) {
1297    case S16:
1298      SetEncodingValue(0x1);
1299      break;
1300    case S32:
1301      SetEncodingValue(0x2);
1302      break;
1303    default:
1304      break;
1305  }
1306}
1307
1308class Dt_size_14 : public EncodingValue {
1309 public:
1310  explicit Dt_size_14(DataType dt);
1311};
1312
1313Dt_size_14::Dt_size_14(DataType dt) {
1314  switch (dt.GetValue()) {
1315    case S16:
1316      SetEncodingValue(0x0);
1317      break;
1318    case S32:
1319      SetEncodingValue(0x1);
1320      break;
1321    case S64:
1322      SetEncodingValue(0x2);
1323      break;
1324    default:
1325      break;
1326  }
1327}
1328
1329class Dt_size_15 : public EncodingValue {
1330 public:
1331  explicit Dt_size_15(DataType dt);
1332};
1333
1334Dt_size_15::Dt_size_15(DataType dt) {
1335  switch (dt.GetValue()) {
1336    case Untyped8:
1337      SetEncodingValue(0x0);
1338      break;
1339    case Untyped16:
1340      SetEncodingValue(0x1);
1341      break;
1342    default:
1343      break;
1344  }
1345}
1346
1347class Dt_size_16 : public EncodingValue {
1348 public:
1349  explicit Dt_size_16(DataType dt);
1350};
1351
1352Dt_size_16::Dt_size_16(DataType dt) {
1353  switch (dt.GetValue()) {
1354    case I8:
1355      SetEncodingValue(0x0);
1356      break;
1357    case I16:
1358      SetEncodingValue(0x1);
1359      break;
1360    case I32:
1361      SetEncodingValue(0x2);
1362      break;
1363    default:
1364      break;
1365  }
1366}
1367
1368class Index_1 : public EncodingValue {
1369 public:
1370  Index_1(const NeonRegisterList& nreglist, DataType dt);
1371};
1372
1373Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) {
1374  switch (dt.GetValue()) {
1375    case Untyped8: {
1376      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1377        return;
1378      }
1379      uint32_t value = nreglist.GetTransferLane() << 1;
1380      if (!nreglist.IsSingleSpaced()) return;
1381      SetEncodingValue(value);
1382      break;
1383    }
1384    case Untyped16: {
1385      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1386        return;
1387      }
1388      uint32_t value = nreglist.GetTransferLane() << 2;
1389      if (nreglist.IsDoubleSpaced()) value |= 2;
1390      SetEncodingValue(value);
1391      break;
1392    }
1393    case Untyped32: {
1394      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1395        return;
1396      }
1397      uint32_t value = nreglist.GetTransferLane() << 3;
1398      if (nreglist.IsDoubleSpaced()) value |= 4;
1399      SetEncodingValue(value);
1400      break;
1401    }
1402    default:
1403      break;
1404  }
1405}
1406
1407class Align_index_align_1 : public EncodingValue {
1408 public:
1409  Align_index_align_1(Alignment align,
1410                      const NeonRegisterList& nreglist,
1411                      DataType dt);
1412};
1413
1414Align_index_align_1::Align_index_align_1(Alignment align,
1415                                         const NeonRegisterList& nreglist,
1416                                         DataType dt) {
1417  switch (dt.GetValue()) {
1418    case Untyped8: {
1419      uint32_t value;
1420      if (align.GetType() == kNoAlignment) {
1421        value = 0;
1422      } else {
1423        return;
1424      }
1425      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1426        return;
1427      }
1428      value |= nreglist.GetTransferLane() << 1;
1429      SetEncodingValue(value);
1430      break;
1431    }
1432    case Untyped16: {
1433      uint32_t value;
1434      if (align.GetType() == k16BitAlign) {
1435        value = 1;
1436      } else if (align.GetType() == kNoAlignment) {
1437        value = 0;
1438      } else {
1439        return;
1440      }
1441      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1442        return;
1443      }
1444      value |= nreglist.GetTransferLane() << 2;
1445      SetEncodingValue(value);
1446      break;
1447    }
1448    case Untyped32: {
1449      uint32_t value;
1450      if (align.GetType() == k32BitAlign) {
1451        value = 3;
1452      } else if (align.GetType() == kNoAlignment) {
1453        value = 0;
1454      } else {
1455        return;
1456      }
1457      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1458        return;
1459      }
1460      value |= nreglist.GetTransferLane() << 3;
1461      SetEncodingValue(value);
1462      break;
1463    }
1464    default:
1465      break;
1466  }
1467}
1468
1469class Align_index_align_2 : public EncodingValue {
1470 public:
1471  Align_index_align_2(Alignment align,
1472                      const NeonRegisterList& nreglist,
1473                      DataType dt);
1474};
1475
1476Align_index_align_2::Align_index_align_2(Alignment align,
1477                                         const NeonRegisterList& nreglist,
1478                                         DataType dt) {
1479  switch (dt.GetValue()) {
1480    case Untyped8: {
1481      uint32_t value;
1482      if (align.GetType() == k16BitAlign) {
1483        value = 1;
1484      } else if (align.GetType() == kNoAlignment) {
1485        value = 0;
1486      } else {
1487        return;
1488      }
1489      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1490        return;
1491      }
1492      value |= nreglist.GetTransferLane() << 1;
1493      if (!nreglist.IsSingleSpaced()) return;
1494      SetEncodingValue(value);
1495      break;
1496    }
1497    case Untyped16: {
1498      uint32_t value;
1499      if (align.GetType() == k32BitAlign) {
1500        value = 1;
1501      } else if (align.GetType() == kNoAlignment) {
1502        value = 0;
1503      } else {
1504        return;
1505      }
1506      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1507        return;
1508      }
1509      value |= nreglist.GetTransferLane() << 2;
1510      if (nreglist.IsDoubleSpaced()) value |= 2;
1511      SetEncodingValue(value);
1512      break;
1513    }
1514    case Untyped32: {
1515      uint32_t value;
1516      if (align.GetType() == k64BitAlign) {
1517        value = 1;
1518      } else if (align.GetType() == kNoAlignment) {
1519        value = 0;
1520      } else {
1521        return;
1522      }
1523      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1524        return;
1525      }
1526      value |= nreglist.GetTransferLane() << 3;
1527      if (nreglist.IsDoubleSpaced()) value |= 4;
1528      SetEncodingValue(value);
1529      break;
1530    }
1531    default:
1532      break;
1533  }
1534}
1535
1536class Align_index_align_3 : public EncodingValue {
1537 public:
1538  Align_index_align_3(Alignment align,
1539                      const NeonRegisterList& nreglist,
1540                      DataType dt);
1541};
1542
1543Align_index_align_3::Align_index_align_3(Alignment align,
1544                                         const NeonRegisterList& nreglist,
1545                                         DataType dt) {
1546  switch (dt.GetValue()) {
1547    case Untyped8: {
1548      uint32_t value;
1549      if (align.GetType() == k32BitAlign) {
1550        value = 1;
1551      } else if (align.GetType() == kNoAlignment) {
1552        value = 0;
1553      } else {
1554        return;
1555      }
1556      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1557        return;
1558      }
1559      value |= nreglist.GetTransferLane() << 1;
1560      if (!nreglist.IsSingleSpaced()) return;
1561      SetEncodingValue(value);
1562      break;
1563    }
1564    case Untyped16: {
1565      uint32_t value;
1566      if (align.GetType() == k64BitAlign) {
1567        value = 1;
1568      } else if (align.GetType() == kNoAlignment) {
1569        value = 0;
1570      } else {
1571        return;
1572      }
1573      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1574        return;
1575      }
1576      value |= nreglist.GetTransferLane() << 2;
1577      if (nreglist.IsDoubleSpaced()) value |= 2;
1578      SetEncodingValue(value);
1579      break;
1580    }
1581    case Untyped32: {
1582      uint32_t value;
1583      if (align.GetType() == k64BitAlign) {
1584        value = 1;
1585      } else if (align.GetType() == k128BitAlign) {
1586        value = 2;
1587      } else if (align.GetType() == kNoAlignment) {
1588        value = 0;
1589      } else {
1590        return;
1591      }
1592      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1593        return;
1594      }
1595      value |= nreglist.GetTransferLane() << 3;
1596      if (nreglist.IsDoubleSpaced()) value |= 4;
1597      SetEncodingValue(value);
1598      break;
1599    }
1600    default:
1601      break;
1602  }
1603}
1604
1605class Align_a_1 : public EncodingValue {
1606 public:
1607  Align_a_1(Alignment align, DataType dt);
1608};
1609
1610Align_a_1::Align_a_1(Alignment align, DataType dt) {
1611  switch (align.GetType()) {
1612    case k16BitAlign:
1613      if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1614      break;
1615    case k32BitAlign:
1616      if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1617      break;
1618    case kNoAlignment:
1619      SetEncodingValue(0x0);
1620      break;
1621    default:
1622      break;
1623  }
1624}
1625
1626class Align_a_2 : public EncodingValue {
1627 public:
1628  Align_a_2(Alignment align, DataType dt);
1629};
1630
1631Align_a_2::Align_a_2(Alignment align, DataType dt) {
1632  switch (align.GetType()) {
1633    case k16BitAlign:
1634      if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1635      break;
1636    case k32BitAlign:
1637      if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1638      break;
1639    case k64BitAlign:
1640      if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1641      break;
1642    case kNoAlignment:
1643      SetEncodingValue(0x0);
1644      break;
1645    default:
1646      break;
1647  }
1648}
1649
1650class Align_a_3 : public EncodingValue {
1651 public:
1652  Align_a_3(Alignment align, DataType dt);
1653};
1654
1655Align_a_3::Align_a_3(Alignment align, DataType dt) {
1656  switch (align.GetType()) {
1657    case k32BitAlign:
1658      if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1659      break;
1660    case k64BitAlign:
1661      if (dt.Is(Untyped16))
1662        SetEncodingValue(0x1);
1663      else if (dt.Is(Untyped32))
1664        SetEncodingValue(0x1);
1665      break;
1666    case k128BitAlign:
1667      if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1668      break;
1669    case kNoAlignment:
1670      SetEncodingValue(0x0);
1671      break;
1672    default:
1673      break;
1674  }
1675}
1676
1677class Align_align_1 : public EncodingValue {
1678 public:
1679  Align_align_1(Alignment align, const NeonRegisterList& nreglist);
1680};
1681
1682Align_align_1::Align_align_1(Alignment align,
1683                             const NeonRegisterList& nreglist) {
1684  switch (align.GetType()) {
1685    case k64BitAlign:
1686      SetEncodingValue(0x1);
1687      break;
1688    case k128BitAlign:
1689      if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1690        SetEncodingValue(0x2);
1691      break;
1692    case k256BitAlign:
1693      if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1694        SetEncodingValue(0x3);
1695      break;
1696    case kNoAlignment:
1697      SetEncodingValue(0x0);
1698      break;
1699    default:
1700      break;
1701  }
1702}
1703
1704class Align_align_2 : public EncodingValue {
1705 public:
1706  Align_align_2(Alignment align, const NeonRegisterList& nreglist);
1707};
1708
1709Align_align_2::Align_align_2(Alignment align,
1710                             const NeonRegisterList& nreglist) {
1711  switch (align.GetType()) {
1712    case k64BitAlign:
1713      SetEncodingValue(0x1);
1714      break;
1715    case k128BitAlign:
1716      SetEncodingValue(0x2);
1717      break;
1718    case k256BitAlign:
1719      if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1720      break;
1721    case kNoAlignment:
1722      SetEncodingValue(0x0);
1723      break;
1724    default:
1725      break;
1726  }
1727}
1728
1729class Align_align_3 : public EncodingValue {
1730 public:
1731  explicit Align_align_3(Alignment align);
1732};
1733
1734Align_align_3::Align_align_3(Alignment align) {
1735  switch (align.GetType()) {
1736    case k64BitAlign:
1737      SetEncodingValue(0x1);
1738      break;
1739    case kNoAlignment:
1740      SetEncodingValue(0x0);
1741      break;
1742    default:
1743      break;
1744  }
1745}
1746
1747class Align_align_4 : public EncodingValue {
1748 public:
1749  explicit Align_align_4(Alignment align);
1750};
1751
1752Align_align_4::Align_align_4(Alignment align) {
1753  switch (align.GetType()) {
1754    case k64BitAlign:
1755      SetEncodingValue(0x1);
1756      break;
1757    case k128BitAlign:
1758      SetEncodingValue(0x2);
1759      break;
1760    case k256BitAlign:
1761      SetEncodingValue(0x3);
1762      break;
1763    case kNoAlignment:
1764      SetEncodingValue(0x0);
1765      break;
1766    default:
1767      break;
1768  }
1769}
1770
1771class Align_align_5 : public EncodingValue {
1772 public:
1773  Align_align_5(Alignment align, const NeonRegisterList& nreglist);
1774};
1775
1776Align_align_5::Align_align_5(Alignment align,
1777                             const NeonRegisterList& nreglist) {
1778  switch (align.GetType()) {
1779    case k64BitAlign:
1780      SetEncodingValue(0x1);
1781      break;
1782    case k128BitAlign:
1783      if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1784        SetEncodingValue(0x2);
1785      break;
1786    case k256BitAlign:
1787      if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1788      break;
1789    case kNoAlignment:
1790      SetEncodingValue(0x0);
1791      break;
1792    default:
1793      break;
1794  }
1795}
1796
1797
1798void Assembler::adc(Condition cond,
1799                    EncodingSize size,
1800                    Register rd,
1801                    Register rn,
1802                    const Operand& operand) {
1803  VIXL_ASSERT(AllowAssembler());
1804  CheckIT(cond);
1805  if (operand.IsImmediate()) {
1806    uint32_t imm = operand.GetImmediate();
1807    if (IsUsingT32()) {
1808      ImmediateT32 immediate_t32(imm);
1809      // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
1810      if (!size.IsNarrow() && immediate_t32.IsValid() &&
1811          ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
1812        EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1813                   (immediate_t32.GetEncodingValue() & 0xff) |
1814                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
1815                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
1816        AdvanceIT();
1817        return;
1818      }
1819    } else {
1820      ImmediateA32 immediate_a32(imm);
1821      // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
1822      if (immediate_a32.IsValid() && cond.IsNotNever()) {
1823        EmitA32(0x02a00000U | (cond.GetCondition() << 28) |
1824                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
1825                immediate_a32.GetEncodingValue());
1826        return;
1827      }
1828    }
1829  }
1830  if (operand.IsImmediateShiftedRegister()) {
1831    Register rm = operand.GetBaseRegister();
1832    if (operand.IsPlainRegister()) {
1833      if (IsUsingT32()) {
1834        // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
1835        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1836            rm.IsLow()) {
1837          EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
1838          AdvanceIT();
1839          return;
1840        }
1841      }
1842    }
1843    Shift shift = operand.GetShift();
1844    uint32_t amount = operand.GetShiftAmount();
1845    if (IsUsingT32()) {
1846      // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
1847      if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
1848          ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
1849        uint32_t amount_ = amount % 32;
1850        EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1851                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
1852                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
1853        AdvanceIT();
1854        return;
1855      }
1856    } else {
1857      // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
1858      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
1859        uint32_t amount_ = amount % 32;
1860        EmitA32(0x00a00000U | (cond.GetCondition() << 28) |
1861                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1862                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
1863        return;
1864      }
1865    }
1866  }
1867  if (operand.IsRegisterShiftedRegister()) {
1868    Register rm = operand.GetBaseRegister();
1869    Shift shift = operand.GetShift();
1870    if (IsUsingA32()) {
1871      // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
1872      if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
1873                                 !operand.GetShiftRegister().IsPC()) ||
1874                                AllowUnpredictable())) {
1875        EmitA32(0x00a00010U | (cond.GetCondition() << 28) |
1876                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1877                (shift.GetType() << 5) |
1878                (operand.GetShiftRegister().GetCode() << 8));
1879        return;
1880      }
1881    }
1882  }
1883  Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand);
1884}
1885
1886void Assembler::adcs(Condition cond,
1887                     EncodingSize size,
1888                     Register rd,
1889                     Register rn,
1890                     const Operand& operand) {
1891  VIXL_ASSERT(AllowAssembler());
1892  CheckIT(cond);
1893  if (operand.IsImmediate()) {
1894    uint32_t imm = operand.GetImmediate();
1895    if (IsUsingT32()) {
1896      ImmediateT32 immediate_t32(imm);
1897      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
1898      if (!size.IsNarrow() && immediate_t32.IsValid() &&
1899          ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
1900        EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1901                   (immediate_t32.GetEncodingValue() & 0xff) |
1902                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
1903                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
1904        AdvanceIT();
1905        return;
1906      }
1907    } else {
1908      ImmediateA32 immediate_a32(imm);
1909      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
1910      if (immediate_a32.IsValid() && cond.IsNotNever()) {
1911        EmitA32(0x02b00000U | (cond.GetCondition() << 28) |
1912                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
1913                immediate_a32.GetEncodingValue());
1914        return;
1915      }
1916    }
1917  }
1918  if (operand.IsImmediateShiftedRegister()) {
1919    Register rm = operand.GetBaseRegister();
1920    if (operand.IsPlainRegister()) {
1921      if (IsUsingT32()) {
1922        // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
1923        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1924            rm.IsLow()) {
1925          EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
1926          AdvanceIT();
1927          return;
1928        }
1929      }
1930    }
1931    Shift shift = operand.GetShift();
1932    uint32_t amount = operand.GetShiftAmount();
1933    if (IsUsingT32()) {
1934      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
1935      if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
1936          ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
1937        uint32_t amount_ = amount % 32;
1938        EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1939                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
1940                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
1941        AdvanceIT();
1942        return;
1943      }
1944    } else {
1945      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
1946      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
1947        uint32_t amount_ = amount % 32;
1948        EmitA32(0x00b00000U | (cond.GetCondition() << 28) |
1949                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1950                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
1951        return;
1952      }
1953    }
1954  }
1955  if (operand.IsRegisterShiftedRegister()) {
1956    Register rm = operand.GetBaseRegister();
1957    Shift shift = operand.GetShift();
1958    if (IsUsingA32()) {
1959      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
1960      if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
1961                                 !operand.GetShiftRegister().IsPC()) ||
1962                                AllowUnpredictable())) {
1963        EmitA32(0x00b00010U | (cond.GetCondition() << 28) |
1964                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1965                (shift.GetType() << 5) |
1966                (operand.GetShiftRegister().GetCode() << 8));
1967        return;
1968      }
1969    }
1970  }
1971  Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand);
1972}
1973
1974void Assembler::add(Condition cond,
1975                    EncodingSize size,
1976                    Register rd,
1977                    Register rn,
1978                    const Operand& operand) {
1979  VIXL_ASSERT(AllowAssembler());
1980  CheckIT(cond);
1981  if (operand.IsImmediate()) {
1982    uint32_t imm = operand.GetImmediate();
1983    if (IsUsingT32()) {
1984      ImmediateT32 immediate_t32(imm);
1985      // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1
1986      if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) &&
1987          ((imm % 4) == 0)) {
1988        uint32_t imm_ = imm >> 2;
1989        EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_);
1990        AdvanceIT();
1991        return;
1992      }
1993      // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
1994      if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
1995          (imm <= 7)) {
1996        EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
1997        AdvanceIT();
1998        return;
1999      }
2000      // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
2001      if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2002          (imm <= 255)) {
2003        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2004        AdvanceIT();
2005        return;
2006      }
2007      // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1
2008      if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) &&
2009          ((imm % 4) == 0)) {
2010        uint32_t imm_ = imm >> 2;
2011        EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_);
2012        AdvanceIT();
2013        return;
2014      }
2015      // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2
2016      if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
2017          ((imm % 4) == 0)) {
2018        uint32_t imm_ = imm >> 2;
2019        EmitT32_16(0xb000 | imm_);
2020        AdvanceIT();
2021        return;
2022      }
2023      // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2024      if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
2025          (!rd.IsPC() || AllowUnpredictable())) {
2026        EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2027                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2028        AdvanceIT();
2029        return;
2030      }
2031      // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2032      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
2033          ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
2034        EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2035                   (immediate_t32.GetEncodingValue() & 0xff) |
2036                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2037                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2038        AdvanceIT();
2039        return;
2040      }
2041      // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2042      if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
2043          (!rd.IsPC() || AllowUnpredictable())) {
2044        EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2045                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2046        AdvanceIT();
2047        return;
2048      }
2049      // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2050      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
2051          (!rd.IsPC() || AllowUnpredictable())) {
2052        EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) |
2053                   (immediate_t32.GetEncodingValue() & 0xff) |
2054                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2055                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2056        AdvanceIT();
2057        return;
2058      }
2059      // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2060      if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
2061          (!rd.IsPC() || AllowUnpredictable())) {
2062        EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2063                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2064        AdvanceIT();
2065        return;
2066      }
2067    } else {
2068      ImmediateA32 immediate_a32(imm);
2069      // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1
2070      if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
2071        EmitA32(0x028f0000U | (cond.GetCondition() << 28) |
2072                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2073        return;
2074      }
2075      // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2076      if (immediate_a32.IsValid() && cond.IsNotNever() &&
2077          ((rn.GetCode() & 0xd) != 0xd)) {
2078        EmitA32(0x02800000U | (cond.GetCondition() << 28) |
2079                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2080                immediate_a32.GetEncodingValue());
2081        return;
2082      }
2083      // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2084      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2085        EmitA32(0x028d0000U | (cond.GetCondition() << 28) |
2086                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2087        return;
2088      }
2089    }
2090  }
2091  if (operand.IsImmediateShiftedRegister()) {
2092    Register rm = operand.GetBaseRegister();
2093    if (operand.IsPlainRegister()) {
2094      if (IsUsingT32()) {
2095        // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
2096        if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2097            rm.IsLow()) {
2098          EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2099                     (rm.GetCode() << 6));
2100          AdvanceIT();
2101          return;
2102        }
2103        // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2
2104        if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) &&
2105            (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
2106              (!rd.IsPC() || !rm.IsPC())) ||
2107             AllowUnpredictable())) {
2108          EmitT32_16(0x4400 | (rd.GetCode() & 0x7) |
2109                     ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
2110          AdvanceIT();
2111          return;
2112        }
2113        // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1
2114        if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) &&
2115            ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
2116             AllowUnpredictable())) {
2117          EmitT32_16(0x4468 | (rd.GetCode() & 0x7) |
2118                     ((rd.GetCode() & 0x8) << 4));
2119          AdvanceIT();
2120          return;
2121        }
2122        // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2
2123        if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) {
2124          EmitT32_16(0x4485 | (rm.GetCode() << 3));
2125          AdvanceIT();
2126          return;
2127        }
2128      }
2129    }
2130    Shift shift = operand.GetShift();
2131    uint32_t amount = operand.GetShiftAmount();
2132    if (IsUsingT32()) {
2133      // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2134      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
2135          ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2136        uint32_t amount_ = amount % 32;
2137        EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2138                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2139                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2140        AdvanceIT();
2141        return;
2142      }
2143      // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2144      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
2145          ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2146        uint32_t amount_ = amount % 32;
2147        EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2148                   (operand.GetTypeEncodingValue() << 4) |
2149                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2150        AdvanceIT();
2151        return;
2152      }
2153    } else {
2154      // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2155      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2156        uint32_t amount_ = amount % 32;
2157        EmitA32(0x00800000U | (cond.GetCondition() << 28) |
2158                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2159                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2160        return;
2161      }
2162      // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2163      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2164        uint32_t amount_ = amount % 32;
2165        EmitA32(0x008d0000U | (cond.GetCondition() << 28) |
2166                (rd.GetCode() << 12) | rm.GetCode() |
2167                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2168        return;
2169      }
2170    }
2171  }
2172  if (operand.IsRegisterShiftedRegister()) {
2173    Register rm = operand.GetBaseRegister();
2174    Shift shift = operand.GetShift();
2175    if (IsUsingA32()) {
2176      // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2177      if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
2178                                 !operand.GetShiftRegister().IsPC()) ||
2179                                AllowUnpredictable())) {
2180        EmitA32(0x00800010U | (cond.GetCondition() << 28) |
2181                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2182                (shift.GetType() << 5) |
2183                (operand.GetShiftRegister().GetCode() << 8));
2184        return;
2185      }
2186    }
2187  }
2188  Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand);
2189}
2190
2191void Assembler::add(Condition cond, Register rd, const Operand& operand) {
2192  VIXL_ASSERT(AllowAssembler());
2193  CheckIT(cond);
2194  if (operand.IsImmediate()) {
2195    uint32_t imm = operand.GetImmediate();
2196    if (IsUsingT32()) {
2197      // ADD<c>{<q>} <Rdn>, #<imm8> ; T2
2198      if (InITBlock() && rd.IsLow() && (imm <= 255)) {
2199        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2200        AdvanceIT();
2201        return;
2202      }
2203    }
2204  }
2205  if (operand.IsPlainRegister()) {
2206    Register rm = operand.GetBaseRegister();
2207    if (IsUsingT32()) {
2208      // ADD<c>{<q>} <Rdn>, <Rm> ; T2
2209      if (InITBlock() && !rm.Is(sp) &&
2210          (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
2211            (!rd.IsPC() || !rm.IsPC())) ||
2212           AllowUnpredictable())) {
2213        EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) |
2214                   (rm.GetCode() << 3));
2215        AdvanceIT();
2216        return;
2217      }
2218    }
2219  }
2220  Delegate(kAdd, &Assembler::add, cond, rd, operand);
2221}
2222
2223void Assembler::adds(Condition cond,
2224                     EncodingSize size,
2225                     Register rd,
2226                     Register rn,
2227                     const Operand& operand) {
2228  VIXL_ASSERT(AllowAssembler());
2229  CheckIT(cond);
2230  if (operand.IsImmediate()) {
2231    uint32_t imm = operand.GetImmediate();
2232    if (IsUsingT32()) {
2233      ImmediateT32 immediate_t32(imm);
2234      // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1
2235      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2236          (imm <= 7)) {
2237        EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
2238        AdvanceIT();
2239        return;
2240      }
2241      // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
2242      if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2243          (imm <= 255)) {
2244        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2245        AdvanceIT();
2246        return;
2247      }
2248      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2249      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
2250          !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) {
2251        EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2252                   (immediate_t32.GetEncodingValue() & 0xff) |
2253                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2254                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2255        AdvanceIT();
2256        return;
2257      }
2258      // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2259      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
2260          !rd.Is(pc)) {
2261        EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) |
2262                   (immediate_t32.GetEncodingValue() & 0xff) |
2263                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2264                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2265        AdvanceIT();
2266        return;
2267      }
2268    } else {
2269      ImmediateA32 immediate_a32(imm);
2270      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2271      if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
2272        EmitA32(0x02900000U | (cond.GetCondition() << 28) |
2273                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2274                immediate_a32.GetEncodingValue());
2275        return;
2276      }
2277      // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2278      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2279        EmitA32(0x029d0000U | (cond.GetCondition() << 28) |
2280                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2281        return;
2282      }
2283    }
2284  }
2285  if (operand.IsImmediateShiftedRegister()) {
2286    Register rm = operand.GetBaseRegister();
2287    if (operand.IsPlainRegister()) {
2288      if (IsUsingT32()) {
2289        // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
2290        if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2291            rm.IsLow()) {
2292          EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2293                     (rm.GetCode() << 6));
2294          AdvanceIT();
2295          return;
2296        }
2297      }
2298    }
2299    Shift shift = operand.GetShift();
2300    uint32_t amount = operand.GetShiftAmount();
2301    if (IsUsingT32()) {
2302      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2303      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
2304          !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2305        uint32_t amount_ = amount % 32;
2306        EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2307                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2308                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2309        AdvanceIT();
2310        return;
2311      }
2312      // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2313      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
2314          !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) {
2315        uint32_t amount_ = amount % 32;
2316        EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2317                   (operand.GetTypeEncodingValue() << 4) |
2318                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2319        AdvanceIT();
2320        return;
2321      }
2322    } else {
2323      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2324      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2325        uint32_t amount_ = amount % 32;
2326        EmitA32(0x00900000U | (cond.GetCondition() << 28) |
2327                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2328                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2329        return;
2330      }
2331      // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2332      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2333        uint32_t amount_ = amount % 32;
2334        EmitA32(0x009d0000U | (cond.GetCondition() << 28) |
2335                (rd.GetCode() << 12) | rm.GetCode() |
2336                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2337        return;
2338      }
2339    }
2340  }
2341  if (operand.IsRegisterShiftedRegister()) {
2342    Register rm = operand.GetBaseRegister();
2343    Shift shift = operand.GetShift();
2344    if (IsUsingA32()) {
2345      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2346      if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
2347                                 !operand.GetShiftRegister().IsPC()) ||
2348                                AllowUnpredictable())) {
2349        EmitA32(0x00900010U | (cond.GetCondition() << 28) |
2350                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2351                (shift.GetType() << 5) |
2352                (operand.GetShiftRegister().GetCode() << 8));
2353        return;
2354      }
2355    }
2356  }
2357  Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand);
2358}
2359
2360void Assembler::adds(Register rd, const Operand& operand) {
2361  VIXL_ASSERT(AllowAssembler());
2362  CheckIT(al);
2363  if (operand.IsImmediate()) {
2364    uint32_t imm = operand.GetImmediate();
2365    if (IsUsingT32()) {
2366      // ADDS{<q>} <Rdn>, #<imm8> ; T2
2367      if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
2368        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2369        AdvanceIT();
2370        return;
2371      }
2372    }
2373  }
2374  Delegate(kAdds, &Assembler::adds, rd, operand);
2375}
2376
2377void Assembler::addw(Condition cond,
2378                     Register rd,
2379                     Register rn,
2380                     const Operand& operand) {
2381  VIXL_ASSERT(AllowAssembler());
2382  CheckIT(cond);
2383  if (operand.IsImmediate()) {
2384    uint32_t imm = operand.GetImmediate();
2385    if (IsUsingT32()) {
2386      // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2387      if (rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2388        EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2389                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2390        AdvanceIT();
2391        return;
2392      }
2393      // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2394      if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
2395          (!rd.IsPC() || AllowUnpredictable())) {
2396        EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2397                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2398        AdvanceIT();
2399        return;
2400      }
2401      // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2402      if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2403        EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2404                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2405        AdvanceIT();
2406        return;
2407      }
2408    }
2409  }
2410  Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand);
2411}
2412
2413void Assembler::adr(Condition cond,
2414                    EncodingSize size,
2415                    Register rd,
2416                    Label* label) {
2417  VIXL_ASSERT(AllowAssembler());
2418  CheckIT(cond);
2419  Label::Offset offset =
2420      label->IsBound()
2421          ? label->GetLocation() -
2422                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
2423          : 0;
2424  if (IsUsingT32()) {
2425    int32_t neg_offset = -offset;
2426    // ADR{<c>}{<q>} <Rd>, <label> ; T1
2427    if (!size.IsWide() && rd.IsLow() &&
2428        ((label->IsBound() && (offset >= 0) && (offset <= 1020) &&
2429          ((offset & 0x3) == 0)) ||
2430         (!label->IsBound() && size.IsNarrow()))) {
2431      static class EmitOp : public Label::LabelEmitOperator {
2432       public:
2433        EmitOp() : Label::LabelEmitOperator(0, 1020) {}
2434        virtual uint32_t Encode(uint32_t instr,
2435                                Label::Offset pc,
2436                                const Label* label) const VIXL_OVERRIDE {
2437          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2438          VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
2439                      ((offset & 0x3) == 0));
2440          const int32_t target = offset >> 2;
2441          return instr | (target & 0xff);
2442        }
2443      } immop;
2444      EmitT32_16(Link(0xa000 | (rd.GetCode() << 8), label, immop));
2445      AdvanceIT();
2446      return;
2447    }
2448    // ADR{<c>}{<q>} <Rd>, <label> ; T2
2449    if (!size.IsNarrow() && label->IsBound() && (neg_offset > 0) &&
2450        (neg_offset <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2451      EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) |
2452                 ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15));
2453      AdvanceIT();
2454      return;
2455    }
2456    // ADR{<c>}{<q>} <Rd>, <label> ; T3
2457    if (!size.IsNarrow() &&
2458        (!label->IsBound() || ((offset >= 0) && (offset <= 4095))) &&
2459        (!rd.IsPC() || AllowUnpredictable())) {
2460      static class EmitOp : public Label::LabelEmitOperator {
2461       public:
2462        EmitOp() : Label::LabelEmitOperator(0, 4095) {}
2463        virtual uint32_t Encode(uint32_t instr,
2464                                Label::Offset pc,
2465                                const Label* label) const VIXL_OVERRIDE {
2466          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2467          int32_t target;
2468          if ((offset >= 0) && (offset <= 4095) && !label->IsMinusZero()) {
2469            target = offset;
2470          } else {
2471            target = -offset;
2472            VIXL_ASSERT((target >= 0) && (target <= 4095));
2473            // Emit the T2 encoding.
2474            instr |= 0x00a00000;
2475          }
2476          return instr | (target & 0xff) | ((target & 0x700) << 4) |
2477                 ((target & 0x800) << 15);
2478        }
2479      } immop;
2480      EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8), label, immop));
2481      AdvanceIT();
2482      return;
2483    }
2484  } else {
2485    ImmediateA32 positive_immediate_a32(offset);
2486    ImmediateA32 negative_immediate_a32(-offset);
2487    // ADR{<c>}{<q>} <Rd>, <label> ; A1
2488    if ((!label->IsBound() || positive_immediate_a32.IsValid()) &&
2489        cond.IsNotNever()) {
2490      static class EmitOp : public Label::LabelEmitOperator {
2491       public:
2492        EmitOp() : Label::LabelEmitOperator(0, 255) {}
2493        virtual uint32_t Encode(uint32_t instr,
2494                                Label::Offset pc,
2495                                const Label* label) const VIXL_OVERRIDE {
2496          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2497          int32_t target;
2498          ImmediateA32 positive_immediate_a32(offset);
2499          if (positive_immediate_a32.IsValid()) {
2500            target = positive_immediate_a32.GetEncodingValue();
2501          } else {
2502            ImmediateA32 negative_immediate_a32(-offset);
2503            VIXL_ASSERT(negative_immediate_a32.IsValid());
2504            // Emit the A2 encoding.
2505            target = negative_immediate_a32.GetEncodingValue();
2506            instr = (instr & ~0x00f00000) | 0x00400000;
2507          }
2508          return instr | (target & 0xfff);
2509        }
2510      } immop;
2511      EmitA32(
2512          Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12),
2513               label,
2514               immop));
2515      return;
2516    }
2517    // ADR{<c>}{<q>} <Rd>, <label> ; A2
2518    if (label->IsBound() && negative_immediate_a32.IsValid() &&
2519        cond.IsNotNever()) {
2520      EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
2521              negative_immediate_a32.GetEncodingValue());
2522      return;
2523    }
2524  }
2525  Delegate(kAdr, &Assembler::adr, cond, size, rd, label);
2526}
2527
2528void Assembler::and_(Condition cond,
2529                     EncodingSize size,
2530                     Register rd,
2531                     Register rn,
2532                     const Operand& operand) {
2533  VIXL_ASSERT(AllowAssembler());
2534  CheckIT(cond);
2535  if (operand.IsImmediate()) {
2536    uint32_t imm = operand.GetImmediate();
2537    if (IsUsingT32()) {
2538      ImmediateT32 immediate_t32(imm);
2539      // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2540      if (!size.IsNarrow() && immediate_t32.IsValid()) {
2541        EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2542                   (immediate_t32.GetEncodingValue() & 0xff) |
2543                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2544                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2545        AdvanceIT();
2546        return;
2547      }
2548    } else {
2549      ImmediateA32 immediate_a32(imm);
2550      // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2551      if (immediate_a32.IsValid() && cond.IsNotNever()) {
2552        EmitA32(0x02000000U | (cond.GetCondition() << 28) |
2553                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2554                immediate_a32.GetEncodingValue());
2555        return;
2556      }
2557    }
2558  }
2559  if (operand.IsImmediateShiftedRegister()) {
2560    Register rm = operand.GetBaseRegister();
2561    if (operand.IsPlainRegister()) {
2562      if (IsUsingT32()) {
2563        // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2564        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2565            rm.IsLow()) {
2566          EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2567          AdvanceIT();
2568          return;
2569        }
2570      }
2571    }
2572    Shift shift = operand.GetShift();
2573    uint32_t amount = operand.GetShiftAmount();
2574    if (IsUsingT32()) {
2575      // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2576      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
2577        uint32_t amount_ = amount % 32;
2578        EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2579                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2580                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2581        AdvanceIT();
2582        return;
2583      }
2584    } else {
2585      // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2586      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2587        uint32_t amount_ = amount % 32;
2588        EmitA32(0x00000000U | (cond.GetCondition() << 28) |
2589                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2590                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2591        return;
2592      }
2593    }
2594  }
2595  if (operand.IsRegisterShiftedRegister()) {
2596    Register rm = operand.GetBaseRegister();
2597    Shift shift = operand.GetShift();
2598    if (IsUsingA32()) {
2599      // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2600      if (cond.IsNotNever()) {
2601        EmitA32(0x00000010U | (cond.GetCondition() << 28) |
2602                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2603                (shift.GetType() << 5) |
2604                (operand.GetShiftRegister().GetCode() << 8));
2605        return;
2606      }
2607    }
2608  }
2609  Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand);
2610}
2611
2612void Assembler::ands(Condition cond,
2613                     EncodingSize size,
2614                     Register rd,
2615                     Register rn,
2616                     const Operand& operand) {
2617  VIXL_ASSERT(AllowAssembler());
2618  CheckIT(cond);
2619  if (operand.IsImmediate()) {
2620    uint32_t imm = operand.GetImmediate();
2621    if (IsUsingT32()) {
2622      ImmediateT32 immediate_t32(imm);
2623      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2624      if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) {
2625        EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2626                   (immediate_t32.GetEncodingValue() & 0xff) |
2627                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2628                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2629        AdvanceIT();
2630        return;
2631      }
2632    } else {
2633      ImmediateA32 immediate_a32(imm);
2634      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2635      if (immediate_a32.IsValid() && cond.IsNotNever()) {
2636        EmitA32(0x02100000U | (cond.GetCondition() << 28) |
2637                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2638                immediate_a32.GetEncodingValue());
2639        return;
2640      }
2641    }
2642  }
2643  if (operand.IsImmediateShiftedRegister()) {
2644    Register rm = operand.GetBaseRegister();
2645    if (operand.IsPlainRegister()) {
2646      if (IsUsingT32()) {
2647        // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2648        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2649            rm.IsLow()) {
2650          EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2651          AdvanceIT();
2652          return;
2653        }
2654      }
2655    }
2656    Shift shift = operand.GetShift();
2657    uint32_t amount = operand.GetShiftAmount();
2658    if (IsUsingT32()) {
2659      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2660      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) {
2661        uint32_t amount_ = amount % 32;
2662        EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2663                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2664                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2665        AdvanceIT();
2666        return;
2667      }
2668    } else {
2669      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2670      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2671        uint32_t amount_ = amount % 32;
2672        EmitA32(0x00100000U | (cond.GetCondition() << 28) |
2673                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2674                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2675        return;
2676      }
2677    }
2678  }
2679  if (operand.IsRegisterShiftedRegister()) {
2680    Register rm = operand.GetBaseRegister();
2681    Shift shift = operand.GetShift();
2682    if (IsUsingA32()) {
2683      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2684      if (cond.IsNotNever()) {
2685        EmitA32(0x00100010U | (cond.GetCondition() << 28) |
2686                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2687                (shift.GetType() << 5) |
2688                (operand.GetShiftRegister().GetCode() << 8));
2689        return;
2690      }
2691    }
2692  }
2693  Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand);
2694}
2695
2696void Assembler::asr(Condition cond,
2697                    EncodingSize size,
2698                    Register rd,
2699                    Register rm,
2700                    const Operand& operand) {
2701  VIXL_ASSERT(AllowAssembler());
2702  CheckIT(cond);
2703  if (operand.IsImmediate()) {
2704    uint32_t imm = operand.GetImmediate();
2705    if (IsUsingT32()) {
2706      // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2707      if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2708          (imm >= 1) && (imm <= 32)) {
2709        uint32_t amount_ = imm % 32;
2710        EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2711                   (amount_ << 6));
2712        AdvanceIT();
2713        return;
2714      }
2715      // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2716      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
2717        uint32_t amount_ = imm % 32;
2718        EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2719                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2720        AdvanceIT();
2721        return;
2722      }
2723    } else {
2724      // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2725      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2726        uint32_t amount_ = imm % 32;
2727        EmitA32(0x01a00040U | (cond.GetCondition() << 28) |
2728                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2729        return;
2730      }
2731    }
2732  }
2733  if (operand.IsPlainRegister()) {
2734    Register rs = operand.GetBaseRegister();
2735    if (IsUsingT32()) {
2736      // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2737      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2738          rs.IsLow()) {
2739        EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2740        AdvanceIT();
2741        return;
2742      }
2743      // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2744      if (!size.IsNarrow()) {
2745        EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2746                   rs.GetCode());
2747        AdvanceIT();
2748        return;
2749      }
2750    } else {
2751      // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
2752      if (cond.IsNotNever()) {
2753        EmitA32(0x01a00050U | (cond.GetCondition() << 28) |
2754                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
2755        return;
2756      }
2757    }
2758  }
2759  Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand);
2760}
2761
2762void Assembler::asrs(Condition cond,
2763                     EncodingSize size,
2764                     Register rd,
2765                     Register rm,
2766                     const Operand& operand) {
2767  VIXL_ASSERT(AllowAssembler());
2768  CheckIT(cond);
2769  if (operand.IsImmediate()) {
2770    uint32_t imm = operand.GetImmediate();
2771    if (IsUsingT32()) {
2772      // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2773      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2774          (imm >= 1) && (imm <= 32)) {
2775        uint32_t amount_ = imm % 32;
2776        EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2777                   (amount_ << 6));
2778        AdvanceIT();
2779        return;
2780      }
2781      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2782      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
2783        uint32_t amount_ = imm % 32;
2784        EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2785                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2786        AdvanceIT();
2787        return;
2788      }
2789    } else {
2790      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2791      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2792        uint32_t amount_ = imm % 32;
2793        EmitA32(0x01b00040U | (cond.GetCondition() << 28) |
2794                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2795        return;
2796      }
2797    }
2798  }
2799  if (operand.IsPlainRegister()) {
2800    Register rs = operand.GetBaseRegister();
2801    if (IsUsingT32()) {
2802      // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2803      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2804          rs.IsLow()) {
2805        EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2806        AdvanceIT();
2807        return;
2808      }
2809      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2810      if (!size.IsNarrow()) {
2811        EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2812                   rs.GetCode());
2813        AdvanceIT();
2814        return;
2815      }
2816    } else {
2817      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
2818      if (cond.IsNotNever()) {
2819        EmitA32(0x01b00050U | (cond.GetCondition() << 28) |
2820                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
2821        return;
2822      }
2823    }
2824  }
2825  Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand);
2826}
2827
2828void Assembler::b(Condition cond, EncodingSize size, Label* label) {
2829  VIXL_ASSERT(AllowAssembler());
2830  Label::Offset offset =
2831      label->IsBound()
2832          ? label->GetLocation() -
2833                (GetCursorOffset() + GetArchitectureStatePCOffset())
2834          : 0;
2835  if (IsUsingT32()) {
2836    // B<c>{<q>} <label> ; T1
2837    if (OutsideITBlock() && !size.IsWide() &&
2838        ((label->IsBound() && (offset >= -256) && (offset <= 254) &&
2839          ((offset & 0x1) == 0)) ||
2840         (!label->IsBound() && size.IsNarrow())) &&
2841        !cond.Is(al) && cond.IsNotNever()) {
2842      static class EmitOp : public Label::LabelEmitOperator {
2843       public:
2844        EmitOp() : Label::LabelEmitOperator(-256, 254) {}
2845        virtual uint32_t Encode(uint32_t instr,
2846                                Label::Offset pc,
2847                                const Label* label) const VIXL_OVERRIDE {
2848          Label::Offset offset = label->GetLocation() - pc;
2849          VIXL_ASSERT((offset >= -256) && (offset <= 254) &&
2850                      ((offset & 0x1) == 0));
2851          const int32_t target = offset >> 1;
2852          return instr | (target & 0xff);
2853        }
2854      } immop;
2855      EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8), label, immop));
2856      AdvanceIT();
2857      return;
2858    }
2859    // B{<c>}{<q>} <label> ; T2
2860    if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() &&
2861        ((label->IsBound() && (offset >= -2048) && (offset <= 2046) &&
2862          ((offset & 0x1) == 0)) ||
2863         (!label->IsBound() && size.IsNarrow()))) {
2864      CheckIT(cond);
2865      static class EmitOp : public Label::LabelEmitOperator {
2866       public:
2867        EmitOp() : Label::LabelEmitOperator(-2048, 2046) {}
2868        virtual uint32_t Encode(uint32_t instr,
2869                                Label::Offset pc,
2870                                const Label* label) const VIXL_OVERRIDE {
2871          Label::Offset offset = label->GetLocation() - pc;
2872          VIXL_ASSERT((offset >= -2048) && (offset <= 2046) &&
2873                      ((offset & 0x1) == 0));
2874          const int32_t target = offset >> 1;
2875          return instr | (target & 0x7ff);
2876        }
2877      } immop;
2878      EmitT32_16(Link(0xe000, label, immop));
2879      AdvanceIT();
2880      return;
2881    }
2882    // B<c>{<q>} <label> ; T3
2883    if (OutsideITBlock() && !size.IsNarrow() &&
2884        ((label->IsBound() && (offset >= -1048576) && (offset <= 1048574) &&
2885          ((offset & 0x1) == 0)) ||
2886         !label->IsBound()) &&
2887        !cond.Is(al) && cond.IsNotNever()) {
2888      static class EmitOp : public Label::LabelEmitOperator {
2889       public:
2890        EmitOp() : Label::LabelEmitOperator(-1048576, 1048574) {}
2891        virtual uint32_t Encode(uint32_t instr,
2892                                Label::Offset pc,
2893                                const Label* label) const VIXL_OVERRIDE {
2894          Label::Offset offset = label->GetLocation() - pc;
2895          VIXL_ASSERT((offset >= -1048576) && (offset <= 1048574) &&
2896                      ((offset & 0x1) == 0));
2897          const int32_t target = offset >> 1;
2898          return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) |
2899                 ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) |
2900                 ((target & 0x80000) << 7);
2901        }
2902      } immop;
2903      EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22), label, immop));
2904      AdvanceIT();
2905      return;
2906    }
2907    // B{<c>}{<q>} <label> ; T4
2908    if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() &&
2909        ((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) &&
2910          ((offset & 0x1) == 0)) ||
2911         !label->IsBound())) {
2912      CheckIT(cond);
2913      static class EmitOp : public Label::LabelEmitOperator {
2914       public:
2915        EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {}
2916        virtual uint32_t Encode(uint32_t instr,
2917                                Label::Offset pc,
2918                                const Label* label) const VIXL_OVERRIDE {
2919          Label::Offset offset = label->GetLocation() - pc;
2920          VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
2921                      ((offset & 0x1) == 0));
2922          int32_t target = offset >> 1;
2923          uint32_t S = target & (1 << 23);
2924          target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
2925          return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
2926                 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
2927                 ((target & 0x800000) << 3);
2928        }
2929      } immop;
2930      EmitT32_32(Link(0xf0009000U, label, immop));
2931      AdvanceIT();
2932      return;
2933    }
2934  } else {
2935    // B{<c>}{<q>} <label> ; A1
2936    if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) &&
2937          ((offset & 0x3) == 0)) ||
2938         !label->IsBound()) &&
2939        cond.IsNotNever()) {
2940      static class EmitOp : public Label::LabelEmitOperator {
2941       public:
2942        EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {}
2943        virtual uint32_t Encode(uint32_t instr,
2944                                Label::Offset pc,
2945                                const Label* label) const VIXL_OVERRIDE {
2946          Label::Offset offset = label->GetLocation() - pc;
2947          VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
2948                      ((offset & 0x3) == 0));
2949          const int32_t target = offset >> 2;
2950          return instr | (target & 0xffffff);
2951        }
2952      } immop;
2953      EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28), label, immop));
2954      return;
2955    }
2956  }
2957  Delegate(kB, &Assembler::b, cond, size, label);
2958}
2959
2960void Assembler::bfc(Condition cond,
2961                    Register rd,
2962                    uint32_t lsb,
2963                    const Operand& operand) {
2964  VIXL_ASSERT(AllowAssembler());
2965  CheckIT(cond);
2966  if (operand.IsImmediate()) {
2967    uint32_t width = operand.GetImmediate();
2968    if (IsUsingT32()) {
2969      // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1
2970      if ((lsb <= 31) &&
2971          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2972        uint32_t msb = lsb + width - 1;
2973        EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) |
2974                   ((lsb & 0x1c) << 10) | msb);
2975        AdvanceIT();
2976        return;
2977      }
2978    } else {
2979      // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1
2980      if ((lsb <= 31) && cond.IsNotNever() &&
2981          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2982        uint32_t msb = lsb + width - 1;
2983        EmitA32(0x07c0001fU | (cond.GetCondition() << 28) |
2984                (rd.GetCode() << 12) | (lsb << 7) | (msb << 16));
2985        return;
2986      }
2987    }
2988  }
2989  Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, operand);
2990}
2991
2992void Assembler::bfi(Condition cond,
2993                    Register rd,
2994                    Register rn,
2995                    uint32_t lsb,
2996                    const Operand& operand) {
2997  VIXL_ASSERT(AllowAssembler());
2998  CheckIT(cond);
2999  if (operand.IsImmediate()) {
3000    uint32_t width = operand.GetImmediate();
3001    if (IsUsingT32()) {
3002      // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
3003      if ((lsb <= 31) && !rn.Is(pc) &&
3004          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
3005        uint32_t msb = lsb + width - 1;
3006        EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3007                   ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb);
3008        AdvanceIT();
3009        return;
3010      }
3011    } else {
3012      // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
3013      if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) &&
3014          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
3015        uint32_t msb = lsb + width - 1;
3016        EmitA32(0x07c00010U | (cond.GetCondition() << 28) |
3017                (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) | (msb << 16));
3018        return;
3019      }
3020    }
3021  }
3022  Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, operand);
3023}
3024
3025void Assembler::bic(Condition cond,
3026                    EncodingSize size,
3027                    Register rd,
3028                    Register rn,
3029                    const Operand& operand) {
3030  VIXL_ASSERT(AllowAssembler());
3031  CheckIT(cond);
3032  if (operand.IsImmediate()) {
3033    uint32_t imm = operand.GetImmediate();
3034    if (IsUsingT32()) {
3035      ImmediateT32 immediate_t32(imm);
3036      // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3037      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3038        EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3039                   (immediate_t32.GetEncodingValue() & 0xff) |
3040                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3041                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3042        AdvanceIT();
3043        return;
3044      }
3045    } else {
3046      ImmediateA32 immediate_a32(imm);
3047      // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3048      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3049        EmitA32(0x03c00000U | (cond.GetCondition() << 28) |
3050                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3051                immediate_a32.GetEncodingValue());
3052        return;
3053      }
3054    }
3055  }
3056  if (operand.IsImmediateShiftedRegister()) {
3057    Register rm = operand.GetBaseRegister();
3058    if (operand.IsPlainRegister()) {
3059      if (IsUsingT32()) {
3060        // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3061        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3062            rm.IsLow()) {
3063          EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3064          AdvanceIT();
3065          return;
3066        }
3067      }
3068    }
3069    Shift shift = operand.GetShift();
3070    uint32_t amount = operand.GetShiftAmount();
3071    if (IsUsingT32()) {
3072      // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3073      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3074        uint32_t amount_ = amount % 32;
3075        EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3076                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3077                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3078        AdvanceIT();
3079        return;
3080      }
3081    } else {
3082      // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3083      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3084        uint32_t amount_ = amount % 32;
3085        EmitA32(0x01c00000U | (cond.GetCondition() << 28) |
3086                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3087                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3088        return;
3089      }
3090    }
3091  }
3092  if (operand.IsRegisterShiftedRegister()) {
3093    Register rm = operand.GetBaseRegister();
3094    Shift shift = operand.GetShift();
3095    if (IsUsingA32()) {
3096      // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3097      if (cond.IsNotNever()) {
3098        EmitA32(0x01c00010U | (cond.GetCondition() << 28) |
3099                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3100                (shift.GetType() << 5) |
3101                (operand.GetShiftRegister().GetCode() << 8));
3102        return;
3103      }
3104    }
3105  }
3106  Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand);
3107}
3108
3109void Assembler::bics(Condition cond,
3110                     EncodingSize size,
3111                     Register rd,
3112                     Register rn,
3113                     const Operand& operand) {
3114  VIXL_ASSERT(AllowAssembler());
3115  CheckIT(cond);
3116  if (operand.IsImmediate()) {
3117    uint32_t imm = operand.GetImmediate();
3118    if (IsUsingT32()) {
3119      ImmediateT32 immediate_t32(imm);
3120      // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3121      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3122        EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3123                   (immediate_t32.GetEncodingValue() & 0xff) |
3124                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3125                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3126        AdvanceIT();
3127        return;
3128      }
3129    } else {
3130      ImmediateA32 immediate_a32(imm);
3131      // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3132      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3133        EmitA32(0x03d00000U | (cond.GetCondition() << 28) |
3134                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3135                immediate_a32.GetEncodingValue());
3136        return;
3137      }
3138    }
3139  }
3140  if (operand.IsImmediateShiftedRegister()) {
3141    Register rm = operand.GetBaseRegister();
3142    if (operand.IsPlainRegister()) {
3143      if (IsUsingT32()) {
3144        // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3145        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3146            rm.IsLow()) {
3147          EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3148          AdvanceIT();
3149          return;
3150        }
3151      }
3152    }
3153    Shift shift = operand.GetShift();
3154    uint32_t amount = operand.GetShiftAmount();
3155    if (IsUsingT32()) {
3156      // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3157      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3158        uint32_t amount_ = amount % 32;
3159        EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3160                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3161                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3162        AdvanceIT();
3163        return;
3164      }
3165    } else {
3166      // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3167      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3168        uint32_t amount_ = amount % 32;
3169        EmitA32(0x01d00000U | (cond.GetCondition() << 28) |
3170                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3171                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3172        return;
3173      }
3174    }
3175  }
3176  if (operand.IsRegisterShiftedRegister()) {
3177    Register rm = operand.GetBaseRegister();
3178    Shift shift = operand.GetShift();
3179    if (IsUsingA32()) {
3180      // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3181      if (cond.IsNotNever()) {
3182        EmitA32(0x01d00010U | (cond.GetCondition() << 28) |
3183                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3184                (shift.GetType() << 5) |
3185                (operand.GetShiftRegister().GetCode() << 8));
3186        return;
3187      }
3188    }
3189  }
3190  Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand);
3191}
3192
3193void Assembler::bkpt(Condition cond, uint32_t imm) {
3194  VIXL_ASSERT(AllowAssembler());
3195  CheckIT(cond);
3196  if (IsUsingT32()) {
3197    // BKPT{<q>} {#}<imm> ; T1
3198    if ((imm <= 255)) {
3199      EmitT32_16(0xbe00 | imm);
3200      AdvanceIT();
3201      return;
3202    }
3203  } else {
3204    // BKPT{<q>} {#}<imm> ; A1
3205    if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
3206      EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) |
3207              ((imm & 0xfff0) << 4));
3208      return;
3209    }
3210  }
3211  Delegate(kBkpt, &Assembler::bkpt, cond, imm);
3212}
3213
3214void Assembler::bl(Condition cond, Label* label) {
3215  VIXL_ASSERT(AllowAssembler());
3216  CheckIT(cond);
3217  Label::Offset offset =
3218      label->IsBound()
3219          ? label->GetLocation() -
3220                (GetCursorOffset() + GetArchitectureStatePCOffset())
3221          : 0;
3222  if (IsUsingT32()) {
3223    // BL{<c>}{<q>} <label> ; T1
3224    if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) &&
3225          ((offset & 0x1) == 0)) ||
3226         !label->IsBound())) {
3227      static class EmitOp : public Label::LabelEmitOperator {
3228       public:
3229        EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {}
3230        virtual uint32_t Encode(uint32_t instr,
3231                                Label::Offset pc,
3232                                const Label* label) const VIXL_OVERRIDE {
3233          Label::Offset offset = label->GetLocation() - pc;
3234          VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
3235                      ((offset & 0x1) == 0));
3236          int32_t target = offset >> 1;
3237          uint32_t S = target & (1 << 23);
3238          target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
3239          return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
3240                 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
3241                 ((target & 0x800000) << 3);
3242        }
3243      } immop;
3244      EmitT32_32(Link(0xf000d000U, label, immop));
3245      AdvanceIT();
3246      return;
3247    }
3248  } else {
3249    // BL{<c>}{<q>} <label> ; A1
3250    if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) &&
3251          ((offset & 0x3) == 0)) ||
3252         !label->IsBound()) &&
3253        cond.IsNotNever()) {
3254      static class EmitOp : public Label::LabelEmitOperator {
3255       public:
3256        EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {}
3257        virtual uint32_t Encode(uint32_t instr,
3258                                Label::Offset pc,
3259                                const Label* label) const VIXL_OVERRIDE {
3260          Label::Offset offset = label->GetLocation() - pc;
3261          VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
3262                      ((offset & 0x3) == 0));
3263          const int32_t target = offset >> 2;
3264          return instr | (target & 0xffffff);
3265        }
3266      } immop;
3267      EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28), label, immop));
3268      return;
3269    }
3270  }
3271  Delegate(kBl, &Assembler::bl, cond, label);
3272}
3273
3274void Assembler::blx(Condition cond, Label* label) {
3275  VIXL_ASSERT(AllowAssembler());
3276  CheckIT(cond);
3277  Label::Offset offset =
3278      label->IsBound()
3279          ? label->GetLocation() -
3280                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
3281          : 0;
3282  if (IsUsingT32()) {
3283    // BLX{<c>}{<q>} <label> ; T2
3284    if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777212) &&
3285          ((offset & 0x3) == 0)) ||
3286         !label->IsBound())) {
3287      static class EmitOp : public Label::LabelEmitOperator {
3288       public:
3289        EmitOp() : Label::LabelEmitOperator(-16777216, 16777212) {}
3290        virtual uint32_t Encode(uint32_t instr,
3291                                Label::Offset pc,
3292                                const Label* label) const VIXL_OVERRIDE {
3293          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
3294          VIXL_ASSERT((offset >= -16777216) && (offset <= 16777212) &&
3295                      ((offset & 0x3) == 0));
3296          int32_t target = offset >> 2;
3297          uint32_t S = target & (1 << 22);
3298          target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20);
3299          return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) |
3300                 ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) |
3301                 ((target & 0x400000) << 4);
3302        }
3303      } immop;
3304      EmitT32_32(Link(0xf000c000U, label, immop));
3305      AdvanceIT();
3306      return;
3307    }
3308  } else {
3309    // BLX{<c>}{<q>} <label> ; A2
3310    if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554430) &&
3311          ((offset & 0x1) == 0)) ||
3312         !label->IsBound())) {
3313      if (cond.Is(al) || AllowStronglyDiscouraged()) {
3314        static class EmitOp : public Label::LabelEmitOperator {
3315         public:
3316          EmitOp() : Label::LabelEmitOperator(-33554432, 33554430) {}
3317          virtual uint32_t Encode(uint32_t instr,
3318                                  Label::Offset pc,
3319                                  const Label* label) const VIXL_OVERRIDE {
3320            Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
3321            VIXL_ASSERT((offset >= -33554432) && (offset <= 33554430) &&
3322                        ((offset & 0x1) == 0));
3323            const int32_t target = offset >> 1;
3324            return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1);
3325          }
3326        } immop;
3327        EmitA32(Link(0xfa000000U, label, immop));
3328        return;
3329      }
3330    }
3331  }
3332  Delegate(kBlx, &Assembler::blx, cond, label);
3333}
3334
3335void Assembler::blx(Condition cond, Register rm) {
3336  VIXL_ASSERT(AllowAssembler());
3337  CheckIT(cond);
3338  if (IsUsingT32()) {
3339    // BLX{<c>}{<q>} <Rm> ; T1
3340    EmitT32_16(0x4780 | (rm.GetCode() << 3));
3341    AdvanceIT();
3342    return;
3343  } else {
3344    // BLX{<c>}{<q>} <Rm> ; A1
3345    if (cond.IsNotNever()) {
3346      EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode());
3347      return;
3348    }
3349  }
3350  Delegate(kBlx, &Assembler::blx, cond, rm);
3351}
3352
3353void Assembler::bx(Condition cond, Register rm) {
3354  VIXL_ASSERT(AllowAssembler());
3355  CheckIT(cond);
3356  if (IsUsingT32()) {
3357    // BX{<c>}{<q>} <Rm> ; T1
3358    EmitT32_16(0x4700 | (rm.GetCode() << 3));
3359    AdvanceIT();
3360    return;
3361  } else {
3362    // BX{<c>}{<q>} <Rm> ; A1
3363    if (cond.IsNotNever()) {
3364      EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode());
3365      return;
3366    }
3367  }
3368  Delegate(kBx, &Assembler::bx, cond, rm);
3369}
3370
3371void Assembler::bxj(Condition cond, Register rm) {
3372  VIXL_ASSERT(AllowAssembler());
3373  CheckIT(cond);
3374  if (IsUsingT32()) {
3375    // BXJ{<c>}{<q>} <Rm> ; T1
3376    EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16));
3377    AdvanceIT();
3378    return;
3379  } else {
3380    // BXJ{<c>}{<q>} <Rm> ; A1
3381    if (cond.IsNotNever()) {
3382      EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode());
3383      return;
3384    }
3385  }
3386  Delegate(kBxj, &Assembler::bxj, cond, rm);
3387}
3388
3389void Assembler::cbnz(Register rn, Label* label) {
3390  VIXL_ASSERT(AllowAssembler());
3391  CheckIT(al);
3392  Label::Offset offset =
3393      label->IsBound()
3394          ? label->GetLocation() -
3395                (GetCursorOffset() + GetArchitectureStatePCOffset())
3396          : 0;
3397  if (IsUsingT32()) {
3398    // CBNZ{<q>} <Rn>, <label> ; T1
3399    if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) &&
3400                        ((offset & 0x1) == 0)) ||
3401                       !label->IsBound())) {
3402      static class EmitOp : public Label::LabelEmitOperator {
3403       public:
3404        EmitOp() : Label::LabelEmitOperator(0, 126) {}
3405        virtual uint32_t Encode(uint32_t instr,
3406                                Label::Offset pc,
3407                                const Label* label) const VIXL_OVERRIDE {
3408          Label::Offset offset = label->GetLocation() - pc;
3409          VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
3410                      ((offset & 0x1) == 0));
3411          const int32_t target = offset >> 1;
3412          return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3413        }
3414      } immop;
3415      EmitT32_16(Link(0xb900 | rn.GetCode(), label, immop));
3416      AdvanceIT();
3417      return;
3418    }
3419  }
3420  Delegate(kCbnz, &Assembler::cbnz, rn, label);
3421}
3422
3423void Assembler::cbz(Register rn, Label* label) {
3424  VIXL_ASSERT(AllowAssembler());
3425  CheckIT(al);
3426  Label::Offset offset =
3427      label->IsBound()
3428          ? label->GetLocation() -
3429                (GetCursorOffset() + GetArchitectureStatePCOffset())
3430          : 0;
3431  if (IsUsingT32()) {
3432    // CBZ{<q>} <Rn>, <label> ; T1
3433    if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) &&
3434                        ((offset & 0x1) == 0)) ||
3435                       !label->IsBound())) {
3436      static class EmitOp : public Label::LabelEmitOperator {
3437       public:
3438        EmitOp() : Label::LabelEmitOperator(0, 126) {}
3439        virtual uint32_t Encode(uint32_t instr,
3440                                Label::Offset pc,
3441                                const Label* label) const VIXL_OVERRIDE {
3442          Label::Offset offset = label->GetLocation() - pc;
3443          VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
3444                      ((offset & 0x1) == 0));
3445          const int32_t target = offset >> 1;
3446          return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3447        }
3448      } immop;
3449      EmitT32_16(Link(0xb100 | rn.GetCode(), label, immop));
3450      AdvanceIT();
3451      return;
3452    }
3453  }
3454  Delegate(kCbz, &Assembler::cbz, rn, label);
3455}
3456
3457void Assembler::clrex(Condition cond) {
3458  VIXL_ASSERT(AllowAssembler());
3459  CheckIT(cond);
3460  if (IsUsingT32()) {
3461    // CLREX{<c>}{<q>} ; T1
3462    EmitT32_32(0xf3bf8f2fU);
3463    AdvanceIT();
3464    return;
3465  } else {
3466    // CLREX{<c>}{<q>} ; A1
3467    if (cond.Is(al)) {
3468      EmitA32(0xf57ff01fU);
3469      return;
3470    }
3471  }
3472  Delegate(kClrex, &Assembler::clrex, cond);
3473}
3474
3475void Assembler::clz(Condition cond, Register rd, Register rm) {
3476  VIXL_ASSERT(AllowAssembler());
3477  CheckIT(cond);
3478  if (IsUsingT32()) {
3479    // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1
3480    EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() |
3481               (rm.GetCode() << 16));
3482    AdvanceIT();
3483    return;
3484  } else {
3485    // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1
3486    if (cond.IsNotNever()) {
3487      EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3488              rm.GetCode());
3489      return;
3490    }
3491  }
3492  Delegate(kClz, &Assembler::clz, cond, rd, rm);
3493}
3494
3495void Assembler::cmn(Condition cond,
3496                    EncodingSize size,
3497                    Register rn,
3498                    const Operand& operand) {
3499  VIXL_ASSERT(AllowAssembler());
3500  CheckIT(cond);
3501  if (operand.IsImmediate()) {
3502    uint32_t imm = operand.GetImmediate();
3503    if (IsUsingT32()) {
3504      ImmediateT32 immediate_t32(imm);
3505      // CMN{<c>}{<q>} <Rn>, #<const> ; T1
3506      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3507        EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) |
3508                   (immediate_t32.GetEncodingValue() & 0xff) |
3509                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3510                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3511        AdvanceIT();
3512        return;
3513      }
3514    } else {
3515      ImmediateA32 immediate_a32(imm);
3516      // CMN{<c>}{<q>} <Rn>, #<const> ; A1
3517      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3518        EmitA32(0x03700000U | (cond.GetCondition() << 28) |
3519                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3520        return;
3521      }
3522    }
3523  }
3524  if (operand.IsImmediateShiftedRegister()) {
3525    Register rm = operand.GetBaseRegister();
3526    if (operand.IsPlainRegister()) {
3527      if (IsUsingT32()) {
3528        // CMN{<c>}{<q>} <Rn>, <Rm> ; T1
3529        if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3530          EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3));
3531          AdvanceIT();
3532          return;
3533        }
3534      }
3535    }
3536    Shift shift = operand.GetShift();
3537    uint32_t amount = operand.GetShiftAmount();
3538    if (IsUsingT32()) {
3539      // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
3540      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3541        uint32_t amount_ = amount % 32;
3542        EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() |
3543                   (operand.GetTypeEncodingValue() << 4) |
3544                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3545        AdvanceIT();
3546        return;
3547      }
3548    } else {
3549      // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3550      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3551        uint32_t amount_ = amount % 32;
3552        EmitA32(0x01700000U | (cond.GetCondition() << 28) |
3553                (rn.GetCode() << 16) | rm.GetCode() |
3554                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3555        return;
3556      }
3557    }
3558  }
3559  if (operand.IsRegisterShiftedRegister()) {
3560    Register rm = operand.GetBaseRegister();
3561    Shift shift = operand.GetShift();
3562    if (IsUsingA32()) {
3563      // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3564      if (cond.IsNotNever()) {
3565        EmitA32(0x01700010U | (cond.GetCondition() << 28) |
3566                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3567                (operand.GetShiftRegister().GetCode() << 8));
3568        return;
3569      }
3570    }
3571  }
3572  Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand);
3573}
3574
3575void Assembler::cmp(Condition cond,
3576                    EncodingSize size,
3577                    Register rn,
3578                    const Operand& operand) {
3579  VIXL_ASSERT(AllowAssembler());
3580  CheckIT(cond);
3581  if (operand.IsImmediate()) {
3582    uint32_t imm = operand.GetImmediate();
3583    if (IsUsingT32()) {
3584      ImmediateT32 immediate_t32(imm);
3585      // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1
3586      if (!size.IsWide() && rn.IsLow() && (imm <= 255)) {
3587        EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm);
3588        AdvanceIT();
3589        return;
3590      }
3591      // CMP{<c>}{<q>} <Rn>, #<const> ; T2
3592      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3593        EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) |
3594                   (immediate_t32.GetEncodingValue() & 0xff) |
3595                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3596                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3597        AdvanceIT();
3598        return;
3599      }
3600    } else {
3601      ImmediateA32 immediate_a32(imm);
3602      // CMP{<c>}{<q>} <Rn>, #<const> ; A1
3603      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3604        EmitA32(0x03500000U | (cond.GetCondition() << 28) |
3605                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3606        return;
3607      }
3608    }
3609  }
3610  if (operand.IsImmediateShiftedRegister()) {
3611    Register rm = operand.GetBaseRegister();
3612    if (operand.IsPlainRegister()) {
3613      if (IsUsingT32()) {
3614        // CMP{<c>}{<q>} <Rn>, <Rm> ; T1
3615        if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3616          EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3));
3617          AdvanceIT();
3618          return;
3619        }
3620        // CMP{<c>}{<q>} <Rn>, <Rm> ; T2
3621        if (!size.IsWide()) {
3622          EmitT32_16(0x4500 | (rn.GetCode() & 0x7) |
3623                     ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
3624          AdvanceIT();
3625          return;
3626        }
3627      }
3628    }
3629    Shift shift = operand.GetShift();
3630    uint32_t amount = operand.GetShiftAmount();
3631    if (IsUsingT32()) {
3632      // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3
3633      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3634        uint32_t amount_ = amount % 32;
3635        EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() |
3636                   (operand.GetTypeEncodingValue() << 4) |
3637                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3638        AdvanceIT();
3639        return;
3640      }
3641    } else {
3642      // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3643      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3644        uint32_t amount_ = amount % 32;
3645        EmitA32(0x01500000U | (cond.GetCondition() << 28) |
3646                (rn.GetCode() << 16) | rm.GetCode() |
3647                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3648        return;
3649      }
3650    }
3651  }
3652  if (operand.IsRegisterShiftedRegister()) {
3653    Register rm = operand.GetBaseRegister();
3654    Shift shift = operand.GetShift();
3655    if (IsUsingA32()) {
3656      // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3657      if (cond.IsNotNever()) {
3658        EmitA32(0x01500010U | (cond.GetCondition() << 28) |
3659                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3660                (operand.GetShiftRegister().GetCode() << 8));
3661        return;
3662      }
3663    }
3664  }
3665  Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand);
3666}
3667
3668void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) {
3669  VIXL_ASSERT(AllowAssembler());
3670  CheckIT(cond);
3671  if (IsUsingT32()) {
3672    // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1
3673    EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3674               rm.GetCode());
3675    AdvanceIT();
3676    return;
3677  } else {
3678    // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1
3679    if ((cond.Is(al) || AllowUnpredictable())) {
3680      EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3681              (rn.GetCode() << 16) | rm.GetCode());
3682      return;
3683    }
3684  }
3685  Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm);
3686}
3687
3688void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) {
3689  VIXL_ASSERT(AllowAssembler());
3690  CheckIT(cond);
3691  if (IsUsingT32()) {
3692    // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1
3693    EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3694               rm.GetCode());
3695    AdvanceIT();
3696    return;
3697  } else {
3698    // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1
3699    if ((cond.Is(al) || AllowUnpredictable())) {
3700      EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3701              (rn.GetCode() << 16) | rm.GetCode());
3702      return;
3703    }
3704  }
3705  Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm);
3706}
3707
3708void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) {
3709  VIXL_ASSERT(AllowAssembler());
3710  CheckIT(cond);
3711  if (IsUsingT32()) {
3712    // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1
3713    EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3714               rm.GetCode());
3715    AdvanceIT();
3716    return;
3717  } else {
3718    // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1
3719    if ((cond.Is(al) || AllowUnpredictable())) {
3720      EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3721              (rn.GetCode() << 16) | rm.GetCode());
3722      return;
3723    }
3724  }
3725  Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm);
3726}
3727
3728void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) {
3729  VIXL_ASSERT(AllowAssembler());
3730  CheckIT(cond);
3731  if (IsUsingT32()) {
3732    // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1
3733    EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3734               rm.GetCode());
3735    AdvanceIT();
3736    return;
3737  } else {
3738    // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1
3739    if ((cond.Is(al) || AllowUnpredictable())) {
3740      EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3741              (rn.GetCode() << 16) | rm.GetCode());
3742      return;
3743    }
3744  }
3745  Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm);
3746}
3747
3748void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) {
3749  VIXL_ASSERT(AllowAssembler());
3750  CheckIT(cond);
3751  if (IsUsingT32()) {
3752    // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1
3753    EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3754               rm.GetCode());
3755    AdvanceIT();
3756    return;
3757  } else {
3758    // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1
3759    if ((cond.Is(al) || AllowUnpredictable())) {
3760      EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3761              (rn.GetCode() << 16) | rm.GetCode());
3762      return;
3763    }
3764  }
3765  Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm);
3766}
3767
3768void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) {
3769  VIXL_ASSERT(AllowAssembler());
3770  CheckIT(cond);
3771  if (IsUsingT32()) {
3772    // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1
3773    EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3774               rm.GetCode());
3775    AdvanceIT();
3776    return;
3777  } else {
3778    // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1
3779    if ((cond.Is(al) || AllowUnpredictable())) {
3780      EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3781              (rn.GetCode() << 16) | rm.GetCode());
3782      return;
3783    }
3784  }
3785  Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm);
3786}
3787
3788void Assembler::dmb(Condition cond, MemoryBarrier option) {
3789  VIXL_ASSERT(AllowAssembler());
3790  CheckIT(cond);
3791  if (IsUsingT32()) {
3792    // DMB{<c>}{<q>} {<option>} ; T1
3793    EmitT32_32(0xf3bf8f50U | option.GetType());
3794    AdvanceIT();
3795    return;
3796  } else {
3797    // DMB{<c>}{<q>} {<option>} ; A1
3798    if (cond.Is(al)) {
3799      EmitA32(0xf57ff050U | option.GetType());
3800      return;
3801    }
3802  }
3803  Delegate(kDmb, &Assembler::dmb, cond, option);
3804}
3805
3806void Assembler::dsb(Condition cond, MemoryBarrier option) {
3807  VIXL_ASSERT(AllowAssembler());
3808  CheckIT(cond);
3809  if (IsUsingT32()) {
3810    // DSB{<c>}{<q>} {<option>} ; T1
3811    EmitT32_32(0xf3bf8f40U | option.GetType());
3812    AdvanceIT();
3813    return;
3814  } else {
3815    // DSB{<c>}{<q>} {<option>} ; A1
3816    if (cond.Is(al)) {
3817      EmitA32(0xf57ff040U | option.GetType());
3818      return;
3819    }
3820  }
3821  Delegate(kDsb, &Assembler::dsb, cond, option);
3822}
3823
3824void Assembler::eor(Condition cond,
3825                    EncodingSize size,
3826                    Register rd,
3827                    Register rn,
3828                    const Operand& operand) {
3829  VIXL_ASSERT(AllowAssembler());
3830  CheckIT(cond);
3831  if (operand.IsImmediate()) {
3832    uint32_t imm = operand.GetImmediate();
3833    if (IsUsingT32()) {
3834      ImmediateT32 immediate_t32(imm);
3835      // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3836      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3837        EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3838                   (immediate_t32.GetEncodingValue() & 0xff) |
3839                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3840                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3841        AdvanceIT();
3842        return;
3843      }
3844    } else {
3845      ImmediateA32 immediate_a32(imm);
3846      // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3847      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3848        EmitA32(0x02200000U | (cond.GetCondition() << 28) |
3849                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3850                immediate_a32.GetEncodingValue());
3851        return;
3852      }
3853    }
3854  }
3855  if (operand.IsImmediateShiftedRegister()) {
3856    Register rm = operand.GetBaseRegister();
3857    if (operand.IsPlainRegister()) {
3858      if (IsUsingT32()) {
3859        // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3860        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3861            rm.IsLow()) {
3862          EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
3863          AdvanceIT();
3864          return;
3865        }
3866      }
3867    }
3868    Shift shift = operand.GetShift();
3869    uint32_t amount = operand.GetShiftAmount();
3870    if (IsUsingT32()) {
3871      // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3872      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3873        uint32_t amount_ = amount % 32;
3874        EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3875                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3876                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3877        AdvanceIT();
3878        return;
3879      }
3880    } else {
3881      // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3882      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3883        uint32_t amount_ = amount % 32;
3884        EmitA32(0x00200000U | (cond.GetCondition() << 28) |
3885                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3886                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3887        return;
3888      }
3889    }
3890  }
3891  if (operand.IsRegisterShiftedRegister()) {
3892    Register rm = operand.GetBaseRegister();
3893    Shift shift = operand.GetShift();
3894    if (IsUsingA32()) {
3895      // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3896      if (cond.IsNotNever()) {
3897        EmitA32(0x00200010U | (cond.GetCondition() << 28) |
3898                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3899                (shift.GetType() << 5) |
3900                (operand.GetShiftRegister().GetCode() << 8));
3901        return;
3902      }
3903    }
3904  }
3905  Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand);
3906}
3907
3908void Assembler::eors(Condition cond,
3909                     EncodingSize size,
3910                     Register rd,
3911                     Register rn,
3912                     const Operand& operand) {
3913  VIXL_ASSERT(AllowAssembler());
3914  CheckIT(cond);
3915  if (operand.IsImmediate()) {
3916    uint32_t imm = operand.GetImmediate();
3917    if (IsUsingT32()) {
3918      ImmediateT32 immediate_t32(imm);
3919      // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3920      if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) {
3921        EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3922                   (immediate_t32.GetEncodingValue() & 0xff) |
3923                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3924                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3925        AdvanceIT();
3926        return;
3927      }
3928    } else {
3929      ImmediateA32 immediate_a32(imm);
3930      // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3931      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3932        EmitA32(0x02300000U | (cond.GetCondition() << 28) |
3933                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3934                immediate_a32.GetEncodingValue());
3935        return;
3936      }
3937    }
3938  }
3939  if (operand.IsImmediateShiftedRegister()) {
3940    Register rm = operand.GetBaseRegister();
3941    if (operand.IsPlainRegister()) {
3942      if (IsUsingT32()) {
3943        // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3944        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3945            rm.IsLow()) {
3946          EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
3947          AdvanceIT();
3948          return;
3949        }
3950      }
3951    }
3952    Shift shift = operand.GetShift();
3953    uint32_t amount = operand.GetShiftAmount();
3954    if (IsUsingT32()) {
3955      // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3956      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) {
3957        uint32_t amount_ = amount % 32;
3958        EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3959                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3960                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3961        AdvanceIT();
3962        return;
3963      }
3964    } else {
3965      // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3966      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3967        uint32_t amount_ = amount % 32;
3968        EmitA32(0x00300000U | (cond.GetCondition() << 28) |
3969                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3970                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3971        return;
3972      }
3973    }
3974  }
3975  if (operand.IsRegisterShiftedRegister()) {
3976    Register rm = operand.GetBaseRegister();
3977    Shift shift = operand.GetShift();
3978    if (IsUsingA32()) {
3979      // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3980      if (cond.IsNotNever()) {
3981        EmitA32(0x00300010U | (cond.GetCondition() << 28) |
3982                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3983                (shift.GetType() << 5) |
3984                (operand.GetShiftRegister().GetCode() << 8));
3985        return;
3986      }
3987    }
3988  }
3989  Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand);
3990}
3991
3992void Assembler::fldmdbx(Condition cond,
3993                        Register rn,
3994                        WriteBack write_back,
3995                        DRegisterList dreglist) {
3996  VIXL_ASSERT(AllowAssembler());
3997  CheckIT(cond);
3998  if (IsUsingT32()) {
3999    // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
4000    if (write_back.DoesWriteBack() &&
4001        (((dreglist.GetLength() <= 16) &&
4002          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4003         AllowUnpredictable())) {
4004      const DRegister& dreg = dreglist.GetFirstDRegister();
4005      unsigned len = dreglist.GetLength() * 2;
4006      EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
4007                 (len & 0xff));
4008      AdvanceIT();
4009      return;
4010    }
4011  } else {
4012    // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
4013    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
4014        (((dreglist.GetLength() <= 16) &&
4015          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4016         AllowUnpredictable())) {
4017      const DRegister& dreg = dreglist.GetFirstDRegister();
4018      unsigned len = dreglist.GetLength() * 2;
4019      EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4020              dreg.Encode(22, 12) | (len & 0xff));
4021      return;
4022    }
4023  }
4024  Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist);
4025}
4026
4027void Assembler::fldmiax(Condition cond,
4028                        Register rn,
4029                        WriteBack write_back,
4030                        DRegisterList dreglist) {
4031  VIXL_ASSERT(AllowAssembler());
4032  CheckIT(cond);
4033  if (IsUsingT32()) {
4034    // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
4035    if ((((dreglist.GetLength() <= 16) &&
4036          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4037         AllowUnpredictable())) {
4038      const DRegister& dreg = dreglist.GetFirstDRegister();
4039      unsigned len = dreglist.GetLength() * 2;
4040      EmitT32_32(0xec900b01U | (rn.GetCode() << 16) |
4041                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4042                 (len & 0xff));
4043      AdvanceIT();
4044      return;
4045    }
4046  } else {
4047    // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
4048    if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
4049                               (dreglist.GetLastDRegister().GetCode() < 16)) ||
4050                              AllowUnpredictable())) {
4051      const DRegister& dreg = dreglist.GetFirstDRegister();
4052      unsigned len = dreglist.GetLength() * 2;
4053      EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4054              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4055              (len & 0xff));
4056      return;
4057    }
4058  }
4059  Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist);
4060}
4061
4062void Assembler::fstmdbx(Condition cond,
4063                        Register rn,
4064                        WriteBack write_back,
4065                        DRegisterList dreglist) {
4066  VIXL_ASSERT(AllowAssembler());
4067  CheckIT(cond);
4068  if (IsUsingT32()) {
4069    // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
4070    if (write_back.DoesWriteBack() &&
4071        (((dreglist.GetLength() <= 16) &&
4072          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4073         AllowUnpredictable())) {
4074      const DRegister& dreg = dreglist.GetFirstDRegister();
4075      unsigned len = dreglist.GetLength() * 2;
4076      EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
4077                 (len & 0xff));
4078      AdvanceIT();
4079      return;
4080    }
4081  } else {
4082    // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
4083    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
4084        (((dreglist.GetLength() <= 16) &&
4085          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4086         AllowUnpredictable())) {
4087      const DRegister& dreg = dreglist.GetFirstDRegister();
4088      unsigned len = dreglist.GetLength() * 2;
4089      EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4090              dreg.Encode(22, 12) | (len & 0xff));
4091      return;
4092    }
4093  }
4094  Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist);
4095}
4096
4097void Assembler::fstmiax(Condition cond,
4098                        Register rn,
4099                        WriteBack write_back,
4100                        DRegisterList dreglist) {
4101  VIXL_ASSERT(AllowAssembler());
4102  CheckIT(cond);
4103  if (IsUsingT32()) {
4104    // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
4105    if ((((dreglist.GetLength() <= 16) &&
4106          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4107         AllowUnpredictable())) {
4108      const DRegister& dreg = dreglist.GetFirstDRegister();
4109      unsigned len = dreglist.GetLength() * 2;
4110      EmitT32_32(0xec800b01U | (rn.GetCode() << 16) |
4111                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4112                 (len & 0xff));
4113      AdvanceIT();
4114      return;
4115    }
4116  } else {
4117    // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
4118    if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
4119                               (dreglist.GetLastDRegister().GetCode() < 16)) ||
4120                              AllowUnpredictable())) {
4121      const DRegister& dreg = dreglist.GetFirstDRegister();
4122      unsigned len = dreglist.GetLength() * 2;
4123      EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4124              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4125              (len & 0xff));
4126      return;
4127    }
4128  }
4129  Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist);
4130}
4131
4132void Assembler::hlt(Condition cond, uint32_t imm) {
4133  VIXL_ASSERT(AllowAssembler());
4134  CheckIT(cond);
4135  if (IsUsingT32()) {
4136    // HLT{<q>} {#}<imm> ; T1
4137    if ((imm <= 63)) {
4138      EmitT32_16(0xba80 | imm);
4139      AdvanceIT();
4140      return;
4141    }
4142  } else {
4143    // HLT{<q>} {#}<imm> ; A1
4144    if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4145      EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4146              ((imm & 0xfff0) << 4));
4147      return;
4148    }
4149  }
4150  Delegate(kHlt, &Assembler::hlt, cond, imm);
4151}
4152
4153void Assembler::hvc(Condition cond, uint32_t imm) {
4154  VIXL_ASSERT(AllowAssembler());
4155  CheckIT(cond);
4156  if (IsUsingT32()) {
4157    // HVC{<q>} {#}<imm16> ; T1
4158    if ((imm <= 65535)) {
4159      EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
4160      AdvanceIT();
4161      return;
4162    }
4163  } else {
4164    // HVC{<q>} {#}<imm16> ; A1
4165    if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4166      EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4167              ((imm & 0xfff0) << 4));
4168      return;
4169    }
4170  }
4171  Delegate(kHvc, &Assembler::hvc, cond, imm);
4172}
4173
4174void Assembler::isb(Condition cond, MemoryBarrier option) {
4175  VIXL_ASSERT(AllowAssembler());
4176  CheckIT(cond);
4177  if (IsUsingT32()) {
4178    // ISB{<c>}{<q>} {<option>} ; T1
4179    EmitT32_32(0xf3bf8f60U | option.GetType());
4180    AdvanceIT();
4181    return;
4182  } else {
4183    // ISB{<c>}{<q>} {<option>} ; A1
4184    if (cond.Is(al)) {
4185      EmitA32(0xf57ff060U | option.GetType());
4186      return;
4187    }
4188  }
4189  Delegate(kIsb, &Assembler::isb, cond, option);
4190}
4191
4192void Assembler::it(Condition cond, uint16_t mask) {
4193  VIXL_ASSERT(AllowAssembler());
4194  CheckNotIT();
4195  if (mask != 0) {
4196    if ((cond.GetCondition() & 0x1) != 0) {
4197      if ((mask & 0x1) != 0) {
4198        mask ^= 0xE;
4199      } else if ((mask & 0x2) != 0) {
4200        mask ^= 0xC;
4201      } else if ((mask & 0x4) != 0) {
4202        mask ^= 0x8;
4203      }
4204    }
4205    if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask);
4206    SetIT(cond, mask);
4207    return;
4208  }
4209  DelegateIt(cond, mask);
4210}
4211
4212void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) {
4213  VIXL_ASSERT(AllowAssembler());
4214  CheckIT(cond);
4215  if (operand.IsImmediateZero()) {
4216    Register rn = operand.GetBaseRegister();
4217    if (IsUsingT32()) {
4218      // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1
4219      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4220        EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4221        AdvanceIT();
4222        return;
4223      }
4224    } else {
4225      // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1
4226      if (operand.IsOffset() && cond.IsNotNever() &&
4227          (!rn.IsPC() || AllowUnpredictable())) {
4228        EmitA32(0x01900c9fU | (cond.GetCondition() << 28) |
4229                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4230        return;
4231      }
4232    }
4233  }
4234  Delegate(kLda, &Assembler::lda, cond, rt, operand);
4235}
4236
4237void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) {
4238  VIXL_ASSERT(AllowAssembler());
4239  CheckIT(cond);
4240  if (operand.IsImmediateZero()) {
4241    Register rn = operand.GetBaseRegister();
4242    if (IsUsingT32()) {
4243      // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4244      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4245        EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4246        AdvanceIT();
4247        return;
4248      }
4249    } else {
4250      // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4251      if (operand.IsOffset() && cond.IsNotNever() &&
4252          (!rn.IsPC() || AllowUnpredictable())) {
4253        EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) |
4254                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4255        return;
4256      }
4257    }
4258  }
4259  Delegate(kLdab, &Assembler::ldab, cond, rt, operand);
4260}
4261
4262void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) {
4263  VIXL_ASSERT(AllowAssembler());
4264  CheckIT(cond);
4265  if (operand.IsImmediateZero()) {
4266    Register rn = operand.GetBaseRegister();
4267    if (IsUsingT32()) {
4268      // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1
4269      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4270        EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4271        AdvanceIT();
4272        return;
4273      }
4274    } else {
4275      // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1
4276      if (operand.IsOffset() && cond.IsNotNever() &&
4277          (!rn.IsPC() || AllowUnpredictable())) {
4278        EmitA32(0x01900e9fU | (cond.GetCondition() << 28) |
4279                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4280        return;
4281      }
4282    }
4283  }
4284  Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand);
4285}
4286
4287void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) {
4288  VIXL_ASSERT(AllowAssembler());
4289  CheckIT(cond);
4290  if (operand.IsImmediateZero()) {
4291    Register rn = operand.GetBaseRegister();
4292    if (IsUsingT32()) {
4293      // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4294      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4295        EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4296        AdvanceIT();
4297        return;
4298      }
4299    } else {
4300      // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4301      if (operand.IsOffset() && cond.IsNotNever() &&
4302          (!rn.IsPC() || AllowUnpredictable())) {
4303        EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) |
4304                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4305        return;
4306      }
4307    }
4308  }
4309  Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand);
4310}
4311
4312void Assembler::ldaexd(Condition cond,
4313                       Register rt,
4314                       Register rt2,
4315                       const MemOperand& operand) {
4316  VIXL_ASSERT(AllowAssembler());
4317  CheckIT(cond);
4318  if (operand.IsImmediateZero()) {
4319    Register rn = operand.GetBaseRegister();
4320    if (IsUsingT32()) {
4321      // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
4322      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4323        EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
4324                   (rn.GetCode() << 16));
4325        AdvanceIT();
4326        return;
4327      }
4328    } else {
4329      // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
4330      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
4331          operand.IsOffset() && cond.IsNotNever() &&
4332          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
4333           AllowUnpredictable())) {
4334        EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) |
4335                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4336        return;
4337      }
4338    }
4339  }
4340  Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand);
4341}
4342
4343void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) {
4344  VIXL_ASSERT(AllowAssembler());
4345  CheckIT(cond);
4346  if (operand.IsImmediateZero()) {
4347    Register rn = operand.GetBaseRegister();
4348    if (IsUsingT32()) {
4349      // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4350      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4351        EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4352        AdvanceIT();
4353        return;
4354      }
4355    } else {
4356      // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4357      if (operand.IsOffset() && cond.IsNotNever() &&
4358          (!rn.IsPC() || AllowUnpredictable())) {
4359        EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) |
4360                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4361        return;
4362      }
4363    }
4364  }
4365  Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand);
4366}
4367
4368void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) {
4369  VIXL_ASSERT(AllowAssembler());
4370  CheckIT(cond);
4371  if (operand.IsImmediateZero()) {
4372    Register rn = operand.GetBaseRegister();
4373    if (IsUsingT32()) {
4374      // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4375      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4376        EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4377        AdvanceIT();
4378        return;
4379      }
4380    } else {
4381      // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4382      if (operand.IsOffset() && cond.IsNotNever() &&
4383          (!rn.IsPC() || AllowUnpredictable())) {
4384        EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) |
4385                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4386        return;
4387      }
4388    }
4389  }
4390  Delegate(kLdah, &Assembler::ldah, cond, rt, operand);
4391}
4392
4393void Assembler::ldm(Condition cond,
4394                    EncodingSize size,
4395                    Register rn,
4396                    WriteBack write_back,
4397                    RegisterList registers) {
4398  VIXL_ASSERT(AllowAssembler());
4399  CheckIT(cond);
4400  if (IsUsingT32()) {
4401    // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1
4402    if (!size.IsWide() && rn.IsLow() &&
4403        (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4404         write_back.DoesWriteBack()) &&
4405        ((registers.GetList() & ~0xff) == 0)) {
4406      EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4407                 GetRegisterListEncoding(registers, 0, 8));
4408      AdvanceIT();
4409      return;
4410    }
4411    // LDM{<c>}{<q>} SP!, <registers> ; T1
4412    if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
4413        ((registers.GetList() & ~0x80ff) == 0)) {
4414      EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
4415                 GetRegisterListEncoding(registers, 0, 8));
4416      AdvanceIT();
4417      return;
4418    }
4419    // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2
4420    if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
4421      EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4422                 (write_back.GetWriteBackUint32() << 21) |
4423                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4424                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4425                 GetRegisterListEncoding(registers, 0, 13));
4426      AdvanceIT();
4427      return;
4428    }
4429  } else {
4430    // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1
4431    if (cond.IsNotNever()) {
4432      EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4433              (write_back.GetWriteBackUint32() << 21) |
4434              GetRegisterListEncoding(registers, 0, 16));
4435      return;
4436    }
4437  }
4438  Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers);
4439}
4440
4441void Assembler::ldmda(Condition cond,
4442                      Register rn,
4443                      WriteBack write_back,
4444                      RegisterList registers) {
4445  VIXL_ASSERT(AllowAssembler());
4446  CheckIT(cond);
4447  if (IsUsingA32()) {
4448    // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4449    if (cond.IsNotNever()) {
4450      EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4451              (write_back.GetWriteBackUint32() << 21) |
4452              GetRegisterListEncoding(registers, 0, 16));
4453      return;
4454    }
4455  }
4456  Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers);
4457}
4458
4459void Assembler::ldmdb(Condition cond,
4460                      Register rn,
4461                      WriteBack write_back,
4462                      RegisterList registers) {
4463  VIXL_ASSERT(AllowAssembler());
4464  CheckIT(cond);
4465  if (IsUsingT32()) {
4466    // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
4467    if (((registers.GetList() & ~0xdfff) == 0)) {
4468      EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4469                 (write_back.GetWriteBackUint32() << 21) |
4470                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4471                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4472                 GetRegisterListEncoding(registers, 0, 13));
4473      AdvanceIT();
4474      return;
4475    }
4476  } else {
4477    // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4478    if (cond.IsNotNever()) {
4479      EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4480              (write_back.GetWriteBackUint32() << 21) |
4481              GetRegisterListEncoding(registers, 0, 16));
4482      return;
4483    }
4484  }
4485  Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers);
4486}
4487
4488void Assembler::ldmea(Condition cond,
4489                      Register rn,
4490                      WriteBack write_back,
4491                      RegisterList registers) {
4492  VIXL_ASSERT(AllowAssembler());
4493  CheckIT(cond);
4494  if (IsUsingT32()) {
4495    // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1
4496    if (((registers.GetList() & ~0xdfff) == 0)) {
4497      EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4498                 (write_back.GetWriteBackUint32() << 21) |
4499                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4500                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4501                 GetRegisterListEncoding(registers, 0, 13));
4502      AdvanceIT();
4503      return;
4504    }
4505  } else {
4506    // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4507    if (cond.IsNotNever()) {
4508      EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4509              (write_back.GetWriteBackUint32() << 21) |
4510              GetRegisterListEncoding(registers, 0, 16));
4511      return;
4512    }
4513  }
4514  Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers);
4515}
4516
4517void Assembler::ldmed(Condition cond,
4518                      Register rn,
4519                      WriteBack write_back,
4520                      RegisterList registers) {
4521  VIXL_ASSERT(AllowAssembler());
4522  CheckIT(cond);
4523  if (IsUsingA32()) {
4524    // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
4525    if (cond.IsNotNever()) {
4526      EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4527              (write_back.GetWriteBackUint32() << 21) |
4528              GetRegisterListEncoding(registers, 0, 16));
4529      return;
4530    }
4531  }
4532  Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers);
4533}
4534
4535void Assembler::ldmfa(Condition cond,
4536                      Register rn,
4537                      WriteBack write_back,
4538                      RegisterList registers) {
4539  VIXL_ASSERT(AllowAssembler());
4540  CheckIT(cond);
4541  if (IsUsingA32()) {
4542    // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4543    if (cond.IsNotNever()) {
4544      EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4545              (write_back.GetWriteBackUint32() << 21) |
4546              GetRegisterListEncoding(registers, 0, 16));
4547      return;
4548    }
4549  }
4550  Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers);
4551}
4552
4553void Assembler::ldmfd(Condition cond,
4554                      EncodingSize size,
4555                      Register rn,
4556                      WriteBack write_back,
4557                      RegisterList registers) {
4558  VIXL_ASSERT(AllowAssembler());
4559  CheckIT(cond);
4560  if (IsUsingT32()) {
4561    // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
4562    if (!size.IsWide() && rn.IsLow() &&
4563        (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4564         write_back.DoesWriteBack()) &&
4565        ((registers.GetList() & ~0xff) == 0)) {
4566      EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4567                 GetRegisterListEncoding(registers, 0, 8));
4568      AdvanceIT();
4569      return;
4570    }
4571    // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2
4572    if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
4573      EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4574                 (write_back.GetWriteBackUint32() << 21) |
4575                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4576                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4577                 GetRegisterListEncoding(registers, 0, 13));
4578      AdvanceIT();
4579      return;
4580    }
4581  } else {
4582    // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
4583    if (cond.IsNotNever()) {
4584      EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4585              (write_back.GetWriteBackUint32() << 21) |
4586              GetRegisterListEncoding(registers, 0, 16));
4587      return;
4588    }
4589  }
4590  Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers);
4591}
4592
4593void Assembler::ldmib(Condition cond,
4594                      Register rn,
4595                      WriteBack write_back,
4596                      RegisterList registers) {
4597  VIXL_ASSERT(AllowAssembler());
4598  CheckIT(cond);
4599  if (IsUsingA32()) {
4600    // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4601    if (cond.IsNotNever()) {
4602      EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4603              (write_back.GetWriteBackUint32() << 21) |
4604              GetRegisterListEncoding(registers, 0, 16));
4605      return;
4606    }
4607  }
4608  Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers);
4609}
4610
4611void Assembler::ldr(Condition cond,
4612                    EncodingSize size,
4613                    Register rt,
4614                    const MemOperand& operand) {
4615  VIXL_ASSERT(AllowAssembler());
4616  CheckIT(cond);
4617  if (operand.IsImmediate()) {
4618    Register rn = operand.GetBaseRegister();
4619    int32_t offset = operand.GetOffsetImmediate();
4620    if (IsUsingT32()) {
4621      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
4622      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
4623          (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
4624        int32_t offset_ = offset >> 2;
4625        EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) |
4626                   ((offset_ & 0x1f) << 6));
4627        AdvanceIT();
4628        return;
4629      }
4630      // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
4631      if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
4632          ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
4633        int32_t offset_ = offset >> 2;
4634        EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff));
4635        AdvanceIT();
4636        return;
4637      }
4638      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
4639      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
4640          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
4641        EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4642                   (offset & 0xfff));
4643        AdvanceIT();
4644        return;
4645      }
4646      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
4647      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
4648          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
4649        EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4650                   (-offset & 0xff));
4651        AdvanceIT();
4652        return;
4653      }
4654      // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
4655      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4656          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4657        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4658        uint32_t offset_ = abs(offset);
4659        EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4660                   offset_ | (sign << 9));
4661        AdvanceIT();
4662        return;
4663      }
4664      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
4665      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4666          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4667        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4668        uint32_t offset_ = abs(offset);
4669        EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4670                   offset_ | (sign << 9));
4671        AdvanceIT();
4672        return;
4673      }
4674      // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2
4675      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
4676          rn.Is(pc) && operand.IsOffset()) {
4677        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4678        uint32_t offset_ = abs(offset);
4679        EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
4680        AdvanceIT();
4681        return;
4682      }
4683    } else {
4684      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
4685      if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
4686          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4687        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4688        uint32_t offset_ = abs(offset);
4689        EmitA32(0x05100000U | (cond.GetCondition() << 28) |
4690                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4691                (sign << 23));
4692        return;
4693      }
4694      // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
4695      if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
4696          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4697        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4698        uint32_t offset_ = abs(offset);
4699        EmitA32(0x04100000U | (cond.GetCondition() << 28) |
4700                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4701                (sign << 23));
4702        return;
4703      }
4704      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
4705      if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
4706          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4707        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4708        uint32_t offset_ = abs(offset);
4709        EmitA32(0x05300000U | (cond.GetCondition() << 28) |
4710                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4711                (sign << 23));
4712        return;
4713      }
4714      // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
4715      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
4716          operand.IsOffset() && cond.IsNotNever()) {
4717        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4718        uint32_t offset_ = abs(offset);
4719        EmitA32(0x051f0000U | (cond.GetCondition() << 28) |
4720                (rt.GetCode() << 12) | offset_ | (sign << 23));
4721        return;
4722      }
4723    }
4724  }
4725  if (operand.IsPlainRegister()) {
4726    Register rn = operand.GetBaseRegister();
4727    Sign sign = operand.GetSign();
4728    Register rm = operand.GetOffsetRegister();
4729    if (IsUsingT32()) {
4730      // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
4731      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
4732          sign.IsPlus() && operand.IsOffset()) {
4733        EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) |
4734                   (rm.GetCode() << 6));
4735        AdvanceIT();
4736        return;
4737      }
4738    }
4739  }
4740  if (operand.IsShiftedRegister()) {
4741    Register rn = operand.GetBaseRegister();
4742    Sign sign = operand.GetSign();
4743    Register rm = operand.GetOffsetRegister();
4744    Shift shift = operand.GetShift();
4745    uint32_t amount = operand.GetShiftAmount();
4746    if (IsUsingT32()) {
4747      // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
4748      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
4749          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
4750        EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4751                   rm.GetCode() | (amount << 4));
4752        AdvanceIT();
4753        return;
4754      }
4755    } else {
4756      // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
4757      if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
4758        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4759        uint32_t shift_ = TypeEncodingValue(shift);
4760        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4761        EmitA32(0x07100000U | (cond.GetCondition() << 28) |
4762                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4763                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4764        return;
4765      }
4766      // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
4767      if (operand.IsShiftValid() && operand.IsPostIndex() &&
4768          cond.IsNotNever()) {
4769        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4770        uint32_t shift_ = TypeEncodingValue(shift);
4771        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4772        EmitA32(0x06100000U | (cond.GetCondition() << 28) |
4773                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4774                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4775        return;
4776      }
4777      // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
4778      if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
4779        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4780        uint32_t shift_ = TypeEncodingValue(shift);
4781        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4782        EmitA32(0x07300000U | (cond.GetCondition() << 28) |
4783                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4784                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4785        return;
4786      }
4787    }
4788  }
4789  Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand);
4790}
4791
4792void Assembler::ldr(Condition cond,
4793                    EncodingSize size,
4794                    Register rt,
4795                    Label* label) {
4796  VIXL_ASSERT(AllowAssembler());
4797  CheckIT(cond);
4798  Label::Offset offset =
4799      label->IsBound()
4800          ? label->GetLocation() -
4801                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
4802          : 0;
4803  if (IsUsingT32()) {
4804    // LDR{<c>}{<q>} <Rt>, <label> ; T1
4805    if (!size.IsWide() && rt.IsLow() &&
4806        ((label->IsBound() && (offset >= 0) && (offset <= 1020) &&
4807          ((offset & 0x3) == 0)) ||
4808         (!label->IsBound() && size.IsNarrow()))) {
4809      static class EmitOp : public Label::LabelEmitOperator {
4810       public:
4811        EmitOp() : Label::LabelEmitOperator(0, 1020) {}
4812        virtual uint32_t Encode(uint32_t instr,
4813                                Label::Offset pc,
4814                                const Label* label) const VIXL_OVERRIDE {
4815          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4816          VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
4817                      ((offset & 0x3) == 0));
4818          const int32_t target = offset >> 2;
4819          return instr | (target & 0xff);
4820        }
4821      } immop;
4822      EmitT32_16(Link(0x4800 | (rt.GetCode() << 8), label, immop));
4823      AdvanceIT();
4824      return;
4825    }
4826    // LDR{<c>}{<q>} <Rt>, <label> ; T2
4827    if (!size.IsNarrow() &&
4828        ((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
4829         !label->IsBound())) {
4830      static class EmitOp : public Label::LabelEmitOperator {
4831       public:
4832        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
4833        virtual uint32_t Encode(uint32_t instr,
4834                                Label::Offset pc,
4835                                const Label* label) const VIXL_OVERRIDE {
4836          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4837          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
4838          uint32_t U = (offset >= 0) && !label->IsMinusZero();
4839          int32_t target = abs(offset) | (U << 12);
4840          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
4841        }
4842      } immop;
4843      EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12), label, immop));
4844      AdvanceIT();
4845      return;
4846    }
4847  } else {
4848    // LDR{<c>}{<q>} <Rt>, <label> ; A1
4849    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
4850         !label->IsBound()) &&
4851        cond.IsNotNever()) {
4852      static class EmitOp : public Label::LabelEmitOperator {
4853       public:
4854        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
4855        virtual uint32_t Encode(uint32_t instr,
4856                                Label::Offset pc,
4857                                const Label* label) const VIXL_OVERRIDE {
4858          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4859          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
4860          uint32_t U = (offset >= 0) && !label->IsMinusZero();
4861          int32_t target = abs(offset) | (U << 12);
4862          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
4863        }
4864      } immop;
4865      EmitA32(
4866          Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
4867               label,
4868               immop));
4869      return;
4870    }
4871  }
4872  Delegate(kLdr, &Assembler::ldr, cond, size, rt, label);
4873}
4874
4875void Assembler::ldrb(Condition cond,
4876                     EncodingSize size,
4877                     Register rt,
4878                     const MemOperand& operand) {
4879  VIXL_ASSERT(AllowAssembler());
4880  CheckIT(cond);
4881  if (operand.IsImmediate()) {
4882    Register rn = operand.GetBaseRegister();
4883    int32_t offset = operand.GetOffsetImmediate();
4884    if (IsUsingT32()) {
4885      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
4886      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
4887          (offset <= 31) && operand.IsOffset()) {
4888        EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) |
4889                   ((offset & 0x1f) << 6));
4890        AdvanceIT();
4891        return;
4892      }
4893      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
4894      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
4895          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
4896        EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4897                   (offset & 0xfff));
4898        AdvanceIT();
4899        return;
4900      }
4901      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
4902      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
4903          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
4904        EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4905                   (-offset & 0xff));
4906        AdvanceIT();
4907        return;
4908      }
4909      // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
4910      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4911          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4912        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4913        uint32_t offset_ = abs(offset);
4914        EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4915                   offset_ | (sign << 9));
4916        AdvanceIT();
4917        return;
4918      }
4919      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
4920      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4921          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4922        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4923        uint32_t offset_ = abs(offset);
4924        EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4925                   offset_ | (sign << 9));
4926        AdvanceIT();
4927        return;
4928      }
4929      // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
4930      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
4931          rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
4932        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4933        uint32_t offset_ = abs(offset);
4934        EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
4935        AdvanceIT();
4936        return;
4937      }
4938    } else {
4939      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
4940      if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
4941          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4942        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4943        uint32_t offset_ = abs(offset);
4944        EmitA32(0x05500000U | (cond.GetCondition() << 28) |
4945                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4946                (sign << 23));
4947        return;
4948      }
4949      // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
4950      if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
4951          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4952        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4953        uint32_t offset_ = abs(offset);
4954        EmitA32(0x04500000U | (cond.GetCondition() << 28) |
4955                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4956                (sign << 23));
4957        return;
4958      }
4959      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
4960      if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
4961          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4962        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4963        uint32_t offset_ = abs(offset);
4964        EmitA32(0x05700000U | (cond.GetCondition() << 28) |
4965                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4966                (sign << 23));
4967        return;
4968      }
4969      // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
4970      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
4971          operand.IsOffset() && cond.IsNotNever()) {
4972        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4973        uint32_t offset_ = abs(offset);
4974        EmitA32(0x055f0000U | (cond.GetCondition() << 28) |
4975                (rt.GetCode() << 12) | offset_ | (sign << 23));
4976        return;
4977      }
4978    }
4979  }
4980  if (operand.IsPlainRegister()) {
4981    Register rn = operand.GetBaseRegister();
4982    Sign sign = operand.GetSign();
4983    Register rm = operand.GetOffsetRegister();
4984    if (IsUsingT32()) {
4985      // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
4986      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
4987          sign.IsPlus() && operand.IsOffset()) {
4988        EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) |
4989                   (rm.GetCode() << 6));
4990        AdvanceIT();
4991        return;
4992      }
4993    }
4994  }
4995  if (operand.IsShiftedRegister()) {
4996    Register rn = operand.GetBaseRegister();
4997    Sign sign = operand.GetSign();
4998    Register rm = operand.GetOffsetRegister();
4999    Shift shift = operand.GetShift();
5000    uint32_t amount = operand.GetShiftAmount();
5001    if (IsUsingT32()) {
5002      // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5003      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5004          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5005        EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5006                   rm.GetCode() | (amount << 4));
5007        AdvanceIT();
5008        return;
5009      }
5010    } else {
5011      // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
5012      if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
5013        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5014        uint32_t shift_ = TypeEncodingValue(shift);
5015        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5016        EmitA32(0x07500000U | (cond.GetCondition() << 28) |
5017                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5018                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5019        return;
5020      }
5021      // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
5022      if (operand.IsShiftValid() && operand.IsPostIndex() &&
5023          cond.IsNotNever()) {
5024        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5025        uint32_t shift_ = TypeEncodingValue(shift);
5026        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5027        EmitA32(0x06500000U | (cond.GetCondition() << 28) |
5028                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5029                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5030        return;
5031      }
5032      // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
5033      if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
5034        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5035        uint32_t shift_ = TypeEncodingValue(shift);
5036        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5037        EmitA32(0x07700000U | (cond.GetCondition() << 28) |
5038                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5039                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5040        return;
5041      }
5042    }
5043  }
5044  Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand);
5045}
5046
5047void Assembler::ldrb(Condition cond, Register rt, Label* label) {
5048  VIXL_ASSERT(AllowAssembler());
5049  CheckIT(cond);
5050  Label::Offset offset =
5051      label->IsBound()
5052          ? label->GetLocation() -
5053                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5054          : 0;
5055  if (IsUsingT32()) {
5056    // LDRB{<c>}{<q>} <Rt>, <label> ; T1
5057    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5058         !label->IsBound()) &&
5059        !rt.Is(pc)) {
5060      static class EmitOp : public Label::LabelEmitOperator {
5061       public:
5062        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5063        virtual uint32_t Encode(uint32_t instr,
5064                                Label::Offset pc,
5065                                const Label* label) const VIXL_OVERRIDE {
5066          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5067          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5068          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5069          int32_t target = abs(offset) | (U << 12);
5070          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5071        }
5072      } immop;
5073      EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12), label, immop));
5074      AdvanceIT();
5075      return;
5076    }
5077  } else {
5078    // LDRB{<c>}{<q>} <Rt>, <label> ; A1
5079    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5080         !label->IsBound()) &&
5081        cond.IsNotNever()) {
5082      static class EmitOp : public Label::LabelEmitOperator {
5083       public:
5084        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5085        virtual uint32_t Encode(uint32_t instr,
5086                                Label::Offset pc,
5087                                const Label* label) const VIXL_OVERRIDE {
5088          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5089          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5090          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5091          int32_t target = abs(offset) | (U << 12);
5092          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5093        }
5094      } immop;
5095      EmitA32(
5096          Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5097               label,
5098               immop));
5099      return;
5100    }
5101  }
5102  Delegate(kLdrb, &Assembler::ldrb, cond, rt, label);
5103}
5104
5105void Assembler::ldrd(Condition cond,
5106                     Register rt,
5107                     Register rt2,
5108                     const MemOperand& operand) {
5109  VIXL_ASSERT(AllowAssembler());
5110  CheckIT(cond);
5111  if (operand.IsImmediate()) {
5112    Register rn = operand.GetBaseRegister();
5113    int32_t offset = operand.GetOffsetImmediate();
5114    if (IsUsingT32()) {
5115      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
5116      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5117          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
5118        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5119        uint32_t offset_ = abs(offset) >> 2;
5120        EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5121                   (rn.GetCode() << 16) | offset_ | (sign << 23));
5122        AdvanceIT();
5123        return;
5124      }
5125      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
5126      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5127          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5128        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5129        uint32_t offset_ = abs(offset) >> 2;
5130        EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5131                   (rn.GetCode() << 16) | offset_ | (sign << 23));
5132        AdvanceIT();
5133        return;
5134      }
5135      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
5136      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5137          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5138        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5139        uint32_t offset_ = abs(offset) >> 2;
5140        EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5141                   (rn.GetCode() << 16) | offset_ | (sign << 23));
5142        AdvanceIT();
5143        return;
5144      }
5145      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1
5146      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5147          operand.IsOffset()) {
5148        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5149        uint32_t offset_ = abs(offset);
5150        EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5151                   offset_ | (sign << 23));
5152        AdvanceIT();
5153        return;
5154      }
5155    } else {
5156      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
5157      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5158          (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5159          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5160          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5161        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5162        uint32_t offset_ = abs(offset);
5163        EmitA32(0x014000d0U | (cond.GetCondition() << 28) |
5164                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5165                ((offset_ & 0xf0) << 4) | (sign << 23));
5166        return;
5167      }
5168      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
5169      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5170          (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5171          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5172          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5173        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5174        uint32_t offset_ = abs(offset);
5175        EmitA32(0x004000d0U | (cond.GetCondition() << 28) |
5176                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5177                ((offset_ & 0xf0) << 4) | (sign << 23));
5178        return;
5179      }
5180      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
5181      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5182          (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5183          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5184          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5185        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5186        uint32_t offset_ = abs(offset);
5187        EmitA32(0x016000d0U | (cond.GetCondition() << 28) |
5188                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5189                ((offset_ & 0xf0) << 4) | (sign << 23));
5190        return;
5191      }
5192      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1
5193      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5194          (offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5195          operand.IsOffset() && cond.IsNotNever() &&
5196          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5197        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5198        uint32_t offset_ = abs(offset);
5199        EmitA32(0x014f00d0U | (cond.GetCondition() << 28) |
5200                (rt.GetCode() << 12) | (offset_ & 0xf) |
5201                ((offset_ & 0xf0) << 4) | (sign << 23));
5202        return;
5203      }
5204    }
5205  }
5206  if (operand.IsPlainRegister()) {
5207    Register rn = operand.GetBaseRegister();
5208    Sign sign = operand.GetSign();
5209    Register rm = operand.GetOffsetRegister();
5210    if (IsUsingA32()) {
5211      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
5212      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5213          operand.IsOffset() && cond.IsNotNever() &&
5214          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5215        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5216        EmitA32(0x010000d0U | (cond.GetCondition() << 28) |
5217                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5218                (sign_ << 23));
5219        return;
5220      }
5221      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
5222      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5223          operand.IsPostIndex() && cond.IsNotNever() &&
5224          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5225        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5226        EmitA32(0x000000d0U | (cond.GetCondition() << 28) |
5227                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5228                (sign_ << 23));
5229        return;
5230      }
5231      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
5232      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5233          operand.IsPreIndex() && cond.IsNotNever() &&
5234          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5235        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5236        EmitA32(0x012000d0U | (cond.GetCondition() << 28) |
5237                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5238                (sign_ << 23));
5239        return;
5240      }
5241    }
5242  }
5243  Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand);
5244}
5245
5246void Assembler::ldrd(Condition cond, Register rt, Register rt2, Label* label) {
5247  VIXL_ASSERT(AllowAssembler());
5248  CheckIT(cond);
5249  Label::Offset offset =
5250      label->IsBound()
5251          ? label->GetLocation() -
5252                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5253          : 0;
5254  if (IsUsingT32()) {
5255    // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
5256    if (((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
5257          ((offset & 0x3) == 0)) ||
5258         !label->IsBound())) {
5259      static class EmitOp : public Label::LabelEmitOperator {
5260       public:
5261        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
5262        virtual uint32_t Encode(uint32_t instr,
5263                                Label::Offset pc,
5264                                const Label* label) const VIXL_OVERRIDE {
5265          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5266          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
5267                      ((offset & 0x3) == 0));
5268          int32_t target = offset >> 2;
5269          uint32_t U = (target >= 0) && !label->IsMinusZero();
5270          target = abs(target) | (U << 8);
5271          return instr | (target & 0xff) | ((target & 0x100) << 15);
5272        }
5273      } immop;
5274      EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8),
5275                      label,
5276                      immop));
5277      AdvanceIT();
5278      return;
5279    }
5280  } else {
5281    // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
5282    if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5283        ((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5284         !label->IsBound()) &&
5285        cond.IsNotNever() &&
5286        ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5287      static class EmitOp : public Label::LabelEmitOperator {
5288       public:
5289        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5290        virtual uint32_t Encode(uint32_t instr,
5291                                Label::Offset pc,
5292                                const Label* label) const VIXL_OVERRIDE {
5293          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5294          VIXL_ASSERT((offset >= -255) && (offset <= 255));
5295          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5296          int32_t target = abs(offset) | (U << 8);
5297          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5298                 ((target & 0x100) << 15);
5299        }
5300      } immop;
5301      EmitA32(
5302          Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5303               label,
5304               immop));
5305      return;
5306    }
5307  }
5308  Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, label);
5309}
5310
5311void Assembler::ldrex(Condition cond, Register rt, const MemOperand& operand) {
5312  VIXL_ASSERT(AllowAssembler());
5313  CheckIT(cond);
5314  if (operand.IsImmediate()) {
5315    Register rn = operand.GetBaseRegister();
5316    int32_t offset = operand.GetOffsetImmediate();
5317    if (IsUsingT32()) {
5318      // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1
5319      if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
5320          operand.IsOffset()) {
5321        int32_t offset_ = offset >> 2;
5322        EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5323                   (offset_ & 0xff));
5324        AdvanceIT();
5325        return;
5326      }
5327    } else {
5328      // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1
5329      if ((offset == 0) && operand.IsOffset() && cond.IsNotNever()) {
5330        EmitA32(0x01900f9fU | (cond.GetCondition() << 28) |
5331                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5332        return;
5333      }
5334    }
5335  }
5336  Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand);
5337}
5338
5339void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) {
5340  VIXL_ASSERT(AllowAssembler());
5341  CheckIT(cond);
5342  if (operand.IsImmediateZero()) {
5343    Register rn = operand.GetBaseRegister();
5344    if (IsUsingT32()) {
5345      // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
5346      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
5347        EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5348        AdvanceIT();
5349        return;
5350      }
5351    } else {
5352      // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
5353      if (operand.IsOffset() && cond.IsNotNever() &&
5354          (!rn.IsPC() || AllowUnpredictable())) {
5355        EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) |
5356                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5357        return;
5358      }
5359    }
5360  }
5361  Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand);
5362}
5363
5364void Assembler::ldrexd(Condition cond,
5365                       Register rt,
5366                       Register rt2,
5367                       const MemOperand& operand) {
5368  VIXL_ASSERT(AllowAssembler());
5369  CheckIT(cond);
5370  if (operand.IsImmediateZero()) {
5371    Register rn = operand.GetBaseRegister();
5372    if (IsUsingT32()) {
5373      // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
5374      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
5375        EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5376                   (rn.GetCode() << 16));
5377        AdvanceIT();
5378        return;
5379      }
5380    } else {
5381      // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
5382      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5383          operand.IsOffset() && cond.IsNotNever() &&
5384          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
5385           AllowUnpredictable())) {
5386        EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) |
5387                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5388        return;
5389      }
5390    }
5391  }
5392  Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand);
5393}
5394
5395void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) {
5396  VIXL_ASSERT(AllowAssembler());
5397  CheckIT(cond);
5398  if (operand.IsImmediateZero()) {
5399    Register rn = operand.GetBaseRegister();
5400    if (IsUsingT32()) {
5401      // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
5402      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
5403        EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5404        AdvanceIT();
5405        return;
5406      }
5407    } else {
5408      // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
5409      if (operand.IsOffset() && cond.IsNotNever() &&
5410          (!rn.IsPC() || AllowUnpredictable())) {
5411        EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) |
5412                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5413        return;
5414      }
5415    }
5416  }
5417  Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand);
5418}
5419
5420void Assembler::ldrh(Condition cond,
5421                     EncodingSize size,
5422                     Register rt,
5423                     const MemOperand& operand) {
5424  VIXL_ASSERT(AllowAssembler());
5425  CheckIT(cond);
5426  if (operand.IsImmediate()) {
5427    Register rn = operand.GetBaseRegister();
5428    int32_t offset = operand.GetOffsetImmediate();
5429    if (IsUsingT32()) {
5430      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5431      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
5432          (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
5433        int32_t offset_ = offset >> 1;
5434        EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) |
5435                   ((offset_ & 0x1f) << 6));
5436        AdvanceIT();
5437        return;
5438      }
5439      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
5440      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5441          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5442        EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5443                   (offset & 0xfff));
5444        AdvanceIT();
5445        return;
5446      }
5447      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
5448      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5449          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5450        EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5451                   (-offset & 0xff));
5452        AdvanceIT();
5453        return;
5454      }
5455      // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
5456      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5457          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5458        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5459        uint32_t offset_ = abs(offset);
5460        EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5461                   offset_ | (sign << 9));
5462        AdvanceIT();
5463        return;
5464      }
5465      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
5466      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5467          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5468        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5469        uint32_t offset_ = abs(offset);
5470        EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5471                   offset_ | (sign << 9));
5472        AdvanceIT();
5473        return;
5474      }
5475      // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5476      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5477          rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5478        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5479        uint32_t offset_ = abs(offset);
5480        EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5481        AdvanceIT();
5482        return;
5483      }
5484    } else {
5485      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
5486      if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5487          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5488        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5489        uint32_t offset_ = abs(offset);
5490        EmitA32(0x015000b0U | (cond.GetCondition() << 28) |
5491                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5492                ((offset_ & 0xf0) << 4) | (sign << 23));
5493        return;
5494      }
5495      // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
5496      if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5497          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5498        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5499        uint32_t offset_ = abs(offset);
5500        EmitA32(0x005000b0U | (cond.GetCondition() << 28) |
5501                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5502                ((offset_ & 0xf0) << 4) | (sign << 23));
5503        return;
5504      }
5505      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
5506      if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5507          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5508        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5509        uint32_t offset_ = abs(offset);
5510        EmitA32(0x017000b0U | (cond.GetCondition() << 28) |
5511                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5512                ((offset_ & 0xf0) << 4) | (sign << 23));
5513        return;
5514      }
5515      // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5516      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5517          operand.IsOffset() && cond.IsNotNever()) {
5518        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5519        uint32_t offset_ = abs(offset);
5520        EmitA32(0x015f00b0U | (cond.GetCondition() << 28) |
5521                (rt.GetCode() << 12) | (offset_ & 0xf) |
5522                ((offset_ & 0xf0) << 4) | (sign << 23));
5523        return;
5524      }
5525    }
5526  }
5527  if (operand.IsPlainRegister()) {
5528    Register rn = operand.GetBaseRegister();
5529    Sign sign = operand.GetSign();
5530    Register rm = operand.GetOffsetRegister();
5531    if (IsUsingT32()) {
5532      // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5533      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5534          sign.IsPlus() && operand.IsOffset()) {
5535        EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) |
5536                   (rm.GetCode() << 6));
5537        AdvanceIT();
5538        return;
5539      }
5540    } else {
5541      // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5542      if (operand.IsOffset() && cond.IsNotNever()) {
5543        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5544        EmitA32(0x011000b0U | (cond.GetCondition() << 28) |
5545                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5546                (sign_ << 23));
5547        return;
5548      }
5549      // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5550      if (operand.IsPostIndex() && cond.IsNotNever()) {
5551        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5552        EmitA32(0x001000b0U | (cond.GetCondition() << 28) |
5553                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5554                (sign_ << 23));
5555        return;
5556      }
5557      // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5558      if (operand.IsPreIndex() && cond.IsNotNever()) {
5559        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5560        EmitA32(0x013000b0U | (cond.GetCondition() << 28) |
5561                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5562                (sign_ << 23));
5563        return;
5564      }
5565    }
5566  }
5567  if (operand.IsShiftedRegister()) {
5568    Register rn = operand.GetBaseRegister();
5569    Sign sign = operand.GetSign();
5570    Register rm = operand.GetOffsetRegister();
5571    Shift shift = operand.GetShift();
5572    uint32_t amount = operand.GetShiftAmount();
5573    if (IsUsingT32()) {
5574      // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5575      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5576          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5577        EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5578                   rm.GetCode() | (amount << 4));
5579        AdvanceIT();
5580        return;
5581      }
5582    }
5583  }
5584  Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand);
5585}
5586
5587void Assembler::ldrh(Condition cond, Register rt, Label* label) {
5588  VIXL_ASSERT(AllowAssembler());
5589  CheckIT(cond);
5590  Label::Offset offset =
5591      label->IsBound()
5592          ? label->GetLocation() -
5593                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5594          : 0;
5595  if (IsUsingT32()) {
5596    // LDRH{<c>}{<q>} <Rt>, <label> ; T1
5597    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5598         !label->IsBound()) &&
5599        !rt.Is(pc)) {
5600      static class EmitOp : public Label::LabelEmitOperator {
5601       public:
5602        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5603        virtual uint32_t Encode(uint32_t instr,
5604                                Label::Offset pc,
5605                                const Label* label) const VIXL_OVERRIDE {
5606          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5607          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5608          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5609          int32_t target = abs(offset) | (U << 12);
5610          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5611        }
5612      } immop;
5613      EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12), label, immop));
5614      AdvanceIT();
5615      return;
5616    }
5617  } else {
5618    // LDRH{<c>}{<q>} <Rt>, <label> ; A1
5619    if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5620         !label->IsBound()) &&
5621        cond.IsNotNever()) {
5622      static class EmitOp : public Label::LabelEmitOperator {
5623       public:
5624        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5625        virtual uint32_t Encode(uint32_t instr,
5626                                Label::Offset pc,
5627                                const Label* label) const VIXL_OVERRIDE {
5628          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5629          VIXL_ASSERT((offset >= -255) && (offset <= 255));
5630          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5631          int32_t target = abs(offset) | (U << 8);
5632          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5633                 ((target & 0x100) << 15);
5634        }
5635      } immop;
5636      EmitA32(
5637          Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5638               label,
5639               immop));
5640      return;
5641    }
5642  }
5643  Delegate(kLdrh, &Assembler::ldrh, cond, rt, label);
5644}
5645
5646void Assembler::ldrsb(Condition cond,
5647                      EncodingSize size,
5648                      Register rt,
5649                      const MemOperand& operand) {
5650  VIXL_ASSERT(AllowAssembler());
5651  CheckIT(cond);
5652  if (operand.IsImmediate()) {
5653    Register rn = operand.GetBaseRegister();
5654    int32_t offset = operand.GetOffsetImmediate();
5655    if (IsUsingT32()) {
5656      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5657      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5658          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5659        EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5660                   (offset & 0xfff));
5661        AdvanceIT();
5662        return;
5663      }
5664      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
5665      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5666          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5667        EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5668                   (-offset & 0xff));
5669        AdvanceIT();
5670        return;
5671      }
5672      // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
5673      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5674          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5675        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5676        uint32_t offset_ = abs(offset);
5677        EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5678                   offset_ | (sign << 9));
5679        AdvanceIT();
5680        return;
5681      }
5682      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
5683      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5684          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5685        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5686        uint32_t offset_ = abs(offset);
5687        EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5688                   offset_ | (sign << 9));
5689        AdvanceIT();
5690        return;
5691      }
5692      // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5693      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5694          rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5695        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5696        uint32_t offset_ = abs(offset);
5697        EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5698        AdvanceIT();
5699        return;
5700      }
5701    } else {
5702      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
5703      if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5704          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5705        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5706        uint32_t offset_ = abs(offset);
5707        EmitA32(0x015000d0U | (cond.GetCondition() << 28) |
5708                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5709                ((offset_ & 0xf0) << 4) | (sign << 23));
5710        return;
5711      }
5712      // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
5713      if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5714          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5715        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5716        uint32_t offset_ = abs(offset);
5717        EmitA32(0x005000d0U | (cond.GetCondition() << 28) |
5718                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5719                ((offset_ & 0xf0) << 4) | (sign << 23));
5720        return;
5721      }
5722      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
5723      if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5724          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5725        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5726        uint32_t offset_ = abs(offset);
5727        EmitA32(0x017000d0U | (cond.GetCondition() << 28) |
5728                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5729                ((offset_ & 0xf0) << 4) | (sign << 23));
5730        return;
5731      }
5732      // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5733      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5734          operand.IsOffset() && cond.IsNotNever()) {
5735        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5736        uint32_t offset_ = abs(offset);
5737        EmitA32(0x015f00d0U | (cond.GetCondition() << 28) |
5738                (rt.GetCode() << 12) | (offset_ & 0xf) |
5739                ((offset_ & 0xf0) << 4) | (sign << 23));
5740        return;
5741      }
5742    }
5743  }
5744  if (operand.IsPlainRegister()) {
5745    Register rn = operand.GetBaseRegister();
5746    Sign sign = operand.GetSign();
5747    Register rm = operand.GetOffsetRegister();
5748    if (IsUsingT32()) {
5749      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5750      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5751          sign.IsPlus() && operand.IsOffset()) {
5752        EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) |
5753                   (rm.GetCode() << 6));
5754        AdvanceIT();
5755        return;
5756      }
5757    } else {
5758      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5759      if (operand.IsOffset() && cond.IsNotNever()) {
5760        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5761        EmitA32(0x011000d0U | (cond.GetCondition() << 28) |
5762                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5763                (sign_ << 23));
5764        return;
5765      }
5766      // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5767      if (operand.IsPostIndex() && cond.IsNotNever()) {
5768        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5769        EmitA32(0x001000d0U | (cond.GetCondition() << 28) |
5770                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5771                (sign_ << 23));
5772        return;
5773      }
5774      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5775      if (operand.IsPreIndex() && cond.IsNotNever()) {
5776        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5777        EmitA32(0x013000d0U | (cond.GetCondition() << 28) |
5778                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5779                (sign_ << 23));
5780        return;
5781      }
5782    }
5783  }
5784  if (operand.IsShiftedRegister()) {
5785    Register rn = operand.GetBaseRegister();
5786    Sign sign = operand.GetSign();
5787    Register rm = operand.GetOffsetRegister();
5788    Shift shift = operand.GetShift();
5789    uint32_t amount = operand.GetShiftAmount();
5790    if (IsUsingT32()) {
5791      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5792      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5793          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5794        EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5795                   rm.GetCode() | (amount << 4));
5796        AdvanceIT();
5797        return;
5798      }
5799    }
5800  }
5801  Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand);
5802}
5803
5804void Assembler::ldrsb(Condition cond, Register rt, Label* label) {
5805  VIXL_ASSERT(AllowAssembler());
5806  CheckIT(cond);
5807  Label::Offset offset =
5808      label->IsBound()
5809          ? label->GetLocation() -
5810                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5811          : 0;
5812  if (IsUsingT32()) {
5813    // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
5814    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5815         !label->IsBound()) &&
5816        !rt.Is(pc)) {
5817      static class EmitOp : public Label::LabelEmitOperator {
5818       public:
5819        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5820        virtual uint32_t Encode(uint32_t instr,
5821                                Label::Offset pc,
5822                                const Label* label) const VIXL_OVERRIDE {
5823          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5824          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5825          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5826          int32_t target = abs(offset) | (U << 12);
5827          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5828        }
5829      } immop;
5830      EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12), label, immop));
5831      AdvanceIT();
5832      return;
5833    }
5834  } else {
5835    // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
5836    if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5837         !label->IsBound()) &&
5838        cond.IsNotNever()) {
5839      static class EmitOp : public Label::LabelEmitOperator {
5840       public:
5841        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5842        virtual uint32_t Encode(uint32_t instr,
5843                                Label::Offset pc,
5844                                const Label* label) const VIXL_OVERRIDE {
5845          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5846          VIXL_ASSERT((offset >= -255) && (offset <= 255));
5847          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5848          int32_t target = abs(offset) | (U << 8);
5849          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5850                 ((target & 0x100) << 15);
5851        }
5852      } immop;
5853      EmitA32(
5854          Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5855               label,
5856               immop));
5857      return;
5858    }
5859  }
5860  Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, label);
5861}
5862
5863void Assembler::ldrsh(Condition cond,
5864                      EncodingSize size,
5865                      Register rt,
5866                      const MemOperand& operand) {
5867  VIXL_ASSERT(AllowAssembler());
5868  CheckIT(cond);
5869  if (operand.IsImmediate()) {
5870    Register rn = operand.GetBaseRegister();
5871    int32_t offset = operand.GetOffsetImmediate();
5872    if (IsUsingT32()) {
5873      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5874      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5875          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5876        EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5877                   (offset & 0xfff));
5878        AdvanceIT();
5879        return;
5880      }
5881      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
5882      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5883          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5884        EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5885                   (-offset & 0xff));
5886        AdvanceIT();
5887        return;
5888      }
5889      // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
5890      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5891          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5892        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5893        uint32_t offset_ = abs(offset);
5894        EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5895                   offset_ | (sign << 9));
5896        AdvanceIT();
5897        return;
5898      }
5899      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
5900      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5901          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5902        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5903        uint32_t offset_ = abs(offset);
5904        EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5905                   offset_ | (sign << 9));
5906        AdvanceIT();
5907        return;
5908      }
5909      // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5910      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5911          rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5912        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5913        uint32_t offset_ = abs(offset);
5914        EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5915        AdvanceIT();
5916        return;
5917      }
5918    } else {
5919      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
5920      if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5921          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5922        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5923        uint32_t offset_ = abs(offset);
5924        EmitA32(0x015000f0U | (cond.GetCondition() << 28) |
5925                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5926                ((offset_ & 0xf0) << 4) | (sign << 23));
5927        return;
5928      }
5929      // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
5930      if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5931          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5932        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5933        uint32_t offset_ = abs(offset);
5934        EmitA32(0x005000f0U | (cond.GetCondition() << 28) |
5935                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5936                ((offset_ & 0xf0) << 4) | (sign << 23));
5937        return;
5938      }
5939      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
5940      if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5941          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5942        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5943        uint32_t offset_ = abs(offset);
5944        EmitA32(0x017000f0U | (cond.GetCondition() << 28) |
5945                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5946                ((offset_ & 0xf0) << 4) | (sign << 23));
5947        return;
5948      }
5949      // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5950      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5951          operand.IsOffset() && cond.IsNotNever()) {
5952        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5953        uint32_t offset_ = abs(offset);
5954        EmitA32(0x015f00f0U | (cond.GetCondition() << 28) |
5955                (rt.GetCode() << 12) | (offset_ & 0xf) |
5956                ((offset_ & 0xf0) << 4) | (sign << 23));
5957        return;
5958      }
5959    }
5960  }
5961  if (operand.IsPlainRegister()) {
5962    Register rn = operand.GetBaseRegister();
5963    Sign sign = operand.GetSign();
5964    Register rm = operand.GetOffsetRegister();
5965    if (IsUsingT32()) {
5966      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5967      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5968          sign.IsPlus() && operand.IsOffset()) {
5969        EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) |
5970                   (rm.GetCode() << 6));
5971        AdvanceIT();
5972        return;
5973      }
5974    } else {
5975      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5976      if (operand.IsOffset() && cond.IsNotNever()) {
5977        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5978        EmitA32(0x011000f0U | (cond.GetCondition() << 28) |
5979                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5980                (sign_ << 23));
5981        return;
5982      }
5983      // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5984      if (operand.IsPostIndex() && cond.IsNotNever()) {
5985        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5986        EmitA32(0x001000f0U | (cond.GetCondition() << 28) |
5987                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5988                (sign_ << 23));
5989        return;
5990      }
5991      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5992      if (operand.IsPreIndex() && cond.IsNotNever()) {
5993        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5994        EmitA32(0x013000f0U | (cond.GetCondition() << 28) |
5995                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5996                (sign_ << 23));
5997        return;
5998      }
5999    }
6000  }
6001  if (operand.IsShiftedRegister()) {
6002    Register rn = operand.GetBaseRegister();
6003    Sign sign = operand.GetSign();
6004    Register rm = operand.GetOffsetRegister();
6005    Shift shift = operand.GetShift();
6006    uint32_t amount = operand.GetShiftAmount();
6007    if (IsUsingT32()) {
6008      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
6009      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
6010          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
6011        EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6012                   rm.GetCode() | (amount << 4));
6013        AdvanceIT();
6014        return;
6015      }
6016    }
6017  }
6018  Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand);
6019}
6020
6021void Assembler::ldrsh(Condition cond, Register rt, Label* label) {
6022  VIXL_ASSERT(AllowAssembler());
6023  CheckIT(cond);
6024  Label::Offset offset =
6025      label->IsBound()
6026          ? label->GetLocation() -
6027                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
6028          : 0;
6029  if (IsUsingT32()) {
6030    // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
6031    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
6032         !label->IsBound()) &&
6033        !rt.Is(pc)) {
6034      static class EmitOp : public Label::LabelEmitOperator {
6035       public:
6036        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
6037        virtual uint32_t Encode(uint32_t instr,
6038                                Label::Offset pc,
6039                                const Label* label) const VIXL_OVERRIDE {
6040          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
6041          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
6042          uint32_t U = (offset >= 0) && !label->IsMinusZero();
6043          int32_t target = abs(offset) | (U << 12);
6044          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
6045        }
6046      } immop;
6047      EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12), label, immop));
6048      AdvanceIT();
6049      return;
6050    }
6051  } else {
6052    // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
6053    if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
6054         !label->IsBound()) &&
6055        cond.IsNotNever()) {
6056      static class EmitOp : public Label::LabelEmitOperator {
6057       public:
6058        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
6059        virtual uint32_t Encode(uint32_t instr,
6060                                Label::Offset pc,
6061                                const Label* label) const VIXL_OVERRIDE {
6062          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
6063          VIXL_ASSERT((offset >= -255) && (offset <= 255));
6064          uint32_t U = (offset >= 0) && !label->IsMinusZero();
6065          int32_t target = abs(offset) | (U << 8);
6066          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
6067                 ((target & 0x100) << 15);
6068        }
6069      } immop;
6070      EmitA32(
6071          Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
6072               label,
6073               immop));
6074      return;
6075    }
6076  }
6077  Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, label);
6078}
6079
6080void Assembler::lsl(Condition cond,
6081                    EncodingSize size,
6082                    Register rd,
6083                    Register rm,
6084                    const Operand& operand) {
6085  VIXL_ASSERT(AllowAssembler());
6086  CheckIT(cond);
6087  if (operand.IsImmediate()) {
6088    uint32_t imm = operand.GetImmediate();
6089    if (IsUsingT32()) {
6090      // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6091      if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6092          (imm >= 1) && (imm <= 31)) {
6093        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6094        AdvanceIT();
6095        return;
6096      }
6097      // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6098      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
6099        EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6100                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6101        AdvanceIT();
6102        return;
6103      }
6104    } else {
6105      // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6106      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6107        EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
6108                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6109        return;
6110      }
6111    }
6112  }
6113  if (operand.IsPlainRegister()) {
6114    Register rs = operand.GetBaseRegister();
6115    if (IsUsingT32()) {
6116      // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6117      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6118          rs.IsLow()) {
6119        EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6120        AdvanceIT();
6121        return;
6122      }
6123      // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6124      if (!size.IsNarrow()) {
6125        EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6126                   rs.GetCode());
6127        AdvanceIT();
6128        return;
6129      }
6130    } else {
6131      // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6132      if (cond.IsNotNever()) {
6133        EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
6134                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6135        return;
6136      }
6137    }
6138  }
6139  Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand);
6140}
6141
6142void Assembler::lsls(Condition cond,
6143                     EncodingSize size,
6144                     Register rd,
6145                     Register rm,
6146                     const Operand& operand) {
6147  VIXL_ASSERT(AllowAssembler());
6148  CheckIT(cond);
6149  if (operand.IsImmediate()) {
6150    uint32_t imm = operand.GetImmediate();
6151    if (IsUsingT32()) {
6152      // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6153      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6154          (imm >= 1) && (imm <= 31)) {
6155        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6156        AdvanceIT();
6157        return;
6158      }
6159      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6160      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
6161        EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6162                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6163        AdvanceIT();
6164        return;
6165      }
6166    } else {
6167      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6168      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6169        EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
6170                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6171        return;
6172      }
6173    }
6174  }
6175  if (operand.IsPlainRegister()) {
6176    Register rs = operand.GetBaseRegister();
6177    if (IsUsingT32()) {
6178      // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6179      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6180          rs.IsLow()) {
6181        EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6182        AdvanceIT();
6183        return;
6184      }
6185      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6186      if (!size.IsNarrow()) {
6187        EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6188                   rs.GetCode());
6189        AdvanceIT();
6190        return;
6191      }
6192    } else {
6193      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6194      if (cond.IsNotNever()) {
6195        EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
6196                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6197        return;
6198      }
6199    }
6200  }
6201  Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand);
6202}
6203
6204void Assembler::lsr(Condition cond,
6205                    EncodingSize size,
6206                    Register rd,
6207                    Register rm,
6208                    const Operand& operand) {
6209  VIXL_ASSERT(AllowAssembler());
6210  CheckIT(cond);
6211  if (operand.IsImmediate()) {
6212    uint32_t imm = operand.GetImmediate();
6213    if (IsUsingT32()) {
6214      // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6215      if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6216          (imm >= 1) && (imm <= 32)) {
6217        uint32_t amount_ = imm % 32;
6218        EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6219                   (amount_ << 6));
6220        AdvanceIT();
6221        return;
6222      }
6223      // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6224      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
6225        uint32_t amount_ = imm % 32;
6226        EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6227                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6228        AdvanceIT();
6229        return;
6230      }
6231    } else {
6232      // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6233      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6234        uint32_t amount_ = imm % 32;
6235        EmitA32(0x01a00020U | (cond.GetCondition() << 28) |
6236                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6237        return;
6238      }
6239    }
6240  }
6241  if (operand.IsPlainRegister()) {
6242    Register rs = operand.GetBaseRegister();
6243    if (IsUsingT32()) {
6244      // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6245      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6246          rs.IsLow()) {
6247        EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6248        AdvanceIT();
6249        return;
6250      }
6251      // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6252      if (!size.IsNarrow()) {
6253        EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6254                   rs.GetCode());
6255        AdvanceIT();
6256        return;
6257      }
6258    } else {
6259      // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6260      if (cond.IsNotNever()) {
6261        EmitA32(0x01a00030U | (cond.GetCondition() << 28) |
6262                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6263        return;
6264      }
6265    }
6266  }
6267  Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand);
6268}
6269
6270void Assembler::lsrs(Condition cond,
6271                     EncodingSize size,
6272                     Register rd,
6273                     Register rm,
6274                     const Operand& operand) {
6275  VIXL_ASSERT(AllowAssembler());
6276  CheckIT(cond);
6277  if (operand.IsImmediate()) {
6278    uint32_t imm = operand.GetImmediate();
6279    if (IsUsingT32()) {
6280      // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6281      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6282          (imm >= 1) && (imm <= 32)) {
6283        uint32_t amount_ = imm % 32;
6284        EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6285                   (amount_ << 6));
6286        AdvanceIT();
6287        return;
6288      }
6289      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6290      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
6291        uint32_t amount_ = imm % 32;
6292        EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6293                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6294        AdvanceIT();
6295        return;
6296      }
6297    } else {
6298      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6299      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6300        uint32_t amount_ = imm % 32;
6301        EmitA32(0x01b00020U | (cond.GetCondition() << 28) |
6302                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6303        return;
6304      }
6305    }
6306  }
6307  if (operand.IsPlainRegister()) {
6308    Register rs = operand.GetBaseRegister();
6309    if (IsUsingT32()) {
6310      // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6311      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6312          rs.IsLow()) {
6313        EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6314        AdvanceIT();
6315        return;
6316      }
6317      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6318      if (!size.IsNarrow()) {
6319        EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6320                   rs.GetCode());
6321        AdvanceIT();
6322        return;
6323      }
6324    } else {
6325      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6326      if (cond.IsNotNever()) {
6327        EmitA32(0x01b00030U | (cond.GetCondition() << 28) |
6328                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6329        return;
6330      }
6331    }
6332  }
6333  Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand);
6334}
6335
6336void Assembler::mla(
6337    Condition cond, Register rd, Register rn, Register rm, Register ra) {
6338  VIXL_ASSERT(AllowAssembler());
6339  CheckIT(cond);
6340  if (IsUsingT32()) {
6341    // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
6342    if (!ra.Is(pc)) {
6343      EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6344                 rm.GetCode() | (ra.GetCode() << 12));
6345      AdvanceIT();
6346      return;
6347    }
6348  } else {
6349    // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6350    if (cond.IsNotNever()) {
6351      EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6352              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6353      return;
6354    }
6355  }
6356  Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra);
6357}
6358
6359void Assembler::mlas(
6360    Condition cond, Register rd, Register rn, Register rm, Register ra) {
6361  VIXL_ASSERT(AllowAssembler());
6362  CheckIT(cond);
6363  if (IsUsingA32()) {
6364    // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6365    if (cond.IsNotNever()) {
6366      EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6367              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6368      return;
6369    }
6370  }
6371  Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra);
6372}
6373
6374void Assembler::mls(
6375    Condition cond, Register rd, Register rn, Register rm, Register ra) {
6376  VIXL_ASSERT(AllowAssembler());
6377  CheckIT(cond);
6378  if (IsUsingT32()) {
6379    // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
6380    EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6381               rm.GetCode() | (ra.GetCode() << 12));
6382    AdvanceIT();
6383    return;
6384  } else {
6385    // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6386    if (cond.IsNotNever()) {
6387      EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6388              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6389      return;
6390    }
6391  }
6392  Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra);
6393}
6394
6395void Assembler::mov(Condition cond,
6396                    EncodingSize size,
6397                    Register rd,
6398                    const Operand& operand) {
6399  VIXL_ASSERT(AllowAssembler());
6400  CheckIT(cond);
6401  if (operand.IsImmediateShiftedRegister()) {
6402    Register rm = operand.GetBaseRegister();
6403    if (operand.IsPlainRegister()) {
6404      if (IsUsingT32()) {
6405        // MOV{<c>}{<q>} <Rd>, <Rm> ; T1
6406        if (!size.IsWide() &&
6407            ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
6408             AllowUnpredictable())) {
6409          EmitT32_16(0x4600 | (rd.GetCode() & 0x7) |
6410                     ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
6411          AdvanceIT();
6412          return;
6413        }
6414      }
6415    }
6416    Shift shift = operand.GetShift();
6417    uint32_t amount = operand.GetShiftAmount();
6418    if (IsUsingT32()) {
6419      // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6420      if (InITBlock() && !size.IsWide() && rd.IsLow() &&
6421          shift.IsValidAmount(amount) && rm.IsLow() &&
6422          (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR)) &&
6423          ((!shift.Is(LSL) || (amount != 0)) || AllowUnpredictable())) {
6424        uint32_t amount_ = amount % 32;
6425        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
6426                   (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
6427        AdvanceIT();
6428        return;
6429      }
6430      // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
6431      if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
6432          ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6433        uint32_t amount_ = amount % 32;
6434        EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6435                   (operand.GetTypeEncodingValue() << 4) |
6436                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6437        AdvanceIT();
6438        return;
6439      }
6440    } else {
6441      // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6442      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6443        uint32_t amount_ = amount % 32;
6444        EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
6445                (rd.GetCode() << 12) | rm.GetCode() |
6446                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6447        return;
6448      }
6449    }
6450  }
6451  if (operand.IsRegisterShiftedRegister()) {
6452    Register rm = operand.GetBaseRegister();
6453    Shift shift = operand.GetShift();
6454    if (IsUsingT32()) {
6455      // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
6456      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6457          shift.IsASR() && operand.GetShiftRegister().IsLow()) {
6458        EmitT32_16(0x4100 | rd.GetCode() |
6459                   (operand.GetShiftRegister().GetCode() << 3));
6460        AdvanceIT();
6461        return;
6462      }
6463      // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
6464      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6465          shift.IsLSL() && operand.GetShiftRegister().IsLow()) {
6466        EmitT32_16(0x4080 | rd.GetCode() |
6467                   (operand.GetShiftRegister().GetCode() << 3));
6468        AdvanceIT();
6469        return;
6470      }
6471      // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
6472      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6473          shift.IsLSR() && operand.GetShiftRegister().IsLow()) {
6474        EmitT32_16(0x40c0 | rd.GetCode() |
6475                   (operand.GetShiftRegister().GetCode() << 3));
6476        AdvanceIT();
6477        return;
6478      }
6479      // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
6480      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6481          shift.IsROR() && operand.GetShiftRegister().IsLow()) {
6482        EmitT32_16(0x41c0 | rd.GetCode() |
6483                   (operand.GetShiftRegister().GetCode() << 3));
6484        AdvanceIT();
6485        return;
6486      }
6487      // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
6488      if (!size.IsNarrow() &&
6489          ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
6490           AllowUnpredictable())) {
6491        EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6492                   (shift.GetType() << 21) |
6493                   operand.GetShiftRegister().GetCode());
6494        AdvanceIT();
6495        return;
6496      }
6497    } else {
6498      // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6499      if (cond.IsNotNever() &&
6500          ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
6501           AllowUnpredictable())) {
6502        EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
6503                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6504                (operand.GetShiftRegister().GetCode() << 8));
6505        return;
6506      }
6507    }
6508  }
6509  if (operand.IsImmediate()) {
6510    uint32_t imm = operand.GetImmediate();
6511    if (IsUsingT32()) {
6512      ImmediateT32 immediate_t32(imm);
6513      // MOV<c>{<q>} <Rd>, #<imm8> ; T1
6514      if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
6515        EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
6516        AdvanceIT();
6517        return;
6518      }
6519      // MOV{<c>}{<q>} <Rd>, #<const> ; T2
6520      if (!size.IsNarrow() && immediate_t32.IsValid() &&
6521          (!rd.IsPC() || AllowUnpredictable())) {
6522        EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) |
6523                   (immediate_t32.GetEncodingValue() & 0xff) |
6524                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6525                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6526        AdvanceIT();
6527        return;
6528      }
6529      // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3
6530      if (!size.IsNarrow() && (imm <= 65535) &&
6531          (!rd.IsPC() || AllowUnpredictable())) {
6532        EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
6533                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6534                   ((imm & 0xf000) << 4));
6535        AdvanceIT();
6536        return;
6537      }
6538    } else {
6539      ImmediateA32 immediate_a32(imm);
6540      // MOV{<c>}{<q>} <Rd>, #<const> ; A1
6541      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6542        EmitA32(0x03a00000U | (cond.GetCondition() << 28) |
6543                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6544        return;
6545      }
6546      // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2
6547      if ((imm <= 65535) && cond.IsNotNever() &&
6548          (!rd.IsPC() || AllowUnpredictable())) {
6549        EmitA32(0x03000000U | (cond.GetCondition() << 28) |
6550                (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6551        return;
6552      }
6553    }
6554  }
6555  Delegate(kMov, &Assembler::mov, cond, size, rd, operand);
6556}
6557
6558void Assembler::movs(Condition cond,
6559                     EncodingSize size,
6560                     Register rd,
6561                     const Operand& operand) {
6562  VIXL_ASSERT(AllowAssembler());
6563  CheckIT(cond);
6564  if (operand.IsImmediateShiftedRegister()) {
6565    Register rm = operand.GetBaseRegister();
6566    Shift shift = operand.GetShift();
6567    uint32_t amount = operand.GetShiftAmount();
6568    if (IsUsingT32()) {
6569      // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6570      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() &&
6571          shift.IsValidAmount(amount) && rm.IsLow() &&
6572          (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) {
6573        uint32_t amount_ = amount % 32;
6574        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
6575                   (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
6576        AdvanceIT();
6577        return;
6578      }
6579      // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
6580      if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
6581          ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6582        uint32_t amount_ = amount % 32;
6583        EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6584                   (operand.GetTypeEncodingValue() << 4) |
6585                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6586        AdvanceIT();
6587        return;
6588      }
6589    } else {
6590      // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6591      if (shift.IsValidAmount(amount) && cond.IsNotNever() &&
6592          (!rd.IsPC() || AllowUnpredictable())) {
6593        uint32_t amount_ = amount % 32;
6594        EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
6595                (rd.GetCode() << 12) | rm.GetCode() |
6596                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6597        return;
6598      }
6599    }
6600  }
6601  if (operand.IsRegisterShiftedRegister()) {
6602    Register rm = operand.GetBaseRegister();
6603    Shift shift = operand.GetShift();
6604    if (IsUsingT32()) {
6605      // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
6606      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6607          shift.IsASR() && operand.GetShiftRegister().IsLow()) {
6608        EmitT32_16(0x4100 | rd.GetCode() |
6609                   (operand.GetShiftRegister().GetCode() << 3));
6610        AdvanceIT();
6611        return;
6612      }
6613      // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
6614      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6615          shift.IsLSL() && operand.GetShiftRegister().IsLow()) {
6616        EmitT32_16(0x4080 | rd.GetCode() |
6617                   (operand.GetShiftRegister().GetCode() << 3));
6618        AdvanceIT();
6619        return;
6620      }
6621      // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
6622      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6623          shift.IsLSR() && operand.GetShiftRegister().IsLow()) {
6624        EmitT32_16(0x40c0 | rd.GetCode() |
6625                   (operand.GetShiftRegister().GetCode() << 3));
6626        AdvanceIT();
6627        return;
6628      }
6629      // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
6630      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6631          shift.IsROR() && operand.GetShiftRegister().IsLow()) {
6632        EmitT32_16(0x41c0 | rd.GetCode() |
6633                   (operand.GetShiftRegister().GetCode() << 3));
6634        AdvanceIT();
6635        return;
6636      }
6637      // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
6638      if (!size.IsNarrow() &&
6639          ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
6640           AllowUnpredictable())) {
6641        EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6642                   (shift.GetType() << 21) |
6643                   operand.GetShiftRegister().GetCode());
6644        AdvanceIT();
6645        return;
6646      }
6647    } else {
6648      // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6649      if (cond.IsNotNever() &&
6650          ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
6651           AllowUnpredictable())) {
6652        EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
6653                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6654                (operand.GetShiftRegister().GetCode() << 8));
6655        return;
6656      }
6657    }
6658  }
6659  if (operand.IsImmediate()) {
6660    uint32_t imm = operand.GetImmediate();
6661    if (IsUsingT32()) {
6662      ImmediateT32 immediate_t32(imm);
6663      // MOVS{<q>} <Rd>, #<imm8> ; T1
6664      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
6665        EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
6666        AdvanceIT();
6667        return;
6668      }
6669      // MOVS{<c>}{<q>} <Rd>, #<const> ; T2
6670      if (!size.IsNarrow() && immediate_t32.IsValid() &&
6671          (!rd.IsPC() || AllowUnpredictable())) {
6672        EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) |
6673                   (immediate_t32.GetEncodingValue() & 0xff) |
6674                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6675                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6676        AdvanceIT();
6677        return;
6678      }
6679    } else {
6680      ImmediateA32 immediate_a32(imm);
6681      // MOVS{<c>}{<q>} <Rd>, #<const> ; A1
6682      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6683        EmitA32(0x03b00000U | (cond.GetCondition() << 28) |
6684                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6685        return;
6686      }
6687    }
6688  }
6689  Delegate(kMovs, &Assembler::movs, cond, size, rd, operand);
6690}
6691
6692void Assembler::movt(Condition cond, Register rd, const Operand& operand) {
6693  VIXL_ASSERT(AllowAssembler());
6694  CheckIT(cond);
6695  if (operand.IsImmediate()) {
6696    uint32_t imm = operand.GetImmediate();
6697    if (IsUsingT32()) {
6698      // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1
6699      if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
6700        EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) |
6701                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6702                   ((imm & 0xf000) << 4));
6703        AdvanceIT();
6704        return;
6705      }
6706    } else {
6707      // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1
6708      if ((imm <= 65535) && cond.IsNotNever() &&
6709          (!rd.IsPC() || AllowUnpredictable())) {
6710        EmitA32(0x03400000U | (cond.GetCondition() << 28) |
6711                (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6712        return;
6713      }
6714    }
6715  }
6716  Delegate(kMovt, &Assembler::movt, cond, rd, operand);
6717}
6718
6719void Assembler::movw(Condition cond, Register rd, const Operand& operand) {
6720  VIXL_ASSERT(AllowAssembler());
6721  CheckIT(cond);
6722  if (operand.IsImmediate()) {
6723    uint32_t imm = operand.GetImmediate();
6724    if (IsUsingT32()) {
6725      // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3
6726      if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
6727        EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
6728                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6729                   ((imm & 0xf000) << 4));
6730        AdvanceIT();
6731        return;
6732      }
6733    } else {
6734      // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2
6735      if ((imm <= 65535) && cond.IsNotNever() &&
6736          (!rd.IsPC() || AllowUnpredictable())) {
6737        EmitA32(0x03000000U | (cond.GetCondition() << 28) |
6738                (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6739        return;
6740      }
6741    }
6742  }
6743  Delegate(kMovw, &Assembler::movw, cond, rd, operand);
6744}
6745
6746void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) {
6747  VIXL_ASSERT(AllowAssembler());
6748  CheckIT(cond);
6749  if (IsUsingT32()) {
6750    // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1
6751    EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20));
6752    AdvanceIT();
6753    return;
6754  } else {
6755    // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1
6756    if (cond.IsNotNever()) {
6757      EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
6758              (spec_reg.GetReg() << 22));
6759      return;
6760    }
6761  }
6762  Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg);
6763}
6764
6765void Assembler::msr(Condition cond,
6766                    MaskedSpecialRegister spec_reg,
6767                    const Operand& operand) {
6768  VIXL_ASSERT(AllowAssembler());
6769  CheckIT(cond);
6770  if (operand.IsImmediate()) {
6771    uint32_t imm = operand.GetImmediate();
6772    if (IsUsingA32()) {
6773      ImmediateA32 immediate_a32(imm);
6774      // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1
6775      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6776        EmitA32(0x0320f000U | (cond.GetCondition() << 28) |
6777                ((spec_reg.GetReg() & 0xf) << 16) |
6778                ((spec_reg.GetReg() & 0x10) << 18) |
6779                immediate_a32.GetEncodingValue());
6780        return;
6781      }
6782    }
6783  }
6784  if (operand.IsPlainRegister()) {
6785    Register rn = operand.GetBaseRegister();
6786    if (IsUsingT32()) {
6787      // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1
6788      EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) |
6789                 ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16));
6790      AdvanceIT();
6791      return;
6792    } else {
6793      // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1
6794      if (cond.IsNotNever()) {
6795        EmitA32(0x0120f000U | (cond.GetCondition() << 28) |
6796                ((spec_reg.GetReg() & 0xf) << 16) |
6797                ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode());
6798        return;
6799      }
6800    }
6801  }
6802  Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand);
6803}
6804
6805void Assembler::mul(
6806    Condition cond, EncodingSize size, Register rd, Register rn, Register rm) {
6807  VIXL_ASSERT(AllowAssembler());
6808  CheckIT(cond);
6809  if (IsUsingT32()) {
6810    // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
6811    if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() &&
6812        rm.IsLow()) {
6813      EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
6814      AdvanceIT();
6815      return;
6816    }
6817    // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2
6818    if (!size.IsNarrow()) {
6819      EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6820                 rm.GetCode());
6821      AdvanceIT();
6822      return;
6823    }
6824  } else {
6825    // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
6826    if (cond.IsNotNever()) {
6827      EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6828              rn.GetCode() | (rm.GetCode() << 8));
6829      return;
6830    }
6831  }
6832  Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm);
6833}
6834
6835void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) {
6836  VIXL_ASSERT(AllowAssembler());
6837  CheckIT(cond);
6838  if (IsUsingT32()) {
6839    // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
6840    if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) {
6841      EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
6842      AdvanceIT();
6843      return;
6844    }
6845  } else {
6846    // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
6847    if (cond.IsNotNever()) {
6848      EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6849              rn.GetCode() | (rm.GetCode() << 8));
6850      return;
6851    }
6852  }
6853  Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm);
6854}
6855
6856void Assembler::mvn(Condition cond,
6857                    EncodingSize size,
6858                    Register rd,
6859                    const Operand& operand) {
6860  VIXL_ASSERT(AllowAssembler());
6861  CheckIT(cond);
6862  if (operand.IsImmediate()) {
6863    uint32_t imm = operand.GetImmediate();
6864    if (IsUsingT32()) {
6865      ImmediateT32 immediate_t32(imm);
6866      // MVN{<c>}{<q>} <Rd>, #<const> ; T1
6867      if (!size.IsNarrow() && immediate_t32.IsValid()) {
6868        EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) |
6869                   (immediate_t32.GetEncodingValue() & 0xff) |
6870                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6871                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6872        AdvanceIT();
6873        return;
6874      }
6875    } else {
6876      ImmediateA32 immediate_a32(imm);
6877      // MVN{<c>}{<q>} <Rd>, #<const> ; A1
6878      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6879        EmitA32(0x03e00000U | (cond.GetCondition() << 28) |
6880                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6881        return;
6882      }
6883    }
6884  }
6885  if (operand.IsImmediateShiftedRegister()) {
6886    Register rm = operand.GetBaseRegister();
6887    if (operand.IsPlainRegister()) {
6888      if (IsUsingT32()) {
6889        // MVN<c>{<q>} <Rd>, <Rm> ; T1
6890        if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
6891          EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
6892          AdvanceIT();
6893          return;
6894        }
6895      }
6896    }
6897    Shift shift = operand.GetShift();
6898    uint32_t amount = operand.GetShiftAmount();
6899    if (IsUsingT32()) {
6900      // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6901      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6902        uint32_t amount_ = amount % 32;
6903        EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6904                   (operand.GetTypeEncodingValue() << 4) |
6905                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6906        AdvanceIT();
6907        return;
6908      }
6909    } else {
6910      // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6911      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6912        uint32_t amount_ = amount % 32;
6913        EmitA32(0x01e00000U | (cond.GetCondition() << 28) |
6914                (rd.GetCode() << 12) | rm.GetCode() |
6915                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6916        return;
6917      }
6918    }
6919  }
6920  if (operand.IsRegisterShiftedRegister()) {
6921    Register rm = operand.GetBaseRegister();
6922    Shift shift = operand.GetShift();
6923    if (IsUsingA32()) {
6924      // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6925      if (cond.IsNotNever()) {
6926        EmitA32(0x01e00010U | (cond.GetCondition() << 28) |
6927                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6928                (operand.GetShiftRegister().GetCode() << 8));
6929        return;
6930      }
6931    }
6932  }
6933  Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand);
6934}
6935
6936void Assembler::mvns(Condition cond,
6937                     EncodingSize size,
6938                     Register rd,
6939                     const Operand& operand) {
6940  VIXL_ASSERT(AllowAssembler());
6941  CheckIT(cond);
6942  if (operand.IsImmediate()) {
6943    uint32_t imm = operand.GetImmediate();
6944    if (IsUsingT32()) {
6945      ImmediateT32 immediate_t32(imm);
6946      // MVNS{<c>}{<q>} <Rd>, #<const> ; T1
6947      if (!size.IsNarrow() && immediate_t32.IsValid()) {
6948        EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) |
6949                   (immediate_t32.GetEncodingValue() & 0xff) |
6950                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6951                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6952        AdvanceIT();
6953        return;
6954      }
6955    } else {
6956      ImmediateA32 immediate_a32(imm);
6957      // MVNS{<c>}{<q>} <Rd>, #<const> ; A1
6958      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6959        EmitA32(0x03f00000U | (cond.GetCondition() << 28) |
6960                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6961        return;
6962      }
6963    }
6964  }
6965  if (operand.IsImmediateShiftedRegister()) {
6966    Register rm = operand.GetBaseRegister();
6967    if (operand.IsPlainRegister()) {
6968      if (IsUsingT32()) {
6969        // MVNS{<q>} <Rd>, <Rm> ; T1
6970        if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
6971          EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
6972          AdvanceIT();
6973          return;
6974        }
6975      }
6976    }
6977    Shift shift = operand.GetShift();
6978    uint32_t amount = operand.GetShiftAmount();
6979    if (IsUsingT32()) {
6980      // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6981      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6982        uint32_t amount_ = amount % 32;
6983        EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6984                   (operand.GetTypeEncodingValue() << 4) |
6985                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6986        AdvanceIT();
6987        return;
6988      }
6989    } else {
6990      // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6991      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6992        uint32_t amount_ = amount % 32;
6993        EmitA32(0x01f00000U | (cond.GetCondition() << 28) |
6994                (rd.GetCode() << 12) | rm.GetCode() |
6995                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6996        return;
6997      }
6998    }
6999  }
7000  if (operand.IsRegisterShiftedRegister()) {
7001    Register rm = operand.GetBaseRegister();
7002    Shift shift = operand.GetShift();
7003    if (IsUsingA32()) {
7004      // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
7005      if (cond.IsNotNever()) {
7006        EmitA32(0x01f00010U | (cond.GetCondition() << 28) |
7007                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
7008                (operand.GetShiftRegister().GetCode() << 8));
7009        return;
7010      }
7011    }
7012  }
7013  Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand);
7014}
7015
7016void Assembler::nop(Condition cond, EncodingSize size) {
7017  VIXL_ASSERT(AllowAssembler());
7018  CheckIT(cond);
7019  if (IsUsingT32()) {
7020    // NOP{<c>}{<q>} ; T1
7021    if (!size.IsWide()) {
7022      EmitT32_16(0xbf00);
7023      AdvanceIT();
7024      return;
7025    }
7026    // NOP{<c>}.W ; T2
7027    if (!size.IsNarrow()) {
7028      EmitT32_32(0xf3af8000U);
7029      AdvanceIT();
7030      return;
7031    }
7032  } else {
7033    // NOP{<c>}{<q>} ; A1
7034    if (cond.IsNotNever()) {
7035      EmitA32(0x0320f000U | (cond.GetCondition() << 28));
7036      return;
7037    }
7038  }
7039  Delegate(kNop, &Assembler::nop, cond, size);
7040}
7041
7042void Assembler::orn(Condition cond,
7043                    Register rd,
7044                    Register rn,
7045                    const Operand& operand) {
7046  VIXL_ASSERT(AllowAssembler());
7047  CheckIT(cond);
7048  if (operand.IsImmediate()) {
7049    uint32_t imm = operand.GetImmediate();
7050    if (IsUsingT32()) {
7051      ImmediateT32 immediate_t32(imm);
7052      // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7053      if (immediate_t32.IsValid() && !rn.Is(pc)) {
7054        EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7055                   (immediate_t32.GetEncodingValue() & 0xff) |
7056                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7057                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7058        AdvanceIT();
7059        return;
7060      }
7061    }
7062  }
7063  if (operand.IsImmediateShiftedRegister()) {
7064    Register rm = operand.GetBaseRegister();
7065    Shift shift = operand.GetShift();
7066    uint32_t amount = operand.GetShiftAmount();
7067    if (IsUsingT32()) {
7068      // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
7069      if (shift.IsValidAmount(amount) && !rn.Is(pc)) {
7070        uint32_t amount_ = amount % 32;
7071        EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7072                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7073                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7074        AdvanceIT();
7075        return;
7076      }
7077    }
7078  }
7079  Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand);
7080}
7081
7082void Assembler::orns(Condition cond,
7083                     Register rd,
7084                     Register rn,
7085                     const Operand& operand) {
7086  VIXL_ASSERT(AllowAssembler());
7087  CheckIT(cond);
7088  if (operand.IsImmediate()) {
7089    uint32_t imm = operand.GetImmediate();
7090    if (IsUsingT32()) {
7091      ImmediateT32 immediate_t32(imm);
7092      // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7093      if (immediate_t32.IsValid() && !rn.Is(pc)) {
7094        EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7095                   (immediate_t32.GetEncodingValue() & 0xff) |
7096                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7097                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7098        AdvanceIT();
7099        return;
7100      }
7101    }
7102  }
7103  if (operand.IsImmediateShiftedRegister()) {
7104    Register rm = operand.GetBaseRegister();
7105    Shift shift = operand.GetShift();
7106    uint32_t amount = operand.GetShiftAmount();
7107    if (IsUsingT32()) {
7108      // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
7109      if (shift.IsValidAmount(amount) && !rn.Is(pc)) {
7110        uint32_t amount_ = amount % 32;
7111        EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7112                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7113                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7114        AdvanceIT();
7115        return;
7116      }
7117    }
7118  }
7119  Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand);
7120}
7121
7122void Assembler::orr(Condition cond,
7123                    EncodingSize size,
7124                    Register rd,
7125                    Register rn,
7126                    const Operand& operand) {
7127  VIXL_ASSERT(AllowAssembler());
7128  CheckIT(cond);
7129  if (operand.IsImmediate()) {
7130    uint32_t imm = operand.GetImmediate();
7131    if (IsUsingT32()) {
7132      ImmediateT32 immediate_t32(imm);
7133      // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7134      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) {
7135        EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7136                   (immediate_t32.GetEncodingValue() & 0xff) |
7137                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7138                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7139        AdvanceIT();
7140        return;
7141      }
7142    } else {
7143      ImmediateA32 immediate_a32(imm);
7144      // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7145      if (immediate_a32.IsValid() && cond.IsNotNever()) {
7146        EmitA32(0x03800000U | (cond.GetCondition() << 28) |
7147                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7148                immediate_a32.GetEncodingValue());
7149        return;
7150      }
7151    }
7152  }
7153  if (operand.IsImmediateShiftedRegister()) {
7154    Register rm = operand.GetBaseRegister();
7155    if (operand.IsPlainRegister()) {
7156      if (IsUsingT32()) {
7157        // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7158        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7159            rm.IsLow()) {
7160          EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7161          AdvanceIT();
7162          return;
7163        }
7164      }
7165    }
7166    Shift shift = operand.GetShift();
7167    uint32_t amount = operand.GetShiftAmount();
7168    if (IsUsingT32()) {
7169      // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7170      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) {
7171        uint32_t amount_ = amount % 32;
7172        EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7173                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7174                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7175        AdvanceIT();
7176        return;
7177      }
7178    } else {
7179      // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7180      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7181        uint32_t amount_ = amount % 32;
7182        EmitA32(0x01800000U | (cond.GetCondition() << 28) |
7183                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7184                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7185        return;
7186      }
7187    }
7188  }
7189  if (operand.IsRegisterShiftedRegister()) {
7190    Register rm = operand.GetBaseRegister();
7191    Shift shift = operand.GetShift();
7192    if (IsUsingA32()) {
7193      // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7194      if (cond.IsNotNever()) {
7195        EmitA32(0x01800010U | (cond.GetCondition() << 28) |
7196                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7197                (shift.GetType() << 5) |
7198                (operand.GetShiftRegister().GetCode() << 8));
7199        return;
7200      }
7201    }
7202  }
7203  Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand);
7204}
7205
7206void Assembler::orrs(Condition cond,
7207                     EncodingSize size,
7208                     Register rd,
7209                     Register rn,
7210                     const Operand& operand) {
7211  VIXL_ASSERT(AllowAssembler());
7212  CheckIT(cond);
7213  if (operand.IsImmediate()) {
7214    uint32_t imm = operand.GetImmediate();
7215    if (IsUsingT32()) {
7216      ImmediateT32 immediate_t32(imm);
7217      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7218      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) {
7219        EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7220                   (immediate_t32.GetEncodingValue() & 0xff) |
7221                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7222                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7223        AdvanceIT();
7224        return;
7225      }
7226    } else {
7227      ImmediateA32 immediate_a32(imm);
7228      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7229      if (immediate_a32.IsValid() && cond.IsNotNever()) {
7230        EmitA32(0x03900000U | (cond.GetCondition() << 28) |
7231                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7232                immediate_a32.GetEncodingValue());
7233        return;
7234      }
7235    }
7236  }
7237  if (operand.IsImmediateShiftedRegister()) {
7238    Register rm = operand.GetBaseRegister();
7239    if (operand.IsPlainRegister()) {
7240      if (IsUsingT32()) {
7241        // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7242        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7243            rm.IsLow()) {
7244          EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7245          AdvanceIT();
7246          return;
7247        }
7248      }
7249    }
7250    Shift shift = operand.GetShift();
7251    uint32_t amount = operand.GetShiftAmount();
7252    if (IsUsingT32()) {
7253      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7254      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) {
7255        uint32_t amount_ = amount % 32;
7256        EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7257                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7258                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7259        AdvanceIT();
7260        return;
7261      }
7262    } else {
7263      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7264      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7265        uint32_t amount_ = amount % 32;
7266        EmitA32(0x01900000U | (cond.GetCondition() << 28) |
7267                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7268                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7269        return;
7270      }
7271    }
7272  }
7273  if (operand.IsRegisterShiftedRegister()) {
7274    Register rm = operand.GetBaseRegister();
7275    Shift shift = operand.GetShift();
7276    if (IsUsingA32()) {
7277      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7278      if (cond.IsNotNever()) {
7279        EmitA32(0x01900010U | (cond.GetCondition() << 28) |
7280                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7281                (shift.GetType() << 5) |
7282                (operand.GetShiftRegister().GetCode() << 8));
7283        return;
7284      }
7285    }
7286  }
7287  Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand);
7288}
7289
7290void Assembler::pkhbt(Condition cond,
7291                      Register rd,
7292                      Register rn,
7293                      const Operand& operand) {
7294  VIXL_ASSERT(AllowAssembler());
7295  CheckIT(cond);
7296  if (operand.IsImmediateShiftedRegister()) {
7297    Register rm = operand.GetBaseRegister();
7298    Shift shift = operand.GetShift();
7299    uint32_t amount = operand.GetShiftAmount();
7300    if (IsUsingT32()) {
7301      // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1
7302      if (shift.IsLSL() && shift.IsValidAmount(amount)) {
7303        EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7304                   rm.GetCode() | ((amount & 0x3) << 6) |
7305                   ((amount & 0x1c) << 10));
7306        AdvanceIT();
7307        return;
7308      }
7309    } else {
7310      // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1
7311      if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever()) {
7312        EmitA32(0x06800010U | (cond.GetCondition() << 28) |
7313                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7314                (amount << 7));
7315        return;
7316      }
7317    }
7318  }
7319  Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand);
7320}
7321
7322void Assembler::pkhtb(Condition cond,
7323                      Register rd,
7324                      Register rn,
7325                      const Operand& operand) {
7326  VIXL_ASSERT(AllowAssembler());
7327  CheckIT(cond);
7328  if (operand.IsImmediateShiftedRegister()) {
7329    Register rm = operand.GetBaseRegister();
7330    Shift shift = operand.GetShift();
7331    uint32_t amount = operand.GetShiftAmount();
7332    if (IsUsingT32()) {
7333      // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1
7334      if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount)) {
7335        uint32_t amount_ = amount % 32;
7336        EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7337                   rm.GetCode() | ((amount_ & 0x3) << 6) |
7338                   ((amount_ & 0x1c) << 10));
7339        AdvanceIT();
7340        return;
7341      }
7342    } else {
7343      // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1
7344      if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
7345          cond.IsNotNever()) {
7346        uint32_t amount_ = amount % 32;
7347        EmitA32(0x06800050U | (cond.GetCondition() << 28) |
7348                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7349                (amount_ << 7));
7350        return;
7351      }
7352    }
7353  }
7354  Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand);
7355}
7356
7357void Assembler::pld(Condition cond, Label* label) {
7358  VIXL_ASSERT(AllowAssembler());
7359  CheckIT(cond);
7360  Label::Offset offset =
7361      label->IsBound()
7362          ? label->GetLocation() -
7363                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
7364          : 0;
7365  if (IsUsingT32()) {
7366    // PLD{<c>}{<q>} <label> ; T1
7367    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7368         !label->IsBound())) {
7369      static class EmitOp : public Label::LabelEmitOperator {
7370       public:
7371        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7372        virtual uint32_t Encode(uint32_t instr,
7373                                Label::Offset pc,
7374                                const Label* label) const VIXL_OVERRIDE {
7375          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7376          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7377          uint32_t U = (offset >= 0) && !label->IsMinusZero();
7378          int32_t target = abs(offset) | (U << 12);
7379          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7380        }
7381      } immop;
7382      EmitT32_32(Link(0xf81ff000U, label, immop));
7383      AdvanceIT();
7384      return;
7385    }
7386  } else {
7387    // PLD{<c>}{<q>} <label> ; A1
7388    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7389         !label->IsBound())) {
7390      if (cond.Is(al)) {
7391        static class EmitOp : public Label::LabelEmitOperator {
7392         public:
7393          EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7394          virtual uint32_t Encode(uint32_t instr,
7395                                  Label::Offset pc,
7396                                  const Label* label) const VIXL_OVERRIDE {
7397            Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7398            VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7399            uint32_t U = (offset >= 0) && !label->IsMinusZero();
7400            int32_t target = abs(offset) | (U << 12);
7401            return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7402          }
7403        } immop;
7404        EmitA32(Link(0xf55ff000U, label, immop));
7405        return;
7406      }
7407    }
7408  }
7409  Delegate(kPld, &Assembler::pld, cond, label);
7410}
7411
7412void Assembler::pld(Condition cond, const MemOperand& operand) {
7413  VIXL_ASSERT(AllowAssembler());
7414  CheckIT(cond);
7415  if (operand.IsImmediate()) {
7416    Register rn = operand.GetBaseRegister();
7417    int32_t offset = operand.GetOffsetImmediate();
7418    if (IsUsingT32()) {
7419      // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1
7420      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
7421          operand.IsOffset()) {
7422        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7423        uint32_t offset_ = abs(offset);
7424        EmitT32_32(0xf81ff000U | offset_ | (sign << 23));
7425        AdvanceIT();
7426        return;
7427      }
7428    } else {
7429      // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1
7430      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
7431          operand.IsOffset()) {
7432        if (cond.Is(al)) {
7433          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7434          uint32_t offset_ = abs(offset);
7435          EmitA32(0xf55ff000U | offset_ | (sign << 23));
7436          return;
7437        }
7438      }
7439    }
7440  }
7441  if (operand.IsImmediate()) {
7442    Register rn = operand.GetBaseRegister();
7443    int32_t offset = operand.GetOffsetImmediate();
7444    if (IsUsingT32()) {
7445      // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7446      if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
7447          ((rn.GetCode() & 0xf) != 0xf)) {
7448        EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7449        AdvanceIT();
7450        return;
7451      }
7452      // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7453      if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
7454          ((rn.GetCode() & 0xf) != 0xf)) {
7455        EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7456        AdvanceIT();
7457        return;
7458      }
7459    } else {
7460      // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
7461      if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
7462          ((rn.GetCode() & 0xf) != 0xf)) {
7463        if (cond.Is(al)) {
7464          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7465          uint32_t offset_ = abs(offset);
7466          EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7467          return;
7468        }
7469      }
7470    }
7471  }
7472  if (operand.IsShiftedRegister()) {
7473    Register rn = operand.GetBaseRegister();
7474    Sign sign = operand.GetSign();
7475    Register rm = operand.GetOffsetRegister();
7476    Shift shift = operand.GetShift();
7477    uint32_t amount = operand.GetShiftAmount();
7478    if (IsUsingT32()) {
7479      // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7480      if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
7481          ((rn.GetCode() & 0xf) != 0xf)) {
7482        EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() |
7483                   (amount << 4));
7484        AdvanceIT();
7485        return;
7486      }
7487    } else {
7488      // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7489      if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
7490        if (cond.Is(al)) {
7491          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7492          uint32_t amount_ = amount % 32;
7493          EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() |
7494                  (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7495          return;
7496        }
7497      }
7498      // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7499      if (shift.IsRRX() && operand.IsOffset()) {
7500        if (cond.Is(al)) {
7501          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7502          EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() |
7503                  (sign_ << 23));
7504          return;
7505        }
7506      }
7507    }
7508  }
7509  Delegate(kPld, &Assembler::pld, cond, operand);
7510}
7511
7512void Assembler::pldw(Condition cond, const MemOperand& operand) {
7513  VIXL_ASSERT(AllowAssembler());
7514  CheckIT(cond);
7515  if (operand.IsImmediate()) {
7516    Register rn = operand.GetBaseRegister();
7517    int32_t offset = operand.GetOffsetImmediate();
7518    if (IsUsingT32()) {
7519      // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7520      if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
7521          ((rn.GetCode() & 0xf) != 0xf)) {
7522        EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7523        AdvanceIT();
7524        return;
7525      }
7526      // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7527      if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
7528          ((rn.GetCode() & 0xf) != 0xf)) {
7529        EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7530        AdvanceIT();
7531        return;
7532      }
7533    } else {
7534      // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
7535      if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
7536          ((rn.GetCode() & 0xf) != 0xf)) {
7537        if (cond.Is(al)) {
7538          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7539          uint32_t offset_ = abs(offset);
7540          EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7541          return;
7542        }
7543      }
7544    }
7545  }
7546  if (operand.IsShiftedRegister()) {
7547    Register rn = operand.GetBaseRegister();
7548    Sign sign = operand.GetSign();
7549    Register rm = operand.GetOffsetRegister();
7550    Shift shift = operand.GetShift();
7551    uint32_t amount = operand.GetShiftAmount();
7552    if (IsUsingT32()) {
7553      // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7554      if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
7555          ((rn.GetCode() & 0xf) != 0xf)) {
7556        EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() |
7557                   (amount << 4));
7558        AdvanceIT();
7559        return;
7560      }
7561    } else {
7562      // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7563      if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
7564        if (cond.Is(al)) {
7565          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7566          uint32_t amount_ = amount % 32;
7567          EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() |
7568                  (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7569          return;
7570        }
7571      }
7572      // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7573      if (shift.IsRRX() && operand.IsOffset()) {
7574        if (cond.Is(al)) {
7575          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7576          EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() |
7577                  (sign_ << 23));
7578          return;
7579        }
7580      }
7581    }
7582  }
7583  Delegate(kPldw, &Assembler::pldw, cond, operand);
7584}
7585
7586void Assembler::pli(Condition cond, const MemOperand& operand) {
7587  VIXL_ASSERT(AllowAssembler());
7588  CheckIT(cond);
7589  if (operand.IsImmediate()) {
7590    Register rn = operand.GetBaseRegister();
7591    int32_t offset = operand.GetOffsetImmediate();
7592    if (IsUsingT32()) {
7593      // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7594      if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
7595          ((rn.GetCode() & 0xf) != 0xf)) {
7596        EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7597        AdvanceIT();
7598        return;
7599      }
7600      // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7601      if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
7602          ((rn.GetCode() & 0xf) != 0xf)) {
7603        EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7604        AdvanceIT();
7605        return;
7606      }
7607    } else {
7608      // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1
7609      if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
7610          ((rn.GetCode() & 0xf) != 0xf)) {
7611        if (cond.Is(al)) {
7612          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7613          uint32_t offset_ = abs(offset);
7614          EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7615          return;
7616        }
7617      }
7618    }
7619  }
7620  if (operand.IsImmediate()) {
7621    Register rn = operand.GetBaseRegister();
7622    int32_t offset = operand.GetOffsetImmediate();
7623    if (IsUsingT32()) {
7624      // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3
7625      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
7626          operand.IsOffset()) {
7627        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7628        uint32_t offset_ = abs(offset);
7629        EmitT32_32(0xf91ff000U | offset_ | (sign << 23));
7630        AdvanceIT();
7631        return;
7632      }
7633    } else {
7634      // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1
7635      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
7636          operand.IsOffset()) {
7637        if (cond.Is(al)) {
7638          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7639          uint32_t offset_ = abs(offset);
7640          EmitA32(0xf45ff000U | offset_ | (sign << 23));
7641          return;
7642        }
7643      }
7644    }
7645  }
7646  if (operand.IsShiftedRegister()) {
7647    Register rn = operand.GetBaseRegister();
7648    Sign sign = operand.GetSign();
7649    Register rm = operand.GetOffsetRegister();
7650    Shift shift = operand.GetShift();
7651    uint32_t amount = operand.GetShiftAmount();
7652    if (IsUsingT32()) {
7653      // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7654      if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
7655          ((rn.GetCode() & 0xf) != 0xf)) {
7656        EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() |
7657                   (amount << 4));
7658        AdvanceIT();
7659        return;
7660      }
7661    } else {
7662      // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7663      if (shift.IsRRX() && operand.IsOffset()) {
7664        if (cond.Is(al)) {
7665          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7666          EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() |
7667                  (sign_ << 23));
7668          return;
7669        }
7670      }
7671      // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7672      if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
7673        if (cond.Is(al)) {
7674          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7675          uint32_t amount_ = amount % 32;
7676          EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() |
7677                  (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7678          return;
7679        }
7680      }
7681    }
7682  }
7683  Delegate(kPli, &Assembler::pli, cond, operand);
7684}
7685
7686void Assembler::pli(Condition cond, Label* label) {
7687  VIXL_ASSERT(AllowAssembler());
7688  CheckIT(cond);
7689  Label::Offset offset =
7690      label->IsBound()
7691          ? label->GetLocation() -
7692                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
7693          : 0;
7694  if (IsUsingT32()) {
7695    // PLI{<c>}{<q>} <label> ; T3
7696    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7697         !label->IsBound())) {
7698      static class EmitOp : public Label::LabelEmitOperator {
7699       public:
7700        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7701        virtual uint32_t Encode(uint32_t instr,
7702                                Label::Offset pc,
7703                                const Label* label) const VIXL_OVERRIDE {
7704          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7705          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7706          uint32_t U = (offset >= 0) && !label->IsMinusZero();
7707          int32_t target = abs(offset) | (U << 12);
7708          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7709        }
7710      } immop;
7711      EmitT32_32(Link(0xf91ff000U, label, immop));
7712      AdvanceIT();
7713      return;
7714    }
7715  } else {
7716    // PLI{<c>}{<q>} <label> ; A1
7717    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7718         !label->IsBound())) {
7719      if (cond.Is(al)) {
7720        static class EmitOp : public Label::LabelEmitOperator {
7721         public:
7722          EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7723          virtual uint32_t Encode(uint32_t instr,
7724                                  Label::Offset pc,
7725                                  const Label* label) const VIXL_OVERRIDE {
7726            Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7727            VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7728            uint32_t U = (offset >= 0) && !label->IsMinusZero();
7729            int32_t target = abs(offset) | (U << 12);
7730            return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7731          }
7732        } immop;
7733        EmitA32(Link(0xf45ff000U, label, immop));
7734        return;
7735      }
7736    }
7737  }
7738  Delegate(kPli, &Assembler::pli, cond, label);
7739}
7740
7741void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) {
7742  VIXL_ASSERT(AllowAssembler());
7743  CheckIT(cond);
7744  if (IsUsingT32()) {
7745    // POP{<c>}{<q>} <registers> ; T1
7746    if (!size.IsWide() && ((registers.GetList() & ~0x80ff) == 0)) {
7747      EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
7748                 GetRegisterListEncoding(registers, 0, 8));
7749      AdvanceIT();
7750      return;
7751    }
7752    // POP{<c>}{<q>} <registers> ; T2
7753    if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
7754      EmitT32_32(0xe8bd0000U |
7755                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
7756                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
7757                 GetRegisterListEncoding(registers, 0, 13));
7758      AdvanceIT();
7759      return;
7760    }
7761  } else {
7762    // POP{<c>}{<q>} <registers> ; A1
7763    if (cond.IsNotNever()) {
7764      EmitA32(0x08bd0000U | (cond.GetCondition() << 28) |
7765              GetRegisterListEncoding(registers, 0, 16));
7766      return;
7767    }
7768  }
7769  Delegate(kPop, &Assembler::pop, cond, size, registers);
7770}
7771
7772void Assembler::pop(Condition cond, EncodingSize size, Register rt) {
7773  VIXL_ASSERT(AllowAssembler());
7774  CheckIT(cond);
7775  if (IsUsingT32()) {
7776    // POP{<c>}{<q>} <single_register_list> ; T4
7777    if (!size.IsNarrow() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) {
7778      EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12));
7779      AdvanceIT();
7780      return;
7781    }
7782  } else {
7783    // POP{<c>}{<q>} <single_register_list> ; A1
7784    if (cond.IsNotNever()) {
7785      EmitA32(0x049d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
7786      return;
7787    }
7788  }
7789  Delegate(kPop, &Assembler::pop, cond, size, rt);
7790}
7791
7792void Assembler::push(Condition cond,
7793                     EncodingSize size,
7794                     RegisterList registers) {
7795  VIXL_ASSERT(AllowAssembler());
7796  CheckIT(cond);
7797  if (IsUsingT32()) {
7798    // PUSH{<c>}{<q>} <registers> ; T1
7799    if (!size.IsWide() && ((registers.GetList() & ~0x40ff) == 0)) {
7800      EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
7801                 GetRegisterListEncoding(registers, 0, 8));
7802      AdvanceIT();
7803      return;
7804    }
7805    // PUSH{<c>}{<q>} <registers> ; T1
7806    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
7807      EmitT32_32(0xe92d0000U |
7808                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
7809                 GetRegisterListEncoding(registers, 0, 13));
7810      AdvanceIT();
7811      return;
7812    }
7813  } else {
7814    // PUSH{<c>}{<q>} <registers> ; A1
7815    if (cond.IsNotNever()) {
7816      EmitA32(0x092d0000U | (cond.GetCondition() << 28) |
7817              GetRegisterListEncoding(registers, 0, 16));
7818      return;
7819    }
7820  }
7821  Delegate(kPush, &Assembler::push, cond, size, registers);
7822}
7823
7824void Assembler::push(Condition cond, EncodingSize size, Register rt) {
7825  VIXL_ASSERT(AllowAssembler());
7826  CheckIT(cond);
7827  if (IsUsingT32()) {
7828    // PUSH{<c>}{<q>} <single_register_list> ; T4
7829    if (!size.IsNarrow()) {
7830      EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12));
7831      AdvanceIT();
7832      return;
7833    }
7834  } else {
7835    // PUSH{<c>}{<q>} <single_register_list> ; A1
7836    if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
7837      EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
7838      return;
7839    }
7840  }
7841  Delegate(kPush, &Assembler::push, cond, size, rt);
7842}
7843
7844void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) {
7845  VIXL_ASSERT(AllowAssembler());
7846  CheckIT(cond);
7847  if (IsUsingT32()) {
7848    // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7849    EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() |
7850               (rn.GetCode() << 16));
7851    AdvanceIT();
7852    return;
7853  } else {
7854    // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7855    if (cond.IsNotNever()) {
7856      EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7857              rm.GetCode() | (rn.GetCode() << 16));
7858      return;
7859    }
7860  }
7861  Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn);
7862}
7863
7864void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) {
7865  VIXL_ASSERT(AllowAssembler());
7866  CheckIT(cond);
7867  if (IsUsingT32()) {
7868    // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7869    EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7870               rm.GetCode());
7871    AdvanceIT();
7872    return;
7873  } else {
7874    // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7875    if (cond.IsNotNever()) {
7876      EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7877              (rn.GetCode() << 16) | rm.GetCode());
7878      return;
7879    }
7880  }
7881  Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm);
7882}
7883
7884void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) {
7885  VIXL_ASSERT(AllowAssembler());
7886  CheckIT(cond);
7887  if (IsUsingT32()) {
7888    // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7889    EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7890               rm.GetCode());
7891    AdvanceIT();
7892    return;
7893  } else {
7894    // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7895    if (cond.IsNotNever()) {
7896      EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7897              (rn.GetCode() << 16) | rm.GetCode());
7898      return;
7899    }
7900  }
7901  Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm);
7902}
7903
7904void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) {
7905  VIXL_ASSERT(AllowAssembler());
7906  CheckIT(cond);
7907  if (IsUsingT32()) {
7908    // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7909    EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7910               rm.GetCode());
7911    AdvanceIT();
7912    return;
7913  } else {
7914    // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7915    if (cond.IsNotNever()) {
7916      EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7917              (rn.GetCode() << 16) | rm.GetCode());
7918      return;
7919    }
7920  }
7921  Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm);
7922}
7923
7924void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) {
7925  VIXL_ASSERT(AllowAssembler());
7926  CheckIT(cond);
7927  if (IsUsingT32()) {
7928    // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7929    EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() |
7930               (rn.GetCode() << 16));
7931    AdvanceIT();
7932    return;
7933  } else {
7934    // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7935    if (cond.IsNotNever()) {
7936      EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7937              rm.GetCode() | (rn.GetCode() << 16));
7938      return;
7939    }
7940  }
7941  Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn);
7942}
7943
7944void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) {
7945  VIXL_ASSERT(AllowAssembler());
7946  CheckIT(cond);
7947  if (IsUsingT32()) {
7948    // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7949    EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
7950               (rn.GetCode() << 16));
7951    AdvanceIT();
7952    return;
7953  } else {
7954    // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7955    if (cond.IsNotNever()) {
7956      EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7957              rm.GetCode() | (rn.GetCode() << 16));
7958      return;
7959    }
7960  }
7961  Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn);
7962}
7963
7964void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) {
7965  VIXL_ASSERT(AllowAssembler());
7966  CheckIT(cond);
7967  if (IsUsingT32()) {
7968    // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7969    EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7970               rm.GetCode());
7971    AdvanceIT();
7972    return;
7973  } else {
7974    // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7975    if (cond.IsNotNever()) {
7976      EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7977              (rn.GetCode() << 16) | rm.GetCode());
7978      return;
7979    }
7980  }
7981  Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm);
7982}
7983
7984void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) {
7985  VIXL_ASSERT(AllowAssembler());
7986  CheckIT(cond);
7987  if (IsUsingT32()) {
7988    // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7989    EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
7990               (rn.GetCode() << 16));
7991    AdvanceIT();
7992    return;
7993  } else {
7994    // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7995    if (cond.IsNotNever()) {
7996      EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7997              rm.GetCode() | (rn.GetCode() << 16));
7998      return;
7999    }
8000  }
8001  Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn);
8002}
8003
8004void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) {
8005  VIXL_ASSERT(AllowAssembler());
8006  CheckIT(cond);
8007  if (IsUsingT32()) {
8008    // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8009    EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8010               rm.GetCode());
8011    AdvanceIT();
8012    return;
8013  } else {
8014    // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8015    if (cond.IsNotNever()) {
8016      EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8017              (rn.GetCode() << 16) | rm.GetCode());
8018      return;
8019    }
8020  }
8021  Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm);
8022}
8023
8024void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) {
8025  VIXL_ASSERT(AllowAssembler());
8026  CheckIT(cond);
8027  if (IsUsingT32()) {
8028    // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8029    EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8030               rm.GetCode());
8031    AdvanceIT();
8032    return;
8033  } else {
8034    // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8035    if (cond.IsNotNever()) {
8036      EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8037              (rn.GetCode() << 16) | rm.GetCode());
8038      return;
8039    }
8040  }
8041  Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm);
8042}
8043
8044void Assembler::rbit(Condition cond, Register rd, Register rm) {
8045  VIXL_ASSERT(AllowAssembler());
8046  CheckIT(cond);
8047  if (IsUsingT32()) {
8048    // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1
8049    EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
8050               (rm.GetCode() << 16));
8051    AdvanceIT();
8052    return;
8053  } else {
8054    // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1
8055    if (cond.IsNotNever()) {
8056      EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8057              rm.GetCode());
8058      return;
8059    }
8060  }
8061  Delegate(kRbit, &Assembler::rbit, cond, rd, rm);
8062}
8063
8064void Assembler::rev(Condition cond,
8065                    EncodingSize size,
8066                    Register rd,
8067                    Register rm) {
8068  VIXL_ASSERT(AllowAssembler());
8069  CheckIT(cond);
8070  if (IsUsingT32()) {
8071    // REV{<c>}{<q>} <Rd>, <Rm> ; T1
8072    if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8073      EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3));
8074      AdvanceIT();
8075      return;
8076    }
8077    // REV{<c>}{<q>} <Rd>, <Rm> ; T2
8078    if (!size.IsNarrow()) {
8079      EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() |
8080                 (rm.GetCode() << 16));
8081      AdvanceIT();
8082      return;
8083    }
8084  } else {
8085    // REV{<c>}{<q>} <Rd>, <Rm> ; A1
8086    if (cond.IsNotNever()) {
8087      EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8088              rm.GetCode());
8089      return;
8090    }
8091  }
8092  Delegate(kRev, &Assembler::rev, cond, size, rd, rm);
8093}
8094
8095void Assembler::rev16(Condition cond,
8096                      EncodingSize size,
8097                      Register rd,
8098                      Register rm) {
8099  VIXL_ASSERT(AllowAssembler());
8100  CheckIT(cond);
8101  if (IsUsingT32()) {
8102    // REV16{<c>}{<q>} <Rd>, <Rm> ; T1
8103    if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8104      EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3));
8105      AdvanceIT();
8106      return;
8107    }
8108    // REV16{<c>}{<q>} <Rd>, <Rm> ; T2
8109    if (!size.IsNarrow()) {
8110      EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() |
8111                 (rm.GetCode() << 16));
8112      AdvanceIT();
8113      return;
8114    }
8115  } else {
8116    // REV16{<c>}{<q>} <Rd>, <Rm> ; A1
8117    if (cond.IsNotNever()) {
8118      EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8119              rm.GetCode());
8120      return;
8121    }
8122  }
8123  Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm);
8124}
8125
8126void Assembler::revsh(Condition cond,
8127                      EncodingSize size,
8128                      Register rd,
8129                      Register rm) {
8130  VIXL_ASSERT(AllowAssembler());
8131  CheckIT(cond);
8132  if (IsUsingT32()) {
8133    // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1
8134    if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8135      EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3));
8136      AdvanceIT();
8137      return;
8138    }
8139    // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2
8140    if (!size.IsNarrow()) {
8141      EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
8142                 (rm.GetCode() << 16));
8143      AdvanceIT();
8144      return;
8145    }
8146  } else {
8147    // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1
8148    if (cond.IsNotNever()) {
8149      EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8150              rm.GetCode());
8151      return;
8152    }
8153  }
8154  Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm);
8155}
8156
8157void Assembler::ror(Condition cond,
8158                    EncodingSize size,
8159                    Register rd,
8160                    Register rm,
8161                    const Operand& operand) {
8162  VIXL_ASSERT(AllowAssembler());
8163  CheckIT(cond);
8164  if (operand.IsImmediate()) {
8165    uint32_t imm = operand.GetImmediate();
8166    if (IsUsingT32()) {
8167      // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
8168      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
8169        EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() |
8170                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
8171        AdvanceIT();
8172        return;
8173      }
8174    } else {
8175      // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
8176      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
8177        EmitA32(0x01a00060U | (cond.GetCondition() << 28) |
8178                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
8179        return;
8180      }
8181    }
8182  }
8183  if (operand.IsPlainRegister()) {
8184    Register rs = operand.GetBaseRegister();
8185    if (IsUsingT32()) {
8186      // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
8187      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
8188          rs.IsLow()) {
8189        EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
8190        AdvanceIT();
8191        return;
8192      }
8193      // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
8194      if (!size.IsNarrow()) {
8195        EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
8196                   rs.GetCode());
8197        AdvanceIT();
8198        return;
8199      }
8200    } else {
8201      // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
8202      if (cond.IsNotNever()) {
8203        EmitA32(0x01a00070U | (cond.GetCondition() << 28) |
8204                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
8205        return;
8206      }
8207    }
8208  }
8209  Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand);
8210}
8211
8212void Assembler::rors(Condition cond,
8213                     EncodingSize size,
8214                     Register rd,
8215                     Register rm,
8216                     const Operand& operand) {
8217  VIXL_ASSERT(AllowAssembler());
8218  CheckIT(cond);
8219  if (operand.IsImmediate()) {
8220    uint32_t imm = operand.GetImmediate();
8221    if (IsUsingT32()) {
8222      // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
8223      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
8224        EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() |
8225                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
8226        AdvanceIT();
8227        return;
8228      }
8229    } else {
8230      // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
8231      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
8232        EmitA32(0x01b00060U | (cond.GetCondition() << 28) |
8233                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
8234        return;
8235      }
8236    }
8237  }
8238  if (operand.IsPlainRegister()) {
8239    Register rs = operand.GetBaseRegister();
8240    if (IsUsingT32()) {
8241      // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
8242      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
8243          rs.IsLow()) {
8244        EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
8245        AdvanceIT();
8246        return;
8247      }
8248      // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
8249      if (!size.IsNarrow()) {
8250        EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
8251                   rs.GetCode());
8252        AdvanceIT();
8253        return;
8254      }
8255    } else {
8256      // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
8257      if (cond.IsNotNever()) {
8258        EmitA32(0x01b00070U | (cond.GetCondition() << 28) |
8259                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
8260        return;
8261      }
8262    }
8263  }
8264  Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand);
8265}
8266
8267void Assembler::rrx(Condition cond, Register rd, Register rm) {
8268  VIXL_ASSERT(AllowAssembler());
8269  CheckIT(cond);
8270  if (IsUsingT32()) {
8271    // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3
8272    EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode());
8273    AdvanceIT();
8274    return;
8275  } else {
8276    // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1
8277    if (cond.IsNotNever()) {
8278      EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8279              rm.GetCode());
8280      return;
8281    }
8282  }
8283  Delegate(kRrx, &Assembler::rrx, cond, rd, rm);
8284}
8285
8286void Assembler::rrxs(Condition cond, Register rd, Register rm) {
8287  VIXL_ASSERT(AllowAssembler());
8288  CheckIT(cond);
8289  if (IsUsingT32()) {
8290    // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3
8291    EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode());
8292    AdvanceIT();
8293    return;
8294  } else {
8295    // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1
8296    if (cond.IsNotNever()) {
8297      EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8298              rm.GetCode());
8299      return;
8300    }
8301  }
8302  Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm);
8303}
8304
8305void Assembler::rsb(Condition cond,
8306                    EncodingSize size,
8307                    Register rd,
8308                    Register rn,
8309                    const Operand& operand) {
8310  VIXL_ASSERT(AllowAssembler());
8311  CheckIT(cond);
8312  if (operand.IsImmediate()) {
8313    uint32_t imm = operand.GetImmediate();
8314    if (IsUsingT32()) {
8315      ImmediateT32 immediate_t32(imm);
8316      // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1
8317      if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
8318          (imm == 0)) {
8319        EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
8320        AdvanceIT();
8321        return;
8322      }
8323      // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
8324      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8325        EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8326                   (immediate_t32.GetEncodingValue() & 0xff) |
8327                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8328                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8329        AdvanceIT();
8330        return;
8331      }
8332    } else {
8333      ImmediateA32 immediate_a32(imm);
8334      // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8335      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8336        EmitA32(0x02600000U | (cond.GetCondition() << 28) |
8337                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8338                immediate_a32.GetEncodingValue());
8339        return;
8340      }
8341    }
8342  }
8343  if (operand.IsImmediateShiftedRegister()) {
8344    Register rm = operand.GetBaseRegister();
8345    Shift shift = operand.GetShift();
8346    uint32_t amount = operand.GetShiftAmount();
8347    if (IsUsingT32()) {
8348      // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
8349      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8350        uint32_t amount_ = amount % 32;
8351        EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8352                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8353                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8354        AdvanceIT();
8355        return;
8356      }
8357    } else {
8358      // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8359      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8360        uint32_t amount_ = amount % 32;
8361        EmitA32(0x00600000U | (cond.GetCondition() << 28) |
8362                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8363                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8364        return;
8365      }
8366    }
8367  }
8368  if (operand.IsRegisterShiftedRegister()) {
8369    Register rm = operand.GetBaseRegister();
8370    Shift shift = operand.GetShift();
8371    if (IsUsingA32()) {
8372      // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8373      if (cond.IsNotNever()) {
8374        EmitA32(0x00600010U | (cond.GetCondition() << 28) |
8375                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8376                (shift.GetType() << 5) |
8377                (operand.GetShiftRegister().GetCode() << 8));
8378        return;
8379      }
8380    }
8381  }
8382  Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand);
8383}
8384
8385void Assembler::rsbs(Condition cond,
8386                     EncodingSize size,
8387                     Register rd,
8388                     Register rn,
8389                     const Operand& operand) {
8390  VIXL_ASSERT(AllowAssembler());
8391  CheckIT(cond);
8392  if (operand.IsImmediate()) {
8393    uint32_t imm = operand.GetImmediate();
8394    if (IsUsingT32()) {
8395      ImmediateT32 immediate_t32(imm);
8396      // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1
8397      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
8398          (imm == 0)) {
8399        EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
8400        AdvanceIT();
8401        return;
8402      }
8403      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
8404      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8405        EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8406                   (immediate_t32.GetEncodingValue() & 0xff) |
8407                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8408                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8409        AdvanceIT();
8410        return;
8411      }
8412    } else {
8413      ImmediateA32 immediate_a32(imm);
8414      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8415      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8416        EmitA32(0x02700000U | (cond.GetCondition() << 28) |
8417                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8418                immediate_a32.GetEncodingValue());
8419        return;
8420      }
8421    }
8422  }
8423  if (operand.IsImmediateShiftedRegister()) {
8424    Register rm = operand.GetBaseRegister();
8425    Shift shift = operand.GetShift();
8426    uint32_t amount = operand.GetShiftAmount();
8427    if (IsUsingT32()) {
8428      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
8429      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8430        uint32_t amount_ = amount % 32;
8431        EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8432                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8433                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8434        AdvanceIT();
8435        return;
8436      }
8437    } else {
8438      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8439      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8440        uint32_t amount_ = amount % 32;
8441        EmitA32(0x00700000U | (cond.GetCondition() << 28) |
8442                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8443                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8444        return;
8445      }
8446    }
8447  }
8448  if (operand.IsRegisterShiftedRegister()) {
8449    Register rm = operand.GetBaseRegister();
8450    Shift shift = operand.GetShift();
8451    if (IsUsingA32()) {
8452      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8453      if (cond.IsNotNever()) {
8454        EmitA32(0x00700010U | (cond.GetCondition() << 28) |
8455                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8456                (shift.GetType() << 5) |
8457                (operand.GetShiftRegister().GetCode() << 8));
8458        return;
8459      }
8460    }
8461  }
8462  Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand);
8463}
8464
8465void Assembler::rsc(Condition cond,
8466                    Register rd,
8467                    Register rn,
8468                    const Operand& operand) {
8469  VIXL_ASSERT(AllowAssembler());
8470  CheckIT(cond);
8471  if (operand.IsImmediate()) {
8472    uint32_t imm = operand.GetImmediate();
8473    if (IsUsingA32()) {
8474      ImmediateA32 immediate_a32(imm);
8475      // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8476      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8477        EmitA32(0x02e00000U | (cond.GetCondition() << 28) |
8478                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8479                immediate_a32.GetEncodingValue());
8480        return;
8481      }
8482    }
8483  }
8484  if (operand.IsImmediateShiftedRegister()) {
8485    Register rm = operand.GetBaseRegister();
8486    Shift shift = operand.GetShift();
8487    uint32_t amount = operand.GetShiftAmount();
8488    if (IsUsingA32()) {
8489      // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8490      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8491        uint32_t amount_ = amount % 32;
8492        EmitA32(0x00e00000U | (cond.GetCondition() << 28) |
8493                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8494                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8495        return;
8496      }
8497    }
8498  }
8499  if (operand.IsRegisterShiftedRegister()) {
8500    Register rm = operand.GetBaseRegister();
8501    Shift shift = operand.GetShift();
8502    if (IsUsingA32()) {
8503      // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8504      if (cond.IsNotNever()) {
8505        EmitA32(0x00e00010U | (cond.GetCondition() << 28) |
8506                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8507                (shift.GetType() << 5) |
8508                (operand.GetShiftRegister().GetCode() << 8));
8509        return;
8510      }
8511    }
8512  }
8513  Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand);
8514}
8515
8516void Assembler::rscs(Condition cond,
8517                     Register rd,
8518                     Register rn,
8519                     const Operand& operand) {
8520  VIXL_ASSERT(AllowAssembler());
8521  CheckIT(cond);
8522  if (operand.IsImmediate()) {
8523    uint32_t imm = operand.GetImmediate();
8524    if (IsUsingA32()) {
8525      ImmediateA32 immediate_a32(imm);
8526      // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8527      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8528        EmitA32(0x02f00000U | (cond.GetCondition() << 28) |
8529                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8530                immediate_a32.GetEncodingValue());
8531        return;
8532      }
8533    }
8534  }
8535  if (operand.IsImmediateShiftedRegister()) {
8536    Register rm = operand.GetBaseRegister();
8537    Shift shift = operand.GetShift();
8538    uint32_t amount = operand.GetShiftAmount();
8539    if (IsUsingA32()) {
8540      // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8541      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8542        uint32_t amount_ = amount % 32;
8543        EmitA32(0x00f00000U | (cond.GetCondition() << 28) |
8544                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8545                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8546        return;
8547      }
8548    }
8549  }
8550  if (operand.IsRegisterShiftedRegister()) {
8551    Register rm = operand.GetBaseRegister();
8552    Shift shift = operand.GetShift();
8553    if (IsUsingA32()) {
8554      // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8555      if (cond.IsNotNever()) {
8556        EmitA32(0x00f00010U | (cond.GetCondition() << 28) |
8557                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8558                (shift.GetType() << 5) |
8559                (operand.GetShiftRegister().GetCode() << 8));
8560        return;
8561      }
8562    }
8563  }
8564  Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand);
8565}
8566
8567void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) {
8568  VIXL_ASSERT(AllowAssembler());
8569  CheckIT(cond);
8570  if (IsUsingT32()) {
8571    // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8572    EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8573               rm.GetCode());
8574    AdvanceIT();
8575    return;
8576  } else {
8577    // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8578    if (cond.IsNotNever()) {
8579      EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8580              (rn.GetCode() << 16) | rm.GetCode());
8581      return;
8582    }
8583  }
8584  Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm);
8585}
8586
8587void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) {
8588  VIXL_ASSERT(AllowAssembler());
8589  CheckIT(cond);
8590  if (IsUsingT32()) {
8591    // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8592    EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8593               rm.GetCode());
8594    AdvanceIT();
8595    return;
8596  } else {
8597    // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8598    if (cond.IsNotNever()) {
8599      EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8600              (rn.GetCode() << 16) | rm.GetCode());
8601      return;
8602    }
8603  }
8604  Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm);
8605}
8606
8607void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) {
8608  VIXL_ASSERT(AllowAssembler());
8609  CheckIT(cond);
8610  if (IsUsingT32()) {
8611    // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8612    EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8613               rm.GetCode());
8614    AdvanceIT();
8615    return;
8616  } else {
8617    // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8618    if (cond.IsNotNever()) {
8619      EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8620              (rn.GetCode() << 16) | rm.GetCode());
8621      return;
8622    }
8623  }
8624  Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm);
8625}
8626
8627void Assembler::sbc(Condition cond,
8628                    EncodingSize size,
8629                    Register rd,
8630                    Register rn,
8631                    const Operand& operand) {
8632  VIXL_ASSERT(AllowAssembler());
8633  CheckIT(cond);
8634  if (operand.IsImmediate()) {
8635    uint32_t imm = operand.GetImmediate();
8636    if (IsUsingT32()) {
8637      ImmediateT32 immediate_t32(imm);
8638      // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
8639      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8640        EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8641                   (immediate_t32.GetEncodingValue() & 0xff) |
8642                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8643                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8644        AdvanceIT();
8645        return;
8646      }
8647    } else {
8648      ImmediateA32 immediate_a32(imm);
8649      // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8650      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8651        EmitA32(0x02c00000U | (cond.GetCondition() << 28) |
8652                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8653                immediate_a32.GetEncodingValue());
8654        return;
8655      }
8656    }
8657  }
8658  if (operand.IsImmediateShiftedRegister()) {
8659    Register rm = operand.GetBaseRegister();
8660    if (operand.IsPlainRegister()) {
8661      if (IsUsingT32()) {
8662        // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
8663        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
8664            rm.IsLow()) {
8665          EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
8666          AdvanceIT();
8667          return;
8668        }
8669      }
8670    }
8671    Shift shift = operand.GetShift();
8672    uint32_t amount = operand.GetShiftAmount();
8673    if (IsUsingT32()) {
8674      // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
8675      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8676        uint32_t amount_ = amount % 32;
8677        EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8678                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8679                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8680        AdvanceIT();
8681        return;
8682      }
8683    } else {
8684      // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8685      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8686        uint32_t amount_ = amount % 32;
8687        EmitA32(0x00c00000U | (cond.GetCondition() << 28) |
8688                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8689                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8690        return;
8691      }
8692    }
8693  }
8694  if (operand.IsRegisterShiftedRegister()) {
8695    Register rm = operand.GetBaseRegister();
8696    Shift shift = operand.GetShift();
8697    if (IsUsingA32()) {
8698      // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8699      if (cond.IsNotNever()) {
8700        EmitA32(0x00c00010U | (cond.GetCondition() << 28) |
8701                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8702                (shift.GetType() << 5) |
8703                (operand.GetShiftRegister().GetCode() << 8));
8704        return;
8705      }
8706    }
8707  }
8708  Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand);
8709}
8710
8711void Assembler::sbcs(Condition cond,
8712                     EncodingSize size,
8713                     Register rd,
8714                     Register rn,
8715                     const Operand& operand) {
8716  VIXL_ASSERT(AllowAssembler());
8717  CheckIT(cond);
8718  if (operand.IsImmediate()) {
8719    uint32_t imm = operand.GetImmediate();
8720    if (IsUsingT32()) {
8721      ImmediateT32 immediate_t32(imm);
8722      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
8723      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8724        EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8725                   (immediate_t32.GetEncodingValue() & 0xff) |
8726                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8727                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8728        AdvanceIT();
8729        return;
8730      }
8731    } else {
8732      ImmediateA32 immediate_a32(imm);
8733      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8734      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8735        EmitA32(0x02d00000U | (cond.GetCondition() << 28) |
8736                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8737                immediate_a32.GetEncodingValue());
8738        return;
8739      }
8740    }
8741  }
8742  if (operand.IsImmediateShiftedRegister()) {
8743    Register rm = operand.GetBaseRegister();
8744    if (operand.IsPlainRegister()) {
8745      if (IsUsingT32()) {
8746        // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
8747        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
8748            rm.IsLow()) {
8749          EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
8750          AdvanceIT();
8751          return;
8752        }
8753      }
8754    }
8755    Shift shift = operand.GetShift();
8756    uint32_t amount = operand.GetShiftAmount();
8757    if (IsUsingT32()) {
8758      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
8759      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8760        uint32_t amount_ = amount % 32;
8761        EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8762                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8763                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8764        AdvanceIT();
8765        return;
8766      }
8767    } else {
8768      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8769      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8770        uint32_t amount_ = amount % 32;
8771        EmitA32(0x00d00000U | (cond.GetCondition() << 28) |
8772                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8773                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8774        return;
8775      }
8776    }
8777  }
8778  if (operand.IsRegisterShiftedRegister()) {
8779    Register rm = operand.GetBaseRegister();
8780    Shift shift = operand.GetShift();
8781    if (IsUsingA32()) {
8782      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8783      if (cond.IsNotNever()) {
8784        EmitA32(0x00d00010U | (cond.GetCondition() << 28) |
8785                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8786                (shift.GetType() << 5) |
8787                (operand.GetShiftRegister().GetCode() << 8));
8788        return;
8789      }
8790    }
8791  }
8792  Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand);
8793}
8794
8795void Assembler::sbfx(Condition cond,
8796                     Register rd,
8797                     Register rn,
8798                     uint32_t lsb,
8799                     const Operand& operand) {
8800  VIXL_ASSERT(AllowAssembler());
8801  CheckIT(cond);
8802  if (operand.IsImmediate()) {
8803    uint32_t width = operand.GetImmediate();
8804    if (IsUsingT32()) {
8805      // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
8806      if ((lsb <= 31) &&
8807          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
8808        uint32_t widthm1 = width - 1;
8809        EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8810                   ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
8811        AdvanceIT();
8812        return;
8813      }
8814    } else {
8815      // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
8816      if ((lsb <= 31) && cond.IsNotNever() &&
8817          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
8818        uint32_t widthm1 = width - 1;
8819        EmitA32(0x07a00050U | (cond.GetCondition() << 28) |
8820                (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) |
8821                (widthm1 << 16));
8822        return;
8823      }
8824    }
8825  }
8826  Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, operand);
8827}
8828
8829void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) {
8830  VIXL_ASSERT(AllowAssembler());
8831  CheckIT(cond);
8832  if (IsUsingT32()) {
8833    // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8834    EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8835               rm.GetCode());
8836    AdvanceIT();
8837    return;
8838  } else {
8839    // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8840    if (cond.IsNotNever()) {
8841      EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
8842              rn.GetCode() | (rm.GetCode() << 8));
8843      return;
8844    }
8845  }
8846  Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm);
8847}
8848
8849void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) {
8850  VIXL_ASSERT(AllowAssembler());
8851  CheckIT(cond);
8852  if (IsUsingT32()) {
8853    // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8854    EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8855               rm.GetCode());
8856    AdvanceIT();
8857    return;
8858  } else {
8859    // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8860    if (cond.IsNotNever()) {
8861      EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8862              (rn.GetCode() << 16) | rm.GetCode());
8863      return;
8864    }
8865  }
8866  Delegate(kSel, &Assembler::sel, cond, rd, rn, rm);
8867}
8868
8869void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) {
8870  VIXL_ASSERT(AllowAssembler());
8871  CheckIT(cond);
8872  if (IsUsingT32()) {
8873    // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8874    EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8875               rm.GetCode());
8876    AdvanceIT();
8877    return;
8878  } else {
8879    // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8880    if (cond.IsNotNever()) {
8881      EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8882              (rn.GetCode() << 16) | rm.GetCode());
8883      return;
8884    }
8885  }
8886  Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm);
8887}
8888
8889void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) {
8890  VIXL_ASSERT(AllowAssembler());
8891  CheckIT(cond);
8892  if (IsUsingT32()) {
8893    // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8894    EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8895               rm.GetCode());
8896    AdvanceIT();
8897    return;
8898  } else {
8899    // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8900    if (cond.IsNotNever()) {
8901      EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8902              (rn.GetCode() << 16) | rm.GetCode());
8903      return;
8904    }
8905  }
8906  Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm);
8907}
8908
8909void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) {
8910  VIXL_ASSERT(AllowAssembler());
8911  CheckIT(cond);
8912  if (IsUsingT32()) {
8913    // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8914    EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8915               rm.GetCode());
8916    AdvanceIT();
8917    return;
8918  } else {
8919    // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8920    if (cond.IsNotNever()) {
8921      EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8922              (rn.GetCode() << 16) | rm.GetCode());
8923      return;
8924    }
8925  }
8926  Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm);
8927}
8928
8929void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) {
8930  VIXL_ASSERT(AllowAssembler());
8931  CheckIT(cond);
8932  if (IsUsingT32()) {
8933    // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8934    EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8935               rm.GetCode());
8936    AdvanceIT();
8937    return;
8938  } else {
8939    // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8940    if (cond.IsNotNever()) {
8941      EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8942              (rn.GetCode() << 16) | rm.GetCode());
8943      return;
8944    }
8945  }
8946  Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm);
8947}
8948
8949void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) {
8950  VIXL_ASSERT(AllowAssembler());
8951  CheckIT(cond);
8952  if (IsUsingT32()) {
8953    // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8954    EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8955               rm.GetCode());
8956    AdvanceIT();
8957    return;
8958  } else {
8959    // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8960    if (cond.IsNotNever()) {
8961      EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8962              (rn.GetCode() << 16) | rm.GetCode());
8963      return;
8964    }
8965  }
8966  Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm);
8967}
8968
8969void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) {
8970  VIXL_ASSERT(AllowAssembler());
8971  CheckIT(cond);
8972  if (IsUsingT32()) {
8973    // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8974    EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8975               rm.GetCode());
8976    AdvanceIT();
8977    return;
8978  } else {
8979    // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8980    if (cond.IsNotNever()) {
8981      EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8982              (rn.GetCode() << 16) | rm.GetCode());
8983      return;
8984    }
8985  }
8986  Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm);
8987}
8988
8989void Assembler::smlabb(
8990    Condition cond, Register rd, Register rn, Register rm, Register ra) {
8991  VIXL_ASSERT(AllowAssembler());
8992  CheckIT(cond);
8993  if (IsUsingT32()) {
8994    // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
8995    if (!ra.Is(pc)) {
8996      EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8997                 rm.GetCode() | (ra.GetCode() << 12));
8998      AdvanceIT();
8999      return;
9000    }
9001  } else {
9002    // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9003    if (cond.IsNotNever()) {
9004      EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9005              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9006      return;
9007    }
9008  }
9009  Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra);
9010}
9011
9012void Assembler::smlabt(
9013    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9014  VIXL_ASSERT(AllowAssembler());
9015  CheckIT(cond);
9016  if (IsUsingT32()) {
9017    // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9018    if (!ra.Is(pc)) {
9019      EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9020                 rm.GetCode() | (ra.GetCode() << 12));
9021      AdvanceIT();
9022      return;
9023    }
9024  } else {
9025    // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9026    if (cond.IsNotNever()) {
9027      EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9028              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9029      return;
9030    }
9031  }
9032  Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra);
9033}
9034
9035void Assembler::smlad(
9036    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9037  VIXL_ASSERT(AllowAssembler());
9038  CheckIT(cond);
9039  if (IsUsingT32()) {
9040    // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9041    if (!ra.Is(pc)) {
9042      EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9043                 rm.GetCode() | (ra.GetCode() << 12));
9044      AdvanceIT();
9045      return;
9046    }
9047  } else {
9048    // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9049    if (cond.IsNotNever() && !ra.Is(pc)) {
9050      EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9051              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9052      return;
9053    }
9054  }
9055  Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra);
9056}
9057
9058void Assembler::smladx(
9059    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9060  VIXL_ASSERT(AllowAssembler());
9061  CheckIT(cond);
9062  if (IsUsingT32()) {
9063    // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9064    if (!ra.Is(pc)) {
9065      EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9066                 rm.GetCode() | (ra.GetCode() << 12));
9067      AdvanceIT();
9068      return;
9069    }
9070  } else {
9071    // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9072    if (cond.IsNotNever() && !ra.Is(pc)) {
9073      EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9074              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9075      return;
9076    }
9077  }
9078  Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra);
9079}
9080
9081void Assembler::smlal(
9082    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9083  VIXL_ASSERT(AllowAssembler());
9084  CheckIT(cond);
9085  if (IsUsingT32()) {
9086    // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9087    EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9088               (rn.GetCode() << 16) | rm.GetCode());
9089    AdvanceIT();
9090    return;
9091  } else {
9092    // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9093    if (cond.IsNotNever()) {
9094      EmitA32(0x00e00090U | (cond.GetCondition() << 28) |
9095              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9096              (rm.GetCode() << 8));
9097      return;
9098    }
9099  }
9100  Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm);
9101}
9102
9103void Assembler::smlalbb(
9104    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9105  VIXL_ASSERT(AllowAssembler());
9106  CheckIT(cond);
9107  if (IsUsingT32()) {
9108    // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9109    EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9110               (rn.GetCode() << 16) | rm.GetCode());
9111    AdvanceIT();
9112    return;
9113  } else {
9114    // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9115    if (cond.IsNotNever()) {
9116      EmitA32(0x01400080U | (cond.GetCondition() << 28) |
9117              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9118              (rm.GetCode() << 8));
9119      return;
9120    }
9121  }
9122  Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm);
9123}
9124
9125void Assembler::smlalbt(
9126    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9127  VIXL_ASSERT(AllowAssembler());
9128  CheckIT(cond);
9129  if (IsUsingT32()) {
9130    // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9131    EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9132               (rn.GetCode() << 16) | rm.GetCode());
9133    AdvanceIT();
9134    return;
9135  } else {
9136    // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9137    if (cond.IsNotNever()) {
9138      EmitA32(0x014000c0U | (cond.GetCondition() << 28) |
9139              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9140              (rm.GetCode() << 8));
9141      return;
9142    }
9143  }
9144  Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm);
9145}
9146
9147void Assembler::smlald(
9148    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9149  VIXL_ASSERT(AllowAssembler());
9150  CheckIT(cond);
9151  if (IsUsingT32()) {
9152    // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9153    EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9154               (rn.GetCode() << 16) | rm.GetCode());
9155    AdvanceIT();
9156    return;
9157  } else {
9158    // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9159    if (cond.IsNotNever()) {
9160      EmitA32(0x07400010U | (cond.GetCondition() << 28) |
9161              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9162              (rm.GetCode() << 8));
9163      return;
9164    }
9165  }
9166  Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm);
9167}
9168
9169void Assembler::smlaldx(
9170    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9171  VIXL_ASSERT(AllowAssembler());
9172  CheckIT(cond);
9173  if (IsUsingT32()) {
9174    // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9175    EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9176               (rn.GetCode() << 16) | rm.GetCode());
9177    AdvanceIT();
9178    return;
9179  } else {
9180    // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9181    if (cond.IsNotNever()) {
9182      EmitA32(0x07400030U | (cond.GetCondition() << 28) |
9183              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9184              (rm.GetCode() << 8));
9185      return;
9186    }
9187  }
9188  Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm);
9189}
9190
9191void Assembler::smlals(
9192    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9193  VIXL_ASSERT(AllowAssembler());
9194  CheckIT(cond);
9195  if (IsUsingA32()) {
9196    // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9197    if (cond.IsNotNever()) {
9198      EmitA32(0x00f00090U | (cond.GetCondition() << 28) |
9199              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9200              (rm.GetCode() << 8));
9201      return;
9202    }
9203  }
9204  Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm);
9205}
9206
9207void Assembler::smlaltb(
9208    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9209  VIXL_ASSERT(AllowAssembler());
9210  CheckIT(cond);
9211  if (IsUsingT32()) {
9212    // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9213    EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9214               (rn.GetCode() << 16) | rm.GetCode());
9215    AdvanceIT();
9216    return;
9217  } else {
9218    // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9219    if (cond.IsNotNever()) {
9220      EmitA32(0x014000a0U | (cond.GetCondition() << 28) |
9221              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9222              (rm.GetCode() << 8));
9223      return;
9224    }
9225  }
9226  Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm);
9227}
9228
9229void Assembler::smlaltt(
9230    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9231  VIXL_ASSERT(AllowAssembler());
9232  CheckIT(cond);
9233  if (IsUsingT32()) {
9234    // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9235    EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9236               (rn.GetCode() << 16) | rm.GetCode());
9237    AdvanceIT();
9238    return;
9239  } else {
9240    // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9241    if (cond.IsNotNever()) {
9242      EmitA32(0x014000e0U | (cond.GetCondition() << 28) |
9243              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9244              (rm.GetCode() << 8));
9245      return;
9246    }
9247  }
9248  Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm);
9249}
9250
9251void Assembler::smlatb(
9252    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9253  VIXL_ASSERT(AllowAssembler());
9254  CheckIT(cond);
9255  if (IsUsingT32()) {
9256    // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9257    if (!ra.Is(pc)) {
9258      EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9259                 rm.GetCode() | (ra.GetCode() << 12));
9260      AdvanceIT();
9261      return;
9262    }
9263  } else {
9264    // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9265    if (cond.IsNotNever()) {
9266      EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9267              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9268      return;
9269    }
9270  }
9271  Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra);
9272}
9273
9274void Assembler::smlatt(
9275    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9276  VIXL_ASSERT(AllowAssembler());
9277  CheckIT(cond);
9278  if (IsUsingT32()) {
9279    // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9280    if (!ra.Is(pc)) {
9281      EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9282                 rm.GetCode() | (ra.GetCode() << 12));
9283      AdvanceIT();
9284      return;
9285    }
9286  } else {
9287    // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9288    if (cond.IsNotNever()) {
9289      EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9290              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9291      return;
9292    }
9293  }
9294  Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra);
9295}
9296
9297void Assembler::smlawb(
9298    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9299  VIXL_ASSERT(AllowAssembler());
9300  CheckIT(cond);
9301  if (IsUsingT32()) {
9302    // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9303    if (!ra.Is(pc)) {
9304      EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9305                 rm.GetCode() | (ra.GetCode() << 12));
9306      AdvanceIT();
9307      return;
9308    }
9309  } else {
9310    // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9311    if (cond.IsNotNever()) {
9312      EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9313              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9314      return;
9315    }
9316  }
9317  Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra);
9318}
9319
9320void Assembler::smlawt(
9321    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9322  VIXL_ASSERT(AllowAssembler());
9323  CheckIT(cond);
9324  if (IsUsingT32()) {
9325    // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9326    if (!ra.Is(pc)) {
9327      EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9328                 rm.GetCode() | (ra.GetCode() << 12));
9329      AdvanceIT();
9330      return;
9331    }
9332  } else {
9333    // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9334    if (cond.IsNotNever()) {
9335      EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9336              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9337      return;
9338    }
9339  }
9340  Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra);
9341}
9342
9343void Assembler::smlsd(
9344    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9345  VIXL_ASSERT(AllowAssembler());
9346  CheckIT(cond);
9347  if (IsUsingT32()) {
9348    // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9349    if (!ra.Is(pc)) {
9350      EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9351                 rm.GetCode() | (ra.GetCode() << 12));
9352      AdvanceIT();
9353      return;
9354    }
9355  } else {
9356    // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9357    if (cond.IsNotNever() && !ra.Is(pc)) {
9358      EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9359              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9360      return;
9361    }
9362  }
9363  Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra);
9364}
9365
9366void Assembler::smlsdx(
9367    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9368  VIXL_ASSERT(AllowAssembler());
9369  CheckIT(cond);
9370  if (IsUsingT32()) {
9371    // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9372    if (!ra.Is(pc)) {
9373      EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9374                 rm.GetCode() | (ra.GetCode() << 12));
9375      AdvanceIT();
9376      return;
9377    }
9378  } else {
9379    // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9380    if (cond.IsNotNever() && !ra.Is(pc)) {
9381      EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9382              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9383      return;
9384    }
9385  }
9386  Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra);
9387}
9388
9389void Assembler::smlsld(
9390    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9391  VIXL_ASSERT(AllowAssembler());
9392  CheckIT(cond);
9393  if (IsUsingT32()) {
9394    // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9395    EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9396               (rn.GetCode() << 16) | rm.GetCode());
9397    AdvanceIT();
9398    return;
9399  } else {
9400    // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9401    if (cond.IsNotNever()) {
9402      EmitA32(0x07400050U | (cond.GetCondition() << 28) |
9403              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9404              (rm.GetCode() << 8));
9405      return;
9406    }
9407  }
9408  Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm);
9409}
9410
9411void Assembler::smlsldx(
9412    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9413  VIXL_ASSERT(AllowAssembler());
9414  CheckIT(cond);
9415  if (IsUsingT32()) {
9416    // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9417    EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9418               (rn.GetCode() << 16) | rm.GetCode());
9419    AdvanceIT();
9420    return;
9421  } else {
9422    // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9423    if (cond.IsNotNever()) {
9424      EmitA32(0x07400070U | (cond.GetCondition() << 28) |
9425              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9426              (rm.GetCode() << 8));
9427      return;
9428    }
9429  }
9430  Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm);
9431}
9432
9433void Assembler::smmla(
9434    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9435  VIXL_ASSERT(AllowAssembler());
9436  CheckIT(cond);
9437  if (IsUsingT32()) {
9438    // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9439    if (!ra.Is(pc)) {
9440      EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9441                 rm.GetCode() | (ra.GetCode() << 12));
9442      AdvanceIT();
9443      return;
9444    }
9445  } else {
9446    // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9447    if (cond.IsNotNever() && !ra.Is(pc)) {
9448      EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9449              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9450      return;
9451    }
9452  }
9453  Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra);
9454}
9455
9456void Assembler::smmlar(
9457    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9458  VIXL_ASSERT(AllowAssembler());
9459  CheckIT(cond);
9460  if (IsUsingT32()) {
9461    // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9462    if (!ra.Is(pc)) {
9463      EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9464                 rm.GetCode() | (ra.GetCode() << 12));
9465      AdvanceIT();
9466      return;
9467    }
9468  } else {
9469    // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9470    if (cond.IsNotNever() && !ra.Is(pc)) {
9471      EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9472              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9473      return;
9474    }
9475  }
9476  Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra);
9477}
9478
9479void Assembler::smmls(
9480    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9481  VIXL_ASSERT(AllowAssembler());
9482  CheckIT(cond);
9483  if (IsUsingT32()) {
9484    // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9485    EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9486               rm.GetCode() | (ra.GetCode() << 12));
9487    AdvanceIT();
9488    return;
9489  } else {
9490    // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9491    if (cond.IsNotNever()) {
9492      EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9493              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9494      return;
9495    }
9496  }
9497  Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra);
9498}
9499
9500void Assembler::smmlsr(
9501    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9502  VIXL_ASSERT(AllowAssembler());
9503  CheckIT(cond);
9504  if (IsUsingT32()) {
9505    // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9506    EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9507               rm.GetCode() | (ra.GetCode() << 12));
9508    AdvanceIT();
9509    return;
9510  } else {
9511    // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9512    if (cond.IsNotNever()) {
9513      EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9514              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9515      return;
9516    }
9517  }
9518  Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra);
9519}
9520
9521void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) {
9522  VIXL_ASSERT(AllowAssembler());
9523  CheckIT(cond);
9524  if (IsUsingT32()) {
9525    // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9526    EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9527               rm.GetCode());
9528    AdvanceIT();
9529    return;
9530  } else {
9531    // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9532    if (cond.IsNotNever()) {
9533      EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9534              rn.GetCode() | (rm.GetCode() << 8));
9535      return;
9536    }
9537  }
9538  Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm);
9539}
9540
9541void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) {
9542  VIXL_ASSERT(AllowAssembler());
9543  CheckIT(cond);
9544  if (IsUsingT32()) {
9545    // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9546    EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9547               rm.GetCode());
9548    AdvanceIT();
9549    return;
9550  } else {
9551    // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9552    if (cond.IsNotNever()) {
9553      EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9554              rn.GetCode() | (rm.GetCode() << 8));
9555      return;
9556    }
9557  }
9558  Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm);
9559}
9560
9561void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) {
9562  VIXL_ASSERT(AllowAssembler());
9563  CheckIT(cond);
9564  if (IsUsingT32()) {
9565    // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9566    EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9567               rm.GetCode());
9568    AdvanceIT();
9569    return;
9570  } else {
9571    // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9572    if (cond.IsNotNever()) {
9573      EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9574              rn.GetCode() | (rm.GetCode() << 8));
9575      return;
9576    }
9577  }
9578  Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm);
9579}
9580
9581void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) {
9582  VIXL_ASSERT(AllowAssembler());
9583  CheckIT(cond);
9584  if (IsUsingT32()) {
9585    // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9586    EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9587               rm.GetCode());
9588    AdvanceIT();
9589    return;
9590  } else {
9591    // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9592    if (cond.IsNotNever()) {
9593      EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9594              rn.GetCode() | (rm.GetCode() << 8));
9595      return;
9596    }
9597  }
9598  Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm);
9599}
9600
9601void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) {
9602  VIXL_ASSERT(AllowAssembler());
9603  CheckIT(cond);
9604  if (IsUsingT32()) {
9605    // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9606    EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9607               rm.GetCode());
9608    AdvanceIT();
9609    return;
9610  } else {
9611    // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9612    if (cond.IsNotNever()) {
9613      EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9614              rn.GetCode() | (rm.GetCode() << 8));
9615      return;
9616    }
9617  }
9618  Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm);
9619}
9620
9621void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) {
9622  VIXL_ASSERT(AllowAssembler());
9623  CheckIT(cond);
9624  if (IsUsingT32()) {
9625    // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9626    EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9627               rm.GetCode());
9628    AdvanceIT();
9629    return;
9630  } else {
9631    // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9632    if (cond.IsNotNever()) {
9633      EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9634              rn.GetCode() | (rm.GetCode() << 8));
9635      return;
9636    }
9637  }
9638  Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm);
9639}
9640
9641void Assembler::smull(
9642    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9643  VIXL_ASSERT(AllowAssembler());
9644  CheckIT(cond);
9645  if (IsUsingT32()) {
9646    // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9647    EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9648               (rn.GetCode() << 16) | rm.GetCode());
9649    AdvanceIT();
9650    return;
9651  } else {
9652    // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9653    if (cond.IsNotNever()) {
9654      EmitA32(0x00c00090U | (cond.GetCondition() << 28) |
9655              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9656              (rm.GetCode() << 8));
9657      return;
9658    }
9659  }
9660  Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm);
9661}
9662
9663void Assembler::smulls(
9664    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9665  VIXL_ASSERT(AllowAssembler());
9666  CheckIT(cond);
9667  if (IsUsingA32()) {
9668    // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9669    if (cond.IsNotNever()) {
9670      EmitA32(0x00d00090U | (cond.GetCondition() << 28) |
9671              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9672              (rm.GetCode() << 8));
9673      return;
9674    }
9675  }
9676  Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm);
9677}
9678
9679void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) {
9680  VIXL_ASSERT(AllowAssembler());
9681  CheckIT(cond);
9682  if (IsUsingT32()) {
9683    // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9684    EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9685               rm.GetCode());
9686    AdvanceIT();
9687    return;
9688  } else {
9689    // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9690    if (cond.IsNotNever()) {
9691      EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9692              rn.GetCode() | (rm.GetCode() << 8));
9693      return;
9694    }
9695  }
9696  Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm);
9697}
9698
9699void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) {
9700  VIXL_ASSERT(AllowAssembler());
9701  CheckIT(cond);
9702  if (IsUsingT32()) {
9703    // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9704    EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9705               rm.GetCode());
9706    AdvanceIT();
9707    return;
9708  } else {
9709    // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9710    if (cond.IsNotNever()) {
9711      EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9712              rn.GetCode() | (rm.GetCode() << 8));
9713      return;
9714    }
9715  }
9716  Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm);
9717}
9718
9719void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) {
9720  VIXL_ASSERT(AllowAssembler());
9721  CheckIT(cond);
9722  if (IsUsingT32()) {
9723    // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9724    EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9725               rm.GetCode());
9726    AdvanceIT();
9727    return;
9728  } else {
9729    // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9730    if (cond.IsNotNever()) {
9731      EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9732              rn.GetCode() | (rm.GetCode() << 8));
9733      return;
9734    }
9735  }
9736  Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm);
9737}
9738
9739void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) {
9740  VIXL_ASSERT(AllowAssembler());
9741  CheckIT(cond);
9742  if (IsUsingT32()) {
9743    // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9744    EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9745               rm.GetCode());
9746    AdvanceIT();
9747    return;
9748  } else {
9749    // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9750    if (cond.IsNotNever()) {
9751      EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9752              rn.GetCode() | (rm.GetCode() << 8));
9753      return;
9754    }
9755  }
9756  Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm);
9757}
9758
9759void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) {
9760  VIXL_ASSERT(AllowAssembler());
9761  CheckIT(cond);
9762  if (IsUsingT32()) {
9763    // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9764    EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9765               rm.GetCode());
9766    AdvanceIT();
9767    return;
9768  } else {
9769    // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9770    if (cond.IsNotNever()) {
9771      EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9772              rn.GetCode() | (rm.GetCode() << 8));
9773      return;
9774    }
9775  }
9776  Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm);
9777}
9778
9779void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) {
9780  VIXL_ASSERT(AllowAssembler());
9781  CheckIT(cond);
9782  if (IsUsingT32()) {
9783    // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9784    EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9785               rm.GetCode());
9786    AdvanceIT();
9787    return;
9788  } else {
9789    // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9790    if (cond.IsNotNever()) {
9791      EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9792              rn.GetCode() | (rm.GetCode() << 8));
9793      return;
9794    }
9795  }
9796  Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm);
9797}
9798
9799void Assembler::ssat(Condition cond,
9800                     Register rd,
9801                     uint32_t imm,
9802                     const Operand& operand) {
9803  VIXL_ASSERT(AllowAssembler());
9804  CheckIT(cond);
9805  if (operand.IsImmediateShiftedRegister()) {
9806    Register rn = operand.GetBaseRegister();
9807    Shift shift = operand.GetShift();
9808    uint32_t amount = operand.GetShiftAmount();
9809    if (IsUsingT32()) {
9810      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
9811      if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
9812          (amount <= 31)) {
9813        uint32_t imm_ = imm - 1;
9814        EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
9815                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
9816                   ((amount & 0x1c) << 10));
9817        AdvanceIT();
9818        return;
9819      }
9820      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
9821      if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31)) {
9822        uint32_t imm_ = imm - 1;
9823        EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ |
9824                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
9825                   ((amount & 0x1c) << 10));
9826        AdvanceIT();
9827        return;
9828      }
9829    } else {
9830      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
9831      if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
9832          (amount <= 32) && cond.IsNotNever()) {
9833        uint32_t imm_ = imm - 1;
9834        uint32_t amount_ = amount % 32;
9835        EmitA32(0x06a00050U | (cond.GetCondition() << 28) |
9836                (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
9837                (amount_ << 7));
9838        return;
9839      }
9840      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
9841      if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
9842          cond.IsNotNever()) {
9843        uint32_t imm_ = imm - 1;
9844        EmitA32(0x06a00010U | (cond.GetCondition() << 28) |
9845                (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
9846                (amount << 7));
9847        return;
9848      }
9849    }
9850  }
9851  Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand);
9852}
9853
9854void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) {
9855  VIXL_ASSERT(AllowAssembler());
9856  CheckIT(cond);
9857  if (IsUsingT32()) {
9858    // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
9859    if ((imm >= 1) && (imm <= 16)) {
9860      uint32_t imm_ = imm - 1;
9861      EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
9862                 (rn.GetCode() << 16));
9863      AdvanceIT();
9864      return;
9865    }
9866  } else {
9867    // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
9868    if ((imm >= 1) && (imm <= 16) && cond.IsNotNever()) {
9869      uint32_t imm_ = imm - 1;
9870      EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9871              (imm_ << 16) | rn.GetCode());
9872      return;
9873    }
9874  }
9875  Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn);
9876}
9877
9878void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) {
9879  VIXL_ASSERT(AllowAssembler());
9880  CheckIT(cond);
9881  if (IsUsingT32()) {
9882    // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9883    EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9884               rm.GetCode());
9885    AdvanceIT();
9886    return;
9887  } else {
9888    // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9889    if (cond.IsNotNever()) {
9890      EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9891              (rn.GetCode() << 16) | rm.GetCode());
9892      return;
9893    }
9894  }
9895  Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm);
9896}
9897
9898void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) {
9899  VIXL_ASSERT(AllowAssembler());
9900  CheckIT(cond);
9901  if (IsUsingT32()) {
9902    // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9903    EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9904               rm.GetCode());
9905    AdvanceIT();
9906    return;
9907  } else {
9908    // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9909    if (cond.IsNotNever()) {
9910      EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9911              (rn.GetCode() << 16) | rm.GetCode());
9912      return;
9913    }
9914  }
9915  Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm);
9916}
9917
9918void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) {
9919  VIXL_ASSERT(AllowAssembler());
9920  CheckIT(cond);
9921  if (IsUsingT32()) {
9922    // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9923    EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9924               rm.GetCode());
9925    AdvanceIT();
9926    return;
9927  } else {
9928    // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9929    if (cond.IsNotNever()) {
9930      EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9931              (rn.GetCode() << 16) | rm.GetCode());
9932      return;
9933    }
9934  }
9935  Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm);
9936}
9937
9938void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) {
9939  VIXL_ASSERT(AllowAssembler());
9940  CheckIT(cond);
9941  if (operand.IsImmediateZero()) {
9942    Register rn = operand.GetBaseRegister();
9943    if (IsUsingT32()) {
9944      // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1
9945      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
9946        EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
9947        AdvanceIT();
9948        return;
9949      }
9950    } else {
9951      // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1
9952      if (operand.IsOffset() && cond.IsNotNever() &&
9953          (!rn.IsPC() || AllowUnpredictable())) {
9954        EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
9955                (rn.GetCode() << 16));
9956        return;
9957      }
9958    }
9959  }
9960  Delegate(kStl, &Assembler::stl, cond, rt, operand);
9961}
9962
9963void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) {
9964  VIXL_ASSERT(AllowAssembler());
9965  CheckIT(cond);
9966  if (operand.IsImmediateZero()) {
9967    Register rn = operand.GetBaseRegister();
9968    if (IsUsingT32()) {
9969      // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1
9970      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
9971        EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
9972        AdvanceIT();
9973        return;
9974      }
9975    } else {
9976      // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1
9977      if (operand.IsOffset() && cond.IsNotNever() &&
9978          (!rn.IsPC() || AllowUnpredictable())) {
9979        EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
9980                (rn.GetCode() << 16));
9981        return;
9982      }
9983    }
9984  }
9985  Delegate(kStlb, &Assembler::stlb, cond, rt, operand);
9986}
9987
9988void Assembler::stlex(Condition cond,
9989                      Register rd,
9990                      Register rt,
9991                      const MemOperand& operand) {
9992  VIXL_ASSERT(AllowAssembler());
9993  CheckIT(cond);
9994  if (operand.IsImmediateZero()) {
9995    Register rn = operand.GetBaseRegister();
9996    if (IsUsingT32()) {
9997      // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
9998      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
9999        EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) |
10000                   (rn.GetCode() << 16));
10001        AdvanceIT();
10002        return;
10003      }
10004    } else {
10005      // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10006      if (operand.IsOffset() && cond.IsNotNever() &&
10007          (!rn.IsPC() || AllowUnpredictable())) {
10008        EmitA32(0x01800e90U | (cond.GetCondition() << 28) |
10009                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10010        return;
10011      }
10012    }
10013  }
10014  Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand);
10015}
10016
10017void Assembler::stlexb(Condition cond,
10018                       Register rd,
10019                       Register rt,
10020                       const MemOperand& operand) {
10021  VIXL_ASSERT(AllowAssembler());
10022  CheckIT(cond);
10023  if (operand.IsImmediateZero()) {
10024    Register rn = operand.GetBaseRegister();
10025    if (IsUsingT32()) {
10026      // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10027      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10028        EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) |
10029                   (rn.GetCode() << 16));
10030        AdvanceIT();
10031        return;
10032      }
10033    } else {
10034      // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10035      if (operand.IsOffset() && cond.IsNotNever() &&
10036          (!rn.IsPC() || AllowUnpredictable())) {
10037        EmitA32(0x01c00e90U | (cond.GetCondition() << 28) |
10038                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10039        return;
10040      }
10041    }
10042  }
10043  Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand);
10044}
10045
10046void Assembler::stlexd(Condition cond,
10047                       Register rd,
10048                       Register rt,
10049                       Register rt2,
10050                       const MemOperand& operand) {
10051  VIXL_ASSERT(AllowAssembler());
10052  CheckIT(cond);
10053  if (operand.IsImmediateZero()) {
10054    Register rn = operand.GetBaseRegister();
10055    if (IsUsingT32()) {
10056      // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
10057      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10058        EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) |
10059                   (rt2.GetCode() << 8) | (rn.GetCode() << 16));
10060        AdvanceIT();
10061        return;
10062      }
10063    } else {
10064      // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
10065      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10066          operand.IsOffset() && cond.IsNotNever() &&
10067          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
10068           AllowUnpredictable())) {
10069        EmitA32(0x01a00e90U | (cond.GetCondition() << 28) |
10070                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10071        return;
10072      }
10073    }
10074  }
10075  Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand);
10076}
10077
10078void Assembler::stlexh(Condition cond,
10079                       Register rd,
10080                       Register rt,
10081                       const MemOperand& operand) {
10082  VIXL_ASSERT(AllowAssembler());
10083  CheckIT(cond);
10084  if (operand.IsImmediateZero()) {
10085    Register rn = operand.GetBaseRegister();
10086    if (IsUsingT32()) {
10087      // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10088      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10089        EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) |
10090                   (rn.GetCode() << 16));
10091        AdvanceIT();
10092        return;
10093      }
10094    } else {
10095      // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10096      if (operand.IsOffset() && cond.IsNotNever() &&
10097          (!rn.IsPC() || AllowUnpredictable())) {
10098        EmitA32(0x01e00e90U | (cond.GetCondition() << 28) |
10099                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10100        return;
10101      }
10102    }
10103  }
10104  Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand);
10105}
10106
10107void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) {
10108  VIXL_ASSERT(AllowAssembler());
10109  CheckIT(cond);
10110  if (operand.IsImmediateZero()) {
10111    Register rn = operand.GetBaseRegister();
10112    if (IsUsingT32()) {
10113      // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1
10114      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10115        EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
10116        AdvanceIT();
10117        return;
10118      }
10119    } else {
10120      // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1
10121      if (operand.IsOffset() && cond.IsNotNever() &&
10122          (!rn.IsPC() || AllowUnpredictable())) {
10123        EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
10124                (rn.GetCode() << 16));
10125        return;
10126      }
10127    }
10128  }
10129  Delegate(kStlh, &Assembler::stlh, cond, rt, operand);
10130}
10131
10132void Assembler::stm(Condition cond,
10133                    EncodingSize size,
10134                    Register rn,
10135                    WriteBack write_back,
10136                    RegisterList registers) {
10137  VIXL_ASSERT(AllowAssembler());
10138  CheckIT(cond);
10139  if (IsUsingT32()) {
10140    // STM{<c>}{<q>} <Rn>!, <registers> ; T1
10141    if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
10142        ((registers.GetList() & ~0xff) == 0)) {
10143      EmitT32_16(0xc000 | (rn.GetCode() << 8) |
10144                 GetRegisterListEncoding(registers, 0, 8));
10145      AdvanceIT();
10146      return;
10147    }
10148    // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2
10149    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10150      EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
10151                 (write_back.GetWriteBackUint32() << 21) |
10152                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10153                 GetRegisterListEncoding(registers, 0, 13));
10154      AdvanceIT();
10155      return;
10156    }
10157  } else {
10158    // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1
10159    if (cond.IsNotNever()) {
10160      EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10161              (write_back.GetWriteBackUint32() << 21) |
10162              GetRegisterListEncoding(registers, 0, 16));
10163      return;
10164    }
10165  }
10166  Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers);
10167}
10168
10169void Assembler::stmda(Condition cond,
10170                      Register rn,
10171                      WriteBack write_back,
10172                      RegisterList registers) {
10173  VIXL_ASSERT(AllowAssembler());
10174  CheckIT(cond);
10175  if (IsUsingA32()) {
10176    // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
10177    if (cond.IsNotNever()) {
10178      EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10179              (write_back.GetWriteBackUint32() << 21) |
10180              GetRegisterListEncoding(registers, 0, 16));
10181      return;
10182    }
10183  }
10184  Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers);
10185}
10186
10187void Assembler::stmdb(Condition cond,
10188                      EncodingSize size,
10189                      Register rn,
10190                      WriteBack write_back,
10191                      RegisterList registers) {
10192  VIXL_ASSERT(AllowAssembler());
10193  CheckIT(cond);
10194  if (IsUsingT32()) {
10195    // STMDB{<c>}{<q>} SP!, <registers> ; T1
10196    if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
10197        ((registers.GetList() & ~0x40ff) == 0)) {
10198      EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
10199                 GetRegisterListEncoding(registers, 0, 8));
10200      AdvanceIT();
10201      return;
10202    }
10203    // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
10204    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10205      EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
10206                 (write_back.GetWriteBackUint32() << 21) |
10207                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10208                 GetRegisterListEncoding(registers, 0, 13));
10209      AdvanceIT();
10210      return;
10211    }
10212  } else {
10213    // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
10214    if (cond.IsNotNever()) {
10215      EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10216              (write_back.GetWriteBackUint32() << 21) |
10217              GetRegisterListEncoding(registers, 0, 16));
10218      return;
10219    }
10220  }
10221  Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers);
10222}
10223
10224void Assembler::stmea(Condition cond,
10225                      EncodingSize size,
10226                      Register rn,
10227                      WriteBack write_back,
10228                      RegisterList registers) {
10229  VIXL_ASSERT(AllowAssembler());
10230  CheckIT(cond);
10231  if (IsUsingT32()) {
10232    // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1
10233    if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
10234        ((registers.GetList() & ~0xff) == 0)) {
10235      EmitT32_16(0xc000 | (rn.GetCode() << 8) |
10236                 GetRegisterListEncoding(registers, 0, 8));
10237      AdvanceIT();
10238      return;
10239    }
10240    // STMEA{<c>}.W <Rn>{!}, <registers> ; T2
10241    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10242      EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
10243                 (write_back.GetWriteBackUint32() << 21) |
10244                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10245                 GetRegisterListEncoding(registers, 0, 13));
10246      AdvanceIT();
10247      return;
10248    }
10249    // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2
10250    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10251      EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
10252                 (write_back.GetWriteBackUint32() << 21) |
10253                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10254                 GetRegisterListEncoding(registers, 0, 13));
10255      AdvanceIT();
10256      return;
10257    }
10258  } else {
10259    // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
10260    if (cond.IsNotNever()) {
10261      EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10262              (write_back.GetWriteBackUint32() << 21) |
10263              GetRegisterListEncoding(registers, 0, 16));
10264      return;
10265    }
10266  }
10267  Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers);
10268}
10269
10270void Assembler::stmed(Condition cond,
10271                      Register rn,
10272                      WriteBack write_back,
10273                      RegisterList registers) {
10274  VIXL_ASSERT(AllowAssembler());
10275  CheckIT(cond);
10276  if (IsUsingA32()) {
10277    // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
10278    if (cond.IsNotNever()) {
10279      EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10280              (write_back.GetWriteBackUint32() << 21) |
10281              GetRegisterListEncoding(registers, 0, 16));
10282      return;
10283    }
10284  }
10285  Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers);
10286}
10287
10288void Assembler::stmfa(Condition cond,
10289                      Register rn,
10290                      WriteBack write_back,
10291                      RegisterList registers) {
10292  VIXL_ASSERT(AllowAssembler());
10293  CheckIT(cond);
10294  if (IsUsingA32()) {
10295    // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
10296    if (cond.IsNotNever()) {
10297      EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10298              (write_back.GetWriteBackUint32() << 21) |
10299              GetRegisterListEncoding(registers, 0, 16));
10300      return;
10301    }
10302  }
10303  Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers);
10304}
10305
10306void Assembler::stmfd(Condition cond,
10307                      Register rn,
10308                      WriteBack write_back,
10309                      RegisterList registers) {
10310  VIXL_ASSERT(AllowAssembler());
10311  CheckIT(cond);
10312  if (IsUsingT32()) {
10313    // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
10314    if (((registers.GetList() & ~0x5fff) == 0)) {
10315      EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
10316                 (write_back.GetWriteBackUint32() << 21) |
10317                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10318                 GetRegisterListEncoding(registers, 0, 13));
10319      AdvanceIT();
10320      return;
10321    }
10322  } else {
10323    // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
10324    if (cond.IsNotNever()) {
10325      EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10326              (write_back.GetWriteBackUint32() << 21) |
10327              GetRegisterListEncoding(registers, 0, 16));
10328      return;
10329    }
10330  }
10331  Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers);
10332}
10333
10334void Assembler::stmib(Condition cond,
10335                      Register rn,
10336                      WriteBack write_back,
10337                      RegisterList registers) {
10338  VIXL_ASSERT(AllowAssembler());
10339  CheckIT(cond);
10340  if (IsUsingA32()) {
10341    // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
10342    if (cond.IsNotNever()) {
10343      EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10344              (write_back.GetWriteBackUint32() << 21) |
10345              GetRegisterListEncoding(registers, 0, 16));
10346      return;
10347    }
10348  }
10349  Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers);
10350}
10351
10352void Assembler::str(Condition cond,
10353                    EncodingSize size,
10354                    Register rt,
10355                    const MemOperand& operand) {
10356  VIXL_ASSERT(AllowAssembler());
10357  CheckIT(cond);
10358  if (operand.IsImmediate()) {
10359    Register rn = operand.GetBaseRegister();
10360    int32_t offset = operand.GetOffsetImmediate();
10361    if (IsUsingT32()) {
10362      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10363      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10364          (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
10365        int32_t offset_ = offset >> 2;
10366        EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) |
10367                   ((offset_ & 0x1f) << 6));
10368        AdvanceIT();
10369        return;
10370      }
10371      // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
10372      if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
10373          ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
10374        int32_t offset_ = offset >> 2;
10375        EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff));
10376        AdvanceIT();
10377        return;
10378      }
10379      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
10380      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10381          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10382        EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10383                   (offset & 0xfff));
10384        AdvanceIT();
10385        return;
10386      }
10387      // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
10388      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10389          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10390        EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10391                   (-offset & 0xff));
10392        AdvanceIT();
10393        return;
10394      }
10395      // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
10396      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10397          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10398        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10399        uint32_t offset_ = abs(offset);
10400        EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10401                   offset_ | (sign << 9));
10402        AdvanceIT();
10403        return;
10404      }
10405      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
10406      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10407          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10408        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10409        uint32_t offset_ = abs(offset);
10410        EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10411                   offset_ | (sign << 9));
10412        AdvanceIT();
10413        return;
10414      }
10415    } else {
10416      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10417      if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
10418          cond.IsNotNever()) {
10419        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10420        uint32_t offset_ = abs(offset);
10421        EmitA32(0x05000000U | (cond.GetCondition() << 28) |
10422                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10423                (sign << 23));
10424        return;
10425      }
10426      // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10427      if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
10428          cond.IsNotNever()) {
10429        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10430        uint32_t offset_ = abs(offset);
10431        EmitA32(0x04000000U | (cond.GetCondition() << 28) |
10432                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10433                (sign << 23));
10434        return;
10435      }
10436      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10437      if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
10438          cond.IsNotNever()) {
10439        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10440        uint32_t offset_ = abs(offset);
10441        EmitA32(0x05200000U | (cond.GetCondition() << 28) |
10442                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10443                (sign << 23));
10444        return;
10445      }
10446    }
10447  }
10448  if (operand.IsPlainRegister()) {
10449    Register rn = operand.GetBaseRegister();
10450    Sign sign = operand.GetSign();
10451    Register rm = operand.GetOffsetRegister();
10452    if (IsUsingT32()) {
10453      // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
10454      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
10455          sign.IsPlus() && operand.IsOffset()) {
10456        EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) |
10457                   (rm.GetCode() << 6));
10458        AdvanceIT();
10459        return;
10460      }
10461    }
10462  }
10463  if (operand.IsShiftedRegister()) {
10464    Register rn = operand.GetBaseRegister();
10465    Sign sign = operand.GetSign();
10466    Register rm = operand.GetOffsetRegister();
10467    Shift shift = operand.GetShift();
10468    uint32_t amount = operand.GetShiftAmount();
10469    if (IsUsingT32()) {
10470      // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
10471      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
10472          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10473        EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10474                   rm.GetCode() | (amount << 4));
10475        AdvanceIT();
10476        return;
10477      }
10478    } else {
10479      // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
10480      if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
10481        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10482        uint32_t shift_ = TypeEncodingValue(shift);
10483        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10484        EmitA32(0x07000000U | (cond.GetCondition() << 28) |
10485                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10486                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10487        return;
10488      }
10489      // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
10490      if (operand.IsShiftValid() && operand.IsPostIndex() &&
10491          cond.IsNotNever()) {
10492        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10493        uint32_t shift_ = TypeEncodingValue(shift);
10494        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10495        EmitA32(0x06000000U | (cond.GetCondition() << 28) |
10496                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10497                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10498        return;
10499      }
10500      // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
10501      if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
10502        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10503        uint32_t shift_ = TypeEncodingValue(shift);
10504        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10505        EmitA32(0x07200000U | (cond.GetCondition() << 28) |
10506                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10507                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10508        return;
10509      }
10510    }
10511  }
10512  Delegate(kStr, &Assembler::str, cond, size, rt, operand);
10513}
10514
10515void Assembler::strb(Condition cond,
10516                     EncodingSize size,
10517                     Register rt,
10518                     const MemOperand& operand) {
10519  VIXL_ASSERT(AllowAssembler());
10520  CheckIT(cond);
10521  if (operand.IsImmediate()) {
10522    Register rn = operand.GetBaseRegister();
10523    int32_t offset = operand.GetOffsetImmediate();
10524    if (IsUsingT32()) {
10525      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10526      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10527          (offset <= 31) && operand.IsOffset()) {
10528        EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) |
10529                   ((offset & 0x1f) << 6));
10530        AdvanceIT();
10531        return;
10532      }
10533      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
10534      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10535          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10536        EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10537                   (offset & 0xfff));
10538        AdvanceIT();
10539        return;
10540      }
10541      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
10542      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10543          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10544        EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10545                   (-offset & 0xff));
10546        AdvanceIT();
10547        return;
10548      }
10549      // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
10550      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10551          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10552        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10553        uint32_t offset_ = abs(offset);
10554        EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10555                   offset_ | (sign << 9));
10556        AdvanceIT();
10557        return;
10558      }
10559      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
10560      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10561          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10562        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10563        uint32_t offset_ = abs(offset);
10564        EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10565                   offset_ | (sign << 9));
10566        AdvanceIT();
10567        return;
10568      }
10569    } else {
10570      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10571      if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
10572          cond.IsNotNever()) {
10573        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10574        uint32_t offset_ = abs(offset);
10575        EmitA32(0x05400000U | (cond.GetCondition() << 28) |
10576                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10577                (sign << 23));
10578        return;
10579      }
10580      // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10581      if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
10582          cond.IsNotNever()) {
10583        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10584        uint32_t offset_ = abs(offset);
10585        EmitA32(0x04400000U | (cond.GetCondition() << 28) |
10586                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10587                (sign << 23));
10588        return;
10589      }
10590      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10591      if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
10592          cond.IsNotNever()) {
10593        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10594        uint32_t offset_ = abs(offset);
10595        EmitA32(0x05600000U | (cond.GetCondition() << 28) |
10596                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10597                (sign << 23));
10598        return;
10599      }
10600    }
10601  }
10602  if (operand.IsPlainRegister()) {
10603    Register rn = operand.GetBaseRegister();
10604    Sign sign = operand.GetSign();
10605    Register rm = operand.GetOffsetRegister();
10606    if (IsUsingT32()) {
10607      // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
10608      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
10609          sign.IsPlus() && operand.IsOffset()) {
10610        EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) |
10611                   (rm.GetCode() << 6));
10612        AdvanceIT();
10613        return;
10614      }
10615    }
10616  }
10617  if (operand.IsShiftedRegister()) {
10618    Register rn = operand.GetBaseRegister();
10619    Sign sign = operand.GetSign();
10620    Register rm = operand.GetOffsetRegister();
10621    Shift shift = operand.GetShift();
10622    uint32_t amount = operand.GetShiftAmount();
10623    if (IsUsingT32()) {
10624      // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
10625      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
10626          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10627        EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10628                   rm.GetCode() | (amount << 4));
10629        AdvanceIT();
10630        return;
10631      }
10632    } else {
10633      // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
10634      if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
10635        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10636        uint32_t shift_ = TypeEncodingValue(shift);
10637        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10638        EmitA32(0x07400000U | (cond.GetCondition() << 28) |
10639                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10640                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10641        return;
10642      }
10643      // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
10644      if (operand.IsShiftValid() && operand.IsPostIndex() &&
10645          cond.IsNotNever()) {
10646        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10647        uint32_t shift_ = TypeEncodingValue(shift);
10648        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10649        EmitA32(0x06400000U | (cond.GetCondition() << 28) |
10650                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10651                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10652        return;
10653      }
10654      // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
10655      if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
10656        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10657        uint32_t shift_ = TypeEncodingValue(shift);
10658        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10659        EmitA32(0x07600000U | (cond.GetCondition() << 28) |
10660                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10661                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10662        return;
10663      }
10664    }
10665  }
10666  Delegate(kStrb, &Assembler::strb, cond, size, rt, operand);
10667}
10668
10669void Assembler::strd(Condition cond,
10670                     Register rt,
10671                     Register rt2,
10672                     const MemOperand& operand) {
10673  VIXL_ASSERT(AllowAssembler());
10674  CheckIT(cond);
10675  if (operand.IsImmediate()) {
10676    Register rn = operand.GetBaseRegister();
10677    int32_t offset = operand.GetOffsetImmediate();
10678    if (IsUsingT32()) {
10679      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
10680      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10681          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10682        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10683        uint32_t offset_ = abs(offset) >> 2;
10684        EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10685                   (rn.GetCode() << 16) | offset_ | (sign << 23));
10686        AdvanceIT();
10687        return;
10688      }
10689      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
10690      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10691          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10692        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10693        uint32_t offset_ = abs(offset) >> 2;
10694        EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10695                   (rn.GetCode() << 16) | offset_ | (sign << 23));
10696        AdvanceIT();
10697        return;
10698      }
10699      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
10700      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10701          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10702        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10703        uint32_t offset_ = abs(offset) >> 2;
10704        EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10705                   (rn.GetCode() << 16) | offset_ | (sign << 23));
10706        AdvanceIT();
10707        return;
10708      }
10709    } else {
10710      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
10711      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10712          (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
10713          cond.IsNotNever() &&
10714          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10715        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10716        uint32_t offset_ = abs(offset);
10717        EmitA32(0x014000f0U | (cond.GetCondition() << 28) |
10718                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10719                ((offset_ & 0xf0) << 4) | (sign << 23));
10720        return;
10721      }
10722      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
10723      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10724          (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
10725          cond.IsNotNever() &&
10726          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10727        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10728        uint32_t offset_ = abs(offset);
10729        EmitA32(0x004000f0U | (cond.GetCondition() << 28) |
10730                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10731                ((offset_ & 0xf0) << 4) | (sign << 23));
10732        return;
10733      }
10734      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
10735      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10736          (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
10737          cond.IsNotNever() &&
10738          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10739        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10740        uint32_t offset_ = abs(offset);
10741        EmitA32(0x016000f0U | (cond.GetCondition() << 28) |
10742                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10743                ((offset_ & 0xf0) << 4) | (sign << 23));
10744        return;
10745      }
10746    }
10747  }
10748  if (operand.IsPlainRegister()) {
10749    Register rn = operand.GetBaseRegister();
10750    Sign sign = operand.GetSign();
10751    Register rm = operand.GetOffsetRegister();
10752    if (IsUsingA32()) {
10753      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
10754      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10755          operand.IsOffset() && cond.IsNotNever() &&
10756          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10757        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10758        EmitA32(0x010000f0U | (cond.GetCondition() << 28) |
10759                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10760                (sign_ << 23));
10761        return;
10762      }
10763      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
10764      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10765          operand.IsPostIndex() && cond.IsNotNever() &&
10766          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10767        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10768        EmitA32(0x000000f0U | (cond.GetCondition() << 28) |
10769                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10770                (sign_ << 23));
10771        return;
10772      }
10773      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
10774      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10775          operand.IsPreIndex() && cond.IsNotNever() &&
10776          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10777        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10778        EmitA32(0x012000f0U | (cond.GetCondition() << 28) |
10779                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10780                (sign_ << 23));
10781        return;
10782      }
10783    }
10784  }
10785  Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand);
10786}
10787
10788void Assembler::strex(Condition cond,
10789                      Register rd,
10790                      Register rt,
10791                      const MemOperand& operand) {
10792  VIXL_ASSERT(AllowAssembler());
10793  CheckIT(cond);
10794  if (operand.IsImmediate()) {
10795    Register rn = operand.GetBaseRegister();
10796    int32_t offset = operand.GetOffsetImmediate();
10797    if (IsUsingT32()) {
10798      // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1
10799      if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
10800          operand.IsOffset()) {
10801        int32_t offset_ = offset >> 2;
10802        EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) |
10803                   (rn.GetCode() << 16) | (offset_ & 0xff));
10804        AdvanceIT();
10805        return;
10806      }
10807    } else {
10808      // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1
10809      if ((offset == 0) && operand.IsOffset() && cond.IsNotNever()) {
10810        EmitA32(0x01800f90U | (cond.GetCondition() << 28) |
10811                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10812        return;
10813      }
10814    }
10815  }
10816  Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand);
10817}
10818
10819void Assembler::strexb(Condition cond,
10820                       Register rd,
10821                       Register rt,
10822                       const MemOperand& operand) {
10823  VIXL_ASSERT(AllowAssembler());
10824  CheckIT(cond);
10825  if (operand.IsImmediateZero()) {
10826    Register rn = operand.GetBaseRegister();
10827    if (IsUsingT32()) {
10828      // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10829      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10830        EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) |
10831                   (rn.GetCode() << 16));
10832        AdvanceIT();
10833        return;
10834      }
10835    } else {
10836      // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10837      if (operand.IsOffset() && cond.IsNotNever() &&
10838          (!rn.IsPC() || AllowUnpredictable())) {
10839        EmitA32(0x01c00f90U | (cond.GetCondition() << 28) |
10840                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10841        return;
10842      }
10843    }
10844  }
10845  Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand);
10846}
10847
10848void Assembler::strexd(Condition cond,
10849                       Register rd,
10850                       Register rt,
10851                       Register rt2,
10852                       const MemOperand& operand) {
10853  VIXL_ASSERT(AllowAssembler());
10854  CheckIT(cond);
10855  if (operand.IsImmediateZero()) {
10856    Register rn = operand.GetBaseRegister();
10857    if (IsUsingT32()) {
10858      // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
10859      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10860        EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) |
10861                   (rt2.GetCode() << 8) | (rn.GetCode() << 16));
10862        AdvanceIT();
10863        return;
10864      }
10865    } else {
10866      // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
10867      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10868          operand.IsOffset() && cond.IsNotNever() &&
10869          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
10870           AllowUnpredictable())) {
10871        EmitA32(0x01a00f90U | (cond.GetCondition() << 28) |
10872                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10873        return;
10874      }
10875    }
10876  }
10877  Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand);
10878}
10879
10880void Assembler::strexh(Condition cond,
10881                       Register rd,
10882                       Register rt,
10883                       const MemOperand& operand) {
10884  VIXL_ASSERT(AllowAssembler());
10885  CheckIT(cond);
10886  if (operand.IsImmediateZero()) {
10887    Register rn = operand.GetBaseRegister();
10888    if (IsUsingT32()) {
10889      // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10890      if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10891        EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) |
10892                   (rn.GetCode() << 16));
10893        AdvanceIT();
10894        return;
10895      }
10896    } else {
10897      // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10898      if (operand.IsOffset() && cond.IsNotNever() &&
10899          (!rn.IsPC() || AllowUnpredictable())) {
10900        EmitA32(0x01e00f90U | (cond.GetCondition() << 28) |
10901                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10902        return;
10903      }
10904    }
10905  }
10906  Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand);
10907}
10908
10909void Assembler::strh(Condition cond,
10910                     EncodingSize size,
10911                     Register rt,
10912                     const MemOperand& operand) {
10913  VIXL_ASSERT(AllowAssembler());
10914  CheckIT(cond);
10915  if (operand.IsImmediate()) {
10916    Register rn = operand.GetBaseRegister();
10917    int32_t offset = operand.GetOffsetImmediate();
10918    if (IsUsingT32()) {
10919      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10920      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10921          (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
10922        int32_t offset_ = offset >> 1;
10923        EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) |
10924                   ((offset_ & 0x1f) << 6));
10925        AdvanceIT();
10926        return;
10927      }
10928      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
10929      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10930          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10931        EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10932                   (offset & 0xfff));
10933        AdvanceIT();
10934        return;
10935      }
10936      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
10937      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10938          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10939        EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10940                   (-offset & 0xff));
10941        AdvanceIT();
10942        return;
10943      }
10944      // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
10945      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10946          operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10947        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10948        uint32_t offset_ = abs(offset);
10949        EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10950                   offset_ | (sign << 9));
10951        AdvanceIT();
10952        return;
10953      }
10954      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
10955      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10956          operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10957        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10958        uint32_t offset_ = abs(offset);
10959        EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10960                   offset_ | (sign << 9));
10961        AdvanceIT();
10962        return;
10963      }
10964    } else {
10965      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10966      if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
10967          cond.IsNotNever()) {
10968        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10969        uint32_t offset_ = abs(offset);
10970        EmitA32(0x014000b0U | (cond.GetCondition() << 28) |
10971                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10972                ((offset_ & 0xf0) << 4) | (sign << 23));
10973        return;
10974      }
10975      // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10976      if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
10977          cond.IsNotNever()) {
10978        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10979        uint32_t offset_ = abs(offset);
10980        EmitA32(0x004000b0U | (cond.GetCondition() << 28) |
10981                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10982                ((offset_ & 0xf0) << 4) | (sign << 23));
10983        return;
10984      }
10985      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10986      if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
10987          cond.IsNotNever()) {
10988        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10989        uint32_t offset_ = abs(offset);
10990        EmitA32(0x016000b0U | (cond.GetCondition() << 28) |
10991                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10992                ((offset_ & 0xf0) << 4) | (sign << 23));
10993        return;
10994      }
10995    }
10996  }
10997  if (operand.IsPlainRegister()) {
10998    Register rn = operand.GetBaseRegister();
10999    Sign sign = operand.GetSign();
11000    Register rm = operand.GetOffsetRegister();
11001    if (IsUsingT32()) {
11002      // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
11003      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
11004          sign.IsPlus() && operand.IsOffset()) {
11005        EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) |
11006                   (rm.GetCode() << 6));
11007        AdvanceIT();
11008        return;
11009      }
11010    } else {
11011      // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
11012      if (operand.IsOffset() && cond.IsNotNever()) {
11013        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11014        EmitA32(0x010000b0U | (cond.GetCondition() << 28) |
11015                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11016                (sign_ << 23));
11017        return;
11018      }
11019      // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
11020      if (operand.IsPostIndex() && cond.IsNotNever()) {
11021        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11022        EmitA32(0x000000b0U | (cond.GetCondition() << 28) |
11023                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11024                (sign_ << 23));
11025        return;
11026      }
11027      // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
11028      if (operand.IsPreIndex() && cond.IsNotNever()) {
11029        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11030        EmitA32(0x012000b0U | (cond.GetCondition() << 28) |
11031                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11032                (sign_ << 23));
11033        return;
11034      }
11035    }
11036  }
11037  if (operand.IsShiftedRegister()) {
11038    Register rn = operand.GetBaseRegister();
11039    Sign sign = operand.GetSign();
11040    Register rm = operand.GetOffsetRegister();
11041    Shift shift = operand.GetShift();
11042    uint32_t amount = operand.GetShiftAmount();
11043    if (IsUsingT32()) {
11044      // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
11045      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
11046          operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
11047        EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11048                   rm.GetCode() | (amount << 4));
11049        AdvanceIT();
11050        return;
11051      }
11052    }
11053  }
11054  Delegate(kStrh, &Assembler::strh, cond, size, rt, operand);
11055}
11056
11057void Assembler::sub(Condition cond,
11058                    EncodingSize size,
11059                    Register rd,
11060                    Register rn,
11061                    const Operand& operand) {
11062  VIXL_ASSERT(AllowAssembler());
11063  CheckIT(cond);
11064  if (operand.IsImmediate()) {
11065    uint32_t imm = operand.GetImmediate();
11066    if (IsUsingT32()) {
11067      ImmediateT32 immediate_t32(imm);
11068      // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
11069      if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11070          (imm <= 7)) {
11071        EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
11072        AdvanceIT();
11073        return;
11074      }
11075      // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
11076      if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
11077          (imm <= 255)) {
11078        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11079        AdvanceIT();
11080        return;
11081      }
11082      // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1
11083      if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
11084          ((imm % 4) == 0)) {
11085        uint32_t imm_ = imm >> 2;
11086        EmitT32_16(0xb080 | imm_);
11087        AdvanceIT();
11088        return;
11089      }
11090      // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2
11091      if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095)) {
11092        EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) |
11093                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11094        AdvanceIT();
11095        return;
11096      }
11097      // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
11098      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp)) {
11099        EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11100                   (immediate_t32.GetEncodingValue() & 0xff) |
11101                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11102                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11103        AdvanceIT();
11104        return;
11105      }
11106      // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
11107      if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
11108        EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11109                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11110        AdvanceIT();
11111        return;
11112      }
11113      // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
11114      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid()) {
11115        EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) |
11116                   (immediate_t32.GetEncodingValue() & 0xff) |
11117                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11118                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11119        AdvanceIT();
11120        return;
11121      }
11122      // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
11123      if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095)) {
11124        EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
11125                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11126        AdvanceIT();
11127        return;
11128      }
11129    } else {
11130      ImmediateA32 immediate_a32(imm);
11131      // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2
11132      if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
11133        EmitA32(0x024f0000U | (cond.GetCondition() << 28) |
11134                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
11135        return;
11136      }
11137      // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
11138      if (immediate_a32.IsValid() && cond.IsNotNever() &&
11139          ((rn.GetCode() & 0xd) != 0xd)) {
11140        EmitA32(0x02400000U | (cond.GetCondition() << 28) |
11141                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
11142                immediate_a32.GetEncodingValue());
11143        return;
11144      }
11145      // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
11146      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
11147        EmitA32(0x024d0000U | (cond.GetCondition() << 28) |
11148                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
11149        return;
11150      }
11151    }
11152  }
11153  if (operand.IsImmediateShiftedRegister()) {
11154    Register rm = operand.GetBaseRegister();
11155    if (operand.IsPlainRegister()) {
11156      if (IsUsingT32()) {
11157        // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
11158        if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11159            rm.IsLow()) {
11160          EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
11161                     (rm.GetCode() << 6));
11162          AdvanceIT();
11163          return;
11164        }
11165        // SUB{<c>} {<Rd>}, SP, <Rm> ; T1
11166        if (rn.Is(sp)) {
11167          EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode());
11168          AdvanceIT();
11169          return;
11170        }
11171      }
11172    }
11173    Shift shift = operand.GetShift();
11174    uint32_t amount = operand.GetShiftAmount();
11175    if (IsUsingT32()) {
11176      // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
11177      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp)) {
11178        uint32_t amount_ = amount % 32;
11179        EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11180                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
11181                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11182        AdvanceIT();
11183        return;
11184      }
11185      // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
11186      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount)) {
11187        uint32_t amount_ = amount % 32;
11188        EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() |
11189                   (operand.GetTypeEncodingValue() << 4) |
11190                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11191        AdvanceIT();
11192        return;
11193      }
11194    } else {
11195      // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
11196      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
11197        uint32_t amount_ = amount % 32;
11198        EmitA32(0x00400000U | (cond.GetCondition() << 28) |
11199                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11200                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11201        return;
11202      }
11203      // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
11204      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
11205        uint32_t amount_ = amount % 32;
11206        EmitA32(0x004d0000U | (cond.GetCondition() << 28) |
11207                (rd.GetCode() << 12) | rm.GetCode() |
11208                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11209        return;
11210      }
11211    }
11212  }
11213  if (operand.IsRegisterShiftedRegister()) {
11214    Register rm = operand.GetBaseRegister();
11215    Shift shift = operand.GetShift();
11216    if (IsUsingA32()) {
11217      // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
11218      if (cond.IsNotNever()) {
11219        EmitA32(0x00400010U | (cond.GetCondition() << 28) |
11220                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11221                (shift.GetType() << 5) |
11222                (operand.GetShiftRegister().GetCode() << 8));
11223        return;
11224      }
11225    }
11226  }
11227  Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand);
11228}
11229
11230void Assembler::sub(Condition cond, Register rd, const Operand& operand) {
11231  VIXL_ASSERT(AllowAssembler());
11232  CheckIT(cond);
11233  if (operand.IsImmediate()) {
11234    uint32_t imm = operand.GetImmediate();
11235    if (IsUsingT32()) {
11236      // SUB<c>{<q>} <Rdn>, #<imm8> ; T2
11237      if (InITBlock() && rd.IsLow() && (imm <= 255)) {
11238        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11239        AdvanceIT();
11240        return;
11241      }
11242    }
11243  }
11244  Delegate(kSub, &Assembler::sub, cond, rd, operand);
11245}
11246
11247void Assembler::subs(Condition cond,
11248                     EncodingSize size,
11249                     Register rd,
11250                     Register rn,
11251                     const Operand& operand) {
11252  VIXL_ASSERT(AllowAssembler());
11253  CheckIT(cond);
11254  if (operand.IsImmediate()) {
11255    uint32_t imm = operand.GetImmediate();
11256    if (IsUsingT32()) {
11257      ImmediateT32 immediate_t32(imm);
11258      // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1
11259      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11260          (imm <= 7)) {
11261        EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
11262        AdvanceIT();
11263        return;
11264      }
11265      // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
11266      if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
11267          (imm <= 255)) {
11268        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11269        AdvanceIT();
11270        return;
11271      }
11272      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
11273      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
11274          !rd.Is(pc)) {
11275        EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11276                   (immediate_t32.GetEncodingValue() & 0xff) |
11277                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11278                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11279        AdvanceIT();
11280        return;
11281      }
11282      // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5
11283      if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255)) {
11284        EmitT32_32(0xf3de8f00U | imm);
11285        AdvanceIT();
11286        return;
11287      }
11288      // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
11289      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
11290          !rd.Is(pc)) {
11291        EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) |
11292                   (immediate_t32.GetEncodingValue() & 0xff) |
11293                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11294                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11295        AdvanceIT();
11296        return;
11297      }
11298    } else {
11299      ImmediateA32 immediate_a32(imm);
11300      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
11301      if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
11302        EmitA32(0x02500000U | (cond.GetCondition() << 28) |
11303                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
11304                immediate_a32.GetEncodingValue());
11305        return;
11306      }
11307      // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
11308      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
11309        EmitA32(0x025d0000U | (cond.GetCondition() << 28) |
11310                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
11311        return;
11312      }
11313    }
11314  }
11315  if (operand.IsImmediateShiftedRegister()) {
11316    Register rm = operand.GetBaseRegister();
11317    if (operand.IsPlainRegister()) {
11318      if (IsUsingT32()) {
11319        // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11320        if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11321            rm.IsLow()) {
11322          EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
11323                     (rm.GetCode() << 6));
11324          AdvanceIT();
11325          return;
11326        }
11327      }
11328    }
11329    Shift shift = operand.GetShift();
11330    uint32_t amount = operand.GetShiftAmount();
11331    if (IsUsingT32()) {
11332      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
11333      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
11334          !rd.Is(pc)) {
11335        uint32_t amount_ = amount % 32;
11336        EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11337                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
11338                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11339        AdvanceIT();
11340        return;
11341      }
11342      // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
11343      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
11344          !rd.Is(pc)) {
11345        uint32_t amount_ = amount % 32;
11346        EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() |
11347                   (operand.GetTypeEncodingValue() << 4) |
11348                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11349        AdvanceIT();
11350        return;
11351      }
11352    } else {
11353      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
11354      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
11355        uint32_t amount_ = amount % 32;
11356        EmitA32(0x00500000U | (cond.GetCondition() << 28) |
11357                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11358                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11359        return;
11360      }
11361      // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
11362      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
11363        uint32_t amount_ = amount % 32;
11364        EmitA32(0x005d0000U | (cond.GetCondition() << 28) |
11365                (rd.GetCode() << 12) | rm.GetCode() |
11366                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11367        return;
11368      }
11369    }
11370  }
11371  if (operand.IsRegisterShiftedRegister()) {
11372    Register rm = operand.GetBaseRegister();
11373    Shift shift = operand.GetShift();
11374    if (IsUsingA32()) {
11375      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
11376      if (cond.IsNotNever()) {
11377        EmitA32(0x00500010U | (cond.GetCondition() << 28) |
11378                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11379                (shift.GetType() << 5) |
11380                (operand.GetShiftRegister().GetCode() << 8));
11381        return;
11382      }
11383    }
11384  }
11385  Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand);
11386}
11387
11388void Assembler::subs(Register rd, const Operand& operand) {
11389  VIXL_ASSERT(AllowAssembler());
11390  CheckIT(al);
11391  if (operand.IsImmediate()) {
11392    uint32_t imm = operand.GetImmediate();
11393    if (IsUsingT32()) {
11394      // SUBS{<q>} <Rdn>, #<imm8> ; T2
11395      if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
11396        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11397        AdvanceIT();
11398        return;
11399      }
11400    }
11401  }
11402  Delegate(kSubs, &Assembler::subs, rd, operand);
11403}
11404
11405void Assembler::subw(Condition cond,
11406                     Register rd,
11407                     Register rn,
11408                     const Operand& operand) {
11409  VIXL_ASSERT(AllowAssembler());
11410  CheckIT(cond);
11411  if (operand.IsImmediate()) {
11412    uint32_t imm = operand.GetImmediate();
11413    if (IsUsingT32()) {
11414      // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
11415      if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
11416        EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11417                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11418        AdvanceIT();
11419        return;
11420      }
11421      // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
11422      if (rn.Is(sp) && (imm <= 4095)) {
11423        EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
11424                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11425        AdvanceIT();
11426        return;
11427      }
11428    }
11429  }
11430  Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand);
11431}
11432
11433void Assembler::svc(Condition cond, uint32_t imm) {
11434  VIXL_ASSERT(AllowAssembler());
11435  CheckIT(cond);
11436  if (IsUsingT32()) {
11437    // SVC{<c>}{<q>} {#}<imm> ; T1
11438    if ((imm <= 255)) {
11439      EmitT32_16(0xdf00 | imm);
11440      AdvanceIT();
11441      return;
11442    }
11443  } else {
11444    // SVC{<c>}{<q>} {#}<imm> ; A1
11445    if ((imm <= 16777215) && cond.IsNotNever()) {
11446      EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm);
11447      return;
11448    }
11449  }
11450  Delegate(kSvc, &Assembler::svc, cond, imm);
11451}
11452
11453void Assembler::sxtab(Condition cond,
11454                      Register rd,
11455                      Register rn,
11456                      const Operand& operand) {
11457  VIXL_ASSERT(AllowAssembler());
11458  CheckIT(cond);
11459  if (operand.IsImmediateShiftedRegister()) {
11460    Register rm = operand.GetBaseRegister();
11461    Shift shift = operand.GetShift();
11462    uint32_t amount = operand.GetShiftAmount();
11463    if (IsUsingT32()) {
11464      // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11465      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11466          ((amount % 8) == 0) && !rn.Is(pc)) {
11467        uint32_t amount_ = amount / 8;
11468        EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11469                   rm.GetCode() | (amount_ << 4));
11470        AdvanceIT();
11471        return;
11472      }
11473    } else {
11474      // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11475      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11476          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11477        uint32_t amount_ = amount / 8;
11478        EmitA32(0x06a00070U | (cond.GetCondition() << 28) |
11479                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11480                (amount_ << 10));
11481        return;
11482      }
11483    }
11484  }
11485  Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand);
11486}
11487
11488void Assembler::sxtab16(Condition cond,
11489                        Register rd,
11490                        Register rn,
11491                        const Operand& operand) {
11492  VIXL_ASSERT(AllowAssembler());
11493  CheckIT(cond);
11494  if (operand.IsImmediateShiftedRegister()) {
11495    Register rm = operand.GetBaseRegister();
11496    Shift shift = operand.GetShift();
11497    uint32_t amount = operand.GetShiftAmount();
11498    if (IsUsingT32()) {
11499      // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11500      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11501          ((amount % 8) == 0) && !rn.Is(pc)) {
11502        uint32_t amount_ = amount / 8;
11503        EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11504                   rm.GetCode() | (amount_ << 4));
11505        AdvanceIT();
11506        return;
11507      }
11508    } else {
11509      // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11510      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11511          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11512        uint32_t amount_ = amount / 8;
11513        EmitA32(0x06800070U | (cond.GetCondition() << 28) |
11514                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11515                (amount_ << 10));
11516        return;
11517      }
11518    }
11519  }
11520  Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand);
11521}
11522
11523void Assembler::sxtah(Condition cond,
11524                      Register rd,
11525                      Register rn,
11526                      const Operand& operand) {
11527  VIXL_ASSERT(AllowAssembler());
11528  CheckIT(cond);
11529  if (operand.IsImmediateShiftedRegister()) {
11530    Register rm = operand.GetBaseRegister();
11531    Shift shift = operand.GetShift();
11532    uint32_t amount = operand.GetShiftAmount();
11533    if (IsUsingT32()) {
11534      // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11535      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11536          ((amount % 8) == 0) && !rn.Is(pc)) {
11537        uint32_t amount_ = amount / 8;
11538        EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11539                   rm.GetCode() | (amount_ << 4));
11540        AdvanceIT();
11541        return;
11542      }
11543    } else {
11544      // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11545      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11546          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11547        uint32_t amount_ = amount / 8;
11548        EmitA32(0x06b00070U | (cond.GetCondition() << 28) |
11549                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11550                (amount_ << 10));
11551        return;
11552      }
11553    }
11554  }
11555  Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand);
11556}
11557
11558void Assembler::sxtb(Condition cond,
11559                     EncodingSize size,
11560                     Register rd,
11561                     const Operand& operand) {
11562  VIXL_ASSERT(AllowAssembler());
11563  CheckIT(cond);
11564  if (operand.IsImmediateShiftedRegister()) {
11565    Register rm = operand.GetBaseRegister();
11566    if (operand.IsPlainRegister()) {
11567      if (IsUsingT32()) {
11568        // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
11569        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
11570          EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3));
11571          AdvanceIT();
11572          return;
11573        }
11574      }
11575    }
11576    Shift shift = operand.GetShift();
11577    uint32_t amount = operand.GetShiftAmount();
11578    if (IsUsingT32()) {
11579      // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
11580      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
11581          (amount <= 24) && ((amount % 8) == 0)) {
11582        uint32_t amount_ = amount / 8;
11583        EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11584                   (amount_ << 4));
11585        AdvanceIT();
11586        return;
11587      }
11588    } else {
11589      // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11590      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11591          ((amount % 8) == 0) && cond.IsNotNever()) {
11592        uint32_t amount_ = amount / 8;
11593        EmitA32(0x06af0070U | (cond.GetCondition() << 28) |
11594                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11595        return;
11596      }
11597    }
11598  }
11599  Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand);
11600}
11601
11602void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) {
11603  VIXL_ASSERT(AllowAssembler());
11604  CheckIT(cond);
11605  if (operand.IsImmediateShiftedRegister()) {
11606    Register rm = operand.GetBaseRegister();
11607    Shift shift = operand.GetShift();
11608    uint32_t amount = operand.GetShiftAmount();
11609    if (IsUsingT32()) {
11610      // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
11611      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11612          ((amount % 8) == 0)) {
11613        uint32_t amount_ = amount / 8;
11614        EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11615                   (amount_ << 4));
11616        AdvanceIT();
11617        return;
11618      }
11619    } else {
11620      // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11621      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11622          ((amount % 8) == 0) && cond.IsNotNever()) {
11623        uint32_t amount_ = amount / 8;
11624        EmitA32(0x068f0070U | (cond.GetCondition() << 28) |
11625                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11626        return;
11627      }
11628    }
11629  }
11630  Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand);
11631}
11632
11633void Assembler::sxth(Condition cond,
11634                     EncodingSize size,
11635                     Register rd,
11636                     const Operand& operand) {
11637  VIXL_ASSERT(AllowAssembler());
11638  CheckIT(cond);
11639  if (operand.IsImmediateShiftedRegister()) {
11640    Register rm = operand.GetBaseRegister();
11641    if (operand.IsPlainRegister()) {
11642      if (IsUsingT32()) {
11643        // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
11644        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
11645          EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3));
11646          AdvanceIT();
11647          return;
11648        }
11649      }
11650    }
11651    Shift shift = operand.GetShift();
11652    uint32_t amount = operand.GetShiftAmount();
11653    if (IsUsingT32()) {
11654      // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
11655      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
11656          (amount <= 24) && ((amount % 8) == 0)) {
11657        uint32_t amount_ = amount / 8;
11658        EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11659                   (amount_ << 4));
11660        AdvanceIT();
11661        return;
11662      }
11663    } else {
11664      // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11665      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11666          ((amount % 8) == 0) && cond.IsNotNever()) {
11667        uint32_t amount_ = amount / 8;
11668        EmitA32(0x06bf0070U | (cond.GetCondition() << 28) |
11669                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11670        return;
11671      }
11672    }
11673  }
11674  Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand);
11675}
11676
11677void Assembler::tbb(Condition cond, Register rn, Register rm) {
11678  VIXL_ASSERT(AllowAssembler());
11679  CheckIT(cond);
11680  if (IsUsingT32()) {
11681    // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1
11682    if (OutsideITBlockAndAlOrLast(cond) &&
11683        (!rm.IsPC() || AllowUnpredictable())) {
11684      EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode());
11685      AdvanceIT();
11686      return;
11687    }
11688  }
11689  Delegate(kTbb, &Assembler::tbb, cond, rn, rm);
11690}
11691
11692void Assembler::tbh(Condition cond, Register rn, Register rm) {
11693  VIXL_ASSERT(AllowAssembler());
11694  CheckIT(cond);
11695  if (IsUsingT32()) {
11696    // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1
11697    if (OutsideITBlockAndAlOrLast(cond) &&
11698        (!rm.IsPC() || AllowUnpredictable())) {
11699      EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode());
11700      AdvanceIT();
11701      return;
11702    }
11703  }
11704  Delegate(kTbh, &Assembler::tbh, cond, rn, rm);
11705}
11706
11707void Assembler::teq(Condition cond, Register rn, const Operand& operand) {
11708  VIXL_ASSERT(AllowAssembler());
11709  CheckIT(cond);
11710  if (operand.IsImmediate()) {
11711    uint32_t imm = operand.GetImmediate();
11712    if (IsUsingT32()) {
11713      ImmediateT32 immediate_t32(imm);
11714      // TEQ{<c>}{<q>} <Rn>, #<const> ; T1
11715      if (immediate_t32.IsValid()) {
11716        EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) |
11717                   (immediate_t32.GetEncodingValue() & 0xff) |
11718                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11719                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11720        AdvanceIT();
11721        return;
11722      }
11723    } else {
11724      ImmediateA32 immediate_a32(imm);
11725      // TEQ{<c>}{<q>} <Rn>, #<const> ; A1
11726      if (immediate_a32.IsValid() && cond.IsNotNever()) {
11727        EmitA32(0x03300000U | (cond.GetCondition() << 28) |
11728                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
11729        return;
11730      }
11731    }
11732  }
11733  if (operand.IsImmediateShiftedRegister()) {
11734    Register rm = operand.GetBaseRegister();
11735    Shift shift = operand.GetShift();
11736    uint32_t amount = operand.GetShiftAmount();
11737    if (IsUsingT32()) {
11738      // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1
11739      if (shift.IsValidAmount(amount)) {
11740        uint32_t amount_ = amount % 32;
11741        EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() |
11742                   (operand.GetTypeEncodingValue() << 4) |
11743                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11744        AdvanceIT();
11745        return;
11746      }
11747    } else {
11748      // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
11749      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
11750        uint32_t amount_ = amount % 32;
11751        EmitA32(0x01300000U | (cond.GetCondition() << 28) |
11752                (rn.GetCode() << 16) | rm.GetCode() |
11753                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11754        return;
11755      }
11756    }
11757  }
11758  if (operand.IsRegisterShiftedRegister()) {
11759    Register rm = operand.GetBaseRegister();
11760    Shift shift = operand.GetShift();
11761    if (IsUsingA32()) {
11762      // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
11763      if (cond.IsNotNever()) {
11764        EmitA32(0x01300010U | (cond.GetCondition() << 28) |
11765                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
11766                (operand.GetShiftRegister().GetCode() << 8));
11767        return;
11768      }
11769    }
11770  }
11771  Delegate(kTeq, &Assembler::teq, cond, rn, operand);
11772}
11773
11774void Assembler::tst(Condition cond,
11775                    EncodingSize size,
11776                    Register rn,
11777                    const Operand& operand) {
11778  VIXL_ASSERT(AllowAssembler());
11779  CheckIT(cond);
11780  if (operand.IsImmediate()) {
11781    uint32_t imm = operand.GetImmediate();
11782    if (IsUsingT32()) {
11783      ImmediateT32 immediate_t32(imm);
11784      // TST{<c>}{<q>} <Rn>, #<const> ; T1
11785      if (!size.IsNarrow() && immediate_t32.IsValid()) {
11786        EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) |
11787                   (immediate_t32.GetEncodingValue() & 0xff) |
11788                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11789                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11790        AdvanceIT();
11791        return;
11792      }
11793    } else {
11794      ImmediateA32 immediate_a32(imm);
11795      // TST{<c>}{<q>} <Rn>, #<const> ; A1
11796      if (immediate_a32.IsValid() && cond.IsNotNever()) {
11797        EmitA32(0x03100000U | (cond.GetCondition() << 28) |
11798                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
11799        return;
11800      }
11801    }
11802  }
11803  if (operand.IsImmediateShiftedRegister()) {
11804    Register rm = operand.GetBaseRegister();
11805    if (operand.IsPlainRegister()) {
11806      if (IsUsingT32()) {
11807        // TST{<c>}{<q>} <Rn>, <Rm> ; T1
11808        if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
11809          EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3));
11810          AdvanceIT();
11811          return;
11812        }
11813      }
11814    }
11815    Shift shift = operand.GetShift();
11816    uint32_t amount = operand.GetShiftAmount();
11817    if (IsUsingT32()) {
11818      // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
11819      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
11820        uint32_t amount_ = amount % 32;
11821        EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() |
11822                   (operand.GetTypeEncodingValue() << 4) |
11823                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11824        AdvanceIT();
11825        return;
11826      }
11827    } else {
11828      // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
11829      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
11830        uint32_t amount_ = amount % 32;
11831        EmitA32(0x01100000U | (cond.GetCondition() << 28) |
11832                (rn.GetCode() << 16) | rm.GetCode() |
11833                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11834        return;
11835      }
11836    }
11837  }
11838  if (operand.IsRegisterShiftedRegister()) {
11839    Register rm = operand.GetBaseRegister();
11840    Shift shift = operand.GetShift();
11841    if (IsUsingA32()) {
11842      // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
11843      if (cond.IsNotNever()) {
11844        EmitA32(0x01100010U | (cond.GetCondition() << 28) |
11845                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
11846                (operand.GetShiftRegister().GetCode() << 8));
11847        return;
11848      }
11849    }
11850  }
11851  Delegate(kTst, &Assembler::tst, cond, size, rn, operand);
11852}
11853
11854void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) {
11855  VIXL_ASSERT(AllowAssembler());
11856  CheckIT(cond);
11857  if (IsUsingT32()) {
11858    // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11859    EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11860               rm.GetCode());
11861    AdvanceIT();
11862    return;
11863  } else {
11864    // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11865    if (cond.IsNotNever()) {
11866      EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11867              (rn.GetCode() << 16) | rm.GetCode());
11868      return;
11869    }
11870  }
11871  Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm);
11872}
11873
11874void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) {
11875  VIXL_ASSERT(AllowAssembler());
11876  CheckIT(cond);
11877  if (IsUsingT32()) {
11878    // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11879    EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11880               rm.GetCode());
11881    AdvanceIT();
11882    return;
11883  } else {
11884    // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11885    if (cond.IsNotNever()) {
11886      EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11887              (rn.GetCode() << 16) | rm.GetCode());
11888      return;
11889    }
11890  }
11891  Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm);
11892}
11893
11894void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) {
11895  VIXL_ASSERT(AllowAssembler());
11896  CheckIT(cond);
11897  if (IsUsingT32()) {
11898    // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11899    EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11900               rm.GetCode());
11901    AdvanceIT();
11902    return;
11903  } else {
11904    // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11905    if (cond.IsNotNever()) {
11906      EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11907              (rn.GetCode() << 16) | rm.GetCode());
11908      return;
11909    }
11910  }
11911  Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm);
11912}
11913
11914void Assembler::ubfx(Condition cond,
11915                     Register rd,
11916                     Register rn,
11917                     uint32_t lsb,
11918                     const Operand& operand) {
11919  VIXL_ASSERT(AllowAssembler());
11920  CheckIT(cond);
11921  if (operand.IsImmediate()) {
11922    uint32_t width = operand.GetImmediate();
11923    if (IsUsingT32()) {
11924      // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
11925      if ((lsb <= 31) &&
11926          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
11927        uint32_t widthm1 = width - 1;
11928        EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11929                   ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
11930        AdvanceIT();
11931        return;
11932      }
11933    } else {
11934      // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
11935      if ((lsb <= 31) && cond.IsNotNever() &&
11936          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
11937        uint32_t widthm1 = width - 1;
11938        EmitA32(0x07e00050U | (cond.GetCondition() << 28) |
11939                (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) |
11940                (widthm1 << 16));
11941        return;
11942      }
11943    }
11944  }
11945  Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, operand);
11946}
11947
11948void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) {
11949  VIXL_ASSERT(AllowAssembler());
11950  CheckIT(cond);
11951  if (IsUsingT32()) {
11952    // UDF{<c>}{<q>} {#}<imm> ; T1
11953    if (!size.IsWide() && (imm <= 255)) {
11954      if (cond.Is(al) || AllowStronglyDiscouraged()) {
11955        EmitT32_16(0xde00 | imm);
11956        AdvanceIT();
11957        return;
11958      }
11959    }
11960    // UDF{<c>}{<q>} {#}<imm> ; T2
11961    if (!size.IsNarrow() && (imm <= 65535)) {
11962      if (cond.Is(al) || AllowStronglyDiscouraged()) {
11963        EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
11964        AdvanceIT();
11965        return;
11966      }
11967    }
11968  } else {
11969    // UDF{<c>}{<q>} {#}<imm> ; A1
11970    if ((imm <= 65535)) {
11971      if (cond.Is(al) || AllowStronglyDiscouraged()) {
11972        EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4));
11973        return;
11974      }
11975    }
11976  }
11977  Delegate(kUdf, &Assembler::udf, cond, size, imm);
11978}
11979
11980void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) {
11981  VIXL_ASSERT(AllowAssembler());
11982  CheckIT(cond);
11983  if (IsUsingT32()) {
11984    // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11985    EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11986               rm.GetCode());
11987    AdvanceIT();
11988    return;
11989  } else {
11990    // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11991    if (cond.IsNotNever()) {
11992      EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
11993              rn.GetCode() | (rm.GetCode() << 8));
11994      return;
11995    }
11996  }
11997  Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm);
11998}
11999
12000void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) {
12001  VIXL_ASSERT(AllowAssembler());
12002  CheckIT(cond);
12003  if (IsUsingT32()) {
12004    // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12005    EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12006               rm.GetCode());
12007    AdvanceIT();
12008    return;
12009  } else {
12010    // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12011    if (cond.IsNotNever()) {
12012      EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12013              (rn.GetCode() << 16) | rm.GetCode());
12014      return;
12015    }
12016  }
12017  Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm);
12018}
12019
12020void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) {
12021  VIXL_ASSERT(AllowAssembler());
12022  CheckIT(cond);
12023  if (IsUsingT32()) {
12024    // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12025    EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12026               rm.GetCode());
12027    AdvanceIT();
12028    return;
12029  } else {
12030    // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12031    if (cond.IsNotNever()) {
12032      EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12033              (rn.GetCode() << 16) | rm.GetCode());
12034      return;
12035    }
12036  }
12037  Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm);
12038}
12039
12040void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) {
12041  VIXL_ASSERT(AllowAssembler());
12042  CheckIT(cond);
12043  if (IsUsingT32()) {
12044    // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12045    EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12046               rm.GetCode());
12047    AdvanceIT();
12048    return;
12049  } else {
12050    // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12051    if (cond.IsNotNever()) {
12052      EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12053              (rn.GetCode() << 16) | rm.GetCode());
12054      return;
12055    }
12056  }
12057  Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm);
12058}
12059
12060void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) {
12061  VIXL_ASSERT(AllowAssembler());
12062  CheckIT(cond);
12063  if (IsUsingT32()) {
12064    // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12065    EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12066               rm.GetCode());
12067    AdvanceIT();
12068    return;
12069  } else {
12070    // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12071    if (cond.IsNotNever()) {
12072      EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12073              (rn.GetCode() << 16) | rm.GetCode());
12074      return;
12075    }
12076  }
12077  Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm);
12078}
12079
12080void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) {
12081  VIXL_ASSERT(AllowAssembler());
12082  CheckIT(cond);
12083  if (IsUsingT32()) {
12084    // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12085    EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12086               rm.GetCode());
12087    AdvanceIT();
12088    return;
12089  } else {
12090    // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12091    if (cond.IsNotNever()) {
12092      EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12093              (rn.GetCode() << 16) | rm.GetCode());
12094      return;
12095    }
12096  }
12097  Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm);
12098}
12099
12100void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) {
12101  VIXL_ASSERT(AllowAssembler());
12102  CheckIT(cond);
12103  if (IsUsingT32()) {
12104    // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12105    EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12106               rm.GetCode());
12107    AdvanceIT();
12108    return;
12109  } else {
12110    // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12111    if (cond.IsNotNever()) {
12112      EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12113              (rn.GetCode() << 16) | rm.GetCode());
12114      return;
12115    }
12116  }
12117  Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm);
12118}
12119
12120void Assembler::umaal(
12121    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12122  VIXL_ASSERT(AllowAssembler());
12123  CheckIT(cond);
12124  if (IsUsingT32()) {
12125    // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
12126    EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
12127               (rn.GetCode() << 16) | rm.GetCode());
12128    AdvanceIT();
12129    return;
12130  } else {
12131    // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12132    if (cond.IsNotNever()) {
12133      EmitA32(0x00400090U | (cond.GetCondition() << 28) |
12134              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12135              (rm.GetCode() << 8));
12136      return;
12137    }
12138  }
12139  Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm);
12140}
12141
12142void Assembler::umlal(
12143    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12144  VIXL_ASSERT(AllowAssembler());
12145  CheckIT(cond);
12146  if (IsUsingT32()) {
12147    // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
12148    EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
12149               (rn.GetCode() << 16) | rm.GetCode());
12150    AdvanceIT();
12151    return;
12152  } else {
12153    // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12154    if (cond.IsNotNever()) {
12155      EmitA32(0x00a00090U | (cond.GetCondition() << 28) |
12156              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12157              (rm.GetCode() << 8));
12158      return;
12159    }
12160  }
12161  Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm);
12162}
12163
12164void Assembler::umlals(
12165    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12166  VIXL_ASSERT(AllowAssembler());
12167  CheckIT(cond);
12168  if (IsUsingA32()) {
12169    // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12170    if (cond.IsNotNever()) {
12171      EmitA32(0x00b00090U | (cond.GetCondition() << 28) |
12172              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12173              (rm.GetCode() << 8));
12174      return;
12175    }
12176  }
12177  Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm);
12178}
12179
12180void Assembler::umull(
12181    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12182  VIXL_ASSERT(AllowAssembler());
12183  CheckIT(cond);
12184  if (IsUsingT32()) {
12185    // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
12186    EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
12187               (rn.GetCode() << 16) | rm.GetCode());
12188    AdvanceIT();
12189    return;
12190  } else {
12191    // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12192    if (cond.IsNotNever()) {
12193      EmitA32(0x00800090U | (cond.GetCondition() << 28) |
12194              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12195              (rm.GetCode() << 8));
12196      return;
12197    }
12198  }
12199  Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm);
12200}
12201
12202void Assembler::umulls(
12203    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12204  VIXL_ASSERT(AllowAssembler());
12205  CheckIT(cond);
12206  if (IsUsingA32()) {
12207    // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12208    if (cond.IsNotNever()) {
12209      EmitA32(0x00900090U | (cond.GetCondition() << 28) |
12210              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12211              (rm.GetCode() << 8));
12212      return;
12213    }
12214  }
12215  Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm);
12216}
12217
12218void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) {
12219  VIXL_ASSERT(AllowAssembler());
12220  CheckIT(cond);
12221  if (IsUsingT32()) {
12222    // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12223    EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12224               rm.GetCode());
12225    AdvanceIT();
12226    return;
12227  } else {
12228    // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12229    if (cond.IsNotNever()) {
12230      EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12231              (rn.GetCode() << 16) | rm.GetCode());
12232      return;
12233    }
12234  }
12235  Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm);
12236}
12237
12238void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) {
12239  VIXL_ASSERT(AllowAssembler());
12240  CheckIT(cond);
12241  if (IsUsingT32()) {
12242    // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12243    EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12244               rm.GetCode());
12245    AdvanceIT();
12246    return;
12247  } else {
12248    // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12249    if (cond.IsNotNever()) {
12250      EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12251              (rn.GetCode() << 16) | rm.GetCode());
12252      return;
12253    }
12254  }
12255  Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm);
12256}
12257
12258void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) {
12259  VIXL_ASSERT(AllowAssembler());
12260  CheckIT(cond);
12261  if (IsUsingT32()) {
12262    // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12263    EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12264               rm.GetCode());
12265    AdvanceIT();
12266    return;
12267  } else {
12268    // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12269    if (cond.IsNotNever()) {
12270      EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12271              (rn.GetCode() << 16) | rm.GetCode());
12272      return;
12273    }
12274  }
12275  Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm);
12276}
12277
12278void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) {
12279  VIXL_ASSERT(AllowAssembler());
12280  CheckIT(cond);
12281  if (IsUsingT32()) {
12282    // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12283    EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12284               rm.GetCode());
12285    AdvanceIT();
12286    return;
12287  } else {
12288    // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12289    if (cond.IsNotNever()) {
12290      EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12291              (rn.GetCode() << 16) | rm.GetCode());
12292      return;
12293    }
12294  }
12295  Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm);
12296}
12297
12298void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) {
12299  VIXL_ASSERT(AllowAssembler());
12300  CheckIT(cond);
12301  if (IsUsingT32()) {
12302    // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12303    EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12304               rm.GetCode());
12305    AdvanceIT();
12306    return;
12307  } else {
12308    // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12309    if (cond.IsNotNever()) {
12310      EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12311              (rn.GetCode() << 16) | rm.GetCode());
12312      return;
12313    }
12314  }
12315  Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm);
12316}
12317
12318void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) {
12319  VIXL_ASSERT(AllowAssembler());
12320  CheckIT(cond);
12321  if (IsUsingT32()) {
12322    // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12323    EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12324               rm.GetCode());
12325    AdvanceIT();
12326    return;
12327  } else {
12328    // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12329    if (cond.IsNotNever()) {
12330      EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12331              (rn.GetCode() << 16) | rm.GetCode());
12332      return;
12333    }
12334  }
12335  Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm);
12336}
12337
12338void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) {
12339  VIXL_ASSERT(AllowAssembler());
12340  CheckIT(cond);
12341  if (IsUsingT32()) {
12342    // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12343    EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12344               rm.GetCode());
12345    AdvanceIT();
12346    return;
12347  } else {
12348    // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12349    if (cond.IsNotNever()) {
12350      EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
12351              rn.GetCode() | (rm.GetCode() << 8));
12352      return;
12353    }
12354  }
12355  Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm);
12356}
12357
12358void Assembler::usada8(
12359    Condition cond, Register rd, Register rn, Register rm, Register ra) {
12360  VIXL_ASSERT(AllowAssembler());
12361  CheckIT(cond);
12362  if (IsUsingT32()) {
12363    // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
12364    if (!ra.Is(pc)) {
12365      EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12366                 rm.GetCode() | (ra.GetCode() << 12));
12367      AdvanceIT();
12368      return;
12369    }
12370  } else {
12371    // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
12372    if (cond.IsNotNever() && !ra.Is(pc)) {
12373      EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
12374              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
12375      return;
12376    }
12377  }
12378  Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra);
12379}
12380
12381void Assembler::usat(Condition cond,
12382                     Register rd,
12383                     uint32_t imm,
12384                     const Operand& operand) {
12385  VIXL_ASSERT(AllowAssembler());
12386  CheckIT(cond);
12387  if (operand.IsImmediateShiftedRegister()) {
12388    Register rn = operand.GetBaseRegister();
12389    Shift shift = operand.GetShift();
12390    uint32_t amount = operand.GetShiftAmount();
12391    if (IsUsingT32()) {
12392      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
12393      if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31)) {
12394        EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
12395                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
12396                   ((amount & 0x1c) << 10));
12397        AdvanceIT();
12398        return;
12399      }
12400      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
12401      if ((imm <= 31) && shift.IsLSL() && (amount <= 31)) {
12402        EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm |
12403                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
12404                   ((amount & 0x1c) << 10));
12405        AdvanceIT();
12406        return;
12407      }
12408    } else {
12409      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
12410      if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) &&
12411          cond.IsNotNever()) {
12412        uint32_t amount_ = amount % 32;
12413        EmitA32(0x06e00050U | (cond.GetCondition() << 28) |
12414                (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
12415                (amount_ << 7));
12416        return;
12417      }
12418      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
12419      if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever()) {
12420        EmitA32(0x06e00010U | (cond.GetCondition() << 28) |
12421                (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
12422                (amount << 7));
12423        return;
12424      }
12425    }
12426  }
12427  Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand);
12428}
12429
12430void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) {
12431  VIXL_ASSERT(AllowAssembler());
12432  CheckIT(cond);
12433  if (IsUsingT32()) {
12434    // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
12435    if ((imm <= 15)) {
12436      EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
12437                 (rn.GetCode() << 16));
12438      AdvanceIT();
12439      return;
12440    }
12441  } else {
12442    // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
12443    if ((imm <= 15) && cond.IsNotNever()) {
12444      EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12445              (imm << 16) | rn.GetCode());
12446      return;
12447    }
12448  }
12449  Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn);
12450}
12451
12452void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) {
12453  VIXL_ASSERT(AllowAssembler());
12454  CheckIT(cond);
12455  if (IsUsingT32()) {
12456    // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12457    EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12458               rm.GetCode());
12459    AdvanceIT();
12460    return;
12461  } else {
12462    // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12463    if (cond.IsNotNever()) {
12464      EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12465              (rn.GetCode() << 16) | rm.GetCode());
12466      return;
12467    }
12468  }
12469  Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm);
12470}
12471
12472void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) {
12473  VIXL_ASSERT(AllowAssembler());
12474  CheckIT(cond);
12475  if (IsUsingT32()) {
12476    // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12477    EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12478               rm.GetCode());
12479    AdvanceIT();
12480    return;
12481  } else {
12482    // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12483    if (cond.IsNotNever()) {
12484      EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12485              (rn.GetCode() << 16) | rm.GetCode());
12486      return;
12487    }
12488  }
12489  Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm);
12490}
12491
12492void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) {
12493  VIXL_ASSERT(AllowAssembler());
12494  CheckIT(cond);
12495  if (IsUsingT32()) {
12496    // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12497    EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12498               rm.GetCode());
12499    AdvanceIT();
12500    return;
12501  } else {
12502    // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12503    if (cond.IsNotNever()) {
12504      EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12505              (rn.GetCode() << 16) | rm.GetCode());
12506      return;
12507    }
12508  }
12509  Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm);
12510}
12511
12512void Assembler::uxtab(Condition cond,
12513                      Register rd,
12514                      Register rn,
12515                      const Operand& operand) {
12516  VIXL_ASSERT(AllowAssembler());
12517  CheckIT(cond);
12518  if (operand.IsImmediateShiftedRegister()) {
12519    Register rm = operand.GetBaseRegister();
12520    Shift shift = operand.GetShift();
12521    uint32_t amount = operand.GetShiftAmount();
12522    if (IsUsingT32()) {
12523      // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12524      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12525          ((amount % 8) == 0) && !rn.Is(pc)) {
12526        uint32_t amount_ = amount / 8;
12527        EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12528                   rm.GetCode() | (amount_ << 4));
12529        AdvanceIT();
12530        return;
12531      }
12532    } else {
12533      // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12534      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12535          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12536        uint32_t amount_ = amount / 8;
12537        EmitA32(0x06e00070U | (cond.GetCondition() << 28) |
12538                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12539                (amount_ << 10));
12540        return;
12541      }
12542    }
12543  }
12544  Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand);
12545}
12546
12547void Assembler::uxtab16(Condition cond,
12548                        Register rd,
12549                        Register rn,
12550                        const Operand& operand) {
12551  VIXL_ASSERT(AllowAssembler());
12552  CheckIT(cond);
12553  if (operand.IsImmediateShiftedRegister()) {
12554    Register rm = operand.GetBaseRegister();
12555    Shift shift = operand.GetShift();
12556    uint32_t amount = operand.GetShiftAmount();
12557    if (IsUsingT32()) {
12558      // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12559      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12560          ((amount % 8) == 0) && !rn.Is(pc)) {
12561        uint32_t amount_ = amount / 8;
12562        EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12563                   rm.GetCode() | (amount_ << 4));
12564        AdvanceIT();
12565        return;
12566      }
12567    } else {
12568      // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12569      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12570          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12571        uint32_t amount_ = amount / 8;
12572        EmitA32(0x06c00070U | (cond.GetCondition() << 28) |
12573                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12574                (amount_ << 10));
12575        return;
12576      }
12577    }
12578  }
12579  Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand);
12580}
12581
12582void Assembler::uxtah(Condition cond,
12583                      Register rd,
12584                      Register rn,
12585                      const Operand& operand) {
12586  VIXL_ASSERT(AllowAssembler());
12587  CheckIT(cond);
12588  if (operand.IsImmediateShiftedRegister()) {
12589    Register rm = operand.GetBaseRegister();
12590    Shift shift = operand.GetShift();
12591    uint32_t amount = operand.GetShiftAmount();
12592    if (IsUsingT32()) {
12593      // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12594      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12595          ((amount % 8) == 0) && !rn.Is(pc)) {
12596        uint32_t amount_ = amount / 8;
12597        EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12598                   rm.GetCode() | (amount_ << 4));
12599        AdvanceIT();
12600        return;
12601      }
12602    } else {
12603      // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12604      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12605          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12606        uint32_t amount_ = amount / 8;
12607        EmitA32(0x06f00070U | (cond.GetCondition() << 28) |
12608                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12609                (amount_ << 10));
12610        return;
12611      }
12612    }
12613  }
12614  Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand);
12615}
12616
12617void Assembler::uxtb(Condition cond,
12618                     EncodingSize size,
12619                     Register rd,
12620                     const Operand& operand) {
12621  VIXL_ASSERT(AllowAssembler());
12622  CheckIT(cond);
12623  if (operand.IsImmediateShiftedRegister()) {
12624    Register rm = operand.GetBaseRegister();
12625    if (operand.IsPlainRegister()) {
12626      if (IsUsingT32()) {
12627        // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
12628        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12629          EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3));
12630          AdvanceIT();
12631          return;
12632        }
12633      }
12634    }
12635    Shift shift = operand.GetShift();
12636    uint32_t amount = operand.GetShiftAmount();
12637    if (IsUsingT32()) {
12638      // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12639      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12640          (amount <= 24) && ((amount % 8) == 0)) {
12641        uint32_t amount_ = amount / 8;
12642        EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12643                   (amount_ << 4));
12644        AdvanceIT();
12645        return;
12646      }
12647    } else {
12648      // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12649      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12650          ((amount % 8) == 0) && cond.IsNotNever()) {
12651        uint32_t amount_ = amount / 8;
12652        EmitA32(0x06ef0070U | (cond.GetCondition() << 28) |
12653                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12654        return;
12655      }
12656    }
12657  }
12658  Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand);
12659}
12660
12661void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) {
12662  VIXL_ASSERT(AllowAssembler());
12663  CheckIT(cond);
12664  if (operand.IsImmediateShiftedRegister()) {
12665    Register rm = operand.GetBaseRegister();
12666    Shift shift = operand.GetShift();
12667    uint32_t amount = operand.GetShiftAmount();
12668    if (IsUsingT32()) {
12669      // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
12670      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12671          ((amount % 8) == 0)) {
12672        uint32_t amount_ = amount / 8;
12673        EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12674                   (amount_ << 4));
12675        AdvanceIT();
12676        return;
12677      }
12678    } else {
12679      // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12680      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12681          ((amount % 8) == 0) && cond.IsNotNever()) {
12682        uint32_t amount_ = amount / 8;
12683        EmitA32(0x06cf0070U | (cond.GetCondition() << 28) |
12684                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12685        return;
12686      }
12687    }
12688  }
12689  Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand);
12690}
12691
12692void Assembler::uxth(Condition cond,
12693                     EncodingSize size,
12694                     Register rd,
12695                     const Operand& operand) {
12696  VIXL_ASSERT(AllowAssembler());
12697  CheckIT(cond);
12698  if (operand.IsImmediateShiftedRegister()) {
12699    Register rm = operand.GetBaseRegister();
12700    if (operand.IsPlainRegister()) {
12701      if (IsUsingT32()) {
12702        // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
12703        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12704          EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3));
12705          AdvanceIT();
12706          return;
12707        }
12708      }
12709    }
12710    Shift shift = operand.GetShift();
12711    uint32_t amount = operand.GetShiftAmount();
12712    if (IsUsingT32()) {
12713      // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12714      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12715          (amount <= 24) && ((amount % 8) == 0)) {
12716        uint32_t amount_ = amount / 8;
12717        EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12718                   (amount_ << 4));
12719        AdvanceIT();
12720        return;
12721      }
12722    } else {
12723      // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12724      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12725          ((amount % 8) == 0) && cond.IsNotNever()) {
12726        uint32_t amount_ = amount / 8;
12727        EmitA32(0x06ff0070U | (cond.GetCondition() << 28) |
12728                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12729        return;
12730      }
12731    }
12732  }
12733  Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand);
12734}
12735
12736void Assembler::vaba(
12737    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12738  VIXL_ASSERT(AllowAssembler());
12739  CheckIT(cond);
12740  Dt_U_size_1 encoded_dt(dt);
12741  if (IsUsingT32()) {
12742    // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1
12743    if (encoded_dt.IsValid()) {
12744      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12745        EmitT32_32(0xef000710U | ((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    // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1
12754    if (encoded_dt.IsValid()) {
12755      if (cond.Is(al)) {
12756        EmitA32(0xf2000710U | ((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(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
12764}
12765
12766void Assembler::vaba(
12767    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12768  VIXL_ASSERT(AllowAssembler());
12769  CheckIT(cond);
12770  Dt_U_size_1 encoded_dt(dt);
12771  if (IsUsingT32()) {
12772    // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1
12773    if (encoded_dt.IsValid()) {
12774      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12775        EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12776                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12777                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12778        AdvanceIT();
12779        return;
12780      }
12781    }
12782  } else {
12783    // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1
12784    if (encoded_dt.IsValid()) {
12785      if (cond.Is(al)) {
12786        EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12787                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12788                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12789        return;
12790      }
12791    }
12792  }
12793  Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
12794}
12795
12796void Assembler::vabal(
12797    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
12798  VIXL_ASSERT(AllowAssembler());
12799  CheckIT(cond);
12800  Dt_U_size_1 encoded_dt(dt);
12801  if (IsUsingT32()) {
12802    // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
12803    if (encoded_dt.IsValid()) {
12804      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12805        EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12806                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12807                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12808        AdvanceIT();
12809        return;
12810      }
12811    }
12812  } else {
12813    // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
12814    if (encoded_dt.IsValid()) {
12815      if (cond.Is(al)) {
12816        EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12817                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12818                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12819        return;
12820      }
12821    }
12822  }
12823  Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm);
12824}
12825
12826void Assembler::vabd(
12827    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12828  VIXL_ASSERT(AllowAssembler());
12829  CheckIT(cond);
12830  Dt_U_size_1 encoded_dt(dt);
12831  if (IsUsingT32()) {
12832    // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
12833    if (dt.Is(F32)) {
12834      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12835        EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12836                   rm.Encode(5, 0));
12837        AdvanceIT();
12838        return;
12839      }
12840    }
12841    // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
12842    if (encoded_dt.IsValid()) {
12843      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12844        EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12845                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12846                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12847        AdvanceIT();
12848        return;
12849      }
12850    }
12851  } else {
12852    // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
12853    if (dt.Is(F32)) {
12854      if (cond.Is(al)) {
12855        EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12856                rm.Encode(5, 0));
12857        return;
12858      }
12859    }
12860    // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
12861    if (encoded_dt.IsValid()) {
12862      if (cond.Is(al)) {
12863        EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12864                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12865                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12866        return;
12867      }
12868    }
12869  }
12870  Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
12871}
12872
12873void Assembler::vabd(
12874    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12875  VIXL_ASSERT(AllowAssembler());
12876  CheckIT(cond);
12877  Dt_U_size_1 encoded_dt(dt);
12878  if (IsUsingT32()) {
12879    // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
12880    if (dt.Is(F32)) {
12881      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12882        EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12883                   rm.Encode(5, 0));
12884        AdvanceIT();
12885        return;
12886      }
12887    }
12888    // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
12889    if (encoded_dt.IsValid()) {
12890      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12891        EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12892                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12893                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12894        AdvanceIT();
12895        return;
12896      }
12897    }
12898  } else {
12899    // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
12900    if (dt.Is(F32)) {
12901      if (cond.Is(al)) {
12902        EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12903                rm.Encode(5, 0));
12904        return;
12905      }
12906    }
12907    // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
12908    if (encoded_dt.IsValid()) {
12909      if (cond.Is(al)) {
12910        EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12911                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12912                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12913        return;
12914      }
12915    }
12916  }
12917  Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
12918}
12919
12920void Assembler::vabdl(
12921    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
12922  VIXL_ASSERT(AllowAssembler());
12923  CheckIT(cond);
12924  Dt_U_size_1 encoded_dt(dt);
12925  if (IsUsingT32()) {
12926    // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
12927    if (encoded_dt.IsValid()) {
12928      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12929        EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12930                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12931                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12932        AdvanceIT();
12933        return;
12934      }
12935    }
12936  } else {
12937    // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
12938    if (encoded_dt.IsValid()) {
12939      if (cond.Is(al)) {
12940        EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12941                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12942                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12943        return;
12944      }
12945    }
12946  }
12947  Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm);
12948}
12949
12950void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
12951  VIXL_ASSERT(AllowAssembler());
12952  CheckIT(cond);
12953  Dt_F_size_1 encoded_dt(dt);
12954  if (IsUsingT32()) {
12955    // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
12956    if (encoded_dt.IsValid()) {
12957      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12958        EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12959                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12960                   rd.Encode(22, 12) | rm.Encode(5, 0));
12961        AdvanceIT();
12962        return;
12963      }
12964    }
12965    // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
12966    if (dt.Is(F64)) {
12967      EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
12968      AdvanceIT();
12969      return;
12970    }
12971  } else {
12972    // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
12973    if (encoded_dt.IsValid()) {
12974      if (cond.Is(al)) {
12975        EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12976                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12977                rd.Encode(22, 12) | rm.Encode(5, 0));
12978        return;
12979      }
12980    }
12981    // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
12982    if (dt.Is(F64) && cond.IsNotNever()) {
12983      EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
12984              rm.Encode(5, 0));
12985      return;
12986    }
12987  }
12988  Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
12989}
12990
12991void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
12992  VIXL_ASSERT(AllowAssembler());
12993  CheckIT(cond);
12994  Dt_F_size_1 encoded_dt(dt);
12995  if (IsUsingT32()) {
12996    // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
12997    if (encoded_dt.IsValid()) {
12998      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12999        EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13000                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13001                   rd.Encode(22, 12) | rm.Encode(5, 0));
13002        AdvanceIT();
13003        return;
13004      }
13005    }
13006  } else {
13007    // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
13008    if (encoded_dt.IsValid()) {
13009      if (cond.Is(al)) {
13010        EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13011                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13012                rd.Encode(22, 12) | rm.Encode(5, 0));
13013        return;
13014      }
13015    }
13016  }
13017  Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
13018}
13019
13020void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) {
13021  VIXL_ASSERT(AllowAssembler());
13022  CheckIT(cond);
13023  if (IsUsingT32()) {
13024    // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
13025    if (dt.Is(F32)) {
13026      EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
13027      AdvanceIT();
13028      return;
13029    }
13030  } else {
13031    // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
13032    if (dt.Is(F32) && cond.IsNotNever()) {
13033      EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
13034              rm.Encode(5, 0));
13035      return;
13036    }
13037  }
13038  Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
13039}
13040
13041void Assembler::vacge(
13042    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13043  VIXL_ASSERT(AllowAssembler());
13044  CheckIT(cond);
13045  if (IsUsingT32()) {
13046    // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13047    if (dt.Is(F32)) {
13048      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13049        EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13050                   rm.Encode(5, 0));
13051        AdvanceIT();
13052        return;
13053      }
13054    }
13055  } else {
13056    // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13057    if (dt.Is(F32)) {
13058      if (cond.Is(al)) {
13059        EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13060                rm.Encode(5, 0));
13061        return;
13062      }
13063    }
13064  }
13065  Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
13066}
13067
13068void Assembler::vacge(
13069    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13070  VIXL_ASSERT(AllowAssembler());
13071  CheckIT(cond);
13072  if (IsUsingT32()) {
13073    // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13074    if (dt.Is(F32)) {
13075      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13076        EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13077                   rm.Encode(5, 0));
13078        AdvanceIT();
13079        return;
13080      }
13081    }
13082  } else {
13083    // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13084    if (dt.Is(F32)) {
13085      if (cond.Is(al)) {
13086        EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13087                rm.Encode(5, 0));
13088        return;
13089      }
13090    }
13091  }
13092  Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
13093}
13094
13095void Assembler::vacgt(
13096    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13097  VIXL_ASSERT(AllowAssembler());
13098  CheckIT(cond);
13099  if (IsUsingT32()) {
13100    // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13101    if (dt.Is(F32)) {
13102      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13103        EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13104                   rm.Encode(5, 0));
13105        AdvanceIT();
13106        return;
13107      }
13108    }
13109  } else {
13110    // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13111    if (dt.Is(F32)) {
13112      if (cond.Is(al)) {
13113        EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13114                rm.Encode(5, 0));
13115        return;
13116      }
13117    }
13118  }
13119  Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
13120}
13121
13122void Assembler::vacgt(
13123    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13124  VIXL_ASSERT(AllowAssembler());
13125  CheckIT(cond);
13126  if (IsUsingT32()) {
13127    // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13128    if (dt.Is(F32)) {
13129      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13130        EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13131                   rm.Encode(5, 0));
13132        AdvanceIT();
13133        return;
13134      }
13135    }
13136  } else {
13137    // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13138    if (dt.Is(F32)) {
13139      if (cond.Is(al)) {
13140        EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13141                rm.Encode(5, 0));
13142        return;
13143      }
13144    }
13145  }
13146  Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
13147}
13148
13149void Assembler::vacle(
13150    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13151  VIXL_ASSERT(AllowAssembler());
13152  CheckIT(cond);
13153  if (IsUsingT32()) {
13154    // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13155    if (dt.Is(F32)) {
13156      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13157        EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13158                   rm.Encode(5, 0));
13159        AdvanceIT();
13160        return;
13161      }
13162    }
13163  } else {
13164    // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13165    if (dt.Is(F32)) {
13166      if (cond.Is(al)) {
13167        EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13168                rm.Encode(5, 0));
13169        return;
13170      }
13171    }
13172  }
13173  Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
13174}
13175
13176void Assembler::vacle(
13177    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13178  VIXL_ASSERT(AllowAssembler());
13179  CheckIT(cond);
13180  if (IsUsingT32()) {
13181    // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13182    if (dt.Is(F32)) {
13183      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13184        EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13185                   rm.Encode(5, 0));
13186        AdvanceIT();
13187        return;
13188      }
13189    }
13190  } else {
13191    // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13192    if (dt.Is(F32)) {
13193      if (cond.Is(al)) {
13194        EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13195                rm.Encode(5, 0));
13196        return;
13197      }
13198    }
13199  }
13200  Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
13201}
13202
13203void Assembler::vaclt(
13204    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13205  VIXL_ASSERT(AllowAssembler());
13206  CheckIT(cond);
13207  if (IsUsingT32()) {
13208    // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13209    if (dt.Is(F32)) {
13210      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13211        EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13212                   rm.Encode(5, 0));
13213        AdvanceIT();
13214        return;
13215      }
13216    }
13217  } else {
13218    // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13219    if (dt.Is(F32)) {
13220      if (cond.Is(al)) {
13221        EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13222                rm.Encode(5, 0));
13223        return;
13224      }
13225    }
13226  }
13227  Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
13228}
13229
13230void Assembler::vaclt(
13231    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13232  VIXL_ASSERT(AllowAssembler());
13233  CheckIT(cond);
13234  if (IsUsingT32()) {
13235    // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13236    if (dt.Is(F32)) {
13237      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13238        EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13239                   rm.Encode(5, 0));
13240        AdvanceIT();
13241        return;
13242      }
13243    }
13244  } else {
13245    // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13246    if (dt.Is(F32)) {
13247      if (cond.Is(al)) {
13248        EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13249                rm.Encode(5, 0));
13250        return;
13251      }
13252    }
13253  }
13254  Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
13255}
13256
13257void Assembler::vadd(
13258    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13259  VIXL_ASSERT(AllowAssembler());
13260  CheckIT(cond);
13261  Dt_size_2 encoded_dt(dt);
13262  if (IsUsingT32()) {
13263    // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13264    if (dt.Is(F32)) {
13265      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13266        EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13267                   rm.Encode(5, 0));
13268        AdvanceIT();
13269        return;
13270      }
13271    }
13272    // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
13273    if (dt.Is(F64)) {
13274      EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13275                 rm.Encode(5, 0));
13276      AdvanceIT();
13277      return;
13278    }
13279    // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
13280    if (encoded_dt.IsValid()) {
13281      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13282        EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) |
13283                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13284        AdvanceIT();
13285        return;
13286      }
13287    }
13288  } else {
13289    // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13290    if (dt.Is(F32)) {
13291      if (cond.Is(al)) {
13292        EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13293                rm.Encode(5, 0));
13294        return;
13295      }
13296    }
13297    // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
13298    if (dt.Is(F64) && cond.IsNotNever()) {
13299      EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
13300              rn.Encode(7, 16) | rm.Encode(5, 0));
13301      return;
13302    }
13303    // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
13304    if (encoded_dt.IsValid()) {
13305      if (cond.Is(al)) {
13306        EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) |
13307                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13308        return;
13309      }
13310    }
13311  }
13312  Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13313}
13314
13315void Assembler::vadd(
13316    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13317  VIXL_ASSERT(AllowAssembler());
13318  CheckIT(cond);
13319  Dt_size_2 encoded_dt(dt);
13320  if (IsUsingT32()) {
13321    // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13322    if (dt.Is(F32)) {
13323      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13324        EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13325                   rm.Encode(5, 0));
13326        AdvanceIT();
13327        return;
13328      }
13329    }
13330    // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
13331    if (encoded_dt.IsValid()) {
13332      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13333        EmitT32_32(0xef000840U | (encoded_dt.GetEncodingValue() << 20) |
13334                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13335        AdvanceIT();
13336        return;
13337      }
13338    }
13339  } else {
13340    // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13341    if (dt.Is(F32)) {
13342      if (cond.Is(al)) {
13343        EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13344                rm.Encode(5, 0));
13345        return;
13346      }
13347    }
13348    // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
13349    if (encoded_dt.IsValid()) {
13350      if (cond.Is(al)) {
13351        EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) |
13352                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13353        return;
13354      }
13355    }
13356  }
13357  Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13358}
13359
13360void Assembler::vadd(
13361    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
13362  VIXL_ASSERT(AllowAssembler());
13363  CheckIT(cond);
13364  if (IsUsingT32()) {
13365    // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
13366    if (dt.Is(F32)) {
13367      EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13368                 rm.Encode(5, 0));
13369      AdvanceIT();
13370      return;
13371    }
13372  } else {
13373    // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
13374    if (dt.Is(F32) && cond.IsNotNever()) {
13375      EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
13376              rn.Encode(7, 16) | rm.Encode(5, 0));
13377      return;
13378    }
13379  }
13380  Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13381}
13382
13383void Assembler::vaddhn(
13384    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
13385  VIXL_ASSERT(AllowAssembler());
13386  CheckIT(cond);
13387  Dt_size_3 encoded_dt(dt);
13388  if (IsUsingT32()) {
13389    // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
13390    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
13391      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13392        EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) |
13393                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13394        AdvanceIT();
13395        return;
13396      }
13397    }
13398  } else {
13399    // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
13400    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
13401      if (cond.Is(al)) {
13402        EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) |
13403                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13404        return;
13405      }
13406    }
13407  }
13408  Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm);
13409}
13410
13411void Assembler::vaddl(
13412    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
13413  VIXL_ASSERT(AllowAssembler());
13414  CheckIT(cond);
13415  Dt_U_size_1 encoded_dt(dt);
13416  if (IsUsingT32()) {
13417    // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
13418    if (encoded_dt.IsValid()) {
13419      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13420        EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13421                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13422                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13423        AdvanceIT();
13424        return;
13425      }
13426    }
13427  } else {
13428    // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
13429    if (encoded_dt.IsValid()) {
13430      if (cond.Is(al)) {
13431        EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13432                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13433                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13434        return;
13435      }
13436    }
13437  }
13438  Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm);
13439}
13440
13441void Assembler::vaddw(
13442    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
13443  VIXL_ASSERT(AllowAssembler());
13444  CheckIT(cond);
13445  Dt_U_size_1 encoded_dt(dt);
13446  if (IsUsingT32()) {
13447    // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
13448    if (encoded_dt.IsValid()) {
13449      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13450        EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13451                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13452                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13453        AdvanceIT();
13454        return;
13455      }
13456    }
13457  } else {
13458    // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
13459    if (encoded_dt.IsValid()) {
13460      if (cond.Is(al)) {
13461        EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13462                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13463                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13464        return;
13465      }
13466    }
13467  }
13468  Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm);
13469}
13470
13471void Assembler::vand(Condition cond,
13472                     DataType dt,
13473                     DRegister rd,
13474                     DRegister rn,
13475                     const DOperand& operand) {
13476  VIXL_ASSERT(AllowAssembler());
13477  CheckIT(cond);
13478  if (operand.IsImmediate()) {
13479    ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
13480    if (IsUsingT32()) {
13481      // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
13482      if (encoded_dt.IsValid() && rd.Is(rn)) {
13483        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13484          EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
13485                     rd.Encode(22, 12) |
13486                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13487                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13488                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13489          AdvanceIT();
13490          return;
13491        }
13492      }
13493    } else {
13494      // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
13495      if (encoded_dt.IsValid() && rd.Is(rn)) {
13496        if (cond.Is(al)) {
13497          EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
13498                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13499                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13500                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13501          return;
13502        }
13503      }
13504    }
13505  }
13506  if (operand.IsRegister()) {
13507    DRegister rm = operand.GetRegister();
13508    USE(dt);
13509    if (IsUsingT32()) {
13510      // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13511      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13512        EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13513                   rm.Encode(5, 0));
13514        AdvanceIT();
13515        return;
13516      }
13517    } else {
13518      // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13519      if (cond.Is(al)) {
13520        EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13521                rm.Encode(5, 0));
13522        return;
13523      }
13524    }
13525  }
13526  Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
13527}
13528
13529void Assembler::vand(Condition cond,
13530                     DataType dt,
13531                     QRegister rd,
13532                     QRegister rn,
13533                     const QOperand& operand) {
13534  VIXL_ASSERT(AllowAssembler());
13535  CheckIT(cond);
13536  if (operand.IsImmediate()) {
13537    ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
13538    if (IsUsingT32()) {
13539      // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
13540      if (encoded_dt.IsValid() && rd.Is(rn)) {
13541        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13542          EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
13543                     rd.Encode(22, 12) |
13544                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13545                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13546                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13547          AdvanceIT();
13548          return;
13549        }
13550      }
13551    } else {
13552      // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
13553      if (encoded_dt.IsValid() && rd.Is(rn)) {
13554        if (cond.Is(al)) {
13555          EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
13556                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13557                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13558                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13559          return;
13560        }
13561      }
13562    }
13563  }
13564  if (operand.IsRegister()) {
13565    QRegister rm = operand.GetRegister();
13566    USE(dt);
13567    if (IsUsingT32()) {
13568      // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13569      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13570        EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13571                   rm.Encode(5, 0));
13572        AdvanceIT();
13573        return;
13574      }
13575    } else {
13576      // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13577      if (cond.Is(al)) {
13578        EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13579                rm.Encode(5, 0));
13580        return;
13581      }
13582    }
13583  }
13584  Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
13585}
13586
13587void Assembler::vbic(Condition cond,
13588                     DataType dt,
13589                     DRegister rd,
13590                     DRegister rn,
13591                     const DOperand& operand) {
13592  VIXL_ASSERT(AllowAssembler());
13593  CheckIT(cond);
13594  if (operand.IsImmediate()) {
13595    ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
13596    if (IsUsingT32()) {
13597      // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
13598      if (encoded_dt.IsValid() && rd.Is(rn)) {
13599        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13600          EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
13601                     rd.Encode(22, 12) |
13602                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13603                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13604                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13605          AdvanceIT();
13606          return;
13607        }
13608      }
13609    } else {
13610      // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
13611      if (encoded_dt.IsValid() && rd.Is(rn)) {
13612        if (cond.Is(al)) {
13613          EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
13614                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13615                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13616                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13617          return;
13618        }
13619      }
13620    }
13621  }
13622  if (operand.IsRegister()) {
13623    DRegister rm = operand.GetRegister();
13624    USE(dt);
13625    if (IsUsingT32()) {
13626      // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13627      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13628        EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13629                   rm.Encode(5, 0));
13630        AdvanceIT();
13631        return;
13632      }
13633    } else {
13634      // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13635      if (cond.Is(al)) {
13636        EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13637                rm.Encode(5, 0));
13638        return;
13639      }
13640    }
13641  }
13642  Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
13643}
13644
13645void Assembler::vbic(Condition cond,
13646                     DataType dt,
13647                     QRegister rd,
13648                     QRegister rn,
13649                     const QOperand& operand) {
13650  VIXL_ASSERT(AllowAssembler());
13651  CheckIT(cond);
13652  if (operand.IsImmediate()) {
13653    ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
13654    if (IsUsingT32()) {
13655      // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
13656      if (encoded_dt.IsValid() && rd.Is(rn)) {
13657        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13658          EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
13659                     rd.Encode(22, 12) |
13660                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13661                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13662                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13663          AdvanceIT();
13664          return;
13665        }
13666      }
13667    } else {
13668      // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
13669      if (encoded_dt.IsValid() && rd.Is(rn)) {
13670        if (cond.Is(al)) {
13671          EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
13672                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13673                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13674                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13675          return;
13676        }
13677      }
13678    }
13679  }
13680  if (operand.IsRegister()) {
13681    QRegister rm = operand.GetRegister();
13682    USE(dt);
13683    if (IsUsingT32()) {
13684      // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13685      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13686        EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13687                   rm.Encode(5, 0));
13688        AdvanceIT();
13689        return;
13690      }
13691    } else {
13692      // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13693      if (cond.Is(al)) {
13694        EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13695                rm.Encode(5, 0));
13696        return;
13697      }
13698    }
13699  }
13700  Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
13701}
13702
13703void Assembler::vbif(
13704    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13705  VIXL_ASSERT(AllowAssembler());
13706  CheckIT(cond);
13707  USE(dt);
13708  if (IsUsingT32()) {
13709    // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13710    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13711      EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13712                 rm.Encode(5, 0));
13713      AdvanceIT();
13714      return;
13715    }
13716  } else {
13717    // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13718    if (cond.Is(al)) {
13719      EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13720              rm.Encode(5, 0));
13721      return;
13722    }
13723  }
13724  Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
13725}
13726
13727void Assembler::vbif(
13728    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13729  VIXL_ASSERT(AllowAssembler());
13730  CheckIT(cond);
13731  USE(dt);
13732  if (IsUsingT32()) {
13733    // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13734    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13735      EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13736                 rm.Encode(5, 0));
13737      AdvanceIT();
13738      return;
13739    }
13740  } else {
13741    // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13742    if (cond.Is(al)) {
13743      EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13744              rm.Encode(5, 0));
13745      return;
13746    }
13747  }
13748  Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
13749}
13750
13751void Assembler::vbit(
13752    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13753  VIXL_ASSERT(AllowAssembler());
13754  CheckIT(cond);
13755  USE(dt);
13756  if (IsUsingT32()) {
13757    // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13758    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13759      EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13760                 rm.Encode(5, 0));
13761      AdvanceIT();
13762      return;
13763    }
13764  } else {
13765    // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13766    if (cond.Is(al)) {
13767      EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13768              rm.Encode(5, 0));
13769      return;
13770    }
13771  }
13772  Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
13773}
13774
13775void Assembler::vbit(
13776    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13777  VIXL_ASSERT(AllowAssembler());
13778  CheckIT(cond);
13779  USE(dt);
13780  if (IsUsingT32()) {
13781    // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13782    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13783      EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13784                 rm.Encode(5, 0));
13785      AdvanceIT();
13786      return;
13787    }
13788  } else {
13789    // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13790    if (cond.Is(al)) {
13791      EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13792              rm.Encode(5, 0));
13793      return;
13794    }
13795  }
13796  Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
13797}
13798
13799void Assembler::vbsl(
13800    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13801  VIXL_ASSERT(AllowAssembler());
13802  CheckIT(cond);
13803  USE(dt);
13804  if (IsUsingT32()) {
13805    // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13806    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13807      EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13808                 rm.Encode(5, 0));
13809      AdvanceIT();
13810      return;
13811    }
13812  } else {
13813    // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13814    if (cond.Is(al)) {
13815      EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13816              rm.Encode(5, 0));
13817      return;
13818    }
13819  }
13820  Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
13821}
13822
13823void Assembler::vbsl(
13824    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13825  VIXL_ASSERT(AllowAssembler());
13826  CheckIT(cond);
13827  USE(dt);
13828  if (IsUsingT32()) {
13829    // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13830    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13831      EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13832                 rm.Encode(5, 0));
13833      AdvanceIT();
13834      return;
13835    }
13836  } else {
13837    // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13838    if (cond.Is(al)) {
13839      EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13840              rm.Encode(5, 0));
13841      return;
13842    }
13843  }
13844  Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
13845}
13846
13847void Assembler::vceq(Condition cond,
13848                     DataType dt,
13849                     DRegister rd,
13850                     DRegister rm,
13851                     const DOperand& operand) {
13852  VIXL_ASSERT(AllowAssembler());
13853  CheckIT(cond);
13854  if (operand.IsImmediate()) {
13855    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13856      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13857      Dt_F_size_2 encoded_dt(dt);
13858      if (IsUsingT32()) {
13859        // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
13860        if (encoded_dt.IsValid() && (imm == 0)) {
13861          if (cond.Is(al) || AllowStronglyDiscouraged()) {
13862            EmitT32_32(0xffb10100U |
13863                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13864                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13865                       rd.Encode(22, 12) | rm.Encode(5, 0));
13866            AdvanceIT();
13867            return;
13868          }
13869        }
13870      } else {
13871        // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
13872        if (encoded_dt.IsValid() && (imm == 0)) {
13873          if (cond.Is(al)) {
13874            EmitA32(0xf3b10100U |
13875                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13876                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13877                    rd.Encode(22, 12) | rm.Encode(5, 0));
13878            return;
13879          }
13880        }
13881      }
13882    }
13883  }
13884  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
13885}
13886
13887void Assembler::vceq(Condition cond,
13888                     DataType dt,
13889                     QRegister rd,
13890                     QRegister rm,
13891                     const QOperand& operand) {
13892  VIXL_ASSERT(AllowAssembler());
13893  CheckIT(cond);
13894  if (operand.IsImmediate()) {
13895    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13896      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13897      Dt_F_size_2 encoded_dt(dt);
13898      if (IsUsingT32()) {
13899        // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
13900        if (encoded_dt.IsValid() && (imm == 0)) {
13901          if (cond.Is(al) || AllowStronglyDiscouraged()) {
13902            EmitT32_32(0xffb10140U |
13903                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13904                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13905                       rd.Encode(22, 12) | rm.Encode(5, 0));
13906            AdvanceIT();
13907            return;
13908          }
13909        }
13910      } else {
13911        // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
13912        if (encoded_dt.IsValid() && (imm == 0)) {
13913          if (cond.Is(al)) {
13914            EmitA32(0xf3b10140U |
13915                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13916                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13917                    rd.Encode(22, 12) | rm.Encode(5, 0));
13918            return;
13919          }
13920        }
13921      }
13922    }
13923  }
13924  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
13925}
13926
13927void Assembler::vceq(
13928    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13929  VIXL_ASSERT(AllowAssembler());
13930  CheckIT(cond);
13931  Dt_size_4 encoded_dt(dt);
13932  Dt_sz_1 encoded_dt_2(dt);
13933  if (IsUsingT32()) {
13934    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
13935    if (encoded_dt.IsValid()) {
13936      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13937        EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) |
13938                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13939        AdvanceIT();
13940        return;
13941      }
13942    }
13943    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2
13944    if (encoded_dt_2.IsValid()) {
13945      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13946        EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
13947                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13948        AdvanceIT();
13949        return;
13950      }
13951    }
13952  } else {
13953    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
13954    if (encoded_dt.IsValid()) {
13955      if (cond.Is(al)) {
13956        EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) |
13957                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13958        return;
13959      }
13960    }
13961    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2
13962    if (encoded_dt_2.IsValid()) {
13963      if (cond.Is(al)) {
13964        EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
13965                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13966        return;
13967      }
13968    }
13969  }
13970  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
13971}
13972
13973void Assembler::vceq(
13974    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13975  VIXL_ASSERT(AllowAssembler());
13976  CheckIT(cond);
13977  Dt_size_4 encoded_dt(dt);
13978  Dt_sz_1 encoded_dt_2(dt);
13979  if (IsUsingT32()) {
13980    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
13981    if (encoded_dt.IsValid()) {
13982      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13983        EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) |
13984                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13985        AdvanceIT();
13986        return;
13987      }
13988    }
13989    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2
13990    if (encoded_dt_2.IsValid()) {
13991      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13992        EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
13993                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13994        AdvanceIT();
13995        return;
13996      }
13997    }
13998  } else {
13999    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14000    if (encoded_dt.IsValid()) {
14001      if (cond.Is(al)) {
14002        EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) |
14003                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14004        return;
14005      }
14006    }
14007    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2
14008    if (encoded_dt_2.IsValid()) {
14009      if (cond.Is(al)) {
14010        EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
14011                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14012        return;
14013      }
14014    }
14015  }
14016  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
14017}
14018
14019void Assembler::vcge(Condition cond,
14020                     DataType dt,
14021                     DRegister rd,
14022                     DRegister rm,
14023                     const DOperand& operand) {
14024  VIXL_ASSERT(AllowAssembler());
14025  CheckIT(cond);
14026  if (operand.IsImmediate()) {
14027    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14028      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14029      Dt_F_size_1 encoded_dt(dt);
14030      if (IsUsingT32()) {
14031        // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14032        if (encoded_dt.IsValid() && (imm == 0)) {
14033          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14034            EmitT32_32(0xffb10080U |
14035                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14036                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14037                       rd.Encode(22, 12) | rm.Encode(5, 0));
14038            AdvanceIT();
14039            return;
14040          }
14041        }
14042      } else {
14043        // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14044        if (encoded_dt.IsValid() && (imm == 0)) {
14045          if (cond.Is(al)) {
14046            EmitA32(0xf3b10080U |
14047                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14048                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14049                    rd.Encode(22, 12) | rm.Encode(5, 0));
14050            return;
14051          }
14052        }
14053      }
14054    }
14055  }
14056  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
14057}
14058
14059void Assembler::vcge(Condition cond,
14060                     DataType dt,
14061                     QRegister rd,
14062                     QRegister rm,
14063                     const QOperand& operand) {
14064  VIXL_ASSERT(AllowAssembler());
14065  CheckIT(cond);
14066  if (operand.IsImmediate()) {
14067    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14068      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14069      Dt_F_size_1 encoded_dt(dt);
14070      if (IsUsingT32()) {
14071        // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14072        if (encoded_dt.IsValid() && (imm == 0)) {
14073          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14074            EmitT32_32(0xffb100c0U |
14075                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14076                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14077                       rd.Encode(22, 12) | rm.Encode(5, 0));
14078            AdvanceIT();
14079            return;
14080          }
14081        }
14082      } else {
14083        // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14084        if (encoded_dt.IsValid() && (imm == 0)) {
14085          if (cond.Is(al)) {
14086            EmitA32(0xf3b100c0U |
14087                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14088                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14089                    rd.Encode(22, 12) | rm.Encode(5, 0));
14090            return;
14091          }
14092        }
14093      }
14094    }
14095  }
14096  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
14097}
14098
14099void Assembler::vcge(
14100    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14101  VIXL_ASSERT(AllowAssembler());
14102  CheckIT(cond);
14103  Dt_U_size_1 encoded_dt(dt);
14104  if (IsUsingT32()) {
14105    // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14106    if (encoded_dt.IsValid()) {
14107      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14108        EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14109                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14110                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14111        AdvanceIT();
14112        return;
14113      }
14114    }
14115    // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14116    if (dt.Is(F32)) {
14117      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14118        EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14119                   rm.Encode(5, 0));
14120        AdvanceIT();
14121        return;
14122      }
14123    }
14124  } else {
14125    // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14126    if (encoded_dt.IsValid()) {
14127      if (cond.Is(al)) {
14128        EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14129                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14130                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14131        return;
14132      }
14133    }
14134    // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14135    if (dt.Is(F32)) {
14136      if (cond.Is(al)) {
14137        EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14138                rm.Encode(5, 0));
14139        return;
14140      }
14141    }
14142  }
14143  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
14144}
14145
14146void Assembler::vcge(
14147    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14148  VIXL_ASSERT(AllowAssembler());
14149  CheckIT(cond);
14150  Dt_U_size_1 encoded_dt(dt);
14151  if (IsUsingT32()) {
14152    // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14153    if (encoded_dt.IsValid()) {
14154      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14155        EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14156                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14157                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14158        AdvanceIT();
14159        return;
14160      }
14161    }
14162    // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14163    if (dt.Is(F32)) {
14164      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14165        EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14166                   rm.Encode(5, 0));
14167        AdvanceIT();
14168        return;
14169      }
14170    }
14171  } else {
14172    // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14173    if (encoded_dt.IsValid()) {
14174      if (cond.Is(al)) {
14175        EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14176                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14177                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14178        return;
14179      }
14180    }
14181    // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14182    if (dt.Is(F32)) {
14183      if (cond.Is(al)) {
14184        EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14185                rm.Encode(5, 0));
14186        return;
14187      }
14188    }
14189  }
14190  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
14191}
14192
14193void Assembler::vcgt(Condition cond,
14194                     DataType dt,
14195                     DRegister rd,
14196                     DRegister rm,
14197                     const DOperand& operand) {
14198  VIXL_ASSERT(AllowAssembler());
14199  CheckIT(cond);
14200  if (operand.IsImmediate()) {
14201    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14202      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14203      Dt_F_size_1 encoded_dt(dt);
14204      if (IsUsingT32()) {
14205        // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14206        if (encoded_dt.IsValid() && (imm == 0)) {
14207          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14208            EmitT32_32(0xffb10000U |
14209                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14210                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14211                       rd.Encode(22, 12) | rm.Encode(5, 0));
14212            AdvanceIT();
14213            return;
14214          }
14215        }
14216      } else {
14217        // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14218        if (encoded_dt.IsValid() && (imm == 0)) {
14219          if (cond.Is(al)) {
14220            EmitA32(0xf3b10000U |
14221                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14222                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14223                    rd.Encode(22, 12) | rm.Encode(5, 0));
14224            return;
14225          }
14226        }
14227      }
14228    }
14229  }
14230  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
14231}
14232
14233void Assembler::vcgt(Condition cond,
14234                     DataType dt,
14235                     QRegister rd,
14236                     QRegister rm,
14237                     const QOperand& operand) {
14238  VIXL_ASSERT(AllowAssembler());
14239  CheckIT(cond);
14240  if (operand.IsImmediate()) {
14241    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14242      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14243      Dt_F_size_1 encoded_dt(dt);
14244      if (IsUsingT32()) {
14245        // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14246        if (encoded_dt.IsValid() && (imm == 0)) {
14247          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14248            EmitT32_32(0xffb10040U |
14249                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14250                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14251                       rd.Encode(22, 12) | rm.Encode(5, 0));
14252            AdvanceIT();
14253            return;
14254          }
14255        }
14256      } else {
14257        // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14258        if (encoded_dt.IsValid() && (imm == 0)) {
14259          if (cond.Is(al)) {
14260            EmitA32(0xf3b10040U |
14261                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14262                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14263                    rd.Encode(22, 12) | rm.Encode(5, 0));
14264            return;
14265          }
14266        }
14267      }
14268    }
14269  }
14270  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
14271}
14272
14273void Assembler::vcgt(
14274    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14275  VIXL_ASSERT(AllowAssembler());
14276  CheckIT(cond);
14277  Dt_U_size_1 encoded_dt(dt);
14278  if (IsUsingT32()) {
14279    // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14280    if (encoded_dt.IsValid()) {
14281      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14282        EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14283                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14284                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14285        AdvanceIT();
14286        return;
14287      }
14288    }
14289    // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14290    if (dt.Is(F32)) {
14291      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14292        EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14293                   rm.Encode(5, 0));
14294        AdvanceIT();
14295        return;
14296      }
14297    }
14298  } else {
14299    // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14300    if (encoded_dt.IsValid()) {
14301      if (cond.Is(al)) {
14302        EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14303                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14304                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14305        return;
14306      }
14307    }
14308    // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14309    if (dt.Is(F32)) {
14310      if (cond.Is(al)) {
14311        EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14312                rm.Encode(5, 0));
14313        return;
14314      }
14315    }
14316  }
14317  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
14318}
14319
14320void Assembler::vcgt(
14321    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14322  VIXL_ASSERT(AllowAssembler());
14323  CheckIT(cond);
14324  Dt_U_size_1 encoded_dt(dt);
14325  if (IsUsingT32()) {
14326    // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14327    if (encoded_dt.IsValid()) {
14328      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14329        EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14330                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14331                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14332        AdvanceIT();
14333        return;
14334      }
14335    }
14336    // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14337    if (dt.Is(F32)) {
14338      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14339        EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14340                   rm.Encode(5, 0));
14341        AdvanceIT();
14342        return;
14343      }
14344    }
14345  } else {
14346    // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14347    if (encoded_dt.IsValid()) {
14348      if (cond.Is(al)) {
14349        EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14350                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14351                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14352        return;
14353      }
14354    }
14355    // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14356    if (dt.Is(F32)) {
14357      if (cond.Is(al)) {
14358        EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14359                rm.Encode(5, 0));
14360        return;
14361      }
14362    }
14363  }
14364  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
14365}
14366
14367void Assembler::vcle(Condition cond,
14368                     DataType dt,
14369                     DRegister rd,
14370                     DRegister rm,
14371                     const DOperand& operand) {
14372  VIXL_ASSERT(AllowAssembler());
14373  CheckIT(cond);
14374  if (operand.IsImmediate()) {
14375    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14376      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14377      Dt_F_size_1 encoded_dt(dt);
14378      if (IsUsingT32()) {
14379        // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14380        if (encoded_dt.IsValid() && (imm == 0)) {
14381          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14382            EmitT32_32(0xffb10180U |
14383                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14384                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14385                       rd.Encode(22, 12) | rm.Encode(5, 0));
14386            AdvanceIT();
14387            return;
14388          }
14389        }
14390      } else {
14391        // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14392        if (encoded_dt.IsValid() && (imm == 0)) {
14393          if (cond.Is(al)) {
14394            EmitA32(0xf3b10180U |
14395                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14396                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14397                    rd.Encode(22, 12) | rm.Encode(5, 0));
14398            return;
14399          }
14400        }
14401      }
14402    }
14403  }
14404  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
14405}
14406
14407void Assembler::vcle(Condition cond,
14408                     DataType dt,
14409                     QRegister rd,
14410                     QRegister rm,
14411                     const QOperand& operand) {
14412  VIXL_ASSERT(AllowAssembler());
14413  CheckIT(cond);
14414  if (operand.IsImmediate()) {
14415    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14416      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14417      Dt_F_size_1 encoded_dt(dt);
14418      if (IsUsingT32()) {
14419        // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14420        if (encoded_dt.IsValid() && (imm == 0)) {
14421          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14422            EmitT32_32(0xffb101c0U |
14423                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14424                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14425                       rd.Encode(22, 12) | rm.Encode(5, 0));
14426            AdvanceIT();
14427            return;
14428          }
14429        }
14430      } else {
14431        // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14432        if (encoded_dt.IsValid() && (imm == 0)) {
14433          if (cond.Is(al)) {
14434            EmitA32(0xf3b101c0U |
14435                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14436                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14437                    rd.Encode(22, 12) | rm.Encode(5, 0));
14438            return;
14439          }
14440        }
14441      }
14442    }
14443  }
14444  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
14445}
14446
14447void Assembler::vcle(
14448    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14449  VIXL_ASSERT(AllowAssembler());
14450  CheckIT(cond);
14451  Dt_U_size_1 encoded_dt(dt);
14452  if (IsUsingT32()) {
14453    // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14454    if (encoded_dt.IsValid()) {
14455      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14456        EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14457                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14458                   rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14459        AdvanceIT();
14460        return;
14461      }
14462    }
14463    // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14464    if (dt.Is(F32)) {
14465      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14466        EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14467                   rm.Encode(7, 16));
14468        AdvanceIT();
14469        return;
14470      }
14471    }
14472  } else {
14473    // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14474    if (encoded_dt.IsValid()) {
14475      if (cond.Is(al)) {
14476        EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14477                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14478                rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14479        return;
14480      }
14481    }
14482    // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14483    if (dt.Is(F32)) {
14484      if (cond.Is(al)) {
14485        EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14486                rm.Encode(7, 16));
14487        return;
14488      }
14489    }
14490  }
14491  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
14492}
14493
14494void Assembler::vcle(
14495    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14496  VIXL_ASSERT(AllowAssembler());
14497  CheckIT(cond);
14498  Dt_U_size_1 encoded_dt(dt);
14499  if (IsUsingT32()) {
14500    // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14501    if (encoded_dt.IsValid()) {
14502      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14503        EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14504                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14505                   rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14506        AdvanceIT();
14507        return;
14508      }
14509    }
14510    // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14511    if (dt.Is(F32)) {
14512      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14513        EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14514                   rm.Encode(7, 16));
14515        AdvanceIT();
14516        return;
14517      }
14518    }
14519  } else {
14520    // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14521    if (encoded_dt.IsValid()) {
14522      if (cond.Is(al)) {
14523        EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14524                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14525                rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14526        return;
14527      }
14528    }
14529    // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14530    if (dt.Is(F32)) {
14531      if (cond.Is(al)) {
14532        EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14533                rm.Encode(7, 16));
14534        return;
14535      }
14536    }
14537  }
14538  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
14539}
14540
14541void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14542  VIXL_ASSERT(AllowAssembler());
14543  CheckIT(cond);
14544  Dt_size_5 encoded_dt(dt);
14545  if (IsUsingT32()) {
14546    // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
14547    if (encoded_dt.IsValid()) {
14548      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14549        EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) |
14550                   rd.Encode(22, 12) | rm.Encode(5, 0));
14551        AdvanceIT();
14552        return;
14553      }
14554    }
14555  } else {
14556    // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
14557    if (encoded_dt.IsValid()) {
14558      if (cond.Is(al)) {
14559        EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) |
14560                rd.Encode(22, 12) | rm.Encode(5, 0));
14561        return;
14562      }
14563    }
14564  }
14565  Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
14566}
14567
14568void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14569  VIXL_ASSERT(AllowAssembler());
14570  CheckIT(cond);
14571  Dt_size_5 encoded_dt(dt);
14572  if (IsUsingT32()) {
14573    // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
14574    if (encoded_dt.IsValid()) {
14575      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14576        EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) |
14577                   rd.Encode(22, 12) | rm.Encode(5, 0));
14578        AdvanceIT();
14579        return;
14580      }
14581    }
14582  } else {
14583    // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
14584    if (encoded_dt.IsValid()) {
14585      if (cond.Is(al)) {
14586        EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) |
14587                rd.Encode(22, 12) | rm.Encode(5, 0));
14588        return;
14589      }
14590    }
14591  }
14592  Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
14593}
14594
14595void Assembler::vclt(Condition cond,
14596                     DataType dt,
14597                     DRegister rd,
14598                     DRegister rm,
14599                     const DOperand& operand) {
14600  VIXL_ASSERT(AllowAssembler());
14601  CheckIT(cond);
14602  if (operand.IsImmediate()) {
14603    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14604      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14605      Dt_F_size_1 encoded_dt(dt);
14606      if (IsUsingT32()) {
14607        // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14608        if (encoded_dt.IsValid() && (imm == 0)) {
14609          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14610            EmitT32_32(0xffb10200U |
14611                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14612                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14613                       rd.Encode(22, 12) | rm.Encode(5, 0));
14614            AdvanceIT();
14615            return;
14616          }
14617        }
14618      } else {
14619        // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14620        if (encoded_dt.IsValid() && (imm == 0)) {
14621          if (cond.Is(al)) {
14622            EmitA32(0xf3b10200U |
14623                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14624                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14625                    rd.Encode(22, 12) | rm.Encode(5, 0));
14626            return;
14627          }
14628        }
14629      }
14630    }
14631  }
14632  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
14633}
14634
14635void Assembler::vclt(Condition cond,
14636                     DataType dt,
14637                     QRegister rd,
14638                     QRegister rm,
14639                     const QOperand& operand) {
14640  VIXL_ASSERT(AllowAssembler());
14641  CheckIT(cond);
14642  if (operand.IsImmediate()) {
14643    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14644      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14645      Dt_F_size_1 encoded_dt(dt);
14646      if (IsUsingT32()) {
14647        // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14648        if (encoded_dt.IsValid() && (imm == 0)) {
14649          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14650            EmitT32_32(0xffb10240U |
14651                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14652                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14653                       rd.Encode(22, 12) | rm.Encode(5, 0));
14654            AdvanceIT();
14655            return;
14656          }
14657        }
14658      } else {
14659        // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14660        if (encoded_dt.IsValid() && (imm == 0)) {
14661          if (cond.Is(al)) {
14662            EmitA32(0xf3b10240U |
14663                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14664                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14665                    rd.Encode(22, 12) | rm.Encode(5, 0));
14666            return;
14667          }
14668        }
14669      }
14670    }
14671  }
14672  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
14673}
14674
14675void Assembler::vclt(
14676    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14677  VIXL_ASSERT(AllowAssembler());
14678  CheckIT(cond);
14679  Dt_U_size_1 encoded_dt(dt);
14680  if (IsUsingT32()) {
14681    // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14682    if (encoded_dt.IsValid()) {
14683      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14684        EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14685                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14686                   rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14687        AdvanceIT();
14688        return;
14689      }
14690    }
14691    // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14692    if (dt.Is(F32)) {
14693      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14694        EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14695                   rm.Encode(7, 16));
14696        AdvanceIT();
14697        return;
14698      }
14699    }
14700  } else {
14701    // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14702    if (encoded_dt.IsValid()) {
14703      if (cond.Is(al)) {
14704        EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14705                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14706                rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14707        return;
14708      }
14709    }
14710    // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14711    if (dt.Is(F32)) {
14712      if (cond.Is(al)) {
14713        EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14714                rm.Encode(7, 16));
14715        return;
14716      }
14717    }
14718  }
14719  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
14720}
14721
14722void Assembler::vclt(
14723    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14724  VIXL_ASSERT(AllowAssembler());
14725  CheckIT(cond);
14726  Dt_U_size_1 encoded_dt(dt);
14727  if (IsUsingT32()) {
14728    // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14729    if (encoded_dt.IsValid()) {
14730      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14731        EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14732                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14733                   rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14734        AdvanceIT();
14735        return;
14736      }
14737    }
14738    // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14739    if (dt.Is(F32)) {
14740      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14741        EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14742                   rm.Encode(7, 16));
14743        AdvanceIT();
14744        return;
14745      }
14746    }
14747  } else {
14748    // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14749    if (encoded_dt.IsValid()) {
14750      if (cond.Is(al)) {
14751        EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14752                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14753                rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14754        return;
14755      }
14756    }
14757    // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14758    if (dt.Is(F32)) {
14759      if (cond.Is(al)) {
14760        EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14761                rm.Encode(7, 16));
14762        return;
14763      }
14764    }
14765  }
14766  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
14767}
14768
14769void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14770  VIXL_ASSERT(AllowAssembler());
14771  CheckIT(cond);
14772  Dt_size_4 encoded_dt(dt);
14773  if (IsUsingT32()) {
14774    // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
14775    if (encoded_dt.IsValid()) {
14776      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14777        EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) |
14778                   rd.Encode(22, 12) | rm.Encode(5, 0));
14779        AdvanceIT();
14780        return;
14781      }
14782    }
14783  } else {
14784    // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
14785    if (encoded_dt.IsValid()) {
14786      if (cond.Is(al)) {
14787        EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) |
14788                rd.Encode(22, 12) | rm.Encode(5, 0));
14789        return;
14790      }
14791    }
14792  }
14793  Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
14794}
14795
14796void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14797  VIXL_ASSERT(AllowAssembler());
14798  CheckIT(cond);
14799  Dt_size_4 encoded_dt(dt);
14800  if (IsUsingT32()) {
14801    // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
14802    if (encoded_dt.IsValid()) {
14803      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14804        EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) |
14805                   rd.Encode(22, 12) | rm.Encode(5, 0));
14806        AdvanceIT();
14807        return;
14808      }
14809    }
14810  } else {
14811    // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
14812    if (encoded_dt.IsValid()) {
14813      if (cond.Is(al)) {
14814        EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) |
14815                rd.Encode(22, 12) | rm.Encode(5, 0));
14816        return;
14817      }
14818    }
14819  }
14820  Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
14821}
14822
14823void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, SRegister rm) {
14824  VIXL_ASSERT(AllowAssembler());
14825  CheckIT(cond);
14826  if (IsUsingT32()) {
14827    // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
14828    if (dt.Is(F32)) {
14829      EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
14830      AdvanceIT();
14831      return;
14832    }
14833  } else {
14834    // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
14835    if (dt.Is(F32) && cond.IsNotNever()) {
14836      EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14837              rm.Encode(5, 0));
14838      return;
14839    }
14840  }
14841  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm);
14842}
14843
14844void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14845  VIXL_ASSERT(AllowAssembler());
14846  CheckIT(cond);
14847  if (IsUsingT32()) {
14848    // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
14849    if (dt.Is(F64)) {
14850      EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
14851      AdvanceIT();
14852      return;
14853    }
14854  } else {
14855    // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
14856    if (dt.Is(F64) && cond.IsNotNever()) {
14857      EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14858              rm.Encode(5, 0));
14859      return;
14860    }
14861  }
14862  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm);
14863}
14864
14865void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, double imm) {
14866  VIXL_ASSERT(AllowAssembler());
14867  CheckIT(cond);
14868  if (IsUsingT32()) {
14869    // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
14870    if (dt.Is(F32) && (imm == 0.0)) {
14871      EmitT32_32(0xeeb50a40U | rd.Encode(22, 12));
14872      AdvanceIT();
14873      return;
14874    }
14875  } else {
14876    // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
14877    if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) {
14878      EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14879      return;
14880    }
14881  }
14882  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm);
14883}
14884
14885void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, double imm) {
14886  VIXL_ASSERT(AllowAssembler());
14887  CheckIT(cond);
14888  if (IsUsingT32()) {
14889    // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
14890    if (dt.Is(F64) && (imm == 0.0)) {
14891      EmitT32_32(0xeeb50b40U | rd.Encode(22, 12));
14892      AdvanceIT();
14893      return;
14894    }
14895  } else {
14896    // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
14897    if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) {
14898      EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14899      return;
14900    }
14901  }
14902  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm);
14903}
14904
14905void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, SRegister rm) {
14906  VIXL_ASSERT(AllowAssembler());
14907  CheckIT(cond);
14908  if (IsUsingT32()) {
14909    // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
14910    if (dt.Is(F32)) {
14911      EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14912      AdvanceIT();
14913      return;
14914    }
14915  } else {
14916    // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
14917    if (dt.Is(F32) && cond.IsNotNever()) {
14918      EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14919              rm.Encode(5, 0));
14920      return;
14921    }
14922  }
14923  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm);
14924}
14925
14926void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14927  VIXL_ASSERT(AllowAssembler());
14928  CheckIT(cond);
14929  if (IsUsingT32()) {
14930    // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
14931    if (dt.Is(F64)) {
14932      EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14933      AdvanceIT();
14934      return;
14935    }
14936  } else {
14937    // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
14938    if (dt.Is(F64) && cond.IsNotNever()) {
14939      EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14940              rm.Encode(5, 0));
14941      return;
14942    }
14943  }
14944  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm);
14945}
14946
14947void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, double imm) {
14948  VIXL_ASSERT(AllowAssembler());
14949  CheckIT(cond);
14950  if (IsUsingT32()) {
14951    // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
14952    if (dt.Is(F32) && (imm == 0.0)) {
14953      EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12));
14954      AdvanceIT();
14955      return;
14956    }
14957  } else {
14958    // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
14959    if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) {
14960      EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14961      return;
14962    }
14963  }
14964  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm);
14965}
14966
14967void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, double imm) {
14968  VIXL_ASSERT(AllowAssembler());
14969  CheckIT(cond);
14970  if (IsUsingT32()) {
14971    // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
14972    if (dt.Is(F64) && (imm == 0.0)) {
14973      EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12));
14974      AdvanceIT();
14975      return;
14976    }
14977  } else {
14978    // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
14979    if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) {
14980      EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14981      return;
14982    }
14983  }
14984  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm);
14985}
14986
14987void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14988  VIXL_ASSERT(AllowAssembler());
14989  CheckIT(cond);
14990  if (IsUsingT32()) {
14991    // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1
14992    if (dt.Is(Untyped8)) {
14993      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14994        EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
14995        AdvanceIT();
14996        return;
14997      }
14998    }
14999  } else {
15000    // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1
15001    if (dt.Is(Untyped8)) {
15002      if (cond.Is(al)) {
15003        EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
15004        return;
15005      }
15006    }
15007  }
15008  Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
15009}
15010
15011void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) {
15012  VIXL_ASSERT(AllowAssembler());
15013  CheckIT(cond);
15014  if (IsUsingT32()) {
15015    // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1
15016    if (dt.Is(Untyped8)) {
15017      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15018        EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
15019        AdvanceIT();
15020        return;
15021      }
15022    }
15023  } else {
15024    // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1
15025    if (dt.Is(Untyped8)) {
15026      if (cond.Is(al)) {
15027        EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
15028        return;
15029      }
15030    }
15031  }
15032  Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
15033}
15034
15035void Assembler::vcvt(
15036    Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
15037  VIXL_ASSERT(AllowAssembler());
15038  CheckIT(cond);
15039  Dt_op_2 encoded_dt(dt2);
15040  if (IsUsingT32()) {
15041    // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1
15042    if (dt1.Is(F64) && dt2.Is(F32)) {
15043      EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15044      AdvanceIT();
15045      return;
15046    }
15047    // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1
15048    if (dt1.Is(F64) && encoded_dt.IsValid()) {
15049      EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) |
15050                 rd.Encode(22, 12) | rm.Encode(5, 0));
15051      AdvanceIT();
15052      return;
15053    }
15054  } else {
15055    // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1
15056    if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) {
15057      EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15058              rm.Encode(5, 0));
15059      return;
15060    }
15061    // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1
15062    if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) {
15063      EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) |
15064              (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
15065              rm.Encode(5, 0));
15066      return;
15067    }
15068  }
15069  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15070}
15071
15072void Assembler::vcvt(
15073    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15074  VIXL_ASSERT(AllowAssembler());
15075  CheckIT(cond);
15076  if (IsUsingT32()) {
15077    // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1
15078    if (dt1.Is(F32) && dt2.Is(F64)) {
15079      EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15080      AdvanceIT();
15081      return;
15082    }
15083    // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
15084    if (dt1.Is(U32) && dt2.Is(F64)) {
15085      EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15086      AdvanceIT();
15087      return;
15088    }
15089    // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
15090    if (dt1.Is(S32) && dt2.Is(F64)) {
15091      EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15092      AdvanceIT();
15093      return;
15094    }
15095  } else {
15096    // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1
15097    if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) {
15098      EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15099              rm.Encode(5, 0));
15100      return;
15101    }
15102    // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
15103    if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
15104      EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15105              rm.Encode(5, 0));
15106      return;
15107    }
15108    // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
15109    if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
15110      EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15111              rm.Encode(5, 0));
15112      return;
15113    }
15114  }
15115  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15116}
15117
15118void Assembler::vcvt(Condition cond,
15119                     DataType dt1,
15120                     DataType dt2,
15121                     DRegister rd,
15122                     DRegister rm,
15123                     int32_t fbits) {
15124  VIXL_ASSERT(AllowAssembler());
15125  CheckIT(cond);
15126  Dt_op_U_1 encoded_dt(dt1, dt2);
15127  Dt_U_sx_1 encoded_dt_2(dt2);
15128  Dt_U_sx_1 encoded_dt_3(dt1);
15129  if (IsUsingT32()) {
15130    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1
15131    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15132      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15133        uint32_t fbits_ = 64 - fbits;
15134        EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
15135                   ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15136                   rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15137        AdvanceIT();
15138        return;
15139      }
15140    }
15141    // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1
15142    if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
15143        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15144         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15145      unsigned offset = 32;
15146      if (dt2.Is(S16) || dt2.Is(U16)) {
15147        offset = 16;
15148      }
15149      uint32_t fbits_ = offset - fbits;
15150      EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15151                 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15152                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15153                 ((fbits_ & 0x1e) >> 1));
15154      AdvanceIT();
15155      return;
15156    }
15157    // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1
15158    if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
15159        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15160         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15161      unsigned offset = 32;
15162      if (dt1.Is(S16) || dt1.Is(U16)) {
15163        offset = 16;
15164      }
15165      uint32_t fbits_ = offset - fbits;
15166      EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
15167                 ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
15168                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15169                 ((fbits_ & 0x1e) >> 1));
15170      AdvanceIT();
15171      return;
15172    }
15173  } else {
15174    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1
15175    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15176      if (cond.Is(al)) {
15177        uint32_t fbits_ = 64 - fbits;
15178        EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
15179                ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15180                rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15181        return;
15182      }
15183    }
15184    // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1
15185    if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
15186        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15187         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15188        cond.IsNotNever()) {
15189      unsigned offset = 32;
15190      if (dt2.Is(S16) || dt2.Is(U16)) {
15191        offset = 16;
15192      }
15193      uint32_t fbits_ = offset - fbits;
15194      EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) |
15195              ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15196              ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15197              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15198              ((fbits_ & 0x1e) >> 1));
15199      return;
15200    }
15201    // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1
15202    if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
15203        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15204         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15205        cond.IsNotNever()) {
15206      unsigned offset = 32;
15207      if (dt1.Is(S16) || dt1.Is(U16)) {
15208        offset = 16;
15209      }
15210      uint32_t fbits_ = offset - fbits;
15211      EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) |
15212              ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
15213              ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
15214              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15215              ((fbits_ & 0x1e) >> 1));
15216      return;
15217    }
15218  }
15219  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
15220}
15221
15222void Assembler::vcvt(Condition cond,
15223                     DataType dt1,
15224                     DataType dt2,
15225                     QRegister rd,
15226                     QRegister rm,
15227                     int32_t fbits) {
15228  VIXL_ASSERT(AllowAssembler());
15229  CheckIT(cond);
15230  Dt_op_U_1 encoded_dt(dt1, dt2);
15231  if (IsUsingT32()) {
15232    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1
15233    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15234      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15235        uint32_t fbits_ = 64 - fbits;
15236        EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
15237                   ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15238                   rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15239        AdvanceIT();
15240        return;
15241      }
15242    }
15243  } else {
15244    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1
15245    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15246      if (cond.Is(al)) {
15247        uint32_t fbits_ = 64 - fbits;
15248        EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
15249                ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15250                rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15251        return;
15252      }
15253    }
15254  }
15255  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
15256}
15257
15258void Assembler::vcvt(Condition cond,
15259                     DataType dt1,
15260                     DataType dt2,
15261                     SRegister rd,
15262                     SRegister rm,
15263                     int32_t fbits) {
15264  VIXL_ASSERT(AllowAssembler());
15265  CheckIT(cond);
15266  Dt_U_sx_1 encoded_dt(dt2);
15267  Dt_U_sx_1 encoded_dt_2(dt1);
15268  if (IsUsingT32()) {
15269    // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1
15270    if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
15271        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15272         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15273      unsigned offset = 32;
15274      if (dt2.Is(S16) || dt2.Is(U16)) {
15275        offset = 16;
15276      }
15277      uint32_t fbits_ = offset - fbits;
15278      EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
15279                 ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
15280                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15281                 ((fbits_ & 0x1e) >> 1));
15282      AdvanceIT();
15283      return;
15284    }
15285    // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1
15286    if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
15287        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15288         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15289      unsigned offset = 32;
15290      if (dt1.Is(S16) || dt1.Is(U16)) {
15291        offset = 16;
15292      }
15293      uint32_t fbits_ = offset - fbits;
15294      EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15295                 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15296                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15297                 ((fbits_ & 0x1e) >> 1));
15298      AdvanceIT();
15299      return;
15300    }
15301  } else {
15302    // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1
15303    if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
15304        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15305         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15306        cond.IsNotNever()) {
15307      unsigned offset = 32;
15308      if (dt2.Is(S16) || dt2.Is(U16)) {
15309        offset = 16;
15310      }
15311      uint32_t fbits_ = offset - fbits;
15312      EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) |
15313              ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
15314              ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
15315              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15316              ((fbits_ & 0x1e) >> 1));
15317      return;
15318    }
15319    // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1
15320    if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
15321        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15322         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15323        cond.IsNotNever()) {
15324      unsigned offset = 32;
15325      if (dt1.Is(S16) || dt1.Is(U16)) {
15326        offset = 16;
15327      }
15328      uint32_t fbits_ = offset - fbits;
15329      EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) |
15330              ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15331              ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15332              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15333              ((fbits_ & 0x1e) >> 1));
15334      return;
15335    }
15336  }
15337  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
15338}
15339
15340void Assembler::vcvt(
15341    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15342  VIXL_ASSERT(AllowAssembler());
15343  CheckIT(cond);
15344  Dt_op_1 encoded_dt(dt1, dt2);
15345  if (IsUsingT32()) {
15346    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1
15347    if (encoded_dt.IsValid()) {
15348      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15349        EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) |
15350                   rd.Encode(22, 12) | rm.Encode(5, 0));
15351        AdvanceIT();
15352        return;
15353      }
15354    }
15355  } else {
15356    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1
15357    if (encoded_dt.IsValid()) {
15358      if (cond.Is(al)) {
15359        EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) |
15360                rd.Encode(22, 12) | rm.Encode(5, 0));
15361        return;
15362      }
15363    }
15364  }
15365  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15366}
15367
15368void Assembler::vcvt(
15369    Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15370  VIXL_ASSERT(AllowAssembler());
15371  CheckIT(cond);
15372  Dt_op_1 encoded_dt(dt1, dt2);
15373  if (IsUsingT32()) {
15374    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1
15375    if (encoded_dt.IsValid()) {
15376      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15377        EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) |
15378                   rd.Encode(22, 12) | rm.Encode(5, 0));
15379        AdvanceIT();
15380        return;
15381      }
15382    }
15383  } else {
15384    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1
15385    if (encoded_dt.IsValid()) {
15386      if (cond.Is(al)) {
15387        EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) |
15388                rd.Encode(22, 12) | rm.Encode(5, 0));
15389        return;
15390      }
15391    }
15392  }
15393  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15394}
15395
15396void Assembler::vcvt(
15397    Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) {
15398  VIXL_ASSERT(AllowAssembler());
15399  CheckIT(cond);
15400  if (IsUsingT32()) {
15401    // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1
15402    if (dt1.Is(F16) && dt2.Is(F32)) {
15403      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15404        EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
15405        AdvanceIT();
15406        return;
15407      }
15408    }
15409  } else {
15410    // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1
15411    if (dt1.Is(F16) && dt2.Is(F32)) {
15412      if (cond.Is(al)) {
15413        EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
15414        return;
15415      }
15416    }
15417  }
15418  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15419}
15420
15421void Assembler::vcvt(
15422    Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) {
15423  VIXL_ASSERT(AllowAssembler());
15424  CheckIT(cond);
15425  if (IsUsingT32()) {
15426    // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1
15427    if (dt1.Is(F32) && dt2.Is(F16)) {
15428      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15429        EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
15430        AdvanceIT();
15431        return;
15432      }
15433    }
15434  } else {
15435    // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1
15436    if (dt1.Is(F32) && dt2.Is(F16)) {
15437      if (cond.Is(al)) {
15438        EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
15439        return;
15440      }
15441    }
15442  }
15443  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15444}
15445
15446void Assembler::vcvt(
15447    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15448  VIXL_ASSERT(AllowAssembler());
15449  CheckIT(cond);
15450  Dt_op_2 encoded_dt(dt2);
15451  if (IsUsingT32()) {
15452    // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
15453    if (dt1.Is(U32) && dt2.Is(F32)) {
15454      EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15455      AdvanceIT();
15456      return;
15457    }
15458    // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
15459    if (dt1.Is(S32) && dt2.Is(F32)) {
15460      EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15461      AdvanceIT();
15462      return;
15463    }
15464    // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1
15465    if (dt1.Is(F32) && encoded_dt.IsValid()) {
15466      EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) |
15467                 rd.Encode(22, 12) | rm.Encode(5, 0));
15468      AdvanceIT();
15469      return;
15470    }
15471  } else {
15472    // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
15473    if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
15474      EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15475              rm.Encode(5, 0));
15476      return;
15477    }
15478    // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
15479    if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
15480      EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15481              rm.Encode(5, 0));
15482      return;
15483    }
15484    // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1
15485    if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) {
15486      EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) |
15487              (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
15488              rm.Encode(5, 0));
15489      return;
15490    }
15491  }
15492  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15493}
15494
15495void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15496  VIXL_ASSERT(AllowAssembler());
15497  CheckIT(al);
15498  Dt_op_3 encoded_dt(dt1);
15499  if (IsUsingT32()) {
15500    // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15501    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15502      EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) |
15503                 rd.Encode(22, 12) | rm.Encode(5, 0));
15504      AdvanceIT();
15505      return;
15506    }
15507  } else {
15508    // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15509    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15510      EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) |
15511              rd.Encode(22, 12) | rm.Encode(5, 0));
15512      return;
15513    }
15514  }
15515  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15516}
15517
15518void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15519  VIXL_ASSERT(AllowAssembler());
15520  CheckIT(al);
15521  Dt_op_3 encoded_dt(dt1);
15522  if (IsUsingT32()) {
15523    // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15524    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15525      EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) |
15526                 rd.Encode(22, 12) | rm.Encode(5, 0));
15527      AdvanceIT();
15528      return;
15529    }
15530  } else {
15531    // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15532    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15533      EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) |
15534              rd.Encode(22, 12) | rm.Encode(5, 0));
15535      return;
15536    }
15537  }
15538  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15539}
15540
15541void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15542  VIXL_ASSERT(AllowAssembler());
15543  CheckIT(al);
15544  Dt_op_2 encoded_dt(dt1);
15545  if (IsUsingT32()) {
15546    // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15547    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15548      EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
15549                 rd.Encode(22, 12) | rm.Encode(5, 0));
15550      AdvanceIT();
15551      return;
15552    }
15553  } else {
15554    // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15555    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15556      EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
15557              rd.Encode(22, 12) | rm.Encode(5, 0));
15558      return;
15559    }
15560  }
15561  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15562}
15563
15564void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15565  VIXL_ASSERT(AllowAssembler());
15566  CheckIT(al);
15567  Dt_op_2 encoded_dt(dt1);
15568  if (IsUsingT32()) {
15569    // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15570    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15571      EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
15572                 rd.Encode(22, 12) | rm.Encode(5, 0));
15573      AdvanceIT();
15574      return;
15575    }
15576  } else {
15577    // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15578    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15579      EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
15580              rd.Encode(22, 12) | rm.Encode(5, 0));
15581      return;
15582    }
15583  }
15584  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15585}
15586
15587void Assembler::vcvtb(
15588    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15589  VIXL_ASSERT(AllowAssembler());
15590  CheckIT(cond);
15591  if (IsUsingT32()) {
15592    // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
15593    if (dt1.Is(F32) && dt2.Is(F16)) {
15594      EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15595      AdvanceIT();
15596      return;
15597    }
15598    // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
15599    if (dt1.Is(F16) && dt2.Is(F32)) {
15600      EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15601      AdvanceIT();
15602      return;
15603    }
15604  } else {
15605    // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
15606    if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
15607      EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15608              rm.Encode(5, 0));
15609      return;
15610    }
15611    // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
15612    if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
15613      EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15614              rm.Encode(5, 0));
15615      return;
15616    }
15617  }
15618  Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15619}
15620
15621void Assembler::vcvtb(
15622    Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
15623  VIXL_ASSERT(AllowAssembler());
15624  CheckIT(cond);
15625  if (IsUsingT32()) {
15626    // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
15627    if (dt1.Is(F64) && dt2.Is(F16)) {
15628      EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15629      AdvanceIT();
15630      return;
15631    }
15632  } else {
15633    // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
15634    if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
15635      EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15636              rm.Encode(5, 0));
15637      return;
15638    }
15639  }
15640  Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15641}
15642
15643void Assembler::vcvtb(
15644    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15645  VIXL_ASSERT(AllowAssembler());
15646  CheckIT(cond);
15647  if (IsUsingT32()) {
15648    // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
15649    if (dt1.Is(F16) && dt2.Is(F64)) {
15650      EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15651      AdvanceIT();
15652      return;
15653    }
15654  } else {
15655    // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
15656    if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
15657      EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15658              rm.Encode(5, 0));
15659      return;
15660    }
15661  }
15662  Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15663}
15664
15665void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15666  VIXL_ASSERT(AllowAssembler());
15667  CheckIT(al);
15668  Dt_op_3 encoded_dt(dt1);
15669  if (IsUsingT32()) {
15670    // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15671    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15672      EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) |
15673                 rd.Encode(22, 12) | rm.Encode(5, 0));
15674      AdvanceIT();
15675      return;
15676    }
15677  } else {
15678    // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15679    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15680      EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) |
15681              rd.Encode(22, 12) | rm.Encode(5, 0));
15682      return;
15683    }
15684  }
15685  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15686}
15687
15688void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15689  VIXL_ASSERT(AllowAssembler());
15690  CheckIT(al);
15691  Dt_op_3 encoded_dt(dt1);
15692  if (IsUsingT32()) {
15693    // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15694    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15695      EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) |
15696                 rd.Encode(22, 12) | rm.Encode(5, 0));
15697      AdvanceIT();
15698      return;
15699    }
15700  } else {
15701    // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15702    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15703      EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) |
15704              rd.Encode(22, 12) | rm.Encode(5, 0));
15705      return;
15706    }
15707  }
15708  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15709}
15710
15711void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15712  VIXL_ASSERT(AllowAssembler());
15713  CheckIT(al);
15714  Dt_op_2 encoded_dt(dt1);
15715  if (IsUsingT32()) {
15716    // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15717    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15718      EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
15719                 rd.Encode(22, 12) | rm.Encode(5, 0));
15720      AdvanceIT();
15721      return;
15722    }
15723  } else {
15724    // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15725    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15726      EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
15727              rd.Encode(22, 12) | rm.Encode(5, 0));
15728      return;
15729    }
15730  }
15731  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15732}
15733
15734void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15735  VIXL_ASSERT(AllowAssembler());
15736  CheckIT(al);
15737  Dt_op_2 encoded_dt(dt1);
15738  if (IsUsingT32()) {
15739    // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15740    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15741      EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
15742                 rd.Encode(22, 12) | rm.Encode(5, 0));
15743      AdvanceIT();
15744      return;
15745    }
15746  } else {
15747    // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15748    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15749      EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
15750              rd.Encode(22, 12) | rm.Encode(5, 0));
15751      return;
15752    }
15753  }
15754  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15755}
15756
15757void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15758  VIXL_ASSERT(AllowAssembler());
15759  CheckIT(al);
15760  Dt_op_3 encoded_dt(dt1);
15761  if (IsUsingT32()) {
15762    // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15763    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15764      EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) |
15765                 rd.Encode(22, 12) | rm.Encode(5, 0));
15766      AdvanceIT();
15767      return;
15768    }
15769  } else {
15770    // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15771    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15772      EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) |
15773              rd.Encode(22, 12) | rm.Encode(5, 0));
15774      return;
15775    }
15776  }
15777  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15778}
15779
15780void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15781  VIXL_ASSERT(AllowAssembler());
15782  CheckIT(al);
15783  Dt_op_3 encoded_dt(dt1);
15784  if (IsUsingT32()) {
15785    // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15786    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15787      EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) |
15788                 rd.Encode(22, 12) | rm.Encode(5, 0));
15789      AdvanceIT();
15790      return;
15791    }
15792  } else {
15793    // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15794    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15795      EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) |
15796              rd.Encode(22, 12) | rm.Encode(5, 0));
15797      return;
15798    }
15799  }
15800  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15801}
15802
15803void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15804  VIXL_ASSERT(AllowAssembler());
15805  CheckIT(al);
15806  Dt_op_2 encoded_dt(dt1);
15807  if (IsUsingT32()) {
15808    // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15809    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15810      EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
15811                 rd.Encode(22, 12) | rm.Encode(5, 0));
15812      AdvanceIT();
15813      return;
15814    }
15815  } else {
15816    // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15817    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15818      EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
15819              rd.Encode(22, 12) | rm.Encode(5, 0));
15820      return;
15821    }
15822  }
15823  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15824}
15825
15826void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15827  VIXL_ASSERT(AllowAssembler());
15828  CheckIT(al);
15829  Dt_op_2 encoded_dt(dt1);
15830  if (IsUsingT32()) {
15831    // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15832    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15833      EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
15834                 rd.Encode(22, 12) | rm.Encode(5, 0));
15835      AdvanceIT();
15836      return;
15837    }
15838  } else {
15839    // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15840    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15841      EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
15842              rd.Encode(22, 12) | rm.Encode(5, 0));
15843      return;
15844    }
15845  }
15846  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15847}
15848
15849void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15850  VIXL_ASSERT(AllowAssembler());
15851  CheckIT(al);
15852  Dt_op_3 encoded_dt(dt1);
15853  if (IsUsingT32()) {
15854    // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15855    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15856      EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) |
15857                 rd.Encode(22, 12) | rm.Encode(5, 0));
15858      AdvanceIT();
15859      return;
15860    }
15861  } else {
15862    // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15863    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15864      EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) |
15865              rd.Encode(22, 12) | rm.Encode(5, 0));
15866      return;
15867    }
15868  }
15869  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15870}
15871
15872void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15873  VIXL_ASSERT(AllowAssembler());
15874  CheckIT(al);
15875  Dt_op_3 encoded_dt(dt1);
15876  if (IsUsingT32()) {
15877    // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15878    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15879      EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) |
15880                 rd.Encode(22, 12) | rm.Encode(5, 0));
15881      AdvanceIT();
15882      return;
15883    }
15884  } else {
15885    // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15886    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15887      EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) |
15888              rd.Encode(22, 12) | rm.Encode(5, 0));
15889      return;
15890    }
15891  }
15892  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15893}
15894
15895void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15896  VIXL_ASSERT(AllowAssembler());
15897  CheckIT(al);
15898  Dt_op_2 encoded_dt(dt1);
15899  if (IsUsingT32()) {
15900    // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15901    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15902      EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
15903                 rd.Encode(22, 12) | rm.Encode(5, 0));
15904      AdvanceIT();
15905      return;
15906    }
15907  } else {
15908    // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15909    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15910      EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
15911              rd.Encode(22, 12) | rm.Encode(5, 0));
15912      return;
15913    }
15914  }
15915  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15916}
15917
15918void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15919  VIXL_ASSERT(AllowAssembler());
15920  CheckIT(al);
15921  Dt_op_2 encoded_dt(dt1);
15922  if (IsUsingT32()) {
15923    // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15924    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15925      EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
15926                 rd.Encode(22, 12) | rm.Encode(5, 0));
15927      AdvanceIT();
15928      return;
15929    }
15930  } else {
15931    // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15932    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15933      EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
15934              rd.Encode(22, 12) | rm.Encode(5, 0));
15935      return;
15936    }
15937  }
15938  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15939}
15940
15941void Assembler::vcvtr(
15942    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15943  VIXL_ASSERT(AllowAssembler());
15944  CheckIT(cond);
15945  if (IsUsingT32()) {
15946    // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
15947    if (dt1.Is(U32) && dt2.Is(F32)) {
15948      EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15949      AdvanceIT();
15950      return;
15951    }
15952    // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
15953    if (dt1.Is(S32) && dt2.Is(F32)) {
15954      EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15955      AdvanceIT();
15956      return;
15957    }
15958  } else {
15959    // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
15960    if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
15961      EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15962              rm.Encode(5, 0));
15963      return;
15964    }
15965    // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
15966    if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
15967      EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15968              rm.Encode(5, 0));
15969      return;
15970    }
15971  }
15972  Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
15973}
15974
15975void Assembler::vcvtr(
15976    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15977  VIXL_ASSERT(AllowAssembler());
15978  CheckIT(cond);
15979  if (IsUsingT32()) {
15980    // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
15981    if (dt1.Is(U32) && dt2.Is(F64)) {
15982      EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15983      AdvanceIT();
15984      return;
15985    }
15986    // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
15987    if (dt1.Is(S32) && dt2.Is(F64)) {
15988      EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15989      AdvanceIT();
15990      return;
15991    }
15992  } else {
15993    // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
15994    if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
15995      EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15996              rm.Encode(5, 0));
15997      return;
15998    }
15999    // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
16000    if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
16001      EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16002              rm.Encode(5, 0));
16003      return;
16004    }
16005  }
16006  Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
16007}
16008
16009void Assembler::vcvtt(
16010    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16011  VIXL_ASSERT(AllowAssembler());
16012  CheckIT(cond);
16013  if (IsUsingT32()) {
16014    // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
16015    if (dt1.Is(F32) && dt2.Is(F16)) {
16016      EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16017      AdvanceIT();
16018      return;
16019    }
16020    // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
16021    if (dt1.Is(F16) && dt2.Is(F32)) {
16022      EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16023      AdvanceIT();
16024      return;
16025    }
16026  } else {
16027    // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
16028    if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
16029      EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16030              rm.Encode(5, 0));
16031      return;
16032    }
16033    // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
16034    if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
16035      EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16036              rm.Encode(5, 0));
16037      return;
16038    }
16039  }
16040  Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
16041}
16042
16043void Assembler::vcvtt(
16044    Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
16045  VIXL_ASSERT(AllowAssembler());
16046  CheckIT(cond);
16047  if (IsUsingT32()) {
16048    // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
16049    if (dt1.Is(F64) && dt2.Is(F16)) {
16050      EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16051      AdvanceIT();
16052      return;
16053    }
16054  } else {
16055    // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
16056    if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
16057      EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16058              rm.Encode(5, 0));
16059      return;
16060    }
16061  }
16062  Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
16063}
16064
16065void Assembler::vcvtt(
16066    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16067  VIXL_ASSERT(AllowAssembler());
16068  CheckIT(cond);
16069  if (IsUsingT32()) {
16070    // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
16071    if (dt1.Is(F16) && dt2.Is(F64)) {
16072      EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16073      AdvanceIT();
16074      return;
16075    }
16076  } else {
16077    // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
16078    if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
16079      EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16080              rm.Encode(5, 0));
16081      return;
16082    }
16083  }
16084  Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
16085}
16086
16087void Assembler::vdiv(
16088    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16089  VIXL_ASSERT(AllowAssembler());
16090  CheckIT(cond);
16091  if (IsUsingT32()) {
16092    // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
16093    if (dt.Is(F32)) {
16094      EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16095                 rm.Encode(5, 0));
16096      AdvanceIT();
16097      return;
16098    }
16099  } else {
16100    // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
16101    if (dt.Is(F32) && cond.IsNotNever()) {
16102      EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16103              rn.Encode(7, 16) | rm.Encode(5, 0));
16104      return;
16105    }
16106  }
16107  Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
16108}
16109
16110void Assembler::vdiv(
16111    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16112  VIXL_ASSERT(AllowAssembler());
16113  CheckIT(cond);
16114  if (IsUsingT32()) {
16115    // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
16116    if (dt.Is(F64)) {
16117      EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16118                 rm.Encode(5, 0));
16119      AdvanceIT();
16120      return;
16121    }
16122  } else {
16123    // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
16124    if (dt.Is(F64) && cond.IsNotNever()) {
16125      EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16126              rn.Encode(7, 16) | rm.Encode(5, 0));
16127      return;
16128    }
16129  }
16130  Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
16131}
16132
16133void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) {
16134  VIXL_ASSERT(AllowAssembler());
16135  CheckIT(cond);
16136  Dt_B_E_1 encoded_dt(dt);
16137  if (IsUsingT32()) {
16138    // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1
16139    if (encoded_dt.IsValid()) {
16140      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16141        EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16142                   ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16143                   rd.Encode(7, 16) | (rt.GetCode() << 12));
16144        AdvanceIT();
16145        return;
16146      }
16147    }
16148  } else {
16149    // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1
16150    if (encoded_dt.IsValid() && cond.IsNotNever()) {
16151      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16152        EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) |
16153                ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16154                ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16155                rd.Encode(7, 16) | (rt.GetCode() << 12));
16156        return;
16157      }
16158    }
16159  }
16160  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
16161}
16162
16163void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) {
16164  VIXL_ASSERT(AllowAssembler());
16165  CheckIT(cond);
16166  Dt_B_E_1 encoded_dt(dt);
16167  if (IsUsingT32()) {
16168    // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1
16169    if (encoded_dt.IsValid()) {
16170      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16171        EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16172                   ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16173                   rd.Encode(7, 16) | (rt.GetCode() << 12));
16174        AdvanceIT();
16175        return;
16176      }
16177    }
16178  } else {
16179    // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1
16180    if (encoded_dt.IsValid() && cond.IsNotNever()) {
16181      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16182        EmitA32(0x0e800b10U | (cond.GetCondition() << 28) |
16183                ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16184                ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16185                rd.Encode(7, 16) | (rt.GetCode() << 12));
16186        return;
16187      }
16188    }
16189  }
16190  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
16191}
16192
16193void Assembler::vdup(Condition cond,
16194                     DataType dt,
16195                     DRegister rd,
16196                     DRegisterLane rm) {
16197  VIXL_ASSERT(AllowAssembler());
16198  CheckIT(cond);
16199  Dt_imm4_1 encoded_dt(dt, rm);
16200  if (IsUsingT32()) {
16201    // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1
16202    if (encoded_dt.IsValid()) {
16203      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16204        EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) |
16205                   rd.Encode(22, 12) | rm.Encode(5, 0));
16206        AdvanceIT();
16207        return;
16208      }
16209    }
16210  } else {
16211    // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1
16212    if (encoded_dt.IsValid()) {
16213      if (cond.Is(al)) {
16214        EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) |
16215                rd.Encode(22, 12) | rm.Encode(5, 0));
16216        return;
16217      }
16218    }
16219  }
16220  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
16221}
16222
16223void Assembler::vdup(Condition cond,
16224                     DataType dt,
16225                     QRegister rd,
16226                     DRegisterLane rm) {
16227  VIXL_ASSERT(AllowAssembler());
16228  CheckIT(cond);
16229  Dt_imm4_1 encoded_dt(dt, rm);
16230  if (IsUsingT32()) {
16231    // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1
16232    if (encoded_dt.IsValid()) {
16233      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16234        EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) |
16235                   rd.Encode(22, 12) | rm.Encode(5, 0));
16236        AdvanceIT();
16237        return;
16238      }
16239    }
16240  } else {
16241    // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1
16242    if (encoded_dt.IsValid()) {
16243      if (cond.Is(al)) {
16244        EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) |
16245                rd.Encode(22, 12) | rm.Encode(5, 0));
16246        return;
16247      }
16248    }
16249  }
16250  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
16251}
16252
16253void Assembler::veor(
16254    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16255  VIXL_ASSERT(AllowAssembler());
16256  CheckIT(cond);
16257  USE(dt);
16258  if (IsUsingT32()) {
16259    // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
16260    if (cond.Is(al) || AllowStronglyDiscouraged()) {
16261      EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16262                 rm.Encode(5, 0));
16263      AdvanceIT();
16264      return;
16265    }
16266  } else {
16267    // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
16268    if (cond.Is(al)) {
16269      EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16270              rm.Encode(5, 0));
16271      return;
16272    }
16273  }
16274  Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
16275}
16276
16277void Assembler::veor(
16278    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16279  VIXL_ASSERT(AllowAssembler());
16280  CheckIT(cond);
16281  USE(dt);
16282  if (IsUsingT32()) {
16283    // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
16284    if (cond.Is(al) || AllowStronglyDiscouraged()) {
16285      EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16286                 rm.Encode(5, 0));
16287      AdvanceIT();
16288      return;
16289    }
16290  } else {
16291    // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
16292    if (cond.Is(al)) {
16293      EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16294              rm.Encode(5, 0));
16295      return;
16296    }
16297  }
16298  Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
16299}
16300
16301void Assembler::vext(Condition cond,
16302                     DataType dt,
16303                     DRegister rd,
16304                     DRegister rn,
16305                     DRegister rm,
16306                     const DOperand& operand) {
16307  VIXL_ASSERT(AllowAssembler());
16308  CheckIT(cond);
16309  if (operand.IsImmediate()) {
16310    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
16311      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
16312      if (IsUsingT32()) {
16313        // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
16314        if (dt.Is(Untyped8) && (imm <= 7)) {
16315          if (cond.Is(al) || AllowStronglyDiscouraged()) {
16316            EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16317                       rm.Encode(5, 0) | (imm << 8));
16318            AdvanceIT();
16319            return;
16320          }
16321        }
16322        // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
16323        if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
16324            (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16325          if (cond.Is(al) || AllowStronglyDiscouraged()) {
16326            uint32_t imm4 = imm / dt.GetSize();
16327            EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16328                       rm.Encode(5, 0) | (imm4 << 8));
16329            AdvanceIT();
16330            return;
16331          }
16332        }
16333      } else {
16334        // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
16335        if (dt.Is(Untyped8) && (imm <= 7)) {
16336          if (cond.Is(al)) {
16337            EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16338                    rm.Encode(5, 0) | (imm << 8));
16339            return;
16340          }
16341        }
16342        // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
16343        if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
16344            (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16345          if (cond.Is(al)) {
16346            uint32_t imm4 = imm / dt.GetSize();
16347            EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16348                    rm.Encode(5, 0) | (imm4 << 8));
16349            return;
16350          }
16351        }
16352      }
16353    }
16354  }
16355  Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
16356}
16357
16358void Assembler::vext(Condition cond,
16359                     DataType dt,
16360                     QRegister rd,
16361                     QRegister rn,
16362                     QRegister rm,
16363                     const QOperand& operand) {
16364  VIXL_ASSERT(AllowAssembler());
16365  CheckIT(cond);
16366  if (operand.IsImmediate()) {
16367    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
16368      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
16369      if (IsUsingT32()) {
16370        // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
16371        if (dt.Is(Untyped8) && (imm <= 15)) {
16372          if (cond.Is(al) || AllowStronglyDiscouraged()) {
16373            EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16374                       rm.Encode(5, 0) | (imm << 8));
16375            AdvanceIT();
16376            return;
16377          }
16378        }
16379        // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
16380        if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
16381            (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16382          if (cond.Is(al) || AllowStronglyDiscouraged()) {
16383            uint32_t imm4 = imm / dt.GetSize();
16384            EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16385                       rm.Encode(5, 0) | (imm4 << 8));
16386            AdvanceIT();
16387            return;
16388          }
16389        }
16390      } else {
16391        // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
16392        if (dt.Is(Untyped8) && (imm <= 15)) {
16393          if (cond.Is(al)) {
16394            EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16395                    rm.Encode(5, 0) | (imm << 8));
16396            return;
16397          }
16398        }
16399        // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
16400        if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
16401            (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16402          if (cond.Is(al)) {
16403            uint32_t imm4 = imm / dt.GetSize();
16404            EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16405                    rm.Encode(5, 0) | (imm4 << 8));
16406            return;
16407          }
16408        }
16409      }
16410    }
16411  }
16412  Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
16413}
16414
16415void Assembler::vfma(
16416    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16417  VIXL_ASSERT(AllowAssembler());
16418  CheckIT(cond);
16419  if (IsUsingT32()) {
16420    // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
16421    if (dt.Is(F32)) {
16422      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16423        EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16424                   rm.Encode(5, 0));
16425        AdvanceIT();
16426        return;
16427      }
16428    }
16429    // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
16430    if (dt.Is(F64)) {
16431      EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16432                 rm.Encode(5, 0));
16433      AdvanceIT();
16434      return;
16435    }
16436  } else {
16437    // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
16438    if (dt.Is(F32)) {
16439      if (cond.Is(al)) {
16440        EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16441                rm.Encode(5, 0));
16442        return;
16443      }
16444    }
16445    // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
16446    if (dt.Is(F64) && cond.IsNotNever()) {
16447      EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16448              rn.Encode(7, 16) | rm.Encode(5, 0));
16449      return;
16450    }
16451  }
16452  Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16453}
16454
16455void Assembler::vfma(
16456    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16457  VIXL_ASSERT(AllowAssembler());
16458  CheckIT(cond);
16459  if (IsUsingT32()) {
16460    // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
16461    if (dt.Is(F32)) {
16462      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16463        EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16464                   rm.Encode(5, 0));
16465        AdvanceIT();
16466        return;
16467      }
16468    }
16469  } else {
16470    // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
16471    if (dt.Is(F32)) {
16472      if (cond.Is(al)) {
16473        EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16474                rm.Encode(5, 0));
16475        return;
16476      }
16477    }
16478  }
16479  Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16480}
16481
16482void Assembler::vfma(
16483    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16484  VIXL_ASSERT(AllowAssembler());
16485  CheckIT(cond);
16486  if (IsUsingT32()) {
16487    // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
16488    if (dt.Is(F32)) {
16489      EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16490                 rm.Encode(5, 0));
16491      AdvanceIT();
16492      return;
16493    }
16494  } else {
16495    // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
16496    if (dt.Is(F32) && cond.IsNotNever()) {
16497      EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16498              rn.Encode(7, 16) | rm.Encode(5, 0));
16499      return;
16500    }
16501  }
16502  Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16503}
16504
16505void Assembler::vfms(
16506    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16507  VIXL_ASSERT(AllowAssembler());
16508  CheckIT(cond);
16509  if (IsUsingT32()) {
16510    // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
16511    if (dt.Is(F32)) {
16512      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16513        EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16514                   rm.Encode(5, 0));
16515        AdvanceIT();
16516        return;
16517      }
16518    }
16519    // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
16520    if (dt.Is(F64)) {
16521      EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16522                 rm.Encode(5, 0));
16523      AdvanceIT();
16524      return;
16525    }
16526  } else {
16527    // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
16528    if (dt.Is(F32)) {
16529      if (cond.Is(al)) {
16530        EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16531                rm.Encode(5, 0));
16532        return;
16533      }
16534    }
16535    // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
16536    if (dt.Is(F64) && cond.IsNotNever()) {
16537      EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16538              rn.Encode(7, 16) | rm.Encode(5, 0));
16539      return;
16540    }
16541  }
16542  Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16543}
16544
16545void Assembler::vfms(
16546    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16547  VIXL_ASSERT(AllowAssembler());
16548  CheckIT(cond);
16549  if (IsUsingT32()) {
16550    // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
16551    if (dt.Is(F32)) {
16552      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16553        EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16554                   rm.Encode(5, 0));
16555        AdvanceIT();
16556        return;
16557      }
16558    }
16559  } else {
16560    // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
16561    if (dt.Is(F32)) {
16562      if (cond.Is(al)) {
16563        EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16564                rm.Encode(5, 0));
16565        return;
16566      }
16567    }
16568  }
16569  Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16570}
16571
16572void Assembler::vfms(
16573    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16574  VIXL_ASSERT(AllowAssembler());
16575  CheckIT(cond);
16576  if (IsUsingT32()) {
16577    // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
16578    if (dt.Is(F32)) {
16579      EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16580                 rm.Encode(5, 0));
16581      AdvanceIT();
16582      return;
16583    }
16584  } else {
16585    // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
16586    if (dt.Is(F32) && cond.IsNotNever()) {
16587      EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16588              rn.Encode(7, 16) | rm.Encode(5, 0));
16589      return;
16590    }
16591  }
16592  Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16593}
16594
16595void Assembler::vfnma(
16596    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16597  VIXL_ASSERT(AllowAssembler());
16598  CheckIT(cond);
16599  if (IsUsingT32()) {
16600    // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
16601    if (dt.Is(F32)) {
16602      EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16603                 rm.Encode(5, 0));
16604      AdvanceIT();
16605      return;
16606    }
16607  } else {
16608    // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
16609    if (dt.Is(F32) && cond.IsNotNever()) {
16610      EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16611              rn.Encode(7, 16) | rm.Encode(5, 0));
16612      return;
16613    }
16614  }
16615  Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
16616}
16617
16618void Assembler::vfnma(
16619    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16620  VIXL_ASSERT(AllowAssembler());
16621  CheckIT(cond);
16622  if (IsUsingT32()) {
16623    // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
16624    if (dt.Is(F64)) {
16625      EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16626                 rm.Encode(5, 0));
16627      AdvanceIT();
16628      return;
16629    }
16630  } else {
16631    // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
16632    if (dt.Is(F64) && cond.IsNotNever()) {
16633      EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16634              rn.Encode(7, 16) | rm.Encode(5, 0));
16635      return;
16636    }
16637  }
16638  Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
16639}
16640
16641void Assembler::vfnms(
16642    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16643  VIXL_ASSERT(AllowAssembler());
16644  CheckIT(cond);
16645  if (IsUsingT32()) {
16646    // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
16647    if (dt.Is(F32)) {
16648      EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16649                 rm.Encode(5, 0));
16650      AdvanceIT();
16651      return;
16652    }
16653  } else {
16654    // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
16655    if (dt.Is(F32) && cond.IsNotNever()) {
16656      EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16657              rn.Encode(7, 16) | rm.Encode(5, 0));
16658      return;
16659    }
16660  }
16661  Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
16662}
16663
16664void Assembler::vfnms(
16665    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16666  VIXL_ASSERT(AllowAssembler());
16667  CheckIT(cond);
16668  if (IsUsingT32()) {
16669    // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
16670    if (dt.Is(F64)) {
16671      EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16672                 rm.Encode(5, 0));
16673      AdvanceIT();
16674      return;
16675    }
16676  } else {
16677    // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
16678    if (dt.Is(F64) && cond.IsNotNever()) {
16679      EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16680              rn.Encode(7, 16) | rm.Encode(5, 0));
16681      return;
16682    }
16683  }
16684  Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
16685}
16686
16687void Assembler::vhadd(
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    // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
16694    if (encoded_dt.IsValid()) {
16695      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16696        EmitT32_32(0xef000000U | ((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    // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
16705    if (encoded_dt.IsValid()) {
16706      if (cond.Is(al)) {
16707        EmitA32(0xf2000000U | ((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(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
16715}
16716
16717void Assembler::vhadd(
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    // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
16724    if (encoded_dt.IsValid()) {
16725      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16726        EmitT32_32(0xef000040U | ((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    // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
16735    if (encoded_dt.IsValid()) {
16736      if (cond.Is(al)) {
16737        EmitA32(0xf2000040U | ((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(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
16745}
16746
16747void Assembler::vhsub(
16748    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16749  VIXL_ASSERT(AllowAssembler());
16750  CheckIT(cond);
16751  Dt_U_size_1 encoded_dt(dt);
16752  if (IsUsingT32()) {
16753    // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
16754    if (encoded_dt.IsValid()) {
16755      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16756        EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16757                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16758                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16759        AdvanceIT();
16760        return;
16761      }
16762    }
16763  } else {
16764    // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
16765    if (encoded_dt.IsValid()) {
16766      if (cond.Is(al)) {
16767        EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16768                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16769                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16770        return;
16771      }
16772    }
16773  }
16774  Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
16775}
16776
16777void Assembler::vhsub(
16778    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16779  VIXL_ASSERT(AllowAssembler());
16780  CheckIT(cond);
16781  Dt_U_size_1 encoded_dt(dt);
16782  if (IsUsingT32()) {
16783    // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
16784    if (encoded_dt.IsValid()) {
16785      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16786        EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16787                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16788                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16789        AdvanceIT();
16790        return;
16791      }
16792    }
16793  } else {
16794    // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
16795    if (encoded_dt.IsValid()) {
16796      if (cond.Is(al)) {
16797        EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16798                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16799                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16800        return;
16801      }
16802    }
16803  }
16804  Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
16805}
16806
16807void Assembler::vld1(Condition cond,
16808                     DataType dt,
16809                     const NeonRegisterList& nreglist,
16810                     const AlignedMemOperand& operand) {
16811  VIXL_ASSERT(AllowAssembler());
16812  CheckIT(cond);
16813  if (operand.IsImmediateZero()) {
16814    Register rn = operand.GetBaseRegister();
16815    Alignment align = operand.GetAlignment();
16816    Dt_size_6 encoded_dt(dt);
16817    Dt_size_7 encoded_dt_2(dt);
16818    Align_align_1 encoded_align_1(align, nreglist);
16819    Align_a_1 encoded_align_2(align, dt);
16820    Align_index_align_1 encoded_align_3(align, nreglist, dt);
16821    if (IsUsingT32()) {
16822      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16823      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16824          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16825          operand.IsOffset() && encoded_align_1.IsValid() &&
16826          (!rn.IsPC() || AllowUnpredictable())) {
16827        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16828          const DRegister& first = nreglist.GetFirstDRegister();
16829          uint32_t len_encoding;
16830          switch (nreglist.GetLength()) {
16831            default:
16832              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16833            case 1:
16834              len_encoding = 0x7;
16835              break;
16836            case 2:
16837              len_encoding = 0xa;
16838              break;
16839            case 3:
16840              len_encoding = 0x6;
16841              break;
16842            case 4:
16843              len_encoding = 0x2;
16844              break;
16845          }
16846          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
16847                     (encoded_align_1.GetEncodingValue() << 4) |
16848                     first.Encode(22, 12) | (len_encoding << 8) |
16849                     (rn.GetCode() << 16));
16850          AdvanceIT();
16851          return;
16852        }
16853      }
16854      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16855      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16856          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16857          operand.IsPostIndex() && encoded_align_1.IsValid() &&
16858          (!rn.IsPC() || AllowUnpredictable())) {
16859        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16860          const DRegister& first = nreglist.GetFirstDRegister();
16861          uint32_t len_encoding;
16862          switch (nreglist.GetLength()) {
16863            default:
16864              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16865            case 1:
16866              len_encoding = 0x7;
16867              break;
16868            case 2:
16869              len_encoding = 0xa;
16870              break;
16871            case 3:
16872              len_encoding = 0x6;
16873              break;
16874            case 4:
16875              len_encoding = 0x2;
16876              break;
16877          }
16878          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
16879                     (encoded_align_1.GetEncodingValue() << 4) |
16880                     first.Encode(22, 12) | (len_encoding << 8) |
16881                     (rn.GetCode() << 16));
16882          AdvanceIT();
16883          return;
16884        }
16885      }
16886      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16887      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16888          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16889          operand.IsOffset() && encoded_align_2.IsValid() &&
16890          (!rn.IsPC() || AllowUnpredictable())) {
16891        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16892          const DRegister& first = nreglist.GetFirstDRegister();
16893          uint32_t len_encoding = nreglist.GetLength() - 1;
16894          EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
16895                     (encoded_align_2.GetEncodingValue() << 4) |
16896                     first.Encode(22, 12) | (len_encoding << 5) |
16897                     (rn.GetCode() << 16));
16898          AdvanceIT();
16899          return;
16900        }
16901      }
16902      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16903      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16904          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16905          operand.IsPostIndex() && encoded_align_2.IsValid() &&
16906          (!rn.IsPC() || AllowUnpredictable())) {
16907        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16908          const DRegister& first = nreglist.GetFirstDRegister();
16909          uint32_t len_encoding = nreglist.GetLength() - 1;
16910          EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
16911                     (encoded_align_2.GetEncodingValue() << 4) |
16912                     first.Encode(22, 12) | (len_encoding << 5) |
16913                     (rn.GetCode() << 16));
16914          AdvanceIT();
16915          return;
16916        }
16917      }
16918      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16919      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16920          (nreglist.GetLength() == 1) && operand.IsOffset() &&
16921          encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
16922        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16923          const DRegister& first = nreglist.GetFirstDRegister();
16924          EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
16925                     (encoded_align_3.GetEncodingValue() << 4) |
16926                     first.Encode(22, 12) | (rn.GetCode() << 16));
16927          AdvanceIT();
16928          return;
16929        }
16930      }
16931      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16932      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16933          (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
16934          encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
16935        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16936          const DRegister& first = nreglist.GetFirstDRegister();
16937          EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
16938                     (encoded_align_3.GetEncodingValue() << 4) |
16939                     first.Encode(22, 12) | (rn.GetCode() << 16));
16940          AdvanceIT();
16941          return;
16942        }
16943      }
16944    } else {
16945      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
16946      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16947          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16948          operand.IsOffset() && encoded_align_1.IsValid() &&
16949          (!rn.IsPC() || AllowUnpredictable())) {
16950        if (cond.Is(al)) {
16951          const DRegister& first = nreglist.GetFirstDRegister();
16952          uint32_t len_encoding;
16953          switch (nreglist.GetLength()) {
16954            default:
16955              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16956            case 1:
16957              len_encoding = 0x7;
16958              break;
16959            case 2:
16960              len_encoding = 0xa;
16961              break;
16962            case 3:
16963              len_encoding = 0x6;
16964              break;
16965            case 4:
16966              len_encoding = 0x2;
16967              break;
16968          }
16969          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
16970                  (encoded_align_1.GetEncodingValue() << 4) |
16971                  first.Encode(22, 12) | (len_encoding << 8) |
16972                  (rn.GetCode() << 16));
16973          return;
16974        }
16975      }
16976      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
16977      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16978          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16979          operand.IsPostIndex() && encoded_align_1.IsValid() &&
16980          (!rn.IsPC() || AllowUnpredictable())) {
16981        if (cond.Is(al)) {
16982          const DRegister& first = nreglist.GetFirstDRegister();
16983          uint32_t len_encoding;
16984          switch (nreglist.GetLength()) {
16985            default:
16986              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16987            case 1:
16988              len_encoding = 0x7;
16989              break;
16990            case 2:
16991              len_encoding = 0xa;
16992              break;
16993            case 3:
16994              len_encoding = 0x6;
16995              break;
16996            case 4:
16997              len_encoding = 0x2;
16998              break;
16999          }
17000          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17001                  (encoded_align_1.GetEncodingValue() << 4) |
17002                  first.Encode(22, 12) | (len_encoding << 8) |
17003                  (rn.GetCode() << 16));
17004          return;
17005        }
17006      }
17007      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17008      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17009          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
17010          operand.IsOffset() && encoded_align_2.IsValid() &&
17011          (!rn.IsPC() || AllowUnpredictable())) {
17012        if (cond.Is(al)) {
17013          const DRegister& first = nreglist.GetFirstDRegister();
17014          uint32_t len_encoding = nreglist.GetLength() - 1;
17015          EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
17016                  (encoded_align_2.GetEncodingValue() << 4) |
17017                  first.Encode(22, 12) | (len_encoding << 5) |
17018                  (rn.GetCode() << 16));
17019          return;
17020        }
17021      }
17022      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17023      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17024          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
17025          operand.IsPostIndex() && encoded_align_2.IsValid() &&
17026          (!rn.IsPC() || AllowUnpredictable())) {
17027        if (cond.Is(al)) {
17028          const DRegister& first = nreglist.GetFirstDRegister();
17029          uint32_t len_encoding = nreglist.GetLength() - 1;
17030          EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
17031                  (encoded_align_2.GetEncodingValue() << 4) |
17032                  first.Encode(22, 12) | (len_encoding << 5) |
17033                  (rn.GetCode() << 16));
17034          return;
17035        }
17036      }
17037      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17038      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
17039          (nreglist.GetLength() == 1) && operand.IsOffset() &&
17040          encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
17041        if (cond.Is(al)) {
17042          const DRegister& first = nreglist.GetFirstDRegister();
17043          EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
17044                  (encoded_align_3.GetEncodingValue() << 4) |
17045                  first.Encode(22, 12) | (rn.GetCode() << 16));
17046          return;
17047        }
17048      }
17049      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17050      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
17051          (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
17052          encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
17053        if (cond.Is(al)) {
17054          const DRegister& first = nreglist.GetFirstDRegister();
17055          EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
17056                  (encoded_align_3.GetEncodingValue() << 4) |
17057                  first.Encode(22, 12) | (rn.GetCode() << 16));
17058          return;
17059        }
17060      }
17061    }
17062  }
17063  if (operand.IsPlainRegister()) {
17064    Register rn = operand.GetBaseRegister();
17065    Alignment align = operand.GetAlignment();
17066    Register rm = operand.GetOffsetRegister();
17067    Dt_size_6 encoded_dt(dt);
17068    Dt_size_7 encoded_dt_2(dt);
17069    Align_align_1 encoded_align_1(align, nreglist);
17070    Align_a_1 encoded_align_2(align, dt);
17071    Align_index_align_1 encoded_align_3(align, nreglist, dt);
17072    if (IsUsingT32()) {
17073      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17074      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17075          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
17076          !rm.IsPC() && !rm.IsSP()) {
17077        if (cond.Is(al) || AllowStronglyDiscouraged()) {
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          EmitT32_32(0xf9200000U | (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          AdvanceIT();
17101          return;
17102        }
17103      }
17104      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17105      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17106          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
17107          !rm.IsPC() && !rm.IsSP()) {
17108        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17109          const DRegister& first = nreglist.GetFirstDRegister();
17110          uint32_t len_encoding = nreglist.GetLength() - 1;
17111          EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
17112                     (encoded_align_2.GetEncodingValue() << 4) |
17113                     first.Encode(22, 12) | (len_encoding << 5) |
17114                     (rn.GetCode() << 16) | rm.GetCode());
17115          AdvanceIT();
17116          return;
17117        }
17118      }
17119      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17120      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
17121          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
17122        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17123          const DRegister& first = nreglist.GetFirstDRegister();
17124          EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
17125                     (encoded_align_3.GetEncodingValue() << 4) |
17126                     first.Encode(22, 12) | (rn.GetCode() << 16) |
17127                     rm.GetCode());
17128          AdvanceIT();
17129          return;
17130        }
17131      }
17132    } else {
17133      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17134      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17135          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
17136          !rm.IsPC() && !rm.IsSP()) {
17137        if (cond.Is(al)) {
17138          const DRegister& first = nreglist.GetFirstDRegister();
17139          uint32_t len_encoding;
17140          switch (nreglist.GetLength()) {
17141            default:
17142              VIXL_UNREACHABLE_OR_FALLTHROUGH();
17143            case 1:
17144              len_encoding = 0x7;
17145              break;
17146            case 2:
17147              len_encoding = 0xa;
17148              break;
17149            case 3:
17150              len_encoding = 0x6;
17151              break;
17152            case 4:
17153              len_encoding = 0x2;
17154              break;
17155          }
17156          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17157                  (encoded_align_1.GetEncodingValue() << 4) |
17158                  first.Encode(22, 12) | (len_encoding << 8) |
17159                  (rn.GetCode() << 16) | rm.GetCode());
17160          return;
17161        }
17162      }
17163      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17164      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17165          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
17166          !rm.IsPC() && !rm.IsSP()) {
17167        if (cond.Is(al)) {
17168          const DRegister& first = nreglist.GetFirstDRegister();
17169          uint32_t len_encoding = nreglist.GetLength() - 1;
17170          EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
17171                  (encoded_align_2.GetEncodingValue() << 4) |
17172                  first.Encode(22, 12) | (len_encoding << 5) |
17173                  (rn.GetCode() << 16) | rm.GetCode());
17174          return;
17175        }
17176      }
17177      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17178      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
17179          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
17180        if (cond.Is(al)) {
17181          const DRegister& first = nreglist.GetFirstDRegister();
17182          EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
17183                  (encoded_align_3.GetEncodingValue() << 4) |
17184                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17185          return;
17186        }
17187      }
17188    }
17189  }
17190  Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand);
17191}
17192
17193void Assembler::vld2(Condition cond,
17194                     DataType dt,
17195                     const NeonRegisterList& nreglist,
17196                     const AlignedMemOperand& operand) {
17197  VIXL_ASSERT(AllowAssembler());
17198  CheckIT(cond);
17199  if (operand.IsImmediateZero()) {
17200    Register rn = operand.GetBaseRegister();
17201    Alignment align = operand.GetAlignment();
17202    Dt_size_7 encoded_dt(dt);
17203    Align_align_2 encoded_align_1(align, nreglist);
17204    Align_a_2 encoded_align_2(align, dt);
17205    Align_index_align_2 encoded_align_3(align, nreglist, dt);
17206    if (IsUsingT32()) {
17207      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17208      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17209          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17210           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17211           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17212          operand.IsOffset() && encoded_align_1.IsValid() &&
17213          (!rn.IsPC() || AllowUnpredictable())) {
17214        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17215          const DRegister& first = nreglist.GetFirstDRegister();
17216          uint32_t len_encoding;
17217          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17218            len_encoding = 0x8;
17219          }
17220          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17221            len_encoding = 0x9;
17222          }
17223          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17224            len_encoding = 0x3;
17225          }
17226          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
17227                     (encoded_align_1.GetEncodingValue() << 4) |
17228                     first.Encode(22, 12) | (len_encoding << 8) |
17229                     (rn.GetCode() << 16));
17230          AdvanceIT();
17231          return;
17232        }
17233      }
17234      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17235      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17236          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17237           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17238           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17239          operand.IsPostIndex() && encoded_align_1.IsValid() &&
17240          (!rn.IsPC() || AllowUnpredictable())) {
17241        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17242          const DRegister& first = nreglist.GetFirstDRegister();
17243          uint32_t len_encoding;
17244          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17245            len_encoding = 0x8;
17246          }
17247          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17248            len_encoding = 0x9;
17249          }
17250          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17251            len_encoding = 0x3;
17252          }
17253          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
17254                     (encoded_align_1.GetEncodingValue() << 4) |
17255                     first.Encode(22, 12) | (len_encoding << 8) |
17256                     (rn.GetCode() << 16));
17257          AdvanceIT();
17258          return;
17259        }
17260      }
17261      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17262      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17263          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17264           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17265          operand.IsOffset() && encoded_align_2.IsValid() &&
17266          (!rn.IsPC() || AllowUnpredictable())) {
17267        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17268          const DRegister& first = nreglist.GetFirstDRegister();
17269          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17270          EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
17271                     (encoded_align_2.GetEncodingValue() << 4) |
17272                     first.Encode(22, 12) | (len_encoding << 5) |
17273                     (rn.GetCode() << 16));
17274          AdvanceIT();
17275          return;
17276        }
17277      }
17278      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17279      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17280          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17281           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17282          operand.IsPostIndex() && encoded_align_2.IsValid() &&
17283          (!rn.IsPC() || AllowUnpredictable())) {
17284        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17285          const DRegister& first = nreglist.GetFirstDRegister();
17286          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17287          EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
17288                     (encoded_align_2.GetEncodingValue() << 4) |
17289                     first.Encode(22, 12) | (len_encoding << 5) |
17290                     (rn.GetCode() << 16));
17291          AdvanceIT();
17292          return;
17293        }
17294      }
17295      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17296      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17297          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17298           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17299          operand.IsOffset() && encoded_align_3.IsValid() &&
17300          (!rn.IsPC() || AllowUnpredictable())) {
17301        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17302          const DRegister& first = nreglist.GetFirstDRegister();
17303          EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) |
17304                     (encoded_align_3.GetEncodingValue() << 4) |
17305                     first.Encode(22, 12) | (rn.GetCode() << 16));
17306          AdvanceIT();
17307          return;
17308        }
17309      }
17310      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17311      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17312          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17313           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17314          operand.IsPostIndex() && encoded_align_3.IsValid() &&
17315          (!rn.IsPC() || AllowUnpredictable())) {
17316        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17317          const DRegister& first = nreglist.GetFirstDRegister();
17318          EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) |
17319                     (encoded_align_3.GetEncodingValue() << 4) |
17320                     first.Encode(22, 12) | (rn.GetCode() << 16));
17321          AdvanceIT();
17322          return;
17323        }
17324      }
17325    } else {
17326      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17327      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17328          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17329           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17330           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17331          operand.IsOffset() && encoded_align_1.IsValid() &&
17332          (!rn.IsPC() || AllowUnpredictable())) {
17333        if (cond.Is(al)) {
17334          const DRegister& first = nreglist.GetFirstDRegister();
17335          uint32_t len_encoding;
17336          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17337            len_encoding = 0x8;
17338          }
17339          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17340            len_encoding = 0x9;
17341          }
17342          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17343            len_encoding = 0x3;
17344          }
17345          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
17346                  (encoded_align_1.GetEncodingValue() << 4) |
17347                  first.Encode(22, 12) | (len_encoding << 8) |
17348                  (rn.GetCode() << 16));
17349          return;
17350        }
17351      }
17352      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17353      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17354          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17355           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17356           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17357          operand.IsPostIndex() && encoded_align_1.IsValid() &&
17358          (!rn.IsPC() || AllowUnpredictable())) {
17359        if (cond.Is(al)) {
17360          const DRegister& first = nreglist.GetFirstDRegister();
17361          uint32_t len_encoding;
17362          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17363            len_encoding = 0x8;
17364          }
17365          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17366            len_encoding = 0x9;
17367          }
17368          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17369            len_encoding = 0x3;
17370          }
17371          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17372                  (encoded_align_1.GetEncodingValue() << 4) |
17373                  first.Encode(22, 12) | (len_encoding << 8) |
17374                  (rn.GetCode() << 16));
17375          return;
17376        }
17377      }
17378      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17379      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17380          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17381           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17382          operand.IsOffset() && encoded_align_2.IsValid() &&
17383          (!rn.IsPC() || AllowUnpredictable())) {
17384        if (cond.Is(al)) {
17385          const DRegister& first = nreglist.GetFirstDRegister();
17386          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17387          EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
17388                  (encoded_align_2.GetEncodingValue() << 4) |
17389                  first.Encode(22, 12) | (len_encoding << 5) |
17390                  (rn.GetCode() << 16));
17391          return;
17392        }
17393      }
17394      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17395      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17396          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17397           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17398          operand.IsPostIndex() && encoded_align_2.IsValid() &&
17399          (!rn.IsPC() || AllowUnpredictable())) {
17400        if (cond.Is(al)) {
17401          const DRegister& first = nreglist.GetFirstDRegister();
17402          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17403          EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
17404                  (encoded_align_2.GetEncodingValue() << 4) |
17405                  first.Encode(22, 12) | (len_encoding << 5) |
17406                  (rn.GetCode() << 16));
17407          return;
17408        }
17409      }
17410      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17411      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17412          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17413           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17414          operand.IsOffset() && encoded_align_3.IsValid() &&
17415          (!rn.IsPC() || AllowUnpredictable())) {
17416        if (cond.Is(al)) {
17417          const DRegister& first = nreglist.GetFirstDRegister();
17418          EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) |
17419                  (encoded_align_3.GetEncodingValue() << 4) |
17420                  first.Encode(22, 12) | (rn.GetCode() << 16));
17421          return;
17422        }
17423      }
17424      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17425      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17426          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17427           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17428          operand.IsPostIndex() && encoded_align_3.IsValid() &&
17429          (!rn.IsPC() || AllowUnpredictable())) {
17430        if (cond.Is(al)) {
17431          const DRegister& first = nreglist.GetFirstDRegister();
17432          EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) |
17433                  (encoded_align_3.GetEncodingValue() << 4) |
17434                  first.Encode(22, 12) | (rn.GetCode() << 16));
17435          return;
17436        }
17437      }
17438    }
17439  }
17440  if (operand.IsPlainRegister()) {
17441    Register rn = operand.GetBaseRegister();
17442    Alignment align = operand.GetAlignment();
17443    Register rm = operand.GetOffsetRegister();
17444    Dt_size_7 encoded_dt(dt);
17445    Align_align_2 encoded_align_1(align, nreglist);
17446    Align_a_2 encoded_align_2(align, dt);
17447    Align_index_align_2 encoded_align_3(align, nreglist, dt);
17448    if (IsUsingT32()) {
17449      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17450      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17451          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17452           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17453           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17454          !rm.IsPC() && !rm.IsSP()) {
17455        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17456          const DRegister& first = nreglist.GetFirstDRegister();
17457          uint32_t len_encoding;
17458          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17459            len_encoding = 0x8;
17460          }
17461          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17462            len_encoding = 0x9;
17463          }
17464          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17465            len_encoding = 0x3;
17466          }
17467          EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
17468                     (encoded_align_1.GetEncodingValue() << 4) |
17469                     first.Encode(22, 12) | (len_encoding << 8) |
17470                     (rn.GetCode() << 16) | rm.GetCode());
17471          AdvanceIT();
17472          return;
17473        }
17474      }
17475      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17476      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17477          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17478           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17479          !rm.IsPC() && !rm.IsSP()) {
17480        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17481          const DRegister& first = nreglist.GetFirstDRegister();
17482          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17483          EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) |
17484                     (encoded_align_2.GetEncodingValue() << 4) |
17485                     first.Encode(22, 12) | (len_encoding << 5) |
17486                     (rn.GetCode() << 16) | rm.GetCode());
17487          AdvanceIT();
17488          return;
17489        }
17490      }
17491      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17492      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17493          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17494           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17495          !rm.IsPC() && !rm.IsSP()) {
17496        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17497          const DRegister& first = nreglist.GetFirstDRegister();
17498          EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) |
17499                     (encoded_align_3.GetEncodingValue() << 4) |
17500                     first.Encode(22, 12) | (rn.GetCode() << 16) |
17501                     rm.GetCode());
17502          AdvanceIT();
17503          return;
17504        }
17505      }
17506    } else {
17507      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17508      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17509          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17510           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17511           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17512          !rm.IsPC() && !rm.IsSP()) {
17513        if (cond.Is(al)) {
17514          const DRegister& first = nreglist.GetFirstDRegister();
17515          uint32_t len_encoding;
17516          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17517            len_encoding = 0x8;
17518          }
17519          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17520            len_encoding = 0x9;
17521          }
17522          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17523            len_encoding = 0x3;
17524          }
17525          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17526                  (encoded_align_1.GetEncodingValue() << 4) |
17527                  first.Encode(22, 12) | (len_encoding << 8) |
17528                  (rn.GetCode() << 16) | rm.GetCode());
17529          return;
17530        }
17531      }
17532      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17533      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17534          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17535           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17536          !rm.IsPC() && !rm.IsSP()) {
17537        if (cond.Is(al)) {
17538          const DRegister& first = nreglist.GetFirstDRegister();
17539          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17540          EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) |
17541                  (encoded_align_2.GetEncodingValue() << 4) |
17542                  first.Encode(22, 12) | (len_encoding << 5) |
17543                  (rn.GetCode() << 16) | rm.GetCode());
17544          return;
17545        }
17546      }
17547      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17548      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17549          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17550           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17551          !rm.IsPC() && !rm.IsSP()) {
17552        if (cond.Is(al)) {
17553          const DRegister& first = nreglist.GetFirstDRegister();
17554          EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) |
17555                  (encoded_align_3.GetEncodingValue() << 4) |
17556                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17557          return;
17558        }
17559      }
17560    }
17561  }
17562  Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand);
17563}
17564
17565void Assembler::vld3(Condition cond,
17566                     DataType dt,
17567                     const NeonRegisterList& nreglist,
17568                     const AlignedMemOperand& operand) {
17569  VIXL_ASSERT(AllowAssembler());
17570  CheckIT(cond);
17571  if (operand.IsImmediateZero()) {
17572    Register rn = operand.GetBaseRegister();
17573    Alignment align = operand.GetAlignment();
17574    Dt_size_7 encoded_dt(dt);
17575    Align_align_3 encoded_align_1(align);
17576    if (IsUsingT32()) {
17577      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17578      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17579          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17580           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17581          operand.IsOffset() && encoded_align_1.IsValid() &&
17582          (!rn.IsPC() || AllowUnpredictable())) {
17583        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17584          const DRegister& first = nreglist.GetFirstDRegister();
17585          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17586          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
17587                     (encoded_align_1.GetEncodingValue() << 4) |
17588                     first.Encode(22, 12) | (len_encoding << 8) |
17589                     (rn.GetCode() << 16));
17590          AdvanceIT();
17591          return;
17592        }
17593      }
17594      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17595      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17596          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17597           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17598          operand.IsPostIndex() && encoded_align_1.IsValid() &&
17599          (!rn.IsPC() || AllowUnpredictable())) {
17600        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17601          const DRegister& first = nreglist.GetFirstDRegister();
17602          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17603          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
17604                     (encoded_align_1.GetEncodingValue() << 4) |
17605                     first.Encode(22, 12) | (len_encoding << 8) |
17606                     (rn.GetCode() << 16));
17607          AdvanceIT();
17608          return;
17609        }
17610      }
17611    } else {
17612      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17613      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17614          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17615           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17616          operand.IsOffset() && encoded_align_1.IsValid() &&
17617          (!rn.IsPC() || AllowUnpredictable())) {
17618        if (cond.Is(al)) {
17619          const DRegister& first = nreglist.GetFirstDRegister();
17620          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17621          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
17622                  (encoded_align_1.GetEncodingValue() << 4) |
17623                  first.Encode(22, 12) | (len_encoding << 8) |
17624                  (rn.GetCode() << 16));
17625          return;
17626        }
17627      }
17628      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17629      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17630          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17631           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17632          operand.IsPostIndex() && encoded_align_1.IsValid() &&
17633          (!rn.IsPC() || AllowUnpredictable())) {
17634        if (cond.Is(al)) {
17635          const DRegister& first = nreglist.GetFirstDRegister();
17636          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17637          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17638                  (encoded_align_1.GetEncodingValue() << 4) |
17639                  first.Encode(22, 12) | (len_encoding << 8) |
17640                  (rn.GetCode() << 16));
17641          return;
17642        }
17643      }
17644    }
17645  }
17646  if (operand.IsPlainRegister()) {
17647    Register rn = operand.GetBaseRegister();
17648    Alignment align = operand.GetAlignment();
17649    Register rm = operand.GetOffsetRegister();
17650    Dt_size_7 encoded_dt(dt);
17651    Align_align_3 encoded_align_1(align);
17652    if (IsUsingT32()) {
17653      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17654      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17655          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17656           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17657          !rm.IsPC() && !rm.IsSP()) {
17658        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17659          const DRegister& first = nreglist.GetFirstDRegister();
17660          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17661          EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
17662                     (encoded_align_1.GetEncodingValue() << 4) |
17663                     first.Encode(22, 12) | (len_encoding << 8) |
17664                     (rn.GetCode() << 16) | rm.GetCode());
17665          AdvanceIT();
17666          return;
17667        }
17668      }
17669    } else {
17670      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17671      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17672          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17673           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17674          !rm.IsPC() && !rm.IsSP()) {
17675        if (cond.Is(al)) {
17676          const DRegister& first = nreglist.GetFirstDRegister();
17677          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17678          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17679                  (encoded_align_1.GetEncodingValue() << 4) |
17680                  first.Encode(22, 12) | (len_encoding << 8) |
17681                  (rn.GetCode() << 16) | rm.GetCode());
17682          return;
17683        }
17684      }
17685    }
17686  }
17687  Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
17688}
17689
17690void Assembler::vld3(Condition cond,
17691                     DataType dt,
17692                     const NeonRegisterList& nreglist,
17693                     const MemOperand& operand) {
17694  VIXL_ASSERT(AllowAssembler());
17695  CheckIT(cond);
17696  if (operand.IsImmediateZero()) {
17697    Register rn = operand.GetBaseRegister();
17698    Dt_size_7 encoded_dt(dt);
17699    Index_1 encoded_align_1(nreglist, dt);
17700    if (IsUsingT32()) {
17701      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
17702      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17703          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17704           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17705          operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
17706        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17707          const DRegister& first = nreglist.GetFirstDRegister();
17708          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17709          EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
17710                     first.Encode(22, 12) | (len_encoding << 5) |
17711                     (rn.GetCode() << 16));
17712          AdvanceIT();
17713          return;
17714        }
17715      }
17716      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
17717      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17718          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17719           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17720          operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
17721        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17722          const DRegister& first = nreglist.GetFirstDRegister();
17723          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17724          EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
17725                     first.Encode(22, 12) | (len_encoding << 5) |
17726                     (rn.GetCode() << 16));
17727          AdvanceIT();
17728          return;
17729        }
17730      }
17731      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
17732      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17733          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17734           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17735          operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
17736        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17737          const DRegister& first = nreglist.GetFirstDRegister();
17738          EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) |
17739                     (encoded_align_1.GetEncodingValue() << 4) |
17740                     first.Encode(22, 12) | (rn.GetCode() << 16));
17741          AdvanceIT();
17742          return;
17743        }
17744      }
17745      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
17746      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17747          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17748           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17749          operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
17750        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17751          const DRegister& first = nreglist.GetFirstDRegister();
17752          EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) |
17753                     (encoded_align_1.GetEncodingValue() << 4) |
17754                     first.Encode(22, 12) | (rn.GetCode() << 16));
17755          AdvanceIT();
17756          return;
17757        }
17758      }
17759    } else {
17760      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
17761      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17762          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17763           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17764          operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
17765        if (cond.Is(al)) {
17766          const DRegister& first = nreglist.GetFirstDRegister();
17767          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17768          EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
17769                  first.Encode(22, 12) | (len_encoding << 5) |
17770                  (rn.GetCode() << 16));
17771          return;
17772        }
17773      }
17774      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
17775      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17776          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17777           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17778          operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
17779        if (cond.Is(al)) {
17780          const DRegister& first = nreglist.GetFirstDRegister();
17781          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17782          EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
17783                  first.Encode(22, 12) | (len_encoding << 5) |
17784                  (rn.GetCode() << 16));
17785          return;
17786        }
17787      }
17788      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
17789      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17790          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17791           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17792          operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
17793        if (cond.Is(al)) {
17794          const DRegister& first = nreglist.GetFirstDRegister();
17795          EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) |
17796                  (encoded_align_1.GetEncodingValue() << 4) |
17797                  first.Encode(22, 12) | (rn.GetCode() << 16));
17798          return;
17799        }
17800      }
17801      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
17802      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17803          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17804           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17805          operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
17806        if (cond.Is(al)) {
17807          const DRegister& first = nreglist.GetFirstDRegister();
17808          EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) |
17809                  (encoded_align_1.GetEncodingValue() << 4) |
17810                  first.Encode(22, 12) | (rn.GetCode() << 16));
17811          return;
17812        }
17813      }
17814    }
17815  }
17816  if (operand.IsPlainRegister()) {
17817    Register rn = operand.GetBaseRegister();
17818    Sign sign = operand.GetSign();
17819    Register rm = operand.GetOffsetRegister();
17820    Dt_size_7 encoded_dt(dt);
17821    Index_1 encoded_align_1(nreglist, dt);
17822    if (IsUsingT32()) {
17823      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
17824      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17825          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17826           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17827          sign.IsPlus() && operand.IsPostIndex()) {
17828        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17829          const DRegister& first = nreglist.GetFirstDRegister();
17830          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17831          EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) |
17832                     first.Encode(22, 12) | (len_encoding << 5) |
17833                     (rn.GetCode() << 16) | rm.GetCode());
17834          AdvanceIT();
17835          return;
17836        }
17837      }
17838      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
17839      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17840          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17841           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17842          sign.IsPlus() && operand.IsPostIndex()) {
17843        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17844          const DRegister& first = nreglist.GetFirstDRegister();
17845          EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) |
17846                     (encoded_align_1.GetEncodingValue() << 4) |
17847                     first.Encode(22, 12) | (rn.GetCode() << 16) |
17848                     rm.GetCode());
17849          AdvanceIT();
17850          return;
17851        }
17852      }
17853    } else {
17854      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
17855      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17856          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17857           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17858          sign.IsPlus() && operand.IsPostIndex()) {
17859        if (cond.Is(al)) {
17860          const DRegister& first = nreglist.GetFirstDRegister();
17861          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17862          EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) |
17863                  first.Encode(22, 12) | (len_encoding << 5) |
17864                  (rn.GetCode() << 16) | rm.GetCode());
17865          return;
17866        }
17867      }
17868      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
17869      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17870          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17871           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17872          sign.IsPlus() && operand.IsPostIndex()) {
17873        if (cond.Is(al)) {
17874          const DRegister& first = nreglist.GetFirstDRegister();
17875          EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) |
17876                  (encoded_align_1.GetEncodingValue() << 4) |
17877                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17878          return;
17879        }
17880      }
17881    }
17882  }
17883  Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
17884}
17885
17886void Assembler::vld4(Condition cond,
17887                     DataType dt,
17888                     const NeonRegisterList& nreglist,
17889                     const AlignedMemOperand& operand) {
17890  VIXL_ASSERT(AllowAssembler());
17891  CheckIT(cond);
17892  if (operand.IsImmediateZero()) {
17893    Register rn = operand.GetBaseRegister();
17894    Alignment align = operand.GetAlignment();
17895    Dt_size_7 encoded_dt(dt);
17896    Dt_size_8 encoded_dt_2(dt, align);
17897    Align_align_4 encoded_align_1(align);
17898    Align_a_3 encoded_align_2(align, dt);
17899    Align_index_align_3 encoded_align_3(align, nreglist, dt);
17900    if (IsUsingT32()) {
17901      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17902      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17903          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17904           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17905          operand.IsOffset() && encoded_align_1.IsValid() &&
17906          (!rn.IsPC() || AllowUnpredictable())) {
17907        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17908          const DRegister& first = nreglist.GetFirstDRegister();
17909          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17910          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
17911                     (encoded_align_1.GetEncodingValue() << 4) |
17912                     first.Encode(22, 12) | (len_encoding << 8) |
17913                     (rn.GetCode() << 16));
17914          AdvanceIT();
17915          return;
17916        }
17917      }
17918      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17919      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17920          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17921           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17922          operand.IsPostIndex() && encoded_align_1.IsValid() &&
17923          (!rn.IsPC() || AllowUnpredictable())) {
17924        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17925          const DRegister& first = nreglist.GetFirstDRegister();
17926          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17927          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
17928                     (encoded_align_1.GetEncodingValue() << 4) |
17929                     first.Encode(22, 12) | (len_encoding << 8) |
17930                     (rn.GetCode() << 16));
17931          AdvanceIT();
17932          return;
17933        }
17934      }
17935      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17936      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17937          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17938           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17939          operand.IsOffset() && encoded_align_2.IsValid() &&
17940          (!rn.IsPC() || AllowUnpredictable())) {
17941        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17942          const DRegister& first = nreglist.GetFirstDRegister();
17943          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17944          EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
17945                     (encoded_align_2.GetEncodingValue() << 4) |
17946                     first.Encode(22, 12) | (len_encoding << 5) |
17947                     (rn.GetCode() << 16));
17948          AdvanceIT();
17949          return;
17950        }
17951      }
17952      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17953      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17954          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17955           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17956          operand.IsPostIndex() && encoded_align_2.IsValid() &&
17957          (!rn.IsPC() || AllowUnpredictable())) {
17958        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17959          const DRegister& first = nreglist.GetFirstDRegister();
17960          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17961          EmitT32_32(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
17962                     (encoded_align_2.GetEncodingValue() << 4) |
17963                     first.Encode(22, 12) | (len_encoding << 5) |
17964                     (rn.GetCode() << 16));
17965          AdvanceIT();
17966          return;
17967        }
17968      }
17969      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17970      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17971          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17972           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17973          operand.IsOffset() && encoded_align_3.IsValid() &&
17974          (!rn.IsPC() || AllowUnpredictable())) {
17975        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17976          const DRegister& first = nreglist.GetFirstDRegister();
17977          EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) |
17978                     (encoded_align_3.GetEncodingValue() << 4) |
17979                     first.Encode(22, 12) | (rn.GetCode() << 16));
17980          AdvanceIT();
17981          return;
17982        }
17983      }
17984      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17985      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17986          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17987           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17988          operand.IsPostIndex() && encoded_align_3.IsValid() &&
17989          (!rn.IsPC() || AllowUnpredictable())) {
17990        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17991          const DRegister& first = nreglist.GetFirstDRegister();
17992          EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) |
17993                     (encoded_align_3.GetEncodingValue() << 4) |
17994                     first.Encode(22, 12) | (rn.GetCode() << 16));
17995          AdvanceIT();
17996          return;
17997        }
17998      }
17999    } else {
18000      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18001      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18002          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18003           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18004          operand.IsOffset() && encoded_align_1.IsValid() &&
18005          (!rn.IsPC() || AllowUnpredictable())) {
18006        if (cond.Is(al)) {
18007          const DRegister& first = nreglist.GetFirstDRegister();
18008          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18009          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
18010                  (encoded_align_1.GetEncodingValue() << 4) |
18011                  first.Encode(22, 12) | (len_encoding << 8) |
18012                  (rn.GetCode() << 16));
18013          return;
18014        }
18015      }
18016      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18017      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18018          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18019           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18020          operand.IsPostIndex() && encoded_align_1.IsValid() &&
18021          (!rn.IsPC() || AllowUnpredictable())) {
18022        if (cond.Is(al)) {
18023          const DRegister& first = nreglist.GetFirstDRegister();
18024          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18025          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
18026                  (encoded_align_1.GetEncodingValue() << 4) |
18027                  first.Encode(22, 12) | (len_encoding << 8) |
18028                  (rn.GetCode() << 16));
18029          return;
18030        }
18031      }
18032      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18033      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18034          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18035           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18036          operand.IsOffset() && encoded_align_2.IsValid() &&
18037          (!rn.IsPC() || AllowUnpredictable())) {
18038        if (cond.Is(al)) {
18039          const DRegister& first = nreglist.GetFirstDRegister();
18040          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18041          EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
18042                  (encoded_align_2.GetEncodingValue() << 4) |
18043                  first.Encode(22, 12) | (len_encoding << 5) |
18044                  (rn.GetCode() << 16));
18045          return;
18046        }
18047      }
18048      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18049      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18050          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18051           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18052          operand.IsPostIndex() && encoded_align_2.IsValid() &&
18053          (!rn.IsPC() || AllowUnpredictable())) {
18054        if (cond.Is(al)) {
18055          const DRegister& first = nreglist.GetFirstDRegister();
18056          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18057          EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
18058                  (encoded_align_2.GetEncodingValue() << 4) |
18059                  first.Encode(22, 12) | (len_encoding << 5) |
18060                  (rn.GetCode() << 16));
18061          return;
18062        }
18063      }
18064      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18065      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18066          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18067           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18068          operand.IsOffset() && encoded_align_3.IsValid() &&
18069          (!rn.IsPC() || AllowUnpredictable())) {
18070        if (cond.Is(al)) {
18071          const DRegister& first = nreglist.GetFirstDRegister();
18072          EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) |
18073                  (encoded_align_3.GetEncodingValue() << 4) |
18074                  first.Encode(22, 12) | (rn.GetCode() << 16));
18075          return;
18076        }
18077      }
18078      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18079      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18080          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18081           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18082          operand.IsPostIndex() && encoded_align_3.IsValid() &&
18083          (!rn.IsPC() || AllowUnpredictable())) {
18084        if (cond.Is(al)) {
18085          const DRegister& first = nreglist.GetFirstDRegister();
18086          EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) |
18087                  (encoded_align_3.GetEncodingValue() << 4) |
18088                  first.Encode(22, 12) | (rn.GetCode() << 16));
18089          return;
18090        }
18091      }
18092    }
18093  }
18094  if (operand.IsPlainRegister()) {
18095    Register rn = operand.GetBaseRegister();
18096    Alignment align = operand.GetAlignment();
18097    Register rm = operand.GetOffsetRegister();
18098    Dt_size_7 encoded_dt(dt);
18099    Dt_size_8 encoded_dt_2(dt, align);
18100    Align_align_4 encoded_align_1(align);
18101    Align_a_3 encoded_align_2(align, dt);
18102    Align_index_align_3 encoded_align_3(align, nreglist, dt);
18103    if (IsUsingT32()) {
18104      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18105      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18106          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18107           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18108          !rm.IsPC() && !rm.IsSP()) {
18109        if (cond.Is(al) || AllowStronglyDiscouraged()) {
18110          const DRegister& first = nreglist.GetFirstDRegister();
18111          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18112          EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
18113                     (encoded_align_1.GetEncodingValue() << 4) |
18114                     first.Encode(22, 12) | (len_encoding << 8) |
18115                     (rn.GetCode() << 16) | rm.GetCode());
18116          AdvanceIT();
18117          return;
18118        }
18119      }
18120      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18121      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18122          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18123           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18124          !rm.IsPC() && !rm.IsSP()) {
18125        if (cond.Is(al) || AllowStronglyDiscouraged()) {
18126          const DRegister& first = nreglist.GetFirstDRegister();
18127          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18128          EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
18129                     (encoded_align_2.GetEncodingValue() << 4) |
18130                     first.Encode(22, 12) | (len_encoding << 5) |
18131                     (rn.GetCode() << 16) | rm.GetCode());
18132          AdvanceIT();
18133          return;
18134        }
18135      }
18136      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18137      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18138          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18139           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18140          !rm.IsPC() && !rm.IsSP()) {
18141        if (cond.Is(al) || AllowStronglyDiscouraged()) {
18142          const DRegister& first = nreglist.GetFirstDRegister();
18143          EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) |
18144                     (encoded_align_3.GetEncodingValue() << 4) |
18145                     first.Encode(22, 12) | (rn.GetCode() << 16) |
18146                     rm.GetCode());
18147          AdvanceIT();
18148          return;
18149        }
18150      }
18151    } else {
18152      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18153      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18154          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18155           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18156          !rm.IsPC() && !rm.IsSP()) {
18157        if (cond.Is(al)) {
18158          const DRegister& first = nreglist.GetFirstDRegister();
18159          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18160          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
18161                  (encoded_align_1.GetEncodingValue() << 4) |
18162                  first.Encode(22, 12) | (len_encoding << 8) |
18163                  (rn.GetCode() << 16) | rm.GetCode());
18164          return;
18165        }
18166      }
18167      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18168      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18169          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18170           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18171          !rm.IsPC() && !rm.IsSP()) {
18172        if (cond.Is(al)) {
18173          const DRegister& first = nreglist.GetFirstDRegister();
18174          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18175          EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
18176                  (encoded_align_2.GetEncodingValue() << 4) |
18177                  first.Encode(22, 12) | (len_encoding << 5) |
18178                  (rn.GetCode() << 16) | rm.GetCode());
18179          return;
18180        }
18181      }
18182      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18183      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18184          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18185           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18186          !rm.IsPC() && !rm.IsSP()) {
18187        if (cond.Is(al)) {
18188          const DRegister& first = nreglist.GetFirstDRegister();
18189          EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) |
18190                  (encoded_align_3.GetEncodingValue() << 4) |
18191                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
18192          return;
18193        }
18194      }
18195    }
18196  }
18197  Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand);
18198}
18199
18200void Assembler::vldm(Condition cond,
18201                     DataType dt,
18202                     Register rn,
18203                     WriteBack write_back,
18204                     DRegisterList dreglist) {
18205  VIXL_ASSERT(AllowAssembler());
18206  CheckIT(cond);
18207  USE(dt);
18208  if (IsUsingT32()) {
18209    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
18210    if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18211      const DRegister& dreg = dreglist.GetFirstDRegister();
18212      unsigned len = dreglist.GetLength() * 2;
18213      EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
18214                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18215                 (len & 0xff));
18216      AdvanceIT();
18217      return;
18218    }
18219  } else {
18220    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
18221    if (cond.IsNotNever() &&
18222        ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18223      const DRegister& dreg = dreglist.GetFirstDRegister();
18224      unsigned len = dreglist.GetLength() * 2;
18225      EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18226              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18227              (len & 0xff));
18228      return;
18229    }
18230  }
18231  Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist);
18232}
18233
18234void Assembler::vldm(Condition cond,
18235                     DataType dt,
18236                     Register rn,
18237                     WriteBack write_back,
18238                     SRegisterList sreglist) {
18239  VIXL_ASSERT(AllowAssembler());
18240  CheckIT(cond);
18241  USE(dt);
18242  if (IsUsingT32()) {
18243    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
18244    const SRegister& sreg = sreglist.GetFirstSRegister();
18245    unsigned len = sreglist.GetLength();
18246    EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
18247               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18248               (len & 0xff));
18249    AdvanceIT();
18250    return;
18251  } else {
18252    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
18253    if (cond.IsNotNever()) {
18254      const SRegister& sreg = sreglist.GetFirstSRegister();
18255      unsigned len = sreglist.GetLength();
18256      EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18257              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18258              (len & 0xff));
18259      return;
18260    }
18261  }
18262  Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist);
18263}
18264
18265void Assembler::vldmdb(Condition cond,
18266                       DataType dt,
18267                       Register rn,
18268                       WriteBack write_back,
18269                       DRegisterList dreglist) {
18270  VIXL_ASSERT(AllowAssembler());
18271  CheckIT(cond);
18272  USE(dt);
18273  if (IsUsingT32()) {
18274    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
18275    if (write_back.DoesWriteBack() &&
18276        ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18277      const DRegister& dreg = dreglist.GetFirstDRegister();
18278      unsigned len = dreglist.GetLength() * 2;
18279      EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
18280                 (len & 0xff));
18281      AdvanceIT();
18282      return;
18283    }
18284  } else {
18285    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
18286    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
18287        ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18288      const DRegister& dreg = dreglist.GetFirstDRegister();
18289      unsigned len = dreglist.GetLength() * 2;
18290      EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18291              dreg.Encode(22, 12) | (len & 0xff));
18292      return;
18293    }
18294  }
18295  Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist);
18296}
18297
18298void Assembler::vldmdb(Condition cond,
18299                       DataType dt,
18300                       Register rn,
18301                       WriteBack write_back,
18302                       SRegisterList sreglist) {
18303  VIXL_ASSERT(AllowAssembler());
18304  CheckIT(cond);
18305  USE(dt);
18306  if (IsUsingT32()) {
18307    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
18308    if (write_back.DoesWriteBack()) {
18309      const SRegister& sreg = sreglist.GetFirstSRegister();
18310      unsigned len = sreglist.GetLength();
18311      EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
18312                 (len & 0xff));
18313      AdvanceIT();
18314      return;
18315    }
18316  } else {
18317    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
18318    if (write_back.DoesWriteBack() && cond.IsNotNever()) {
18319      const SRegister& sreg = sreglist.GetFirstSRegister();
18320      unsigned len = sreglist.GetLength();
18321      EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18322              sreg.Encode(22, 12) | (len & 0xff));
18323      return;
18324    }
18325  }
18326  Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist);
18327}
18328
18329void Assembler::vldmia(Condition cond,
18330                       DataType dt,
18331                       Register rn,
18332                       WriteBack write_back,
18333                       DRegisterList dreglist) {
18334  VIXL_ASSERT(AllowAssembler());
18335  CheckIT(cond);
18336  USE(dt);
18337  if (IsUsingT32()) {
18338    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
18339    if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18340      const DRegister& dreg = dreglist.GetFirstDRegister();
18341      unsigned len = dreglist.GetLength() * 2;
18342      EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
18343                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18344                 (len & 0xff));
18345      AdvanceIT();
18346      return;
18347    }
18348  } else {
18349    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
18350    if (cond.IsNotNever() &&
18351        ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18352      const DRegister& dreg = dreglist.GetFirstDRegister();
18353      unsigned len = dreglist.GetLength() * 2;
18354      EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18355              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18356              (len & 0xff));
18357      return;
18358    }
18359  }
18360  Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist);
18361}
18362
18363void Assembler::vldmia(Condition cond,
18364                       DataType dt,
18365                       Register rn,
18366                       WriteBack write_back,
18367                       SRegisterList sreglist) {
18368  VIXL_ASSERT(AllowAssembler());
18369  CheckIT(cond);
18370  USE(dt);
18371  if (IsUsingT32()) {
18372    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
18373    const SRegister& sreg = sreglist.GetFirstSRegister();
18374    unsigned len = sreglist.GetLength();
18375    EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
18376               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18377               (len & 0xff));
18378    AdvanceIT();
18379    return;
18380  } else {
18381    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
18382    if (cond.IsNotNever()) {
18383      const SRegister& sreg = sreglist.GetFirstSRegister();
18384      unsigned len = sreglist.GetLength();
18385      EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18386              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18387              (len & 0xff));
18388      return;
18389    }
18390  }
18391  Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist);
18392}
18393
18394void Assembler::vldr(Condition cond, DataType dt, DRegister rd, Label* label) {
18395  VIXL_ASSERT(AllowAssembler());
18396  CheckIT(cond);
18397  Label::Offset offset =
18398      label->IsBound()
18399          ? label->GetLocation() -
18400                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
18401          : 0;
18402  if (IsUsingT32()) {
18403    // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
18404    if (dt.IsNoneOr(Untyped64) &&
18405        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18406          ((offset & 0x3) == 0)) ||
18407         !label->IsBound())) {
18408      static class EmitOp : public Label::LabelEmitOperator {
18409       public:
18410        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18411        virtual uint32_t Encode(uint32_t instr,
18412                                Label::Offset pc,
18413                                const Label* label) const VIXL_OVERRIDE {
18414          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18415          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18416                      ((offset & 0x3) == 0));
18417          int32_t target = offset >> 2;
18418          uint32_t U = (target >= 0) && !label->IsMinusZero();
18419          target = abs(target) | (U << 8);
18420          return instr | (target & 0xff) | ((target & 0x100) << 15);
18421        }
18422      } immop;
18423      EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12), label, immop));
18424      AdvanceIT();
18425      return;
18426    }
18427  } else {
18428    // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
18429    if (dt.IsNoneOr(Untyped64) &&
18430        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18431          ((offset & 0x3) == 0)) ||
18432         !label->IsBound()) &&
18433        cond.IsNotNever()) {
18434      static class EmitOp : public Label::LabelEmitOperator {
18435       public:
18436        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18437        virtual uint32_t Encode(uint32_t instr,
18438                                Label::Offset pc,
18439                                const Label* label) const VIXL_OVERRIDE {
18440          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18441          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18442                      ((offset & 0x3) == 0));
18443          int32_t target = offset >> 2;
18444          uint32_t U = (target >= 0) && !label->IsMinusZero();
18445          target = abs(target) | (U << 8);
18446          return instr | (target & 0xff) | ((target & 0x100) << 15);
18447        }
18448      } immop;
18449      EmitA32(
18450          Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
18451               label,
18452               immop));
18453      return;
18454    }
18455  }
18456  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label);
18457}
18458
18459void Assembler::vldr(Condition cond,
18460                     DataType dt,
18461                     DRegister rd,
18462                     const MemOperand& operand) {
18463  VIXL_ASSERT(AllowAssembler());
18464  CheckIT(cond);
18465  if (operand.IsImmediate()) {
18466    Register rn = operand.GetBaseRegister();
18467    int32_t offset = operand.GetOffsetImmediate();
18468    if (IsUsingT32()) {
18469      // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1
18470      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18471          ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
18472        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18473        uint32_t offset_ = abs(offset) >> 2;
18474        EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23));
18475        AdvanceIT();
18476        return;
18477      }
18478      // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
18479      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18480          ((offset % 4) == 0) && operand.IsOffset() &&
18481          ((rn.GetCode() & 0xf) != 0xf)) {
18482        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18483        uint32_t offset_ = abs(offset) >> 2;
18484        EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
18485                   offset_ | (sign << 23));
18486        AdvanceIT();
18487        return;
18488      }
18489    } else {
18490      // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1
18491      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18492          ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
18493          cond.IsNotNever()) {
18494        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18495        uint32_t offset_ = abs(offset) >> 2;
18496        EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18497                offset_ | (sign << 23));
18498        return;
18499      }
18500      // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
18501      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18502          ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
18503          ((rn.GetCode() & 0xf) != 0xf)) {
18504        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18505        uint32_t offset_ = abs(offset) >> 2;
18506        EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18507                (rn.GetCode() << 16) | offset_ | (sign << 23));
18508        return;
18509      }
18510    }
18511  }
18512  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
18513}
18514
18515void Assembler::vldr(Condition cond, DataType dt, SRegister rd, Label* label) {
18516  VIXL_ASSERT(AllowAssembler());
18517  CheckIT(cond);
18518  Label::Offset offset =
18519      label->IsBound()
18520          ? label->GetLocation() -
18521                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
18522          : 0;
18523  if (IsUsingT32()) {
18524    // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
18525    if (dt.IsNoneOr(Untyped32) &&
18526        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18527          ((offset & 0x3) == 0)) ||
18528         !label->IsBound())) {
18529      static class EmitOp : public Label::LabelEmitOperator {
18530       public:
18531        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18532        virtual uint32_t Encode(uint32_t instr,
18533                                Label::Offset pc,
18534                                const Label* label) const VIXL_OVERRIDE {
18535          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18536          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18537                      ((offset & 0x3) == 0));
18538          int32_t target = offset >> 2;
18539          uint32_t U = (target >= 0) && !label->IsMinusZero();
18540          target = abs(target) | (U << 8);
18541          return instr | (target & 0xff) | ((target & 0x100) << 15);
18542        }
18543      } immop;
18544      EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12), label, immop));
18545      AdvanceIT();
18546      return;
18547    }
18548  } else {
18549    // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
18550    if (dt.IsNoneOr(Untyped32) &&
18551        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18552          ((offset & 0x3) == 0)) ||
18553         !label->IsBound()) &&
18554        cond.IsNotNever()) {
18555      static class EmitOp : public Label::LabelEmitOperator {
18556       public:
18557        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18558        virtual uint32_t Encode(uint32_t instr,
18559                                Label::Offset pc,
18560                                const Label* label) const VIXL_OVERRIDE {
18561          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18562          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18563                      ((offset & 0x3) == 0));
18564          int32_t target = offset >> 2;
18565          uint32_t U = (target >= 0) && !label->IsMinusZero();
18566          target = abs(target) | (U << 8);
18567          return instr | (target & 0xff) | ((target & 0x100) << 15);
18568        }
18569      } immop;
18570      EmitA32(
18571          Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
18572               label,
18573               immop));
18574      return;
18575    }
18576  }
18577  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label);
18578}
18579
18580void Assembler::vldr(Condition cond,
18581                     DataType dt,
18582                     SRegister rd,
18583                     const MemOperand& operand) {
18584  VIXL_ASSERT(AllowAssembler());
18585  CheckIT(cond);
18586  if (operand.IsImmediate()) {
18587    Register rn = operand.GetBaseRegister();
18588    int32_t offset = operand.GetOffsetImmediate();
18589    if (IsUsingT32()) {
18590      // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2
18591      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18592          ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
18593        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18594        uint32_t offset_ = abs(offset) >> 2;
18595        EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23));
18596        AdvanceIT();
18597        return;
18598      }
18599      // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
18600      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18601          ((offset % 4) == 0) && operand.IsOffset() &&
18602          ((rn.GetCode() & 0xf) != 0xf)) {
18603        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18604        uint32_t offset_ = abs(offset) >> 2;
18605        EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
18606                   offset_ | (sign << 23));
18607        AdvanceIT();
18608        return;
18609      }
18610    } else {
18611      // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2
18612      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18613          ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
18614          cond.IsNotNever()) {
18615        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18616        uint32_t offset_ = abs(offset) >> 2;
18617        EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18618                offset_ | (sign << 23));
18619        return;
18620      }
18621      // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
18622      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18623          ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
18624          ((rn.GetCode() & 0xf) != 0xf)) {
18625        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18626        uint32_t offset_ = abs(offset) >> 2;
18627        EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18628                (rn.GetCode() << 16) | offset_ | (sign << 23));
18629        return;
18630      }
18631    }
18632  }
18633  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
18634}
18635
18636void Assembler::vmax(
18637    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18638  VIXL_ASSERT(AllowAssembler());
18639  CheckIT(cond);
18640  Dt_U_size_1 encoded_dt(dt);
18641  if (IsUsingT32()) {
18642    // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
18643    if (dt.Is(F32)) {
18644      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18645        EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18646                   rm.Encode(5, 0));
18647        AdvanceIT();
18648        return;
18649      }
18650    }
18651    // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
18652    if (encoded_dt.IsValid()) {
18653      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18654        EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18655                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18656                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18657        AdvanceIT();
18658        return;
18659      }
18660    }
18661  } else {
18662    // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
18663    if (dt.Is(F32)) {
18664      if (cond.Is(al)) {
18665        EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18666                rm.Encode(5, 0));
18667        return;
18668      }
18669    }
18670    // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
18671    if (encoded_dt.IsValid()) {
18672      if (cond.Is(al)) {
18673        EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18674                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18675                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18676        return;
18677      }
18678    }
18679  }
18680  Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
18681}
18682
18683void Assembler::vmax(
18684    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18685  VIXL_ASSERT(AllowAssembler());
18686  CheckIT(cond);
18687  Dt_U_size_1 encoded_dt(dt);
18688  if (IsUsingT32()) {
18689    // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
18690    if (dt.Is(F32)) {
18691      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18692        EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18693                   rm.Encode(5, 0));
18694        AdvanceIT();
18695        return;
18696      }
18697    }
18698    // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
18699    if (encoded_dt.IsValid()) {
18700      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18701        EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18702                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18703                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18704        AdvanceIT();
18705        return;
18706      }
18707    }
18708  } else {
18709    // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
18710    if (dt.Is(F32)) {
18711      if (cond.Is(al)) {
18712        EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18713                rm.Encode(5, 0));
18714        return;
18715      }
18716    }
18717    // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
18718    if (encoded_dt.IsValid()) {
18719      if (cond.Is(al)) {
18720        EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18721                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18722                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18723        return;
18724      }
18725    }
18726  }
18727  Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
18728}
18729
18730void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18731  VIXL_ASSERT(AllowAssembler());
18732  CheckIT(al);
18733  if (IsUsingT32()) {
18734    // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
18735    if (OutsideITBlock() && dt.Is(F32)) {
18736      EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18737                 rm.Encode(5, 0));
18738      AdvanceIT();
18739      return;
18740    }
18741    // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
18742    if (OutsideITBlock() && dt.Is(F64)) {
18743      EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18744                 rm.Encode(5, 0));
18745      AdvanceIT();
18746      return;
18747    }
18748  } else {
18749    // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
18750    if (dt.Is(F32)) {
18751      EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18752              rm.Encode(5, 0));
18753      return;
18754    }
18755    // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
18756    if (dt.Is(F64)) {
18757      EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18758              rm.Encode(5, 0));
18759      return;
18760    }
18761  }
18762  Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18763}
18764
18765void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18766  VIXL_ASSERT(AllowAssembler());
18767  CheckIT(al);
18768  if (IsUsingT32()) {
18769    // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
18770    if (OutsideITBlock() && dt.Is(F32)) {
18771      EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18772                 rm.Encode(5, 0));
18773      AdvanceIT();
18774      return;
18775    }
18776  } else {
18777    // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
18778    if (dt.Is(F32)) {
18779      EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18780              rm.Encode(5, 0));
18781      return;
18782    }
18783  }
18784  Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18785}
18786
18787void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
18788  VIXL_ASSERT(AllowAssembler());
18789  CheckIT(al);
18790  if (IsUsingT32()) {
18791    // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
18792    if (OutsideITBlock() && dt.Is(F32)) {
18793      EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18794                 rm.Encode(5, 0));
18795      AdvanceIT();
18796      return;
18797    }
18798  } else {
18799    // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
18800    if (dt.Is(F32)) {
18801      EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18802              rm.Encode(5, 0));
18803      return;
18804    }
18805  }
18806  Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18807}
18808
18809void Assembler::vmin(
18810    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18811  VIXL_ASSERT(AllowAssembler());
18812  CheckIT(cond);
18813  Dt_U_size_1 encoded_dt(dt);
18814  if (IsUsingT32()) {
18815    // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
18816    if (dt.Is(F32)) {
18817      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18818        EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18819                   rm.Encode(5, 0));
18820        AdvanceIT();
18821        return;
18822      }
18823    }
18824    // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
18825    if (encoded_dt.IsValid()) {
18826      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18827        EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18828                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18829                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18830        AdvanceIT();
18831        return;
18832      }
18833    }
18834  } else {
18835    // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
18836    if (dt.Is(F32)) {
18837      if (cond.Is(al)) {
18838        EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18839                rm.Encode(5, 0));
18840        return;
18841      }
18842    }
18843    // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
18844    if (encoded_dt.IsValid()) {
18845      if (cond.Is(al)) {
18846        EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18847                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18848                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18849        return;
18850      }
18851    }
18852  }
18853  Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
18854}
18855
18856void Assembler::vmin(
18857    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18858  VIXL_ASSERT(AllowAssembler());
18859  CheckIT(cond);
18860  Dt_U_size_1 encoded_dt(dt);
18861  if (IsUsingT32()) {
18862    // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
18863    if (dt.Is(F32)) {
18864      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18865        EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18866                   rm.Encode(5, 0));
18867        AdvanceIT();
18868        return;
18869      }
18870    }
18871    // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
18872    if (encoded_dt.IsValid()) {
18873      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18874        EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18875                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18876                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18877        AdvanceIT();
18878        return;
18879      }
18880    }
18881  } else {
18882    // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
18883    if (dt.Is(F32)) {
18884      if (cond.Is(al)) {
18885        EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18886                rm.Encode(5, 0));
18887        return;
18888      }
18889    }
18890    // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
18891    if (encoded_dt.IsValid()) {
18892      if (cond.Is(al)) {
18893        EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18894                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18895                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18896        return;
18897      }
18898    }
18899  }
18900  Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
18901}
18902
18903void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18904  VIXL_ASSERT(AllowAssembler());
18905  CheckIT(al);
18906  if (IsUsingT32()) {
18907    // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
18908    if (OutsideITBlock() && dt.Is(F32)) {
18909      EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18910                 rm.Encode(5, 0));
18911      AdvanceIT();
18912      return;
18913    }
18914    // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
18915    if (OutsideITBlock() && dt.Is(F64)) {
18916      EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18917                 rm.Encode(5, 0));
18918      AdvanceIT();
18919      return;
18920    }
18921  } else {
18922    // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
18923    if (dt.Is(F32)) {
18924      EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18925              rm.Encode(5, 0));
18926      return;
18927    }
18928    // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
18929    if (dt.Is(F64)) {
18930      EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18931              rm.Encode(5, 0));
18932      return;
18933    }
18934  }
18935  Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18936}
18937
18938void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18939  VIXL_ASSERT(AllowAssembler());
18940  CheckIT(al);
18941  if (IsUsingT32()) {
18942    // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
18943    if (OutsideITBlock() && dt.Is(F32)) {
18944      EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18945                 rm.Encode(5, 0));
18946      AdvanceIT();
18947      return;
18948    }
18949  } else {
18950    // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
18951    if (dt.Is(F32)) {
18952      EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18953              rm.Encode(5, 0));
18954      return;
18955    }
18956  }
18957  Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18958}
18959
18960void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
18961  VIXL_ASSERT(AllowAssembler());
18962  CheckIT(al);
18963  if (IsUsingT32()) {
18964    // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
18965    if (OutsideITBlock() && dt.Is(F32)) {
18966      EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18967                 rm.Encode(5, 0));
18968      AdvanceIT();
18969      return;
18970    }
18971  } else {
18972    // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
18973    if (dt.Is(F32)) {
18974      EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18975              rm.Encode(5, 0));
18976      return;
18977    }
18978  }
18979  Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18980}
18981
18982void Assembler::vmla(
18983    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
18984  VIXL_ASSERT(AllowAssembler());
18985  CheckIT(cond);
18986  Dt_size_9 encoded_dt(dt);
18987  if (IsUsingT32()) {
18988    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
18989    if (encoded_dt.IsValid() &&
18990        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18991         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18992          (rm.GetLane() <= 1)))) {
18993      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18994        EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
18995                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18996                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18997        AdvanceIT();
18998        return;
18999      }
19000    }
19001  } else {
19002    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
19003    if (encoded_dt.IsValid() &&
19004        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19005         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19006          (rm.GetLane() <= 1)))) {
19007      if (cond.Is(al)) {
19008        EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
19009                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19010                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19011        return;
19012      }
19013    }
19014  }
19015  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19016}
19017
19018void Assembler::vmla(
19019    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
19020  VIXL_ASSERT(AllowAssembler());
19021  CheckIT(cond);
19022  Dt_size_9 encoded_dt(dt);
19023  if (IsUsingT32()) {
19024    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
19025    if (encoded_dt.IsValid() &&
19026        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19027         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19028          (rm.GetLane() <= 1)))) {
19029      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19030        EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
19031                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19032                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19033        AdvanceIT();
19034        return;
19035      }
19036    }
19037  } else {
19038    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
19039    if (encoded_dt.IsValid() &&
19040        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19041         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19042          (rm.GetLane() <= 1)))) {
19043      if (cond.Is(al)) {
19044        EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
19045                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19046                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19047        return;
19048      }
19049    }
19050  }
19051  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19052}
19053
19054void Assembler::vmla(
19055    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
19056  VIXL_ASSERT(AllowAssembler());
19057  CheckIT(cond);
19058  Dt_size_10 encoded_dt(dt);
19059  if (IsUsingT32()) {
19060    // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
19061    if (dt.Is(F32)) {
19062      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19063        EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19064                   rm.Encode(5, 0));
19065        AdvanceIT();
19066        return;
19067      }
19068    }
19069    // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
19070    if (dt.Is(F64)) {
19071      EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19072                 rm.Encode(5, 0));
19073      AdvanceIT();
19074      return;
19075    }
19076    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
19077    if (encoded_dt.IsValid()) {
19078      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19079        EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) |
19080                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19081        AdvanceIT();
19082        return;
19083      }
19084    }
19085  } else {
19086    // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
19087    if (dt.Is(F32)) {
19088      if (cond.Is(al)) {
19089        EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19090                rm.Encode(5, 0));
19091        return;
19092      }
19093    }
19094    // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
19095    if (dt.Is(F64) && cond.IsNotNever()) {
19096      EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19097              rn.Encode(7, 16) | rm.Encode(5, 0));
19098      return;
19099    }
19100    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
19101    if (encoded_dt.IsValid()) {
19102      if (cond.Is(al)) {
19103        EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) |
19104                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19105        return;
19106      }
19107    }
19108  }
19109  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19110}
19111
19112void Assembler::vmla(
19113    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
19114  VIXL_ASSERT(AllowAssembler());
19115  CheckIT(cond);
19116  Dt_size_10 encoded_dt(dt);
19117  if (IsUsingT32()) {
19118    // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
19119    if (dt.Is(F32)) {
19120      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19121        EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19122                   rm.Encode(5, 0));
19123        AdvanceIT();
19124        return;
19125      }
19126    }
19127    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
19128    if (encoded_dt.IsValid()) {
19129      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19130        EmitT32_32(0xef000940U | (encoded_dt.GetEncodingValue() << 20) |
19131                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19132        AdvanceIT();
19133        return;
19134      }
19135    }
19136  } else {
19137    // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
19138    if (dt.Is(F32)) {
19139      if (cond.Is(al)) {
19140        EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19141                rm.Encode(5, 0));
19142        return;
19143      }
19144    }
19145    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
19146    if (encoded_dt.IsValid()) {
19147      if (cond.Is(al)) {
19148        EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) |
19149                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19150        return;
19151      }
19152    }
19153  }
19154  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19155}
19156
19157void Assembler::vmla(
19158    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
19159  VIXL_ASSERT(AllowAssembler());
19160  CheckIT(cond);
19161  if (IsUsingT32()) {
19162    // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
19163    if (dt.Is(F32)) {
19164      EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19165                 rm.Encode(5, 0));
19166      AdvanceIT();
19167      return;
19168    }
19169  } else {
19170    // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
19171    if (dt.Is(F32) && cond.IsNotNever()) {
19172      EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19173              rn.Encode(7, 16) | rm.Encode(5, 0));
19174      return;
19175    }
19176  }
19177  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19178}
19179
19180void Assembler::vmlal(
19181    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
19182  VIXL_ASSERT(AllowAssembler());
19183  CheckIT(cond);
19184  Dt_size_11 encoded_dt(dt);
19185  if (IsUsingT32()) {
19186    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
19187    if (encoded_dt.IsValid() &&
19188        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19189         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19190          (rm.GetLane() <= 1)))) {
19191      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19192        EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) |
19193                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19194                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19195        AdvanceIT();
19196        return;
19197      }
19198    }
19199  } else {
19200    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
19201    if (encoded_dt.IsValid() &&
19202        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19203         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19204          (rm.GetLane() <= 1)))) {
19205      if (cond.Is(al)) {
19206        EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) |
19207                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19208                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19209        return;
19210      }
19211    }
19212  }
19213  Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
19214}
19215
19216void Assembler::vmlal(
19217    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
19218  VIXL_ASSERT(AllowAssembler());
19219  CheckIT(cond);
19220  Dt_size_12 encoded_dt(dt);
19221  if (IsUsingT32()) {
19222    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
19223    if (encoded_dt.IsValid()) {
19224      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19225        EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) |
19226                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19227                   rn.Encode(7, 16) | rm.Encode(5, 0));
19228        AdvanceIT();
19229        return;
19230      }
19231    }
19232  } else {
19233    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
19234    if (encoded_dt.IsValid()) {
19235      if (cond.Is(al)) {
19236        EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) |
19237                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19238                rn.Encode(7, 16) | rm.Encode(5, 0));
19239        return;
19240      }
19241    }
19242  }
19243  Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
19244}
19245
19246void Assembler::vmls(
19247    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
19248  VIXL_ASSERT(AllowAssembler());
19249  CheckIT(cond);
19250  Dt_size_9 encoded_dt(dt);
19251  if (IsUsingT32()) {
19252    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
19253    if (encoded_dt.IsValid() &&
19254        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19255         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19256          (rm.GetLane() <= 1)))) {
19257      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19258        EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19259                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19260                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19261        AdvanceIT();
19262        return;
19263      }
19264    }
19265  } else {
19266    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
19267    if (encoded_dt.IsValid() &&
19268        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19269         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19270          (rm.GetLane() <= 1)))) {
19271      if (cond.Is(al)) {
19272        EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19273                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19274                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19275        return;
19276      }
19277    }
19278  }
19279  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19280}
19281
19282void Assembler::vmls(
19283    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
19284  VIXL_ASSERT(AllowAssembler());
19285  CheckIT(cond);
19286  Dt_size_9 encoded_dt(dt);
19287  if (IsUsingT32()) {
19288    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
19289    if (encoded_dt.IsValid() &&
19290        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19291         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19292          (rm.GetLane() <= 1)))) {
19293      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19294        EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19295                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19296                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19297        AdvanceIT();
19298        return;
19299      }
19300    }
19301  } else {
19302    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
19303    if (encoded_dt.IsValid() &&
19304        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19305         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19306          (rm.GetLane() <= 1)))) {
19307      if (cond.Is(al)) {
19308        EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19309                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19310                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19311        return;
19312      }
19313    }
19314  }
19315  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19316}
19317
19318void Assembler::vmls(
19319    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
19320  VIXL_ASSERT(AllowAssembler());
19321  CheckIT(cond);
19322  Dt_size_10 encoded_dt(dt);
19323  if (IsUsingT32()) {
19324    // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
19325    if (dt.Is(F32)) {
19326      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19327        EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19328                   rm.Encode(5, 0));
19329        AdvanceIT();
19330        return;
19331      }
19332    }
19333    // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
19334    if (dt.Is(F64)) {
19335      EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19336                 rm.Encode(5, 0));
19337      AdvanceIT();
19338      return;
19339    }
19340    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
19341    if (encoded_dt.IsValid()) {
19342      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19343        EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) |
19344                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19345        AdvanceIT();
19346        return;
19347      }
19348    }
19349  } else {
19350    // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
19351    if (dt.Is(F32)) {
19352      if (cond.Is(al)) {
19353        EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19354                rm.Encode(5, 0));
19355        return;
19356      }
19357    }
19358    // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
19359    if (dt.Is(F64) && cond.IsNotNever()) {
19360      EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19361              rn.Encode(7, 16) | rm.Encode(5, 0));
19362      return;
19363    }
19364    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
19365    if (encoded_dt.IsValid()) {
19366      if (cond.Is(al)) {
19367        EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) |
19368                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19369        return;
19370      }
19371    }
19372  }
19373  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19374}
19375
19376void Assembler::vmls(
19377    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
19378  VIXL_ASSERT(AllowAssembler());
19379  CheckIT(cond);
19380  Dt_size_10 encoded_dt(dt);
19381  if (IsUsingT32()) {
19382    // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
19383    if (dt.Is(F32)) {
19384      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19385        EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19386                   rm.Encode(5, 0));
19387        AdvanceIT();
19388        return;
19389      }
19390    }
19391    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
19392    if (encoded_dt.IsValid()) {
19393      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19394        EmitT32_32(0xff000940U | (encoded_dt.GetEncodingValue() << 20) |
19395                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19396        AdvanceIT();
19397        return;
19398      }
19399    }
19400  } else {
19401    // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
19402    if (dt.Is(F32)) {
19403      if (cond.Is(al)) {
19404        EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19405                rm.Encode(5, 0));
19406        return;
19407      }
19408    }
19409    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
19410    if (encoded_dt.IsValid()) {
19411      if (cond.Is(al)) {
19412        EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) |
19413                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19414        return;
19415      }
19416    }
19417  }
19418  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19419}
19420
19421void Assembler::vmls(
19422    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
19423  VIXL_ASSERT(AllowAssembler());
19424  CheckIT(cond);
19425  if (IsUsingT32()) {
19426    // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
19427    if (dt.Is(F32)) {
19428      EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19429                 rm.Encode(5, 0));
19430      AdvanceIT();
19431      return;
19432    }
19433  } else {
19434    // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
19435    if (dt.Is(F32) && cond.IsNotNever()) {
19436      EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19437              rn.Encode(7, 16) | rm.Encode(5, 0));
19438      return;
19439    }
19440  }
19441  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19442}
19443
19444void Assembler::vmlsl(
19445    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
19446  VIXL_ASSERT(AllowAssembler());
19447  CheckIT(cond);
19448  Dt_size_11 encoded_dt(dt);
19449  if (IsUsingT32()) {
19450    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
19451    if (encoded_dt.IsValid() &&
19452        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19453         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19454          (rm.GetLane() <= 1)))) {
19455      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19456        EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) |
19457                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19458                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19459        AdvanceIT();
19460        return;
19461      }
19462    }
19463  } else {
19464    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
19465    if (encoded_dt.IsValid() &&
19466        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19467         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19468          (rm.GetLane() <= 1)))) {
19469      if (cond.Is(al)) {
19470        EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) |
19471                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19472                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19473        return;
19474      }
19475    }
19476  }
19477  Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
19478}
19479
19480void Assembler::vmlsl(
19481    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
19482  VIXL_ASSERT(AllowAssembler());
19483  CheckIT(cond);
19484  Dt_size_12 encoded_dt(dt);
19485  if (IsUsingT32()) {
19486    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
19487    if (encoded_dt.IsValid()) {
19488      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19489        EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) |
19490                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19491                   rn.Encode(7, 16) | rm.Encode(5, 0));
19492        AdvanceIT();
19493        return;
19494      }
19495    }
19496  } else {
19497    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
19498    if (encoded_dt.IsValid()) {
19499      if (cond.Is(al)) {
19500        EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) |
19501                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19502                rn.Encode(7, 16) | rm.Encode(5, 0));
19503        return;
19504      }
19505    }
19506  }
19507  Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
19508}
19509
19510void Assembler::vmov(Condition cond, Register rt, SRegister rn) {
19511  VIXL_ASSERT(AllowAssembler());
19512  CheckIT(cond);
19513  if (IsUsingT32()) {
19514    // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1
19515    EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16));
19516    AdvanceIT();
19517    return;
19518  } else {
19519    // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1
19520    if (cond.IsNotNever()) {
19521      EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19522              rn.Encode(7, 16));
19523      return;
19524    }
19525  }
19526  Delegate(kVmov, &Assembler::vmov, cond, rt, rn);
19527}
19528
19529void Assembler::vmov(Condition cond, SRegister rn, Register rt) {
19530  VIXL_ASSERT(AllowAssembler());
19531  CheckIT(cond);
19532  if (IsUsingT32()) {
19533    // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1
19534    EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12));
19535    AdvanceIT();
19536    return;
19537  } else {
19538    // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1
19539    if (cond.IsNotNever()) {
19540      EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) |
19541              (rt.GetCode() << 12));
19542      return;
19543    }
19544  }
19545  Delegate(kVmov, &Assembler::vmov, cond, rn, rt);
19546}
19547
19548void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) {
19549  VIXL_ASSERT(AllowAssembler());
19550  CheckIT(cond);
19551  if (IsUsingT32()) {
19552    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1
19553    EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
19554               rm.Encode(5, 0));
19555    AdvanceIT();
19556    return;
19557  } else {
19558    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1
19559    if (cond.IsNotNever()) {
19560      EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19561              (rt2.GetCode() << 16) | rm.Encode(5, 0));
19562      return;
19563    }
19564  }
19565  Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm);
19566}
19567
19568void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) {
19569  VIXL_ASSERT(AllowAssembler());
19570  CheckIT(cond);
19571  if (IsUsingT32()) {
19572    // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1
19573    EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
19574               (rt2.GetCode() << 16));
19575    AdvanceIT();
19576    return;
19577  } else {
19578    // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1
19579    if (cond.IsNotNever()) {
19580      EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
19581              (rt.GetCode() << 12) | (rt2.GetCode() << 16));
19582      return;
19583    }
19584  }
19585  Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2);
19586}
19587
19588void Assembler::vmov(
19589    Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) {
19590  VIXL_ASSERT(AllowAssembler());
19591  CheckIT(cond);
19592  if (IsUsingT32()) {
19593    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1
19594    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) {
19595      EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
19596                 rm.Encode(5, 0));
19597      AdvanceIT();
19598      return;
19599    }
19600  } else {
19601    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1
19602    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
19603        cond.IsNotNever()) {
19604      EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19605              (rt2.GetCode() << 16) | rm.Encode(5, 0));
19606      return;
19607    }
19608  }
19609  Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1);
19610}
19611
19612void Assembler::vmov(
19613    Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) {
19614  VIXL_ASSERT(AllowAssembler());
19615  CheckIT(cond);
19616  if (IsUsingT32()) {
19617    // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1
19618    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) {
19619      EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
19620                 (rt2.GetCode() << 16));
19621      AdvanceIT();
19622      return;
19623    }
19624  } else {
19625    // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1
19626    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
19627        cond.IsNotNever()) {
19628      EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
19629              (rt.GetCode() << 12) | (rt2.GetCode() << 16));
19630      return;
19631    }
19632  }
19633  Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2);
19634}
19635
19636void Assembler::vmov(Condition cond,
19637                     DataType dt,
19638                     DRegisterLane rd,
19639                     Register rt) {
19640  VIXL_ASSERT(AllowAssembler());
19641  CheckIT(cond);
19642  Dt_opc1_opc2_1 encoded_dt(dt, rd);
19643  if (IsUsingT32()) {
19644    // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1
19645    if (encoded_dt.IsValid()) {
19646      EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19647                 ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19648                 rd.Encode(7, 16) | (rt.GetCode() << 12));
19649      AdvanceIT();
19650      return;
19651    }
19652  } else {
19653    // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1
19654    if (encoded_dt.IsValid() && cond.IsNotNever()) {
19655      EmitA32(0x0e000b10U | (cond.GetCondition() << 28) |
19656              ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19657              ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) |
19658              (rt.GetCode() << 12));
19659      return;
19660    }
19661  }
19662  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt);
19663}
19664
19665void Assembler::vmov(Condition cond,
19666                     DataType dt,
19667                     DRegister rd,
19668                     const DOperand& operand) {
19669  VIXL_ASSERT(AllowAssembler());
19670  CheckIT(cond);
19671  if (operand.IsImmediate()) {
19672    ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
19673    ImmediateVFP vfp(operand.GetNeonImmediate());
19674    if (IsUsingT32()) {
19675      // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
19676      if (encoded_dt.IsValid()) {
19677        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19678          EmitT32_32(
19679              0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19680              ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19681              rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19682              ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19683              ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
19684          AdvanceIT();
19685          return;
19686        }
19687      }
19688      // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2
19689      if (dt.Is(F64) && vfp.IsValid()) {
19690        EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) |
19691                   (vfp.GetEncodingValue() & 0xf) |
19692                   ((vfp.GetEncodingValue() & 0xf0) << 12));
19693        AdvanceIT();
19694        return;
19695      }
19696    } else {
19697      // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
19698      if (encoded_dt.IsValid()) {
19699        if (cond.Is(al)) {
19700          EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19701                  ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19702                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19703                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19704                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
19705          return;
19706        }
19707      }
19708      // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2
19709      if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) {
19710        EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19711                (vfp.GetEncodingValue() & 0xf) |
19712                ((vfp.GetEncodingValue() & 0xf0) << 12));
19713        return;
19714      }
19715    }
19716  }
19717  if (operand.IsRegister()) {
19718    DRegister rm = operand.GetRegister();
19719    if (IsUsingT32()) {
19720      // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
19721      if (dt.Is(F64)) {
19722        EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
19723        AdvanceIT();
19724        return;
19725      }
19726      // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
19727      if (!dt.Is(F64)) {
19728        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19729          EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19730                     rm.Encode(5, 0));
19731          AdvanceIT();
19732          return;
19733        }
19734      }
19735    } else {
19736      // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
19737      if (dt.Is(F64) && cond.IsNotNever()) {
19738        EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19739                rm.Encode(5, 0));
19740        return;
19741      }
19742      // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
19743      if (!dt.Is(F64)) {
19744        if (cond.Is(al)) {
19745          EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19746                  rm.Encode(5, 0));
19747          return;
19748        }
19749      }
19750    }
19751  }
19752  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19753}
19754
19755void Assembler::vmov(Condition cond,
19756                     DataType dt,
19757                     QRegister rd,
19758                     const QOperand& operand) {
19759  VIXL_ASSERT(AllowAssembler());
19760  CheckIT(cond);
19761  if (operand.IsImmediate()) {
19762    ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
19763    if (IsUsingT32()) {
19764      // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
19765      if (encoded_dt.IsValid()) {
19766        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19767          EmitT32_32(
19768              0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19769              ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19770              rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19771              ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19772              ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
19773          AdvanceIT();
19774          return;
19775        }
19776      }
19777    } else {
19778      // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
19779      if (encoded_dt.IsValid()) {
19780        if (cond.Is(al)) {
19781          EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19782                  ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19783                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19784                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19785                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
19786          return;
19787        }
19788      }
19789    }
19790  }
19791  if (operand.IsRegister()) {
19792    QRegister rm = operand.GetRegister();
19793    if (IsUsingT32()) {
19794      // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
19795      if (!dt.Is(F64)) {
19796        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19797          EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19798                     rm.Encode(5, 0));
19799          AdvanceIT();
19800          return;
19801        }
19802      }
19803    } else {
19804      // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
19805      if (!dt.Is(F64)) {
19806        if (cond.Is(al)) {
19807          EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19808                  rm.Encode(5, 0));
19809          return;
19810        }
19811      }
19812    }
19813  }
19814  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19815}
19816
19817void Assembler::vmov(Condition cond,
19818                     DataType dt,
19819                     SRegister rd,
19820                     const SOperand& operand) {
19821  VIXL_ASSERT(AllowAssembler());
19822  CheckIT(cond);
19823  if (operand.IsImmediate()) {
19824    ImmediateVFP vfp(operand.GetNeonImmediate());
19825    if (IsUsingT32()) {
19826      // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2
19827      if (dt.Is(F32) && vfp.IsValid()) {
19828        EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) |
19829                   (vfp.GetEncodingValue() & 0xf) |
19830                   ((vfp.GetEncodingValue() & 0xf0) << 12));
19831        AdvanceIT();
19832        return;
19833      }
19834    } else {
19835      // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2
19836      if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) {
19837        EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19838                (vfp.GetEncodingValue() & 0xf) |
19839                ((vfp.GetEncodingValue() & 0xf0) << 12));
19840        return;
19841      }
19842    }
19843  }
19844  if (operand.IsRegister()) {
19845    SRegister rm = operand.GetRegister();
19846    if (IsUsingT32()) {
19847      // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
19848      if (dt.Is(F32)) {
19849        EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
19850        AdvanceIT();
19851        return;
19852      }
19853    } else {
19854      // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
19855      if (dt.Is(F32) && cond.IsNotNever()) {
19856        EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19857                rm.Encode(5, 0));
19858        return;
19859      }
19860    }
19861  }
19862  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19863}
19864
19865void Assembler::vmov(Condition cond,
19866                     DataType dt,
19867                     Register rt,
19868                     DRegisterLane rn) {
19869  VIXL_ASSERT(AllowAssembler());
19870  CheckIT(cond);
19871  Dt_U_opc1_opc2_1 encoded_dt(dt, rn);
19872  if (IsUsingT32()) {
19873    // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1
19874    if (encoded_dt.IsValid()) {
19875      EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19876                 ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19877                 ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
19878                 (rt.GetCode() << 12) | rn.Encode(7, 16));
19879      AdvanceIT();
19880      return;
19881    }
19882  } else {
19883    // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1
19884    if (encoded_dt.IsValid() && cond.IsNotNever()) {
19885      EmitA32(0x0e100b10U | (cond.GetCondition() << 28) |
19886              ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19887              ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19888              ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
19889              (rt.GetCode() << 12) | rn.Encode(7, 16));
19890      return;
19891    }
19892  }
19893  Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn);
19894}
19895
19896void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) {
19897  VIXL_ASSERT(AllowAssembler());
19898  CheckIT(cond);
19899  Dt_U_imm3H_1 encoded_dt(dt);
19900  if (IsUsingT32()) {
19901    // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1
19902    if (encoded_dt.IsValid()) {
19903      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19904        EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
19905                   ((encoded_dt.GetEncodingValue() & 0x8) << 25) |
19906                   rd.Encode(22, 12) | rm.Encode(5, 0));
19907        AdvanceIT();
19908        return;
19909      }
19910    }
19911  } else {
19912    // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
19913    if (encoded_dt.IsValid()) {
19914      if (cond.Is(al)) {
19915        EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
19916                ((encoded_dt.GetEncodingValue() & 0x8) << 21) |
19917                rd.Encode(22, 12) | rm.Encode(5, 0));
19918        return;
19919      }
19920    }
19921  }
19922  Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm);
19923}
19924
19925void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) {
19926  VIXL_ASSERT(AllowAssembler());
19927  CheckIT(cond);
19928  Dt_size_3 encoded_dt(dt);
19929  if (IsUsingT32()) {
19930    // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
19931    if (encoded_dt.IsValid()) {
19932      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19933        EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) |
19934                   rd.Encode(22, 12) | rm.Encode(5, 0));
19935        AdvanceIT();
19936        return;
19937      }
19938    }
19939  } else {
19940    // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
19941    if (encoded_dt.IsValid()) {
19942      if (cond.Is(al)) {
19943        EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) |
19944                rd.Encode(22, 12) | rm.Encode(5, 0));
19945        return;
19946      }
19947    }
19948  }
19949  Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm);
19950}
19951
19952void Assembler::vmrs(Condition cond,
19953                     RegisterOrAPSR_nzcv rt,
19954                     SpecialFPRegister spec_reg) {
19955  VIXL_ASSERT(AllowAssembler());
19956  CheckIT(cond);
19957  if (IsUsingT32()) {
19958    // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1
19959    EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16));
19960    AdvanceIT();
19961    return;
19962  } else {
19963    // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1
19964    if (cond.IsNotNever()) {
19965      EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19966              (spec_reg.GetReg() << 16));
19967      return;
19968    }
19969  }
19970  Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg);
19971}
19972
19973void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) {
19974  VIXL_ASSERT(AllowAssembler());
19975  CheckIT(cond);
19976  if (IsUsingT32()) {
19977    // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1
19978    EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
19979    AdvanceIT();
19980    return;
19981  } else {
19982    // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1
19983    if (cond.IsNotNever()) {
19984      EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) |
19985              (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
19986      return;
19987    }
19988  }
19989  Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt);
19990}
19991
19992void Assembler::vmul(Condition cond,
19993                     DataType dt,
19994                     DRegister rd,
19995                     DRegister rn,
19996                     DRegister dm,
19997                     unsigned index) {
19998  VIXL_ASSERT(AllowAssembler());
19999  CheckIT(cond);
20000  Dt_F_size_3 encoded_dt(dt);
20001  if (IsUsingT32()) {
20002    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1
20003    if (encoded_dt.IsValid() &&
20004        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
20005         (!dt.Is(I16) && (index <= 1)))) {
20006      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20007        uint32_t shift = 4;
20008        if (dt.Is(I16)) {
20009          shift = 3;
20010        }
20011        uint32_t mvm = dm.GetCode() | index << shift;
20012        EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20013                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
20014                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20015                   ((mvm & 0x10) << 1));
20016        AdvanceIT();
20017        return;
20018      }
20019    }
20020  } else {
20021    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1
20022    if (encoded_dt.IsValid() &&
20023        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
20024         (!dt.Is(I16) && (index <= 1)))) {
20025      if (cond.Is(al)) {
20026        uint32_t shift = 4;
20027        if (dt.Is(I16)) {
20028          shift = 3;
20029        }
20030        uint32_t mvm = dm.GetCode() | index << shift;
20031        EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20032                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
20033                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20034                ((mvm & 0x10) << 1));
20035        return;
20036      }
20037    }
20038  }
20039  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
20040}
20041
20042void Assembler::vmul(Condition cond,
20043                     DataType dt,
20044                     QRegister rd,
20045                     QRegister rn,
20046                     DRegister dm,
20047                     unsigned index) {
20048  VIXL_ASSERT(AllowAssembler());
20049  CheckIT(cond);
20050  Dt_F_size_3 encoded_dt(dt);
20051  if (IsUsingT32()) {
20052    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1
20053    if (encoded_dt.IsValid() &&
20054        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
20055         (!dt.Is(I16) && (index <= 1)))) {
20056      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20057        uint32_t shift = 4;
20058        if (dt.Is(I16)) {
20059          shift = 3;
20060        }
20061        uint32_t mvm = dm.GetCode() | index << shift;
20062        EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20063                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
20064                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20065                   ((mvm & 0x10) << 1));
20066        AdvanceIT();
20067        return;
20068      }
20069    }
20070  } else {
20071    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1
20072    if (encoded_dt.IsValid() &&
20073        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
20074         (!dt.Is(I16) && (index <= 1)))) {
20075      if (cond.Is(al)) {
20076        uint32_t shift = 4;
20077        if (dt.Is(I16)) {
20078          shift = 3;
20079        }
20080        uint32_t mvm = dm.GetCode() | index << shift;
20081        EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20082                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
20083                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20084                ((mvm & 0x10) << 1));
20085        return;
20086      }
20087    }
20088  }
20089  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
20090}
20091
20092void Assembler::vmul(
20093    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20094  VIXL_ASSERT(AllowAssembler());
20095  CheckIT(cond);
20096  Dt_op_size_1 encoded_dt(dt);
20097  if (IsUsingT32()) {
20098    // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20099    if (dt.Is(F32)) {
20100      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20101        EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20102                   rm.Encode(5, 0));
20103        AdvanceIT();
20104        return;
20105      }
20106    }
20107    // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
20108    if (dt.Is(F64)) {
20109      EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20110                 rm.Encode(5, 0));
20111      AdvanceIT();
20112      return;
20113    }
20114    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20115    if (encoded_dt.IsValid()) {
20116      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20117        EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20118                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20119                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20120        AdvanceIT();
20121        return;
20122      }
20123    }
20124  } else {
20125    // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
20126    if (dt.Is(F32)) {
20127      if (cond.Is(al)) {
20128        EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20129                rm.Encode(5, 0));
20130        return;
20131      }
20132    }
20133    // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
20134    if (dt.Is(F64) && cond.IsNotNever()) {
20135      EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20136              rn.Encode(7, 16) | rm.Encode(5, 0));
20137      return;
20138    }
20139    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20140    if (encoded_dt.IsValid()) {
20141      if (cond.Is(al)) {
20142        EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20143                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20144                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20145        return;
20146      }
20147    }
20148  }
20149  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
20150}
20151
20152void Assembler::vmul(
20153    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20154  VIXL_ASSERT(AllowAssembler());
20155  CheckIT(cond);
20156  Dt_op_size_1 encoded_dt(dt);
20157  if (IsUsingT32()) {
20158    // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
20159    if (dt.Is(F32)) {
20160      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20161        EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20162                   rm.Encode(5, 0));
20163        AdvanceIT();
20164        return;
20165      }
20166    }
20167    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
20168    if (encoded_dt.IsValid()) {
20169      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20170        EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20171                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20172                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20173        AdvanceIT();
20174        return;
20175      }
20176    }
20177  } else {
20178    // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
20179    if (dt.Is(F32)) {
20180      if (cond.Is(al)) {
20181        EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20182                rm.Encode(5, 0));
20183        return;
20184      }
20185    }
20186    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
20187    if (encoded_dt.IsValid()) {
20188      if (cond.Is(al)) {
20189        EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20190                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20191                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20192        return;
20193      }
20194    }
20195  }
20196  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
20197}
20198
20199void Assembler::vmul(
20200    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20201  VIXL_ASSERT(AllowAssembler());
20202  CheckIT(cond);
20203  if (IsUsingT32()) {
20204    // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
20205    if (dt.Is(F32)) {
20206      EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20207                 rm.Encode(5, 0));
20208      AdvanceIT();
20209      return;
20210    }
20211  } else {
20212    // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
20213    if (dt.Is(F32) && cond.IsNotNever()) {
20214      EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20215              rn.Encode(7, 16) | rm.Encode(5, 0));
20216      return;
20217    }
20218  }
20219  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
20220}
20221
20222void Assembler::vmull(Condition cond,
20223                      DataType dt,
20224                      QRegister rd,
20225                      DRegister rn,
20226                      DRegister dm,
20227                      unsigned index) {
20228  VIXL_ASSERT(AllowAssembler());
20229  CheckIT(cond);
20230  Dt_U_size_2 encoded_dt(dt);
20231  if (IsUsingT32()) {
20232    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1
20233    if (encoded_dt.IsValid() &&
20234        (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
20235         (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) {
20236      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20237        uint32_t shift = 4;
20238        if (dt.Is(S16) || dt.Is(U16)) {
20239          shift = 3;
20240        }
20241        uint32_t mvm = dm.GetCode() | index << shift;
20242        EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20243                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20244                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20245                   ((mvm & 0x10) << 1));
20246        AdvanceIT();
20247        return;
20248      }
20249    }
20250  } else {
20251    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1
20252    if (encoded_dt.IsValid() &&
20253        (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
20254         (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) {
20255      if (cond.Is(al)) {
20256        uint32_t shift = 4;
20257        if (dt.Is(S16) || dt.Is(U16)) {
20258          shift = 3;
20259        }
20260        uint32_t mvm = dm.GetCode() | index << shift;
20261        EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20262                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20263                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20264                ((mvm & 0x10) << 1));
20265        return;
20266      }
20267    }
20268  }
20269  Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index);
20270}
20271
20272void Assembler::vmull(
20273    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
20274  VIXL_ASSERT(AllowAssembler());
20275  CheckIT(cond);
20276  Dt_op_U_size_1 encoded_dt(dt);
20277  if (IsUsingT32()) {
20278    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
20279    if (encoded_dt.IsValid()) {
20280      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20281        EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20282                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20283                   ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
20284                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20285        AdvanceIT();
20286        return;
20287      }
20288    }
20289  } else {
20290    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
20291    if (encoded_dt.IsValid()) {
20292      if (cond.Is(al)) {
20293        EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20294                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20295                ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
20296                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20297        return;
20298      }
20299    }
20300  }
20301  Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm);
20302}
20303
20304void Assembler::vmvn(Condition cond,
20305                     DataType dt,
20306                     DRegister rd,
20307                     const DOperand& operand) {
20308  VIXL_ASSERT(AllowAssembler());
20309  CheckIT(cond);
20310  if (operand.IsImmediate()) {
20311    ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
20312    if (IsUsingT32()) {
20313      // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
20314      if (encoded_dt.IsValid()) {
20315        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20316          EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
20317                     rd.Encode(22, 12) |
20318                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20319                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20320                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20321          AdvanceIT();
20322          return;
20323        }
20324      }
20325    } else {
20326      // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
20327      if (encoded_dt.IsValid()) {
20328        if (cond.Is(al)) {
20329          EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
20330                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20331                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20332                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20333          return;
20334        }
20335      }
20336    }
20337  }
20338  if (operand.IsRegister()) {
20339    DRegister rm = operand.GetRegister();
20340    USE(dt);
20341    if (IsUsingT32()) {
20342      // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
20343      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20344        EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
20345        AdvanceIT();
20346        return;
20347      }
20348    } else {
20349      // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
20350      if (cond.Is(al)) {
20351        EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
20352        return;
20353      }
20354    }
20355  }
20356  Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
20357}
20358
20359void Assembler::vmvn(Condition cond,
20360                     DataType dt,
20361                     QRegister rd,
20362                     const QOperand& operand) {
20363  VIXL_ASSERT(AllowAssembler());
20364  CheckIT(cond);
20365  if (operand.IsImmediate()) {
20366    ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
20367    if (IsUsingT32()) {
20368      // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
20369      if (encoded_dt.IsValid()) {
20370        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20371          EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
20372                     rd.Encode(22, 12) |
20373                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20374                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20375                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20376          AdvanceIT();
20377          return;
20378        }
20379      }
20380    } else {
20381      // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
20382      if (encoded_dt.IsValid()) {
20383        if (cond.Is(al)) {
20384          EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
20385                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20386                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20387                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20388          return;
20389        }
20390      }
20391    }
20392  }
20393  if (operand.IsRegister()) {
20394    QRegister rm = operand.GetRegister();
20395    USE(dt);
20396    if (IsUsingT32()) {
20397      // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
20398      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20399        EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
20400        AdvanceIT();
20401        return;
20402      }
20403    } else {
20404      // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
20405      if (cond.Is(al)) {
20406        EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
20407        return;
20408      }
20409    }
20410  }
20411  Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
20412}
20413
20414void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
20415  VIXL_ASSERT(AllowAssembler());
20416  CheckIT(cond);
20417  Dt_F_size_1 encoded_dt(dt);
20418  if (IsUsingT32()) {
20419    // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20420    if (encoded_dt.IsValid()) {
20421      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20422        EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20423                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20424                   rd.Encode(22, 12) | rm.Encode(5, 0));
20425        AdvanceIT();
20426        return;
20427      }
20428    }
20429    // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
20430    if (dt.Is(F64)) {
20431      EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
20432      AdvanceIT();
20433      return;
20434    }
20435  } else {
20436    // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
20437    if (encoded_dt.IsValid()) {
20438      if (cond.Is(al)) {
20439        EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20440                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20441                rd.Encode(22, 12) | rm.Encode(5, 0));
20442        return;
20443      }
20444    }
20445    // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
20446    if (dt.Is(F64) && cond.IsNotNever()) {
20447      EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20448              rm.Encode(5, 0));
20449      return;
20450    }
20451  }
20452  Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20453}
20454
20455void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
20456  VIXL_ASSERT(AllowAssembler());
20457  CheckIT(cond);
20458  Dt_F_size_1 encoded_dt(dt);
20459  if (IsUsingT32()) {
20460    // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
20461    if (encoded_dt.IsValid()) {
20462      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20463        EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20464                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20465                   rd.Encode(22, 12) | rm.Encode(5, 0));
20466        AdvanceIT();
20467        return;
20468      }
20469    }
20470  } else {
20471    // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
20472    if (encoded_dt.IsValid()) {
20473      if (cond.Is(al)) {
20474        EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20475                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20476                rd.Encode(22, 12) | rm.Encode(5, 0));
20477        return;
20478      }
20479    }
20480  }
20481  Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20482}
20483
20484void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) {
20485  VIXL_ASSERT(AllowAssembler());
20486  CheckIT(cond);
20487  if (IsUsingT32()) {
20488    // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
20489    if (dt.Is(F32)) {
20490      EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
20491      AdvanceIT();
20492      return;
20493    }
20494  } else {
20495    // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
20496    if (dt.Is(F32) && cond.IsNotNever()) {
20497      EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20498              rm.Encode(5, 0));
20499      return;
20500    }
20501  }
20502  Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20503}
20504
20505void Assembler::vnmla(
20506    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20507  VIXL_ASSERT(AllowAssembler());
20508  CheckIT(cond);
20509  if (IsUsingT32()) {
20510    // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
20511    if (dt.Is(F32)) {
20512      EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20513                 rm.Encode(5, 0));
20514      AdvanceIT();
20515      return;
20516    }
20517  } else {
20518    // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
20519    if (dt.Is(F32) && cond.IsNotNever()) {
20520      EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20521              rn.Encode(7, 16) | rm.Encode(5, 0));
20522      return;
20523    }
20524  }
20525  Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
20526}
20527
20528void Assembler::vnmla(
20529    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20530  VIXL_ASSERT(AllowAssembler());
20531  CheckIT(cond);
20532  if (IsUsingT32()) {
20533    // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
20534    if (dt.Is(F64)) {
20535      EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20536                 rm.Encode(5, 0));
20537      AdvanceIT();
20538      return;
20539    }
20540  } else {
20541    // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
20542    if (dt.Is(F64) && cond.IsNotNever()) {
20543      EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20544              rn.Encode(7, 16) | rm.Encode(5, 0));
20545      return;
20546    }
20547  }
20548  Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
20549}
20550
20551void Assembler::vnmls(
20552    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20553  VIXL_ASSERT(AllowAssembler());
20554  CheckIT(cond);
20555  if (IsUsingT32()) {
20556    // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
20557    if (dt.Is(F32)) {
20558      EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20559                 rm.Encode(5, 0));
20560      AdvanceIT();
20561      return;
20562    }
20563  } else {
20564    // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
20565    if (dt.Is(F32) && cond.IsNotNever()) {
20566      EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20567              rn.Encode(7, 16) | rm.Encode(5, 0));
20568      return;
20569    }
20570  }
20571  Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
20572}
20573
20574void Assembler::vnmls(
20575    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20576  VIXL_ASSERT(AllowAssembler());
20577  CheckIT(cond);
20578  if (IsUsingT32()) {
20579    // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
20580    if (dt.Is(F64)) {
20581      EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20582                 rm.Encode(5, 0));
20583      AdvanceIT();
20584      return;
20585    }
20586  } else {
20587    // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
20588    if (dt.Is(F64) && cond.IsNotNever()) {
20589      EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20590              rn.Encode(7, 16) | rm.Encode(5, 0));
20591      return;
20592    }
20593  }
20594  Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
20595}
20596
20597void Assembler::vnmul(
20598    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20599  VIXL_ASSERT(AllowAssembler());
20600  CheckIT(cond);
20601  if (IsUsingT32()) {
20602    // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
20603    if (dt.Is(F32)) {
20604      EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20605                 rm.Encode(5, 0));
20606      AdvanceIT();
20607      return;
20608    }
20609  } else {
20610    // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
20611    if (dt.Is(F32) && cond.IsNotNever()) {
20612      EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20613              rn.Encode(7, 16) | rm.Encode(5, 0));
20614      return;
20615    }
20616  }
20617  Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
20618}
20619
20620void Assembler::vnmul(
20621    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20622  VIXL_ASSERT(AllowAssembler());
20623  CheckIT(cond);
20624  if (IsUsingT32()) {
20625    // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
20626    if (dt.Is(F64)) {
20627      EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20628                 rm.Encode(5, 0));
20629      AdvanceIT();
20630      return;
20631    }
20632  } else {
20633    // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
20634    if (dt.Is(F64) && cond.IsNotNever()) {
20635      EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20636              rn.Encode(7, 16) | rm.Encode(5, 0));
20637      return;
20638    }
20639  }
20640  Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
20641}
20642
20643void Assembler::vorn(Condition cond,
20644                     DataType dt,
20645                     DRegister rd,
20646                     DRegister rn,
20647                     const DOperand& operand) {
20648  VIXL_ASSERT(AllowAssembler());
20649  CheckIT(cond);
20650  if (operand.IsImmediate()) {
20651    ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
20652    if (IsUsingT32()) {
20653      // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
20654      if (encoded_dt.IsValid() && rd.Is(rn)) {
20655        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20656          EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
20657                     rd.Encode(22, 12) |
20658                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20659                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20660                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20661          AdvanceIT();
20662          return;
20663        }
20664      }
20665    } else {
20666      // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
20667      if (encoded_dt.IsValid() && rd.Is(rn)) {
20668        if (cond.Is(al)) {
20669          EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
20670                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20671                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20672                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20673          return;
20674        }
20675      }
20676    }
20677  }
20678  if (operand.IsRegister()) {
20679    DRegister rm = operand.GetRegister();
20680    USE(dt);
20681    if (IsUsingT32()) {
20682      // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
20683      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20684        EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20685                   rm.Encode(5, 0));
20686        AdvanceIT();
20687        return;
20688      }
20689    } else {
20690      // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
20691      if (cond.Is(al)) {
20692        EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20693                rm.Encode(5, 0));
20694        return;
20695      }
20696    }
20697  }
20698  Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
20699}
20700
20701void Assembler::vorn(Condition cond,
20702                     DataType dt,
20703                     QRegister rd,
20704                     QRegister rn,
20705                     const QOperand& operand) {
20706  VIXL_ASSERT(AllowAssembler());
20707  CheckIT(cond);
20708  if (operand.IsImmediate()) {
20709    ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
20710    if (IsUsingT32()) {
20711      // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
20712      if (encoded_dt.IsValid() && rd.Is(rn)) {
20713        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20714          EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
20715                     rd.Encode(22, 12) |
20716                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20717                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20718                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20719          AdvanceIT();
20720          return;
20721        }
20722      }
20723    } else {
20724      // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
20725      if (encoded_dt.IsValid() && rd.Is(rn)) {
20726        if (cond.Is(al)) {
20727          EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
20728                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20729                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20730                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20731          return;
20732        }
20733      }
20734    }
20735  }
20736  if (operand.IsRegister()) {
20737    QRegister rm = operand.GetRegister();
20738    USE(dt);
20739    if (IsUsingT32()) {
20740      // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
20741      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20742        EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20743                   rm.Encode(5, 0));
20744        AdvanceIT();
20745        return;
20746      }
20747    } else {
20748      // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
20749      if (cond.Is(al)) {
20750        EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20751                rm.Encode(5, 0));
20752        return;
20753      }
20754    }
20755  }
20756  Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
20757}
20758
20759void Assembler::vorr(Condition cond,
20760                     DataType dt,
20761                     DRegister rd,
20762                     DRegister rn,
20763                     const DOperand& operand) {
20764  VIXL_ASSERT(AllowAssembler());
20765  CheckIT(cond);
20766  if (operand.IsRegister()) {
20767    DRegister rm = operand.GetRegister();
20768    USE(dt);
20769    if (IsUsingT32()) {
20770      // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
20771      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20772        EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20773                   rm.Encode(5, 0));
20774        AdvanceIT();
20775        return;
20776      }
20777    } else {
20778      // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
20779      if (cond.Is(al)) {
20780        EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20781                rm.Encode(5, 0));
20782        return;
20783      }
20784    }
20785  }
20786  if (operand.IsImmediate()) {
20787    ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
20788    if (IsUsingT32()) {
20789      // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
20790      if (encoded_dt.IsValid() && rd.Is(rn)) {
20791        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20792          EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
20793                     rd.Encode(22, 12) |
20794                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20795                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20796                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20797          AdvanceIT();
20798          return;
20799        }
20800      }
20801    } else {
20802      // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
20803      if (encoded_dt.IsValid() && rd.Is(rn)) {
20804        if (cond.Is(al)) {
20805          EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
20806                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20807                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20808                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20809          return;
20810        }
20811      }
20812    }
20813  }
20814  Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
20815}
20816
20817void Assembler::vorr(Condition cond,
20818                     DataType dt,
20819                     QRegister rd,
20820                     QRegister rn,
20821                     const QOperand& operand) {
20822  VIXL_ASSERT(AllowAssembler());
20823  CheckIT(cond);
20824  if (operand.IsRegister()) {
20825    QRegister rm = operand.GetRegister();
20826    USE(dt);
20827    if (IsUsingT32()) {
20828      // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
20829      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20830        EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20831                   rm.Encode(5, 0));
20832        AdvanceIT();
20833        return;
20834      }
20835    } else {
20836      // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
20837      if (cond.Is(al)) {
20838        EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20839                rm.Encode(5, 0));
20840        return;
20841      }
20842    }
20843  }
20844  if (operand.IsImmediate()) {
20845    ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
20846    if (IsUsingT32()) {
20847      // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
20848      if (encoded_dt.IsValid() && rd.Is(rn)) {
20849        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20850          EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
20851                     rd.Encode(22, 12) |
20852                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20853                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20854                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20855          AdvanceIT();
20856          return;
20857        }
20858      }
20859    } else {
20860      // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
20861      if (encoded_dt.IsValid() && rd.Is(rn)) {
20862        if (cond.Is(al)) {
20863          EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
20864                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20865                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20866                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20867          return;
20868        }
20869      }
20870    }
20871  }
20872  Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
20873}
20874
20875void Assembler::vpadal(Condition cond,
20876                       DataType dt,
20877                       DRegister rd,
20878                       DRegister rm) {
20879  VIXL_ASSERT(AllowAssembler());
20880  CheckIT(cond);
20881  Dt_op_size_2 encoded_dt(dt);
20882  if (IsUsingT32()) {
20883    // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20884    if (encoded_dt.IsValid()) {
20885      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20886        EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20887                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20888                   rd.Encode(22, 12) | rm.Encode(5, 0));
20889        AdvanceIT();
20890        return;
20891      }
20892    }
20893  } else {
20894    // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
20895    if (encoded_dt.IsValid()) {
20896      if (cond.Is(al)) {
20897        EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20898                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20899                rd.Encode(22, 12) | rm.Encode(5, 0));
20900        return;
20901      }
20902    }
20903  }
20904  Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
20905}
20906
20907void Assembler::vpadal(Condition cond,
20908                       DataType dt,
20909                       QRegister rd,
20910                       QRegister rm) {
20911  VIXL_ASSERT(AllowAssembler());
20912  CheckIT(cond);
20913  Dt_op_size_2 encoded_dt(dt);
20914  if (IsUsingT32()) {
20915    // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
20916    if (encoded_dt.IsValid()) {
20917      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20918        EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20919                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20920                   rd.Encode(22, 12) | rm.Encode(5, 0));
20921        AdvanceIT();
20922        return;
20923      }
20924    }
20925  } else {
20926    // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
20927    if (encoded_dt.IsValid()) {
20928      if (cond.Is(al)) {
20929        EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20930                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20931                rd.Encode(22, 12) | rm.Encode(5, 0));
20932        return;
20933      }
20934    }
20935  }
20936  Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
20937}
20938
20939void Assembler::vpadd(
20940    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20941  VIXL_ASSERT(AllowAssembler());
20942  CheckIT(cond);
20943  Dt_size_4 encoded_dt(dt);
20944  if (IsUsingT32()) {
20945    // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20946    if (dt.Is(F32)) {
20947      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20948        EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20949                   rm.Encode(5, 0));
20950        AdvanceIT();
20951        return;
20952      }
20953    }
20954    // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20955    if (encoded_dt.IsValid()) {
20956      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20957        EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) |
20958                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20959        AdvanceIT();
20960        return;
20961      }
20962    }
20963  } else {
20964    // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
20965    if (dt.Is(F32)) {
20966      if (cond.Is(al)) {
20967        EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20968                rm.Encode(5, 0));
20969        return;
20970      }
20971    }
20972    // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20973    if (encoded_dt.IsValid()) {
20974      if (cond.Is(al)) {
20975        EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) |
20976                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20977        return;
20978      }
20979    }
20980  }
20981  Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm);
20982}
20983
20984void Assembler::vpaddl(Condition cond,
20985                       DataType dt,
20986                       DRegister rd,
20987                       DRegister rm) {
20988  VIXL_ASSERT(AllowAssembler());
20989  CheckIT(cond);
20990  Dt_op_size_2 encoded_dt(dt);
20991  if (IsUsingT32()) {
20992    // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20993    if (encoded_dt.IsValid()) {
20994      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20995        EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20996                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20997                   rd.Encode(22, 12) | rm.Encode(5, 0));
20998        AdvanceIT();
20999        return;
21000      }
21001    }
21002  } else {
21003    // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
21004    if (encoded_dt.IsValid()) {
21005      if (cond.Is(al)) {
21006        EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21007                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
21008                rd.Encode(22, 12) | rm.Encode(5, 0));
21009        return;
21010      }
21011    }
21012  }
21013  Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
21014}
21015
21016void Assembler::vpaddl(Condition cond,
21017                       DataType dt,
21018                       QRegister rd,
21019                       QRegister rm) {
21020  VIXL_ASSERT(AllowAssembler());
21021  CheckIT(cond);
21022  Dt_op_size_2 encoded_dt(dt);
21023  if (IsUsingT32()) {
21024    // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
21025    if (encoded_dt.IsValid()) {
21026      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21027        EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21028                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
21029                   rd.Encode(22, 12) | rm.Encode(5, 0));
21030        AdvanceIT();
21031        return;
21032      }
21033    }
21034  } else {
21035    // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
21036    if (encoded_dt.IsValid()) {
21037      if (cond.Is(al)) {
21038        EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21039                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
21040                rd.Encode(22, 12) | rm.Encode(5, 0));
21041        return;
21042      }
21043    }
21044  }
21045  Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
21046}
21047
21048void Assembler::vpmax(
21049    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21050  VIXL_ASSERT(AllowAssembler());
21051  CheckIT(cond);
21052  Dt_U_size_1 encoded_dt(dt);
21053  if (IsUsingT32()) {
21054    // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
21055    if (dt.Is(F32)) {
21056      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21057        EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21058                   rm.Encode(5, 0));
21059        AdvanceIT();
21060        return;
21061      }
21062    }
21063    // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21064    if (encoded_dt.IsValid()) {
21065      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21066        EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21067                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21068                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21069        AdvanceIT();
21070        return;
21071      }
21072    }
21073  } else {
21074    // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
21075    if (dt.Is(F32)) {
21076      if (cond.Is(al)) {
21077        EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21078                rm.Encode(5, 0));
21079        return;
21080      }
21081    }
21082    // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21083    if (encoded_dt.IsValid()) {
21084      if (cond.Is(al)) {
21085        EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21086                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21087                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21088        return;
21089      }
21090    }
21091  }
21092  Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm);
21093}
21094
21095void Assembler::vpmin(
21096    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21097  VIXL_ASSERT(AllowAssembler());
21098  CheckIT(cond);
21099  Dt_U_size_1 encoded_dt(dt);
21100  if (IsUsingT32()) {
21101    // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
21102    if (dt.Is(F32)) {
21103      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21104        EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21105                   rm.Encode(5, 0));
21106        AdvanceIT();
21107        return;
21108      }
21109    }
21110    // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21111    if (encoded_dt.IsValid()) {
21112      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21113        EmitT32_32(0xef000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21114                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21115                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21116        AdvanceIT();
21117        return;
21118      }
21119    }
21120  } else {
21121    // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
21122    if (dt.Is(F32)) {
21123      if (cond.Is(al)) {
21124        EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21125                rm.Encode(5, 0));
21126        return;
21127      }
21128    }
21129    // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21130    if (encoded_dt.IsValid()) {
21131      if (cond.Is(al)) {
21132        EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21133                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21134                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21135        return;
21136      }
21137    }
21138  }
21139  Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm);
21140}
21141
21142void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) {
21143  VIXL_ASSERT(AllowAssembler());
21144  CheckIT(cond);
21145  USE(dt);
21146  if (IsUsingT32()) {
21147    // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1
21148    if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
21149      const DRegister& dreg = dreglist.GetFirstDRegister();
21150      unsigned len = dreglist.GetLength() * 2;
21151      EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff));
21152      AdvanceIT();
21153      return;
21154    }
21155  } else {
21156    // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1
21157    if (cond.IsNotNever() &&
21158        ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
21159      const DRegister& dreg = dreglist.GetFirstDRegister();
21160      unsigned len = dreglist.GetLength() * 2;
21161      EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
21162              (len & 0xff));
21163      return;
21164    }
21165  }
21166  Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist);
21167}
21168
21169void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) {
21170  VIXL_ASSERT(AllowAssembler());
21171  CheckIT(cond);
21172  USE(dt);
21173  if (IsUsingT32()) {
21174    // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2
21175    const SRegister& sreg = sreglist.GetFirstSRegister();
21176    unsigned len = sreglist.GetLength();
21177    EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff));
21178    AdvanceIT();
21179    return;
21180  } else {
21181    // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2
21182    if (cond.IsNotNever()) {
21183      const SRegister& sreg = sreglist.GetFirstSRegister();
21184      unsigned len = sreglist.GetLength();
21185      EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
21186              (len & 0xff));
21187      return;
21188    }
21189  }
21190  Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist);
21191}
21192
21193void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) {
21194  VIXL_ASSERT(AllowAssembler());
21195  CheckIT(cond);
21196  USE(dt);
21197  if (IsUsingT32()) {
21198    // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1
21199    if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
21200      const DRegister& dreg = dreglist.GetFirstDRegister();
21201      unsigned len = dreglist.GetLength() * 2;
21202      EmitT32_32(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff));
21203      AdvanceIT();
21204      return;
21205    }
21206  } else {
21207    // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1
21208    if (cond.IsNotNever() &&
21209        ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
21210      const DRegister& dreg = dreglist.GetFirstDRegister();
21211      unsigned len = dreglist.GetLength() * 2;
21212      EmitA32(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
21213              (len & 0xff));
21214      return;
21215    }
21216  }
21217  Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist);
21218}
21219
21220void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) {
21221  VIXL_ASSERT(AllowAssembler());
21222  CheckIT(cond);
21223  USE(dt);
21224  if (IsUsingT32()) {
21225    // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2
21226    const SRegister& sreg = sreglist.GetFirstSRegister();
21227    unsigned len = sreglist.GetLength();
21228    EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff));
21229    AdvanceIT();
21230    return;
21231  } else {
21232    // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2
21233    if (cond.IsNotNever()) {
21234      const SRegister& sreg = sreglist.GetFirstSRegister();
21235      unsigned len = sreglist.GetLength();
21236      EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
21237              (len & 0xff));
21238      return;
21239    }
21240  }
21241  Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist);
21242}
21243
21244void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
21245  VIXL_ASSERT(AllowAssembler());
21246  CheckIT(cond);
21247  Dt_size_5 encoded_dt(dt);
21248  if (IsUsingT32()) {
21249    // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
21250    if (encoded_dt.IsValid()) {
21251      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21252        EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) |
21253                   rd.Encode(22, 12) | rm.Encode(5, 0));
21254        AdvanceIT();
21255        return;
21256      }
21257    }
21258  } else {
21259    // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
21260    if (encoded_dt.IsValid()) {
21261      if (cond.Is(al)) {
21262        EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) |
21263                rd.Encode(22, 12) | rm.Encode(5, 0));
21264        return;
21265      }
21266    }
21267  }
21268  Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
21269}
21270
21271void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
21272  VIXL_ASSERT(AllowAssembler());
21273  CheckIT(cond);
21274  Dt_size_5 encoded_dt(dt);
21275  if (IsUsingT32()) {
21276    // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
21277    if (encoded_dt.IsValid()) {
21278      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21279        EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) |
21280                   rd.Encode(22, 12) | rm.Encode(5, 0));
21281        AdvanceIT();
21282        return;
21283      }
21284    }
21285  } else {
21286    // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
21287    if (encoded_dt.IsValid()) {
21288      if (cond.Is(al)) {
21289        EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) |
21290                rd.Encode(22, 12) | rm.Encode(5, 0));
21291        return;
21292      }
21293    }
21294  }
21295  Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
21296}
21297
21298void Assembler::vqadd(
21299    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21300  VIXL_ASSERT(AllowAssembler());
21301  CheckIT(cond);
21302  Dt_U_size_3 encoded_dt(dt);
21303  if (IsUsingT32()) {
21304    // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21305    if (encoded_dt.IsValid()) {
21306      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21307        EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21308                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21309                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21310        AdvanceIT();
21311        return;
21312      }
21313    }
21314  } else {
21315    // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21316    if (encoded_dt.IsValid()) {
21317      if (cond.Is(al)) {
21318        EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21319                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21320                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21321        return;
21322      }
21323    }
21324  }
21325  Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
21326}
21327
21328void Assembler::vqadd(
21329    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21330  VIXL_ASSERT(AllowAssembler());
21331  CheckIT(cond);
21332  Dt_U_size_3 encoded_dt(dt);
21333  if (IsUsingT32()) {
21334    // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21335    if (encoded_dt.IsValid()) {
21336      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21337        EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21338                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21339                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21340        AdvanceIT();
21341        return;
21342      }
21343    }
21344  } else {
21345    // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21346    if (encoded_dt.IsValid()) {
21347      if (cond.Is(al)) {
21348        EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21349                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21350                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21351        return;
21352      }
21353    }
21354  }
21355  Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
21356}
21357
21358void Assembler::vqdmlal(
21359    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21360  VIXL_ASSERT(AllowAssembler());
21361  CheckIT(cond);
21362  Dt_size_13 encoded_dt(dt);
21363  if (IsUsingT32()) {
21364    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21365    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21366      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21367        EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) |
21368                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21369        AdvanceIT();
21370        return;
21371      }
21372    }
21373  } else {
21374    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21375    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21376      if (cond.Is(al)) {
21377        EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) |
21378                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21379        return;
21380      }
21381    }
21382  }
21383  Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm);
21384}
21385
21386void Assembler::vqdmlal(Condition cond,
21387                        DataType dt,
21388                        QRegister rd,
21389                        DRegister rn,
21390                        DRegister dm,
21391                        unsigned index) {
21392  VIXL_ASSERT(AllowAssembler());
21393  CheckIT(cond);
21394  Dt_size_13 encoded_dt(dt);
21395  if (IsUsingT32()) {
21396    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
21397    if (encoded_dt.IsValid() &&
21398        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21399         (!dt.Is(S16) && (index <= 1))) &&
21400        (dt.Is(S16) || dt.Is(S32))) {
21401      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21402        uint32_t shift = 4;
21403        if (dt.Is(S16)) {
21404          shift = 3;
21405        }
21406        uint32_t mvm = dm.GetCode() | index << shift;
21407        EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) |
21408                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21409                   ((mvm & 0x10) << 1));
21410        AdvanceIT();
21411        return;
21412      }
21413    }
21414  } else {
21415    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
21416    if (encoded_dt.IsValid() &&
21417        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21418         (!dt.Is(S16) && (index <= 1))) &&
21419        (dt.Is(S16) || dt.Is(S32))) {
21420      if (cond.Is(al)) {
21421        uint32_t shift = 4;
21422        if (dt.Is(S16)) {
21423          shift = 3;
21424        }
21425        uint32_t mvm = dm.GetCode() | index << shift;
21426        EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) |
21427                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21428                ((mvm & 0x10) << 1));
21429        return;
21430      }
21431    }
21432  }
21433  Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index);
21434}
21435
21436void Assembler::vqdmlsl(
21437    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21438  VIXL_ASSERT(AllowAssembler());
21439  CheckIT(cond);
21440  Dt_size_13 encoded_dt(dt);
21441  if (IsUsingT32()) {
21442    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21443    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21444      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21445        EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) |
21446                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21447        AdvanceIT();
21448        return;
21449      }
21450    }
21451  } else {
21452    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21453    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21454      if (cond.Is(al)) {
21455        EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) |
21456                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21457        return;
21458      }
21459    }
21460  }
21461  Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm);
21462}
21463
21464void Assembler::vqdmlsl(Condition cond,
21465                        DataType dt,
21466                        QRegister rd,
21467                        DRegister rn,
21468                        DRegister dm,
21469                        unsigned index) {
21470  VIXL_ASSERT(AllowAssembler());
21471  CheckIT(cond);
21472  Dt_size_13 encoded_dt(dt);
21473  if (IsUsingT32()) {
21474    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
21475    if (encoded_dt.IsValid() &&
21476        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21477         (!dt.Is(S16) && (index <= 1))) &&
21478        (dt.Is(S16) || dt.Is(S32))) {
21479      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21480        uint32_t shift = 4;
21481        if (dt.Is(S16)) {
21482          shift = 3;
21483        }
21484        uint32_t mvm = dm.GetCode() | index << shift;
21485        EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) |
21486                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21487                   ((mvm & 0x10) << 1));
21488        AdvanceIT();
21489        return;
21490      }
21491    }
21492  } else {
21493    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
21494    if (encoded_dt.IsValid() &&
21495        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21496         (!dt.Is(S16) && (index <= 1))) &&
21497        (dt.Is(S16) || dt.Is(S32))) {
21498      if (cond.Is(al)) {
21499        uint32_t shift = 4;
21500        if (dt.Is(S16)) {
21501          shift = 3;
21502        }
21503        uint32_t mvm = dm.GetCode() | index << shift;
21504        EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) |
21505                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21506                ((mvm & 0x10) << 1));
21507        return;
21508      }
21509    }
21510  }
21511  Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index);
21512}
21513
21514void Assembler::vqdmulh(
21515    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21516  VIXL_ASSERT(AllowAssembler());
21517  CheckIT(cond);
21518  Dt_size_13 encoded_dt(dt);
21519  if (IsUsingT32()) {
21520    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21521    if (encoded_dt.IsValid()) {
21522      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21523        EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) |
21524                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21525        AdvanceIT();
21526        return;
21527      }
21528    }
21529  } else {
21530    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21531    if (encoded_dt.IsValid()) {
21532      if (cond.Is(al)) {
21533        EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) |
21534                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21535        return;
21536      }
21537    }
21538  }
21539  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21540}
21541
21542void Assembler::vqdmulh(
21543    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21544  VIXL_ASSERT(AllowAssembler());
21545  CheckIT(cond);
21546  Dt_size_13 encoded_dt(dt);
21547  if (IsUsingT32()) {
21548    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21549    if (encoded_dt.IsValid()) {
21550      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21551        EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) |
21552                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21553        AdvanceIT();
21554        return;
21555      }
21556    }
21557  } else {
21558    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21559    if (encoded_dt.IsValid()) {
21560      if (cond.Is(al)) {
21561        EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) |
21562                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21563        return;
21564      }
21565    }
21566  }
21567  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21568}
21569
21570void Assembler::vqdmulh(
21571    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
21572  VIXL_ASSERT(AllowAssembler());
21573  CheckIT(cond);
21574  Dt_size_13 encoded_dt(dt);
21575  if (IsUsingT32()) {
21576    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
21577    if (encoded_dt.IsValid() &&
21578        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21579         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21580          (rm.GetLane() <= 1))) &&
21581        (dt.Is(S16) || dt.Is(S32))) {
21582      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21583        EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) |
21584                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21585        AdvanceIT();
21586        return;
21587      }
21588    }
21589  } else {
21590    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
21591    if (encoded_dt.IsValid() &&
21592        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21593         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21594          (rm.GetLane() <= 1))) &&
21595        (dt.Is(S16) || dt.Is(S32))) {
21596      if (cond.Is(al)) {
21597        EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) |
21598                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21599        return;
21600      }
21601    }
21602  }
21603  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21604}
21605
21606void Assembler::vqdmulh(
21607    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
21608  VIXL_ASSERT(AllowAssembler());
21609  CheckIT(cond);
21610  Dt_size_13 encoded_dt(dt);
21611  if (IsUsingT32()) {
21612    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
21613    if (encoded_dt.IsValid() &&
21614        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21615         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21616          (rm.GetLane() <= 1))) &&
21617        (dt.Is(S16) || dt.Is(S32))) {
21618      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21619        EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) |
21620                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21621        AdvanceIT();
21622        return;
21623      }
21624    }
21625  } else {
21626    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
21627    if (encoded_dt.IsValid() &&
21628        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21629         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21630          (rm.GetLane() <= 1))) &&
21631        (dt.Is(S16) || dt.Is(S32))) {
21632      if (cond.Is(al)) {
21633        EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) |
21634                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21635        return;
21636      }
21637    }
21638  }
21639  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21640}
21641
21642void Assembler::vqdmull(
21643    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21644  VIXL_ASSERT(AllowAssembler());
21645  CheckIT(cond);
21646  Dt_size_13 encoded_dt(dt);
21647  if (IsUsingT32()) {
21648    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21649    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21650      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21651        EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) |
21652                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21653        AdvanceIT();
21654        return;
21655      }
21656    }
21657  } else {
21658    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21659    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21660      if (cond.Is(al)) {
21661        EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) |
21662                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21663        return;
21664      }
21665    }
21666  }
21667  Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
21668}
21669
21670void Assembler::vqdmull(
21671    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
21672  VIXL_ASSERT(AllowAssembler());
21673  CheckIT(cond);
21674  Dt_size_13 encoded_dt(dt);
21675  if (IsUsingT32()) {
21676    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2
21677    if (encoded_dt.IsValid() &&
21678        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21679         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21680          (rm.GetLane() <= 1))) &&
21681        (dt.Is(S16) || dt.Is(S32))) {
21682      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21683        EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) |
21684                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21685        AdvanceIT();
21686        return;
21687      }
21688    }
21689  } else {
21690    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2
21691    if (encoded_dt.IsValid() &&
21692        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21693         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21694          (rm.GetLane() <= 1))) &&
21695        (dt.Is(S16) || dt.Is(S32))) {
21696      if (cond.Is(al)) {
21697        EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) |
21698                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21699        return;
21700      }
21701    }
21702  }
21703  Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
21704}
21705
21706void Assembler::vqmovn(Condition cond,
21707                       DataType dt,
21708                       DRegister rd,
21709                       QRegister rm) {
21710  VIXL_ASSERT(AllowAssembler());
21711  CheckIT(cond);
21712  Dt_op_size_3 encoded_dt(dt);
21713  if (IsUsingT32()) {
21714    // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
21715    if (encoded_dt.IsValid()) {
21716      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21717        EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21718                   ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21719                   rd.Encode(22, 12) | rm.Encode(5, 0));
21720        AdvanceIT();
21721        return;
21722      }
21723    }
21724  } else {
21725    // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
21726    if (encoded_dt.IsValid()) {
21727      if (cond.Is(al)) {
21728        EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21729                ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21730                rd.Encode(22, 12) | rm.Encode(5, 0));
21731        return;
21732      }
21733    }
21734  }
21735  Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm);
21736}
21737
21738void Assembler::vqmovun(Condition cond,
21739                        DataType dt,
21740                        DRegister rd,
21741                        QRegister rm) {
21742  VIXL_ASSERT(AllowAssembler());
21743  CheckIT(cond);
21744  Dt_size_14 encoded_dt(dt);
21745  if (IsUsingT32()) {
21746    // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
21747    if (encoded_dt.IsValid()) {
21748      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21749        EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) |
21750                   rd.Encode(22, 12) | rm.Encode(5, 0));
21751        AdvanceIT();
21752        return;
21753      }
21754    }
21755  } else {
21756    // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
21757    if (encoded_dt.IsValid()) {
21758      if (cond.Is(al)) {
21759        EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) |
21760                rd.Encode(22, 12) | rm.Encode(5, 0));
21761        return;
21762      }
21763    }
21764  }
21765  Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm);
21766}
21767
21768void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
21769  VIXL_ASSERT(AllowAssembler());
21770  CheckIT(cond);
21771  Dt_size_5 encoded_dt(dt);
21772  if (IsUsingT32()) {
21773    // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
21774    if (encoded_dt.IsValid()) {
21775      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21776        EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) |
21777                   rd.Encode(22, 12) | rm.Encode(5, 0));
21778        AdvanceIT();
21779        return;
21780      }
21781    }
21782  } else {
21783    // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
21784    if (encoded_dt.IsValid()) {
21785      if (cond.Is(al)) {
21786        EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) |
21787                rd.Encode(22, 12) | rm.Encode(5, 0));
21788        return;
21789      }
21790    }
21791  }
21792  Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
21793}
21794
21795void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
21796  VIXL_ASSERT(AllowAssembler());
21797  CheckIT(cond);
21798  Dt_size_5 encoded_dt(dt);
21799  if (IsUsingT32()) {
21800    // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
21801    if (encoded_dt.IsValid()) {
21802      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21803        EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) |
21804                   rd.Encode(22, 12) | rm.Encode(5, 0));
21805        AdvanceIT();
21806        return;
21807      }
21808    }
21809  } else {
21810    // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
21811    if (encoded_dt.IsValid()) {
21812      if (cond.Is(al)) {
21813        EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) |
21814                rd.Encode(22, 12) | rm.Encode(5, 0));
21815        return;
21816      }
21817    }
21818  }
21819  Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
21820}
21821
21822void Assembler::vqrdmulh(
21823    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21824  VIXL_ASSERT(AllowAssembler());
21825  CheckIT(cond);
21826  Dt_size_13 encoded_dt(dt);
21827  if (IsUsingT32()) {
21828    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21829    if (encoded_dt.IsValid()) {
21830      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21831        EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) |
21832                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21833        AdvanceIT();
21834        return;
21835      }
21836    }
21837  } else {
21838    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21839    if (encoded_dt.IsValid()) {
21840      if (cond.Is(al)) {
21841        EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) |
21842                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21843        return;
21844      }
21845    }
21846  }
21847  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21848}
21849
21850void Assembler::vqrdmulh(
21851    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21852  VIXL_ASSERT(AllowAssembler());
21853  CheckIT(cond);
21854  Dt_size_13 encoded_dt(dt);
21855  if (IsUsingT32()) {
21856    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21857    if (encoded_dt.IsValid()) {
21858      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21859        EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) |
21860                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21861        AdvanceIT();
21862        return;
21863      }
21864    }
21865  } else {
21866    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21867    if (encoded_dt.IsValid()) {
21868      if (cond.Is(al)) {
21869        EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) |
21870                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21871        return;
21872      }
21873    }
21874  }
21875  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21876}
21877
21878void Assembler::vqrdmulh(
21879    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
21880  VIXL_ASSERT(AllowAssembler());
21881  CheckIT(cond);
21882  Dt_size_13 encoded_dt(dt);
21883  if (IsUsingT32()) {
21884    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
21885    if (encoded_dt.IsValid() &&
21886        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21887         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21888          (rm.GetLane() <= 1))) &&
21889        (dt.Is(S16) || dt.Is(S32))) {
21890      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21891        EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) |
21892                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21893        AdvanceIT();
21894        return;
21895      }
21896    }
21897  } else {
21898    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
21899    if (encoded_dt.IsValid() &&
21900        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21901         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21902          (rm.GetLane() <= 1))) &&
21903        (dt.Is(S16) || dt.Is(S32))) {
21904      if (cond.Is(al)) {
21905        EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) |
21906                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21907        return;
21908      }
21909    }
21910  }
21911  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21912}
21913
21914void Assembler::vqrdmulh(
21915    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
21916  VIXL_ASSERT(AllowAssembler());
21917  CheckIT(cond);
21918  Dt_size_13 encoded_dt(dt);
21919  if (IsUsingT32()) {
21920    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
21921    if (encoded_dt.IsValid() &&
21922        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21923         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21924          (rm.GetLane() <= 1))) &&
21925        (dt.Is(S16) || dt.Is(S32))) {
21926      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21927        EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) |
21928                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21929        AdvanceIT();
21930        return;
21931      }
21932    }
21933  } else {
21934    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
21935    if (encoded_dt.IsValid() &&
21936        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21937         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21938          (rm.GetLane() <= 1))) &&
21939        (dt.Is(S16) || dt.Is(S32))) {
21940      if (cond.Is(al)) {
21941        EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) |
21942                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21943        return;
21944      }
21945    }
21946  }
21947  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21948}
21949
21950void Assembler::vqrshl(
21951    Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
21952  VIXL_ASSERT(AllowAssembler());
21953  CheckIT(cond);
21954  Dt_U_size_3 encoded_dt(dt);
21955  if (IsUsingT32()) {
21956    // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
21957    if (encoded_dt.IsValid()) {
21958      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21959        EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21960                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21961                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21962        AdvanceIT();
21963        return;
21964      }
21965    }
21966  } else {
21967    // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
21968    if (encoded_dt.IsValid()) {
21969      if (cond.Is(al)) {
21970        EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21971                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21972                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21973        return;
21974      }
21975    }
21976  }
21977  Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
21978}
21979
21980void Assembler::vqrshl(
21981    Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
21982  VIXL_ASSERT(AllowAssembler());
21983  CheckIT(cond);
21984  Dt_U_size_3 encoded_dt(dt);
21985  if (IsUsingT32()) {
21986    // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
21987    if (encoded_dt.IsValid()) {
21988      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21989        EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21990                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21991                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21992        AdvanceIT();
21993        return;
21994      }
21995    }
21996  } else {
21997    // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
21998    if (encoded_dt.IsValid()) {
21999      if (cond.Is(al)) {
22000        EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22001                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22002                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22003        return;
22004      }
22005    }
22006  }
22007  Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
22008}
22009
22010void Assembler::vqrshrn(Condition cond,
22011                        DataType dt,
22012                        DRegister rd,
22013                        QRegister rm,
22014                        const QOperand& operand) {
22015  VIXL_ASSERT(AllowAssembler());
22016  CheckIT(cond);
22017  if (operand.IsImmediate()) {
22018    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22019      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22020      Dt_op_size_3 encoded_dt(dt);
22021      Dt_imm6_1 encoded_dt_2(dt);
22022      if (IsUsingT32()) {
22023        // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
22024        if (encoded_dt.IsValid() && (imm == 0)) {
22025          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22026            EmitT32_32(0xffb20280U |
22027                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22028                       ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22029                       rd.Encode(22, 12) | rm.Encode(5, 0));
22030            AdvanceIT();
22031            return;
22032          }
22033        }
22034        // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
22035        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22036          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22037            uint32_t imm6 = dt.GetSize() / 2 - imm;
22038            EmitT32_32(0xef800950U |
22039                       (encoded_dt_2.GetTypeEncodingValue() << 28) |
22040                       ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
22041                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22042            AdvanceIT();
22043            return;
22044          }
22045        }
22046      } else {
22047        // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
22048        if (encoded_dt.IsValid() && (imm == 0)) {
22049          if (cond.Is(al)) {
22050            EmitA32(0xf3b20280U |
22051                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22052                    ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22053                    rd.Encode(22, 12) | rm.Encode(5, 0));
22054            return;
22055          }
22056        }
22057        // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
22058        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22059          if (cond.Is(al)) {
22060            uint32_t imm6 = dt.GetSize() / 2 - imm;
22061            EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
22062                    ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
22063                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22064            return;
22065          }
22066        }
22067      }
22068    }
22069  }
22070  Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand);
22071}
22072
22073void Assembler::vqrshrun(Condition cond,
22074                         DataType dt,
22075                         DRegister rd,
22076                         QRegister rm,
22077                         const QOperand& operand) {
22078  VIXL_ASSERT(AllowAssembler());
22079  CheckIT(cond);
22080  if (operand.IsImmediate()) {
22081    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22082      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22083      Dt_imm6_2 encoded_dt(dt);
22084      Dt_size_14 encoded_dt_2(dt);
22085      if (IsUsingT32()) {
22086        // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
22087        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22088          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22089            uint32_t imm6 = dt.GetSize() / 2 - imm;
22090            EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) |
22091                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22092                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22093            AdvanceIT();
22094            return;
22095          }
22096        }
22097        // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
22098        if (encoded_dt_2.IsValid() && (imm == 0)) {
22099          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22100            EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22101                       rd.Encode(22, 12) | rm.Encode(5, 0));
22102            AdvanceIT();
22103            return;
22104          }
22105        }
22106      } else {
22107        // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
22108        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22109          if (cond.Is(al)) {
22110            uint32_t imm6 = dt.GetSize() / 2 - imm;
22111            EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) |
22112                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22113                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22114            return;
22115          }
22116        }
22117        // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
22118        if (encoded_dt_2.IsValid() && (imm == 0)) {
22119          if (cond.Is(al)) {
22120            EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22121                    rd.Encode(22, 12) | rm.Encode(5, 0));
22122            return;
22123          }
22124        }
22125      }
22126    }
22127  }
22128  Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand);
22129}
22130
22131void Assembler::vqshl(Condition cond,
22132                      DataType dt,
22133                      DRegister rd,
22134                      DRegister rm,
22135                      const DOperand& operand) {
22136  VIXL_ASSERT(AllowAssembler());
22137  CheckIT(cond);
22138  if (operand.IsRegister()) {
22139    DRegister rn = operand.GetRegister();
22140    Dt_U_size_3 encoded_dt(dt);
22141    if (IsUsingT32()) {
22142      // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
22143      if (encoded_dt.IsValid()) {
22144        if (cond.Is(al) || AllowStronglyDiscouraged()) {
22145          EmitT32_32(0xef000410U |
22146                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22147                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22148                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22149          AdvanceIT();
22150          return;
22151        }
22152      }
22153    } else {
22154      // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
22155      if (encoded_dt.IsValid()) {
22156        if (cond.Is(al)) {
22157          EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22158                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22159                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22160          return;
22161        }
22162      }
22163    }
22164  }
22165  if (operand.IsImmediate()) {
22166    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22167      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22168      Dt_L_imm6_1 encoded_dt(dt);
22169      if (IsUsingT32()) {
22170        // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
22171        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22172          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22173            uint32_t imm6 = imm;
22174            EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) |
22175                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22176                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22177                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22178            AdvanceIT();
22179            return;
22180          }
22181        }
22182      } else {
22183        // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
22184        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22185          if (cond.Is(al)) {
22186            uint32_t imm6 = imm;
22187            EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) |
22188                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22189                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22190                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22191            return;
22192          }
22193        }
22194      }
22195    }
22196  }
22197  Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
22198}
22199
22200void Assembler::vqshl(Condition cond,
22201                      DataType dt,
22202                      QRegister rd,
22203                      QRegister rm,
22204                      const QOperand& operand) {
22205  VIXL_ASSERT(AllowAssembler());
22206  CheckIT(cond);
22207  if (operand.IsRegister()) {
22208    QRegister rn = operand.GetRegister();
22209    Dt_U_size_3 encoded_dt(dt);
22210    if (IsUsingT32()) {
22211      // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
22212      if (encoded_dt.IsValid()) {
22213        if (cond.Is(al) || AllowStronglyDiscouraged()) {
22214          EmitT32_32(0xef000450U |
22215                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22216                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22217                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22218          AdvanceIT();
22219          return;
22220        }
22221      }
22222    } else {
22223      // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
22224      if (encoded_dt.IsValid()) {
22225        if (cond.Is(al)) {
22226          EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22227                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22228                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22229          return;
22230        }
22231      }
22232    }
22233  }
22234  if (operand.IsImmediate()) {
22235    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22236      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22237      Dt_L_imm6_1 encoded_dt(dt);
22238      if (IsUsingT32()) {
22239        // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
22240        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22241          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22242            uint32_t imm6 = imm;
22243            EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) |
22244                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22245                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22246                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22247            AdvanceIT();
22248            return;
22249          }
22250        }
22251      } else {
22252        // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
22253        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22254          if (cond.Is(al)) {
22255            uint32_t imm6 = imm;
22256            EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) |
22257                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22258                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22259                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22260            return;
22261          }
22262        }
22263      }
22264    }
22265  }
22266  Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
22267}
22268
22269void Assembler::vqshlu(Condition cond,
22270                       DataType dt,
22271                       DRegister rd,
22272                       DRegister rm,
22273                       const DOperand& operand) {
22274  VIXL_ASSERT(AllowAssembler());
22275  CheckIT(cond);
22276  if (operand.IsImmediate()) {
22277    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22278      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22279      Dt_L_imm6_2 encoded_dt(dt);
22280      if (IsUsingT32()) {
22281        // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
22282        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22283          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22284            uint32_t imm6 = imm;
22285            EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) |
22286                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22287                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22288                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22289            AdvanceIT();
22290            return;
22291          }
22292        }
22293      } else {
22294        // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
22295        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22296          if (cond.Is(al)) {
22297            uint32_t imm6 = imm;
22298            EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) |
22299                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22300                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22301                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22302            return;
22303          }
22304        }
22305      }
22306    }
22307  }
22308  Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
22309}
22310
22311void Assembler::vqshlu(Condition cond,
22312                       DataType dt,
22313                       QRegister rd,
22314                       QRegister rm,
22315                       const QOperand& operand) {
22316  VIXL_ASSERT(AllowAssembler());
22317  CheckIT(cond);
22318  if (operand.IsImmediate()) {
22319    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22320      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22321      Dt_L_imm6_2 encoded_dt(dt);
22322      if (IsUsingT32()) {
22323        // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
22324        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22325          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22326            uint32_t imm6 = imm;
22327            EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) |
22328                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22329                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22330                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22331            AdvanceIT();
22332            return;
22333          }
22334        }
22335      } else {
22336        // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
22337        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22338          if (cond.Is(al)) {
22339            uint32_t imm6 = imm;
22340            EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) |
22341                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22342                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22343                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22344            return;
22345          }
22346        }
22347      }
22348    }
22349  }
22350  Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
22351}
22352
22353void Assembler::vqshrn(Condition cond,
22354                       DataType dt,
22355                       DRegister rd,
22356                       QRegister rm,
22357                       const QOperand& operand) {
22358  VIXL_ASSERT(AllowAssembler());
22359  CheckIT(cond);
22360  if (operand.IsImmediate()) {
22361    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22362      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22363      Dt_op_size_3 encoded_dt(dt);
22364      Dt_imm6_1 encoded_dt_2(dt);
22365      if (IsUsingT32()) {
22366        // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
22367        if (encoded_dt.IsValid() && (imm == 0)) {
22368          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22369            EmitT32_32(0xffb20280U |
22370                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22371                       ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22372                       rd.Encode(22, 12) | rm.Encode(5, 0));
22373            AdvanceIT();
22374            return;
22375          }
22376        }
22377        // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
22378        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22379          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22380            uint32_t imm6 = dt.GetSize() / 2 - imm;
22381            EmitT32_32(0xef800910U |
22382                       (encoded_dt_2.GetTypeEncodingValue() << 28) |
22383                       ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
22384                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22385            AdvanceIT();
22386            return;
22387          }
22388        }
22389      } else {
22390        // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
22391        if (encoded_dt.IsValid() && (imm == 0)) {
22392          if (cond.Is(al)) {
22393            EmitA32(0xf3b20280U |
22394                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22395                    ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22396                    rd.Encode(22, 12) | rm.Encode(5, 0));
22397            return;
22398          }
22399        }
22400        // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
22401        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22402          if (cond.Is(al)) {
22403            uint32_t imm6 = dt.GetSize() / 2 - imm;
22404            EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
22405                    ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
22406                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22407            return;
22408          }
22409        }
22410      }
22411    }
22412  }
22413  Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand);
22414}
22415
22416void Assembler::vqshrun(Condition cond,
22417                        DataType dt,
22418                        DRegister rd,
22419                        QRegister rm,
22420                        const QOperand& operand) {
22421  VIXL_ASSERT(AllowAssembler());
22422  CheckIT(cond);
22423  if (operand.IsImmediate()) {
22424    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22425      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22426      Dt_imm6_2 encoded_dt(dt);
22427      Dt_size_14 encoded_dt_2(dt);
22428      if (IsUsingT32()) {
22429        // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
22430        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22431          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22432            uint32_t imm6 = dt.GetSize() / 2 - imm;
22433            EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) |
22434                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22435                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22436            AdvanceIT();
22437            return;
22438          }
22439        }
22440        // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
22441        if (encoded_dt_2.IsValid() && (imm == 0)) {
22442          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22443            EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22444                       rd.Encode(22, 12) | rm.Encode(5, 0));
22445            AdvanceIT();
22446            return;
22447          }
22448        }
22449      } else {
22450        // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
22451        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22452          if (cond.Is(al)) {
22453            uint32_t imm6 = dt.GetSize() / 2 - imm;
22454            EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) |
22455                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22456                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22457            return;
22458          }
22459        }
22460        // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
22461        if (encoded_dt_2.IsValid() && (imm == 0)) {
22462          if (cond.Is(al)) {
22463            EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22464                    rd.Encode(22, 12) | rm.Encode(5, 0));
22465            return;
22466          }
22467        }
22468      }
22469    }
22470  }
22471  Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand);
22472}
22473
22474void Assembler::vqsub(
22475    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22476  VIXL_ASSERT(AllowAssembler());
22477  CheckIT(cond);
22478  Dt_U_size_3 encoded_dt(dt);
22479  if (IsUsingT32()) {
22480    // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22481    if (encoded_dt.IsValid()) {
22482      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22483        EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22484                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22485                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22486        AdvanceIT();
22487        return;
22488      }
22489    }
22490  } else {
22491    // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22492    if (encoded_dt.IsValid()) {
22493      if (cond.Is(al)) {
22494        EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22495                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22496                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22497        return;
22498      }
22499    }
22500  }
22501  Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
22502}
22503
22504void Assembler::vqsub(
22505    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22506  VIXL_ASSERT(AllowAssembler());
22507  CheckIT(cond);
22508  Dt_U_size_3 encoded_dt(dt);
22509  if (IsUsingT32()) {
22510    // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22511    if (encoded_dt.IsValid()) {
22512      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22513        EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22514                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22515                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22516        AdvanceIT();
22517        return;
22518      }
22519    }
22520  } else {
22521    // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22522    if (encoded_dt.IsValid()) {
22523      if (cond.Is(al)) {
22524        EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22525                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22526                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22527        return;
22528      }
22529    }
22530  }
22531  Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
22532}
22533
22534void Assembler::vraddhn(
22535    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
22536  VIXL_ASSERT(AllowAssembler());
22537  CheckIT(cond);
22538  Dt_size_3 encoded_dt(dt);
22539  if (IsUsingT32()) {
22540    // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
22541    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
22542      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22543        EmitT32_32(0xff800400U | (encoded_dt.GetEncodingValue() << 20) |
22544                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22545        AdvanceIT();
22546        return;
22547      }
22548    }
22549  } else {
22550    // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
22551    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
22552      if (cond.Is(al)) {
22553        EmitA32(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) |
22554                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22555        return;
22556      }
22557    }
22558  }
22559  Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm);
22560}
22561
22562void Assembler::vrecpe(Condition cond,
22563                       DataType dt,
22564                       DRegister rd,
22565                       DRegister rm) {
22566  VIXL_ASSERT(AllowAssembler());
22567  CheckIT(cond);
22568  Dt_F_size_4 encoded_dt(dt);
22569  if (IsUsingT32()) {
22570    // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22571    if (encoded_dt.IsValid()) {
22572      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22573        EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22574                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22575                   rd.Encode(22, 12) | rm.Encode(5, 0));
22576        AdvanceIT();
22577        return;
22578      }
22579    }
22580  } else {
22581    // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22582    if (encoded_dt.IsValid()) {
22583      if (cond.Is(al)) {
22584        EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22585                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22586                rd.Encode(22, 12) | rm.Encode(5, 0));
22587        return;
22588      }
22589    }
22590  }
22591  Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
22592}
22593
22594void Assembler::vrecpe(Condition cond,
22595                       DataType dt,
22596                       QRegister rd,
22597                       QRegister rm) {
22598  VIXL_ASSERT(AllowAssembler());
22599  CheckIT(cond);
22600  Dt_F_size_4 encoded_dt(dt);
22601  if (IsUsingT32()) {
22602    // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22603    if (encoded_dt.IsValid()) {
22604      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22605        EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22606                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22607                   rd.Encode(22, 12) | rm.Encode(5, 0));
22608        AdvanceIT();
22609        return;
22610      }
22611    }
22612  } else {
22613    // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22614    if (encoded_dt.IsValid()) {
22615      if (cond.Is(al)) {
22616        EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22617                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22618                rd.Encode(22, 12) | rm.Encode(5, 0));
22619        return;
22620      }
22621    }
22622  }
22623  Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
22624}
22625
22626void Assembler::vrecps(
22627    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22628  VIXL_ASSERT(AllowAssembler());
22629  CheckIT(cond);
22630  if (IsUsingT32()) {
22631    // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
22632    if (dt.Is(F32)) {
22633      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22634        EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22635                   rm.Encode(5, 0));
22636        AdvanceIT();
22637        return;
22638      }
22639    }
22640  } else {
22641    // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
22642    if (dt.Is(F32)) {
22643      if (cond.Is(al)) {
22644        EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22645                rm.Encode(5, 0));
22646        return;
22647      }
22648    }
22649  }
22650  Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
22651}
22652
22653void Assembler::vrecps(
22654    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22655  VIXL_ASSERT(AllowAssembler());
22656  CheckIT(cond);
22657  if (IsUsingT32()) {
22658    // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
22659    if (dt.Is(F32)) {
22660      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22661        EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22662                   rm.Encode(5, 0));
22663        AdvanceIT();
22664        return;
22665      }
22666    }
22667  } else {
22668    // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
22669    if (dt.Is(F32)) {
22670      if (cond.Is(al)) {
22671        EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22672                rm.Encode(5, 0));
22673        return;
22674      }
22675    }
22676  }
22677  Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
22678}
22679
22680void Assembler::vrev16(Condition cond,
22681                       DataType dt,
22682                       DRegister rd,
22683                       DRegister rm) {
22684  VIXL_ASSERT(AllowAssembler());
22685  CheckIT(cond);
22686  Dt_size_1 encoded_dt(dt);
22687  if (IsUsingT32()) {
22688    // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22689    if (encoded_dt.IsValid()) {
22690      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22691        EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) |
22692                   rd.Encode(22, 12) | rm.Encode(5, 0));
22693        AdvanceIT();
22694        return;
22695      }
22696    }
22697  } else {
22698    // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22699    if (encoded_dt.IsValid()) {
22700      if (cond.Is(al)) {
22701        EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) |
22702                rd.Encode(22, 12) | rm.Encode(5, 0));
22703        return;
22704      }
22705    }
22706  }
22707  Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
22708}
22709
22710void Assembler::vrev16(Condition cond,
22711                       DataType dt,
22712                       QRegister rd,
22713                       QRegister rm) {
22714  VIXL_ASSERT(AllowAssembler());
22715  CheckIT(cond);
22716  Dt_size_1 encoded_dt(dt);
22717  if (IsUsingT32()) {
22718    // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22719    if (encoded_dt.IsValid()) {
22720      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22721        EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) |
22722                   rd.Encode(22, 12) | rm.Encode(5, 0));
22723        AdvanceIT();
22724        return;
22725      }
22726    }
22727  } else {
22728    // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22729    if (encoded_dt.IsValid()) {
22730      if (cond.Is(al)) {
22731        EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) |
22732                rd.Encode(22, 12) | rm.Encode(5, 0));
22733        return;
22734      }
22735    }
22736  }
22737  Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
22738}
22739
22740void Assembler::vrev32(Condition cond,
22741                       DataType dt,
22742                       DRegister rd,
22743                       DRegister rm) {
22744  VIXL_ASSERT(AllowAssembler());
22745  CheckIT(cond);
22746  Dt_size_15 encoded_dt(dt);
22747  if (IsUsingT32()) {
22748    // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22749    if (encoded_dt.IsValid()) {
22750      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22751        EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) |
22752                   rd.Encode(22, 12) | rm.Encode(5, 0));
22753        AdvanceIT();
22754        return;
22755      }
22756    }
22757  } else {
22758    // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22759    if (encoded_dt.IsValid()) {
22760      if (cond.Is(al)) {
22761        EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) |
22762                rd.Encode(22, 12) | rm.Encode(5, 0));
22763        return;
22764      }
22765    }
22766  }
22767  Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
22768}
22769
22770void Assembler::vrev32(Condition cond,
22771                       DataType dt,
22772                       QRegister rd,
22773                       QRegister rm) {
22774  VIXL_ASSERT(AllowAssembler());
22775  CheckIT(cond);
22776  Dt_size_15 encoded_dt(dt);
22777  if (IsUsingT32()) {
22778    // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22779    if (encoded_dt.IsValid()) {
22780      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22781        EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) |
22782                   rd.Encode(22, 12) | rm.Encode(5, 0));
22783        AdvanceIT();
22784        return;
22785      }
22786    }
22787  } else {
22788    // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22789    if (encoded_dt.IsValid()) {
22790      if (cond.Is(al)) {
22791        EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) |
22792                rd.Encode(22, 12) | rm.Encode(5, 0));
22793        return;
22794      }
22795    }
22796  }
22797  Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
22798}
22799
22800void Assembler::vrev64(Condition cond,
22801                       DataType dt,
22802                       DRegister rd,
22803                       DRegister rm) {
22804  VIXL_ASSERT(AllowAssembler());
22805  CheckIT(cond);
22806  Dt_size_7 encoded_dt(dt);
22807  if (IsUsingT32()) {
22808    // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22809    if (encoded_dt.IsValid()) {
22810      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22811        EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) |
22812                   rd.Encode(22, 12) | rm.Encode(5, 0));
22813        AdvanceIT();
22814        return;
22815      }
22816    }
22817  } else {
22818    // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22819    if (encoded_dt.IsValid()) {
22820      if (cond.Is(al)) {
22821        EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) |
22822                rd.Encode(22, 12) | rm.Encode(5, 0));
22823        return;
22824      }
22825    }
22826  }
22827  Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
22828}
22829
22830void Assembler::vrev64(Condition cond,
22831                       DataType dt,
22832                       QRegister rd,
22833                       QRegister rm) {
22834  VIXL_ASSERT(AllowAssembler());
22835  CheckIT(cond);
22836  Dt_size_7 encoded_dt(dt);
22837  if (IsUsingT32()) {
22838    // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22839    if (encoded_dt.IsValid()) {
22840      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22841        EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) |
22842                   rd.Encode(22, 12) | rm.Encode(5, 0));
22843        AdvanceIT();
22844        return;
22845      }
22846    }
22847  } else {
22848    // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22849    if (encoded_dt.IsValid()) {
22850      if (cond.Is(al)) {
22851        EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) |
22852                rd.Encode(22, 12) | rm.Encode(5, 0));
22853        return;
22854      }
22855    }
22856  }
22857  Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
22858}
22859
22860void Assembler::vrhadd(
22861    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22862  VIXL_ASSERT(AllowAssembler());
22863  CheckIT(cond);
22864  Dt_U_size_1 encoded_dt(dt);
22865  if (IsUsingT32()) {
22866    // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22867    if (encoded_dt.IsValid()) {
22868      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22869        EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22870                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22871                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22872        AdvanceIT();
22873        return;
22874      }
22875    }
22876  } else {
22877    // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22878    if (encoded_dt.IsValid()) {
22879      if (cond.Is(al)) {
22880        EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22881                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22882                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22883        return;
22884      }
22885    }
22886  }
22887  Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
22888}
22889
22890void Assembler::vrhadd(
22891    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22892  VIXL_ASSERT(AllowAssembler());
22893  CheckIT(cond);
22894  Dt_U_size_1 encoded_dt(dt);
22895  if (IsUsingT32()) {
22896    // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22897    if (encoded_dt.IsValid()) {
22898      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22899        EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22900                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22901                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22902        AdvanceIT();
22903        return;
22904      }
22905    }
22906  } else {
22907    // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22908    if (encoded_dt.IsValid()) {
22909      if (cond.Is(al)) {
22910        EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22911                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22912                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22913        return;
22914      }
22915    }
22916  }
22917  Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
22918}
22919
22920void Assembler::vrinta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22921  VIXL_ASSERT(AllowAssembler());
22922  CheckIT(al);
22923  if (IsUsingT32()) {
22924    // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; T1
22925    if (dt1.Is(F32) && dt2.Is(F32)) {
22926      EmitT32_32(0xffba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
22927      AdvanceIT();
22928      return;
22929    }
22930    // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; T1
22931    if (dt1.Is(F64) && dt2.Is(F64)) {
22932      EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22933      AdvanceIT();
22934      return;
22935    }
22936  } else {
22937    // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; A1
22938    if (dt1.Is(F32) && dt2.Is(F32)) {
22939      EmitA32(0xf3ba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
22940      return;
22941    }
22942    // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; A1
22943    if (dt1.Is(F64) && dt2.Is(F64)) {
22944      EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22945      return;
22946    }
22947  }
22948  Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22949}
22950
22951void Assembler::vrinta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
22952  VIXL_ASSERT(AllowAssembler());
22953  CheckIT(al);
22954  if (IsUsingT32()) {
22955    // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; T1
22956    if (dt1.Is(F32) && dt2.Is(F32)) {
22957      EmitT32_32(0xffba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
22958      AdvanceIT();
22959      return;
22960    }
22961  } else {
22962    // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; A1
22963    if (dt1.Is(F32) && dt2.Is(F32)) {
22964      EmitA32(0xf3ba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
22965      return;
22966    }
22967  }
22968  Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22969}
22970
22971void Assembler::vrinta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
22972  VIXL_ASSERT(AllowAssembler());
22973  CheckIT(al);
22974  if (IsUsingT32()) {
22975    // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; T1
22976    if (dt1.Is(F32) && dt2.Is(F32)) {
22977      EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22978      AdvanceIT();
22979      return;
22980    }
22981  } else {
22982    // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; A1
22983    if (dt1.Is(F32) && dt2.Is(F32)) {
22984      EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22985      return;
22986    }
22987  }
22988  Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22989}
22990
22991void Assembler::vrintm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22992  VIXL_ASSERT(AllowAssembler());
22993  CheckIT(al);
22994  if (IsUsingT32()) {
22995    // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; T1
22996    if (dt1.Is(F32) && dt2.Is(F32)) {
22997      EmitT32_32(0xffba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
22998      AdvanceIT();
22999      return;
23000    }
23001    // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; T1
23002    if (dt1.Is(F64) && dt2.Is(F64)) {
23003      EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23004      AdvanceIT();
23005      return;
23006    }
23007  } else {
23008    // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; A1
23009    if (dt1.Is(F32) && dt2.Is(F32)) {
23010      EmitA32(0xf3ba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
23011      return;
23012    }
23013    // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; A1
23014    if (dt1.Is(F64) && dt2.Is(F64)) {
23015      EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23016      return;
23017    }
23018  }
23019  Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
23020}
23021
23022void Assembler::vrintm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23023  VIXL_ASSERT(AllowAssembler());
23024  CheckIT(al);
23025  if (IsUsingT32()) {
23026    // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; T1
23027    if (dt1.Is(F32) && dt2.Is(F32)) {
23028      EmitT32_32(0xffba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23029      AdvanceIT();
23030      return;
23031    }
23032  } else {
23033    // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; A1
23034    if (dt1.Is(F32) && dt2.Is(F32)) {
23035      EmitA32(0xf3ba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23036      return;
23037    }
23038  }
23039  Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
23040}
23041
23042void Assembler::vrintm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23043  VIXL_ASSERT(AllowAssembler());
23044  CheckIT(al);
23045  if (IsUsingT32()) {
23046    // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; T1
23047    if (dt1.Is(F32) && dt2.Is(F32)) {
23048      EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23049      AdvanceIT();
23050      return;
23051    }
23052  } else {
23053    // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; A1
23054    if (dt1.Is(F32) && dt2.Is(F32)) {
23055      EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23056      return;
23057    }
23058  }
23059  Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
23060}
23061
23062void Assembler::vrintn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23063  VIXL_ASSERT(AllowAssembler());
23064  CheckIT(al);
23065  if (IsUsingT32()) {
23066    // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; T1
23067    if (dt1.Is(F32) && dt2.Is(F32)) {
23068      EmitT32_32(0xffba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
23069      AdvanceIT();
23070      return;
23071    }
23072    // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; T1
23073    if (dt1.Is(F64) && dt2.Is(F64)) {
23074      EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23075      AdvanceIT();
23076      return;
23077    }
23078  } else {
23079    // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; A1
23080    if (dt1.Is(F32) && dt2.Is(F32)) {
23081      EmitA32(0xf3ba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
23082      return;
23083    }
23084    // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; A1
23085    if (dt1.Is(F64) && dt2.Is(F64)) {
23086      EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23087      return;
23088    }
23089  }
23090  Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
23091}
23092
23093void Assembler::vrintn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23094  VIXL_ASSERT(AllowAssembler());
23095  CheckIT(al);
23096  if (IsUsingT32()) {
23097    // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; T1
23098    if (dt1.Is(F32) && dt2.Is(F32)) {
23099      EmitT32_32(0xffba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
23100      AdvanceIT();
23101      return;
23102    }
23103  } else {
23104    // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; A1
23105    if (dt1.Is(F32) && dt2.Is(F32)) {
23106      EmitA32(0xf3ba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
23107      return;
23108    }
23109  }
23110  Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
23111}
23112
23113void Assembler::vrintn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23114  VIXL_ASSERT(AllowAssembler());
23115  CheckIT(al);
23116  if (IsUsingT32()) {
23117    // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; T1
23118    if (dt1.Is(F32) && dt2.Is(F32)) {
23119      EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23120      AdvanceIT();
23121      return;
23122    }
23123  } else {
23124    // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; A1
23125    if (dt1.Is(F32) && dt2.Is(F32)) {
23126      EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23127      return;
23128    }
23129  }
23130  Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
23131}
23132
23133void Assembler::vrintp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23134  VIXL_ASSERT(AllowAssembler());
23135  CheckIT(al);
23136  if (IsUsingT32()) {
23137    // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; T1
23138    if (dt1.Is(F32) && dt2.Is(F32)) {
23139      EmitT32_32(0xffba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
23140      AdvanceIT();
23141      return;
23142    }
23143    // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; T1
23144    if (dt1.Is(F64) && dt2.Is(F64)) {
23145      EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23146      AdvanceIT();
23147      return;
23148    }
23149  } else {
23150    // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; A1
23151    if (dt1.Is(F32) && dt2.Is(F32)) {
23152      EmitA32(0xf3ba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
23153      return;
23154    }
23155    // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; A1
23156    if (dt1.Is(F64) && dt2.Is(F64)) {
23157      EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23158      return;
23159    }
23160  }
23161  Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
23162}
23163
23164void Assembler::vrintp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23165  VIXL_ASSERT(AllowAssembler());
23166  CheckIT(al);
23167  if (IsUsingT32()) {
23168    // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; T1
23169    if (dt1.Is(F32) && dt2.Is(F32)) {
23170      EmitT32_32(0xffba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23171      AdvanceIT();
23172      return;
23173    }
23174  } else {
23175    // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; A1
23176    if (dt1.Is(F32) && dt2.Is(F32)) {
23177      EmitA32(0xf3ba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23178      return;
23179    }
23180  }
23181  Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
23182}
23183
23184void Assembler::vrintp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23185  VIXL_ASSERT(AllowAssembler());
23186  CheckIT(al);
23187  if (IsUsingT32()) {
23188    // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; T1
23189    if (dt1.Is(F32) && dt2.Is(F32)) {
23190      EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23191      AdvanceIT();
23192      return;
23193    }
23194  } else {
23195    // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; A1
23196    if (dt1.Is(F32) && dt2.Is(F32)) {
23197      EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23198      return;
23199    }
23200  }
23201  Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
23202}
23203
23204void Assembler::vrintr(
23205    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23206  VIXL_ASSERT(AllowAssembler());
23207  CheckIT(cond);
23208  if (IsUsingT32()) {
23209    // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
23210    if (dt1.Is(F32) && dt2.Is(F32)) {
23211      EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23212      AdvanceIT();
23213      return;
23214    }
23215  } else {
23216    // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
23217    if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
23218      EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23219              rm.Encode(5, 0));
23220      return;
23221    }
23222  }
23223  Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
23224}
23225
23226void Assembler::vrintr(
23227    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23228  VIXL_ASSERT(AllowAssembler());
23229  CheckIT(cond);
23230  if (IsUsingT32()) {
23231    // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
23232    if (dt1.Is(F64) && dt2.Is(F64)) {
23233      EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23234      AdvanceIT();
23235      return;
23236    }
23237  } else {
23238    // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
23239    if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
23240      EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23241              rm.Encode(5, 0));
23242      return;
23243    }
23244  }
23245  Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
23246}
23247
23248void Assembler::vrintx(
23249    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23250  VIXL_ASSERT(AllowAssembler());
23251  CheckIT(cond);
23252  if (IsUsingT32()) {
23253    // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; T1
23254    if (dt1.Is(F32) && dt2.Is(F32)) {
23255      EmitT32_32(0xffba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
23256      AdvanceIT();
23257      return;
23258    }
23259    // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
23260    if (dt1.Is(F64) && dt2.Is(F64)) {
23261      EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23262      AdvanceIT();
23263      return;
23264    }
23265  } else {
23266    // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; A1
23267    if (dt1.Is(F32) && dt2.Is(F32)) {
23268      EmitA32(0xf3ba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
23269      return;
23270    }
23271    // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
23272    if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
23273      EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23274              rm.Encode(5, 0));
23275      return;
23276    }
23277  }
23278  Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
23279}
23280
23281void Assembler::vrintx(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23282  VIXL_ASSERT(AllowAssembler());
23283  CheckIT(al);
23284  if (IsUsingT32()) {
23285    // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; T1
23286    if (dt1.Is(F32) && dt2.Is(F32)) {
23287      EmitT32_32(0xffba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23288      AdvanceIT();
23289      return;
23290    }
23291  } else {
23292    // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; A1
23293    if (dt1.Is(F32) && dt2.Is(F32)) {
23294      EmitA32(0xf3ba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23295      return;
23296    }
23297  }
23298  Delegate(kVrintx, &Assembler::vrintx, dt1, dt2, rd, rm);
23299}
23300
23301void Assembler::vrintx(
23302    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23303  VIXL_ASSERT(AllowAssembler());
23304  CheckIT(cond);
23305  if (IsUsingT32()) {
23306    // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
23307    if (dt1.Is(F32) && dt2.Is(F32)) {
23308      EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23309      AdvanceIT();
23310      return;
23311    }
23312  } else {
23313    // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
23314    if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
23315      EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23316              rm.Encode(5, 0));
23317      return;
23318    }
23319  }
23320  Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
23321}
23322
23323void Assembler::vrintz(
23324    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23325  VIXL_ASSERT(AllowAssembler());
23326  CheckIT(cond);
23327  if (IsUsingT32()) {
23328    // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; T1
23329    if (dt1.Is(F32) && dt2.Is(F32)) {
23330      EmitT32_32(0xffba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
23331      AdvanceIT();
23332      return;
23333    }
23334    // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
23335    if (dt1.Is(F64) && dt2.Is(F64)) {
23336      EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23337      AdvanceIT();
23338      return;
23339    }
23340  } else {
23341    // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; A1
23342    if (dt1.Is(F32) && dt2.Is(F32)) {
23343      EmitA32(0xf3ba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
23344      return;
23345    }
23346    // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
23347    if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
23348      EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23349              rm.Encode(5, 0));
23350      return;
23351    }
23352  }
23353  Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
23354}
23355
23356void Assembler::vrintz(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23357  VIXL_ASSERT(AllowAssembler());
23358  CheckIT(al);
23359  if (IsUsingT32()) {
23360    // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; T1
23361    if (dt1.Is(F32) && dt2.Is(F32)) {
23362      EmitT32_32(0xffba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23363      AdvanceIT();
23364      return;
23365    }
23366  } else {
23367    // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; A1
23368    if (dt1.Is(F32) && dt2.Is(F32)) {
23369      EmitA32(0xf3ba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23370      return;
23371    }
23372  }
23373  Delegate(kVrintz, &Assembler::vrintz, dt1, dt2, rd, rm);
23374}
23375
23376void Assembler::vrintz(
23377    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23378  VIXL_ASSERT(AllowAssembler());
23379  CheckIT(cond);
23380  if (IsUsingT32()) {
23381    // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
23382    if (dt1.Is(F32) && dt2.Is(F32)) {
23383      EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23384      AdvanceIT();
23385      return;
23386    }
23387  } else {
23388    // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
23389    if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
23390      EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23391              rm.Encode(5, 0));
23392      return;
23393    }
23394  }
23395  Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
23396}
23397
23398void Assembler::vrshl(
23399    Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
23400  VIXL_ASSERT(AllowAssembler());
23401  CheckIT(cond);
23402  Dt_U_size_3 encoded_dt(dt);
23403  if (IsUsingT32()) {
23404    // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
23405    if (encoded_dt.IsValid()) {
23406      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23407        EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23408                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23409                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23410        AdvanceIT();
23411        return;
23412      }
23413    }
23414  } else {
23415    // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
23416    if (encoded_dt.IsValid()) {
23417      if (cond.Is(al)) {
23418        EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23419                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23420                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23421        return;
23422      }
23423    }
23424  }
23425  Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
23426}
23427
23428void Assembler::vrshl(
23429    Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
23430  VIXL_ASSERT(AllowAssembler());
23431  CheckIT(cond);
23432  Dt_U_size_3 encoded_dt(dt);
23433  if (IsUsingT32()) {
23434    // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
23435    if (encoded_dt.IsValid()) {
23436      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23437        EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23438                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23439                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23440        AdvanceIT();
23441        return;
23442      }
23443    }
23444  } else {
23445    // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
23446    if (encoded_dt.IsValid()) {
23447      if (cond.Is(al)) {
23448        EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23449                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23450                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23451        return;
23452      }
23453    }
23454  }
23455  Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
23456}
23457
23458void Assembler::vrshr(Condition cond,
23459                      DataType dt,
23460                      DRegister rd,
23461                      DRegister rm,
23462                      const DOperand& operand) {
23463  VIXL_ASSERT(AllowAssembler());
23464  CheckIT(cond);
23465  if (operand.IsImmediate()) {
23466    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23467      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23468      Dt_L_imm6_1 encoded_dt(dt);
23469      if (IsUsingT32()) {
23470        // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23471        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23472          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23473            uint32_t imm6 = dt.GetSize() - imm;
23474            EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) |
23475                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23476                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23477                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23478            AdvanceIT();
23479            return;
23480          }
23481        }
23482        // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
23483        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23484          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23485            EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23486                       rm.Encode(5, 0));
23487            AdvanceIT();
23488            return;
23489          }
23490        }
23491      } else {
23492        // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23493        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23494          if (cond.Is(al)) {
23495            uint32_t imm6 = dt.GetSize() - imm;
23496            EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) |
23497                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23498                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23499                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23500            return;
23501          }
23502        }
23503        // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
23504        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23505          if (cond.Is(al)) {
23506            EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23507                    rm.Encode(5, 0));
23508            return;
23509          }
23510        }
23511      }
23512    }
23513  }
23514  Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
23515}
23516
23517void Assembler::vrshr(Condition cond,
23518                      DataType dt,
23519                      QRegister rd,
23520                      QRegister rm,
23521                      const QOperand& operand) {
23522  VIXL_ASSERT(AllowAssembler());
23523  CheckIT(cond);
23524  if (operand.IsImmediate()) {
23525    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23526      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23527      Dt_L_imm6_1 encoded_dt(dt);
23528      if (IsUsingT32()) {
23529        // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23530        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23531          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23532            uint32_t imm6 = dt.GetSize() - imm;
23533            EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) |
23534                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23535                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23536                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23537            AdvanceIT();
23538            return;
23539          }
23540        }
23541        // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
23542        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23543          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23544            EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23545                       rm.Encode(5, 0));
23546            AdvanceIT();
23547            return;
23548          }
23549        }
23550      } else {
23551        // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23552        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23553          if (cond.Is(al)) {
23554            uint32_t imm6 = dt.GetSize() - imm;
23555            EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) |
23556                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23557                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23558                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23559            return;
23560          }
23561        }
23562        // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
23563        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23564          if (cond.Is(al)) {
23565            EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23566                    rm.Encode(5, 0));
23567            return;
23568          }
23569        }
23570      }
23571    }
23572  }
23573  Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
23574}
23575
23576void Assembler::vrshrn(Condition cond,
23577                       DataType dt,
23578                       DRegister rd,
23579                       QRegister rm,
23580                       const QOperand& operand) {
23581  VIXL_ASSERT(AllowAssembler());
23582  CheckIT(cond);
23583  if (operand.IsImmediate()) {
23584    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23585      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23586      Dt_imm6_3 encoded_dt(dt);
23587      Dt_size_3 encoded_dt_2(dt);
23588      if (IsUsingT32()) {
23589        // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
23590        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23591          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23592            uint32_t imm6 = dt.GetSize() / 2 - imm;
23593            EmitT32_32(0xef800850U |
23594                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23595                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23596            AdvanceIT();
23597            return;
23598          }
23599        }
23600        // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23601        if (encoded_dt_2.IsValid() && (imm == 0)) {
23602          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23603            EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
23604                       rd.Encode(22, 12) | rm.Encode(5, 0));
23605            AdvanceIT();
23606            return;
23607          }
23608        }
23609      } else {
23610        // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
23611        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23612          if (cond.Is(al)) {
23613            uint32_t imm6 = dt.GetSize() / 2 - imm;
23614            EmitA32(0xf2800850U |
23615                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23616                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23617            return;
23618          }
23619        }
23620        // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23621        if (encoded_dt_2.IsValid() && (imm == 0)) {
23622          if (cond.Is(al)) {
23623            EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
23624                    rd.Encode(22, 12) | rm.Encode(5, 0));
23625            return;
23626          }
23627        }
23628      }
23629    }
23630  }
23631  Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand);
23632}
23633
23634void Assembler::vrsqrte(Condition cond,
23635                        DataType dt,
23636                        DRegister rd,
23637                        DRegister rm) {
23638  VIXL_ASSERT(AllowAssembler());
23639  CheckIT(cond);
23640  Dt_F_size_4 encoded_dt(dt);
23641  if (IsUsingT32()) {
23642    // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
23643    if (encoded_dt.IsValid()) {
23644      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23645        EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23646                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23647                   rd.Encode(22, 12) | rm.Encode(5, 0));
23648        AdvanceIT();
23649        return;
23650      }
23651    }
23652  } else {
23653    // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
23654    if (encoded_dt.IsValid()) {
23655      if (cond.Is(al)) {
23656        EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23657                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23658                rd.Encode(22, 12) | rm.Encode(5, 0));
23659        return;
23660      }
23661    }
23662  }
23663  Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
23664}
23665
23666void Assembler::vrsqrte(Condition cond,
23667                        DataType dt,
23668                        QRegister rd,
23669                        QRegister rm) {
23670  VIXL_ASSERT(AllowAssembler());
23671  CheckIT(cond);
23672  Dt_F_size_4 encoded_dt(dt);
23673  if (IsUsingT32()) {
23674    // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
23675    if (encoded_dt.IsValid()) {
23676      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23677        EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23678                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23679                   rd.Encode(22, 12) | rm.Encode(5, 0));
23680        AdvanceIT();
23681        return;
23682      }
23683    }
23684  } else {
23685    // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
23686    if (encoded_dt.IsValid()) {
23687      if (cond.Is(al)) {
23688        EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23689                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23690                rd.Encode(22, 12) | rm.Encode(5, 0));
23691        return;
23692      }
23693    }
23694  }
23695  Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
23696}
23697
23698void Assembler::vrsqrts(
23699    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23700  VIXL_ASSERT(AllowAssembler());
23701  CheckIT(cond);
23702  if (IsUsingT32()) {
23703    // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
23704    if (dt.Is(F32)) {
23705      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23706        EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23707                   rm.Encode(5, 0));
23708        AdvanceIT();
23709        return;
23710      }
23711    }
23712  } else {
23713    // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
23714    if (dt.Is(F32)) {
23715      if (cond.Is(al)) {
23716        EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23717                rm.Encode(5, 0));
23718        return;
23719      }
23720    }
23721  }
23722  Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
23723}
23724
23725void Assembler::vrsqrts(
23726    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
23727  VIXL_ASSERT(AllowAssembler());
23728  CheckIT(cond);
23729  if (IsUsingT32()) {
23730    // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
23731    if (dt.Is(F32)) {
23732      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23733        EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23734                   rm.Encode(5, 0));
23735        AdvanceIT();
23736        return;
23737      }
23738    }
23739  } else {
23740    // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
23741    if (dt.Is(F32)) {
23742      if (cond.Is(al)) {
23743        EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23744                rm.Encode(5, 0));
23745        return;
23746      }
23747    }
23748  }
23749  Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
23750}
23751
23752void Assembler::vrsra(Condition cond,
23753                      DataType dt,
23754                      DRegister rd,
23755                      DRegister rm,
23756                      const DOperand& operand) {
23757  VIXL_ASSERT(AllowAssembler());
23758  CheckIT(cond);
23759  if (operand.IsImmediate()) {
23760    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23761      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23762      Dt_L_imm6_1 encoded_dt(dt);
23763      if (IsUsingT32()) {
23764        // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23765        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23766          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23767            uint32_t imm6 = dt.GetSize() - imm;
23768            EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) |
23769                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23770                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23771                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23772            AdvanceIT();
23773            return;
23774          }
23775        }
23776      } else {
23777        // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23778        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23779          if (cond.Is(al)) {
23780            uint32_t imm6 = dt.GetSize() - imm;
23781            EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) |
23782                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23783                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23784                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23785            return;
23786          }
23787        }
23788      }
23789    }
23790  }
23791  Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
23792}
23793
23794void Assembler::vrsra(Condition cond,
23795                      DataType dt,
23796                      QRegister rd,
23797                      QRegister rm,
23798                      const QOperand& operand) {
23799  VIXL_ASSERT(AllowAssembler());
23800  CheckIT(cond);
23801  if (operand.IsImmediate()) {
23802    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23803      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23804      Dt_L_imm6_1 encoded_dt(dt);
23805      if (IsUsingT32()) {
23806        // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23807        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23808          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23809            uint32_t imm6 = dt.GetSize() - imm;
23810            EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) |
23811                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23812                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23813                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23814            AdvanceIT();
23815            return;
23816          }
23817        }
23818      } else {
23819        // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23820        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23821          if (cond.Is(al)) {
23822            uint32_t imm6 = dt.GetSize() - imm;
23823            EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) |
23824                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23825                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23826                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23827            return;
23828          }
23829        }
23830      }
23831    }
23832  }
23833  Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
23834}
23835
23836void Assembler::vrsubhn(
23837    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
23838  VIXL_ASSERT(AllowAssembler());
23839  CheckIT(cond);
23840  Dt_size_3 encoded_dt(dt);
23841  if (IsUsingT32()) {
23842    // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
23843    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
23844      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23845        EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) |
23846                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23847        AdvanceIT();
23848        return;
23849      }
23850    }
23851  } else {
23852    // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
23853    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
23854      if (cond.Is(al)) {
23855        EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) |
23856                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23857        return;
23858      }
23859    }
23860  }
23861  Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm);
23862}
23863
23864void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23865  VIXL_ASSERT(AllowAssembler());
23866  CheckIT(al);
23867  if (IsUsingT32()) {
23868    // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1
23869    if (OutsideITBlock() && dt.Is(F64)) {
23870      EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23871                 rm.Encode(5, 0));
23872      AdvanceIT();
23873      return;
23874    }
23875  } else {
23876    // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1
23877    if (dt.Is(F64)) {
23878      EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23879              rm.Encode(5, 0));
23880      return;
23881    }
23882  }
23883  Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
23884}
23885
23886void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23887  VIXL_ASSERT(AllowAssembler());
23888  CheckIT(al);
23889  if (IsUsingT32()) {
23890    // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1
23891    if (OutsideITBlock() && dt.Is(F32)) {
23892      EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23893                 rm.Encode(5, 0));
23894      AdvanceIT();
23895      return;
23896    }
23897  } else {
23898    // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1
23899    if (dt.Is(F32)) {
23900      EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23901              rm.Encode(5, 0));
23902      return;
23903    }
23904  }
23905  Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
23906}
23907
23908void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23909  VIXL_ASSERT(AllowAssembler());
23910  CheckIT(al);
23911  if (IsUsingT32()) {
23912    // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1
23913    if (OutsideITBlock() && dt.Is(F64)) {
23914      EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23915                 rm.Encode(5, 0));
23916      AdvanceIT();
23917      return;
23918    }
23919  } else {
23920    // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1
23921    if (dt.Is(F64)) {
23922      EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23923              rm.Encode(5, 0));
23924      return;
23925    }
23926  }
23927  Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
23928}
23929
23930void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23931  VIXL_ASSERT(AllowAssembler());
23932  CheckIT(al);
23933  if (IsUsingT32()) {
23934    // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1
23935    if (OutsideITBlock() && dt.Is(F32)) {
23936      EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23937                 rm.Encode(5, 0));
23938      AdvanceIT();
23939      return;
23940    }
23941  } else {
23942    // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1
23943    if (dt.Is(F32)) {
23944      EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23945              rm.Encode(5, 0));
23946      return;
23947    }
23948  }
23949  Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
23950}
23951
23952void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23953  VIXL_ASSERT(AllowAssembler());
23954  CheckIT(al);
23955  if (IsUsingT32()) {
23956    // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1
23957    if (OutsideITBlock() && dt.Is(F64)) {
23958      EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23959                 rm.Encode(5, 0));
23960      AdvanceIT();
23961      return;
23962    }
23963  } else {
23964    // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1
23965    if (dt.Is(F64)) {
23966      EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23967              rm.Encode(5, 0));
23968      return;
23969    }
23970  }
23971  Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
23972}
23973
23974void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23975  VIXL_ASSERT(AllowAssembler());
23976  CheckIT(al);
23977  if (IsUsingT32()) {
23978    // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1
23979    if (OutsideITBlock() && dt.Is(F32)) {
23980      EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23981                 rm.Encode(5, 0));
23982      AdvanceIT();
23983      return;
23984    }
23985  } else {
23986    // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1
23987    if (dt.Is(F32)) {
23988      EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23989              rm.Encode(5, 0));
23990      return;
23991    }
23992  }
23993  Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
23994}
23995
23996void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23997  VIXL_ASSERT(AllowAssembler());
23998  CheckIT(al);
23999  if (IsUsingT32()) {
24000    // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1
24001    if (OutsideITBlock() && dt.Is(F64)) {
24002      EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
24003                 rm.Encode(5, 0));
24004      AdvanceIT();
24005      return;
24006    }
24007  } else {
24008    // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1
24009    if (dt.Is(F64)) {
24010      EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
24011              rm.Encode(5, 0));
24012      return;
24013    }
24014  }
24015  Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
24016}
24017
24018void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
24019  VIXL_ASSERT(AllowAssembler());
24020  CheckIT(al);
24021  if (IsUsingT32()) {
24022    // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1
24023    if (OutsideITBlock() && dt.Is(F32)) {
24024      EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
24025                 rm.Encode(5, 0));
24026      AdvanceIT();
24027      return;
24028    }
24029  } else {
24030    // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1
24031    if (dt.Is(F32)) {
24032      EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
24033              rm.Encode(5, 0));
24034      return;
24035    }
24036  }
24037  Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
24038}
24039
24040void Assembler::vshl(Condition cond,
24041                     DataType dt,
24042                     DRegister rd,
24043                     DRegister rm,
24044                     const DOperand& operand) {
24045  VIXL_ASSERT(AllowAssembler());
24046  CheckIT(cond);
24047  if (operand.IsImmediate()) {
24048    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24049      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24050      Dt_L_imm6_3 encoded_dt(dt);
24051      if (IsUsingT32()) {
24052        // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1
24053        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24054          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24055            uint32_t imm6 = imm;
24056            EmitT32_32(0xef800510U |
24057                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24058                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24059                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24060            AdvanceIT();
24061            return;
24062          }
24063        }
24064      } else {
24065        // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1
24066        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24067          if (cond.Is(al)) {
24068            uint32_t imm6 = imm;
24069            EmitA32(0xf2800510U |
24070                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24071                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24072                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24073            return;
24074          }
24075        }
24076      }
24077    }
24078  }
24079  if (operand.IsRegister()) {
24080    DRegister rn = operand.GetRegister();
24081    Dt_U_size_3 encoded_dt(dt);
24082    if (IsUsingT32()) {
24083      // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
24084      if (encoded_dt.IsValid()) {
24085        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24086          EmitT32_32(0xef000400U |
24087                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24088                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24089                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24090          AdvanceIT();
24091          return;
24092        }
24093      }
24094    } else {
24095      // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
24096      if (encoded_dt.IsValid()) {
24097        if (cond.Is(al)) {
24098          EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24099                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24100                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24101          return;
24102        }
24103      }
24104    }
24105  }
24106  Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
24107}
24108
24109void Assembler::vshl(Condition cond,
24110                     DataType dt,
24111                     QRegister rd,
24112                     QRegister rm,
24113                     const QOperand& operand) {
24114  VIXL_ASSERT(AllowAssembler());
24115  CheckIT(cond);
24116  if (operand.IsImmediate()) {
24117    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24118      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24119      Dt_L_imm6_3 encoded_dt(dt);
24120      if (IsUsingT32()) {
24121        // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1
24122        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24123          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24124            uint32_t imm6 = imm;
24125            EmitT32_32(0xef800550U |
24126                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24127                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24128                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24129            AdvanceIT();
24130            return;
24131          }
24132        }
24133      } else {
24134        // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1
24135        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24136          if (cond.Is(al)) {
24137            uint32_t imm6 = imm;
24138            EmitA32(0xf2800550U |
24139                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24140                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24141                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24142            return;
24143          }
24144        }
24145      }
24146    }
24147  }
24148  if (operand.IsRegister()) {
24149    QRegister rn = operand.GetRegister();
24150    Dt_U_size_3 encoded_dt(dt);
24151    if (IsUsingT32()) {
24152      // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
24153      if (encoded_dt.IsValid()) {
24154        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24155          EmitT32_32(0xef000440U |
24156                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24157                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24158                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24159          AdvanceIT();
24160          return;
24161        }
24162      }
24163    } else {
24164      // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
24165      if (encoded_dt.IsValid()) {
24166        if (cond.Is(al)) {
24167          EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24168                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24169                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24170          return;
24171        }
24172      }
24173    }
24174  }
24175  Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
24176}
24177
24178void Assembler::vshll(Condition cond,
24179                      DataType dt,
24180                      QRegister rd,
24181                      DRegister rm,
24182                      const DOperand& operand) {
24183  VIXL_ASSERT(AllowAssembler());
24184  CheckIT(cond);
24185  if (operand.IsImmediate()) {
24186    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24187      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24188      Dt_imm6_4 encoded_dt(dt);
24189      Dt_size_16 encoded_dt_2(dt);
24190      if (IsUsingT32()) {
24191        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1
24192        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
24193          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24194            uint32_t imm6 = dt.GetSize() + imm;
24195            EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) |
24196                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24197                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24198            AdvanceIT();
24199            return;
24200          }
24201        }
24202        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2
24203        if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
24204          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24205            EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) |
24206                       rd.Encode(22, 12) | rm.Encode(5, 0));
24207            AdvanceIT();
24208            return;
24209          }
24210        }
24211      } else {
24212        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1
24213        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
24214          if (cond.Is(al)) {
24215            uint32_t imm6 = dt.GetSize() + imm;
24216            EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) |
24217                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24218                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24219            return;
24220          }
24221        }
24222        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2
24223        if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
24224          if (cond.Is(al)) {
24225            EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) |
24226                    rd.Encode(22, 12) | rm.Encode(5, 0));
24227            return;
24228          }
24229        }
24230      }
24231    }
24232  }
24233  Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand);
24234}
24235
24236void Assembler::vshr(Condition cond,
24237                     DataType dt,
24238                     DRegister rd,
24239                     DRegister rm,
24240                     const DOperand& operand) {
24241  VIXL_ASSERT(AllowAssembler());
24242  CheckIT(cond);
24243  if (operand.IsImmediate()) {
24244    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24245      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24246      Dt_L_imm6_1 encoded_dt(dt);
24247      if (IsUsingT32()) {
24248        // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
24249        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24250          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24251            uint32_t imm6 = dt.GetSize() - imm;
24252            EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) |
24253                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24254                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24255                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24256            AdvanceIT();
24257            return;
24258          }
24259        }
24260        // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
24261        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24262          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24263            EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24264                       rm.Encode(5, 0));
24265            AdvanceIT();
24266            return;
24267          }
24268        }
24269      } else {
24270        // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
24271        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24272          if (cond.Is(al)) {
24273            uint32_t imm6 = dt.GetSize() - imm;
24274            EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) |
24275                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24276                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24277                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24278            return;
24279          }
24280        }
24281        // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
24282        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24283          if (cond.Is(al)) {
24284            EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24285                    rm.Encode(5, 0));
24286            return;
24287          }
24288        }
24289      }
24290    }
24291  }
24292  Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
24293}
24294
24295void Assembler::vshr(Condition cond,
24296                     DataType dt,
24297                     QRegister rd,
24298                     QRegister rm,
24299                     const QOperand& operand) {
24300  VIXL_ASSERT(AllowAssembler());
24301  CheckIT(cond);
24302  if (operand.IsImmediate()) {
24303    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24304      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24305      Dt_L_imm6_1 encoded_dt(dt);
24306      if (IsUsingT32()) {
24307        // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
24308        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24309          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24310            uint32_t imm6 = dt.GetSize() - imm;
24311            EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) |
24312                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24313                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24314                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24315            AdvanceIT();
24316            return;
24317          }
24318        }
24319        // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
24320        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24321          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24322            EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24323                       rm.Encode(5, 0));
24324            AdvanceIT();
24325            return;
24326          }
24327        }
24328      } else {
24329        // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
24330        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24331          if (cond.Is(al)) {
24332            uint32_t imm6 = dt.GetSize() - imm;
24333            EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) |
24334                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24335                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24336                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24337            return;
24338          }
24339        }
24340        // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
24341        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24342          if (cond.Is(al)) {
24343            EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24344                    rm.Encode(5, 0));
24345            return;
24346          }
24347        }
24348      }
24349    }
24350  }
24351  Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
24352}
24353
24354void Assembler::vshrn(Condition cond,
24355                      DataType dt,
24356                      DRegister rd,
24357                      QRegister rm,
24358                      const QOperand& operand) {
24359  VIXL_ASSERT(AllowAssembler());
24360  CheckIT(cond);
24361  if (operand.IsImmediate()) {
24362    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24363      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24364      Dt_imm6_3 encoded_dt(dt);
24365      Dt_size_3 encoded_dt_2(dt);
24366      if (IsUsingT32()) {
24367        // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
24368        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
24369          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24370            uint32_t imm6 = dt.GetSize() / 2 - imm;
24371            EmitT32_32(0xef800810U |
24372                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24373                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24374            AdvanceIT();
24375            return;
24376          }
24377        }
24378        // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
24379        if (encoded_dt_2.IsValid() && (imm == 0)) {
24380          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24381            EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
24382                       rd.Encode(22, 12) | rm.Encode(5, 0));
24383            AdvanceIT();
24384            return;
24385          }
24386        }
24387      } else {
24388        // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
24389        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
24390          if (cond.Is(al)) {
24391            uint32_t imm6 = dt.GetSize() / 2 - imm;
24392            EmitA32(0xf2800810U |
24393                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24394                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24395            return;
24396          }
24397        }
24398        // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
24399        if (encoded_dt_2.IsValid() && (imm == 0)) {
24400          if (cond.Is(al)) {
24401            EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
24402                    rd.Encode(22, 12) | rm.Encode(5, 0));
24403            return;
24404          }
24405        }
24406      }
24407    }
24408  }
24409  Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand);
24410}
24411
24412void Assembler::vsli(Condition cond,
24413                     DataType dt,
24414                     DRegister rd,
24415                     DRegister rm,
24416                     const DOperand& operand) {
24417  VIXL_ASSERT(AllowAssembler());
24418  CheckIT(cond);
24419  if (operand.IsImmediate()) {
24420    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24421      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24422      Dt_L_imm6_4 encoded_dt(dt);
24423      if (IsUsingT32()) {
24424        // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
24425        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24426          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24427            uint32_t imm6 = imm;
24428            EmitT32_32(0xff800510U |
24429                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24430                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24431                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24432            AdvanceIT();
24433            return;
24434          }
24435        }
24436      } else {
24437        // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
24438        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24439          if (cond.Is(al)) {
24440            uint32_t imm6 = imm;
24441            EmitA32(0xf3800510U |
24442                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24443                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24444                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24445            return;
24446          }
24447        }
24448      }
24449    }
24450  }
24451  Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
24452}
24453
24454void Assembler::vsli(Condition cond,
24455                     DataType dt,
24456                     QRegister rd,
24457                     QRegister rm,
24458                     const QOperand& operand) {
24459  VIXL_ASSERT(AllowAssembler());
24460  CheckIT(cond);
24461  if (operand.IsImmediate()) {
24462    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24463      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24464      Dt_L_imm6_4 encoded_dt(dt);
24465      if (IsUsingT32()) {
24466        // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
24467        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24468          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24469            uint32_t imm6 = imm;
24470            EmitT32_32(0xff800550U |
24471                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24472                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24473                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24474            AdvanceIT();
24475            return;
24476          }
24477        }
24478      } else {
24479        // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
24480        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24481          if (cond.Is(al)) {
24482            uint32_t imm6 = imm;
24483            EmitA32(0xf3800550U |
24484                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24485                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24486                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24487            return;
24488          }
24489        }
24490      }
24491    }
24492  }
24493  Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
24494}
24495
24496void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) {
24497  VIXL_ASSERT(AllowAssembler());
24498  CheckIT(cond);
24499  if (IsUsingT32()) {
24500    // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
24501    if (dt.Is(F32)) {
24502      EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
24503      AdvanceIT();
24504      return;
24505    }
24506  } else {
24507    // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
24508    if (dt.Is(F32) && cond.IsNotNever()) {
24509      EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24510              rm.Encode(5, 0));
24511      return;
24512    }
24513  }
24514  Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
24515}
24516
24517void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
24518  VIXL_ASSERT(AllowAssembler());
24519  CheckIT(cond);
24520  if (IsUsingT32()) {
24521    // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
24522    if (dt.Is(F64)) {
24523      EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
24524      AdvanceIT();
24525      return;
24526    }
24527  } else {
24528    // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
24529    if (dt.Is(F64) && cond.IsNotNever()) {
24530      EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24531              rm.Encode(5, 0));
24532      return;
24533    }
24534  }
24535  Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
24536}
24537
24538void Assembler::vsra(Condition cond,
24539                     DataType dt,
24540                     DRegister rd,
24541                     DRegister rm,
24542                     const DOperand& operand) {
24543  VIXL_ASSERT(AllowAssembler());
24544  CheckIT(cond);
24545  if (operand.IsImmediate()) {
24546    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24547      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24548      Dt_L_imm6_1 encoded_dt(dt);
24549      if (IsUsingT32()) {
24550        // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
24551        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24552          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24553            uint32_t imm6 = dt.GetSize() - imm;
24554            EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) |
24555                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24556                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24557                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24558            AdvanceIT();
24559            return;
24560          }
24561        }
24562      } else {
24563        // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
24564        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24565          if (cond.Is(al)) {
24566            uint32_t imm6 = dt.GetSize() - imm;
24567            EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) |
24568                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24569                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24570                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24571            return;
24572          }
24573        }
24574      }
24575    }
24576  }
24577  Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
24578}
24579
24580void Assembler::vsra(Condition cond,
24581                     DataType dt,
24582                     QRegister rd,
24583                     QRegister rm,
24584                     const QOperand& operand) {
24585  VIXL_ASSERT(AllowAssembler());
24586  CheckIT(cond);
24587  if (operand.IsImmediate()) {
24588    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24589      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24590      Dt_L_imm6_1 encoded_dt(dt);
24591      if (IsUsingT32()) {
24592        // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
24593        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24594          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24595            uint32_t imm6 = dt.GetSize() - imm;
24596            EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) |
24597                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24598                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24599                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24600            AdvanceIT();
24601            return;
24602          }
24603        }
24604      } else {
24605        // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
24606        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24607          if (cond.Is(al)) {
24608            uint32_t imm6 = dt.GetSize() - imm;
24609            EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) |
24610                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24611                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24612                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24613            return;
24614          }
24615        }
24616      }
24617    }
24618  }
24619  Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
24620}
24621
24622void Assembler::vsri(Condition cond,
24623                     DataType dt,
24624                     DRegister rd,
24625                     DRegister rm,
24626                     const DOperand& operand) {
24627  VIXL_ASSERT(AllowAssembler());
24628  CheckIT(cond);
24629  if (operand.IsImmediate()) {
24630    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24631      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24632      Dt_L_imm6_4 encoded_dt(dt);
24633      if (IsUsingT32()) {
24634        // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
24635        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24636          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24637            uint32_t imm6 = dt.GetSize() - imm;
24638            EmitT32_32(0xff800410U |
24639                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24640                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24641                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24642            AdvanceIT();
24643            return;
24644          }
24645        }
24646      } else {
24647        // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
24648        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24649          if (cond.Is(al)) {
24650            uint32_t imm6 = dt.GetSize() - imm;
24651            EmitA32(0xf3800410U |
24652                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24653                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24654                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24655            return;
24656          }
24657        }
24658      }
24659    }
24660  }
24661  Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
24662}
24663
24664void Assembler::vsri(Condition cond,
24665                     DataType dt,
24666                     QRegister rd,
24667                     QRegister rm,
24668                     const QOperand& operand) {
24669  VIXL_ASSERT(AllowAssembler());
24670  CheckIT(cond);
24671  if (operand.IsImmediate()) {
24672    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24673      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24674      Dt_L_imm6_4 encoded_dt(dt);
24675      if (IsUsingT32()) {
24676        // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
24677        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24678          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24679            uint32_t imm6 = dt.GetSize() - imm;
24680            EmitT32_32(0xff800450U |
24681                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24682                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24683                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24684            AdvanceIT();
24685            return;
24686          }
24687        }
24688      } else {
24689        // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
24690        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24691          if (cond.Is(al)) {
24692            uint32_t imm6 = dt.GetSize() - imm;
24693            EmitA32(0xf3800450U |
24694                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24695                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24696                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24697            return;
24698          }
24699        }
24700      }
24701    }
24702  }
24703  Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
24704}
24705
24706void Assembler::vst1(Condition cond,
24707                     DataType dt,
24708                     const NeonRegisterList& nreglist,
24709                     const AlignedMemOperand& operand) {
24710  VIXL_ASSERT(AllowAssembler());
24711  CheckIT(cond);
24712  if (operand.IsImmediateZero()) {
24713    Register rn = operand.GetBaseRegister();
24714    Alignment align = operand.GetAlignment();
24715    Dt_size_6 encoded_dt(dt);
24716    Dt_size_7 encoded_dt_2(dt);
24717    Align_align_5 encoded_align_1(align, nreglist);
24718    Align_index_align_1 encoded_align_2(align, nreglist, dt);
24719    if (IsUsingT32()) {
24720      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24721      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24722          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24723          operand.IsOffset() && encoded_align_1.IsValid() &&
24724          (!rn.IsPC() || AllowUnpredictable())) {
24725        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24726          const DRegister& first = nreglist.GetFirstDRegister();
24727          uint32_t len_encoding;
24728          switch (nreglist.GetLength()) {
24729            default:
24730              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24731            case 1:
24732              len_encoding = 0x7;
24733              break;
24734            case 2:
24735              len_encoding = 0xa;
24736              break;
24737            case 3:
24738              len_encoding = 0x6;
24739              break;
24740            case 4:
24741              len_encoding = 0x2;
24742              break;
24743          }
24744          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
24745                     (encoded_align_1.GetEncodingValue() << 4) |
24746                     first.Encode(22, 12) | (len_encoding << 8) |
24747                     (rn.GetCode() << 16));
24748          AdvanceIT();
24749          return;
24750        }
24751      }
24752      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24753      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24754          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24755          operand.IsPostIndex() && encoded_align_1.IsValid() &&
24756          (!rn.IsPC() || AllowUnpredictable())) {
24757        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24758          const DRegister& first = nreglist.GetFirstDRegister();
24759          uint32_t len_encoding;
24760          switch (nreglist.GetLength()) {
24761            default:
24762              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24763            case 1:
24764              len_encoding = 0x7;
24765              break;
24766            case 2:
24767              len_encoding = 0xa;
24768              break;
24769            case 3:
24770              len_encoding = 0x6;
24771              break;
24772            case 4:
24773              len_encoding = 0x2;
24774              break;
24775          }
24776          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
24777                     (encoded_align_1.GetEncodingValue() << 4) |
24778                     first.Encode(22, 12) | (len_encoding << 8) |
24779                     (rn.GetCode() << 16));
24780          AdvanceIT();
24781          return;
24782        }
24783      }
24784      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24785      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24786          (nreglist.GetLength() == 1) && operand.IsOffset() &&
24787          encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
24788        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24789          const DRegister& first = nreglist.GetFirstDRegister();
24790          EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) |
24791                     (encoded_align_2.GetEncodingValue() << 4) |
24792                     first.Encode(22, 12) | (rn.GetCode() << 16));
24793          AdvanceIT();
24794          return;
24795        }
24796      }
24797      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24798      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24799          (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
24800          encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
24801        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24802          const DRegister& first = nreglist.GetFirstDRegister();
24803          EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) |
24804                     (encoded_align_2.GetEncodingValue() << 4) |
24805                     first.Encode(22, 12) | (rn.GetCode() << 16));
24806          AdvanceIT();
24807          return;
24808        }
24809      }
24810    } else {
24811      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
24812      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24813          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24814          operand.IsOffset() && encoded_align_1.IsValid() &&
24815          (!rn.IsPC() || AllowUnpredictable())) {
24816        if (cond.Is(al)) {
24817          const DRegister& first = nreglist.GetFirstDRegister();
24818          uint32_t len_encoding;
24819          switch (nreglist.GetLength()) {
24820            default:
24821              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24822            case 1:
24823              len_encoding = 0x7;
24824              break;
24825            case 2:
24826              len_encoding = 0xa;
24827              break;
24828            case 3:
24829              len_encoding = 0x6;
24830              break;
24831            case 4:
24832              len_encoding = 0x2;
24833              break;
24834          }
24835          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
24836                  (encoded_align_1.GetEncodingValue() << 4) |
24837                  first.Encode(22, 12) | (len_encoding << 8) |
24838                  (rn.GetCode() << 16));
24839          return;
24840        }
24841      }
24842      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
24843      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24844          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24845          operand.IsPostIndex() && encoded_align_1.IsValid() &&
24846          (!rn.IsPC() || AllowUnpredictable())) {
24847        if (cond.Is(al)) {
24848          const DRegister& first = nreglist.GetFirstDRegister();
24849          uint32_t len_encoding;
24850          switch (nreglist.GetLength()) {
24851            default:
24852              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24853            case 1:
24854              len_encoding = 0x7;
24855              break;
24856            case 2:
24857              len_encoding = 0xa;
24858              break;
24859            case 3:
24860              len_encoding = 0x6;
24861              break;
24862            case 4:
24863              len_encoding = 0x2;
24864              break;
24865          }
24866          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
24867                  (encoded_align_1.GetEncodingValue() << 4) |
24868                  first.Encode(22, 12) | (len_encoding << 8) |
24869                  (rn.GetCode() << 16));
24870          return;
24871        }
24872      }
24873      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
24874      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24875          (nreglist.GetLength() == 1) && operand.IsOffset() &&
24876          encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
24877        if (cond.Is(al)) {
24878          const DRegister& first = nreglist.GetFirstDRegister();
24879          EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) |
24880                  (encoded_align_2.GetEncodingValue() << 4) |
24881                  first.Encode(22, 12) | (rn.GetCode() << 16));
24882          return;
24883        }
24884      }
24885      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
24886      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24887          (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
24888          encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
24889        if (cond.Is(al)) {
24890          const DRegister& first = nreglist.GetFirstDRegister();
24891          EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) |
24892                  (encoded_align_2.GetEncodingValue() << 4) |
24893                  first.Encode(22, 12) | (rn.GetCode() << 16));
24894          return;
24895        }
24896      }
24897    }
24898  }
24899  if (operand.IsPlainRegister()) {
24900    Register rn = operand.GetBaseRegister();
24901    Alignment align = operand.GetAlignment();
24902    Register rm = operand.GetOffsetRegister();
24903    Dt_size_6 encoded_dt(dt);
24904    Dt_size_7 encoded_dt_2(dt);
24905    Align_align_5 encoded_align_1(align, nreglist);
24906    Align_index_align_1 encoded_align_2(align, nreglist, dt);
24907    if (IsUsingT32()) {
24908      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
24909      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24910          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24911          !rm.IsPC() && !rm.IsSP()) {
24912        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24913          const DRegister& first = nreglist.GetFirstDRegister();
24914          uint32_t len_encoding;
24915          switch (nreglist.GetLength()) {
24916            default:
24917              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24918            case 1:
24919              len_encoding = 0x7;
24920              break;
24921            case 2:
24922              len_encoding = 0xa;
24923              break;
24924            case 3:
24925              len_encoding = 0x6;
24926              break;
24927            case 4:
24928              len_encoding = 0x2;
24929              break;
24930          }
24931          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
24932                     (encoded_align_1.GetEncodingValue() << 4) |
24933                     first.Encode(22, 12) | (len_encoding << 8) |
24934                     (rn.GetCode() << 16) | rm.GetCode());
24935          AdvanceIT();
24936          return;
24937        }
24938      }
24939      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
24940      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24941          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
24942        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24943          const DRegister& first = nreglist.GetFirstDRegister();
24944          EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) |
24945                     (encoded_align_2.GetEncodingValue() << 4) |
24946                     first.Encode(22, 12) | (rn.GetCode() << 16) |
24947                     rm.GetCode());
24948          AdvanceIT();
24949          return;
24950        }
24951      }
24952    } else {
24953      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
24954      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24955          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24956          !rm.IsPC() && !rm.IsSP()) {
24957        if (cond.Is(al)) {
24958          const DRegister& first = nreglist.GetFirstDRegister();
24959          uint32_t len_encoding;
24960          switch (nreglist.GetLength()) {
24961            default:
24962              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24963            case 1:
24964              len_encoding = 0x7;
24965              break;
24966            case 2:
24967              len_encoding = 0xa;
24968              break;
24969            case 3:
24970              len_encoding = 0x6;
24971              break;
24972            case 4:
24973              len_encoding = 0x2;
24974              break;
24975          }
24976          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
24977                  (encoded_align_1.GetEncodingValue() << 4) |
24978                  first.Encode(22, 12) | (len_encoding << 8) |
24979                  (rn.GetCode() << 16) | rm.GetCode());
24980          return;
24981        }
24982      }
24983      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
24984      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24985          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
24986        if (cond.Is(al)) {
24987          const DRegister& first = nreglist.GetFirstDRegister();
24988          EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) |
24989                  (encoded_align_2.GetEncodingValue() << 4) |
24990                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
24991          return;
24992        }
24993      }
24994    }
24995  }
24996  Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand);
24997}
24998
24999void Assembler::vst2(Condition cond,
25000                     DataType dt,
25001                     const NeonRegisterList& nreglist,
25002                     const AlignedMemOperand& operand) {
25003  VIXL_ASSERT(AllowAssembler());
25004  CheckIT(cond);
25005  if (operand.IsImmediateZero()) {
25006    Register rn = operand.GetBaseRegister();
25007    Alignment align = operand.GetAlignment();
25008    Dt_size_7 encoded_dt(dt);
25009    Align_align_2 encoded_align_1(align, nreglist);
25010    Align_index_align_2 encoded_align_2(align, nreglist, dt);
25011    if (IsUsingT32()) {
25012      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25013      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25014          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25015           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25016           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25017          operand.IsOffset() && encoded_align_1.IsValid() &&
25018          (!rn.IsPC() || AllowUnpredictable())) {
25019        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25020          const DRegister& first = nreglist.GetFirstDRegister();
25021          uint32_t len_encoding;
25022          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25023            len_encoding = 0x8;
25024          }
25025          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25026            len_encoding = 0x9;
25027          }
25028          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25029            len_encoding = 0x3;
25030          }
25031          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
25032                     (encoded_align_1.GetEncodingValue() << 4) |
25033                     first.Encode(22, 12) | (len_encoding << 8) |
25034                     (rn.GetCode() << 16));
25035          AdvanceIT();
25036          return;
25037        }
25038      }
25039      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25040      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25041          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25042           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25043           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25044          operand.IsPostIndex() && encoded_align_1.IsValid() &&
25045          (!rn.IsPC() || AllowUnpredictable())) {
25046        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25047          const DRegister& first = nreglist.GetFirstDRegister();
25048          uint32_t len_encoding;
25049          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25050            len_encoding = 0x8;
25051          }
25052          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25053            len_encoding = 0x9;
25054          }
25055          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25056            len_encoding = 0x3;
25057          }
25058          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
25059                     (encoded_align_1.GetEncodingValue() << 4) |
25060                     first.Encode(22, 12) | (len_encoding << 8) |
25061                     (rn.GetCode() << 16));
25062          AdvanceIT();
25063          return;
25064        }
25065      }
25066      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25067      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25068          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25069           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25070          operand.IsOffset() && encoded_align_2.IsValid() &&
25071          (!rn.IsPC() || AllowUnpredictable())) {
25072        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25073          const DRegister& first = nreglist.GetFirstDRegister();
25074          EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) |
25075                     (encoded_align_2.GetEncodingValue() << 4) |
25076                     first.Encode(22, 12) | (rn.GetCode() << 16));
25077          AdvanceIT();
25078          return;
25079        }
25080      }
25081      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25082      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25083          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25084           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25085          operand.IsPostIndex() && encoded_align_2.IsValid() &&
25086          (!rn.IsPC() || AllowUnpredictable())) {
25087        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25088          const DRegister& first = nreglist.GetFirstDRegister();
25089          EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) |
25090                     (encoded_align_2.GetEncodingValue() << 4) |
25091                     first.Encode(22, 12) | (rn.GetCode() << 16));
25092          AdvanceIT();
25093          return;
25094        }
25095      }
25096    } else {
25097      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25098      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25099          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25100           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25101           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25102          operand.IsOffset() && encoded_align_1.IsValid() &&
25103          (!rn.IsPC() || AllowUnpredictable())) {
25104        if (cond.Is(al)) {
25105          const DRegister& first = nreglist.GetFirstDRegister();
25106          uint32_t len_encoding;
25107          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25108            len_encoding = 0x8;
25109          }
25110          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25111            len_encoding = 0x9;
25112          }
25113          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25114            len_encoding = 0x3;
25115          }
25116          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
25117                  (encoded_align_1.GetEncodingValue() << 4) |
25118                  first.Encode(22, 12) | (len_encoding << 8) |
25119                  (rn.GetCode() << 16));
25120          return;
25121        }
25122      }
25123      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25124      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25125          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25126           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25127           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25128          operand.IsPostIndex() && encoded_align_1.IsValid() &&
25129          (!rn.IsPC() || AllowUnpredictable())) {
25130        if (cond.Is(al)) {
25131          const DRegister& first = nreglist.GetFirstDRegister();
25132          uint32_t len_encoding;
25133          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25134            len_encoding = 0x8;
25135          }
25136          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25137            len_encoding = 0x9;
25138          }
25139          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25140            len_encoding = 0x3;
25141          }
25142          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
25143                  (encoded_align_1.GetEncodingValue() << 4) |
25144                  first.Encode(22, 12) | (len_encoding << 8) |
25145                  (rn.GetCode() << 16));
25146          return;
25147        }
25148      }
25149      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25150      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25151          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25152           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25153          operand.IsOffset() && encoded_align_2.IsValid() &&
25154          (!rn.IsPC() || AllowUnpredictable())) {
25155        if (cond.Is(al)) {
25156          const DRegister& first = nreglist.GetFirstDRegister();
25157          EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) |
25158                  (encoded_align_2.GetEncodingValue() << 4) |
25159                  first.Encode(22, 12) | (rn.GetCode() << 16));
25160          return;
25161        }
25162      }
25163      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25164      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25165          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25166           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25167          operand.IsPostIndex() && encoded_align_2.IsValid() &&
25168          (!rn.IsPC() || AllowUnpredictable())) {
25169        if (cond.Is(al)) {
25170          const DRegister& first = nreglist.GetFirstDRegister();
25171          EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) |
25172                  (encoded_align_2.GetEncodingValue() << 4) |
25173                  first.Encode(22, 12) | (rn.GetCode() << 16));
25174          return;
25175        }
25176      }
25177    }
25178  }
25179  if (operand.IsPlainRegister()) {
25180    Register rn = operand.GetBaseRegister();
25181    Alignment align = operand.GetAlignment();
25182    Register rm = operand.GetOffsetRegister();
25183    Dt_size_7 encoded_dt(dt);
25184    Align_align_2 encoded_align_1(align, nreglist);
25185    Align_index_align_2 encoded_align_2(align, nreglist, dt);
25186    if (IsUsingT32()) {
25187      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25188      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25189          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25190           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25191           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25192          !rm.IsPC() && !rm.IsSP()) {
25193        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25194          const DRegister& first = nreglist.GetFirstDRegister();
25195          uint32_t len_encoding;
25196          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25197            len_encoding = 0x8;
25198          }
25199          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25200            len_encoding = 0x9;
25201          }
25202          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25203            len_encoding = 0x3;
25204          }
25205          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
25206                     (encoded_align_1.GetEncodingValue() << 4) |
25207                     first.Encode(22, 12) | (len_encoding << 8) |
25208                     (rn.GetCode() << 16) | rm.GetCode());
25209          AdvanceIT();
25210          return;
25211        }
25212      }
25213      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25214      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25215          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25216           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25217          !rm.IsPC() && !rm.IsSP()) {
25218        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25219          const DRegister& first = nreglist.GetFirstDRegister();
25220          EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) |
25221                     (encoded_align_2.GetEncodingValue() << 4) |
25222                     first.Encode(22, 12) | (rn.GetCode() << 16) |
25223                     rm.GetCode());
25224          AdvanceIT();
25225          return;
25226        }
25227      }
25228    } else {
25229      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25230      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25231          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25232           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25233           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25234          !rm.IsPC() && !rm.IsSP()) {
25235        if (cond.Is(al)) {
25236          const DRegister& first = nreglist.GetFirstDRegister();
25237          uint32_t len_encoding;
25238          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25239            len_encoding = 0x8;
25240          }
25241          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25242            len_encoding = 0x9;
25243          }
25244          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25245            len_encoding = 0x3;
25246          }
25247          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
25248                  (encoded_align_1.GetEncodingValue() << 4) |
25249                  first.Encode(22, 12) | (len_encoding << 8) |
25250                  (rn.GetCode() << 16) | rm.GetCode());
25251          return;
25252        }
25253      }
25254      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25255      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25256          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25257           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25258          !rm.IsPC() && !rm.IsSP()) {
25259        if (cond.Is(al)) {
25260          const DRegister& first = nreglist.GetFirstDRegister();
25261          EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) |
25262                  (encoded_align_2.GetEncodingValue() << 4) |
25263                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
25264          return;
25265        }
25266      }
25267    }
25268  }
25269  Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand);
25270}
25271
25272void Assembler::vst3(Condition cond,
25273                     DataType dt,
25274                     const NeonRegisterList& nreglist,
25275                     const AlignedMemOperand& operand) {
25276  VIXL_ASSERT(AllowAssembler());
25277  CheckIT(cond);
25278  if (operand.IsImmediateZero()) {
25279    Register rn = operand.GetBaseRegister();
25280    Alignment align = operand.GetAlignment();
25281    Dt_size_7 encoded_dt(dt);
25282    Align_align_3 encoded_align_1(align);
25283    if (IsUsingT32()) {
25284      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25285      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25286          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25287           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25288          operand.IsOffset() && encoded_align_1.IsValid() &&
25289          (!rn.IsPC() || AllowUnpredictable())) {
25290        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25291          const DRegister& first = nreglist.GetFirstDRegister();
25292          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25293          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
25294                     (encoded_align_1.GetEncodingValue() << 4) |
25295                     first.Encode(22, 12) | (len_encoding << 8) |
25296                     (rn.GetCode() << 16));
25297          AdvanceIT();
25298          return;
25299        }
25300      }
25301      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25302      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25303          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25304           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25305          operand.IsPostIndex() && encoded_align_1.IsValid() &&
25306          (!rn.IsPC() || AllowUnpredictable())) {
25307        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25308          const DRegister& first = nreglist.GetFirstDRegister();
25309          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25310          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
25311                     (encoded_align_1.GetEncodingValue() << 4) |
25312                     first.Encode(22, 12) | (len_encoding << 8) |
25313                     (rn.GetCode() << 16));
25314          AdvanceIT();
25315          return;
25316        }
25317      }
25318    } else {
25319      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25320      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25321          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25322           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25323          operand.IsOffset() && encoded_align_1.IsValid() &&
25324          (!rn.IsPC() || AllowUnpredictable())) {
25325        if (cond.Is(al)) {
25326          const DRegister& first = nreglist.GetFirstDRegister();
25327          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25328          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
25329                  (encoded_align_1.GetEncodingValue() << 4) |
25330                  first.Encode(22, 12) | (len_encoding << 8) |
25331                  (rn.GetCode() << 16));
25332          return;
25333        }
25334      }
25335      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25336      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25337          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25338           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25339          operand.IsPostIndex() && encoded_align_1.IsValid() &&
25340          (!rn.IsPC() || AllowUnpredictable())) {
25341        if (cond.Is(al)) {
25342          const DRegister& first = nreglist.GetFirstDRegister();
25343          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25344          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
25345                  (encoded_align_1.GetEncodingValue() << 4) |
25346                  first.Encode(22, 12) | (len_encoding << 8) |
25347                  (rn.GetCode() << 16));
25348          return;
25349        }
25350      }
25351    }
25352  }
25353  if (operand.IsPlainRegister()) {
25354    Register rn = operand.GetBaseRegister();
25355    Alignment align = operand.GetAlignment();
25356    Register rm = operand.GetOffsetRegister();
25357    Dt_size_7 encoded_dt(dt);
25358    Align_align_3 encoded_align_1(align);
25359    if (IsUsingT32()) {
25360      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25361      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25362          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25363           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25364          !rm.IsPC() && !rm.IsSP()) {
25365        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25366          const DRegister& first = nreglist.GetFirstDRegister();
25367          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25368          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
25369                     (encoded_align_1.GetEncodingValue() << 4) |
25370                     first.Encode(22, 12) | (len_encoding << 8) |
25371                     (rn.GetCode() << 16) | rm.GetCode());
25372          AdvanceIT();
25373          return;
25374        }
25375      }
25376    } else {
25377      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25378      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25379          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25380           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25381          !rm.IsPC() && !rm.IsSP()) {
25382        if (cond.Is(al)) {
25383          const DRegister& first = nreglist.GetFirstDRegister();
25384          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25385          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
25386                  (encoded_align_1.GetEncodingValue() << 4) |
25387                  first.Encode(22, 12) | (len_encoding << 8) |
25388                  (rn.GetCode() << 16) | rm.GetCode());
25389          return;
25390        }
25391      }
25392    }
25393  }
25394  Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
25395}
25396
25397void Assembler::vst3(Condition cond,
25398                     DataType dt,
25399                     const NeonRegisterList& nreglist,
25400                     const MemOperand& operand) {
25401  VIXL_ASSERT(AllowAssembler());
25402  CheckIT(cond);
25403  if (operand.IsImmediateZero()) {
25404    Register rn = operand.GetBaseRegister();
25405    Dt_size_7 encoded_dt(dt);
25406    Index_1 encoded_align_1(nreglist, dt);
25407    if (IsUsingT32()) {
25408      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
25409      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25410          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25411           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25412          operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
25413        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25414          const DRegister& first = nreglist.GetFirstDRegister();
25415          EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) |
25416                     (encoded_align_1.GetEncodingValue() << 4) |
25417                     first.Encode(22, 12) | (rn.GetCode() << 16));
25418          AdvanceIT();
25419          return;
25420        }
25421      }
25422      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
25423      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25424          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25425           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25426          operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
25427        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25428          const DRegister& first = nreglist.GetFirstDRegister();
25429          EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) |
25430                     (encoded_align_1.GetEncodingValue() << 4) |
25431                     first.Encode(22, 12) | (rn.GetCode() << 16));
25432          AdvanceIT();
25433          return;
25434        }
25435      }
25436    } else {
25437      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
25438      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25439          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25440           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25441          operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
25442        if (cond.Is(al)) {
25443          const DRegister& first = nreglist.GetFirstDRegister();
25444          EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) |
25445                  (encoded_align_1.GetEncodingValue() << 4) |
25446                  first.Encode(22, 12) | (rn.GetCode() << 16));
25447          return;
25448        }
25449      }
25450      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
25451      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25452          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25453           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25454          operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
25455        if (cond.Is(al)) {
25456          const DRegister& first = nreglist.GetFirstDRegister();
25457          EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) |
25458                  (encoded_align_1.GetEncodingValue() << 4) |
25459                  first.Encode(22, 12) | (rn.GetCode() << 16));
25460          return;
25461        }
25462      }
25463    }
25464  }
25465  if (operand.IsPlainRegister()) {
25466    Register rn = operand.GetBaseRegister();
25467    Sign sign = operand.GetSign();
25468    Register rm = operand.GetOffsetRegister();
25469    Dt_size_7 encoded_dt(dt);
25470    Index_1 encoded_align_1(nreglist, dt);
25471    if (IsUsingT32()) {
25472      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
25473      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25474          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25475           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25476          sign.IsPlus() && operand.IsPostIndex()) {
25477        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25478          const DRegister& first = nreglist.GetFirstDRegister();
25479          EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) |
25480                     (encoded_align_1.GetEncodingValue() << 4) |
25481                     first.Encode(22, 12) | (rn.GetCode() << 16) |
25482                     rm.GetCode());
25483          AdvanceIT();
25484          return;
25485        }
25486      }
25487    } else {
25488      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
25489      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25490          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25491           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25492          sign.IsPlus() && operand.IsPostIndex()) {
25493        if (cond.Is(al)) {
25494          const DRegister& first = nreglist.GetFirstDRegister();
25495          EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) |
25496                  (encoded_align_1.GetEncodingValue() << 4) |
25497                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
25498          return;
25499        }
25500      }
25501    }
25502  }
25503  Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
25504}
25505
25506void Assembler::vst4(Condition cond,
25507                     DataType dt,
25508                     const NeonRegisterList& nreglist,
25509                     const AlignedMemOperand& operand) {
25510  VIXL_ASSERT(AllowAssembler());
25511  CheckIT(cond);
25512  if (operand.IsImmediateZero()) {
25513    Register rn = operand.GetBaseRegister();
25514    Alignment align = operand.GetAlignment();
25515    Dt_size_7 encoded_dt(dt);
25516    Align_align_4 encoded_align_1(align);
25517    Align_index_align_3 encoded_align_2(align, nreglist, dt);
25518    if (IsUsingT32()) {
25519      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25520      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25521          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25522           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25523          operand.IsOffset() && encoded_align_1.IsValid() &&
25524          (!rn.IsPC() || AllowUnpredictable())) {
25525        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25526          const DRegister& first = nreglist.GetFirstDRegister();
25527          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25528          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
25529                     (encoded_align_1.GetEncodingValue() << 4) |
25530                     first.Encode(22, 12) | (len_encoding << 8) |
25531                     (rn.GetCode() << 16));
25532          AdvanceIT();
25533          return;
25534        }
25535      }
25536      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25537      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25538          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25539           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25540          operand.IsPostIndex() && encoded_align_1.IsValid() &&
25541          (!rn.IsPC() || AllowUnpredictable())) {
25542        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25543          const DRegister& first = nreglist.GetFirstDRegister();
25544          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25545          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
25546                     (encoded_align_1.GetEncodingValue() << 4) |
25547                     first.Encode(22, 12) | (len_encoding << 8) |
25548                     (rn.GetCode() << 16));
25549          AdvanceIT();
25550          return;
25551        }
25552      }
25553      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25554      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25555          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25556           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25557          operand.IsOffset() && encoded_align_2.IsValid() &&
25558          (!rn.IsPC() || AllowUnpredictable())) {
25559        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25560          const DRegister& first = nreglist.GetFirstDRegister();
25561          EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) |
25562                     (encoded_align_2.GetEncodingValue() << 4) |
25563                     first.Encode(22, 12) | (rn.GetCode() << 16));
25564          AdvanceIT();
25565          return;
25566        }
25567      }
25568      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25569      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25570          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25571           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25572          operand.IsPostIndex() && encoded_align_2.IsValid() &&
25573          (!rn.IsPC() || AllowUnpredictable())) {
25574        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25575          const DRegister& first = nreglist.GetFirstDRegister();
25576          EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) |
25577                     (encoded_align_2.GetEncodingValue() << 4) |
25578                     first.Encode(22, 12) | (rn.GetCode() << 16));
25579          AdvanceIT();
25580          return;
25581        }
25582      }
25583    } else {
25584      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25585      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25586          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25587           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25588          operand.IsOffset() && encoded_align_1.IsValid() &&
25589          (!rn.IsPC() || AllowUnpredictable())) {
25590        if (cond.Is(al)) {
25591          const DRegister& first = nreglist.GetFirstDRegister();
25592          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25593          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
25594                  (encoded_align_1.GetEncodingValue() << 4) |
25595                  first.Encode(22, 12) | (len_encoding << 8) |
25596                  (rn.GetCode() << 16));
25597          return;
25598        }
25599      }
25600      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25601      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25602          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25603           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25604          operand.IsPostIndex() && encoded_align_1.IsValid() &&
25605          (!rn.IsPC() || AllowUnpredictable())) {
25606        if (cond.Is(al)) {
25607          const DRegister& first = nreglist.GetFirstDRegister();
25608          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25609          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
25610                  (encoded_align_1.GetEncodingValue() << 4) |
25611                  first.Encode(22, 12) | (len_encoding << 8) |
25612                  (rn.GetCode() << 16));
25613          return;
25614        }
25615      }
25616      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25617      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25618          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25619           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25620          operand.IsOffset() && encoded_align_2.IsValid() &&
25621          (!rn.IsPC() || AllowUnpredictable())) {
25622        if (cond.Is(al)) {
25623          const DRegister& first = nreglist.GetFirstDRegister();
25624          EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) |
25625                  (encoded_align_2.GetEncodingValue() << 4) |
25626                  first.Encode(22, 12) | (rn.GetCode() << 16));
25627          return;
25628        }
25629      }
25630      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25631      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25632          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25633           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25634          operand.IsPostIndex() && encoded_align_2.IsValid() &&
25635          (!rn.IsPC() || AllowUnpredictable())) {
25636        if (cond.Is(al)) {
25637          const DRegister& first = nreglist.GetFirstDRegister();
25638          EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) |
25639                  (encoded_align_2.GetEncodingValue() << 4) |
25640                  first.Encode(22, 12) | (rn.GetCode() << 16));
25641          return;
25642        }
25643      }
25644    }
25645  }
25646  if (operand.IsPlainRegister()) {
25647    Register rn = operand.GetBaseRegister();
25648    Alignment align = operand.GetAlignment();
25649    Register rm = operand.GetOffsetRegister();
25650    Dt_size_7 encoded_dt(dt);
25651    Align_align_4 encoded_align_1(align);
25652    Align_index_align_3 encoded_align_2(align, nreglist, dt);
25653    if (IsUsingT32()) {
25654      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25655      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25656          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25657           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25658          !rm.IsPC() && !rm.IsSP()) {
25659        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25660          const DRegister& first = nreglist.GetFirstDRegister();
25661          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25662          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
25663                     (encoded_align_1.GetEncodingValue() << 4) |
25664                     first.Encode(22, 12) | (len_encoding << 8) |
25665                     (rn.GetCode() << 16) | rm.GetCode());
25666          AdvanceIT();
25667          return;
25668        }
25669      }
25670      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25671      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25672          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25673           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25674          !rm.IsPC() && !rm.IsSP()) {
25675        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25676          const DRegister& first = nreglist.GetFirstDRegister();
25677          EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) |
25678                     (encoded_align_2.GetEncodingValue() << 4) |
25679                     first.Encode(22, 12) | (rn.GetCode() << 16) |
25680                     rm.GetCode());
25681          AdvanceIT();
25682          return;
25683        }
25684      }
25685    } else {
25686      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25687      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25688          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25689           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25690          !rm.IsPC() && !rm.IsSP()) {
25691        if (cond.Is(al)) {
25692          const DRegister& first = nreglist.GetFirstDRegister();
25693          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25694          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
25695                  (encoded_align_1.GetEncodingValue() << 4) |
25696                  first.Encode(22, 12) | (len_encoding << 8) |
25697                  (rn.GetCode() << 16) | rm.GetCode());
25698          return;
25699        }
25700      }
25701      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25702      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25703          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25704           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25705          !rm.IsPC() && !rm.IsSP()) {
25706        if (cond.Is(al)) {
25707          const DRegister& first = nreglist.GetFirstDRegister();
25708          EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) |
25709                  (encoded_align_2.GetEncodingValue() << 4) |
25710                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
25711          return;
25712        }
25713      }
25714    }
25715  }
25716  Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand);
25717}
25718
25719void Assembler::vstm(Condition cond,
25720                     DataType dt,
25721                     Register rn,
25722                     WriteBack write_back,
25723                     DRegisterList dreglist) {
25724  VIXL_ASSERT(AllowAssembler());
25725  CheckIT(cond);
25726  USE(dt);
25727  if (IsUsingT32()) {
25728    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
25729    if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25730      const DRegister& dreg = dreglist.GetFirstDRegister();
25731      unsigned len = dreglist.GetLength() * 2;
25732      EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
25733                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25734                 (len & 0xff));
25735      AdvanceIT();
25736      return;
25737    }
25738  } else {
25739    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
25740    if (cond.IsNotNever() &&
25741        ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25742      const DRegister& dreg = dreglist.GetFirstDRegister();
25743      unsigned len = dreglist.GetLength() * 2;
25744      EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25745              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25746              (len & 0xff));
25747      return;
25748    }
25749  }
25750  Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist);
25751}
25752
25753void Assembler::vstm(Condition cond,
25754                     DataType dt,
25755                     Register rn,
25756                     WriteBack write_back,
25757                     SRegisterList sreglist) {
25758  VIXL_ASSERT(AllowAssembler());
25759  CheckIT(cond);
25760  USE(dt);
25761  if (IsUsingT32()) {
25762    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
25763    const SRegister& sreg = sreglist.GetFirstSRegister();
25764    unsigned len = sreglist.GetLength();
25765    EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
25766               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25767               (len & 0xff));
25768    AdvanceIT();
25769    return;
25770  } else {
25771    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
25772    if (cond.IsNotNever()) {
25773      const SRegister& sreg = sreglist.GetFirstSRegister();
25774      unsigned len = sreglist.GetLength();
25775      EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25776              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25777              (len & 0xff));
25778      return;
25779    }
25780  }
25781  Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist);
25782}
25783
25784void Assembler::vstmdb(Condition cond,
25785                       DataType dt,
25786                       Register rn,
25787                       WriteBack write_back,
25788                       DRegisterList dreglist) {
25789  VIXL_ASSERT(AllowAssembler());
25790  CheckIT(cond);
25791  USE(dt);
25792  if (IsUsingT32()) {
25793    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
25794    if (write_back.DoesWriteBack() &&
25795        ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25796      const DRegister& dreg = dreglist.GetFirstDRegister();
25797      unsigned len = dreglist.GetLength() * 2;
25798      EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
25799                 (len & 0xff));
25800      AdvanceIT();
25801      return;
25802    }
25803  } else {
25804    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
25805    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
25806        ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25807      const DRegister& dreg = dreglist.GetFirstDRegister();
25808      unsigned len = dreglist.GetLength() * 2;
25809      EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25810              dreg.Encode(22, 12) | (len & 0xff));
25811      return;
25812    }
25813  }
25814  Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist);
25815}
25816
25817void Assembler::vstmdb(Condition cond,
25818                       DataType dt,
25819                       Register rn,
25820                       WriteBack write_back,
25821                       SRegisterList sreglist) {
25822  VIXL_ASSERT(AllowAssembler());
25823  CheckIT(cond);
25824  USE(dt);
25825  if (IsUsingT32()) {
25826    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
25827    if (write_back.DoesWriteBack()) {
25828      const SRegister& sreg = sreglist.GetFirstSRegister();
25829      unsigned len = sreglist.GetLength();
25830      EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
25831                 (len & 0xff));
25832      AdvanceIT();
25833      return;
25834    }
25835  } else {
25836    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
25837    if (write_back.DoesWriteBack() && cond.IsNotNever()) {
25838      const SRegister& sreg = sreglist.GetFirstSRegister();
25839      unsigned len = sreglist.GetLength();
25840      EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25841              sreg.Encode(22, 12) | (len & 0xff));
25842      return;
25843    }
25844  }
25845  Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist);
25846}
25847
25848void Assembler::vstmia(Condition cond,
25849                       DataType dt,
25850                       Register rn,
25851                       WriteBack write_back,
25852                       DRegisterList dreglist) {
25853  VIXL_ASSERT(AllowAssembler());
25854  CheckIT(cond);
25855  USE(dt);
25856  if (IsUsingT32()) {
25857    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
25858    if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25859      const DRegister& dreg = dreglist.GetFirstDRegister();
25860      unsigned len = dreglist.GetLength() * 2;
25861      EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
25862                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25863                 (len & 0xff));
25864      AdvanceIT();
25865      return;
25866    }
25867  } else {
25868    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
25869    if (cond.IsNotNever() &&
25870        ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25871      const DRegister& dreg = dreglist.GetFirstDRegister();
25872      unsigned len = dreglist.GetLength() * 2;
25873      EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25874              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25875              (len & 0xff));
25876      return;
25877    }
25878  }
25879  Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist);
25880}
25881
25882void Assembler::vstmia(Condition cond,
25883                       DataType dt,
25884                       Register rn,
25885                       WriteBack write_back,
25886                       SRegisterList sreglist) {
25887  VIXL_ASSERT(AllowAssembler());
25888  CheckIT(cond);
25889  USE(dt);
25890  if (IsUsingT32()) {
25891    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
25892    const SRegister& sreg = sreglist.GetFirstSRegister();
25893    unsigned len = sreglist.GetLength();
25894    EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
25895               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25896               (len & 0xff));
25897    AdvanceIT();
25898    return;
25899  } else {
25900    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
25901    if (cond.IsNotNever()) {
25902      const SRegister& sreg = sreglist.GetFirstSRegister();
25903      unsigned len = sreglist.GetLength();
25904      EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25905              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25906              (len & 0xff));
25907      return;
25908    }
25909  }
25910  Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist);
25911}
25912
25913void Assembler::vstr(Condition cond,
25914                     DataType dt,
25915                     DRegister rd,
25916                     const MemOperand& operand) {
25917  VIXL_ASSERT(AllowAssembler());
25918  CheckIT(cond);
25919  if (operand.IsImmediate()) {
25920    Register rn = operand.GetBaseRegister();
25921    int32_t offset = operand.GetOffsetImmediate();
25922    if (IsUsingT32()) {
25923      // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
25924      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
25925          ((offset % 4) == 0) && operand.IsOffset()) {
25926        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25927        uint32_t offset_ = abs(offset) >> 2;
25928        EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
25929                   offset_ | (sign << 23));
25930        AdvanceIT();
25931        return;
25932      }
25933    } else {
25934      // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
25935      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
25936          ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
25937        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25938        uint32_t offset_ = abs(offset) >> 2;
25939        EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25940                (rn.GetCode() << 16) | offset_ | (sign << 23));
25941        return;
25942      }
25943    }
25944  }
25945  Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
25946}
25947
25948void Assembler::vstr(Condition cond,
25949                     DataType dt,
25950                     SRegister rd,
25951                     const MemOperand& operand) {
25952  VIXL_ASSERT(AllowAssembler());
25953  CheckIT(cond);
25954  if (operand.IsImmediate()) {
25955    Register rn = operand.GetBaseRegister();
25956    int32_t offset = operand.GetOffsetImmediate();
25957    if (IsUsingT32()) {
25958      // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
25959      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
25960          ((offset % 4) == 0) && operand.IsOffset()) {
25961        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25962        uint32_t offset_ = abs(offset) >> 2;
25963        EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
25964                   offset_ | (sign << 23));
25965        AdvanceIT();
25966        return;
25967      }
25968    } else {
25969      // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
25970      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
25971          ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
25972        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25973        uint32_t offset_ = abs(offset) >> 2;
25974        EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25975                (rn.GetCode() << 16) | offset_ | (sign << 23));
25976        return;
25977      }
25978    }
25979  }
25980  Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
25981}
25982
25983void Assembler::vsub(
25984    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25985  VIXL_ASSERT(AllowAssembler());
25986  CheckIT(cond);
25987  Dt_size_2 encoded_dt(dt);
25988  if (IsUsingT32()) {
25989    // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
25990    if (dt.Is(F32)) {
25991      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25992        EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25993                   rm.Encode(5, 0));
25994        AdvanceIT();
25995        return;
25996      }
25997    }
25998    // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
25999    if (dt.Is(F64)) {
26000      EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26001                 rm.Encode(5, 0));
26002      AdvanceIT();
26003      return;
26004    }
26005    // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
26006    if (encoded_dt.IsValid()) {
26007      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26008        EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) |
26009                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26010        AdvanceIT();
26011        return;
26012      }
26013    }
26014  } else {
26015    // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
26016    if (dt.Is(F32)) {
26017      if (cond.Is(al)) {
26018        EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26019                rm.Encode(5, 0));
26020        return;
26021      }
26022    }
26023    // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
26024    if (dt.Is(F64) && cond.IsNotNever()) {
26025      EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
26026              rn.Encode(7, 16) | rm.Encode(5, 0));
26027      return;
26028    }
26029    // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
26030    if (encoded_dt.IsValid()) {
26031      if (cond.Is(al)) {
26032        EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) |
26033                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26034        return;
26035      }
26036    }
26037  }
26038  Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
26039}
26040
26041void Assembler::vsub(
26042    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
26043  VIXL_ASSERT(AllowAssembler());
26044  CheckIT(cond);
26045  Dt_size_2 encoded_dt(dt);
26046  if (IsUsingT32()) {
26047    // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
26048    if (dt.Is(F32)) {
26049      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26050        EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26051                   rm.Encode(5, 0));
26052        AdvanceIT();
26053        return;
26054      }
26055    }
26056    // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
26057    if (encoded_dt.IsValid()) {
26058      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26059        EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) |
26060                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26061        AdvanceIT();
26062        return;
26063      }
26064    }
26065  } else {
26066    // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
26067    if (dt.Is(F32)) {
26068      if (cond.Is(al)) {
26069        EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26070                rm.Encode(5, 0));
26071        return;
26072      }
26073    }
26074    // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
26075    if (encoded_dt.IsValid()) {
26076      if (cond.Is(al)) {
26077        EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) |
26078                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26079        return;
26080      }
26081    }
26082  }
26083  Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
26084}
26085
26086void Assembler::vsub(
26087    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
26088  VIXL_ASSERT(AllowAssembler());
26089  CheckIT(cond);
26090  if (IsUsingT32()) {
26091    // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
26092    if (dt.Is(F32)) {
26093      EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26094                 rm.Encode(5, 0));
26095      AdvanceIT();
26096      return;
26097    }
26098  } else {
26099    // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
26100    if (dt.Is(F32) && cond.IsNotNever()) {
26101      EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
26102              rn.Encode(7, 16) | rm.Encode(5, 0));
26103      return;
26104    }
26105  }
26106  Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
26107}
26108
26109void Assembler::vsubhn(
26110    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
26111  VIXL_ASSERT(AllowAssembler());
26112  CheckIT(cond);
26113  Dt_size_3 encoded_dt(dt);
26114  if (IsUsingT32()) {
26115    // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
26116    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
26117      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26118        EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) |
26119                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26120        AdvanceIT();
26121        return;
26122      }
26123    }
26124  } else {
26125    // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
26126    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
26127      if (cond.Is(al)) {
26128        EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) |
26129                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26130        return;
26131      }
26132    }
26133  }
26134  Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm);
26135}
26136
26137void Assembler::vsubl(
26138    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
26139  VIXL_ASSERT(AllowAssembler());
26140  CheckIT(cond);
26141  Dt_U_size_1 encoded_dt(dt);
26142  if (IsUsingT32()) {
26143    // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
26144    if (encoded_dt.IsValid()) {
26145      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26146        EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26147                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
26148                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26149        AdvanceIT();
26150        return;
26151      }
26152    }
26153  } else {
26154    // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
26155    if (encoded_dt.IsValid()) {
26156      if (cond.Is(al)) {
26157        EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26158                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
26159                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26160        return;
26161      }
26162    }
26163  }
26164  Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm);
26165}
26166
26167void Assembler::vsubw(
26168    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
26169  VIXL_ASSERT(AllowAssembler());
26170  CheckIT(cond);
26171  Dt_U_size_1 encoded_dt(dt);
26172  if (IsUsingT32()) {
26173    // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
26174    if (encoded_dt.IsValid()) {
26175      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26176        EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26177                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
26178                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26179        AdvanceIT();
26180        return;
26181      }
26182    }
26183  } else {
26184    // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
26185    if (encoded_dt.IsValid()) {
26186      if (cond.Is(al)) {
26187        EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26188                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
26189                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26190        return;
26191      }
26192    }
26193  }
26194  Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm);
26195}
26196
26197void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26198  VIXL_ASSERT(AllowAssembler());
26199  CheckIT(cond);
26200  USE(dt);
26201  if (IsUsingT32()) {
26202    // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
26203    if (cond.Is(al) || AllowStronglyDiscouraged()) {
26204      EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
26205      AdvanceIT();
26206      return;
26207    }
26208  } else {
26209    // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
26210    if (cond.Is(al)) {
26211      EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
26212      return;
26213    }
26214  }
26215  Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
26216}
26217
26218void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26219  VIXL_ASSERT(AllowAssembler());
26220  CheckIT(cond);
26221  USE(dt);
26222  if (IsUsingT32()) {
26223    // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
26224    if (cond.Is(al) || AllowStronglyDiscouraged()) {
26225      EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
26226      AdvanceIT();
26227      return;
26228    }
26229  } else {
26230    // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
26231    if (cond.Is(al)) {
26232      EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
26233      return;
26234    }
26235  }
26236  Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
26237}
26238
26239void Assembler::vtbl(Condition cond,
26240                     DataType dt,
26241                     DRegister rd,
26242                     const NeonRegisterList& nreglist,
26243                     DRegister rm) {
26244  VIXL_ASSERT(AllowAssembler());
26245  CheckIT(cond);
26246  if (IsUsingT32()) {
26247    // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
26248    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26249        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26250      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26251        const DRegister& first = nreglist.GetFirstDRegister();
26252        uint32_t len_encoding = nreglist.GetLength() - 1;
26253        EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
26254                   (len_encoding << 8) | rm.Encode(5, 0));
26255        AdvanceIT();
26256        return;
26257      }
26258    }
26259  } else {
26260    // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
26261    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26262        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26263      if (cond.Is(al)) {
26264        const DRegister& first = nreglist.GetFirstDRegister();
26265        uint32_t len_encoding = nreglist.GetLength() - 1;
26266        EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
26267                (len_encoding << 8) | rm.Encode(5, 0));
26268        return;
26269      }
26270    }
26271  }
26272  Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm);
26273}
26274
26275void Assembler::vtbx(Condition cond,
26276                     DataType dt,
26277                     DRegister rd,
26278                     const NeonRegisterList& nreglist,
26279                     DRegister rm) {
26280  VIXL_ASSERT(AllowAssembler());
26281  CheckIT(cond);
26282  if (IsUsingT32()) {
26283    // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
26284    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26285        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26286      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26287        const DRegister& first = nreglist.GetFirstDRegister();
26288        uint32_t len_encoding = nreglist.GetLength() - 1;
26289        EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
26290                   (len_encoding << 8) | rm.Encode(5, 0));
26291        AdvanceIT();
26292        return;
26293      }
26294    }
26295  } else {
26296    // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
26297    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26298        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26299      if (cond.Is(al)) {
26300        const DRegister& first = nreglist.GetFirstDRegister();
26301        uint32_t len_encoding = nreglist.GetLength() - 1;
26302        EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
26303                (len_encoding << 8) | rm.Encode(5, 0));
26304        return;
26305      }
26306    }
26307  }
26308  Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm);
26309}
26310
26311void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26312  VIXL_ASSERT(AllowAssembler());
26313  CheckIT(cond);
26314  Dt_size_7 encoded_dt(dt);
26315  if (IsUsingT32()) {
26316    // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
26317    if (encoded_dt.IsValid()) {
26318      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26319        EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) |
26320                   rd.Encode(22, 12) | rm.Encode(5, 0));
26321        AdvanceIT();
26322        return;
26323      }
26324    }
26325  } else {
26326    // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
26327    if (encoded_dt.IsValid()) {
26328      if (cond.Is(al)) {
26329        EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) |
26330                rd.Encode(22, 12) | rm.Encode(5, 0));
26331        return;
26332      }
26333    }
26334  }
26335  Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
26336}
26337
26338void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26339  VIXL_ASSERT(AllowAssembler());
26340  CheckIT(cond);
26341  Dt_size_7 encoded_dt(dt);
26342  if (IsUsingT32()) {
26343    // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
26344    if (encoded_dt.IsValid()) {
26345      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26346        EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) |
26347                   rd.Encode(22, 12) | rm.Encode(5, 0));
26348        AdvanceIT();
26349        return;
26350      }
26351    }
26352  } else {
26353    // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
26354    if (encoded_dt.IsValid()) {
26355      if (cond.Is(al)) {
26356        EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) |
26357                rd.Encode(22, 12) | rm.Encode(5, 0));
26358        return;
26359      }
26360    }
26361  }
26362  Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
26363}
26364
26365void Assembler::vtst(
26366    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
26367  VIXL_ASSERT(AllowAssembler());
26368  CheckIT(cond);
26369  Dt_size_7 encoded_dt(dt);
26370  if (IsUsingT32()) {
26371    // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
26372    if (encoded_dt.IsValid()) {
26373      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26374        EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) |
26375                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26376        AdvanceIT();
26377        return;
26378      }
26379    }
26380  } else {
26381    // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
26382    if (encoded_dt.IsValid()) {
26383      if (cond.Is(al)) {
26384        EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) |
26385                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26386        return;
26387      }
26388    }
26389  }
26390  Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
26391}
26392
26393void Assembler::vtst(
26394    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
26395  VIXL_ASSERT(AllowAssembler());
26396  CheckIT(cond);
26397  Dt_size_7 encoded_dt(dt);
26398  if (IsUsingT32()) {
26399    // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
26400    if (encoded_dt.IsValid()) {
26401      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26402        EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) |
26403                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26404        AdvanceIT();
26405        return;
26406      }
26407    }
26408  } else {
26409    // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
26410    if (encoded_dt.IsValid()) {
26411      if (cond.Is(al)) {
26412        EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) |
26413                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26414        return;
26415      }
26416    }
26417  }
26418  Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
26419}
26420
26421void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26422  VIXL_ASSERT(AllowAssembler());
26423  CheckIT(cond);
26424  Dt_size_15 encoded_dt(dt);
26425  if (IsUsingT32()) {
26426    // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
26427    if (encoded_dt.IsValid()) {
26428      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26429        EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) |
26430                   rd.Encode(22, 12) | rm.Encode(5, 0));
26431        AdvanceIT();
26432        return;
26433      }
26434    }
26435    // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
26436    if (dt.Is(Untyped32)) {
26437      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26438        EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26439        AdvanceIT();
26440        return;
26441      }
26442    }
26443  } else {
26444    // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
26445    if (encoded_dt.IsValid()) {
26446      if (cond.Is(al)) {
26447        EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) |
26448                rd.Encode(22, 12) | rm.Encode(5, 0));
26449        return;
26450      }
26451    }
26452    // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
26453    if (dt.Is(Untyped32)) {
26454      if (cond.Is(al)) {
26455        EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26456        return;
26457      }
26458    }
26459  }
26460  Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
26461}
26462
26463void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26464  VIXL_ASSERT(AllowAssembler());
26465  CheckIT(cond);
26466  Dt_size_7 encoded_dt(dt);
26467  if (IsUsingT32()) {
26468    // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
26469    if (encoded_dt.IsValid()) {
26470      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26471        EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) |
26472                   rd.Encode(22, 12) | rm.Encode(5, 0));
26473        AdvanceIT();
26474        return;
26475      }
26476    }
26477  } else {
26478    // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
26479    if (encoded_dt.IsValid()) {
26480      if (cond.Is(al)) {
26481        EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) |
26482                rd.Encode(22, 12) | rm.Encode(5, 0));
26483        return;
26484      }
26485    }
26486  }
26487  Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
26488}
26489
26490void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26491  VIXL_ASSERT(AllowAssembler());
26492  CheckIT(cond);
26493  Dt_size_15 encoded_dt(dt);
26494  if (IsUsingT32()) {
26495    // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
26496    if (encoded_dt.IsValid()) {
26497      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26498        EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) |
26499                   rd.Encode(22, 12) | rm.Encode(5, 0));
26500        AdvanceIT();
26501        return;
26502      }
26503    }
26504    // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
26505    if (dt.Is(Untyped32)) {
26506      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26507        EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26508        AdvanceIT();
26509        return;
26510      }
26511    }
26512  } else {
26513    // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
26514    if (encoded_dt.IsValid()) {
26515      if (cond.Is(al)) {
26516        EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) |
26517                rd.Encode(22, 12) | rm.Encode(5, 0));
26518        return;
26519      }
26520    }
26521    // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
26522    if (dt.Is(Untyped32)) {
26523      if (cond.Is(al)) {
26524        EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26525        return;
26526      }
26527    }
26528  }
26529  Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
26530}
26531
26532void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26533  VIXL_ASSERT(AllowAssembler());
26534  CheckIT(cond);
26535  Dt_size_7 encoded_dt(dt);
26536  if (IsUsingT32()) {
26537    // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
26538    if (encoded_dt.IsValid()) {
26539      if (cond.Is(al) || AllowStronglyDiscouraged()) {
26540        EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) |
26541                   rd.Encode(22, 12) | rm.Encode(5, 0));
26542        AdvanceIT();
26543        return;
26544      }
26545    }
26546  } else {
26547    // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
26548    if (encoded_dt.IsValid()) {
26549      if (cond.Is(al)) {
26550        EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) |
26551                rd.Encode(22, 12) | rm.Encode(5, 0));
26552        return;
26553      }
26554    }
26555  }
26556  Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
26557}
26558
26559void Assembler::yield(Condition cond, EncodingSize size) {
26560  VIXL_ASSERT(AllowAssembler());
26561  CheckIT(cond);
26562  if (IsUsingT32()) {
26563    // YIELD{<c>}{<q>} ; T1
26564    if (!size.IsWide()) {
26565      EmitT32_16(0xbf10);
26566      AdvanceIT();
26567      return;
26568    }
26569    // YIELD{<c>}.W ; T2
26570    if (!size.IsNarrow()) {
26571      EmitT32_32(0xf3af8001U);
26572      AdvanceIT();
26573      return;
26574    }
26575  } else {
26576    // YIELD{<c>}{<q>} ; A1
26577    if (cond.IsNotNever()) {
26578      EmitA32(0x0320f001U | (cond.GetCondition() << 28));
26579      return;
26580    }
26581  }
26582  Delegate(kYield, &Assembler::yield, cond, size);
26583}
26584// End of generated code.
26585
26586}  // namespace aarch32
26587}  // namespace vixl
26588