assembler-aarch32.cc revision 78973f258039f6e96eba85f1b5ecdb14b3c51dbb
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>  // NOLINT
36
37#include "utils-vixl.h"
38#include "aarch32/constants-aarch32.h"
39#include "aarch32/instructions-aarch32.h"
40#include "aarch32/operand-aarch32.h"
41#include "aarch32/assembler-aarch32.h"
42
43namespace vixl {
44namespace aarch32 {
45
46void Assembler::EmitT32_16(uint16_t instr) {
47  VIXL_ASSERT(buffer_.Is16bitAligned());
48  buffer_.Emit16(instr);
49}
50
51
52void Assembler::EmitT32_32(uint32_t instr) {
53  VIXL_ASSERT(buffer_.Is16bitAligned());
54  buffer_.Emit16(static_cast<uint16_t>(instr >> 16));
55  buffer_.Emit16(static_cast<uint16_t>(instr & 0xffff));
56}
57
58
59void Assembler::EmitA32(uint32_t instr) {
60  VIXL_ASSERT(buffer_.Is32bitAligned());
61  buffer_.Emit32(instr);
62}
63
64
65#ifdef VIXL_DEBUG
66void Assembler::PerformCheckIT(Condition condition) {
67  if (it_mask_ == 0) {
68    VIXL_ASSERT(IsUsingA32() || condition.Is(al));
69  } else {
70    VIXL_ASSERT(condition.Is(first_condition_));
71    first_condition_ =
72        Condition((first_condition_.GetCondition() & 0xe) | (it_mask_ >> 3));
73    // For A32, AdavanceIT() is not called by the assembler. We must call it
74    // in order to check that IT instructions are used consistently with
75    // the following conditional instructions.
76    if (IsUsingA32()) AdvanceIT();
77  }
78}
79#endif
80
81
82uint32_t Assembler::Link(uint32_t instr,
83                         Label* label,
84                         const Label::LabelEmitOperator& op) {
85  if (label->IsBound()) {
86    return op.Encode(instr,
87                     GetCursorOffset() + GetArchitectureStatePCOffset(),
88                     label);
89  }
90  label->AddForwardRef(GetCursorOffset(), IsUsingT32(), op);
91  return instr;
92}
93
94
95void Assembler::EncodeLabelFor(const Label::ForwardReference& forward,
96                               Label* label) {
97  const uint32_t location = forward.GetLocation();
98  const uint32_t from = location + forward.GetStatePCOffset();
99  const Label::LabelEmitOperator& encoder = forward.GetEmitOperator();
100  if (forward.IsUsingT32()) {
101    uint16_t* instr_ptr = buffer_.GetOffsetAddress<uint16_t*>(location);
102    if (Is16BitEncoding(instr_ptr[0])) {
103      // The Encode methods always deals with uint32_t types so we need
104      // to explicitely cast it.
105      uint32_t instr = static_cast<uint32_t>(instr_ptr[0]);
106      instr = encoder.Encode(instr, from, label);
107      // The Encode method should not ever set the top 16 bits.
108      VIXL_ASSERT((instr & ~0xffff) == 0);
109      instr_ptr[0] = static_cast<uint16_t>(instr);
110    } else {
111      uint32_t instr =
112          instr_ptr[1] | (static_cast<uint32_t>(instr_ptr[0]) << 16);
113      instr = encoder.Encode(instr, from, label);
114      instr_ptr[0] = static_cast<uint16_t>(instr >> 16);
115      instr_ptr[1] = static_cast<uint16_t>(instr);
116    }
117  } else {
118    uint32_t* instr_ptr = buffer_.GetOffsetAddress<uint32_t*>(location);
119    instr_ptr[0] = encoder.Encode(instr_ptr[0], from, label);
120  }
121}
122
123
124void Assembler::bind(Label* label) {
125  VIXL_ASSERT(!label->IsBound());
126  label->Bind(GetCursorOffset(), IsUsingT32());
127
128  for (Label::ForwardRefList::iterator ref = label->GetFirstForwardRef();
129       ref != label->GetEndForwardRef();
130       ref++) {
131    EncodeLabelFor(*ref, label);
132  }
133}
134
135
136// Start of generated code.
137class Dt_L_imm6_1 : public EncodingValue {
138  uint32_t type_;
139
140 public:
141  explicit Dt_L_imm6_1(DataType dt);
142  uint32_t GetTypeEncodingValue() const { return type_; }
143};
144
145Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) {
146  switch (dt.GetValue()) {
147    case S8:
148      type_ = 0x0;
149      SetEncodingValue(0x1);
150      break;
151    case U8:
152      type_ = 0x1;
153      SetEncodingValue(0x1);
154      break;
155    case S16:
156      type_ = 0x0;
157      SetEncodingValue(0x2);
158      break;
159    case U16:
160      type_ = 0x1;
161      SetEncodingValue(0x2);
162      break;
163    case S32:
164      type_ = 0x0;
165      SetEncodingValue(0x4);
166      break;
167    case U32:
168      type_ = 0x1;
169      SetEncodingValue(0x4);
170      break;
171    case S64:
172      type_ = 0x0;
173      SetEncodingValue(0x8);
174      break;
175    case U64:
176      type_ = 0x1;
177      SetEncodingValue(0x8);
178      break;
179    default:
180      VIXL_UNREACHABLE();
181      type_ = 0x0;
182      break;
183  }
184}
185
186class Dt_L_imm6_2 : public EncodingValue {
187  uint32_t type_;
188
189 public:
190  explicit Dt_L_imm6_2(DataType dt);
191  uint32_t GetTypeEncodingValue() const { return type_; }
192};
193
194Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) {
195  switch (dt.GetValue()) {
196    case S8:
197      type_ = 0x1;
198      SetEncodingValue(0x1);
199      break;
200    case S16:
201      type_ = 0x1;
202      SetEncodingValue(0x2);
203      break;
204    case S32:
205      type_ = 0x1;
206      SetEncodingValue(0x4);
207      break;
208    case S64:
209      type_ = 0x1;
210      SetEncodingValue(0x8);
211      break;
212    default:
213      VIXL_UNREACHABLE();
214      type_ = 0x0;
215      break;
216  }
217}
218
219class Dt_L_imm6_3 : public EncodingValue {
220 public:
221  explicit Dt_L_imm6_3(DataType dt);
222};
223
224Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) {
225  switch (dt.GetValue()) {
226    case I8:
227      SetEncodingValue(0x1);
228      break;
229    case I16:
230      SetEncodingValue(0x2);
231      break;
232    case I32:
233      SetEncodingValue(0x4);
234      break;
235    case I64:
236      SetEncodingValue(0x8);
237      break;
238    default:
239      break;
240  }
241}
242
243class Dt_L_imm6_4 : public EncodingValue {
244 public:
245  explicit Dt_L_imm6_4(DataType dt);
246};
247
248Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) {
249  switch (dt.GetValue()) {
250    case Untyped8:
251      SetEncodingValue(0x1);
252      break;
253    case Untyped16:
254      SetEncodingValue(0x2);
255      break;
256    case Untyped32:
257      SetEncodingValue(0x4);
258      break;
259    case Untyped64:
260      SetEncodingValue(0x8);
261      break;
262    default:
263      break;
264  }
265}
266
267class Dt_imm6_1 : public EncodingValue {
268  uint32_t type_;
269
270 public:
271  explicit Dt_imm6_1(DataType dt);
272  uint32_t GetTypeEncodingValue() const { return type_; }
273};
274
275Dt_imm6_1::Dt_imm6_1(DataType dt) {
276  switch (dt.GetValue()) {
277    case S16:
278      type_ = 0x0;
279      SetEncodingValue(0x1);
280      break;
281    case U16:
282      type_ = 0x1;
283      SetEncodingValue(0x1);
284      break;
285    case S32:
286      type_ = 0x0;
287      SetEncodingValue(0x2);
288      break;
289    case U32:
290      type_ = 0x1;
291      SetEncodingValue(0x2);
292      break;
293    case S64:
294      type_ = 0x0;
295      SetEncodingValue(0x4);
296      break;
297    case U64:
298      type_ = 0x1;
299      SetEncodingValue(0x4);
300      break;
301    default:
302      VIXL_UNREACHABLE();
303      type_ = 0x0;
304      break;
305  }
306}
307
308class Dt_imm6_2 : public EncodingValue {
309  uint32_t type_;
310
311 public:
312  explicit Dt_imm6_2(DataType dt);
313  uint32_t GetTypeEncodingValue() const { return type_; }
314};
315
316Dt_imm6_2::Dt_imm6_2(DataType dt) {
317  switch (dt.GetValue()) {
318    case S16:
319      type_ = 0x1;
320      SetEncodingValue(0x1);
321      break;
322    case S32:
323      type_ = 0x1;
324      SetEncodingValue(0x2);
325      break;
326    case S64:
327      type_ = 0x1;
328      SetEncodingValue(0x4);
329      break;
330    default:
331      VIXL_UNREACHABLE();
332      type_ = 0x0;
333      break;
334  }
335}
336
337class Dt_imm6_3 : public EncodingValue {
338 public:
339  explicit Dt_imm6_3(DataType dt);
340};
341
342Dt_imm6_3::Dt_imm6_3(DataType dt) {
343  switch (dt.GetValue()) {
344    case I16:
345      SetEncodingValue(0x1);
346      break;
347    case I32:
348      SetEncodingValue(0x2);
349      break;
350    case I64:
351      SetEncodingValue(0x4);
352      break;
353    default:
354      break;
355  }
356}
357
358class Dt_imm6_4 : public EncodingValue {
359  uint32_t type_;
360
361 public:
362  explicit Dt_imm6_4(DataType dt);
363  uint32_t GetTypeEncodingValue() const { return type_; }
364};
365
366Dt_imm6_4::Dt_imm6_4(DataType dt) {
367  switch (dt.GetValue()) {
368    case S8:
369      type_ = 0x0;
370      SetEncodingValue(0x1);
371      break;
372    case U8:
373      type_ = 0x1;
374      SetEncodingValue(0x1);
375      break;
376    case S16:
377      type_ = 0x0;
378      SetEncodingValue(0x2);
379      break;
380    case U16:
381      type_ = 0x1;
382      SetEncodingValue(0x2);
383      break;
384    case S32:
385      type_ = 0x0;
386      SetEncodingValue(0x4);
387      break;
388    case U32:
389      type_ = 0x1;
390      SetEncodingValue(0x4);
391      break;
392    default:
393      VIXL_UNREACHABLE();
394      type_ = 0x0;
395      break;
396  }
397}
398
399class Dt_op_U_size_1 : public EncodingValue {
400 public:
401  explicit Dt_op_U_size_1(DataType dt);
402};
403
404Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) {
405  switch (dt.GetValue()) {
406    case S8:
407      SetEncodingValue(0x0);
408      break;
409    case S16:
410      SetEncodingValue(0x1);
411      break;
412    case S32:
413      SetEncodingValue(0x2);
414      break;
415    case U8:
416      SetEncodingValue(0x4);
417      break;
418    case U16:
419      SetEncodingValue(0x5);
420      break;
421    case U32:
422      SetEncodingValue(0x6);
423      break;
424    case P8:
425      SetEncodingValue(0x8);
426      break;
427    case P64:
428      SetEncodingValue(0xa);
429      break;
430    default:
431      break;
432  }
433}
434
435class Dt_op_size_1 : public EncodingValue {
436 public:
437  explicit Dt_op_size_1(DataType dt);
438};
439
440Dt_op_size_1::Dt_op_size_1(DataType dt) {
441  switch (dt.GetValue()) {
442    case I8:
443      SetEncodingValue(0x0);
444      break;
445    case I16:
446      SetEncodingValue(0x1);
447      break;
448    case I32:
449      SetEncodingValue(0x2);
450      break;
451    case P8:
452      SetEncodingValue(0x4);
453      break;
454    default:
455      break;
456  }
457}
458
459class Dt_op_size_2 : public EncodingValue {
460 public:
461  explicit Dt_op_size_2(DataType dt);
462};
463
464Dt_op_size_2::Dt_op_size_2(DataType dt) {
465  switch (dt.GetValue()) {
466    case S8:
467      SetEncodingValue(0x0);
468      break;
469    case S16:
470      SetEncodingValue(0x1);
471      break;
472    case S32:
473      SetEncodingValue(0x2);
474      break;
475    case U8:
476      SetEncodingValue(0x4);
477      break;
478    case U16:
479      SetEncodingValue(0x5);
480      break;
481    case U32:
482      SetEncodingValue(0x6);
483      break;
484    default:
485      break;
486  }
487}
488
489class Dt_op_size_3 : public EncodingValue {
490 public:
491  explicit Dt_op_size_3(DataType dt);
492};
493
494Dt_op_size_3::Dt_op_size_3(DataType dt) {
495  switch (dt.GetValue()) {
496    case S16:
497      SetEncodingValue(0x0);
498      break;
499    case S32:
500      SetEncodingValue(0x1);
501      break;
502    case S64:
503      SetEncodingValue(0x2);
504      break;
505    case U16:
506      SetEncodingValue(0x4);
507      break;
508    case U32:
509      SetEncodingValue(0x5);
510      break;
511    case U64:
512      SetEncodingValue(0x6);
513      break;
514    default:
515      break;
516  }
517}
518
519class Dt_U_imm3H_1 : public EncodingValue {
520 public:
521  explicit Dt_U_imm3H_1(DataType dt);
522};
523
524Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) {
525  switch (dt.GetValue()) {
526    case S8:
527      SetEncodingValue(0x1);
528      break;
529    case S16:
530      SetEncodingValue(0x2);
531      break;
532    case S32:
533      SetEncodingValue(0x4);
534      break;
535    case U8:
536      SetEncodingValue(0x9);
537      break;
538    case U16:
539      SetEncodingValue(0xa);
540      break;
541    case U32:
542      SetEncodingValue(0xc);
543      break;
544    default:
545      break;
546  }
547}
548
549class Dt_U_opc1_opc2_1 : public EncodingValue {
550 public:
551  explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
552};
553
554Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
555  switch (dt.GetValue()) {
556    case S8:
557      if ((lane.GetLane() & 7) != lane.GetLane()) {
558        return;
559      }
560      SetEncodingValue(0x8 | lane.GetLane());
561      break;
562    case S16:
563      if ((lane.GetLane() & 3) != lane.GetLane()) {
564        return;
565      }
566      SetEncodingValue(0x1 | (lane.GetLane() << 1));
567      break;
568    case U8:
569      if ((lane.GetLane() & 7) != lane.GetLane()) {
570        return;
571      }
572      SetEncodingValue(0x18 | lane.GetLane());
573      break;
574    case U16:
575      if ((lane.GetLane() & 3) != lane.GetLane()) {
576        return;
577      }
578      SetEncodingValue(0x11 | (lane.GetLane() << 1));
579      break;
580    case Untyped32:
581      if ((lane.GetLane() & 1) != lane.GetLane()) {
582        return;
583      }
584      SetEncodingValue(0x0 | (lane.GetLane() << 2));
585      break;
586    case kDataTypeValueNone:
587      if ((lane.GetLane() & 1) != lane.GetLane()) {
588        return;
589      }
590      SetEncodingValue(0x0 | (lane.GetLane() << 2));
591      break;
592    default:
593      break;
594  }
595}
596
597class Dt_opc1_opc2_1 : public EncodingValue {
598 public:
599  explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
600};
601
602Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
603  switch (dt.GetValue()) {
604    case Untyped8:
605      if ((lane.GetLane() & 7) != lane.GetLane()) {
606        return;
607      }
608      SetEncodingValue(0x8 | lane.GetLane());
609      break;
610    case Untyped16:
611      if ((lane.GetLane() & 3) != lane.GetLane()) {
612        return;
613      }
614      SetEncodingValue(0x1 | (lane.GetLane() << 1));
615      break;
616    case Untyped32:
617      if ((lane.GetLane() & 1) != lane.GetLane()) {
618        return;
619      }
620      SetEncodingValue(0x0 | (lane.GetLane() << 2));
621      break;
622    case kDataTypeValueNone:
623      if ((lane.GetLane() & 1) != lane.GetLane()) {
624        return;
625      }
626      SetEncodingValue(0x0 | (lane.GetLane() << 2));
627      break;
628    default:
629      break;
630  }
631}
632
633class Dt_imm4_1 : public EncodingValue {
634 public:
635  explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane);
636};
637
638Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) {
639  switch (dt.GetValue()) {
640    case Untyped8:
641      if ((lane.GetLane() & 7) != lane.GetLane()) {
642        return;
643      }
644      SetEncodingValue(0x1 | (lane.GetLane() << 1));
645      break;
646    case Untyped16:
647      if ((lane.GetLane() & 3) != lane.GetLane()) {
648        return;
649      }
650      SetEncodingValue(0x2 | (lane.GetLane() << 2));
651      break;
652    case Untyped32:
653      if ((lane.GetLane() & 1) != lane.GetLane()) {
654        return;
655      }
656      SetEncodingValue(0x4 | (lane.GetLane() << 3));
657      break;
658    default:
659      break;
660  }
661}
662
663class Dt_B_E_1 : public EncodingValue {
664 public:
665  explicit Dt_B_E_1(DataType dt);
666};
667
668Dt_B_E_1::Dt_B_E_1(DataType dt) {
669  switch (dt.GetValue()) {
670    case Untyped8:
671      SetEncodingValue(0x2);
672      break;
673    case Untyped16:
674      SetEncodingValue(0x1);
675      break;
676    case Untyped32:
677      SetEncodingValue(0x0);
678      break;
679    default:
680      break;
681  }
682}
683
684class Dt_op_1 : public EncodingValue {
685 public:
686  Dt_op_1(DataType dt1, DataType dt2);
687};
688
689Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) {
690  if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
691    SetEncodingValue(0x0);
692    return;
693  }
694  if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
695    SetEncodingValue(0x1);
696    return;
697  }
698  if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
699    SetEncodingValue(0x2);
700    return;
701  }
702  if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
703    SetEncodingValue(0x3);
704    return;
705  }
706}
707
708class Dt_op_2 : public EncodingValue {
709 public:
710  explicit Dt_op_2(DataType dt);
711};
712
713Dt_op_2::Dt_op_2(DataType dt) {
714  switch (dt.GetValue()) {
715    case U32:
716      SetEncodingValue(0x0);
717      break;
718    case S32:
719      SetEncodingValue(0x1);
720      break;
721    default:
722      break;
723  }
724}
725
726class Dt_op_3 : public EncodingValue {
727 public:
728  explicit Dt_op_3(DataType dt);
729};
730
731Dt_op_3::Dt_op_3(DataType dt) {
732  switch (dt.GetValue()) {
733    case S32:
734      SetEncodingValue(0x0);
735      break;
736    case U32:
737      SetEncodingValue(0x1);
738      break;
739    default:
740      break;
741  }
742}
743
744class Dt_U_sx_1 : public EncodingValue {
745 public:
746  explicit Dt_U_sx_1(DataType dt);
747};
748
749Dt_U_sx_1::Dt_U_sx_1(DataType dt) {
750  switch (dt.GetValue()) {
751    case S16:
752      SetEncodingValue(0x0);
753      break;
754    case S32:
755      SetEncodingValue(0x1);
756      break;
757    case U16:
758      SetEncodingValue(0x2);
759      break;
760    case U32:
761      SetEncodingValue(0x3);
762      break;
763    default:
764      break;
765  }
766}
767
768class Dt_op_U_1 : public EncodingValue {
769 public:
770  Dt_op_U_1(DataType dt1, DataType dt2);
771};
772
773Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) {
774  if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
775    SetEncodingValue(0x0);
776    return;
777  }
778  if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
779    SetEncodingValue(0x1);
780    return;
781  }
782  if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
783    SetEncodingValue(0x2);
784    return;
785  }
786  if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
787    SetEncodingValue(0x3);
788    return;
789  }
790}
791
792class Dt_sz_1 : public EncodingValue {
793 public:
794  explicit Dt_sz_1(DataType dt);
795};
796
797Dt_sz_1::Dt_sz_1(DataType dt) {
798  switch (dt.GetValue()) {
799    case F32:
800      SetEncodingValue(0x0);
801      break;
802    default:
803      break;
804  }
805}
806
807class Dt_F_size_1 : public EncodingValue {
808 public:
809  explicit Dt_F_size_1(DataType dt);
810};
811
812Dt_F_size_1::Dt_F_size_1(DataType dt) {
813  switch (dt.GetValue()) {
814    case S8:
815      SetEncodingValue(0x0);
816      break;
817    case S16:
818      SetEncodingValue(0x1);
819      break;
820    case S32:
821      SetEncodingValue(0x2);
822      break;
823    case F32:
824      SetEncodingValue(0x6);
825      break;
826    default:
827      break;
828  }
829}
830
831class Dt_F_size_2 : public EncodingValue {
832 public:
833  explicit Dt_F_size_2(DataType dt);
834};
835
836Dt_F_size_2::Dt_F_size_2(DataType dt) {
837  switch (dt.GetValue()) {
838    case I8:
839      SetEncodingValue(0x0);
840      break;
841    case I16:
842      SetEncodingValue(0x1);
843      break;
844    case I32:
845      SetEncodingValue(0x2);
846      break;
847    case F32:
848      SetEncodingValue(0x6);
849      break;
850    default:
851      break;
852  }
853}
854
855class Dt_F_size_3 : public EncodingValue {
856 public:
857  explicit Dt_F_size_3(DataType dt);
858};
859
860Dt_F_size_3::Dt_F_size_3(DataType dt) {
861  switch (dt.GetValue()) {
862    case I16:
863      SetEncodingValue(0x1);
864      break;
865    case I32:
866      SetEncodingValue(0x2);
867      break;
868    case F32:
869      SetEncodingValue(0x6);
870      break;
871    default:
872      break;
873  }
874}
875
876class Dt_F_size_4 : public EncodingValue {
877 public:
878  explicit Dt_F_size_4(DataType dt);
879};
880
881Dt_F_size_4::Dt_F_size_4(DataType dt) {
882  switch (dt.GetValue()) {
883    case U32:
884      SetEncodingValue(0x2);
885      break;
886    case F32:
887      SetEncodingValue(0x6);
888      break;
889    default:
890      break;
891  }
892}
893
894class Dt_U_size_1 : public EncodingValue {
895 public:
896  explicit Dt_U_size_1(DataType dt);
897};
898
899Dt_U_size_1::Dt_U_size_1(DataType dt) {
900  switch (dt.GetValue()) {
901    case S8:
902      SetEncodingValue(0x0);
903      break;
904    case S16:
905      SetEncodingValue(0x1);
906      break;
907    case S32:
908      SetEncodingValue(0x2);
909      break;
910    case U8:
911      SetEncodingValue(0x4);
912      break;
913    case U16:
914      SetEncodingValue(0x5);
915      break;
916    case U32:
917      SetEncodingValue(0x6);
918      break;
919    default:
920      break;
921  }
922}
923
924class Dt_U_size_2 : public EncodingValue {
925 public:
926  explicit Dt_U_size_2(DataType dt);
927};
928
929Dt_U_size_2::Dt_U_size_2(DataType dt) {
930  switch (dt.GetValue()) {
931    case S16:
932      SetEncodingValue(0x1);
933      break;
934    case S32:
935      SetEncodingValue(0x2);
936      break;
937    case U16:
938      SetEncodingValue(0x5);
939      break;
940    case U32:
941      SetEncodingValue(0x6);
942      break;
943    default:
944      break;
945  }
946}
947
948class Dt_U_size_3 : public EncodingValue {
949 public:
950  explicit Dt_U_size_3(DataType dt);
951};
952
953Dt_U_size_3::Dt_U_size_3(DataType dt) {
954  switch (dt.GetValue()) {
955    case S8:
956      SetEncodingValue(0x0);
957      break;
958    case S16:
959      SetEncodingValue(0x1);
960      break;
961    case S32:
962      SetEncodingValue(0x2);
963      break;
964    case S64:
965      SetEncodingValue(0x3);
966      break;
967    case U8:
968      SetEncodingValue(0x4);
969      break;
970    case U16:
971      SetEncodingValue(0x5);
972      break;
973    case U32:
974      SetEncodingValue(0x6);
975      break;
976    case U64:
977      SetEncodingValue(0x7);
978      break;
979    default:
980      break;
981  }
982}
983
984class Dt_size_1 : public EncodingValue {
985 public:
986  explicit Dt_size_1(DataType dt);
987};
988
989Dt_size_1::Dt_size_1(DataType dt) {
990  switch (dt.GetValue()) {
991    case Untyped8:
992      SetEncodingValue(0x0);
993      break;
994    default:
995      break;
996  }
997}
998
999class Dt_size_2 : public EncodingValue {
1000 public:
1001  explicit Dt_size_2(DataType dt);
1002};
1003
1004Dt_size_2::Dt_size_2(DataType dt) {
1005  switch (dt.GetValue()) {
1006    case I8:
1007      SetEncodingValue(0x0);
1008      break;
1009    case I16:
1010      SetEncodingValue(0x1);
1011      break;
1012    case I32:
1013      SetEncodingValue(0x2);
1014      break;
1015    case I64:
1016      SetEncodingValue(0x3);
1017      break;
1018    default:
1019      break;
1020  }
1021}
1022
1023class Dt_size_3 : public EncodingValue {
1024 public:
1025  explicit Dt_size_3(DataType dt);
1026};
1027
1028Dt_size_3::Dt_size_3(DataType dt) {
1029  switch (dt.GetValue()) {
1030    case I16:
1031      SetEncodingValue(0x0);
1032      break;
1033    case I32:
1034      SetEncodingValue(0x1);
1035      break;
1036    case I64:
1037      SetEncodingValue(0x2);
1038      break;
1039    default:
1040      break;
1041  }
1042}
1043
1044class Dt_size_4 : public EncodingValue {
1045 public:
1046  explicit Dt_size_4(DataType dt);
1047};
1048
1049Dt_size_4::Dt_size_4(DataType dt) {
1050  switch (dt.GetValue()) {
1051    case I8:
1052      SetEncodingValue(0x0);
1053      break;
1054    case I16:
1055      SetEncodingValue(0x1);
1056      break;
1057    case I32:
1058      SetEncodingValue(0x2);
1059      break;
1060    default:
1061      break;
1062  }
1063}
1064
1065class Dt_size_5 : public EncodingValue {
1066 public:
1067  explicit Dt_size_5(DataType dt);
1068};
1069
1070Dt_size_5::Dt_size_5(DataType dt) {
1071  switch (dt.GetValue()) {
1072    case S8:
1073      SetEncodingValue(0x0);
1074      break;
1075    case S16:
1076      SetEncodingValue(0x1);
1077      break;
1078    case S32:
1079      SetEncodingValue(0x2);
1080      break;
1081    default:
1082      break;
1083  }
1084}
1085
1086class Dt_size_6 : public EncodingValue {
1087 public:
1088  explicit Dt_size_6(DataType dt);
1089};
1090
1091Dt_size_6::Dt_size_6(DataType dt) {
1092  switch (dt.GetValue()) {
1093    case Untyped8:
1094      SetEncodingValue(0x0);
1095      break;
1096    case Untyped16:
1097      SetEncodingValue(0x1);
1098      break;
1099    case Untyped32:
1100      SetEncodingValue(0x2);
1101      break;
1102    case Untyped64:
1103      SetEncodingValue(0x3);
1104      break;
1105    default:
1106      break;
1107  }
1108}
1109
1110class Dt_size_7 : public EncodingValue {
1111 public:
1112  explicit Dt_size_7(DataType dt);
1113};
1114
1115Dt_size_7::Dt_size_7(DataType dt) {
1116  switch (dt.GetValue()) {
1117    case Untyped8:
1118      SetEncodingValue(0x0);
1119      break;
1120    case Untyped16:
1121      SetEncodingValue(0x1);
1122      break;
1123    case Untyped32:
1124      SetEncodingValue(0x2);
1125      break;
1126    default:
1127      break;
1128  }
1129}
1130
1131class Dt_size_8 : public EncodingValue {
1132 public:
1133  Dt_size_8(DataType dt, Alignment align);
1134};
1135
1136Dt_size_8::Dt_size_8(DataType dt, Alignment align) {
1137  switch (dt.GetValue()) {
1138    case Untyped8:
1139      SetEncodingValue(0x0);
1140      break;
1141    case Untyped16:
1142      SetEncodingValue(0x1);
1143      break;
1144    case Untyped32:
1145      if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) {
1146        SetEncodingValue(0x2);
1147      } else if (align.Is(k128BitAlign)) {
1148        SetEncodingValue(0x3);
1149      }
1150      break;
1151    default:
1152      break;
1153  }
1154}
1155
1156class Dt_size_9 : public EncodingValue {
1157  uint32_t type_;
1158
1159 public:
1160  explicit Dt_size_9(DataType dt);
1161  uint32_t GetTypeEncodingValue() const { return type_; }
1162};
1163
1164Dt_size_9::Dt_size_9(DataType dt) {
1165  switch (dt.GetValue()) {
1166    case I16:
1167      type_ = 0x0;
1168      SetEncodingValue(0x1);
1169      break;
1170    case I32:
1171      type_ = 0x0;
1172      SetEncodingValue(0x2);
1173      break;
1174    case F32:
1175      type_ = 0x1;
1176      SetEncodingValue(0x2);
1177      break;
1178    default:
1179      VIXL_UNREACHABLE();
1180      type_ = 0x0;
1181      break;
1182  }
1183}
1184
1185class Dt_size_10 : public EncodingValue {
1186 public:
1187  explicit Dt_size_10(DataType dt);
1188};
1189
1190Dt_size_10::Dt_size_10(DataType dt) {
1191  switch (dt.GetValue()) {
1192    case S8:
1193    case U8:
1194    case I8:
1195      SetEncodingValue(0x0);
1196      break;
1197    case S16:
1198    case U16:
1199    case I16:
1200      SetEncodingValue(0x1);
1201      break;
1202    case S32:
1203    case U32:
1204    case I32:
1205      SetEncodingValue(0x2);
1206      break;
1207    default:
1208      break;
1209  }
1210}
1211
1212class Dt_size_11 : public EncodingValue {
1213  uint32_t type_;
1214
1215 public:
1216  explicit Dt_size_11(DataType dt);
1217  uint32_t GetTypeEncodingValue() const { return type_; }
1218};
1219
1220Dt_size_11::Dt_size_11(DataType dt) {
1221  switch (dt.GetValue()) {
1222    case S16:
1223      type_ = 0x0;
1224      SetEncodingValue(0x1);
1225      break;
1226    case U16:
1227      type_ = 0x1;
1228      SetEncodingValue(0x1);
1229      break;
1230    case S32:
1231      type_ = 0x0;
1232      SetEncodingValue(0x2);
1233      break;
1234    case U32:
1235      type_ = 0x1;
1236      SetEncodingValue(0x2);
1237      break;
1238    default:
1239      VIXL_UNREACHABLE();
1240      type_ = 0x0;
1241      break;
1242  }
1243}
1244
1245class Dt_size_12 : public EncodingValue {
1246  uint32_t type_;
1247
1248 public:
1249  explicit Dt_size_12(DataType dt);
1250  uint32_t GetTypeEncodingValue() const { return type_; }
1251};
1252
1253Dt_size_12::Dt_size_12(DataType dt) {
1254  switch (dt.GetValue()) {
1255    case S8:
1256      type_ = 0x0;
1257      SetEncodingValue(0x0);
1258      break;
1259    case U8:
1260      type_ = 0x1;
1261      SetEncodingValue(0x0);
1262      break;
1263    case S16:
1264      type_ = 0x0;
1265      SetEncodingValue(0x1);
1266      break;
1267    case U16:
1268      type_ = 0x1;
1269      SetEncodingValue(0x1);
1270      break;
1271    case S32:
1272      type_ = 0x0;
1273      SetEncodingValue(0x2);
1274      break;
1275    case U32:
1276      type_ = 0x1;
1277      SetEncodingValue(0x2);
1278      break;
1279    default:
1280      VIXL_UNREACHABLE();
1281      type_ = 0x0;
1282      break;
1283  }
1284}
1285
1286class Dt_size_13 : public EncodingValue {
1287 public:
1288  explicit Dt_size_13(DataType dt);
1289};
1290
1291Dt_size_13::Dt_size_13(DataType dt) {
1292  switch (dt.GetValue()) {
1293    case S16:
1294      SetEncodingValue(0x1);
1295      break;
1296    case S32:
1297      SetEncodingValue(0x2);
1298      break;
1299    default:
1300      break;
1301  }
1302}
1303
1304class Dt_size_14 : public EncodingValue {
1305 public:
1306  explicit Dt_size_14(DataType dt);
1307};
1308
1309Dt_size_14::Dt_size_14(DataType dt) {
1310  switch (dt.GetValue()) {
1311    case S16:
1312      SetEncodingValue(0x0);
1313      break;
1314    case S32:
1315      SetEncodingValue(0x1);
1316      break;
1317    case S64:
1318      SetEncodingValue(0x2);
1319      break;
1320    default:
1321      break;
1322  }
1323}
1324
1325class Dt_size_15 : public EncodingValue {
1326 public:
1327  explicit Dt_size_15(DataType dt);
1328};
1329
1330Dt_size_15::Dt_size_15(DataType dt) {
1331  switch (dt.GetValue()) {
1332    case Untyped8:
1333      SetEncodingValue(0x0);
1334      break;
1335    case Untyped16:
1336      SetEncodingValue(0x1);
1337      break;
1338    default:
1339      break;
1340  }
1341}
1342
1343class Dt_size_16 : public EncodingValue {
1344 public:
1345  explicit Dt_size_16(DataType dt);
1346};
1347
1348Dt_size_16::Dt_size_16(DataType dt) {
1349  switch (dt.GetValue()) {
1350    case I8:
1351      SetEncodingValue(0x0);
1352      break;
1353    case I16:
1354      SetEncodingValue(0x1);
1355      break;
1356    case I32:
1357      SetEncodingValue(0x2);
1358      break;
1359    default:
1360      break;
1361  }
1362}
1363
1364class Index_1 : public EncodingValue {
1365 public:
1366  Index_1(const NeonRegisterList& nreglist, DataType dt);
1367};
1368
1369Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) {
1370  switch (dt.GetValue()) {
1371    case Untyped8: {
1372      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1373        return;
1374      }
1375      uint32_t value = nreglist.GetTransferLane() << 1;
1376      if (!nreglist.IsSingleSpaced()) return;
1377      SetEncodingValue(value);
1378      break;
1379    }
1380    case Untyped16: {
1381      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1382        return;
1383      }
1384      uint32_t value = nreglist.GetTransferLane() << 2;
1385      if (nreglist.IsDoubleSpaced()) value |= 2;
1386      SetEncodingValue(value);
1387      break;
1388    }
1389    case Untyped32: {
1390      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1391        return;
1392      }
1393      uint32_t value = nreglist.GetTransferLane() << 3;
1394      if (nreglist.IsDoubleSpaced()) value |= 4;
1395      SetEncodingValue(value);
1396      break;
1397    }
1398    default:
1399      break;
1400  }
1401}
1402
1403class Align_index_align_1 : public EncodingValue {
1404 public:
1405  Align_index_align_1(Alignment align,
1406                      const NeonRegisterList& nreglist,
1407                      DataType dt);
1408};
1409
1410Align_index_align_1::Align_index_align_1(Alignment align,
1411                                         const NeonRegisterList& nreglist,
1412                                         DataType dt) {
1413  switch (dt.GetValue()) {
1414    case Untyped8: {
1415      uint32_t value;
1416      if (align.GetType() == kNoAlignment) {
1417        value = 0;
1418      } else {
1419        return;
1420      }
1421      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1422        return;
1423      }
1424      value |= nreglist.GetTransferLane() << 1;
1425      SetEncodingValue(value);
1426      break;
1427    }
1428    case Untyped16: {
1429      uint32_t value;
1430      if (align.GetType() == k16BitAlign) {
1431        value = 1;
1432      } else if (align.GetType() == kNoAlignment) {
1433        value = 0;
1434      } else {
1435        return;
1436      }
1437      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1438        return;
1439      }
1440      value |= nreglist.GetTransferLane() << 2;
1441      SetEncodingValue(value);
1442      break;
1443    }
1444    case Untyped32: {
1445      uint32_t value;
1446      if (align.GetType() == k32BitAlign) {
1447        value = 3;
1448      } else if (align.GetType() == kNoAlignment) {
1449        value = 0;
1450      } else {
1451        return;
1452      }
1453      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1454        return;
1455      }
1456      value |= nreglist.GetTransferLane() << 3;
1457      SetEncodingValue(value);
1458      break;
1459    }
1460    default:
1461      break;
1462  }
1463}
1464
1465class Align_index_align_2 : public EncodingValue {
1466 public:
1467  Align_index_align_2(Alignment align,
1468                      const NeonRegisterList& nreglist,
1469                      DataType dt);
1470};
1471
1472Align_index_align_2::Align_index_align_2(Alignment align,
1473                                         const NeonRegisterList& nreglist,
1474                                         DataType dt) {
1475  switch (dt.GetValue()) {
1476    case Untyped8: {
1477      uint32_t value;
1478      if (align.GetType() == k16BitAlign) {
1479        value = 1;
1480      } else if (align.GetType() == kNoAlignment) {
1481        value = 0;
1482      } else {
1483        return;
1484      }
1485      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1486        return;
1487      }
1488      value |= nreglist.GetTransferLane() << 1;
1489      if (!nreglist.IsSingleSpaced()) return;
1490      SetEncodingValue(value);
1491      break;
1492    }
1493    case Untyped16: {
1494      uint32_t value;
1495      if (align.GetType() == k32BitAlign) {
1496        value = 1;
1497      } else if (align.GetType() == kNoAlignment) {
1498        value = 0;
1499      } else {
1500        return;
1501      }
1502      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1503        return;
1504      }
1505      value |= nreglist.GetTransferLane() << 2;
1506      if (nreglist.IsDoubleSpaced()) value |= 2;
1507      SetEncodingValue(value);
1508      break;
1509    }
1510    case Untyped32: {
1511      uint32_t value;
1512      if (align.GetType() == k64BitAlign) {
1513        value = 1;
1514      } else if (align.GetType() == kNoAlignment) {
1515        value = 0;
1516      } else {
1517        return;
1518      }
1519      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1520        return;
1521      }
1522      value |= nreglist.GetTransferLane() << 3;
1523      if (nreglist.IsDoubleSpaced()) value |= 4;
1524      SetEncodingValue(value);
1525      break;
1526    }
1527    default:
1528      break;
1529  }
1530}
1531
1532class Align_index_align_3 : public EncodingValue {
1533 public:
1534  Align_index_align_3(Alignment align,
1535                      const NeonRegisterList& nreglist,
1536                      DataType dt);
1537};
1538
1539Align_index_align_3::Align_index_align_3(Alignment align,
1540                                         const NeonRegisterList& nreglist,
1541                                         DataType dt) {
1542  switch (dt.GetValue()) {
1543    case Untyped8: {
1544      uint32_t value;
1545      if (align.GetType() == k32BitAlign) {
1546        value = 1;
1547      } else if (align.GetType() == kNoAlignment) {
1548        value = 0;
1549      } else {
1550        return;
1551      }
1552      if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1553        return;
1554      }
1555      value |= nreglist.GetTransferLane() << 1;
1556      if (!nreglist.IsSingleSpaced()) return;
1557      SetEncodingValue(value);
1558      break;
1559    }
1560    case Untyped16: {
1561      uint32_t value;
1562      if (align.GetType() == k64BitAlign) {
1563        value = 1;
1564      } else if (align.GetType() == kNoAlignment) {
1565        value = 0;
1566      } else {
1567        return;
1568      }
1569      if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1570        return;
1571      }
1572      value |= nreglist.GetTransferLane() << 2;
1573      if (nreglist.IsDoubleSpaced()) value |= 2;
1574      SetEncodingValue(value);
1575      break;
1576    }
1577    case Untyped32: {
1578      uint32_t value;
1579      if (align.GetType() == k64BitAlign) {
1580        value = 1;
1581      } else if (align.GetType() == k128BitAlign) {
1582        value = 2;
1583      } else if (align.GetType() == kNoAlignment) {
1584        value = 0;
1585      } else {
1586        return;
1587      }
1588      if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1589        return;
1590      }
1591      value |= nreglist.GetTransferLane() << 3;
1592      if (nreglist.IsDoubleSpaced()) value |= 4;
1593      SetEncodingValue(value);
1594      break;
1595    }
1596    default:
1597      break;
1598  }
1599}
1600
1601class Align_a_1 : public EncodingValue {
1602 public:
1603  Align_a_1(Alignment align, DataType dt);
1604};
1605
1606Align_a_1::Align_a_1(Alignment align, DataType dt) {
1607  switch (align.GetType()) {
1608    case k16BitAlign:
1609      if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1610      break;
1611    case k32BitAlign:
1612      if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1613      break;
1614    case kNoAlignment:
1615      SetEncodingValue(0x0);
1616      break;
1617    default:
1618      break;
1619  }
1620}
1621
1622class Align_a_2 : public EncodingValue {
1623 public:
1624  Align_a_2(Alignment align, DataType dt);
1625};
1626
1627Align_a_2::Align_a_2(Alignment align, DataType dt) {
1628  switch (align.GetType()) {
1629    case k16BitAlign:
1630      if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1631      break;
1632    case k32BitAlign:
1633      if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1634      break;
1635    case k64BitAlign:
1636      if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1637      break;
1638    case kNoAlignment:
1639      SetEncodingValue(0x0);
1640      break;
1641    default:
1642      break;
1643  }
1644}
1645
1646class Align_a_3 : public EncodingValue {
1647 public:
1648  Align_a_3(Alignment align, DataType dt);
1649};
1650
1651Align_a_3::Align_a_3(Alignment align, DataType dt) {
1652  switch (align.GetType()) {
1653    case k32BitAlign:
1654      if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1655      break;
1656    case k64BitAlign:
1657      if (dt.Is(Untyped16))
1658        SetEncodingValue(0x1);
1659      else if (dt.Is(Untyped32))
1660        SetEncodingValue(0x1);
1661      break;
1662    case k128BitAlign:
1663      if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1664      break;
1665    case kNoAlignment:
1666      SetEncodingValue(0x0);
1667      break;
1668    default:
1669      break;
1670  }
1671}
1672
1673class Align_align_1 : public EncodingValue {
1674 public:
1675  Align_align_1(Alignment align, const NeonRegisterList& nreglist);
1676};
1677
1678Align_align_1::Align_align_1(Alignment align,
1679                             const NeonRegisterList& nreglist) {
1680  switch (align.GetType()) {
1681    case k64BitAlign:
1682      SetEncodingValue(0x1);
1683      break;
1684    case k128BitAlign:
1685      if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1686        SetEncodingValue(0x2);
1687      break;
1688    case k256BitAlign:
1689      if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1690        SetEncodingValue(0x3);
1691      break;
1692    case kNoAlignment:
1693      SetEncodingValue(0x0);
1694      break;
1695    default:
1696      break;
1697  }
1698}
1699
1700class Align_align_2 : public EncodingValue {
1701 public:
1702  Align_align_2(Alignment align, const NeonRegisterList& nreglist);
1703};
1704
1705Align_align_2::Align_align_2(Alignment align,
1706                             const NeonRegisterList& nreglist) {
1707  switch (align.GetType()) {
1708    case k64BitAlign:
1709      SetEncodingValue(0x1);
1710      break;
1711    case k128BitAlign:
1712      SetEncodingValue(0x2);
1713      break;
1714    case k256BitAlign:
1715      if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1716      break;
1717    case kNoAlignment:
1718      SetEncodingValue(0x0);
1719      break;
1720    default:
1721      break;
1722  }
1723}
1724
1725class Align_align_3 : public EncodingValue {
1726 public:
1727  explicit Align_align_3(Alignment align);
1728};
1729
1730Align_align_3::Align_align_3(Alignment align) {
1731  switch (align.GetType()) {
1732    case k64BitAlign:
1733      SetEncodingValue(0x1);
1734      break;
1735    case kNoAlignment:
1736      SetEncodingValue(0x0);
1737      break;
1738    default:
1739      break;
1740  }
1741}
1742
1743class Align_align_4 : public EncodingValue {
1744 public:
1745  explicit Align_align_4(Alignment align);
1746};
1747
1748Align_align_4::Align_align_4(Alignment align) {
1749  switch (align.GetType()) {
1750    case k64BitAlign:
1751      SetEncodingValue(0x1);
1752      break;
1753    case k128BitAlign:
1754      SetEncodingValue(0x2);
1755      break;
1756    case k256BitAlign:
1757      SetEncodingValue(0x3);
1758      break;
1759    case kNoAlignment:
1760      SetEncodingValue(0x0);
1761      break;
1762    default:
1763      break;
1764  }
1765}
1766
1767class Align_align_5 : public EncodingValue {
1768 public:
1769  Align_align_5(Alignment align, const NeonRegisterList& nreglist);
1770};
1771
1772Align_align_5::Align_align_5(Alignment align,
1773                             const NeonRegisterList& nreglist) {
1774  switch (align.GetType()) {
1775    case k64BitAlign:
1776      SetEncodingValue(0x1);
1777      break;
1778    case k128BitAlign:
1779      if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1780        SetEncodingValue(0x2);
1781      break;
1782    case k256BitAlign:
1783      if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1784      break;
1785    case kNoAlignment:
1786      SetEncodingValue(0x0);
1787      break;
1788    default:
1789      break;
1790  }
1791}
1792
1793
1794void Assembler::adc(Condition cond,
1795                    EncodingSize size,
1796                    Register rd,
1797                    Register rn,
1798                    const Operand& operand) {
1799  CheckIT(cond);
1800  if (operand.IsImmediate()) {
1801    uint32_t imm = operand.GetImmediate();
1802    if (IsUsingT32()) {
1803      ImmediateT32 immediate_t32(imm);
1804      // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
1805      if (!size.IsNarrow() && immediate_t32.IsValid()) {
1806        EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1807                   (immediate_t32.GetEncodingValue() & 0xff) |
1808                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
1809                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
1810        AdvanceIT();
1811        return;
1812      }
1813    } else {
1814      ImmediateA32 immediate_a32(imm);
1815      // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
1816      if (immediate_a32.IsValid() && cond.IsNotNever()) {
1817        EmitA32(0x02a00000U | (cond.GetCondition() << 28) |
1818                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
1819                immediate_a32.GetEncodingValue());
1820        return;
1821      }
1822    }
1823  }
1824  if (operand.IsImmediateShiftedRegister()) {
1825    Register rm = operand.GetBaseRegister();
1826    if (operand.IsPlainRegister()) {
1827      if (IsUsingT32()) {
1828        // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
1829        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1830            rm.IsLow()) {
1831          EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
1832          AdvanceIT();
1833          return;
1834        }
1835      }
1836    }
1837    Shift shift = operand.GetShift();
1838    uint32_t amount = operand.GetShiftAmount();
1839    if (IsUsingT32()) {
1840      // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
1841      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
1842        uint32_t amount_ = amount % 32;
1843        EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1844                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
1845                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
1846        AdvanceIT();
1847        return;
1848      }
1849    } else {
1850      // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
1851      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
1852        uint32_t amount_ = amount % 32;
1853        EmitA32(0x00a00000U | (cond.GetCondition() << 28) |
1854                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1855                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
1856        return;
1857      }
1858    }
1859  }
1860  if (operand.IsRegisterShiftedRegister()) {
1861    Register rm = operand.GetBaseRegister();
1862    Shift shift = operand.GetShift();
1863    if (IsUsingA32()) {
1864      // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
1865      if (cond.IsNotNever()) {
1866        EmitA32(0x00a00010U | (cond.GetCondition() << 28) |
1867                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1868                (shift.GetType() << 5) |
1869                (operand.GetShiftRegister().GetCode() << 8));
1870        return;
1871      }
1872    }
1873  }
1874  Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand);
1875}
1876
1877void Assembler::adcs(Condition cond,
1878                     EncodingSize size,
1879                     Register rd,
1880                     Register rn,
1881                     const Operand& operand) {
1882  CheckIT(cond);
1883  if (operand.IsImmediate()) {
1884    uint32_t imm = operand.GetImmediate();
1885    if (IsUsingT32()) {
1886      ImmediateT32 immediate_t32(imm);
1887      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
1888      if (!size.IsNarrow() && immediate_t32.IsValid()) {
1889        EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1890                   (immediate_t32.GetEncodingValue() & 0xff) |
1891                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
1892                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
1893        AdvanceIT();
1894        return;
1895      }
1896    } else {
1897      ImmediateA32 immediate_a32(imm);
1898      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
1899      if (immediate_a32.IsValid() && cond.IsNotNever()) {
1900        EmitA32(0x02b00000U | (cond.GetCondition() << 28) |
1901                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
1902                immediate_a32.GetEncodingValue());
1903        return;
1904      }
1905    }
1906  }
1907  if (operand.IsImmediateShiftedRegister()) {
1908    Register rm = operand.GetBaseRegister();
1909    if (operand.IsPlainRegister()) {
1910      if (IsUsingT32()) {
1911        // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
1912        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1913            rm.IsLow()) {
1914          EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
1915          AdvanceIT();
1916          return;
1917        }
1918      }
1919    }
1920    Shift shift = operand.GetShift();
1921    uint32_t amount = operand.GetShiftAmount();
1922    if (IsUsingT32()) {
1923      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
1924      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
1925        uint32_t amount_ = amount % 32;
1926        EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1927                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
1928                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
1929        AdvanceIT();
1930        return;
1931      }
1932    } else {
1933      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
1934      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
1935        uint32_t amount_ = amount % 32;
1936        EmitA32(0x00b00000U | (cond.GetCondition() << 28) |
1937                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1938                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
1939        return;
1940      }
1941    }
1942  }
1943  if (operand.IsRegisterShiftedRegister()) {
1944    Register rm = operand.GetBaseRegister();
1945    Shift shift = operand.GetShift();
1946    if (IsUsingA32()) {
1947      // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
1948      if (cond.IsNotNever()) {
1949        EmitA32(0x00b00010U | (cond.GetCondition() << 28) |
1950                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1951                (shift.GetType() << 5) |
1952                (operand.GetShiftRegister().GetCode() << 8));
1953        return;
1954      }
1955    }
1956  }
1957  Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand);
1958}
1959
1960void Assembler::add(Condition cond,
1961                    EncodingSize size,
1962                    Register rd,
1963                    Register rn,
1964                    const Operand& operand) {
1965  CheckIT(cond);
1966  if (operand.IsImmediate()) {
1967    uint32_t imm = operand.GetImmediate();
1968    if (IsUsingT32()) {
1969      ImmediateT32 immediate_t32(imm);
1970      // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1
1971      if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) &&
1972          ((imm % 4) == 0)) {
1973        uint32_t imm_ = imm >> 2;
1974        EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_);
1975        AdvanceIT();
1976        return;
1977      }
1978      // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
1979      if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
1980          (imm <= 7)) {
1981        EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
1982        AdvanceIT();
1983        return;
1984      }
1985      // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
1986      if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1987          (imm <= 255)) {
1988        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
1989        AdvanceIT();
1990        return;
1991      }
1992      // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1
1993      if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) &&
1994          ((imm % 4) == 0)) {
1995        uint32_t imm_ = imm >> 2;
1996        EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_);
1997        AdvanceIT();
1998        return;
1999      }
2000      // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2
2001      if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
2002          ((imm % 4) == 0)) {
2003        uint32_t imm_ = imm >> 2;
2004        EmitT32_16(0xb000 | imm_);
2005        AdvanceIT();
2006        return;
2007      }
2008      // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2009      if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095)) {
2010        EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2011                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2012        AdvanceIT();
2013        return;
2014      }
2015      // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2016      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp)) {
2017        EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2018                   (immediate_t32.GetEncodingValue() & 0xff) |
2019                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2020                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2021        AdvanceIT();
2022        return;
2023      }
2024      // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2025      if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
2026        EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2027                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2028        AdvanceIT();
2029        return;
2030      }
2031      // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2032      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid()) {
2033        EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) |
2034                   (immediate_t32.GetEncodingValue() & 0xff) |
2035                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2036                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2037        AdvanceIT();
2038        return;
2039      }
2040      // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2041      if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095)) {
2042        EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2043                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2044        AdvanceIT();
2045        return;
2046      }
2047    } else {
2048      ImmediateA32 immediate_a32(imm);
2049      // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1
2050      if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
2051        EmitA32(0x028f0000U | (cond.GetCondition() << 28) |
2052                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2053        return;
2054      }
2055      // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2056      if (immediate_a32.IsValid() && cond.IsNotNever() &&
2057          ((rn.GetCode() & 0xd) != 0xd)) {
2058        EmitA32(0x02800000U | (cond.GetCondition() << 28) |
2059                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2060                immediate_a32.GetEncodingValue());
2061        return;
2062      }
2063      // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2064      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2065        EmitA32(0x028d0000U | (cond.GetCondition() << 28) |
2066                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2067        return;
2068      }
2069    }
2070  }
2071  if (operand.IsImmediateShiftedRegister()) {
2072    Register rm = operand.GetBaseRegister();
2073    if (operand.IsPlainRegister()) {
2074      if (IsUsingT32()) {
2075        // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
2076        if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2077            rm.IsLow()) {
2078          EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2079                     (rm.GetCode() << 6));
2080          AdvanceIT();
2081          return;
2082        }
2083        // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2
2084        if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp)) {
2085          EmitT32_16(0x4400 | (rd.GetCode() & 0x7) |
2086                     ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
2087          AdvanceIT();
2088          return;
2089        }
2090        // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1
2091        if (!size.IsWide() && rd.Is(rm) && rn.Is(sp)) {
2092          EmitT32_16(0x4468 | (rd.GetCode() & 0x7) |
2093                     ((rd.GetCode() & 0x8) << 4));
2094          AdvanceIT();
2095          return;
2096        }
2097        // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2
2098        if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) {
2099          EmitT32_16(0x4485 | (rm.GetCode() << 3));
2100          AdvanceIT();
2101          return;
2102        }
2103      }
2104    }
2105    Shift shift = operand.GetShift();
2106    uint32_t amount = operand.GetShiftAmount();
2107    if (IsUsingT32()) {
2108      // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2109      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp)) {
2110        uint32_t amount_ = amount % 32;
2111        EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2112                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2113                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2114        AdvanceIT();
2115        return;
2116      }
2117      // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2118      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount)) {
2119        uint32_t amount_ = amount % 32;
2120        EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2121                   (operand.GetTypeEncodingValue() << 4) |
2122                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2123        AdvanceIT();
2124        return;
2125      }
2126    } else {
2127      // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2128      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2129        uint32_t amount_ = amount % 32;
2130        EmitA32(0x00800000U | (cond.GetCondition() << 28) |
2131                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2132                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2133        return;
2134      }
2135      // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2136      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2137        uint32_t amount_ = amount % 32;
2138        EmitA32(0x008d0000U | (cond.GetCondition() << 28) |
2139                (rd.GetCode() << 12) | rm.GetCode() |
2140                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2141        return;
2142      }
2143    }
2144  }
2145  if (operand.IsRegisterShiftedRegister()) {
2146    Register rm = operand.GetBaseRegister();
2147    Shift shift = operand.GetShift();
2148    if (IsUsingA32()) {
2149      // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2150      if (cond.IsNotNever()) {
2151        EmitA32(0x00800010U | (cond.GetCondition() << 28) |
2152                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2153                (shift.GetType() << 5) |
2154                (operand.GetShiftRegister().GetCode() << 8));
2155        return;
2156      }
2157    }
2158  }
2159  Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand);
2160}
2161
2162void Assembler::add(Condition cond, Register rd, const Operand& operand) {
2163  CheckIT(cond);
2164  if (operand.IsImmediate()) {
2165    uint32_t imm = operand.GetImmediate();
2166    if (IsUsingT32()) {
2167      // ADD<c>{<q>} <Rdn>, #<imm8> ; T2
2168      if (InITBlock() && rd.IsLow() && (imm <= 255)) {
2169        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2170        AdvanceIT();
2171        return;
2172      }
2173    }
2174  }
2175  if (operand.IsPlainRegister()) {
2176    Register rm = operand.GetBaseRegister();
2177    if (IsUsingT32()) {
2178      // ADD<c>{<q>} <Rdn>, <Rm> ; T2
2179      if (InITBlock() && !rm.Is(sp)) {
2180        EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) |
2181                   (rm.GetCode() << 3));
2182        AdvanceIT();
2183        return;
2184      }
2185    }
2186  }
2187  Delegate(kAdd, &Assembler::add, cond, rd, operand);
2188}
2189
2190void Assembler::adds(Condition cond,
2191                     EncodingSize size,
2192                     Register rd,
2193                     Register rn,
2194                     const Operand& operand) {
2195  CheckIT(cond);
2196  if (operand.IsImmediate()) {
2197    uint32_t imm = operand.GetImmediate();
2198    if (IsUsingT32()) {
2199      ImmediateT32 immediate_t32(imm);
2200      // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1
2201      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2202          (imm <= 7)) {
2203        EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
2204        AdvanceIT();
2205        return;
2206      }
2207      // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
2208      if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2209          (imm <= 255)) {
2210        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2211        AdvanceIT();
2212        return;
2213      }
2214      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2215      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
2216          !rd.Is(pc)) {
2217        EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2218                   (immediate_t32.GetEncodingValue() & 0xff) |
2219                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2220                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2221        AdvanceIT();
2222        return;
2223      }
2224      // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2225      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
2226          !rd.Is(pc)) {
2227        EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) |
2228                   (immediate_t32.GetEncodingValue() & 0xff) |
2229                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2230                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2231        AdvanceIT();
2232        return;
2233      }
2234    } else {
2235      ImmediateA32 immediate_a32(imm);
2236      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2237      if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
2238        EmitA32(0x02900000U | (cond.GetCondition() << 28) |
2239                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2240                immediate_a32.GetEncodingValue());
2241        return;
2242      }
2243      // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2244      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2245        EmitA32(0x029d0000U | (cond.GetCondition() << 28) |
2246                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2247        return;
2248      }
2249    }
2250  }
2251  if (operand.IsImmediateShiftedRegister()) {
2252    Register rm = operand.GetBaseRegister();
2253    if (operand.IsPlainRegister()) {
2254      if (IsUsingT32()) {
2255        // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
2256        if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2257            rm.IsLow()) {
2258          EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2259                     (rm.GetCode() << 6));
2260          AdvanceIT();
2261          return;
2262        }
2263      }
2264    }
2265    Shift shift = operand.GetShift();
2266    uint32_t amount = operand.GetShiftAmount();
2267    if (IsUsingT32()) {
2268      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2269      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
2270          !rd.Is(pc)) {
2271        uint32_t amount_ = amount % 32;
2272        EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2273                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2274                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2275        AdvanceIT();
2276        return;
2277      }
2278      // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2279      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
2280          !rd.Is(pc)) {
2281        uint32_t amount_ = amount % 32;
2282        EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2283                   (operand.GetTypeEncodingValue() << 4) |
2284                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2285        AdvanceIT();
2286        return;
2287      }
2288    } else {
2289      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2290      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2291        uint32_t amount_ = amount % 32;
2292        EmitA32(0x00900000U | (cond.GetCondition() << 28) |
2293                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2294                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2295        return;
2296      }
2297      // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2298      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2299        uint32_t amount_ = amount % 32;
2300        EmitA32(0x009d0000U | (cond.GetCondition() << 28) |
2301                (rd.GetCode() << 12) | rm.GetCode() |
2302                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2303        return;
2304      }
2305    }
2306  }
2307  if (operand.IsRegisterShiftedRegister()) {
2308    Register rm = operand.GetBaseRegister();
2309    Shift shift = operand.GetShift();
2310    if (IsUsingA32()) {
2311      // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2312      if (cond.IsNotNever()) {
2313        EmitA32(0x00900010U | (cond.GetCondition() << 28) |
2314                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2315                (shift.GetType() << 5) |
2316                (operand.GetShiftRegister().GetCode() << 8));
2317        return;
2318      }
2319    }
2320  }
2321  Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand);
2322}
2323
2324void Assembler::adds(Register rd, const Operand& operand) {
2325  CheckIT(al);
2326  if (operand.IsImmediate()) {
2327    uint32_t imm = operand.GetImmediate();
2328    if (IsUsingT32()) {
2329      // ADDS{<q>} <Rdn>, #<imm8> ; T2
2330      if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
2331        EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2332        AdvanceIT();
2333        return;
2334      }
2335    }
2336  }
2337  Delegate(kAdds, &Assembler::adds, rd, operand);
2338}
2339
2340void Assembler::addw(Condition cond,
2341                     Register rd,
2342                     Register rn,
2343                     const Operand& operand) {
2344  CheckIT(cond);
2345  if (operand.IsImmediate()) {
2346    uint32_t imm = operand.GetImmediate();
2347    if (IsUsingT32()) {
2348      // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2349      if (rn.Is(pc) && (imm <= 4095)) {
2350        EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2351                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2352        AdvanceIT();
2353        return;
2354      }
2355      // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2356      if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
2357        EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2358                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2359        AdvanceIT();
2360        return;
2361      }
2362      // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2363      if (rn.Is(sp) && (imm <= 4095)) {
2364        EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2365                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2366        AdvanceIT();
2367        return;
2368      }
2369    }
2370  }
2371  Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand);
2372}
2373
2374void Assembler::adr(Condition cond,
2375                    EncodingSize size,
2376                    Register rd,
2377                    Label* label) {
2378  CheckIT(cond);
2379  Label::Offset offset =
2380      label->IsBound()
2381          ? label->GetLocation() -
2382                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
2383          : 0;
2384  if (IsUsingT32()) {
2385    int32_t neg_offset = -offset;
2386    // ADR{<c>}{<q>} <Rd>, <label> ; T1
2387    if (!size.IsWide() && rd.IsLow() &&
2388        ((label->IsBound() && (offset >= 0) && (offset <= 1020) &&
2389          ((offset & 0x3) == 0)) ||
2390         (!label->IsBound() && size.IsNarrow()))) {
2391      static class EmitOp : public Label::LabelEmitOperator {
2392       public:
2393        EmitOp() : Label::LabelEmitOperator(0, 1020) {}
2394        uint32_t Encode(uint32_t instr,
2395                        Label::Offset pc,
2396                        const Label* label) const {
2397          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2398          VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
2399                      ((offset & 0x3) == 0));
2400          const int32_t target = offset >> 2;
2401          return instr | (target & 0xff);
2402        }
2403      } immop;
2404      EmitT32_16(Link(0xa000 | (rd.GetCode() << 8), label, immop));
2405      AdvanceIT();
2406      return;
2407    }
2408    // ADR{<c>}{<q>} <Rd>, <label> ; T2
2409    if (!size.IsNarrow() && label->IsBound() && (neg_offset > 0) &&
2410        (neg_offset <= 4095)) {
2411      EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) |
2412                 ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15));
2413      AdvanceIT();
2414      return;
2415    }
2416    // ADR{<c>}{<q>} <Rd>, <label> ; T3
2417    if (!size.IsNarrow() &&
2418        (!label->IsBound() || ((offset >= 0) && (offset <= 4095)))) {
2419      static class EmitOp : public Label::LabelEmitOperator {
2420       public:
2421        EmitOp() : Label::LabelEmitOperator(0, 4095) {}
2422        uint32_t Encode(uint32_t instr,
2423                        Label::Offset pc,
2424                        const Label* label) const {
2425          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2426          int32_t target;
2427          if ((offset >= 0) && (offset <= 4095) && !label->IsMinusZero()) {
2428            target = offset;
2429          } else {
2430            target = -offset;
2431            VIXL_ASSERT((target >= 0) && (target <= 4095));
2432            // Emit the T2 encoding.
2433            instr |= 0x00a00000;
2434          }
2435          return instr | (target & 0xff) | ((target & 0x700) << 4) |
2436                 ((target & 0x800) << 15);
2437        }
2438      } immop;
2439      EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8), label, immop));
2440      AdvanceIT();
2441      return;
2442    }
2443  } else {
2444    ImmediateA32 positive_immediate_a32(offset);
2445    ImmediateA32 negative_immediate_a32(-offset);
2446    // ADR{<c>}{<q>} <Rd>, <label> ; A1
2447    if ((!label->IsBound() || positive_immediate_a32.IsValid()) &&
2448        cond.IsNotNever()) {
2449      static class EmitOp : public Label::LabelEmitOperator {
2450       public:
2451        EmitOp() : Label::LabelEmitOperator(0, 255) {}
2452        uint32_t Encode(uint32_t instr,
2453                        Label::Offset pc,
2454                        const Label* label) const {
2455          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2456          int32_t target;
2457          ImmediateA32 positive_immediate_a32(offset);
2458          if (positive_immediate_a32.IsValid()) {
2459            target = positive_immediate_a32.GetEncodingValue();
2460          } else {
2461            ImmediateA32 negative_immediate_a32(-offset);
2462            VIXL_ASSERT(negative_immediate_a32.IsValid());
2463            // Emit the A2 encoding.
2464            target = negative_immediate_a32.GetEncodingValue();
2465            instr = (instr & ~0x00f00000) | 0x00400000;
2466          }
2467          return instr | (target & 0xfff);
2468        }
2469      } immop;
2470      EmitA32(
2471          Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12),
2472               label,
2473               immop));
2474      return;
2475    }
2476    // ADR{<c>}{<q>} <Rd>, <label> ; A2
2477    if (label->IsBound() && negative_immediate_a32.IsValid() &&
2478        cond.IsNotNever()) {
2479      EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
2480              negative_immediate_a32.GetEncodingValue());
2481      return;
2482    }
2483  }
2484  Delegate(kAdr, &Assembler::adr, cond, size, rd, label);
2485}
2486
2487void Assembler::and_(Condition cond,
2488                     EncodingSize size,
2489                     Register rd,
2490                     Register rn,
2491                     const Operand& operand) {
2492  CheckIT(cond);
2493  if (operand.IsImmediate()) {
2494    uint32_t imm = operand.GetImmediate();
2495    if (IsUsingT32()) {
2496      ImmediateT32 immediate_t32(imm);
2497      // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2498      if (!size.IsNarrow() && immediate_t32.IsValid()) {
2499        EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2500                   (immediate_t32.GetEncodingValue() & 0xff) |
2501                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2502                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2503        AdvanceIT();
2504        return;
2505      }
2506    } else {
2507      ImmediateA32 immediate_a32(imm);
2508      // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2509      if (immediate_a32.IsValid() && cond.IsNotNever()) {
2510        EmitA32(0x02000000U | (cond.GetCondition() << 28) |
2511                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2512                immediate_a32.GetEncodingValue());
2513        return;
2514      }
2515    }
2516  }
2517  if (operand.IsImmediateShiftedRegister()) {
2518    Register rm = operand.GetBaseRegister();
2519    if (operand.IsPlainRegister()) {
2520      if (IsUsingT32()) {
2521        // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2522        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2523            rm.IsLow()) {
2524          EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2525          AdvanceIT();
2526          return;
2527        }
2528      }
2529    }
2530    Shift shift = operand.GetShift();
2531    uint32_t amount = operand.GetShiftAmount();
2532    if (IsUsingT32()) {
2533      // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2534      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
2535        uint32_t amount_ = amount % 32;
2536        EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2537                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2538                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2539        AdvanceIT();
2540        return;
2541      }
2542    } else {
2543      // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2544      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2545        uint32_t amount_ = amount % 32;
2546        EmitA32(0x00000000U | (cond.GetCondition() << 28) |
2547                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2548                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2549        return;
2550      }
2551    }
2552  }
2553  if (operand.IsRegisterShiftedRegister()) {
2554    Register rm = operand.GetBaseRegister();
2555    Shift shift = operand.GetShift();
2556    if (IsUsingA32()) {
2557      // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2558      if (cond.IsNotNever()) {
2559        EmitA32(0x00000010U | (cond.GetCondition() << 28) |
2560                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2561                (shift.GetType() << 5) |
2562                (operand.GetShiftRegister().GetCode() << 8));
2563        return;
2564      }
2565    }
2566  }
2567  Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand);
2568}
2569
2570void Assembler::ands(Condition cond,
2571                     EncodingSize size,
2572                     Register rd,
2573                     Register rn,
2574                     const Operand& operand) {
2575  CheckIT(cond);
2576  if (operand.IsImmediate()) {
2577    uint32_t imm = operand.GetImmediate();
2578    if (IsUsingT32()) {
2579      ImmediateT32 immediate_t32(imm);
2580      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2581      if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) {
2582        EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2583                   (immediate_t32.GetEncodingValue() & 0xff) |
2584                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2585                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2586        AdvanceIT();
2587        return;
2588      }
2589    } else {
2590      ImmediateA32 immediate_a32(imm);
2591      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2592      if (immediate_a32.IsValid() && cond.IsNotNever()) {
2593        EmitA32(0x02100000U | (cond.GetCondition() << 28) |
2594                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2595                immediate_a32.GetEncodingValue());
2596        return;
2597      }
2598    }
2599  }
2600  if (operand.IsImmediateShiftedRegister()) {
2601    Register rm = operand.GetBaseRegister();
2602    if (operand.IsPlainRegister()) {
2603      if (IsUsingT32()) {
2604        // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2605        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2606            rm.IsLow()) {
2607          EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2608          AdvanceIT();
2609          return;
2610        }
2611      }
2612    }
2613    Shift shift = operand.GetShift();
2614    uint32_t amount = operand.GetShiftAmount();
2615    if (IsUsingT32()) {
2616      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2617      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) {
2618        uint32_t amount_ = amount % 32;
2619        EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2620                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2621                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2622        AdvanceIT();
2623        return;
2624      }
2625    } else {
2626      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2627      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2628        uint32_t amount_ = amount % 32;
2629        EmitA32(0x00100000U | (cond.GetCondition() << 28) |
2630                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2631                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2632        return;
2633      }
2634    }
2635  }
2636  if (operand.IsRegisterShiftedRegister()) {
2637    Register rm = operand.GetBaseRegister();
2638    Shift shift = operand.GetShift();
2639    if (IsUsingA32()) {
2640      // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2641      if (cond.IsNotNever()) {
2642        EmitA32(0x00100010U | (cond.GetCondition() << 28) |
2643                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2644                (shift.GetType() << 5) |
2645                (operand.GetShiftRegister().GetCode() << 8));
2646        return;
2647      }
2648    }
2649  }
2650  Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand);
2651}
2652
2653void Assembler::asr(Condition cond,
2654                    EncodingSize size,
2655                    Register rd,
2656                    Register rm,
2657                    const Operand& operand) {
2658  CheckIT(cond);
2659  if (operand.IsImmediate()) {
2660    uint32_t imm = operand.GetImmediate();
2661    if (IsUsingT32()) {
2662      // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2663      if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2664          (imm >= 1) && (imm <= 32)) {
2665        uint32_t amount_ = imm % 32;
2666        EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2667                   (amount_ << 6));
2668        AdvanceIT();
2669        return;
2670      }
2671      // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2672      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
2673        uint32_t amount_ = imm % 32;
2674        EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2675                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2676        AdvanceIT();
2677        return;
2678      }
2679    } else {
2680      // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2681      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2682        uint32_t amount_ = imm % 32;
2683        EmitA32(0x01a00040U | (cond.GetCondition() << 28) |
2684                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2685        return;
2686      }
2687    }
2688  }
2689  if (operand.IsPlainRegister()) {
2690    Register rs = operand.GetBaseRegister();
2691    if (IsUsingT32()) {
2692      // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2693      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2694          rs.IsLow()) {
2695        EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2696        AdvanceIT();
2697        return;
2698      }
2699      // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2700      if (!size.IsNarrow()) {
2701        EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2702                   rs.GetCode());
2703        AdvanceIT();
2704        return;
2705      }
2706    } else {
2707      // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
2708      if (cond.IsNotNever()) {
2709        EmitA32(0x01a00050U | (cond.GetCondition() << 28) |
2710                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
2711        return;
2712      }
2713    }
2714  }
2715  Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand);
2716}
2717
2718void Assembler::asrs(Condition cond,
2719                     EncodingSize size,
2720                     Register rd,
2721                     Register rm,
2722                     const Operand& operand) {
2723  CheckIT(cond);
2724  if (operand.IsImmediate()) {
2725    uint32_t imm = operand.GetImmediate();
2726    if (IsUsingT32()) {
2727      // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2728      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2729          (imm >= 1) && (imm <= 32)) {
2730        uint32_t amount_ = imm % 32;
2731        EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2732                   (amount_ << 6));
2733        AdvanceIT();
2734        return;
2735      }
2736      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2737      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
2738        uint32_t amount_ = imm % 32;
2739        EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2740                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2741        AdvanceIT();
2742        return;
2743      }
2744    } else {
2745      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2746      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2747        uint32_t amount_ = imm % 32;
2748        EmitA32(0x01b00040U | (cond.GetCondition() << 28) |
2749                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2750        return;
2751      }
2752    }
2753  }
2754  if (operand.IsPlainRegister()) {
2755    Register rs = operand.GetBaseRegister();
2756    if (IsUsingT32()) {
2757      // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2758      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2759          rs.IsLow()) {
2760        EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2761        AdvanceIT();
2762        return;
2763      }
2764      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2765      if (!size.IsNarrow()) {
2766        EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2767                   rs.GetCode());
2768        AdvanceIT();
2769        return;
2770      }
2771    } else {
2772      // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
2773      if (cond.IsNotNever()) {
2774        EmitA32(0x01b00050U | (cond.GetCondition() << 28) |
2775                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
2776        return;
2777      }
2778    }
2779  }
2780  Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand);
2781}
2782
2783void Assembler::b(Condition cond, EncodingSize size, Label* label) {
2784  Label::Offset offset =
2785      label->IsBound()
2786          ? label->GetLocation() -
2787                (GetCursorOffset() + GetArchitectureStatePCOffset())
2788          : 0;
2789  if (IsUsingT32()) {
2790    // B<c>{<q>} <label> ; T1
2791    if (OutsideITBlock() && !size.IsWide() &&
2792        ((label->IsBound() && (offset >= -256) && (offset <= 254) &&
2793          ((offset & 0x1) == 0)) ||
2794         (!label->IsBound() && size.IsNarrow())) &&
2795        !cond.Is(al) && cond.IsNotNever()) {
2796      static class EmitOp : public Label::LabelEmitOperator {
2797       public:
2798        EmitOp() : Label::LabelEmitOperator(-256, 254) {}
2799        uint32_t Encode(uint32_t instr,
2800                        Label::Offset pc,
2801                        const Label* label) const {
2802          Label::Offset offset = label->GetLocation() - pc;
2803          VIXL_ASSERT((offset >= -256) && (offset <= 254) &&
2804                      ((offset & 0x1) == 0));
2805          const int32_t target = offset >> 1;
2806          return instr | (target & 0xff);
2807        }
2808      } immop;
2809      EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8), label, immop));
2810      AdvanceIT();
2811      return;
2812    }
2813    // B{<c>}{<q>} <label> ; T2
2814    if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() &&
2815        ((label->IsBound() && (offset >= -2048) && (offset <= 2046) &&
2816          ((offset & 0x1) == 0)) ||
2817         (!label->IsBound() && size.IsNarrow()))) {
2818      CheckIT(cond);
2819      static class EmitOp : public Label::LabelEmitOperator {
2820       public:
2821        EmitOp() : Label::LabelEmitOperator(-2048, 2046) {}
2822        uint32_t Encode(uint32_t instr,
2823                        Label::Offset pc,
2824                        const Label* label) const {
2825          Label::Offset offset = label->GetLocation() - pc;
2826          VIXL_ASSERT((offset >= -2048) && (offset <= 2046) &&
2827                      ((offset & 0x1) == 0));
2828          const int32_t target = offset >> 1;
2829          return instr | (target & 0x7ff);
2830        }
2831      } immop;
2832      EmitT32_16(Link(0xe000, label, immop));
2833      AdvanceIT();
2834      return;
2835    }
2836    // B<c>{<q>} <label> ; T3
2837    if (OutsideITBlock() && !size.IsNarrow() &&
2838        ((label->IsBound() && (offset >= -1048576) && (offset <= 1048574) &&
2839          ((offset & 0x1) == 0)) ||
2840         !label->IsBound()) &&
2841        !cond.Is(al) && cond.IsNotNever()) {
2842      static class EmitOp : public Label::LabelEmitOperator {
2843       public:
2844        EmitOp() : Label::LabelEmitOperator(-1048576, 1048574) {}
2845        uint32_t Encode(uint32_t instr,
2846                        Label::Offset pc,
2847                        const Label* label) const {
2848          Label::Offset offset = label->GetLocation() - pc;
2849          VIXL_ASSERT((offset >= -1048576) && (offset <= 1048574) &&
2850                      ((offset & 0x1) == 0));
2851          const int32_t target = offset >> 1;
2852          return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) |
2853                 ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) |
2854                 ((target & 0x80000) << 7);
2855        }
2856      } immop;
2857      EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22), label, immop));
2858      AdvanceIT();
2859      return;
2860    }
2861    // B{<c>}{<q>} <label> ; T4
2862    if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() &&
2863        ((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) &&
2864          ((offset & 0x1) == 0)) ||
2865         !label->IsBound())) {
2866      CheckIT(cond);
2867      static class EmitOp : public Label::LabelEmitOperator {
2868       public:
2869        EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {}
2870        uint32_t Encode(uint32_t instr,
2871                        Label::Offset pc,
2872                        const Label* label) const {
2873          Label::Offset offset = label->GetLocation() - pc;
2874          VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
2875                      ((offset & 0x1) == 0));
2876          int32_t target = offset >> 1;
2877          uint32_t S = target & (1 << 23);
2878          target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
2879          return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
2880                 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
2881                 ((target & 0x800000) << 3);
2882        }
2883      } immop;
2884      EmitT32_32(Link(0xf0009000U, label, immop));
2885      AdvanceIT();
2886      return;
2887    }
2888  } else {
2889    // B{<c>}{<q>} <label> ; A1
2890    if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) &&
2891          ((offset & 0x3) == 0)) ||
2892         !label->IsBound()) &&
2893        cond.IsNotNever()) {
2894      static class EmitOp : public Label::LabelEmitOperator {
2895       public:
2896        EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {}
2897        uint32_t Encode(uint32_t instr,
2898                        Label::Offset pc,
2899                        const Label* label) const {
2900          Label::Offset offset = label->GetLocation() - pc;
2901          VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
2902                      ((offset & 0x3) == 0));
2903          const int32_t target = offset >> 2;
2904          return instr | (target & 0xffffff);
2905        }
2906      } immop;
2907      EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28), label, immop));
2908      return;
2909    }
2910  }
2911  Delegate(kB, &Assembler::b, cond, size, label);
2912}
2913
2914void Assembler::bfc(Condition cond,
2915                    Register rd,
2916                    uint32_t lsb,
2917                    const Operand& operand) {
2918  CheckIT(cond);
2919  if (operand.IsImmediate()) {
2920    uint32_t width = operand.GetImmediate();
2921    if (IsUsingT32()) {
2922      // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1
2923      if ((lsb <= 31) &&
2924          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2925        uint32_t msb = lsb + width - 1;
2926        EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) |
2927                   ((lsb & 0x1c) << 10) | msb);
2928        AdvanceIT();
2929        return;
2930      }
2931    } else {
2932      // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1
2933      if ((lsb <= 31) && cond.IsNotNever() &&
2934          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2935        uint32_t msb = lsb + width - 1;
2936        EmitA32(0x07c0001fU | (cond.GetCondition() << 28) |
2937                (rd.GetCode() << 12) | (lsb << 7) | (msb << 16));
2938        return;
2939      }
2940    }
2941  }
2942  Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, operand);
2943}
2944
2945void Assembler::bfi(Condition cond,
2946                    Register rd,
2947                    Register rn,
2948                    uint32_t lsb,
2949                    const Operand& operand) {
2950  CheckIT(cond);
2951  if (operand.IsImmediate()) {
2952    uint32_t width = operand.GetImmediate();
2953    if (IsUsingT32()) {
2954      // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
2955      if ((lsb <= 31) && !rn.Is(pc) &&
2956          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2957        uint32_t msb = lsb + width - 1;
2958        EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2959                   ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb);
2960        AdvanceIT();
2961        return;
2962      }
2963    } else {
2964      // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
2965      if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) &&
2966          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2967        uint32_t msb = lsb + width - 1;
2968        EmitA32(0x07c00010U | (cond.GetCondition() << 28) |
2969                (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) | (msb << 16));
2970        return;
2971      }
2972    }
2973  }
2974  Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, operand);
2975}
2976
2977void Assembler::bic(Condition cond,
2978                    EncodingSize size,
2979                    Register rd,
2980                    Register rn,
2981                    const Operand& operand) {
2982  CheckIT(cond);
2983  if (operand.IsImmediate()) {
2984    uint32_t imm = operand.GetImmediate();
2985    if (IsUsingT32()) {
2986      ImmediateT32 immediate_t32(imm);
2987      // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2988      if (!size.IsNarrow() && immediate_t32.IsValid()) {
2989        EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2990                   (immediate_t32.GetEncodingValue() & 0xff) |
2991                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2992                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2993        AdvanceIT();
2994        return;
2995      }
2996    } else {
2997      ImmediateA32 immediate_a32(imm);
2998      // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2999      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3000        EmitA32(0x03c00000U | (cond.GetCondition() << 28) |
3001                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3002                immediate_a32.GetEncodingValue());
3003        return;
3004      }
3005    }
3006  }
3007  if (operand.IsImmediateShiftedRegister()) {
3008    Register rm = operand.GetBaseRegister();
3009    if (operand.IsPlainRegister()) {
3010      if (IsUsingT32()) {
3011        // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3012        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3013            rm.IsLow()) {
3014          EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3015          AdvanceIT();
3016          return;
3017        }
3018      }
3019    }
3020    Shift shift = operand.GetShift();
3021    uint32_t amount = operand.GetShiftAmount();
3022    if (IsUsingT32()) {
3023      // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3024      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3025        uint32_t amount_ = amount % 32;
3026        EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3027                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3028                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3029        AdvanceIT();
3030        return;
3031      }
3032    } else {
3033      // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3034      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3035        uint32_t amount_ = amount % 32;
3036        EmitA32(0x01c00000U | (cond.GetCondition() << 28) |
3037                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3038                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3039        return;
3040      }
3041    }
3042  }
3043  if (operand.IsRegisterShiftedRegister()) {
3044    Register rm = operand.GetBaseRegister();
3045    Shift shift = operand.GetShift();
3046    if (IsUsingA32()) {
3047      // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3048      if (cond.IsNotNever()) {
3049        EmitA32(0x01c00010U | (cond.GetCondition() << 28) |
3050                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3051                (shift.GetType() << 5) |
3052                (operand.GetShiftRegister().GetCode() << 8));
3053        return;
3054      }
3055    }
3056  }
3057  Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand);
3058}
3059
3060void Assembler::bics(Condition cond,
3061                     EncodingSize size,
3062                     Register rd,
3063                     Register rn,
3064                     const Operand& operand) {
3065  CheckIT(cond);
3066  if (operand.IsImmediate()) {
3067    uint32_t imm = operand.GetImmediate();
3068    if (IsUsingT32()) {
3069      ImmediateT32 immediate_t32(imm);
3070      // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3071      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3072        EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3073                   (immediate_t32.GetEncodingValue() & 0xff) |
3074                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3075                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3076        AdvanceIT();
3077        return;
3078      }
3079    } else {
3080      ImmediateA32 immediate_a32(imm);
3081      // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3082      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3083        EmitA32(0x03d00000U | (cond.GetCondition() << 28) |
3084                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3085                immediate_a32.GetEncodingValue());
3086        return;
3087      }
3088    }
3089  }
3090  if (operand.IsImmediateShiftedRegister()) {
3091    Register rm = operand.GetBaseRegister();
3092    if (operand.IsPlainRegister()) {
3093      if (IsUsingT32()) {
3094        // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3095        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3096            rm.IsLow()) {
3097          EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3098          AdvanceIT();
3099          return;
3100        }
3101      }
3102    }
3103    Shift shift = operand.GetShift();
3104    uint32_t amount = operand.GetShiftAmount();
3105    if (IsUsingT32()) {
3106      // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3107      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3108        uint32_t amount_ = amount % 32;
3109        EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3110                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3111                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3112        AdvanceIT();
3113        return;
3114      }
3115    } else {
3116      // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3117      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3118        uint32_t amount_ = amount % 32;
3119        EmitA32(0x01d00000U | (cond.GetCondition() << 28) |
3120                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3121                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3122        return;
3123      }
3124    }
3125  }
3126  if (operand.IsRegisterShiftedRegister()) {
3127    Register rm = operand.GetBaseRegister();
3128    Shift shift = operand.GetShift();
3129    if (IsUsingA32()) {
3130      // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3131      if (cond.IsNotNever()) {
3132        EmitA32(0x01d00010U | (cond.GetCondition() << 28) |
3133                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3134                (shift.GetType() << 5) |
3135                (operand.GetShiftRegister().GetCode() << 8));
3136        return;
3137      }
3138    }
3139  }
3140  Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand);
3141}
3142
3143void Assembler::bkpt(Condition cond, uint32_t imm) {
3144  CheckIT(cond);
3145  if (IsUsingT32()) {
3146    // BKPT{<q>} {#}<imm> ; T1
3147    if ((imm <= 255)) {
3148      EmitT32_16(0xbe00 | imm);
3149      AdvanceIT();
3150      return;
3151    }
3152  } else {
3153    // BKPT{<q>} {#}<imm> ; A1
3154    if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
3155      EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) |
3156              ((imm & 0xfff0) << 4));
3157      return;
3158    }
3159  }
3160  Delegate(kBkpt, &Assembler::bkpt, cond, imm);
3161}
3162
3163void Assembler::bl(Condition cond, Label* label) {
3164  CheckIT(cond);
3165  Label::Offset offset =
3166      label->IsBound()
3167          ? label->GetLocation() -
3168                (GetCursorOffset() + GetArchitectureStatePCOffset())
3169          : 0;
3170  if (IsUsingT32()) {
3171    // BL{<c>}{<q>} <label> ; T1
3172    if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) &&
3173          ((offset & 0x1) == 0)) ||
3174         !label->IsBound())) {
3175      static class EmitOp : public Label::LabelEmitOperator {
3176       public:
3177        EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {}
3178        uint32_t Encode(uint32_t instr,
3179                        Label::Offset pc,
3180                        const Label* label) const {
3181          Label::Offset offset = label->GetLocation() - pc;
3182          VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
3183                      ((offset & 0x1) == 0));
3184          int32_t target = offset >> 1;
3185          uint32_t S = target & (1 << 23);
3186          target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
3187          return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
3188                 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
3189                 ((target & 0x800000) << 3);
3190        }
3191      } immop;
3192      EmitT32_32(Link(0xf000d000U, label, immop));
3193      AdvanceIT();
3194      return;
3195    }
3196  } else {
3197    // BL{<c>}{<q>} <label> ; A1
3198    if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) &&
3199          ((offset & 0x3) == 0)) ||
3200         !label->IsBound()) &&
3201        cond.IsNotNever()) {
3202      static class EmitOp : public Label::LabelEmitOperator {
3203       public:
3204        EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {}
3205        uint32_t Encode(uint32_t instr,
3206                        Label::Offset pc,
3207                        const Label* label) const {
3208          Label::Offset offset = label->GetLocation() - pc;
3209          VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
3210                      ((offset & 0x3) == 0));
3211          const int32_t target = offset >> 2;
3212          return instr | (target & 0xffffff);
3213        }
3214      } immop;
3215      EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28), label, immop));
3216      return;
3217    }
3218  }
3219  Delegate(kBl, &Assembler::bl, cond, label);
3220}
3221
3222void Assembler::blx(Condition cond, Label* label) {
3223  CheckIT(cond);
3224  Label::Offset offset =
3225      label->IsBound()
3226          ? label->GetLocation() -
3227                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
3228          : 0;
3229  if (IsUsingT32()) {
3230    // BLX{<c>}{<q>} <label> ; T2
3231    if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777212) &&
3232          ((offset & 0x3) == 0)) ||
3233         !label->IsBound())) {
3234      static class EmitOp : public Label::LabelEmitOperator {
3235       public:
3236        EmitOp() : Label::LabelEmitOperator(-16777216, 16777212) {}
3237        uint32_t Encode(uint32_t instr,
3238                        Label::Offset pc,
3239                        const Label* label) const {
3240          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
3241          VIXL_ASSERT((offset >= -16777216) && (offset <= 16777212) &&
3242                      ((offset & 0x3) == 0));
3243          int32_t target = offset >> 2;
3244          uint32_t S = target & (1 << 22);
3245          target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20);
3246          return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) |
3247                 ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) |
3248                 ((target & 0x400000) << 4);
3249        }
3250      } immop;
3251      EmitT32_32(Link(0xf000c000U, label, immop));
3252      AdvanceIT();
3253      return;
3254    }
3255  } else {
3256    // BLX{<c>}{<q>} <label> ; A2
3257    if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554430) &&
3258          ((offset & 0x1) == 0)) ||
3259         !label->IsBound())) {
3260      if (cond.Is(al) || AllowStronglyDiscouraged()) {
3261        static class EmitOp : public Label::LabelEmitOperator {
3262         public:
3263          EmitOp() : Label::LabelEmitOperator(-33554432, 33554430) {}
3264          uint32_t Encode(uint32_t instr,
3265                          Label::Offset pc,
3266                          const Label* label) const {
3267            Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
3268            VIXL_ASSERT((offset >= -33554432) && (offset <= 33554430) &&
3269                        ((offset & 0x1) == 0));
3270            const int32_t target = offset >> 1;
3271            return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1);
3272          }
3273        } immop;
3274        EmitA32(Link(0xfa000000U, label, immop));
3275        return;
3276      }
3277    }
3278  }
3279  Delegate(kBlx, &Assembler::blx, cond, label);
3280}
3281
3282void Assembler::blx(Condition cond, Register rm) {
3283  CheckIT(cond);
3284  if (IsUsingT32()) {
3285    // BLX{<c>}{<q>} <Rm> ; T1
3286    EmitT32_16(0x4780 | (rm.GetCode() << 3));
3287    AdvanceIT();
3288    return;
3289  } else {
3290    // BLX{<c>}{<q>} <Rm> ; A1
3291    if (cond.IsNotNever()) {
3292      EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode());
3293      return;
3294    }
3295  }
3296  Delegate(kBlx, &Assembler::blx, cond, rm);
3297}
3298
3299void Assembler::bx(Condition cond, Register rm) {
3300  CheckIT(cond);
3301  if (IsUsingT32()) {
3302    // BX{<c>}{<q>} <Rm> ; T1
3303    EmitT32_16(0x4700 | (rm.GetCode() << 3));
3304    AdvanceIT();
3305    return;
3306  } else {
3307    // BX{<c>}{<q>} <Rm> ; A1
3308    if (cond.IsNotNever()) {
3309      EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode());
3310      return;
3311    }
3312  }
3313  Delegate(kBx, &Assembler::bx, cond, rm);
3314}
3315
3316void Assembler::bxj(Condition cond, Register rm) {
3317  CheckIT(cond);
3318  if (IsUsingT32()) {
3319    // BXJ{<c>}{<q>} <Rm> ; T1
3320    EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16));
3321    AdvanceIT();
3322    return;
3323  } else {
3324    // BXJ{<c>}{<q>} <Rm> ; A1
3325    if (cond.IsNotNever()) {
3326      EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode());
3327      return;
3328    }
3329  }
3330  Delegate(kBxj, &Assembler::bxj, cond, rm);
3331}
3332
3333void Assembler::cbnz(Register rn, Label* label) {
3334  CheckIT(al);
3335  Label::Offset offset =
3336      label->IsBound()
3337          ? label->GetLocation() -
3338                (GetCursorOffset() + GetArchitectureStatePCOffset())
3339          : 0;
3340  if (IsUsingT32()) {
3341    // CBNZ{<q>} <Rn>, <label> ; T1
3342    if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) &&
3343                        ((offset & 0x1) == 0)) ||
3344                       !label->IsBound())) {
3345      static class EmitOp : public Label::LabelEmitOperator {
3346       public:
3347        EmitOp() : Label::LabelEmitOperator(0, 126) {}
3348        uint32_t Encode(uint32_t instr,
3349                        Label::Offset pc,
3350                        const Label* label) const {
3351          Label::Offset offset = label->GetLocation() - pc;
3352          VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
3353                      ((offset & 0x1) == 0));
3354          const int32_t target = offset >> 1;
3355          return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3356        }
3357      } immop;
3358      EmitT32_16(Link(0xb900 | rn.GetCode(), label, immop));
3359      AdvanceIT();
3360      return;
3361    }
3362  }
3363  Delegate(kCbnz, &Assembler::cbnz, rn, label);
3364}
3365
3366void Assembler::cbz(Register rn, Label* label) {
3367  CheckIT(al);
3368  Label::Offset offset =
3369      label->IsBound()
3370          ? label->GetLocation() -
3371                (GetCursorOffset() + GetArchitectureStatePCOffset())
3372          : 0;
3373  if (IsUsingT32()) {
3374    // CBZ{<q>} <Rn>, <label> ; T1
3375    if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) &&
3376                        ((offset & 0x1) == 0)) ||
3377                       !label->IsBound())) {
3378      static class EmitOp : public Label::LabelEmitOperator {
3379       public:
3380        EmitOp() : Label::LabelEmitOperator(0, 126) {}
3381        uint32_t Encode(uint32_t instr,
3382                        Label::Offset pc,
3383                        const Label* label) const {
3384          Label::Offset offset = label->GetLocation() - pc;
3385          VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
3386                      ((offset & 0x1) == 0));
3387          const int32_t target = offset >> 1;
3388          return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3389        }
3390      } immop;
3391      EmitT32_16(Link(0xb100 | rn.GetCode(), label, immop));
3392      AdvanceIT();
3393      return;
3394    }
3395  }
3396  Delegate(kCbz, &Assembler::cbz, rn, label);
3397}
3398
3399void Assembler::clrex(Condition cond) {
3400  CheckIT(cond);
3401  if (IsUsingT32()) {
3402    // CLREX{<c>}{<q>} ; T1
3403    EmitT32_32(0xf3bf8f2fU);
3404    AdvanceIT();
3405    return;
3406  } else {
3407    // CLREX{<c>}{<q>} ; A1
3408    if (cond.Is(al)) {
3409      EmitA32(0xf57ff01fU);
3410      return;
3411    }
3412  }
3413  Delegate(kClrex, &Assembler::clrex, cond);
3414}
3415
3416void Assembler::clz(Condition cond, Register rd, Register rm) {
3417  CheckIT(cond);
3418  if (IsUsingT32()) {
3419    // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1
3420    EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() |
3421               (rm.GetCode() << 16));
3422    AdvanceIT();
3423    return;
3424  } else {
3425    // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1
3426    if (cond.IsNotNever()) {
3427      EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3428              rm.GetCode());
3429      return;
3430    }
3431  }
3432  Delegate(kClz, &Assembler::clz, cond, rd, rm);
3433}
3434
3435void Assembler::cmn(Condition cond,
3436                    EncodingSize size,
3437                    Register rn,
3438                    const Operand& operand) {
3439  CheckIT(cond);
3440  if (operand.IsImmediate()) {
3441    uint32_t imm = operand.GetImmediate();
3442    if (IsUsingT32()) {
3443      ImmediateT32 immediate_t32(imm);
3444      // CMN{<c>}{<q>} <Rn>, #<const> ; T1
3445      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3446        EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) |
3447                   (immediate_t32.GetEncodingValue() & 0xff) |
3448                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3449                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3450        AdvanceIT();
3451        return;
3452      }
3453    } else {
3454      ImmediateA32 immediate_a32(imm);
3455      // CMN{<c>}{<q>} <Rn>, #<const> ; A1
3456      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3457        EmitA32(0x03700000U | (cond.GetCondition() << 28) |
3458                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3459        return;
3460      }
3461    }
3462  }
3463  if (operand.IsImmediateShiftedRegister()) {
3464    Register rm = operand.GetBaseRegister();
3465    if (operand.IsPlainRegister()) {
3466      if (IsUsingT32()) {
3467        // CMN{<c>}{<q>} <Rn>, <Rm> ; T1
3468        if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3469          EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3));
3470          AdvanceIT();
3471          return;
3472        }
3473      }
3474    }
3475    Shift shift = operand.GetShift();
3476    uint32_t amount = operand.GetShiftAmount();
3477    if (IsUsingT32()) {
3478      // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
3479      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3480        uint32_t amount_ = amount % 32;
3481        EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() |
3482                   (operand.GetTypeEncodingValue() << 4) |
3483                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3484        AdvanceIT();
3485        return;
3486      }
3487    } else {
3488      // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3489      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3490        uint32_t amount_ = amount % 32;
3491        EmitA32(0x01700000U | (cond.GetCondition() << 28) |
3492                (rn.GetCode() << 16) | rm.GetCode() |
3493                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3494        return;
3495      }
3496    }
3497  }
3498  if (operand.IsRegisterShiftedRegister()) {
3499    Register rm = operand.GetBaseRegister();
3500    Shift shift = operand.GetShift();
3501    if (IsUsingA32()) {
3502      // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3503      if (cond.IsNotNever()) {
3504        EmitA32(0x01700010U | (cond.GetCondition() << 28) |
3505                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3506                (operand.GetShiftRegister().GetCode() << 8));
3507        return;
3508      }
3509    }
3510  }
3511  Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand);
3512}
3513
3514void Assembler::cmp(Condition cond,
3515                    EncodingSize size,
3516                    Register rn,
3517                    const Operand& operand) {
3518  CheckIT(cond);
3519  if (operand.IsImmediate()) {
3520    uint32_t imm = operand.GetImmediate();
3521    if (IsUsingT32()) {
3522      ImmediateT32 immediate_t32(imm);
3523      // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1
3524      if (!size.IsWide() && rn.IsLow() && (imm <= 255)) {
3525        EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm);
3526        AdvanceIT();
3527        return;
3528      }
3529      // CMP{<c>}{<q>} <Rn>, #<const> ; T2
3530      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3531        EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) |
3532                   (immediate_t32.GetEncodingValue() & 0xff) |
3533                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3534                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3535        AdvanceIT();
3536        return;
3537      }
3538    } else {
3539      ImmediateA32 immediate_a32(imm);
3540      // CMP{<c>}{<q>} <Rn>, #<const> ; A1
3541      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3542        EmitA32(0x03500000U | (cond.GetCondition() << 28) |
3543                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3544        return;
3545      }
3546    }
3547  }
3548  if (operand.IsImmediateShiftedRegister()) {
3549    Register rm = operand.GetBaseRegister();
3550    if (operand.IsPlainRegister()) {
3551      if (IsUsingT32()) {
3552        // CMP{<c>}{<q>} <Rn>, <Rm> ; T1
3553        if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3554          EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3));
3555          AdvanceIT();
3556          return;
3557        }
3558        // CMP{<c>}{<q>} <Rn>, <Rm> ; T2
3559        if (!size.IsWide()) {
3560          EmitT32_16(0x4500 | (rn.GetCode() & 0x7) |
3561                     ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
3562          AdvanceIT();
3563          return;
3564        }
3565      }
3566    }
3567    Shift shift = operand.GetShift();
3568    uint32_t amount = operand.GetShiftAmount();
3569    if (IsUsingT32()) {
3570      // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3
3571      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3572        uint32_t amount_ = amount % 32;
3573        EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() |
3574                   (operand.GetTypeEncodingValue() << 4) |
3575                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3576        AdvanceIT();
3577        return;
3578      }
3579    } else {
3580      // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3581      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3582        uint32_t amount_ = amount % 32;
3583        EmitA32(0x01500000U | (cond.GetCondition() << 28) |
3584                (rn.GetCode() << 16) | rm.GetCode() |
3585                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3586        return;
3587      }
3588    }
3589  }
3590  if (operand.IsRegisterShiftedRegister()) {
3591    Register rm = operand.GetBaseRegister();
3592    Shift shift = operand.GetShift();
3593    if (IsUsingA32()) {
3594      // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3595      if (cond.IsNotNever()) {
3596        EmitA32(0x01500010U | (cond.GetCondition() << 28) |
3597                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3598                (operand.GetShiftRegister().GetCode() << 8));
3599        return;
3600      }
3601    }
3602  }
3603  Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand);
3604}
3605
3606void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) {
3607  CheckIT(cond);
3608  if (IsUsingT32()) {
3609    // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1
3610    EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3611               rm.GetCode());
3612    AdvanceIT();
3613    return;
3614  } else {
3615    // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1
3616    if ((cond.Is(al) || AllowUnpredictable())) {
3617      EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3618              (rn.GetCode() << 16) | rm.GetCode());
3619      return;
3620    }
3621  }
3622  Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm);
3623}
3624
3625void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) {
3626  CheckIT(cond);
3627  if (IsUsingT32()) {
3628    // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1
3629    EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3630               rm.GetCode());
3631    AdvanceIT();
3632    return;
3633  } else {
3634    // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1
3635    if ((cond.Is(al) || AllowUnpredictable())) {
3636      EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3637              (rn.GetCode() << 16) | rm.GetCode());
3638      return;
3639    }
3640  }
3641  Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm);
3642}
3643
3644void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) {
3645  CheckIT(cond);
3646  if (IsUsingT32()) {
3647    // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1
3648    EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3649               rm.GetCode());
3650    AdvanceIT();
3651    return;
3652  } else {
3653    // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1
3654    if ((cond.Is(al) || AllowUnpredictable())) {
3655      EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3656              (rn.GetCode() << 16) | rm.GetCode());
3657      return;
3658    }
3659  }
3660  Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm);
3661}
3662
3663void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) {
3664  CheckIT(cond);
3665  if (IsUsingT32()) {
3666    // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1
3667    EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3668               rm.GetCode());
3669    AdvanceIT();
3670    return;
3671  } else {
3672    // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1
3673    if ((cond.Is(al) || AllowUnpredictable())) {
3674      EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3675              (rn.GetCode() << 16) | rm.GetCode());
3676      return;
3677    }
3678  }
3679  Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm);
3680}
3681
3682void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) {
3683  CheckIT(cond);
3684  if (IsUsingT32()) {
3685    // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1
3686    EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3687               rm.GetCode());
3688    AdvanceIT();
3689    return;
3690  } else {
3691    // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1
3692    if ((cond.Is(al) || AllowUnpredictable())) {
3693      EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3694              (rn.GetCode() << 16) | rm.GetCode());
3695      return;
3696    }
3697  }
3698  Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm);
3699}
3700
3701void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) {
3702  CheckIT(cond);
3703  if (IsUsingT32()) {
3704    // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1
3705    EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3706               rm.GetCode());
3707    AdvanceIT();
3708    return;
3709  } else {
3710    // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1
3711    if ((cond.Is(al) || AllowUnpredictable())) {
3712      EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3713              (rn.GetCode() << 16) | rm.GetCode());
3714      return;
3715    }
3716  }
3717  Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm);
3718}
3719
3720void Assembler::dmb(Condition cond, MemoryBarrier option) {
3721  CheckIT(cond);
3722  if (IsUsingT32()) {
3723    // DMB{<c>}{<q>} {<option>} ; T1
3724    EmitT32_32(0xf3bf8f50U | option.GetType());
3725    AdvanceIT();
3726    return;
3727  } else {
3728    // DMB{<c>}{<q>} {<option>} ; A1
3729    if (cond.Is(al)) {
3730      EmitA32(0xf57ff050U | option.GetType());
3731      return;
3732    }
3733  }
3734  Delegate(kDmb, &Assembler::dmb, cond, option);
3735}
3736
3737void Assembler::dsb(Condition cond, MemoryBarrier option) {
3738  CheckIT(cond);
3739  if (IsUsingT32()) {
3740    // DSB{<c>}{<q>} {<option>} ; T1
3741    EmitT32_32(0xf3bf8f40U | option.GetType());
3742    AdvanceIT();
3743    return;
3744  } else {
3745    // DSB{<c>}{<q>} {<option>} ; A1
3746    if (cond.Is(al)) {
3747      EmitA32(0xf57ff040U | option.GetType());
3748      return;
3749    }
3750  }
3751  Delegate(kDsb, &Assembler::dsb, cond, option);
3752}
3753
3754void Assembler::eor(Condition cond,
3755                    EncodingSize size,
3756                    Register rd,
3757                    Register rn,
3758                    const Operand& operand) {
3759  CheckIT(cond);
3760  if (operand.IsImmediate()) {
3761    uint32_t imm = operand.GetImmediate();
3762    if (IsUsingT32()) {
3763      ImmediateT32 immediate_t32(imm);
3764      // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3765      if (!size.IsNarrow() && immediate_t32.IsValid()) {
3766        EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3767                   (immediate_t32.GetEncodingValue() & 0xff) |
3768                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3769                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3770        AdvanceIT();
3771        return;
3772      }
3773    } else {
3774      ImmediateA32 immediate_a32(imm);
3775      // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3776      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3777        EmitA32(0x02200000U | (cond.GetCondition() << 28) |
3778                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3779                immediate_a32.GetEncodingValue());
3780        return;
3781      }
3782    }
3783  }
3784  if (operand.IsImmediateShiftedRegister()) {
3785    Register rm = operand.GetBaseRegister();
3786    if (operand.IsPlainRegister()) {
3787      if (IsUsingT32()) {
3788        // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3789        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3790            rm.IsLow()) {
3791          EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
3792          AdvanceIT();
3793          return;
3794        }
3795      }
3796    }
3797    Shift shift = operand.GetShift();
3798    uint32_t amount = operand.GetShiftAmount();
3799    if (IsUsingT32()) {
3800      // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3801      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3802        uint32_t amount_ = amount % 32;
3803        EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3804                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3805                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3806        AdvanceIT();
3807        return;
3808      }
3809    } else {
3810      // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3811      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3812        uint32_t amount_ = amount % 32;
3813        EmitA32(0x00200000U | (cond.GetCondition() << 28) |
3814                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3815                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3816        return;
3817      }
3818    }
3819  }
3820  if (operand.IsRegisterShiftedRegister()) {
3821    Register rm = operand.GetBaseRegister();
3822    Shift shift = operand.GetShift();
3823    if (IsUsingA32()) {
3824      // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3825      if (cond.IsNotNever()) {
3826        EmitA32(0x00200010U | (cond.GetCondition() << 28) |
3827                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3828                (shift.GetType() << 5) |
3829                (operand.GetShiftRegister().GetCode() << 8));
3830        return;
3831      }
3832    }
3833  }
3834  Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand);
3835}
3836
3837void Assembler::eors(Condition cond,
3838                     EncodingSize size,
3839                     Register rd,
3840                     Register rn,
3841                     const Operand& operand) {
3842  CheckIT(cond);
3843  if (operand.IsImmediate()) {
3844    uint32_t imm = operand.GetImmediate();
3845    if (IsUsingT32()) {
3846      ImmediateT32 immediate_t32(imm);
3847      // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3848      if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) {
3849        EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3850                   (immediate_t32.GetEncodingValue() & 0xff) |
3851                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3852                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3853        AdvanceIT();
3854        return;
3855      }
3856    } else {
3857      ImmediateA32 immediate_a32(imm);
3858      // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3859      if (immediate_a32.IsValid() && cond.IsNotNever()) {
3860        EmitA32(0x02300000U | (cond.GetCondition() << 28) |
3861                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3862                immediate_a32.GetEncodingValue());
3863        return;
3864      }
3865    }
3866  }
3867  if (operand.IsImmediateShiftedRegister()) {
3868    Register rm = operand.GetBaseRegister();
3869    if (operand.IsPlainRegister()) {
3870      if (IsUsingT32()) {
3871        // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3872        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3873            rm.IsLow()) {
3874          EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
3875          AdvanceIT();
3876          return;
3877        }
3878      }
3879    }
3880    Shift shift = operand.GetShift();
3881    uint32_t amount = operand.GetShiftAmount();
3882    if (IsUsingT32()) {
3883      // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3884      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) {
3885        uint32_t amount_ = amount % 32;
3886        EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3887                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3888                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3889        AdvanceIT();
3890        return;
3891      }
3892    } else {
3893      // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3894      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3895        uint32_t amount_ = amount % 32;
3896        EmitA32(0x00300000U | (cond.GetCondition() << 28) |
3897                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3898                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3899        return;
3900      }
3901    }
3902  }
3903  if (operand.IsRegisterShiftedRegister()) {
3904    Register rm = operand.GetBaseRegister();
3905    Shift shift = operand.GetShift();
3906    if (IsUsingA32()) {
3907      // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3908      if (cond.IsNotNever()) {
3909        EmitA32(0x00300010U | (cond.GetCondition() << 28) |
3910                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3911                (shift.GetType() << 5) |
3912                (operand.GetShiftRegister().GetCode() << 8));
3913        return;
3914      }
3915    }
3916  }
3917  Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand);
3918}
3919
3920void Assembler::fldmdbx(Condition cond,
3921                        Register rn,
3922                        WriteBack write_back,
3923                        DRegisterList dreglist) {
3924  CheckIT(cond);
3925  if (IsUsingT32()) {
3926    // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
3927    if (write_back.DoesWriteBack() &&
3928        (((dreglist.GetLength() <= 16) &&
3929          (dreglist.GetLastDRegister().GetCode() < 16)) ||
3930         AllowUnpredictable())) {
3931      const DRegister& dreg = dreglist.GetFirstDRegister();
3932      unsigned len = dreglist.GetLength() * 2;
3933      EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
3934                 (len & 0xff));
3935      AdvanceIT();
3936      return;
3937    }
3938  } else {
3939    // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
3940    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
3941        (((dreglist.GetLength() <= 16) &&
3942          (dreglist.GetLastDRegister().GetCode() < 16)) ||
3943         AllowUnpredictable())) {
3944      const DRegister& dreg = dreglist.GetFirstDRegister();
3945      unsigned len = dreglist.GetLength() * 2;
3946      EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
3947              dreg.Encode(22, 12) | (len & 0xff));
3948      return;
3949    }
3950  }
3951  Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist);
3952}
3953
3954void Assembler::fldmiax(Condition cond,
3955                        Register rn,
3956                        WriteBack write_back,
3957                        DRegisterList dreglist) {
3958  CheckIT(cond);
3959  if (IsUsingT32()) {
3960    // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
3961    if ((((dreglist.GetLength() <= 16) &&
3962          (dreglist.GetLastDRegister().GetCode() < 16)) ||
3963         AllowUnpredictable())) {
3964      const DRegister& dreg = dreglist.GetFirstDRegister();
3965      unsigned len = dreglist.GetLength() * 2;
3966      EmitT32_32(0xec900b01U | (rn.GetCode() << 16) |
3967                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
3968                 (len & 0xff));
3969      AdvanceIT();
3970      return;
3971    }
3972  } else {
3973    // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
3974    if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
3975                               (dreglist.GetLastDRegister().GetCode() < 16)) ||
3976                              AllowUnpredictable())) {
3977      const DRegister& dreg = dreglist.GetFirstDRegister();
3978      unsigned len = dreglist.GetLength() * 2;
3979      EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
3980              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
3981              (len & 0xff));
3982      return;
3983    }
3984  }
3985  Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist);
3986}
3987
3988void Assembler::fstmdbx(Condition cond,
3989                        Register rn,
3990                        WriteBack write_back,
3991                        DRegisterList dreglist) {
3992  CheckIT(cond);
3993  if (IsUsingT32()) {
3994    // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
3995    if (write_back.DoesWriteBack() &&
3996        (((dreglist.GetLength() <= 16) &&
3997          (dreglist.GetLastDRegister().GetCode() < 16)) ||
3998         AllowUnpredictable())) {
3999      const DRegister& dreg = dreglist.GetFirstDRegister();
4000      unsigned len = dreglist.GetLength() * 2;
4001      EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
4002                 (len & 0xff));
4003      AdvanceIT();
4004      return;
4005    }
4006  } else {
4007    // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
4008    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
4009        (((dreglist.GetLength() <= 16) &&
4010          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4011         AllowUnpredictable())) {
4012      const DRegister& dreg = dreglist.GetFirstDRegister();
4013      unsigned len = dreglist.GetLength() * 2;
4014      EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4015              dreg.Encode(22, 12) | (len & 0xff));
4016      return;
4017    }
4018  }
4019  Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist);
4020}
4021
4022void Assembler::fstmiax(Condition cond,
4023                        Register rn,
4024                        WriteBack write_back,
4025                        DRegisterList dreglist) {
4026  CheckIT(cond);
4027  if (IsUsingT32()) {
4028    // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
4029    if ((((dreglist.GetLength() <= 16) &&
4030          (dreglist.GetLastDRegister().GetCode() < 16)) ||
4031         AllowUnpredictable())) {
4032      const DRegister& dreg = dreglist.GetFirstDRegister();
4033      unsigned len = dreglist.GetLength() * 2;
4034      EmitT32_32(0xec800b01U | (rn.GetCode() << 16) |
4035                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4036                 (len & 0xff));
4037      AdvanceIT();
4038      return;
4039    }
4040  } else {
4041    // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
4042    if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
4043                               (dreglist.GetLastDRegister().GetCode() < 16)) ||
4044                              AllowUnpredictable())) {
4045      const DRegister& dreg = dreglist.GetFirstDRegister();
4046      unsigned len = dreglist.GetLength() * 2;
4047      EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4048              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4049              (len & 0xff));
4050      return;
4051    }
4052  }
4053  Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist);
4054}
4055
4056void Assembler::hlt(Condition cond, uint32_t imm) {
4057  CheckIT(cond);
4058  if (IsUsingT32()) {
4059    // HLT{<q>} {#}<imm> ; T1
4060    if ((imm <= 63)) {
4061      EmitT32_16(0xba80 | imm);
4062      AdvanceIT();
4063      return;
4064    }
4065  } else {
4066    // HLT{<q>} {#}<imm> ; A1
4067    if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4068      EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4069              ((imm & 0xfff0) << 4));
4070      return;
4071    }
4072  }
4073  Delegate(kHlt, &Assembler::hlt, cond, imm);
4074}
4075
4076void Assembler::hvc(Condition cond, uint32_t imm) {
4077  CheckIT(cond);
4078  if (IsUsingT32()) {
4079    // HVC{<q>} {#}<imm16> ; T1
4080    if ((imm <= 65535)) {
4081      EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
4082      AdvanceIT();
4083      return;
4084    }
4085  } else {
4086    // HVC{<q>} {#}<imm16> ; A1
4087    if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4088      EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4089              ((imm & 0xfff0) << 4));
4090      return;
4091    }
4092  }
4093  Delegate(kHvc, &Assembler::hvc, cond, imm);
4094}
4095
4096void Assembler::isb(Condition cond, MemoryBarrier option) {
4097  CheckIT(cond);
4098  if (IsUsingT32()) {
4099    // ISB{<c>}{<q>} {<option>} ; T1
4100    EmitT32_32(0xf3bf8f60U | option.GetType());
4101    AdvanceIT();
4102    return;
4103  } else {
4104    // ISB{<c>}{<q>} {<option>} ; A1
4105    if (cond.Is(al)) {
4106      EmitA32(0xf57ff060U | option.GetType());
4107      return;
4108    }
4109  }
4110  Delegate(kIsb, &Assembler::isb, cond, option);
4111}
4112
4113void Assembler::it(Condition cond, uint16_t mask) {
4114  CheckNotIT();
4115  if (mask != 0) {
4116    if ((cond.GetCondition() & 0x1) != 0) {
4117      if ((mask & 0x1) != 0) {
4118        mask ^= 0xE;
4119      } else if ((mask & 0x2) != 0) {
4120        mask ^= 0xC;
4121      } else if ((mask & 0x4) != 0) {
4122        mask ^= 0x8;
4123      }
4124    }
4125    if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask);
4126    SetIT(cond, mask);
4127    return;
4128  }
4129  DelegateIt(cond, mask);
4130}
4131
4132void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) {
4133  CheckIT(cond);
4134  if (operand.IsImmediateZero()) {
4135    Register rn = operand.GetBaseRegister();
4136    if (IsUsingT32()) {
4137      // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1
4138      if ((operand.GetAddrMode() == Offset) &&
4139          ((!rn.IsPC()) || AllowUnpredictable())) {
4140        EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4141        AdvanceIT();
4142        return;
4143      }
4144    } else {
4145      // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1
4146      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
4147          ((!rn.IsPC()) || AllowUnpredictable())) {
4148        EmitA32(0x01900c9fU | (cond.GetCondition() << 28) |
4149                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4150        return;
4151      }
4152    }
4153  }
4154  Delegate(kLda, &Assembler::lda, cond, rt, operand);
4155}
4156
4157void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) {
4158  CheckIT(cond);
4159  if (operand.IsImmediateZero()) {
4160    Register rn = operand.GetBaseRegister();
4161    if (IsUsingT32()) {
4162      // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4163      if ((operand.GetAddrMode() == Offset) &&
4164          ((!rn.IsPC()) || AllowUnpredictable())) {
4165        EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4166        AdvanceIT();
4167        return;
4168      }
4169    } else {
4170      // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4171      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
4172          ((!rn.IsPC()) || AllowUnpredictable())) {
4173        EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) |
4174                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4175        return;
4176      }
4177    }
4178  }
4179  Delegate(kLdab, &Assembler::ldab, cond, rt, operand);
4180}
4181
4182void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) {
4183  CheckIT(cond);
4184  if (operand.IsImmediateZero()) {
4185    Register rn = operand.GetBaseRegister();
4186    if (IsUsingT32()) {
4187      // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1
4188      if ((operand.GetAddrMode() == Offset) &&
4189          ((!rn.IsPC()) || AllowUnpredictable())) {
4190        EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4191        AdvanceIT();
4192        return;
4193      }
4194    } else {
4195      // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1
4196      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
4197          ((!rn.IsPC()) || AllowUnpredictable())) {
4198        EmitA32(0x01900e9fU | (cond.GetCondition() << 28) |
4199                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4200        return;
4201      }
4202    }
4203  }
4204  Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand);
4205}
4206
4207void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) {
4208  CheckIT(cond);
4209  if (operand.IsImmediateZero()) {
4210    Register rn = operand.GetBaseRegister();
4211    if (IsUsingT32()) {
4212      // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4213      if ((operand.GetAddrMode() == Offset) &&
4214          ((!rn.IsPC()) || AllowUnpredictable())) {
4215        EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4216        AdvanceIT();
4217        return;
4218      }
4219    } else {
4220      // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4221      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
4222          ((!rn.IsPC()) || AllowUnpredictable())) {
4223        EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) |
4224                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4225        return;
4226      }
4227    }
4228  }
4229  Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand);
4230}
4231
4232void Assembler::ldaexd(Condition cond,
4233                       Register rt,
4234                       Register rt2,
4235                       const MemOperand& operand) {
4236  CheckIT(cond);
4237  if (operand.IsImmediateZero()) {
4238    Register rn = operand.GetBaseRegister();
4239    if (IsUsingT32()) {
4240      // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
4241      if ((operand.GetAddrMode() == Offset) &&
4242          ((!rn.IsPC()) || AllowUnpredictable())) {
4243        EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
4244                   (rn.GetCode() << 16));
4245        AdvanceIT();
4246        return;
4247      }
4248    } else {
4249      // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
4250      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
4251          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
4252          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
4253           AllowUnpredictable())) {
4254        EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) |
4255                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4256        return;
4257      }
4258    }
4259  }
4260  Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand);
4261}
4262
4263void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) {
4264  CheckIT(cond);
4265  if (operand.IsImmediateZero()) {
4266    Register rn = operand.GetBaseRegister();
4267    if (IsUsingT32()) {
4268      // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4269      if ((operand.GetAddrMode() == Offset) &&
4270          ((!rn.IsPC()) || AllowUnpredictable())) {
4271        EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4272        AdvanceIT();
4273        return;
4274      }
4275    } else {
4276      // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4277      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
4278          ((!rn.IsPC()) || AllowUnpredictable())) {
4279        EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) |
4280                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4281        return;
4282      }
4283    }
4284  }
4285  Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand);
4286}
4287
4288void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) {
4289  CheckIT(cond);
4290  if (operand.IsImmediateZero()) {
4291    Register rn = operand.GetBaseRegister();
4292    if (IsUsingT32()) {
4293      // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4294      if ((operand.GetAddrMode() == Offset) &&
4295          ((!rn.IsPC()) || AllowUnpredictable())) {
4296        EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4297        AdvanceIT();
4298        return;
4299      }
4300    } else {
4301      // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4302      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
4303          ((!rn.IsPC()) || AllowUnpredictable())) {
4304        EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) |
4305                (rt.GetCode() << 12) | (rn.GetCode() << 16));
4306        return;
4307      }
4308    }
4309  }
4310  Delegate(kLdah, &Assembler::ldah, cond, rt, operand);
4311}
4312
4313void Assembler::ldm(Condition cond,
4314                    EncodingSize size,
4315                    Register rn,
4316                    WriteBack write_back,
4317                    RegisterList registers) {
4318  CheckIT(cond);
4319  if (IsUsingT32()) {
4320    // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1
4321    if (!size.IsWide() && rn.IsLow() &&
4322        (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4323         write_back.DoesWriteBack()) &&
4324        ((registers.GetList() & ~0xff) == 0)) {
4325      EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4326                 GetRegisterListEncoding(registers, 0, 8));
4327      AdvanceIT();
4328      return;
4329    }
4330    // LDM{<c>}{<q>} SP!, <registers> ; T1
4331    if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
4332        ((registers.GetList() & ~0x80ff) == 0)) {
4333      EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
4334                 GetRegisterListEncoding(registers, 0, 8));
4335      AdvanceIT();
4336      return;
4337    }
4338    // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2
4339    if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
4340      EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4341                 (write_back.GetWriteBackUint32() << 21) |
4342                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4343                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4344                 GetRegisterListEncoding(registers, 0, 13));
4345      AdvanceIT();
4346      return;
4347    }
4348  } else {
4349    // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1
4350    if (cond.IsNotNever()) {
4351      EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4352              (write_back.GetWriteBackUint32() << 21) |
4353              GetRegisterListEncoding(registers, 0, 16));
4354      return;
4355    }
4356  }
4357  Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers);
4358}
4359
4360void Assembler::ldmda(Condition cond,
4361                      Register rn,
4362                      WriteBack write_back,
4363                      RegisterList registers) {
4364  CheckIT(cond);
4365  if (IsUsingA32()) {
4366    // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4367    if (cond.IsNotNever()) {
4368      EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4369              (write_back.GetWriteBackUint32() << 21) |
4370              GetRegisterListEncoding(registers, 0, 16));
4371      return;
4372    }
4373  }
4374  Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers);
4375}
4376
4377void Assembler::ldmdb(Condition cond,
4378                      Register rn,
4379                      WriteBack write_back,
4380                      RegisterList registers) {
4381  CheckIT(cond);
4382  if (IsUsingT32()) {
4383    // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
4384    if (((registers.GetList() & ~0xdfff) == 0)) {
4385      EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4386                 (write_back.GetWriteBackUint32() << 21) |
4387                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4388                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4389                 GetRegisterListEncoding(registers, 0, 13));
4390      AdvanceIT();
4391      return;
4392    }
4393  } else {
4394    // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4395    if (cond.IsNotNever()) {
4396      EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4397              (write_back.GetWriteBackUint32() << 21) |
4398              GetRegisterListEncoding(registers, 0, 16));
4399      return;
4400    }
4401  }
4402  Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers);
4403}
4404
4405void Assembler::ldmea(Condition cond,
4406                      Register rn,
4407                      WriteBack write_back,
4408                      RegisterList registers) {
4409  CheckIT(cond);
4410  if (IsUsingT32()) {
4411    // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1
4412    if (((registers.GetList() & ~0xdfff) == 0)) {
4413      EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4414                 (write_back.GetWriteBackUint32() << 21) |
4415                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4416                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4417                 GetRegisterListEncoding(registers, 0, 13));
4418      AdvanceIT();
4419      return;
4420    }
4421  } else {
4422    // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4423    if (cond.IsNotNever()) {
4424      EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4425              (write_back.GetWriteBackUint32() << 21) |
4426              GetRegisterListEncoding(registers, 0, 16));
4427      return;
4428    }
4429  }
4430  Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers);
4431}
4432
4433void Assembler::ldmed(Condition cond,
4434                      Register rn,
4435                      WriteBack write_back,
4436                      RegisterList registers) {
4437  CheckIT(cond);
4438  if (IsUsingA32()) {
4439    // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
4440    if (cond.IsNotNever()) {
4441      EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4442              (write_back.GetWriteBackUint32() << 21) |
4443              GetRegisterListEncoding(registers, 0, 16));
4444      return;
4445    }
4446  }
4447  Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers);
4448}
4449
4450void Assembler::ldmfa(Condition cond,
4451                      Register rn,
4452                      WriteBack write_back,
4453                      RegisterList registers) {
4454  CheckIT(cond);
4455  if (IsUsingA32()) {
4456    // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4457    if (cond.IsNotNever()) {
4458      EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4459              (write_back.GetWriteBackUint32() << 21) |
4460              GetRegisterListEncoding(registers, 0, 16));
4461      return;
4462    }
4463  }
4464  Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers);
4465}
4466
4467void Assembler::ldmfd(Condition cond,
4468                      EncodingSize size,
4469                      Register rn,
4470                      WriteBack write_back,
4471                      RegisterList registers) {
4472  CheckIT(cond);
4473  if (IsUsingT32()) {
4474    // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
4475    if (!size.IsWide() && rn.IsLow() &&
4476        (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4477         write_back.DoesWriteBack()) &&
4478        ((registers.GetList() & ~0xff) == 0)) {
4479      EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4480                 GetRegisterListEncoding(registers, 0, 8));
4481      AdvanceIT();
4482      return;
4483    }
4484    // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2
4485    if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
4486      EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4487                 (write_back.GetWriteBackUint32() << 21) |
4488                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4489                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4490                 GetRegisterListEncoding(registers, 0, 13));
4491      AdvanceIT();
4492      return;
4493    }
4494  } else {
4495    // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
4496    if (cond.IsNotNever()) {
4497      EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4498              (write_back.GetWriteBackUint32() << 21) |
4499              GetRegisterListEncoding(registers, 0, 16));
4500      return;
4501    }
4502  }
4503  Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers);
4504}
4505
4506void Assembler::ldmib(Condition cond,
4507                      Register rn,
4508                      WriteBack write_back,
4509                      RegisterList registers) {
4510  CheckIT(cond);
4511  if (IsUsingA32()) {
4512    // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4513    if (cond.IsNotNever()) {
4514      EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4515              (write_back.GetWriteBackUint32() << 21) |
4516              GetRegisterListEncoding(registers, 0, 16));
4517      return;
4518    }
4519  }
4520  Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers);
4521}
4522
4523void Assembler::ldr(Condition cond,
4524                    EncodingSize size,
4525                    Register rt,
4526                    const MemOperand& operand) {
4527  CheckIT(cond);
4528  if (operand.IsImmediate()) {
4529    Register rn = operand.GetBaseRegister();
4530    int32_t offset = operand.GetOffsetImmediate();
4531    if (IsUsingT32()) {
4532      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
4533      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
4534          (offset <= 124) && ((offset % 4) == 0) &&
4535          (operand.GetAddrMode() == Offset)) {
4536        int32_t offset_ = offset >> 2;
4537        EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) |
4538                   ((offset_ & 0x1f) << 6));
4539        AdvanceIT();
4540        return;
4541      }
4542      // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
4543      if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
4544          ((offset % 4) == 0) && rn.Is(sp) &&
4545          (operand.GetAddrMode() == Offset)) {
4546        int32_t offset_ = offset >> 2;
4547        EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff));
4548        AdvanceIT();
4549        return;
4550      }
4551      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
4552      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
4553          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
4554        EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4555                   (offset & 0xfff));
4556        AdvanceIT();
4557        return;
4558      }
4559      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
4560      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
4561          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
4562        EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4563                   (-offset & 0xff));
4564        AdvanceIT();
4565        return;
4566      }
4567      // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
4568      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4569          (operand.GetAddrMode() == PostIndex) &&
4570          ((rn.GetCode() & 0xf) != 0xf)) {
4571        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4572        uint32_t offset_ = abs(offset);
4573        EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4574                   offset_ | (sign << 9));
4575        AdvanceIT();
4576        return;
4577      }
4578      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
4579      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4580          (operand.GetAddrMode() == PreIndex) &&
4581          ((rn.GetCode() & 0xf) != 0xf)) {
4582        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4583        uint32_t offset_ = abs(offset);
4584        EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4585                   offset_ | (sign << 9));
4586        AdvanceIT();
4587        return;
4588      }
4589      // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2
4590      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
4591          rn.Is(pc) && (operand.GetAddrMode() == Offset)) {
4592        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4593        uint32_t offset_ = abs(offset);
4594        EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
4595        AdvanceIT();
4596        return;
4597      }
4598    } else {
4599      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
4600      if ((offset >= -4095) && (offset <= 4095) &&
4601          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
4602          ((rn.GetCode() & 0xf) != 0xf)) {
4603        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4604        uint32_t offset_ = abs(offset);
4605        EmitA32(0x05100000U | (cond.GetCondition() << 28) |
4606                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4607                (sign << 23));
4608        return;
4609      }
4610      // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
4611      if ((offset >= -4095) && (offset <= 4095) &&
4612          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever() &&
4613          ((rn.GetCode() & 0xf) != 0xf)) {
4614        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4615        uint32_t offset_ = abs(offset);
4616        EmitA32(0x04100000U | (cond.GetCondition() << 28) |
4617                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4618                (sign << 23));
4619        return;
4620      }
4621      // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
4622      if ((offset >= -4095) && (offset <= 4095) &&
4623          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever() &&
4624          ((rn.GetCode() & 0xf) != 0xf)) {
4625        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4626        uint32_t offset_ = abs(offset);
4627        EmitA32(0x05300000U | (cond.GetCondition() << 28) |
4628                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4629                (sign << 23));
4630        return;
4631      }
4632      // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
4633      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
4634          (operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
4635        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4636        uint32_t offset_ = abs(offset);
4637        EmitA32(0x051f0000U | (cond.GetCondition() << 28) |
4638                (rt.GetCode() << 12) | offset_ | (sign << 23));
4639        return;
4640      }
4641    }
4642  }
4643  if (operand.IsPlainRegister()) {
4644    Register rn = operand.GetBaseRegister();
4645    Sign sign = operand.GetSign();
4646    Register rm = operand.GetOffsetRegister();
4647    if (IsUsingT32()) {
4648      // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
4649      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
4650          sign.IsPlus() && (operand.GetAddrMode() == Offset)) {
4651        EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) |
4652                   (rm.GetCode() << 6));
4653        AdvanceIT();
4654        return;
4655      }
4656    }
4657  }
4658  if (operand.IsShiftedRegister()) {
4659    Register rn = operand.GetBaseRegister();
4660    Sign sign = operand.GetSign();
4661    Register rm = operand.GetOffsetRegister();
4662    Shift shift = operand.GetShift();
4663    uint32_t amount = operand.GetShiftAmount();
4664    if (IsUsingT32()) {
4665      // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
4666      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
4667          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
4668        EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4669                   rm.GetCode() | (amount << 4));
4670        AdvanceIT();
4671        return;
4672      }
4673    } else {
4674      // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
4675      if (operand.IsShiftValid() && (operand.GetAddrMode() == Offset) &&
4676          cond.IsNotNever()) {
4677        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4678        uint32_t shift_ = TypeEncodingValue(shift);
4679        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4680        EmitA32(0x07100000U | (cond.GetCondition() << 28) |
4681                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4682                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4683        return;
4684      }
4685      // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
4686      if (operand.IsShiftValid() && (operand.GetAddrMode() == PostIndex) &&
4687          cond.IsNotNever()) {
4688        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4689        uint32_t shift_ = TypeEncodingValue(shift);
4690        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4691        EmitA32(0x06100000U | (cond.GetCondition() << 28) |
4692                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4693                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4694        return;
4695      }
4696      // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
4697      if (operand.IsShiftValid() && (operand.GetAddrMode() == PreIndex) &&
4698          cond.IsNotNever()) {
4699        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4700        uint32_t shift_ = TypeEncodingValue(shift);
4701        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4702        EmitA32(0x07300000U | (cond.GetCondition() << 28) |
4703                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4704                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4705        return;
4706      }
4707    }
4708  }
4709  Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand);
4710}
4711
4712void Assembler::ldr(Condition cond,
4713                    EncodingSize size,
4714                    Register rt,
4715                    Label* label) {
4716  CheckIT(cond);
4717  Label::Offset offset =
4718      label->IsBound()
4719          ? label->GetLocation() -
4720                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
4721          : 0;
4722  if (IsUsingT32()) {
4723    // LDR{<c>}{<q>} <Rt>, <label> ; T1
4724    if (!size.IsWide() && rt.IsLow() &&
4725        ((label->IsBound() && (offset >= 0) && (offset <= 1020) &&
4726          ((offset & 0x3) == 0)) ||
4727         (!label->IsBound() && size.IsNarrow()))) {
4728      static class EmitOp : public Label::LabelEmitOperator {
4729       public:
4730        EmitOp() : Label::LabelEmitOperator(0, 1020) {}
4731        uint32_t Encode(uint32_t instr,
4732                        Label::Offset pc,
4733                        const Label* label) const {
4734          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4735          VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
4736                      ((offset & 0x3) == 0));
4737          const int32_t target = offset >> 2;
4738          return instr | (target & 0xff);
4739        }
4740      } immop;
4741      EmitT32_16(Link(0x4800 | (rt.GetCode() << 8), label, immop));
4742      AdvanceIT();
4743      return;
4744    }
4745    // LDR{<c>}{<q>} <Rt>, <label> ; T2
4746    if (!size.IsNarrow() &&
4747        ((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
4748         !label->IsBound())) {
4749      static class EmitOp : public Label::LabelEmitOperator {
4750       public:
4751        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
4752        uint32_t Encode(uint32_t instr,
4753                        Label::Offset pc,
4754                        const Label* label) const {
4755          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4756          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
4757          uint32_t U = (offset >= 0) && !label->IsMinusZero();
4758          int32_t target = abs(offset) | (U << 12);
4759          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
4760        }
4761      } immop;
4762      EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12), label, immop));
4763      AdvanceIT();
4764      return;
4765    }
4766  } else {
4767    // LDR{<c>}{<q>} <Rt>, <label> ; A1
4768    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
4769         !label->IsBound()) &&
4770        cond.IsNotNever()) {
4771      static class EmitOp : public Label::LabelEmitOperator {
4772       public:
4773        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
4774        uint32_t Encode(uint32_t instr,
4775                        Label::Offset pc,
4776                        const Label* label) const {
4777          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4778          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
4779          uint32_t U = (offset >= 0) && !label->IsMinusZero();
4780          int32_t target = abs(offset) | (U << 12);
4781          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
4782        }
4783      } immop;
4784      EmitA32(
4785          Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
4786               label,
4787               immop));
4788      return;
4789    }
4790  }
4791  Delegate(kLdr, &Assembler::ldr, cond, size, rt, label);
4792}
4793
4794void Assembler::ldrb(Condition cond,
4795                     EncodingSize size,
4796                     Register rt,
4797                     const MemOperand& operand) {
4798  CheckIT(cond);
4799  if (operand.IsImmediate()) {
4800    Register rn = operand.GetBaseRegister();
4801    int32_t offset = operand.GetOffsetImmediate();
4802    if (IsUsingT32()) {
4803      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
4804      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
4805          (offset <= 31) && (operand.GetAddrMode() == Offset)) {
4806        EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) |
4807                   ((offset & 0x1f) << 6));
4808        AdvanceIT();
4809        return;
4810      }
4811      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
4812      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
4813          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
4814          !rt.Is(pc)) {
4815        EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4816                   (offset & 0xfff));
4817        AdvanceIT();
4818        return;
4819      }
4820      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
4821      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
4822          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
4823          !rt.Is(pc)) {
4824        EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4825                   (-offset & 0xff));
4826        AdvanceIT();
4827        return;
4828      }
4829      // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
4830      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4831          (operand.GetAddrMode() == PostIndex) &&
4832          ((rn.GetCode() & 0xf) != 0xf)) {
4833        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4834        uint32_t offset_ = abs(offset);
4835        EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4836                   offset_ | (sign << 9));
4837        AdvanceIT();
4838        return;
4839      }
4840      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
4841      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4842          (operand.GetAddrMode() == PreIndex) &&
4843          ((rn.GetCode() & 0xf) != 0xf)) {
4844        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4845        uint32_t offset_ = abs(offset);
4846        EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4847                   offset_ | (sign << 9));
4848        AdvanceIT();
4849        return;
4850      }
4851      // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
4852      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
4853          rn.Is(pc) && (operand.GetAddrMode() == Offset) && !rt.Is(pc)) {
4854        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4855        uint32_t offset_ = abs(offset);
4856        EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
4857        AdvanceIT();
4858        return;
4859      }
4860    } else {
4861      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
4862      if ((offset >= -4095) && (offset <= 4095) &&
4863          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
4864          ((rn.GetCode() & 0xf) != 0xf)) {
4865        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4866        uint32_t offset_ = abs(offset);
4867        EmitA32(0x05500000U | (cond.GetCondition() << 28) |
4868                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4869                (sign << 23));
4870        return;
4871      }
4872      // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
4873      if ((offset >= -4095) && (offset <= 4095) &&
4874          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever() &&
4875          ((rn.GetCode() & 0xf) != 0xf)) {
4876        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4877        uint32_t offset_ = abs(offset);
4878        EmitA32(0x04500000U | (cond.GetCondition() << 28) |
4879                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4880                (sign << 23));
4881        return;
4882      }
4883      // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
4884      if ((offset >= -4095) && (offset <= 4095) &&
4885          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever() &&
4886          ((rn.GetCode() & 0xf) != 0xf)) {
4887        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4888        uint32_t offset_ = abs(offset);
4889        EmitA32(0x05700000U | (cond.GetCondition() << 28) |
4890                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4891                (sign << 23));
4892        return;
4893      }
4894      // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
4895      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
4896          (operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
4897        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4898        uint32_t offset_ = abs(offset);
4899        EmitA32(0x055f0000U | (cond.GetCondition() << 28) |
4900                (rt.GetCode() << 12) | offset_ | (sign << 23));
4901        return;
4902      }
4903    }
4904  }
4905  if (operand.IsPlainRegister()) {
4906    Register rn = operand.GetBaseRegister();
4907    Sign sign = operand.GetSign();
4908    Register rm = operand.GetOffsetRegister();
4909    if (IsUsingT32()) {
4910      // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
4911      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
4912          sign.IsPlus() && (operand.GetAddrMode() == Offset)) {
4913        EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) |
4914                   (rm.GetCode() << 6));
4915        AdvanceIT();
4916        return;
4917      }
4918    }
4919  }
4920  if (operand.IsShiftedRegister()) {
4921    Register rn = operand.GetBaseRegister();
4922    Sign sign = operand.GetSign();
4923    Register rm = operand.GetOffsetRegister();
4924    Shift shift = operand.GetShift();
4925    uint32_t amount = operand.GetShiftAmount();
4926    if (IsUsingT32()) {
4927      // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
4928      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
4929          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
4930          !rt.Is(pc)) {
4931        EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4932                   rm.GetCode() | (amount << 4));
4933        AdvanceIT();
4934        return;
4935      }
4936    } else {
4937      // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
4938      if (operand.IsShiftValid() && (operand.GetAddrMode() == Offset) &&
4939          cond.IsNotNever()) {
4940        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4941        uint32_t shift_ = TypeEncodingValue(shift);
4942        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4943        EmitA32(0x07500000U | (cond.GetCondition() << 28) |
4944                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4945                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4946        return;
4947      }
4948      // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
4949      if (operand.IsShiftValid() && (operand.GetAddrMode() == PostIndex) &&
4950          cond.IsNotNever()) {
4951        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4952        uint32_t shift_ = TypeEncodingValue(shift);
4953        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4954        EmitA32(0x06500000U | (cond.GetCondition() << 28) |
4955                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4956                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4957        return;
4958      }
4959      // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
4960      if (operand.IsShiftValid() && (operand.GetAddrMode() == PreIndex) &&
4961          cond.IsNotNever()) {
4962        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4963        uint32_t shift_ = TypeEncodingValue(shift);
4964        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4965        EmitA32(0x07700000U | (cond.GetCondition() << 28) |
4966                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4967                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4968        return;
4969      }
4970    }
4971  }
4972  Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand);
4973}
4974
4975void Assembler::ldrb(Condition cond, Register rt, Label* label) {
4976  CheckIT(cond);
4977  Label::Offset offset =
4978      label->IsBound()
4979          ? label->GetLocation() -
4980                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
4981          : 0;
4982  if (IsUsingT32()) {
4983    // LDRB{<c>}{<q>} <Rt>, <label> ; T1
4984    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
4985         !label->IsBound()) &&
4986        !rt.Is(pc)) {
4987      static class EmitOp : public Label::LabelEmitOperator {
4988       public:
4989        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
4990        uint32_t Encode(uint32_t instr,
4991                        Label::Offset pc,
4992                        const Label* label) const {
4993          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4994          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
4995          uint32_t U = (offset >= 0) && !label->IsMinusZero();
4996          int32_t target = abs(offset) | (U << 12);
4997          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
4998        }
4999      } immop;
5000      EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12), label, immop));
5001      AdvanceIT();
5002      return;
5003    }
5004  } else {
5005    // LDRB{<c>}{<q>} <Rt>, <label> ; A1
5006    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5007         !label->IsBound()) &&
5008        cond.IsNotNever()) {
5009      static class EmitOp : public Label::LabelEmitOperator {
5010       public:
5011        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5012        uint32_t Encode(uint32_t instr,
5013                        Label::Offset pc,
5014                        const Label* label) const {
5015          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5016          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5017          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5018          int32_t target = abs(offset) | (U << 12);
5019          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5020        }
5021      } immop;
5022      EmitA32(
5023          Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5024               label,
5025               immop));
5026      return;
5027    }
5028  }
5029  Delegate(kLdrb, &Assembler::ldrb, cond, rt, label);
5030}
5031
5032void Assembler::ldrd(Condition cond,
5033                     Register rt,
5034                     Register rt2,
5035                     const MemOperand& operand) {
5036  CheckIT(cond);
5037  if (operand.IsImmediate()) {
5038    Register rn = operand.GetBaseRegister();
5039    int32_t offset = operand.GetOffsetImmediate();
5040    if (IsUsingT32()) {
5041      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
5042      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5043          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
5044        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5045        uint32_t offset_ = abs(offset) >> 2;
5046        EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5047                   (rn.GetCode() << 16) | offset_ | (sign << 23));
5048        AdvanceIT();
5049        return;
5050      }
5051      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
5052      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5053          (operand.GetAddrMode() == PostIndex) &&
5054          ((rn.GetCode() & 0xf) != 0xf)) {
5055        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5056        uint32_t offset_ = abs(offset) >> 2;
5057        EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5058                   (rn.GetCode() << 16) | offset_ | (sign << 23));
5059        AdvanceIT();
5060        return;
5061      }
5062      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
5063      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5064          (operand.GetAddrMode() == PreIndex) &&
5065          ((rn.GetCode() & 0xf) != 0xf)) {
5066        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5067        uint32_t offset_ = abs(offset) >> 2;
5068        EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5069                   (rn.GetCode() << 16) | offset_ | (sign << 23));
5070        AdvanceIT();
5071        return;
5072      }
5073      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1
5074      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5075          (operand.GetAddrMode() == Offset)) {
5076        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5077        uint32_t offset_ = abs(offset);
5078        EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5079                   offset_ | (sign << 23));
5080        AdvanceIT();
5081        return;
5082      }
5083    } else {
5084      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
5085      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5086          (offset >= -255) && (offset <= 255) &&
5087          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
5088          ((rn.GetCode() & 0xf) != 0xf) &&
5089          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5090        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5091        uint32_t offset_ = abs(offset);
5092        EmitA32(0x014000d0U | (cond.GetCondition() << 28) |
5093                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5094                ((offset_ & 0xf0) << 4) | (sign << 23));
5095        return;
5096      }
5097      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
5098      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5099          (offset >= -255) && (offset <= 255) &&
5100          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever() &&
5101          ((rn.GetCode() & 0xf) != 0xf) &&
5102          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5103        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5104        uint32_t offset_ = abs(offset);
5105        EmitA32(0x004000d0U | (cond.GetCondition() << 28) |
5106                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5107                ((offset_ & 0xf0) << 4) | (sign << 23));
5108        return;
5109      }
5110      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
5111      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5112          (offset >= -255) && (offset <= 255) &&
5113          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever() &&
5114          ((rn.GetCode() & 0xf) != 0xf) &&
5115          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5116        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5117        uint32_t offset_ = abs(offset);
5118        EmitA32(0x016000d0U | (cond.GetCondition() << 28) |
5119                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5120                ((offset_ & 0xf0) << 4) | (sign << 23));
5121        return;
5122      }
5123      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1
5124      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5125          (offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5126          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
5127          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5128        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5129        uint32_t offset_ = abs(offset);
5130        EmitA32(0x014f00d0U | (cond.GetCondition() << 28) |
5131                (rt.GetCode() << 12) | (offset_ & 0xf) |
5132                ((offset_ & 0xf0) << 4) | (sign << 23));
5133        return;
5134      }
5135    }
5136  }
5137  if (operand.IsPlainRegister()) {
5138    Register rn = operand.GetBaseRegister();
5139    Sign sign = operand.GetSign();
5140    Register rm = operand.GetOffsetRegister();
5141    if (IsUsingA32()) {
5142      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
5143      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5144          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
5145          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5146        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5147        EmitA32(0x010000d0U | (cond.GetCondition() << 28) |
5148                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5149                (sign_ << 23));
5150        return;
5151      }
5152      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
5153      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5154          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever() &&
5155          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5156        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5157        EmitA32(0x000000d0U | (cond.GetCondition() << 28) |
5158                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5159                (sign_ << 23));
5160        return;
5161      }
5162      // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
5163      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5164          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever() &&
5165          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5166        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5167        EmitA32(0x012000d0U | (cond.GetCondition() << 28) |
5168                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5169                (sign_ << 23));
5170        return;
5171      }
5172    }
5173  }
5174  Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand);
5175}
5176
5177void Assembler::ldrd(Condition cond, Register rt, Register rt2, Label* label) {
5178  CheckIT(cond);
5179  Label::Offset offset =
5180      label->IsBound()
5181          ? label->GetLocation() -
5182                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5183          : 0;
5184  if (IsUsingT32()) {
5185    // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
5186    if (((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
5187          ((offset & 0x3) == 0)) ||
5188         !label->IsBound())) {
5189      static class EmitOp : public Label::LabelEmitOperator {
5190       public:
5191        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
5192        uint32_t Encode(uint32_t instr,
5193                        Label::Offset pc,
5194                        const Label* label) const {
5195          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5196          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
5197                      ((offset & 0x3) == 0));
5198          int32_t target = offset >> 2;
5199          uint32_t U = (target >= 0) && !label->IsMinusZero();
5200          target = abs(target) | (U << 8);
5201          return instr | (target & 0xff) | ((target & 0x100) << 15);
5202        }
5203      } immop;
5204      EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8),
5205                      label,
5206                      immop));
5207      AdvanceIT();
5208      return;
5209    }
5210  } else {
5211    // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
5212    if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5213        ((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5214         !label->IsBound()) &&
5215        cond.IsNotNever() &&
5216        ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5217      static class EmitOp : public Label::LabelEmitOperator {
5218       public:
5219        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5220        uint32_t Encode(uint32_t instr,
5221                        Label::Offset pc,
5222                        const Label* label) const {
5223          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5224          VIXL_ASSERT((offset >= -255) && (offset <= 255));
5225          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5226          int32_t target = abs(offset) | (U << 8);
5227          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5228                 ((target & 0x100) << 15);
5229        }
5230      } immop;
5231      EmitA32(
5232          Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5233               label,
5234               immop));
5235      return;
5236    }
5237  }
5238  Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, label);
5239}
5240
5241void Assembler::ldrex(Condition cond, Register rt, const MemOperand& operand) {
5242  CheckIT(cond);
5243  if (operand.IsImmediate()) {
5244    Register rn = operand.GetBaseRegister();
5245    int32_t offset = operand.GetOffsetImmediate();
5246    if (IsUsingT32()) {
5247      // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1
5248      if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
5249          (operand.GetAddrMode() == Offset)) {
5250        int32_t offset_ = offset >> 2;
5251        EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5252                   (offset_ & 0xff));
5253        AdvanceIT();
5254        return;
5255      }
5256    } else {
5257      // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1
5258      if ((offset == 0) && (operand.GetAddrMode() == Offset) &&
5259          cond.IsNotNever()) {
5260        EmitA32(0x01900f9fU | (cond.GetCondition() << 28) |
5261                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5262        return;
5263      }
5264    }
5265  }
5266  Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand);
5267}
5268
5269void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) {
5270  CheckIT(cond);
5271  if (operand.IsImmediateZero()) {
5272    Register rn = operand.GetBaseRegister();
5273    if (IsUsingT32()) {
5274      // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
5275      if ((operand.GetAddrMode() == Offset) &&
5276          ((!rn.IsPC()) || AllowUnpredictable())) {
5277        EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5278        AdvanceIT();
5279        return;
5280      }
5281    } else {
5282      // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
5283      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
5284          ((!rn.IsPC()) || AllowUnpredictable())) {
5285        EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) |
5286                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5287        return;
5288      }
5289    }
5290  }
5291  Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand);
5292}
5293
5294void Assembler::ldrexd(Condition cond,
5295                       Register rt,
5296                       Register rt2,
5297                       const MemOperand& operand) {
5298  CheckIT(cond);
5299  if (operand.IsImmediateZero()) {
5300    Register rn = operand.GetBaseRegister();
5301    if (IsUsingT32()) {
5302      // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
5303      if ((operand.GetAddrMode() == Offset) &&
5304          ((!rn.IsPC()) || AllowUnpredictable())) {
5305        EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5306                   (rn.GetCode() << 16));
5307        AdvanceIT();
5308        return;
5309      }
5310    } else {
5311      // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
5312      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5313          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
5314          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
5315           AllowUnpredictable())) {
5316        EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) |
5317                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5318        return;
5319      }
5320    }
5321  }
5322  Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand);
5323}
5324
5325void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) {
5326  CheckIT(cond);
5327  if (operand.IsImmediateZero()) {
5328    Register rn = operand.GetBaseRegister();
5329    if (IsUsingT32()) {
5330      // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
5331      if ((operand.GetAddrMode() == Offset) &&
5332          ((!rn.IsPC()) || AllowUnpredictable())) {
5333        EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5334        AdvanceIT();
5335        return;
5336      }
5337    } else {
5338      // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
5339      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
5340          ((!rn.IsPC()) || AllowUnpredictable())) {
5341        EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) |
5342                (rt.GetCode() << 12) | (rn.GetCode() << 16));
5343        return;
5344      }
5345    }
5346  }
5347  Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand);
5348}
5349
5350void Assembler::ldrh(Condition cond,
5351                     EncodingSize size,
5352                     Register rt,
5353                     const MemOperand& operand) {
5354  CheckIT(cond);
5355  if (operand.IsImmediate()) {
5356    Register rn = operand.GetBaseRegister();
5357    int32_t offset = operand.GetOffsetImmediate();
5358    if (IsUsingT32()) {
5359      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5360      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
5361          (offset <= 62) && ((offset % 2) == 0) &&
5362          (operand.GetAddrMode() == Offset)) {
5363        int32_t offset_ = offset >> 1;
5364        EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) |
5365                   ((offset_ & 0x1f) << 6));
5366        AdvanceIT();
5367        return;
5368      }
5369      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
5370      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5371          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
5372          !rt.Is(pc)) {
5373        EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5374                   (offset & 0xfff));
5375        AdvanceIT();
5376        return;
5377      }
5378      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
5379      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5380          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
5381          !rt.Is(pc)) {
5382        EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5383                   (-offset & 0xff));
5384        AdvanceIT();
5385        return;
5386      }
5387      // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
5388      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5389          (operand.GetAddrMode() == PostIndex) &&
5390          ((rn.GetCode() & 0xf) != 0xf)) {
5391        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5392        uint32_t offset_ = abs(offset);
5393        EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5394                   offset_ | (sign << 9));
5395        AdvanceIT();
5396        return;
5397      }
5398      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
5399      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5400          (operand.GetAddrMode() == PreIndex) &&
5401          ((rn.GetCode() & 0xf) != 0xf)) {
5402        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5403        uint32_t offset_ = abs(offset);
5404        EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5405                   offset_ | (sign << 9));
5406        AdvanceIT();
5407        return;
5408      }
5409      // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5410      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5411          rn.Is(pc) && (operand.GetAddrMode() == Offset) && !rt.Is(pc)) {
5412        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5413        uint32_t offset_ = abs(offset);
5414        EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5415        AdvanceIT();
5416        return;
5417      }
5418    } else {
5419      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
5420      if ((offset >= -255) && (offset <= 255) &&
5421          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
5422          ((rn.GetCode() & 0xf) != 0xf)) {
5423        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5424        uint32_t offset_ = abs(offset);
5425        EmitA32(0x015000b0U | (cond.GetCondition() << 28) |
5426                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5427                ((offset_ & 0xf0) << 4) | (sign << 23));
5428        return;
5429      }
5430      // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
5431      if ((offset >= -255) && (offset <= 255) &&
5432          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever() &&
5433          ((rn.GetCode() & 0xf) != 0xf)) {
5434        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5435        uint32_t offset_ = abs(offset);
5436        EmitA32(0x005000b0U | (cond.GetCondition() << 28) |
5437                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5438                ((offset_ & 0xf0) << 4) | (sign << 23));
5439        return;
5440      }
5441      // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
5442      if ((offset >= -255) && (offset <= 255) &&
5443          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever() &&
5444          ((rn.GetCode() & 0xf) != 0xf)) {
5445        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5446        uint32_t offset_ = abs(offset);
5447        EmitA32(0x017000b0U | (cond.GetCondition() << 28) |
5448                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5449                ((offset_ & 0xf0) << 4) | (sign << 23));
5450        return;
5451      }
5452      // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5453      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5454          (operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
5455        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5456        uint32_t offset_ = abs(offset);
5457        EmitA32(0x015f00b0U | (cond.GetCondition() << 28) |
5458                (rt.GetCode() << 12) | (offset_ & 0xf) |
5459                ((offset_ & 0xf0) << 4) | (sign << 23));
5460        return;
5461      }
5462    }
5463  }
5464  if (operand.IsPlainRegister()) {
5465    Register rn = operand.GetBaseRegister();
5466    Sign sign = operand.GetSign();
5467    Register rm = operand.GetOffsetRegister();
5468    if (IsUsingT32()) {
5469      // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5470      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5471          sign.IsPlus() && (operand.GetAddrMode() == Offset)) {
5472        EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) |
5473                   (rm.GetCode() << 6));
5474        AdvanceIT();
5475        return;
5476      }
5477    } else {
5478      // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5479      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
5480        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5481        EmitA32(0x011000b0U | (cond.GetCondition() << 28) |
5482                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5483                (sign_ << 23));
5484        return;
5485      }
5486      // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5487      if ((operand.GetAddrMode() == PostIndex) && cond.IsNotNever()) {
5488        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5489        EmitA32(0x001000b0U | (cond.GetCondition() << 28) |
5490                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5491                (sign_ << 23));
5492        return;
5493      }
5494      // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5495      if ((operand.GetAddrMode() == PreIndex) && cond.IsNotNever()) {
5496        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5497        EmitA32(0x013000b0U | (cond.GetCondition() << 28) |
5498                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5499                (sign_ << 23));
5500        return;
5501      }
5502    }
5503  }
5504  if (operand.IsShiftedRegister()) {
5505    Register rn = operand.GetBaseRegister();
5506    Sign sign = operand.GetSign();
5507    Register rm = operand.GetOffsetRegister();
5508    Shift shift = operand.GetShift();
5509    uint32_t amount = operand.GetShiftAmount();
5510    if (IsUsingT32()) {
5511      // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5512      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5513          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
5514          !rt.Is(pc)) {
5515        EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5516                   rm.GetCode() | (amount << 4));
5517        AdvanceIT();
5518        return;
5519      }
5520    }
5521  }
5522  Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand);
5523}
5524
5525void Assembler::ldrh(Condition cond, Register rt, Label* label) {
5526  CheckIT(cond);
5527  Label::Offset offset =
5528      label->IsBound()
5529          ? label->GetLocation() -
5530                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5531          : 0;
5532  if (IsUsingT32()) {
5533    // LDRH{<c>}{<q>} <Rt>, <label> ; T1
5534    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5535         !label->IsBound()) &&
5536        !rt.Is(pc)) {
5537      static class EmitOp : public Label::LabelEmitOperator {
5538       public:
5539        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5540        uint32_t Encode(uint32_t instr,
5541                        Label::Offset pc,
5542                        const Label* label) const {
5543          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5544          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5545          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5546          int32_t target = abs(offset) | (U << 12);
5547          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5548        }
5549      } immop;
5550      EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12), label, immop));
5551      AdvanceIT();
5552      return;
5553    }
5554  } else {
5555    // LDRH{<c>}{<q>} <Rt>, <label> ; A1
5556    if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5557         !label->IsBound()) &&
5558        cond.IsNotNever()) {
5559      static class EmitOp : public Label::LabelEmitOperator {
5560       public:
5561        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5562        uint32_t Encode(uint32_t instr,
5563                        Label::Offset pc,
5564                        const Label* label) const {
5565          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5566          VIXL_ASSERT((offset >= -255) && (offset <= 255));
5567          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5568          int32_t target = abs(offset) | (U << 8);
5569          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5570                 ((target & 0x100) << 15);
5571        }
5572      } immop;
5573      EmitA32(
5574          Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5575               label,
5576               immop));
5577      return;
5578    }
5579  }
5580  Delegate(kLdrh, &Assembler::ldrh, cond, rt, label);
5581}
5582
5583void Assembler::ldrsb(Condition cond,
5584                      EncodingSize size,
5585                      Register rt,
5586                      const MemOperand& operand) {
5587  CheckIT(cond);
5588  if (operand.IsImmediate()) {
5589    Register rn = operand.GetBaseRegister();
5590    int32_t offset = operand.GetOffsetImmediate();
5591    if (IsUsingT32()) {
5592      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5593      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5594          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
5595          !rt.Is(pc)) {
5596        EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5597                   (offset & 0xfff));
5598        AdvanceIT();
5599        return;
5600      }
5601      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
5602      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5603          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
5604          !rt.Is(pc)) {
5605        EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5606                   (-offset & 0xff));
5607        AdvanceIT();
5608        return;
5609      }
5610      // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
5611      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5612          (operand.GetAddrMode() == PostIndex) &&
5613          ((rn.GetCode() & 0xf) != 0xf)) {
5614        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5615        uint32_t offset_ = abs(offset);
5616        EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5617                   offset_ | (sign << 9));
5618        AdvanceIT();
5619        return;
5620      }
5621      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
5622      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5623          (operand.GetAddrMode() == PreIndex) &&
5624          ((rn.GetCode() & 0xf) != 0xf)) {
5625        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5626        uint32_t offset_ = abs(offset);
5627        EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5628                   offset_ | (sign << 9));
5629        AdvanceIT();
5630        return;
5631      }
5632      // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5633      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5634          rn.Is(pc) && (operand.GetAddrMode() == Offset) && !rt.Is(pc)) {
5635        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5636        uint32_t offset_ = abs(offset);
5637        EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5638        AdvanceIT();
5639        return;
5640      }
5641    } else {
5642      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
5643      if ((offset >= -255) && (offset <= 255) &&
5644          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
5645          ((rn.GetCode() & 0xf) != 0xf)) {
5646        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5647        uint32_t offset_ = abs(offset);
5648        EmitA32(0x015000d0U | (cond.GetCondition() << 28) |
5649                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5650                ((offset_ & 0xf0) << 4) | (sign << 23));
5651        return;
5652      }
5653      // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
5654      if ((offset >= -255) && (offset <= 255) &&
5655          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever() &&
5656          ((rn.GetCode() & 0xf) != 0xf)) {
5657        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5658        uint32_t offset_ = abs(offset);
5659        EmitA32(0x005000d0U | (cond.GetCondition() << 28) |
5660                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5661                ((offset_ & 0xf0) << 4) | (sign << 23));
5662        return;
5663      }
5664      // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
5665      if ((offset >= -255) && (offset <= 255) &&
5666          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever() &&
5667          ((rn.GetCode() & 0xf) != 0xf)) {
5668        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5669        uint32_t offset_ = abs(offset);
5670        EmitA32(0x017000d0U | (cond.GetCondition() << 28) |
5671                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5672                ((offset_ & 0xf0) << 4) | (sign << 23));
5673        return;
5674      }
5675      // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5676      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5677          (operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
5678        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5679        uint32_t offset_ = abs(offset);
5680        EmitA32(0x015f00d0U | (cond.GetCondition() << 28) |
5681                (rt.GetCode() << 12) | (offset_ & 0xf) |
5682                ((offset_ & 0xf0) << 4) | (sign << 23));
5683        return;
5684      }
5685    }
5686  }
5687  if (operand.IsPlainRegister()) {
5688    Register rn = operand.GetBaseRegister();
5689    Sign sign = operand.GetSign();
5690    Register rm = operand.GetOffsetRegister();
5691    if (IsUsingT32()) {
5692      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5693      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5694          sign.IsPlus() && (operand.GetAddrMode() == Offset)) {
5695        EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) |
5696                   (rm.GetCode() << 6));
5697        AdvanceIT();
5698        return;
5699      }
5700    } else {
5701      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5702      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
5703        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5704        EmitA32(0x011000d0U | (cond.GetCondition() << 28) |
5705                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5706                (sign_ << 23));
5707        return;
5708      }
5709      // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5710      if ((operand.GetAddrMode() == PostIndex) && cond.IsNotNever()) {
5711        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5712        EmitA32(0x001000d0U | (cond.GetCondition() << 28) |
5713                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5714                (sign_ << 23));
5715        return;
5716      }
5717      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5718      if ((operand.GetAddrMode() == PreIndex) && cond.IsNotNever()) {
5719        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5720        EmitA32(0x013000d0U | (cond.GetCondition() << 28) |
5721                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5722                (sign_ << 23));
5723        return;
5724      }
5725    }
5726  }
5727  if (operand.IsShiftedRegister()) {
5728    Register rn = operand.GetBaseRegister();
5729    Sign sign = operand.GetSign();
5730    Register rm = operand.GetOffsetRegister();
5731    Shift shift = operand.GetShift();
5732    uint32_t amount = operand.GetShiftAmount();
5733    if (IsUsingT32()) {
5734      // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5735      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5736          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
5737          !rt.Is(pc)) {
5738        EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5739                   rm.GetCode() | (amount << 4));
5740        AdvanceIT();
5741        return;
5742      }
5743    }
5744  }
5745  Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand);
5746}
5747
5748void Assembler::ldrsb(Condition cond, Register rt, Label* label) {
5749  CheckIT(cond);
5750  Label::Offset offset =
5751      label->IsBound()
5752          ? label->GetLocation() -
5753                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5754          : 0;
5755  if (IsUsingT32()) {
5756    // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
5757    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5758         !label->IsBound()) &&
5759        !rt.Is(pc)) {
5760      static class EmitOp : public Label::LabelEmitOperator {
5761       public:
5762        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5763        uint32_t Encode(uint32_t instr,
5764                        Label::Offset pc,
5765                        const Label* label) const {
5766          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5767          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5768          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5769          int32_t target = abs(offset) | (U << 12);
5770          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5771        }
5772      } immop;
5773      EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12), label, immop));
5774      AdvanceIT();
5775      return;
5776    }
5777  } else {
5778    // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
5779    if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5780         !label->IsBound()) &&
5781        cond.IsNotNever()) {
5782      static class EmitOp : public Label::LabelEmitOperator {
5783       public:
5784        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5785        uint32_t Encode(uint32_t instr,
5786                        Label::Offset pc,
5787                        const Label* label) const {
5788          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5789          VIXL_ASSERT((offset >= -255) && (offset <= 255));
5790          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5791          int32_t target = abs(offset) | (U << 8);
5792          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5793                 ((target & 0x100) << 15);
5794        }
5795      } immop;
5796      EmitA32(
5797          Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5798               label,
5799               immop));
5800      return;
5801    }
5802  }
5803  Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, label);
5804}
5805
5806void Assembler::ldrsh(Condition cond,
5807                      EncodingSize size,
5808                      Register rt,
5809                      const MemOperand& operand) {
5810  CheckIT(cond);
5811  if (operand.IsImmediate()) {
5812    Register rn = operand.GetBaseRegister();
5813    int32_t offset = operand.GetOffsetImmediate();
5814    if (IsUsingT32()) {
5815      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5816      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5817          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
5818          !rt.Is(pc)) {
5819        EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5820                   (offset & 0xfff));
5821        AdvanceIT();
5822        return;
5823      }
5824      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
5825      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5826          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
5827          !rt.Is(pc)) {
5828        EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5829                   (-offset & 0xff));
5830        AdvanceIT();
5831        return;
5832      }
5833      // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
5834      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5835          (operand.GetAddrMode() == PostIndex) &&
5836          ((rn.GetCode() & 0xf) != 0xf)) {
5837        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5838        uint32_t offset_ = abs(offset);
5839        EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5840                   offset_ | (sign << 9));
5841        AdvanceIT();
5842        return;
5843      }
5844      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
5845      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5846          (operand.GetAddrMode() == PreIndex) &&
5847          ((rn.GetCode() & 0xf) != 0xf)) {
5848        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5849        uint32_t offset_ = abs(offset);
5850        EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5851                   offset_ | (sign << 9));
5852        AdvanceIT();
5853        return;
5854      }
5855      // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5856      if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5857          rn.Is(pc) && (operand.GetAddrMode() == Offset) && !rt.Is(pc)) {
5858        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5859        uint32_t offset_ = abs(offset);
5860        EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5861        AdvanceIT();
5862        return;
5863      }
5864    } else {
5865      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
5866      if ((offset >= -255) && (offset <= 255) &&
5867          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
5868          ((rn.GetCode() & 0xf) != 0xf)) {
5869        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5870        uint32_t offset_ = abs(offset);
5871        EmitA32(0x015000f0U | (cond.GetCondition() << 28) |
5872                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5873                ((offset_ & 0xf0) << 4) | (sign << 23));
5874        return;
5875      }
5876      // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
5877      if ((offset >= -255) && (offset <= 255) &&
5878          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever() &&
5879          ((rn.GetCode() & 0xf) != 0xf)) {
5880        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5881        uint32_t offset_ = abs(offset);
5882        EmitA32(0x005000f0U | (cond.GetCondition() << 28) |
5883                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5884                ((offset_ & 0xf0) << 4) | (sign << 23));
5885        return;
5886      }
5887      // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
5888      if ((offset >= -255) && (offset <= 255) &&
5889          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever() &&
5890          ((rn.GetCode() & 0xf) != 0xf)) {
5891        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5892        uint32_t offset_ = abs(offset);
5893        EmitA32(0x017000f0U | (cond.GetCondition() << 28) |
5894                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5895                ((offset_ & 0xf0) << 4) | (sign << 23));
5896        return;
5897      }
5898      // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5899      if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5900          (operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
5901        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5902        uint32_t offset_ = abs(offset);
5903        EmitA32(0x015f00f0U | (cond.GetCondition() << 28) |
5904                (rt.GetCode() << 12) | (offset_ & 0xf) |
5905                ((offset_ & 0xf0) << 4) | (sign << 23));
5906        return;
5907      }
5908    }
5909  }
5910  if (operand.IsPlainRegister()) {
5911    Register rn = operand.GetBaseRegister();
5912    Sign sign = operand.GetSign();
5913    Register rm = operand.GetOffsetRegister();
5914    if (IsUsingT32()) {
5915      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5916      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5917          sign.IsPlus() && (operand.GetAddrMode() == Offset)) {
5918        EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) |
5919                   (rm.GetCode() << 6));
5920        AdvanceIT();
5921        return;
5922      }
5923    } else {
5924      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5925      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
5926        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5927        EmitA32(0x011000f0U | (cond.GetCondition() << 28) |
5928                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5929                (sign_ << 23));
5930        return;
5931      }
5932      // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5933      if ((operand.GetAddrMode() == PostIndex) && cond.IsNotNever()) {
5934        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5935        EmitA32(0x001000f0U | (cond.GetCondition() << 28) |
5936                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5937                (sign_ << 23));
5938        return;
5939      }
5940      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5941      if ((operand.GetAddrMode() == PreIndex) && cond.IsNotNever()) {
5942        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5943        EmitA32(0x013000f0U | (cond.GetCondition() << 28) |
5944                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5945                (sign_ << 23));
5946        return;
5947      }
5948    }
5949  }
5950  if (operand.IsShiftedRegister()) {
5951    Register rn = operand.GetBaseRegister();
5952    Sign sign = operand.GetSign();
5953    Register rm = operand.GetOffsetRegister();
5954    Shift shift = operand.GetShift();
5955    uint32_t amount = operand.GetShiftAmount();
5956    if (IsUsingT32()) {
5957      // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5958      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5959          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf) &&
5960          !rt.Is(pc)) {
5961        EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5962                   rm.GetCode() | (amount << 4));
5963        AdvanceIT();
5964        return;
5965      }
5966    }
5967  }
5968  Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand);
5969}
5970
5971void Assembler::ldrsh(Condition cond, Register rt, Label* label) {
5972  CheckIT(cond);
5973  Label::Offset offset =
5974      label->IsBound()
5975          ? label->GetLocation() -
5976                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5977          : 0;
5978  if (IsUsingT32()) {
5979    // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
5980    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5981         !label->IsBound()) &&
5982        !rt.Is(pc)) {
5983      static class EmitOp : public Label::LabelEmitOperator {
5984       public:
5985        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5986        uint32_t Encode(uint32_t instr,
5987                        Label::Offset pc,
5988                        const Label* label) const {
5989          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5990          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5991          uint32_t U = (offset >= 0) && !label->IsMinusZero();
5992          int32_t target = abs(offset) | (U << 12);
5993          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5994        }
5995      } immop;
5996      EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12), label, immop));
5997      AdvanceIT();
5998      return;
5999    }
6000  } else {
6001    // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
6002    if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
6003         !label->IsBound()) &&
6004        cond.IsNotNever()) {
6005      static class EmitOp : public Label::LabelEmitOperator {
6006       public:
6007        EmitOp() : Label::LabelEmitOperator(-255, 255) {}
6008        uint32_t Encode(uint32_t instr,
6009                        Label::Offset pc,
6010                        const Label* label) const {
6011          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
6012          VIXL_ASSERT((offset >= -255) && (offset <= 255));
6013          uint32_t U = (offset >= 0) && !label->IsMinusZero();
6014          int32_t target = abs(offset) | (U << 8);
6015          return instr | (target & 0xf) | ((target & 0xf0) << 4) |
6016                 ((target & 0x100) << 15);
6017        }
6018      } immop;
6019      EmitA32(
6020          Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
6021               label,
6022               immop));
6023      return;
6024    }
6025  }
6026  Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, label);
6027}
6028
6029void Assembler::lsl(Condition cond,
6030                    EncodingSize size,
6031                    Register rd,
6032                    Register rm,
6033                    const Operand& operand) {
6034  CheckIT(cond);
6035  if (operand.IsImmediate()) {
6036    uint32_t imm = operand.GetImmediate();
6037    if (IsUsingT32()) {
6038      // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6039      if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6040          (imm >= 1) && (imm <= 31)) {
6041        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6042        AdvanceIT();
6043        return;
6044      }
6045      // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6046      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
6047        EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6048                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6049        AdvanceIT();
6050        return;
6051      }
6052    } else {
6053      // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6054      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6055        EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
6056                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6057        return;
6058      }
6059    }
6060  }
6061  if (operand.IsPlainRegister()) {
6062    Register rs = operand.GetBaseRegister();
6063    if (IsUsingT32()) {
6064      // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6065      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6066          rs.IsLow()) {
6067        EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6068        AdvanceIT();
6069        return;
6070      }
6071      // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6072      if (!size.IsNarrow()) {
6073        EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6074                   rs.GetCode());
6075        AdvanceIT();
6076        return;
6077      }
6078    } else {
6079      // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6080      if (cond.IsNotNever()) {
6081        EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
6082                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6083        return;
6084      }
6085    }
6086  }
6087  Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand);
6088}
6089
6090void Assembler::lsls(Condition cond,
6091                     EncodingSize size,
6092                     Register rd,
6093                     Register rm,
6094                     const Operand& operand) {
6095  CheckIT(cond);
6096  if (operand.IsImmediate()) {
6097    uint32_t imm = operand.GetImmediate();
6098    if (IsUsingT32()) {
6099      // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6100      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6101          (imm >= 1) && (imm <= 31)) {
6102        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6103        AdvanceIT();
6104        return;
6105      }
6106      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6107      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
6108        EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6109                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6110        AdvanceIT();
6111        return;
6112      }
6113    } else {
6114      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6115      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6116        EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
6117                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6118        return;
6119      }
6120    }
6121  }
6122  if (operand.IsPlainRegister()) {
6123    Register rs = operand.GetBaseRegister();
6124    if (IsUsingT32()) {
6125      // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6126      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6127          rs.IsLow()) {
6128        EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6129        AdvanceIT();
6130        return;
6131      }
6132      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6133      if (!size.IsNarrow()) {
6134        EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6135                   rs.GetCode());
6136        AdvanceIT();
6137        return;
6138      }
6139    } else {
6140      // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6141      if (cond.IsNotNever()) {
6142        EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
6143                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6144        return;
6145      }
6146    }
6147  }
6148  Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand);
6149}
6150
6151void Assembler::lsr(Condition cond,
6152                    EncodingSize size,
6153                    Register rd,
6154                    Register rm,
6155                    const Operand& operand) {
6156  CheckIT(cond);
6157  if (operand.IsImmediate()) {
6158    uint32_t imm = operand.GetImmediate();
6159    if (IsUsingT32()) {
6160      // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6161      if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6162          (imm >= 1) && (imm <= 32)) {
6163        uint32_t amount_ = imm % 32;
6164        EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6165                   (amount_ << 6));
6166        AdvanceIT();
6167        return;
6168      }
6169      // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6170      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
6171        uint32_t amount_ = imm % 32;
6172        EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6173                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6174        AdvanceIT();
6175        return;
6176      }
6177    } else {
6178      // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6179      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6180        uint32_t amount_ = imm % 32;
6181        EmitA32(0x01a00020U | (cond.GetCondition() << 28) |
6182                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6183        return;
6184      }
6185    }
6186  }
6187  if (operand.IsPlainRegister()) {
6188    Register rs = operand.GetBaseRegister();
6189    if (IsUsingT32()) {
6190      // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6191      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6192          rs.IsLow()) {
6193        EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6194        AdvanceIT();
6195        return;
6196      }
6197      // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6198      if (!size.IsNarrow()) {
6199        EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6200                   rs.GetCode());
6201        AdvanceIT();
6202        return;
6203      }
6204    } else {
6205      // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6206      if (cond.IsNotNever()) {
6207        EmitA32(0x01a00030U | (cond.GetCondition() << 28) |
6208                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6209        return;
6210      }
6211    }
6212  }
6213  Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand);
6214}
6215
6216void Assembler::lsrs(Condition cond,
6217                     EncodingSize size,
6218                     Register rd,
6219                     Register rm,
6220                     const Operand& operand) {
6221  CheckIT(cond);
6222  if (operand.IsImmediate()) {
6223    uint32_t imm = operand.GetImmediate();
6224    if (IsUsingT32()) {
6225      // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6226      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6227          (imm >= 1) && (imm <= 32)) {
6228        uint32_t amount_ = imm % 32;
6229        EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6230                   (amount_ << 6));
6231        AdvanceIT();
6232        return;
6233      }
6234      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6235      if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
6236        uint32_t amount_ = imm % 32;
6237        EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6238                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6239        AdvanceIT();
6240        return;
6241      }
6242    } else {
6243      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6244      if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6245        uint32_t amount_ = imm % 32;
6246        EmitA32(0x01b00020U | (cond.GetCondition() << 28) |
6247                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6248        return;
6249      }
6250    }
6251  }
6252  if (operand.IsPlainRegister()) {
6253    Register rs = operand.GetBaseRegister();
6254    if (IsUsingT32()) {
6255      // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6256      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6257          rs.IsLow()) {
6258        EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6259        AdvanceIT();
6260        return;
6261      }
6262      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6263      if (!size.IsNarrow()) {
6264        EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6265                   rs.GetCode());
6266        AdvanceIT();
6267        return;
6268      }
6269    } else {
6270      // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6271      if (cond.IsNotNever()) {
6272        EmitA32(0x01b00030U | (cond.GetCondition() << 28) |
6273                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6274        return;
6275      }
6276    }
6277  }
6278  Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand);
6279}
6280
6281void Assembler::mla(
6282    Condition cond, Register rd, Register rn, Register rm, Register ra) {
6283  CheckIT(cond);
6284  if (IsUsingT32()) {
6285    // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
6286    if (!ra.Is(pc)) {
6287      EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6288                 rm.GetCode() | (ra.GetCode() << 12));
6289      AdvanceIT();
6290      return;
6291    }
6292  } else {
6293    // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6294    if (cond.IsNotNever()) {
6295      EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6296              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6297      return;
6298    }
6299  }
6300  Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra);
6301}
6302
6303void Assembler::mlas(
6304    Condition cond, Register rd, Register rn, Register rm, Register ra) {
6305  CheckIT(cond);
6306  if (IsUsingA32()) {
6307    // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6308    if (cond.IsNotNever()) {
6309      EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6310              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6311      return;
6312    }
6313  }
6314  Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra);
6315}
6316
6317void Assembler::mls(
6318    Condition cond, Register rd, Register rn, Register rm, Register ra) {
6319  CheckIT(cond);
6320  if (IsUsingT32()) {
6321    // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
6322    EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6323               rm.GetCode() | (ra.GetCode() << 12));
6324    AdvanceIT();
6325    return;
6326  } else {
6327    // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6328    if (cond.IsNotNever()) {
6329      EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6330              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6331      return;
6332    }
6333  }
6334  Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra);
6335}
6336
6337void Assembler::mov(Condition cond,
6338                    EncodingSize size,
6339                    Register rd,
6340                    const Operand& operand) {
6341  CheckIT(cond);
6342  if (operand.IsImmediateShiftedRegister()) {
6343    Register rm = operand.GetBaseRegister();
6344    if (operand.IsPlainRegister()) {
6345      if (IsUsingT32()) {
6346        // MOV{<c>}{<q>} <Rd>, <Rm> ; T1
6347        if (!size.IsWide()) {
6348          EmitT32_16(0x4600 | (rd.GetCode() & 0x7) |
6349                     ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
6350          AdvanceIT();
6351          return;
6352        }
6353      }
6354    }
6355    Shift shift = operand.GetShift();
6356    uint32_t amount = operand.GetShiftAmount();
6357    if (IsUsingT32()) {
6358      // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6359      if (InITBlock() && !size.IsWide() && rd.IsLow() &&
6360          shift.IsValidAmount(amount) && rm.IsLow() &&
6361          (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) {
6362        uint32_t amount_ = amount % 32;
6363        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
6364                   (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
6365        AdvanceIT();
6366        return;
6367      }
6368      // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
6369      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6370        uint32_t amount_ = amount % 32;
6371        EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6372                   (operand.GetTypeEncodingValue() << 4) |
6373                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6374        AdvanceIT();
6375        return;
6376      }
6377    } else {
6378      // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6379      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6380        uint32_t amount_ = amount % 32;
6381        EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
6382                (rd.GetCode() << 12) | rm.GetCode() |
6383                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6384        return;
6385      }
6386    }
6387  }
6388  if (operand.IsRegisterShiftedRegister()) {
6389    Register rm = operand.GetBaseRegister();
6390    Shift shift = operand.GetShift();
6391    if (IsUsingT32()) {
6392      // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
6393      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6394          shift.IsASR() && operand.GetShiftRegister().IsLow()) {
6395        EmitT32_16(0x4100 | rd.GetCode() |
6396                   (operand.GetShiftRegister().GetCode() << 3));
6397        AdvanceIT();
6398        return;
6399      }
6400      // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
6401      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6402          shift.IsLSL() && operand.GetShiftRegister().IsLow()) {
6403        EmitT32_16(0x4080 | rd.GetCode() |
6404                   (operand.GetShiftRegister().GetCode() << 3));
6405        AdvanceIT();
6406        return;
6407      }
6408      // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
6409      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6410          shift.IsLSR() && operand.GetShiftRegister().IsLow()) {
6411        EmitT32_16(0x40c0 | rd.GetCode() |
6412                   (operand.GetShiftRegister().GetCode() << 3));
6413        AdvanceIT();
6414        return;
6415      }
6416      // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
6417      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6418          shift.IsROR() && operand.GetShiftRegister().IsLow()) {
6419        EmitT32_16(0x41c0 | rd.GetCode() |
6420                   (operand.GetShiftRegister().GetCode() << 3));
6421        AdvanceIT();
6422        return;
6423      }
6424      // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
6425      if (!size.IsNarrow()) {
6426        EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6427                   (shift.GetType() << 21) |
6428                   operand.GetShiftRegister().GetCode());
6429        AdvanceIT();
6430        return;
6431      }
6432    } else {
6433      // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6434      if (cond.IsNotNever()) {
6435        EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
6436                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6437                (operand.GetShiftRegister().GetCode() << 8));
6438        return;
6439      }
6440    }
6441  }
6442  if (operand.IsImmediate()) {
6443    uint32_t imm = operand.GetImmediate();
6444    if (IsUsingT32()) {
6445      ImmediateT32 immediate_t32(imm);
6446      // MOV<c>{<q>} <Rd>, #<imm8> ; T1
6447      if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
6448        EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
6449        AdvanceIT();
6450        return;
6451      }
6452      // MOV{<c>}{<q>} <Rd>, #<const> ; T2
6453      if (!size.IsNarrow() && immediate_t32.IsValid()) {
6454        EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) |
6455                   (immediate_t32.GetEncodingValue() & 0xff) |
6456                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6457                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6458        AdvanceIT();
6459        return;
6460      }
6461      // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3
6462      if (!size.IsNarrow() && (imm <= 65535)) {
6463        EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
6464                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6465                   ((imm & 0xf000) << 4));
6466        AdvanceIT();
6467        return;
6468      }
6469    } else {
6470      ImmediateA32 immediate_a32(imm);
6471      // MOV{<c>}{<q>} <Rd>, #<const> ; A1
6472      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6473        EmitA32(0x03a00000U | (cond.GetCondition() << 28) |
6474                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6475        return;
6476      }
6477      // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2
6478      if ((imm <= 65535) && cond.IsNotNever()) {
6479        EmitA32(0x03000000U | (cond.GetCondition() << 28) |
6480                (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6481        return;
6482      }
6483    }
6484  }
6485  Delegate(kMov, &Assembler::mov, cond, size, rd, operand);
6486}
6487
6488void Assembler::movs(Condition cond,
6489                     EncodingSize size,
6490                     Register rd,
6491                     const Operand& operand) {
6492  CheckIT(cond);
6493  if (operand.IsImmediateShiftedRegister()) {
6494    Register rm = operand.GetBaseRegister();
6495    Shift shift = operand.GetShift();
6496    uint32_t amount = operand.GetShiftAmount();
6497    if (IsUsingT32()) {
6498      // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6499      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() &&
6500          shift.IsValidAmount(amount) && rm.IsLow() &&
6501          (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) {
6502        uint32_t amount_ = amount % 32;
6503        EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
6504                   (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
6505        AdvanceIT();
6506        return;
6507      }
6508      // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
6509      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6510        uint32_t amount_ = amount % 32;
6511        EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6512                   (operand.GetTypeEncodingValue() << 4) |
6513                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6514        AdvanceIT();
6515        return;
6516      }
6517    } else {
6518      // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6519      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6520        uint32_t amount_ = amount % 32;
6521        EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
6522                (rd.GetCode() << 12) | rm.GetCode() |
6523                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6524        return;
6525      }
6526    }
6527  }
6528  if (operand.IsRegisterShiftedRegister()) {
6529    Register rm = operand.GetBaseRegister();
6530    Shift shift = operand.GetShift();
6531    if (IsUsingT32()) {
6532      // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
6533      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6534          shift.IsASR() && operand.GetShiftRegister().IsLow()) {
6535        EmitT32_16(0x4100 | rd.GetCode() |
6536                   (operand.GetShiftRegister().GetCode() << 3));
6537        AdvanceIT();
6538        return;
6539      }
6540      // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
6541      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6542          shift.IsLSL() && operand.GetShiftRegister().IsLow()) {
6543        EmitT32_16(0x4080 | rd.GetCode() |
6544                   (operand.GetShiftRegister().GetCode() << 3));
6545        AdvanceIT();
6546        return;
6547      }
6548      // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
6549      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6550          shift.IsLSR() && operand.GetShiftRegister().IsLow()) {
6551        EmitT32_16(0x40c0 | rd.GetCode() |
6552                   (operand.GetShiftRegister().GetCode() << 3));
6553        AdvanceIT();
6554        return;
6555      }
6556      // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
6557      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6558          shift.IsROR() && operand.GetShiftRegister().IsLow()) {
6559        EmitT32_16(0x41c0 | rd.GetCode() |
6560                   (operand.GetShiftRegister().GetCode() << 3));
6561        AdvanceIT();
6562        return;
6563      }
6564      // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
6565      if (!size.IsNarrow()) {
6566        EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6567                   (shift.GetType() << 21) |
6568                   operand.GetShiftRegister().GetCode());
6569        AdvanceIT();
6570        return;
6571      }
6572    } else {
6573      // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6574      if (cond.IsNotNever()) {
6575        EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
6576                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6577                (operand.GetShiftRegister().GetCode() << 8));
6578        return;
6579      }
6580    }
6581  }
6582  if (operand.IsImmediate()) {
6583    uint32_t imm = operand.GetImmediate();
6584    if (IsUsingT32()) {
6585      ImmediateT32 immediate_t32(imm);
6586      // MOVS{<q>} <Rd>, #<imm8> ; T1
6587      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
6588        EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
6589        AdvanceIT();
6590        return;
6591      }
6592      // MOVS{<c>}{<q>} <Rd>, #<const> ; T2
6593      if (!size.IsNarrow() && immediate_t32.IsValid()) {
6594        EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) |
6595                   (immediate_t32.GetEncodingValue() & 0xff) |
6596                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6597                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6598        AdvanceIT();
6599        return;
6600      }
6601    } else {
6602      ImmediateA32 immediate_a32(imm);
6603      // MOVS{<c>}{<q>} <Rd>, #<const> ; A1
6604      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6605        EmitA32(0x03b00000U | (cond.GetCondition() << 28) |
6606                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6607        return;
6608      }
6609    }
6610  }
6611  Delegate(kMovs, &Assembler::movs, cond, size, rd, operand);
6612}
6613
6614void Assembler::movt(Condition cond, Register rd, const Operand& operand) {
6615  CheckIT(cond);
6616  if (operand.IsImmediate()) {
6617    uint32_t imm = operand.GetImmediate();
6618    if (IsUsingT32()) {
6619      // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1
6620      if ((imm <= 65535)) {
6621        EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) |
6622                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6623                   ((imm & 0xf000) << 4));
6624        AdvanceIT();
6625        return;
6626      }
6627    } else {
6628      // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1
6629      if ((imm <= 65535) && cond.IsNotNever()) {
6630        EmitA32(0x03400000U | (cond.GetCondition() << 28) |
6631                (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6632        return;
6633      }
6634    }
6635  }
6636  Delegate(kMovt, &Assembler::movt, cond, rd, operand);
6637}
6638
6639void Assembler::movw(Condition cond, Register rd, const Operand& operand) {
6640  CheckIT(cond);
6641  if (operand.IsImmediate()) {
6642    uint32_t imm = operand.GetImmediate();
6643    if (IsUsingT32()) {
6644      // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3
6645      if ((imm <= 65535)) {
6646        EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
6647                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6648                   ((imm & 0xf000) << 4));
6649        AdvanceIT();
6650        return;
6651      }
6652    } else {
6653      // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2
6654      if ((imm <= 65535) && cond.IsNotNever()) {
6655        EmitA32(0x03000000U | (cond.GetCondition() << 28) |
6656                (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6657        return;
6658      }
6659    }
6660  }
6661  Delegate(kMovw, &Assembler::movw, cond, rd, operand);
6662}
6663
6664void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) {
6665  CheckIT(cond);
6666  if (IsUsingT32()) {
6667    // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1
6668    EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20));
6669    AdvanceIT();
6670    return;
6671  } else {
6672    // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1
6673    if (cond.IsNotNever()) {
6674      EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
6675              (spec_reg.GetReg() << 22));
6676      return;
6677    }
6678  }
6679  Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg);
6680}
6681
6682void Assembler::msr(Condition cond,
6683                    MaskedSpecialRegister spec_reg,
6684                    const Operand& operand) {
6685  CheckIT(cond);
6686  if (operand.IsImmediate()) {
6687    uint32_t imm = operand.GetImmediate();
6688    if (IsUsingA32()) {
6689      ImmediateA32 immediate_a32(imm);
6690      // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1
6691      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6692        EmitA32(0x0320f000U | (cond.GetCondition() << 28) |
6693                ((spec_reg.GetReg() & 0xf) << 16) |
6694                ((spec_reg.GetReg() & 0x10) << 18) |
6695                immediate_a32.GetEncodingValue());
6696        return;
6697      }
6698    }
6699  }
6700  if (operand.IsPlainRegister()) {
6701    Register rn = operand.GetBaseRegister();
6702    if (IsUsingT32()) {
6703      // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1
6704      EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) |
6705                 ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16));
6706      AdvanceIT();
6707      return;
6708    } else {
6709      // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1
6710      if (cond.IsNotNever()) {
6711        EmitA32(0x0120f000U | (cond.GetCondition() << 28) |
6712                ((spec_reg.GetReg() & 0xf) << 16) |
6713                ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode());
6714        return;
6715      }
6716    }
6717  }
6718  Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand);
6719}
6720
6721void Assembler::mul(
6722    Condition cond, EncodingSize size, Register rd, Register rn, Register rm) {
6723  CheckIT(cond);
6724  if (IsUsingT32()) {
6725    // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
6726    if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() &&
6727        rm.IsLow()) {
6728      EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
6729      AdvanceIT();
6730      return;
6731    }
6732    // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2
6733    if (!size.IsNarrow()) {
6734      EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6735                 rm.GetCode());
6736      AdvanceIT();
6737      return;
6738    }
6739  } else {
6740    // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
6741    if (cond.IsNotNever()) {
6742      EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6743              rn.GetCode() | (rm.GetCode() << 8));
6744      return;
6745    }
6746  }
6747  Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm);
6748}
6749
6750void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) {
6751  CheckIT(cond);
6752  if (IsUsingT32()) {
6753    // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
6754    if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) {
6755      EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
6756      AdvanceIT();
6757      return;
6758    }
6759  } else {
6760    // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
6761    if (cond.IsNotNever()) {
6762      EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6763              rn.GetCode() | (rm.GetCode() << 8));
6764      return;
6765    }
6766  }
6767  Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm);
6768}
6769
6770void Assembler::mvn(Condition cond,
6771                    EncodingSize size,
6772                    Register rd,
6773                    const Operand& operand) {
6774  CheckIT(cond);
6775  if (operand.IsImmediate()) {
6776    uint32_t imm = operand.GetImmediate();
6777    if (IsUsingT32()) {
6778      ImmediateT32 immediate_t32(imm);
6779      // MVN{<c>}{<q>} <Rd>, #<const> ; T1
6780      if (!size.IsNarrow() && immediate_t32.IsValid()) {
6781        EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) |
6782                   (immediate_t32.GetEncodingValue() & 0xff) |
6783                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6784                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6785        AdvanceIT();
6786        return;
6787      }
6788    } else {
6789      ImmediateA32 immediate_a32(imm);
6790      // MVN{<c>}{<q>} <Rd>, #<const> ; A1
6791      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6792        EmitA32(0x03e00000U | (cond.GetCondition() << 28) |
6793                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6794        return;
6795      }
6796    }
6797  }
6798  if (operand.IsImmediateShiftedRegister()) {
6799    Register rm = operand.GetBaseRegister();
6800    if (operand.IsPlainRegister()) {
6801      if (IsUsingT32()) {
6802        // MVN<c>{<q>} <Rd>, <Rm> ; T1
6803        if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
6804          EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
6805          AdvanceIT();
6806          return;
6807        }
6808      }
6809    }
6810    Shift shift = operand.GetShift();
6811    uint32_t amount = operand.GetShiftAmount();
6812    if (IsUsingT32()) {
6813      // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6814      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6815        uint32_t amount_ = amount % 32;
6816        EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6817                   (operand.GetTypeEncodingValue() << 4) |
6818                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6819        AdvanceIT();
6820        return;
6821      }
6822    } else {
6823      // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6824      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6825        uint32_t amount_ = amount % 32;
6826        EmitA32(0x01e00000U | (cond.GetCondition() << 28) |
6827                (rd.GetCode() << 12) | rm.GetCode() |
6828                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6829        return;
6830      }
6831    }
6832  }
6833  if (operand.IsRegisterShiftedRegister()) {
6834    Register rm = operand.GetBaseRegister();
6835    Shift shift = operand.GetShift();
6836    if (IsUsingA32()) {
6837      // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6838      if (cond.IsNotNever()) {
6839        EmitA32(0x01e00010U | (cond.GetCondition() << 28) |
6840                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6841                (operand.GetShiftRegister().GetCode() << 8));
6842        return;
6843      }
6844    }
6845  }
6846  Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand);
6847}
6848
6849void Assembler::mvns(Condition cond,
6850                     EncodingSize size,
6851                     Register rd,
6852                     const Operand& operand) {
6853  CheckIT(cond);
6854  if (operand.IsImmediate()) {
6855    uint32_t imm = operand.GetImmediate();
6856    if (IsUsingT32()) {
6857      ImmediateT32 immediate_t32(imm);
6858      // MVNS{<c>}{<q>} <Rd>, #<const> ; T1
6859      if (!size.IsNarrow() && immediate_t32.IsValid()) {
6860        EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) |
6861                   (immediate_t32.GetEncodingValue() & 0xff) |
6862                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6863                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6864        AdvanceIT();
6865        return;
6866      }
6867    } else {
6868      ImmediateA32 immediate_a32(imm);
6869      // MVNS{<c>}{<q>} <Rd>, #<const> ; A1
6870      if (immediate_a32.IsValid() && cond.IsNotNever()) {
6871        EmitA32(0x03f00000U | (cond.GetCondition() << 28) |
6872                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6873        return;
6874      }
6875    }
6876  }
6877  if (operand.IsImmediateShiftedRegister()) {
6878    Register rm = operand.GetBaseRegister();
6879    if (operand.IsPlainRegister()) {
6880      if (IsUsingT32()) {
6881        // MVNS{<q>} <Rd>, <Rm> ; T1
6882        if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
6883          EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
6884          AdvanceIT();
6885          return;
6886        }
6887      }
6888    }
6889    Shift shift = operand.GetShift();
6890    uint32_t amount = operand.GetShiftAmount();
6891    if (IsUsingT32()) {
6892      // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6893      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6894        uint32_t amount_ = amount % 32;
6895        EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6896                   (operand.GetTypeEncodingValue() << 4) |
6897                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6898        AdvanceIT();
6899        return;
6900      }
6901    } else {
6902      // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6903      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6904        uint32_t amount_ = amount % 32;
6905        EmitA32(0x01f00000U | (cond.GetCondition() << 28) |
6906                (rd.GetCode() << 12) | rm.GetCode() |
6907                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6908        return;
6909      }
6910    }
6911  }
6912  if (operand.IsRegisterShiftedRegister()) {
6913    Register rm = operand.GetBaseRegister();
6914    Shift shift = operand.GetShift();
6915    if (IsUsingA32()) {
6916      // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6917      if (cond.IsNotNever()) {
6918        EmitA32(0x01f00010U | (cond.GetCondition() << 28) |
6919                (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6920                (operand.GetShiftRegister().GetCode() << 8));
6921        return;
6922      }
6923    }
6924  }
6925  Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand);
6926}
6927
6928void Assembler::nop(Condition cond, EncodingSize size) {
6929  CheckIT(cond);
6930  if (IsUsingT32()) {
6931    // NOP{<c>}{<q>} ; T1
6932    if (!size.IsWide()) {
6933      EmitT32_16(0xbf00);
6934      AdvanceIT();
6935      return;
6936    }
6937    // NOP{<c>}.W ; T2
6938    if (!size.IsNarrow()) {
6939      EmitT32_32(0xf3af8000U);
6940      AdvanceIT();
6941      return;
6942    }
6943  } else {
6944    // NOP{<c>}{<q>} ; A1
6945    if (cond.IsNotNever()) {
6946      EmitA32(0x0320f000U | (cond.GetCondition() << 28));
6947      return;
6948    }
6949  }
6950  Delegate(kNop, &Assembler::nop, cond, size);
6951}
6952
6953void Assembler::orn(Condition cond,
6954                    Register rd,
6955                    Register rn,
6956                    const Operand& operand) {
6957  CheckIT(cond);
6958  if (operand.IsImmediate()) {
6959    uint32_t imm = operand.GetImmediate();
6960    if (IsUsingT32()) {
6961      ImmediateT32 immediate_t32(imm);
6962      // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
6963      if (immediate_t32.IsValid() && !rn.Is(pc)) {
6964        EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6965                   (immediate_t32.GetEncodingValue() & 0xff) |
6966                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6967                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6968        AdvanceIT();
6969        return;
6970      }
6971    }
6972  }
6973  if (operand.IsImmediateShiftedRegister()) {
6974    Register rm = operand.GetBaseRegister();
6975    Shift shift = operand.GetShift();
6976    uint32_t amount = operand.GetShiftAmount();
6977    if (IsUsingT32()) {
6978      // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
6979      if (shift.IsValidAmount(amount) && !rn.Is(pc)) {
6980        uint32_t amount_ = amount % 32;
6981        EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6982                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
6983                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6984        AdvanceIT();
6985        return;
6986      }
6987    }
6988  }
6989  Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand);
6990}
6991
6992void Assembler::orns(Condition cond,
6993                     Register rd,
6994                     Register rn,
6995                     const Operand& operand) {
6996  CheckIT(cond);
6997  if (operand.IsImmediate()) {
6998    uint32_t imm = operand.GetImmediate();
6999    if (IsUsingT32()) {
7000      ImmediateT32 immediate_t32(imm);
7001      // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7002      if (immediate_t32.IsValid() && !rn.Is(pc)) {
7003        EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7004                   (immediate_t32.GetEncodingValue() & 0xff) |
7005                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7006                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7007        AdvanceIT();
7008        return;
7009      }
7010    }
7011  }
7012  if (operand.IsImmediateShiftedRegister()) {
7013    Register rm = operand.GetBaseRegister();
7014    Shift shift = operand.GetShift();
7015    uint32_t amount = operand.GetShiftAmount();
7016    if (IsUsingT32()) {
7017      // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
7018      if (shift.IsValidAmount(amount) && !rn.Is(pc)) {
7019        uint32_t amount_ = amount % 32;
7020        EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7021                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7022                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7023        AdvanceIT();
7024        return;
7025      }
7026    }
7027  }
7028  Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand);
7029}
7030
7031void Assembler::orr(Condition cond,
7032                    EncodingSize size,
7033                    Register rd,
7034                    Register rn,
7035                    const Operand& operand) {
7036  CheckIT(cond);
7037  if (operand.IsImmediate()) {
7038    uint32_t imm = operand.GetImmediate();
7039    if (IsUsingT32()) {
7040      ImmediateT32 immediate_t32(imm);
7041      // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7042      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) {
7043        EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7044                   (immediate_t32.GetEncodingValue() & 0xff) |
7045                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7046                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7047        AdvanceIT();
7048        return;
7049      }
7050    } else {
7051      ImmediateA32 immediate_a32(imm);
7052      // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7053      if (immediate_a32.IsValid() && cond.IsNotNever()) {
7054        EmitA32(0x03800000U | (cond.GetCondition() << 28) |
7055                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7056                immediate_a32.GetEncodingValue());
7057        return;
7058      }
7059    }
7060  }
7061  if (operand.IsImmediateShiftedRegister()) {
7062    Register rm = operand.GetBaseRegister();
7063    if (operand.IsPlainRegister()) {
7064      if (IsUsingT32()) {
7065        // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7066        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7067            rm.IsLow()) {
7068          EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7069          AdvanceIT();
7070          return;
7071        }
7072      }
7073    }
7074    Shift shift = operand.GetShift();
7075    uint32_t amount = operand.GetShiftAmount();
7076    if (IsUsingT32()) {
7077      // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7078      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) {
7079        uint32_t amount_ = amount % 32;
7080        EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7081                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7082                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7083        AdvanceIT();
7084        return;
7085      }
7086    } else {
7087      // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7088      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7089        uint32_t amount_ = amount % 32;
7090        EmitA32(0x01800000U | (cond.GetCondition() << 28) |
7091                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7092                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7093        return;
7094      }
7095    }
7096  }
7097  if (operand.IsRegisterShiftedRegister()) {
7098    Register rm = operand.GetBaseRegister();
7099    Shift shift = operand.GetShift();
7100    if (IsUsingA32()) {
7101      // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7102      if (cond.IsNotNever()) {
7103        EmitA32(0x01800010U | (cond.GetCondition() << 28) |
7104                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7105                (shift.GetType() << 5) |
7106                (operand.GetShiftRegister().GetCode() << 8));
7107        return;
7108      }
7109    }
7110  }
7111  Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand);
7112}
7113
7114void Assembler::orrs(Condition cond,
7115                     EncodingSize size,
7116                     Register rd,
7117                     Register rn,
7118                     const Operand& operand) {
7119  CheckIT(cond);
7120  if (operand.IsImmediate()) {
7121    uint32_t imm = operand.GetImmediate();
7122    if (IsUsingT32()) {
7123      ImmediateT32 immediate_t32(imm);
7124      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7125      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) {
7126        EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7127                   (immediate_t32.GetEncodingValue() & 0xff) |
7128                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7129                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7130        AdvanceIT();
7131        return;
7132      }
7133    } else {
7134      ImmediateA32 immediate_a32(imm);
7135      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7136      if (immediate_a32.IsValid() && cond.IsNotNever()) {
7137        EmitA32(0x03900000U | (cond.GetCondition() << 28) |
7138                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7139                immediate_a32.GetEncodingValue());
7140        return;
7141      }
7142    }
7143  }
7144  if (operand.IsImmediateShiftedRegister()) {
7145    Register rm = operand.GetBaseRegister();
7146    if (operand.IsPlainRegister()) {
7147      if (IsUsingT32()) {
7148        // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7149        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7150            rm.IsLow()) {
7151          EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7152          AdvanceIT();
7153          return;
7154        }
7155      }
7156    }
7157    Shift shift = operand.GetShift();
7158    uint32_t amount = operand.GetShiftAmount();
7159    if (IsUsingT32()) {
7160      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7161      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) {
7162        uint32_t amount_ = amount % 32;
7163        EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7164                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7165                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7166        AdvanceIT();
7167        return;
7168      }
7169    } else {
7170      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7171      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7172        uint32_t amount_ = amount % 32;
7173        EmitA32(0x01900000U | (cond.GetCondition() << 28) |
7174                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7175                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7176        return;
7177      }
7178    }
7179  }
7180  if (operand.IsRegisterShiftedRegister()) {
7181    Register rm = operand.GetBaseRegister();
7182    Shift shift = operand.GetShift();
7183    if (IsUsingA32()) {
7184      // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7185      if (cond.IsNotNever()) {
7186        EmitA32(0x01900010U | (cond.GetCondition() << 28) |
7187                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7188                (shift.GetType() << 5) |
7189                (operand.GetShiftRegister().GetCode() << 8));
7190        return;
7191      }
7192    }
7193  }
7194  Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand);
7195}
7196
7197void Assembler::pkhbt(Condition cond,
7198                      Register rd,
7199                      Register rn,
7200                      const Operand& operand) {
7201  CheckIT(cond);
7202  if (operand.IsImmediateShiftedRegister()) {
7203    Register rm = operand.GetBaseRegister();
7204    Shift shift = operand.GetShift();
7205    uint32_t amount = operand.GetShiftAmount();
7206    if (IsUsingT32()) {
7207      // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1
7208      if (shift.IsLSL() && shift.IsValidAmount(amount)) {
7209        EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7210                   rm.GetCode() | ((amount & 0x3) << 6) |
7211                   ((amount & 0x1c) << 10));
7212        AdvanceIT();
7213        return;
7214      }
7215    } else {
7216      // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1
7217      if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever()) {
7218        EmitA32(0x06800010U | (cond.GetCondition() << 28) |
7219                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7220                (amount << 7));
7221        return;
7222      }
7223    }
7224  }
7225  Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand);
7226}
7227
7228void Assembler::pkhtb(Condition cond,
7229                      Register rd,
7230                      Register rn,
7231                      const Operand& operand) {
7232  CheckIT(cond);
7233  if (operand.IsImmediateShiftedRegister()) {
7234    Register rm = operand.GetBaseRegister();
7235    Shift shift = operand.GetShift();
7236    uint32_t amount = operand.GetShiftAmount();
7237    if (IsUsingT32()) {
7238      // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1
7239      if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount)) {
7240        uint32_t amount_ = amount % 32;
7241        EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7242                   rm.GetCode() | ((amount_ & 0x3) << 6) |
7243                   ((amount_ & 0x1c) << 10));
7244        AdvanceIT();
7245        return;
7246      }
7247    } else {
7248      // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1
7249      if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
7250          cond.IsNotNever()) {
7251        uint32_t amount_ = amount % 32;
7252        EmitA32(0x06800050U | (cond.GetCondition() << 28) |
7253                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7254                (amount_ << 7));
7255        return;
7256      }
7257    }
7258  }
7259  Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand);
7260}
7261
7262void Assembler::pld(Condition cond, Label* label) {
7263  CheckIT(cond);
7264  Label::Offset offset =
7265      label->IsBound()
7266          ? label->GetLocation() -
7267                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
7268          : 0;
7269  if (IsUsingT32()) {
7270    // PLD{<c>}{<q>} <label> ; T1
7271    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7272         !label->IsBound())) {
7273      static class EmitOp : public Label::LabelEmitOperator {
7274       public:
7275        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7276        uint32_t Encode(uint32_t instr,
7277                        Label::Offset pc,
7278                        const Label* label) const {
7279          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7280          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7281          uint32_t U = (offset >= 0) && !label->IsMinusZero();
7282          int32_t target = abs(offset) | (U << 12);
7283          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7284        }
7285      } immop;
7286      EmitT32_32(Link(0xf81ff000U, label, immop));
7287      AdvanceIT();
7288      return;
7289    }
7290  } else {
7291    // PLD{<c>}{<q>} <label> ; A1
7292    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7293         !label->IsBound())) {
7294      if (cond.Is(al)) {
7295        static class EmitOp : public Label::LabelEmitOperator {
7296         public:
7297          EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7298          uint32_t Encode(uint32_t instr,
7299                          Label::Offset pc,
7300                          const Label* label) const {
7301            Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7302            VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7303            uint32_t U = (offset >= 0) && !label->IsMinusZero();
7304            int32_t target = abs(offset) | (U << 12);
7305            return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7306          }
7307        } immop;
7308        EmitA32(Link(0xf55ff000U, label, immop));
7309        return;
7310      }
7311    }
7312  }
7313  Delegate(kPld, &Assembler::pld, cond, label);
7314}
7315
7316void Assembler::pld(Condition cond, const MemOperand& operand) {
7317  CheckIT(cond);
7318  if (operand.IsImmediate()) {
7319    Register rn = operand.GetBaseRegister();
7320    int32_t offset = operand.GetOffsetImmediate();
7321    if (IsUsingT32()) {
7322      // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1
7323      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc)) {
7324        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7325        uint32_t offset_ = abs(offset);
7326        EmitT32_32(0xf81ff000U | offset_ | (sign << 23));
7327        AdvanceIT();
7328        return;
7329      }
7330    } else {
7331      // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1
7332      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc)) {
7333        if (cond.Is(al)) {
7334          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7335          uint32_t offset_ = abs(offset);
7336          EmitA32(0xf55ff000U | offset_ | (sign << 23));
7337          return;
7338        }
7339      }
7340    }
7341  }
7342  if (operand.IsImmediate()) {
7343    Register rn = operand.GetBaseRegister();
7344    int32_t offset = operand.GetOffsetImmediate();
7345    if (IsUsingT32()) {
7346      // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7347      if ((offset >= 0) && (offset <= 4095) && ((rn.GetCode() & 0xf) != 0xf)) {
7348        EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7349        AdvanceIT();
7350        return;
7351      }
7352      // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7353      if ((-offset >= 0) && (-offset <= 255) && ((rn.GetCode() & 0xf) != 0xf)) {
7354        EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7355        AdvanceIT();
7356        return;
7357      }
7358    } else {
7359      // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
7360      if ((offset >= -4095) && (offset <= 4095) &&
7361          ((rn.GetCode() & 0xf) != 0xf)) {
7362        if (cond.Is(al)) {
7363          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7364          uint32_t offset_ = abs(offset);
7365          EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7366          return;
7367        }
7368      }
7369    }
7370  }
7371  if (operand.IsShiftedRegister()) {
7372    Register rn = operand.GetBaseRegister();
7373    Sign sign = operand.GetSign();
7374    Register rm = operand.GetOffsetRegister();
7375    Shift shift = operand.GetShift();
7376    uint32_t amount = operand.GetShiftAmount();
7377    if (IsUsingT32()) {
7378      // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7379      if (sign.IsPlus() && shift.IsLSL() && (operand.GetAddrMode() == Offset) &&
7380          ((rn.GetCode() & 0xf) != 0xf)) {
7381        EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() |
7382                   (amount << 4));
7383        AdvanceIT();
7384        return;
7385      }
7386    } else {
7387      // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7388      if (!shift.IsRRX() && shift.IsValidAmount(amount) &&
7389          (operand.GetAddrMode() == Offset)) {
7390        if (cond.Is(al)) {
7391          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7392          uint32_t amount_ = amount % 32;
7393          EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() |
7394                  (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7395          return;
7396        }
7397      }
7398      // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7399      if (shift.IsRRX() && (operand.GetAddrMode() == Offset)) {
7400        if (cond.Is(al)) {
7401          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7402          EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() |
7403                  (sign_ << 23));
7404          return;
7405        }
7406      }
7407    }
7408  }
7409  Delegate(kPld, &Assembler::pld, cond, operand);
7410}
7411
7412void Assembler::pldw(Condition cond, const MemOperand& operand) {
7413  CheckIT(cond);
7414  if (operand.IsImmediate()) {
7415    Register rn = operand.GetBaseRegister();
7416    int32_t offset = operand.GetOffsetImmediate();
7417    if (IsUsingT32()) {
7418      // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7419      if ((offset >= 0) && (offset <= 4095) && ((rn.GetCode() & 0xf) != 0xf)) {
7420        EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7421        AdvanceIT();
7422        return;
7423      }
7424      // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7425      if ((-offset >= 0) && (-offset <= 255) && ((rn.GetCode() & 0xf) != 0xf)) {
7426        EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7427        AdvanceIT();
7428        return;
7429      }
7430    } else {
7431      // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
7432      if ((offset >= -4095) && (offset <= 4095) &&
7433          ((rn.GetCode() & 0xf) != 0xf)) {
7434        if (cond.Is(al)) {
7435          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7436          uint32_t offset_ = abs(offset);
7437          EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7438          return;
7439        }
7440      }
7441    }
7442  }
7443  if (operand.IsShiftedRegister()) {
7444    Register rn = operand.GetBaseRegister();
7445    Sign sign = operand.GetSign();
7446    Register rm = operand.GetOffsetRegister();
7447    Shift shift = operand.GetShift();
7448    uint32_t amount = operand.GetShiftAmount();
7449    if (IsUsingT32()) {
7450      // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7451      if (sign.IsPlus() && shift.IsLSL() && (operand.GetAddrMode() == Offset) &&
7452          ((rn.GetCode() & 0xf) != 0xf)) {
7453        EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() |
7454                   (amount << 4));
7455        AdvanceIT();
7456        return;
7457      }
7458    } else {
7459      // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7460      if (!shift.IsRRX() && shift.IsValidAmount(amount) &&
7461          (operand.GetAddrMode() == Offset)) {
7462        if (cond.Is(al)) {
7463          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7464          uint32_t amount_ = amount % 32;
7465          EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() |
7466                  (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7467          return;
7468        }
7469      }
7470      // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7471      if (shift.IsRRX() && (operand.GetAddrMode() == Offset)) {
7472        if (cond.Is(al)) {
7473          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7474          EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() |
7475                  (sign_ << 23));
7476          return;
7477        }
7478      }
7479    }
7480  }
7481  Delegate(kPldw, &Assembler::pldw, cond, operand);
7482}
7483
7484void Assembler::pli(Condition cond, const MemOperand& operand) {
7485  CheckIT(cond);
7486  if (operand.IsImmediate()) {
7487    Register rn = operand.GetBaseRegister();
7488    int32_t offset = operand.GetOffsetImmediate();
7489    if (IsUsingT32()) {
7490      // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7491      if ((offset >= 0) && (offset <= 4095) && ((rn.GetCode() & 0xf) != 0xf)) {
7492        EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7493        AdvanceIT();
7494        return;
7495      }
7496      // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7497      if ((-offset >= 0) && (-offset <= 255) && ((rn.GetCode() & 0xf) != 0xf)) {
7498        EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7499        AdvanceIT();
7500        return;
7501      }
7502    } else {
7503      // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1
7504      if ((offset >= -4095) && (offset <= 4095) &&
7505          ((rn.GetCode() & 0xf) != 0xf)) {
7506        if (cond.Is(al)) {
7507          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7508          uint32_t offset_ = abs(offset);
7509          EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7510          return;
7511        }
7512      }
7513    }
7514  }
7515  if (operand.IsImmediate()) {
7516    Register rn = operand.GetBaseRegister();
7517    int32_t offset = operand.GetOffsetImmediate();
7518    if (IsUsingT32()) {
7519      // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3
7520      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc)) {
7521        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7522        uint32_t offset_ = abs(offset);
7523        EmitT32_32(0xf91ff000U | offset_ | (sign << 23));
7524        AdvanceIT();
7525        return;
7526      }
7527    } else {
7528      // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1
7529      if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc)) {
7530        if (cond.Is(al)) {
7531          uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7532          uint32_t offset_ = abs(offset);
7533          EmitA32(0xf45ff000U | offset_ | (sign << 23));
7534          return;
7535        }
7536      }
7537    }
7538  }
7539  if (operand.IsShiftedRegister()) {
7540    Register rn = operand.GetBaseRegister();
7541    Sign sign = operand.GetSign();
7542    Register rm = operand.GetOffsetRegister();
7543    Shift shift = operand.GetShift();
7544    uint32_t amount = operand.GetShiftAmount();
7545    if (IsUsingT32()) {
7546      // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7547      if (sign.IsPlus() && shift.IsLSL() && (operand.GetAddrMode() == Offset) &&
7548          ((rn.GetCode() & 0xf) != 0xf)) {
7549        EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() |
7550                   (amount << 4));
7551        AdvanceIT();
7552        return;
7553      }
7554    } else {
7555      // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7556      if (shift.IsRRX() && (operand.GetAddrMode() == Offset)) {
7557        if (cond.Is(al)) {
7558          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7559          EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() |
7560                  (sign_ << 23));
7561          return;
7562        }
7563      }
7564      // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7565      if (!shift.IsRRX() && shift.IsValidAmount(amount) &&
7566          (operand.GetAddrMode() == Offset)) {
7567        if (cond.Is(al)) {
7568          uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7569          uint32_t amount_ = amount % 32;
7570          EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() |
7571                  (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7572          return;
7573        }
7574      }
7575    }
7576  }
7577  Delegate(kPli, &Assembler::pli, cond, operand);
7578}
7579
7580void Assembler::pli(Condition cond, Label* label) {
7581  CheckIT(cond);
7582  Label::Offset offset =
7583      label->IsBound()
7584          ? label->GetLocation() -
7585                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
7586          : 0;
7587  if (IsUsingT32()) {
7588    // PLI{<c>}{<q>} <label> ; T3
7589    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7590         !label->IsBound())) {
7591      static class EmitOp : public Label::LabelEmitOperator {
7592       public:
7593        EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7594        uint32_t Encode(uint32_t instr,
7595                        Label::Offset pc,
7596                        const Label* label) const {
7597          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7598          VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7599          uint32_t U = (offset >= 0) && !label->IsMinusZero();
7600          int32_t target = abs(offset) | (U << 12);
7601          return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7602        }
7603      } immop;
7604      EmitT32_32(Link(0xf91ff000U, label, immop));
7605      AdvanceIT();
7606      return;
7607    }
7608  } else {
7609    // PLI{<c>}{<q>} <label> ; A1
7610    if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7611         !label->IsBound())) {
7612      if (cond.Is(al)) {
7613        static class EmitOp : public Label::LabelEmitOperator {
7614         public:
7615          EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7616          uint32_t Encode(uint32_t instr,
7617                          Label::Offset pc,
7618                          const Label* label) const {
7619            Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7620            VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7621            uint32_t U = (offset >= 0) && !label->IsMinusZero();
7622            int32_t target = abs(offset) | (U << 12);
7623            return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7624          }
7625        } immop;
7626        EmitA32(Link(0xf45ff000U, label, immop));
7627        return;
7628      }
7629    }
7630  }
7631  Delegate(kPli, &Assembler::pli, cond, label);
7632}
7633
7634void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) {
7635  CheckIT(cond);
7636  if (IsUsingT32()) {
7637    // POP{<c>}{<q>} <registers> ; T1
7638    if (!size.IsWide() && ((registers.GetList() & ~0x80ff) == 0)) {
7639      EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
7640                 GetRegisterListEncoding(registers, 0, 8));
7641      AdvanceIT();
7642      return;
7643    }
7644    // POP{<c>}{<q>} <registers> ; T2
7645    if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
7646      EmitT32_32(0xe8bd0000U |
7647                 (GetRegisterListEncoding(registers, 15, 1) << 15) |
7648                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
7649                 GetRegisterListEncoding(registers, 0, 13));
7650      AdvanceIT();
7651      return;
7652    }
7653  } else {
7654    // POP{<c>}{<q>} <registers> ; A1
7655    if (cond.IsNotNever()) {
7656      EmitA32(0x08bd0000U | (cond.GetCondition() << 28) |
7657              GetRegisterListEncoding(registers, 0, 16));
7658      return;
7659    }
7660  }
7661  Delegate(kPop, &Assembler::pop, cond, size, registers);
7662}
7663
7664void Assembler::pop(Condition cond, EncodingSize size, Register rt) {
7665  CheckIT(cond);
7666  if (IsUsingT32()) {
7667    // POP{<c>}{<q>} <single_register_list> ; T4
7668    if (!size.IsNarrow() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) {
7669      EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12));
7670      AdvanceIT();
7671      return;
7672    }
7673  } else {
7674    // POP{<c>}{<q>} <single_register_list> ; A1
7675    if (cond.IsNotNever()) {
7676      EmitA32(0x049d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
7677      return;
7678    }
7679  }
7680  Delegate(kPop, &Assembler::pop, cond, size, rt);
7681}
7682
7683void Assembler::push(Condition cond,
7684                     EncodingSize size,
7685                     RegisterList registers) {
7686  CheckIT(cond);
7687  if (IsUsingT32()) {
7688    // PUSH{<c>}{<q>} <registers> ; T1
7689    if (!size.IsWide() && ((registers.GetList() & ~0x40ff) == 0)) {
7690      EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
7691                 GetRegisterListEncoding(registers, 0, 8));
7692      AdvanceIT();
7693      return;
7694    }
7695    // PUSH{<c>}{<q>} <registers> ; T1
7696    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
7697      EmitT32_32(0xe92d0000U |
7698                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
7699                 GetRegisterListEncoding(registers, 0, 13));
7700      AdvanceIT();
7701      return;
7702    }
7703  } else {
7704    // PUSH{<c>}{<q>} <registers> ; A1
7705    if (cond.IsNotNever()) {
7706      EmitA32(0x092d0000U | (cond.GetCondition() << 28) |
7707              GetRegisterListEncoding(registers, 0, 16));
7708      return;
7709    }
7710  }
7711  Delegate(kPush, &Assembler::push, cond, size, registers);
7712}
7713
7714void Assembler::push(Condition cond, EncodingSize size, Register rt) {
7715  CheckIT(cond);
7716  if (IsUsingT32()) {
7717    // PUSH{<c>}{<q>} <single_register_list> ; T4
7718    if (!size.IsNarrow()) {
7719      EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12));
7720      AdvanceIT();
7721      return;
7722    }
7723  } else {
7724    // PUSH{<c>}{<q>} <single_register_list> ; A1
7725    if (cond.IsNotNever() && ((!rt.IsPC()) || AllowUnpredictable())) {
7726      EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
7727      return;
7728    }
7729  }
7730  Delegate(kPush, &Assembler::push, cond, size, rt);
7731}
7732
7733void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) {
7734  CheckIT(cond);
7735  if (IsUsingT32()) {
7736    // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7737    EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() |
7738               (rn.GetCode() << 16));
7739    AdvanceIT();
7740    return;
7741  } else {
7742    // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7743    if (cond.IsNotNever()) {
7744      EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7745              rm.GetCode() | (rn.GetCode() << 16));
7746      return;
7747    }
7748  }
7749  Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn);
7750}
7751
7752void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) {
7753  CheckIT(cond);
7754  if (IsUsingT32()) {
7755    // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7756    EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7757               rm.GetCode());
7758    AdvanceIT();
7759    return;
7760  } else {
7761    // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7762    if (cond.IsNotNever()) {
7763      EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7764              (rn.GetCode() << 16) | rm.GetCode());
7765      return;
7766    }
7767  }
7768  Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm);
7769}
7770
7771void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) {
7772  CheckIT(cond);
7773  if (IsUsingT32()) {
7774    // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7775    EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7776               rm.GetCode());
7777    AdvanceIT();
7778    return;
7779  } else {
7780    // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7781    if (cond.IsNotNever()) {
7782      EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7783              (rn.GetCode() << 16) | rm.GetCode());
7784      return;
7785    }
7786  }
7787  Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm);
7788}
7789
7790void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) {
7791  CheckIT(cond);
7792  if (IsUsingT32()) {
7793    // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7794    EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7795               rm.GetCode());
7796    AdvanceIT();
7797    return;
7798  } else {
7799    // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7800    if (cond.IsNotNever()) {
7801      EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7802              (rn.GetCode() << 16) | rm.GetCode());
7803      return;
7804    }
7805  }
7806  Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm);
7807}
7808
7809void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) {
7810  CheckIT(cond);
7811  if (IsUsingT32()) {
7812    // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7813    EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() |
7814               (rn.GetCode() << 16));
7815    AdvanceIT();
7816    return;
7817  } else {
7818    // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7819    if (cond.IsNotNever()) {
7820      EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7821              rm.GetCode() | (rn.GetCode() << 16));
7822      return;
7823    }
7824  }
7825  Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn);
7826}
7827
7828void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) {
7829  CheckIT(cond);
7830  if (IsUsingT32()) {
7831    // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7832    EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
7833               (rn.GetCode() << 16));
7834    AdvanceIT();
7835    return;
7836  } else {
7837    // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7838    if (cond.IsNotNever()) {
7839      EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7840              rm.GetCode() | (rn.GetCode() << 16));
7841      return;
7842    }
7843  }
7844  Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn);
7845}
7846
7847void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) {
7848  CheckIT(cond);
7849  if (IsUsingT32()) {
7850    // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7851    EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7852               rm.GetCode());
7853    AdvanceIT();
7854    return;
7855  } else {
7856    // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7857    if (cond.IsNotNever()) {
7858      EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7859              (rn.GetCode() << 16) | rm.GetCode());
7860      return;
7861    }
7862  }
7863  Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm);
7864}
7865
7866void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) {
7867  CheckIT(cond);
7868  if (IsUsingT32()) {
7869    // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7870    EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
7871               (rn.GetCode() << 16));
7872    AdvanceIT();
7873    return;
7874  } else {
7875    // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7876    if (cond.IsNotNever()) {
7877      EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7878              rm.GetCode() | (rn.GetCode() << 16));
7879      return;
7880    }
7881  }
7882  Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn);
7883}
7884
7885void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) {
7886  CheckIT(cond);
7887  if (IsUsingT32()) {
7888    // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7889    EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7890               rm.GetCode());
7891    AdvanceIT();
7892    return;
7893  } else {
7894    // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7895    if (cond.IsNotNever()) {
7896      EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7897              (rn.GetCode() << 16) | rm.GetCode());
7898      return;
7899    }
7900  }
7901  Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm);
7902}
7903
7904void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) {
7905  CheckIT(cond);
7906  if (IsUsingT32()) {
7907    // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7908    EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7909               rm.GetCode());
7910    AdvanceIT();
7911    return;
7912  } else {
7913    // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7914    if (cond.IsNotNever()) {
7915      EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7916              (rn.GetCode() << 16) | rm.GetCode());
7917      return;
7918    }
7919  }
7920  Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm);
7921}
7922
7923void Assembler::rbit(Condition cond, Register rd, Register rm) {
7924  CheckIT(cond);
7925  if (IsUsingT32()) {
7926    // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1
7927    EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
7928               (rm.GetCode() << 16));
7929    AdvanceIT();
7930    return;
7931  } else {
7932    // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1
7933    if (cond.IsNotNever()) {
7934      EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7935              rm.GetCode());
7936      return;
7937    }
7938  }
7939  Delegate(kRbit, &Assembler::rbit, cond, rd, rm);
7940}
7941
7942void Assembler::rev(Condition cond,
7943                    EncodingSize size,
7944                    Register rd,
7945                    Register rm) {
7946  CheckIT(cond);
7947  if (IsUsingT32()) {
7948    // REV{<c>}{<q>} <Rd>, <Rm> ; T1
7949    if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
7950      EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3));
7951      AdvanceIT();
7952      return;
7953    }
7954    // REV{<c>}{<q>} <Rd>, <Rm> ; T2
7955    if (!size.IsNarrow()) {
7956      EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() |
7957                 (rm.GetCode() << 16));
7958      AdvanceIT();
7959      return;
7960    }
7961  } else {
7962    // REV{<c>}{<q>} <Rd>, <Rm> ; A1
7963    if (cond.IsNotNever()) {
7964      EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7965              rm.GetCode());
7966      return;
7967    }
7968  }
7969  Delegate(kRev, &Assembler::rev, cond, size, rd, rm);
7970}
7971
7972void Assembler::rev16(Condition cond,
7973                      EncodingSize size,
7974                      Register rd,
7975                      Register rm) {
7976  CheckIT(cond);
7977  if (IsUsingT32()) {
7978    // REV16{<c>}{<q>} <Rd>, <Rm> ; T1
7979    if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
7980      EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3));
7981      AdvanceIT();
7982      return;
7983    }
7984    // REV16{<c>}{<q>} <Rd>, <Rm> ; T2
7985    if (!size.IsNarrow()) {
7986      EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() |
7987                 (rm.GetCode() << 16));
7988      AdvanceIT();
7989      return;
7990    }
7991  } else {
7992    // REV16{<c>}{<q>} <Rd>, <Rm> ; A1
7993    if (cond.IsNotNever()) {
7994      EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7995              rm.GetCode());
7996      return;
7997    }
7998  }
7999  Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm);
8000}
8001
8002void Assembler::revsh(Condition cond,
8003                      EncodingSize size,
8004                      Register rd,
8005                      Register rm) {
8006  CheckIT(cond);
8007  if (IsUsingT32()) {
8008    // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1
8009    if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8010      EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3));
8011      AdvanceIT();
8012      return;
8013    }
8014    // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2
8015    if (!size.IsNarrow()) {
8016      EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
8017                 (rm.GetCode() << 16));
8018      AdvanceIT();
8019      return;
8020    }
8021  } else {
8022    // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1
8023    if (cond.IsNotNever()) {
8024      EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8025              rm.GetCode());
8026      return;
8027    }
8028  }
8029  Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm);
8030}
8031
8032void Assembler::ror(Condition cond,
8033                    EncodingSize size,
8034                    Register rd,
8035                    Register rm,
8036                    const Operand& operand) {
8037  CheckIT(cond);
8038  if (operand.IsImmediate()) {
8039    uint32_t imm = operand.GetImmediate();
8040    if (IsUsingT32()) {
8041      // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
8042      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
8043        EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() |
8044                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
8045        AdvanceIT();
8046        return;
8047      }
8048    } else {
8049      // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
8050      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
8051        EmitA32(0x01a00060U | (cond.GetCondition() << 28) |
8052                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
8053        return;
8054      }
8055    }
8056  }
8057  if (operand.IsPlainRegister()) {
8058    Register rs = operand.GetBaseRegister();
8059    if (IsUsingT32()) {
8060      // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
8061      if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
8062          rs.IsLow()) {
8063        EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
8064        AdvanceIT();
8065        return;
8066      }
8067      // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
8068      if (!size.IsNarrow()) {
8069        EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
8070                   rs.GetCode());
8071        AdvanceIT();
8072        return;
8073      }
8074    } else {
8075      // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
8076      if (cond.IsNotNever()) {
8077        EmitA32(0x01a00070U | (cond.GetCondition() << 28) |
8078                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
8079        return;
8080      }
8081    }
8082  }
8083  Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand);
8084}
8085
8086void Assembler::rors(Condition cond,
8087                     EncodingSize size,
8088                     Register rd,
8089                     Register rm,
8090                     const Operand& operand) {
8091  CheckIT(cond);
8092  if (operand.IsImmediate()) {
8093    uint32_t imm = operand.GetImmediate();
8094    if (IsUsingT32()) {
8095      // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
8096      if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
8097        EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() |
8098                   ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
8099        AdvanceIT();
8100        return;
8101      }
8102    } else {
8103      // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
8104      if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
8105        EmitA32(0x01b00060U | (cond.GetCondition() << 28) |
8106                (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
8107        return;
8108      }
8109    }
8110  }
8111  if (operand.IsPlainRegister()) {
8112    Register rs = operand.GetBaseRegister();
8113    if (IsUsingT32()) {
8114      // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
8115      if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
8116          rs.IsLow()) {
8117        EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
8118        AdvanceIT();
8119        return;
8120      }
8121      // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
8122      if (!size.IsNarrow()) {
8123        EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
8124                   rs.GetCode());
8125        AdvanceIT();
8126        return;
8127      }
8128    } else {
8129      // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
8130      if (cond.IsNotNever()) {
8131        EmitA32(0x01b00070U | (cond.GetCondition() << 28) |
8132                (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
8133        return;
8134      }
8135    }
8136  }
8137  Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand);
8138}
8139
8140void Assembler::rrx(Condition cond, Register rd, Register rm) {
8141  CheckIT(cond);
8142  if (IsUsingT32()) {
8143    // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3
8144    EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode());
8145    AdvanceIT();
8146    return;
8147  } else {
8148    // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1
8149    if (cond.IsNotNever()) {
8150      EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8151              rm.GetCode());
8152      return;
8153    }
8154  }
8155  Delegate(kRrx, &Assembler::rrx, cond, rd, rm);
8156}
8157
8158void Assembler::rrxs(Condition cond, Register rd, Register rm) {
8159  CheckIT(cond);
8160  if (IsUsingT32()) {
8161    // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3
8162    EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode());
8163    AdvanceIT();
8164    return;
8165  } else {
8166    // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1
8167    if (cond.IsNotNever()) {
8168      EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8169              rm.GetCode());
8170      return;
8171    }
8172  }
8173  Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm);
8174}
8175
8176void Assembler::rsb(Condition cond,
8177                    EncodingSize size,
8178                    Register rd,
8179                    Register rn,
8180                    const Operand& operand) {
8181  CheckIT(cond);
8182  if (operand.IsImmediate()) {
8183    uint32_t imm = operand.GetImmediate();
8184    if (IsUsingT32()) {
8185      ImmediateT32 immediate_t32(imm);
8186      // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1
8187      if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
8188          (imm == 0)) {
8189        EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
8190        AdvanceIT();
8191        return;
8192      }
8193      // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
8194      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8195        EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8196                   (immediate_t32.GetEncodingValue() & 0xff) |
8197                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8198                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8199        AdvanceIT();
8200        return;
8201      }
8202    } else {
8203      ImmediateA32 immediate_a32(imm);
8204      // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8205      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8206        EmitA32(0x02600000U | (cond.GetCondition() << 28) |
8207                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8208                immediate_a32.GetEncodingValue());
8209        return;
8210      }
8211    }
8212  }
8213  if (operand.IsImmediateShiftedRegister()) {
8214    Register rm = operand.GetBaseRegister();
8215    Shift shift = operand.GetShift();
8216    uint32_t amount = operand.GetShiftAmount();
8217    if (IsUsingT32()) {
8218      // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
8219      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8220        uint32_t amount_ = amount % 32;
8221        EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8222                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8223                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8224        AdvanceIT();
8225        return;
8226      }
8227    } else {
8228      // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8229      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8230        uint32_t amount_ = amount % 32;
8231        EmitA32(0x00600000U | (cond.GetCondition() << 28) |
8232                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8233                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8234        return;
8235      }
8236    }
8237  }
8238  if (operand.IsRegisterShiftedRegister()) {
8239    Register rm = operand.GetBaseRegister();
8240    Shift shift = operand.GetShift();
8241    if (IsUsingA32()) {
8242      // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8243      if (cond.IsNotNever()) {
8244        EmitA32(0x00600010U | (cond.GetCondition() << 28) |
8245                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8246                (shift.GetType() << 5) |
8247                (operand.GetShiftRegister().GetCode() << 8));
8248        return;
8249      }
8250    }
8251  }
8252  Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand);
8253}
8254
8255void Assembler::rsbs(Condition cond,
8256                     EncodingSize size,
8257                     Register rd,
8258                     Register rn,
8259                     const Operand& operand) {
8260  CheckIT(cond);
8261  if (operand.IsImmediate()) {
8262    uint32_t imm = operand.GetImmediate();
8263    if (IsUsingT32()) {
8264      ImmediateT32 immediate_t32(imm);
8265      // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1
8266      if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
8267          (imm == 0)) {
8268        EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
8269        AdvanceIT();
8270        return;
8271      }
8272      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
8273      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8274        EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8275                   (immediate_t32.GetEncodingValue() & 0xff) |
8276                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8277                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8278        AdvanceIT();
8279        return;
8280      }
8281    } else {
8282      ImmediateA32 immediate_a32(imm);
8283      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8284      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8285        EmitA32(0x02700000U | (cond.GetCondition() << 28) |
8286                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8287                immediate_a32.GetEncodingValue());
8288        return;
8289      }
8290    }
8291  }
8292  if (operand.IsImmediateShiftedRegister()) {
8293    Register rm = operand.GetBaseRegister();
8294    Shift shift = operand.GetShift();
8295    uint32_t amount = operand.GetShiftAmount();
8296    if (IsUsingT32()) {
8297      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
8298      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8299        uint32_t amount_ = amount % 32;
8300        EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8301                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8302                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8303        AdvanceIT();
8304        return;
8305      }
8306    } else {
8307      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8308      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8309        uint32_t amount_ = amount % 32;
8310        EmitA32(0x00700000U | (cond.GetCondition() << 28) |
8311                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8312                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8313        return;
8314      }
8315    }
8316  }
8317  if (operand.IsRegisterShiftedRegister()) {
8318    Register rm = operand.GetBaseRegister();
8319    Shift shift = operand.GetShift();
8320    if (IsUsingA32()) {
8321      // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8322      if (cond.IsNotNever()) {
8323        EmitA32(0x00700010U | (cond.GetCondition() << 28) |
8324                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8325                (shift.GetType() << 5) |
8326                (operand.GetShiftRegister().GetCode() << 8));
8327        return;
8328      }
8329    }
8330  }
8331  Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand);
8332}
8333
8334void Assembler::rsc(Condition cond,
8335                    Register rd,
8336                    Register rn,
8337                    const Operand& operand) {
8338  CheckIT(cond);
8339  if (operand.IsImmediate()) {
8340    uint32_t imm = operand.GetImmediate();
8341    if (IsUsingA32()) {
8342      ImmediateA32 immediate_a32(imm);
8343      // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8344      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8345        EmitA32(0x02e00000U | (cond.GetCondition() << 28) |
8346                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8347                immediate_a32.GetEncodingValue());
8348        return;
8349      }
8350    }
8351  }
8352  if (operand.IsImmediateShiftedRegister()) {
8353    Register rm = operand.GetBaseRegister();
8354    Shift shift = operand.GetShift();
8355    uint32_t amount = operand.GetShiftAmount();
8356    if (IsUsingA32()) {
8357      // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8358      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8359        uint32_t amount_ = amount % 32;
8360        EmitA32(0x00e00000U | (cond.GetCondition() << 28) |
8361                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8362                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8363        return;
8364      }
8365    }
8366  }
8367  if (operand.IsRegisterShiftedRegister()) {
8368    Register rm = operand.GetBaseRegister();
8369    Shift shift = operand.GetShift();
8370    if (IsUsingA32()) {
8371      // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8372      if (cond.IsNotNever()) {
8373        EmitA32(0x00e00010U | (cond.GetCondition() << 28) |
8374                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8375                (shift.GetType() << 5) |
8376                (operand.GetShiftRegister().GetCode() << 8));
8377        return;
8378      }
8379    }
8380  }
8381  Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand);
8382}
8383
8384void Assembler::rscs(Condition cond,
8385                     Register rd,
8386                     Register rn,
8387                     const Operand& operand) {
8388  CheckIT(cond);
8389  if (operand.IsImmediate()) {
8390    uint32_t imm = operand.GetImmediate();
8391    if (IsUsingA32()) {
8392      ImmediateA32 immediate_a32(imm);
8393      // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8394      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8395        EmitA32(0x02f00000U | (cond.GetCondition() << 28) |
8396                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8397                immediate_a32.GetEncodingValue());
8398        return;
8399      }
8400    }
8401  }
8402  if (operand.IsImmediateShiftedRegister()) {
8403    Register rm = operand.GetBaseRegister();
8404    Shift shift = operand.GetShift();
8405    uint32_t amount = operand.GetShiftAmount();
8406    if (IsUsingA32()) {
8407      // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8408      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8409        uint32_t amount_ = amount % 32;
8410        EmitA32(0x00f00000U | (cond.GetCondition() << 28) |
8411                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8412                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8413        return;
8414      }
8415    }
8416  }
8417  if (operand.IsRegisterShiftedRegister()) {
8418    Register rm = operand.GetBaseRegister();
8419    Shift shift = operand.GetShift();
8420    if (IsUsingA32()) {
8421      // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8422      if (cond.IsNotNever()) {
8423        EmitA32(0x00f00010U | (cond.GetCondition() << 28) |
8424                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8425                (shift.GetType() << 5) |
8426                (operand.GetShiftRegister().GetCode() << 8));
8427        return;
8428      }
8429    }
8430  }
8431  Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand);
8432}
8433
8434void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) {
8435  CheckIT(cond);
8436  if (IsUsingT32()) {
8437    // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8438    EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8439               rm.GetCode());
8440    AdvanceIT();
8441    return;
8442  } else {
8443    // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8444    if (cond.IsNotNever()) {
8445      EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8446              (rn.GetCode() << 16) | rm.GetCode());
8447      return;
8448    }
8449  }
8450  Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm);
8451}
8452
8453void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) {
8454  CheckIT(cond);
8455  if (IsUsingT32()) {
8456    // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8457    EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8458               rm.GetCode());
8459    AdvanceIT();
8460    return;
8461  } else {
8462    // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8463    if (cond.IsNotNever()) {
8464      EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8465              (rn.GetCode() << 16) | rm.GetCode());
8466      return;
8467    }
8468  }
8469  Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm);
8470}
8471
8472void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) {
8473  CheckIT(cond);
8474  if (IsUsingT32()) {
8475    // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8476    EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8477               rm.GetCode());
8478    AdvanceIT();
8479    return;
8480  } else {
8481    // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8482    if (cond.IsNotNever()) {
8483      EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8484              (rn.GetCode() << 16) | rm.GetCode());
8485      return;
8486    }
8487  }
8488  Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm);
8489}
8490
8491void Assembler::sbc(Condition cond,
8492                    EncodingSize size,
8493                    Register rd,
8494                    Register rn,
8495                    const Operand& operand) {
8496  CheckIT(cond);
8497  if (operand.IsImmediate()) {
8498    uint32_t imm = operand.GetImmediate();
8499    if (IsUsingT32()) {
8500      ImmediateT32 immediate_t32(imm);
8501      // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
8502      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8503        EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8504                   (immediate_t32.GetEncodingValue() & 0xff) |
8505                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8506                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8507        AdvanceIT();
8508        return;
8509      }
8510    } else {
8511      ImmediateA32 immediate_a32(imm);
8512      // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8513      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8514        EmitA32(0x02c00000U | (cond.GetCondition() << 28) |
8515                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8516                immediate_a32.GetEncodingValue());
8517        return;
8518      }
8519    }
8520  }
8521  if (operand.IsImmediateShiftedRegister()) {
8522    Register rm = operand.GetBaseRegister();
8523    if (operand.IsPlainRegister()) {
8524      if (IsUsingT32()) {
8525        // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
8526        if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
8527            rm.IsLow()) {
8528          EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
8529          AdvanceIT();
8530          return;
8531        }
8532      }
8533    }
8534    Shift shift = operand.GetShift();
8535    uint32_t amount = operand.GetShiftAmount();
8536    if (IsUsingT32()) {
8537      // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
8538      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8539        uint32_t amount_ = amount % 32;
8540        EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8541                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8542                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8543        AdvanceIT();
8544        return;
8545      }
8546    } else {
8547      // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8548      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8549        uint32_t amount_ = amount % 32;
8550        EmitA32(0x00c00000U | (cond.GetCondition() << 28) |
8551                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8552                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8553        return;
8554      }
8555    }
8556  }
8557  if (operand.IsRegisterShiftedRegister()) {
8558    Register rm = operand.GetBaseRegister();
8559    Shift shift = operand.GetShift();
8560    if (IsUsingA32()) {
8561      // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8562      if (cond.IsNotNever()) {
8563        EmitA32(0x00c00010U | (cond.GetCondition() << 28) |
8564                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8565                (shift.GetType() << 5) |
8566                (operand.GetShiftRegister().GetCode() << 8));
8567        return;
8568      }
8569    }
8570  }
8571  Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand);
8572}
8573
8574void Assembler::sbcs(Condition cond,
8575                     EncodingSize size,
8576                     Register rd,
8577                     Register rn,
8578                     const Operand& operand) {
8579  CheckIT(cond);
8580  if (operand.IsImmediate()) {
8581    uint32_t imm = operand.GetImmediate();
8582    if (IsUsingT32()) {
8583      ImmediateT32 immediate_t32(imm);
8584      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
8585      if (!size.IsNarrow() && immediate_t32.IsValid()) {
8586        EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8587                   (immediate_t32.GetEncodingValue() & 0xff) |
8588                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8589                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8590        AdvanceIT();
8591        return;
8592      }
8593    } else {
8594      ImmediateA32 immediate_a32(imm);
8595      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8596      if (immediate_a32.IsValid() && cond.IsNotNever()) {
8597        EmitA32(0x02d00000U | (cond.GetCondition() << 28) |
8598                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8599                immediate_a32.GetEncodingValue());
8600        return;
8601      }
8602    }
8603  }
8604  if (operand.IsImmediateShiftedRegister()) {
8605    Register rm = operand.GetBaseRegister();
8606    if (operand.IsPlainRegister()) {
8607      if (IsUsingT32()) {
8608        // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
8609        if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
8610            rm.IsLow()) {
8611          EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
8612          AdvanceIT();
8613          return;
8614        }
8615      }
8616    }
8617    Shift shift = operand.GetShift();
8618    uint32_t amount = operand.GetShiftAmount();
8619    if (IsUsingT32()) {
8620      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
8621      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8622        uint32_t amount_ = amount % 32;
8623        EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8624                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8625                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8626        AdvanceIT();
8627        return;
8628      }
8629    } else {
8630      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8631      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8632        uint32_t amount_ = amount % 32;
8633        EmitA32(0x00d00000U | (cond.GetCondition() << 28) |
8634                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8635                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8636        return;
8637      }
8638    }
8639  }
8640  if (operand.IsRegisterShiftedRegister()) {
8641    Register rm = operand.GetBaseRegister();
8642    Shift shift = operand.GetShift();
8643    if (IsUsingA32()) {
8644      // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8645      if (cond.IsNotNever()) {
8646        EmitA32(0x00d00010U | (cond.GetCondition() << 28) |
8647                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8648                (shift.GetType() << 5) |
8649                (operand.GetShiftRegister().GetCode() << 8));
8650        return;
8651      }
8652    }
8653  }
8654  Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand);
8655}
8656
8657void Assembler::sbfx(Condition cond,
8658                     Register rd,
8659                     Register rn,
8660                     uint32_t lsb,
8661                     const Operand& operand) {
8662  CheckIT(cond);
8663  if (operand.IsImmediate()) {
8664    uint32_t width = operand.GetImmediate();
8665    if (IsUsingT32()) {
8666      // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
8667      if ((lsb <= 31) &&
8668          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
8669        uint32_t widthm1 = width - 1;
8670        EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8671                   ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
8672        AdvanceIT();
8673        return;
8674      }
8675    } else {
8676      // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
8677      if ((lsb <= 31) && cond.IsNotNever() &&
8678          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
8679        uint32_t widthm1 = width - 1;
8680        EmitA32(0x07a00050U | (cond.GetCondition() << 28) |
8681                (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) |
8682                (widthm1 << 16));
8683        return;
8684      }
8685    }
8686  }
8687  Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, operand);
8688}
8689
8690void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) {
8691  CheckIT(cond);
8692  if (IsUsingT32()) {
8693    // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8694    EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8695               rm.GetCode());
8696    AdvanceIT();
8697    return;
8698  } else {
8699    // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8700    if (cond.IsNotNever()) {
8701      EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
8702              rn.GetCode() | (rm.GetCode() << 8));
8703      return;
8704    }
8705  }
8706  Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm);
8707}
8708
8709void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) {
8710  CheckIT(cond);
8711  if (IsUsingT32()) {
8712    // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8713    EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8714               rm.GetCode());
8715    AdvanceIT();
8716    return;
8717  } else {
8718    // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8719    if (cond.IsNotNever()) {
8720      EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8721              (rn.GetCode() << 16) | rm.GetCode());
8722      return;
8723    }
8724  }
8725  Delegate(kSel, &Assembler::sel, cond, rd, rn, rm);
8726}
8727
8728void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) {
8729  CheckIT(cond);
8730  if (IsUsingT32()) {
8731    // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8732    EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8733               rm.GetCode());
8734    AdvanceIT();
8735    return;
8736  } else {
8737    // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8738    if (cond.IsNotNever()) {
8739      EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8740              (rn.GetCode() << 16) | rm.GetCode());
8741      return;
8742    }
8743  }
8744  Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm);
8745}
8746
8747void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) {
8748  CheckIT(cond);
8749  if (IsUsingT32()) {
8750    // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8751    EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8752               rm.GetCode());
8753    AdvanceIT();
8754    return;
8755  } else {
8756    // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8757    if (cond.IsNotNever()) {
8758      EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8759              (rn.GetCode() << 16) | rm.GetCode());
8760      return;
8761    }
8762  }
8763  Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm);
8764}
8765
8766void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) {
8767  CheckIT(cond);
8768  if (IsUsingT32()) {
8769    // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8770    EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8771               rm.GetCode());
8772    AdvanceIT();
8773    return;
8774  } else {
8775    // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8776    if (cond.IsNotNever()) {
8777      EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8778              (rn.GetCode() << 16) | rm.GetCode());
8779      return;
8780    }
8781  }
8782  Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm);
8783}
8784
8785void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) {
8786  CheckIT(cond);
8787  if (IsUsingT32()) {
8788    // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8789    EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8790               rm.GetCode());
8791    AdvanceIT();
8792    return;
8793  } else {
8794    // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8795    if (cond.IsNotNever()) {
8796      EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8797              (rn.GetCode() << 16) | rm.GetCode());
8798      return;
8799    }
8800  }
8801  Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm);
8802}
8803
8804void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) {
8805  CheckIT(cond);
8806  if (IsUsingT32()) {
8807    // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8808    EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8809               rm.GetCode());
8810    AdvanceIT();
8811    return;
8812  } else {
8813    // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8814    if (cond.IsNotNever()) {
8815      EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8816              (rn.GetCode() << 16) | rm.GetCode());
8817      return;
8818    }
8819  }
8820  Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm);
8821}
8822
8823void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) {
8824  CheckIT(cond);
8825  if (IsUsingT32()) {
8826    // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8827    EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8828               rm.GetCode());
8829    AdvanceIT();
8830    return;
8831  } else {
8832    // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8833    if (cond.IsNotNever()) {
8834      EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8835              (rn.GetCode() << 16) | rm.GetCode());
8836      return;
8837    }
8838  }
8839  Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm);
8840}
8841
8842void Assembler::smlabb(
8843    Condition cond, Register rd, Register rn, Register rm, Register ra) {
8844  CheckIT(cond);
8845  if (IsUsingT32()) {
8846    // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
8847    if (!ra.Is(pc)) {
8848      EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8849                 rm.GetCode() | (ra.GetCode() << 12));
8850      AdvanceIT();
8851      return;
8852    }
8853  } else {
8854    // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
8855    if (cond.IsNotNever()) {
8856      EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
8857              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
8858      return;
8859    }
8860  }
8861  Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra);
8862}
8863
8864void Assembler::smlabt(
8865    Condition cond, Register rd, Register rn, Register rm, Register ra) {
8866  CheckIT(cond);
8867  if (IsUsingT32()) {
8868    // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
8869    if (!ra.Is(pc)) {
8870      EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8871                 rm.GetCode() | (ra.GetCode() << 12));
8872      AdvanceIT();
8873      return;
8874    }
8875  } else {
8876    // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
8877    if (cond.IsNotNever()) {
8878      EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
8879              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
8880      return;
8881    }
8882  }
8883  Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra);
8884}
8885
8886void Assembler::smlad(
8887    Condition cond, Register rd, Register rn, Register rm, Register ra) {
8888  CheckIT(cond);
8889  if (IsUsingT32()) {
8890    // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
8891    if (!ra.Is(pc)) {
8892      EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8893                 rm.GetCode() | (ra.GetCode() << 12));
8894      AdvanceIT();
8895      return;
8896    }
8897  } else {
8898    // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
8899    if (cond.IsNotNever() && !ra.Is(pc)) {
8900      EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
8901              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
8902      return;
8903    }
8904  }
8905  Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra);
8906}
8907
8908void Assembler::smladx(
8909    Condition cond, Register rd, Register rn, Register rm, Register ra) {
8910  CheckIT(cond);
8911  if (IsUsingT32()) {
8912    // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
8913    if (!ra.Is(pc)) {
8914      EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8915                 rm.GetCode() | (ra.GetCode() << 12));
8916      AdvanceIT();
8917      return;
8918    }
8919  } else {
8920    // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
8921    if (cond.IsNotNever() && !ra.Is(pc)) {
8922      EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
8923              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
8924      return;
8925    }
8926  }
8927  Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra);
8928}
8929
8930void Assembler::smlal(
8931    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
8932  CheckIT(cond);
8933  if (IsUsingT32()) {
8934    // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
8935    EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
8936               (rn.GetCode() << 16) | rm.GetCode());
8937    AdvanceIT();
8938    return;
8939  } else {
8940    // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
8941    if (cond.IsNotNever()) {
8942      EmitA32(0x00e00090U | (cond.GetCondition() << 28) |
8943              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
8944              (rm.GetCode() << 8));
8945      return;
8946    }
8947  }
8948  Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm);
8949}
8950
8951void Assembler::smlalbb(
8952    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
8953  CheckIT(cond);
8954  if (IsUsingT32()) {
8955    // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
8956    EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
8957               (rn.GetCode() << 16) | rm.GetCode());
8958    AdvanceIT();
8959    return;
8960  } else {
8961    // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
8962    if (cond.IsNotNever()) {
8963      EmitA32(0x01400080U | (cond.GetCondition() << 28) |
8964              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
8965              (rm.GetCode() << 8));
8966      return;
8967    }
8968  }
8969  Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm);
8970}
8971
8972void Assembler::smlalbt(
8973    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
8974  CheckIT(cond);
8975  if (IsUsingT32()) {
8976    // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
8977    EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
8978               (rn.GetCode() << 16) | rm.GetCode());
8979    AdvanceIT();
8980    return;
8981  } else {
8982    // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
8983    if (cond.IsNotNever()) {
8984      EmitA32(0x014000c0U | (cond.GetCondition() << 28) |
8985              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
8986              (rm.GetCode() << 8));
8987      return;
8988    }
8989  }
8990  Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm);
8991}
8992
8993void Assembler::smlald(
8994    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
8995  CheckIT(cond);
8996  if (IsUsingT32()) {
8997    // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
8998    EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
8999               (rn.GetCode() << 16) | rm.GetCode());
9000    AdvanceIT();
9001    return;
9002  } else {
9003    // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9004    if (cond.IsNotNever()) {
9005      EmitA32(0x07400010U | (cond.GetCondition() << 28) |
9006              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9007              (rm.GetCode() << 8));
9008      return;
9009    }
9010  }
9011  Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm);
9012}
9013
9014void Assembler::smlaldx(
9015    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9016  CheckIT(cond);
9017  if (IsUsingT32()) {
9018    // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9019    EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9020               (rn.GetCode() << 16) | rm.GetCode());
9021    AdvanceIT();
9022    return;
9023  } else {
9024    // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9025    if (cond.IsNotNever()) {
9026      EmitA32(0x07400030U | (cond.GetCondition() << 28) |
9027              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9028              (rm.GetCode() << 8));
9029      return;
9030    }
9031  }
9032  Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm);
9033}
9034
9035void Assembler::smlals(
9036    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9037  CheckIT(cond);
9038  if (IsUsingA32()) {
9039    // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9040    if (cond.IsNotNever()) {
9041      EmitA32(0x00f00090U | (cond.GetCondition() << 28) |
9042              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9043              (rm.GetCode() << 8));
9044      return;
9045    }
9046  }
9047  Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm);
9048}
9049
9050void Assembler::smlaltb(
9051    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9052  CheckIT(cond);
9053  if (IsUsingT32()) {
9054    // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9055    EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9056               (rn.GetCode() << 16) | rm.GetCode());
9057    AdvanceIT();
9058    return;
9059  } else {
9060    // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9061    if (cond.IsNotNever()) {
9062      EmitA32(0x014000a0U | (cond.GetCondition() << 28) |
9063              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9064              (rm.GetCode() << 8));
9065      return;
9066    }
9067  }
9068  Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm);
9069}
9070
9071void Assembler::smlaltt(
9072    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9073  CheckIT(cond);
9074  if (IsUsingT32()) {
9075    // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9076    EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9077               (rn.GetCode() << 16) | rm.GetCode());
9078    AdvanceIT();
9079    return;
9080  } else {
9081    // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9082    if (cond.IsNotNever()) {
9083      EmitA32(0x014000e0U | (cond.GetCondition() << 28) |
9084              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9085              (rm.GetCode() << 8));
9086      return;
9087    }
9088  }
9089  Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm);
9090}
9091
9092void Assembler::smlatb(
9093    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9094  CheckIT(cond);
9095  if (IsUsingT32()) {
9096    // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9097    if (!ra.Is(pc)) {
9098      EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9099                 rm.GetCode() | (ra.GetCode() << 12));
9100      AdvanceIT();
9101      return;
9102    }
9103  } else {
9104    // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9105    if (cond.IsNotNever()) {
9106      EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9107              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9108      return;
9109    }
9110  }
9111  Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra);
9112}
9113
9114void Assembler::smlatt(
9115    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9116  CheckIT(cond);
9117  if (IsUsingT32()) {
9118    // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9119    if (!ra.Is(pc)) {
9120      EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9121                 rm.GetCode() | (ra.GetCode() << 12));
9122      AdvanceIT();
9123      return;
9124    }
9125  } else {
9126    // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9127    if (cond.IsNotNever()) {
9128      EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9129              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9130      return;
9131    }
9132  }
9133  Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra);
9134}
9135
9136void Assembler::smlawb(
9137    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9138  CheckIT(cond);
9139  if (IsUsingT32()) {
9140    // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9141    if (!ra.Is(pc)) {
9142      EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9143                 rm.GetCode() | (ra.GetCode() << 12));
9144      AdvanceIT();
9145      return;
9146    }
9147  } else {
9148    // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9149    if (cond.IsNotNever()) {
9150      EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9151              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9152      return;
9153    }
9154  }
9155  Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra);
9156}
9157
9158void Assembler::smlawt(
9159    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9160  CheckIT(cond);
9161  if (IsUsingT32()) {
9162    // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9163    if (!ra.Is(pc)) {
9164      EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9165                 rm.GetCode() | (ra.GetCode() << 12));
9166      AdvanceIT();
9167      return;
9168    }
9169  } else {
9170    // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9171    if (cond.IsNotNever()) {
9172      EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9173              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9174      return;
9175    }
9176  }
9177  Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra);
9178}
9179
9180void Assembler::smlsd(
9181    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9182  CheckIT(cond);
9183  if (IsUsingT32()) {
9184    // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9185    if (!ra.Is(pc)) {
9186      EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9187                 rm.GetCode() | (ra.GetCode() << 12));
9188      AdvanceIT();
9189      return;
9190    }
9191  } else {
9192    // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9193    if (cond.IsNotNever() && !ra.Is(pc)) {
9194      EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9195              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9196      return;
9197    }
9198  }
9199  Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra);
9200}
9201
9202void Assembler::smlsdx(
9203    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9204  CheckIT(cond);
9205  if (IsUsingT32()) {
9206    // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9207    if (!ra.Is(pc)) {
9208      EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9209                 rm.GetCode() | (ra.GetCode() << 12));
9210      AdvanceIT();
9211      return;
9212    }
9213  } else {
9214    // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9215    if (cond.IsNotNever() && !ra.Is(pc)) {
9216      EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9217              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9218      return;
9219    }
9220  }
9221  Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra);
9222}
9223
9224void Assembler::smlsld(
9225    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9226  CheckIT(cond);
9227  if (IsUsingT32()) {
9228    // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9229    EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9230               (rn.GetCode() << 16) | rm.GetCode());
9231    AdvanceIT();
9232    return;
9233  } else {
9234    // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9235    if (cond.IsNotNever()) {
9236      EmitA32(0x07400050U | (cond.GetCondition() << 28) |
9237              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9238              (rm.GetCode() << 8));
9239      return;
9240    }
9241  }
9242  Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm);
9243}
9244
9245void Assembler::smlsldx(
9246    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9247  CheckIT(cond);
9248  if (IsUsingT32()) {
9249    // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9250    EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9251               (rn.GetCode() << 16) | rm.GetCode());
9252    AdvanceIT();
9253    return;
9254  } else {
9255    // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9256    if (cond.IsNotNever()) {
9257      EmitA32(0x07400070U | (cond.GetCondition() << 28) |
9258              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9259              (rm.GetCode() << 8));
9260      return;
9261    }
9262  }
9263  Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm);
9264}
9265
9266void Assembler::smmla(
9267    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9268  CheckIT(cond);
9269  if (IsUsingT32()) {
9270    // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9271    if (!ra.Is(pc)) {
9272      EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9273                 rm.GetCode() | (ra.GetCode() << 12));
9274      AdvanceIT();
9275      return;
9276    }
9277  } else {
9278    // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9279    if (cond.IsNotNever() && !ra.Is(pc)) {
9280      EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9281              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9282      return;
9283    }
9284  }
9285  Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra);
9286}
9287
9288void Assembler::smmlar(
9289    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9290  CheckIT(cond);
9291  if (IsUsingT32()) {
9292    // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9293    if (!ra.Is(pc)) {
9294      EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9295                 rm.GetCode() | (ra.GetCode() << 12));
9296      AdvanceIT();
9297      return;
9298    }
9299  } else {
9300    // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9301    if (cond.IsNotNever() && !ra.Is(pc)) {
9302      EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9303              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9304      return;
9305    }
9306  }
9307  Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra);
9308}
9309
9310void Assembler::smmls(
9311    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9312  CheckIT(cond);
9313  if (IsUsingT32()) {
9314    // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9315    EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9316               rm.GetCode() | (ra.GetCode() << 12));
9317    AdvanceIT();
9318    return;
9319  } else {
9320    // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9321    if (cond.IsNotNever()) {
9322      EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9323              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9324      return;
9325    }
9326  }
9327  Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra);
9328}
9329
9330void Assembler::smmlsr(
9331    Condition cond, Register rd, Register rn, Register rm, Register ra) {
9332  CheckIT(cond);
9333  if (IsUsingT32()) {
9334    // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9335    EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9336               rm.GetCode() | (ra.GetCode() << 12));
9337    AdvanceIT();
9338    return;
9339  } else {
9340    // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9341    if (cond.IsNotNever()) {
9342      EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9343              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9344      return;
9345    }
9346  }
9347  Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra);
9348}
9349
9350void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) {
9351  CheckIT(cond);
9352  if (IsUsingT32()) {
9353    // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9354    EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9355               rm.GetCode());
9356    AdvanceIT();
9357    return;
9358  } else {
9359    // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9360    if (cond.IsNotNever()) {
9361      EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9362              rn.GetCode() | (rm.GetCode() << 8));
9363      return;
9364    }
9365  }
9366  Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm);
9367}
9368
9369void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) {
9370  CheckIT(cond);
9371  if (IsUsingT32()) {
9372    // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9373    EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9374               rm.GetCode());
9375    AdvanceIT();
9376    return;
9377  } else {
9378    // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9379    if (cond.IsNotNever()) {
9380      EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9381              rn.GetCode() | (rm.GetCode() << 8));
9382      return;
9383    }
9384  }
9385  Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm);
9386}
9387
9388void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) {
9389  CheckIT(cond);
9390  if (IsUsingT32()) {
9391    // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9392    EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9393               rm.GetCode());
9394    AdvanceIT();
9395    return;
9396  } else {
9397    // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9398    if (cond.IsNotNever()) {
9399      EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9400              rn.GetCode() | (rm.GetCode() << 8));
9401      return;
9402    }
9403  }
9404  Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm);
9405}
9406
9407void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) {
9408  CheckIT(cond);
9409  if (IsUsingT32()) {
9410    // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9411    EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9412               rm.GetCode());
9413    AdvanceIT();
9414    return;
9415  } else {
9416    // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9417    if (cond.IsNotNever()) {
9418      EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9419              rn.GetCode() | (rm.GetCode() << 8));
9420      return;
9421    }
9422  }
9423  Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm);
9424}
9425
9426void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) {
9427  CheckIT(cond);
9428  if (IsUsingT32()) {
9429    // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9430    EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9431               rm.GetCode());
9432    AdvanceIT();
9433    return;
9434  } else {
9435    // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9436    if (cond.IsNotNever()) {
9437      EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9438              rn.GetCode() | (rm.GetCode() << 8));
9439      return;
9440    }
9441  }
9442  Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm);
9443}
9444
9445void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) {
9446  CheckIT(cond);
9447  if (IsUsingT32()) {
9448    // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9449    EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9450               rm.GetCode());
9451    AdvanceIT();
9452    return;
9453  } else {
9454    // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9455    if (cond.IsNotNever()) {
9456      EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9457              rn.GetCode() | (rm.GetCode() << 8));
9458      return;
9459    }
9460  }
9461  Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm);
9462}
9463
9464void Assembler::smull(
9465    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9466  CheckIT(cond);
9467  if (IsUsingT32()) {
9468    // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9469    EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9470               (rn.GetCode() << 16) | rm.GetCode());
9471    AdvanceIT();
9472    return;
9473  } else {
9474    // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9475    if (cond.IsNotNever()) {
9476      EmitA32(0x00c00090U | (cond.GetCondition() << 28) |
9477              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9478              (rm.GetCode() << 8));
9479      return;
9480    }
9481  }
9482  Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm);
9483}
9484
9485void Assembler::smulls(
9486    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9487  CheckIT(cond);
9488  if (IsUsingA32()) {
9489    // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9490    if (cond.IsNotNever()) {
9491      EmitA32(0x00d00090U | (cond.GetCondition() << 28) |
9492              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9493              (rm.GetCode() << 8));
9494      return;
9495    }
9496  }
9497  Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm);
9498}
9499
9500void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) {
9501  CheckIT(cond);
9502  if (IsUsingT32()) {
9503    // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9504    EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9505               rm.GetCode());
9506    AdvanceIT();
9507    return;
9508  } else {
9509    // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9510    if (cond.IsNotNever()) {
9511      EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9512              rn.GetCode() | (rm.GetCode() << 8));
9513      return;
9514    }
9515  }
9516  Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm);
9517}
9518
9519void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) {
9520  CheckIT(cond);
9521  if (IsUsingT32()) {
9522    // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9523    EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9524               rm.GetCode());
9525    AdvanceIT();
9526    return;
9527  } else {
9528    // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9529    if (cond.IsNotNever()) {
9530      EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9531              rn.GetCode() | (rm.GetCode() << 8));
9532      return;
9533    }
9534  }
9535  Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm);
9536}
9537
9538void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) {
9539  CheckIT(cond);
9540  if (IsUsingT32()) {
9541    // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9542    EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9543               rm.GetCode());
9544    AdvanceIT();
9545    return;
9546  } else {
9547    // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9548    if (cond.IsNotNever()) {
9549      EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9550              rn.GetCode() | (rm.GetCode() << 8));
9551      return;
9552    }
9553  }
9554  Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm);
9555}
9556
9557void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) {
9558  CheckIT(cond);
9559  if (IsUsingT32()) {
9560    // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9561    EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9562               rm.GetCode());
9563    AdvanceIT();
9564    return;
9565  } else {
9566    // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9567    if (cond.IsNotNever()) {
9568      EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9569              rn.GetCode() | (rm.GetCode() << 8));
9570      return;
9571    }
9572  }
9573  Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm);
9574}
9575
9576void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) {
9577  CheckIT(cond);
9578  if (IsUsingT32()) {
9579    // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9580    EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9581               rm.GetCode());
9582    AdvanceIT();
9583    return;
9584  } else {
9585    // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9586    if (cond.IsNotNever()) {
9587      EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9588              rn.GetCode() | (rm.GetCode() << 8));
9589      return;
9590    }
9591  }
9592  Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm);
9593}
9594
9595void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) {
9596  CheckIT(cond);
9597  if (IsUsingT32()) {
9598    // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9599    EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9600               rm.GetCode());
9601    AdvanceIT();
9602    return;
9603  } else {
9604    // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9605    if (cond.IsNotNever()) {
9606      EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9607              rn.GetCode() | (rm.GetCode() << 8));
9608      return;
9609    }
9610  }
9611  Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm);
9612}
9613
9614void Assembler::ssat(Condition cond,
9615                     Register rd,
9616                     uint32_t imm,
9617                     const Operand& operand) {
9618  CheckIT(cond);
9619  if (operand.IsImmediateShiftedRegister()) {
9620    Register rn = operand.GetBaseRegister();
9621    Shift shift = operand.GetShift();
9622    uint32_t amount = operand.GetShiftAmount();
9623    if (IsUsingT32()) {
9624      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
9625      if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
9626          (amount <= 31)) {
9627        uint32_t imm_ = imm - 1;
9628        EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
9629                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
9630                   ((amount & 0x1c) << 10));
9631        AdvanceIT();
9632        return;
9633      }
9634      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
9635      if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31)) {
9636        uint32_t imm_ = imm - 1;
9637        EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ |
9638                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
9639                   ((amount & 0x1c) << 10));
9640        AdvanceIT();
9641        return;
9642      }
9643    } else {
9644      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
9645      if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
9646          (amount <= 32) && cond.IsNotNever()) {
9647        uint32_t imm_ = imm - 1;
9648        uint32_t amount_ = amount % 32;
9649        EmitA32(0x06a00050U | (cond.GetCondition() << 28) |
9650                (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
9651                (amount_ << 7));
9652        return;
9653      }
9654      // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
9655      if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
9656          cond.IsNotNever()) {
9657        uint32_t imm_ = imm - 1;
9658        EmitA32(0x06a00010U | (cond.GetCondition() << 28) |
9659                (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
9660                (amount << 7));
9661        return;
9662      }
9663    }
9664  }
9665  Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand);
9666}
9667
9668void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) {
9669  CheckIT(cond);
9670  if (IsUsingT32()) {
9671    // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
9672    if ((imm >= 1) && (imm <= 16)) {
9673      uint32_t imm_ = imm - 1;
9674      EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
9675                 (rn.GetCode() << 16));
9676      AdvanceIT();
9677      return;
9678    }
9679  } else {
9680    // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
9681    if ((imm >= 1) && (imm <= 16) && cond.IsNotNever()) {
9682      uint32_t imm_ = imm - 1;
9683      EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9684              (imm_ << 16) | rn.GetCode());
9685      return;
9686    }
9687  }
9688  Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn);
9689}
9690
9691void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) {
9692  CheckIT(cond);
9693  if (IsUsingT32()) {
9694    // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9695    EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9696               rm.GetCode());
9697    AdvanceIT();
9698    return;
9699  } else {
9700    // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9701    if (cond.IsNotNever()) {
9702      EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9703              (rn.GetCode() << 16) | rm.GetCode());
9704      return;
9705    }
9706  }
9707  Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm);
9708}
9709
9710void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) {
9711  CheckIT(cond);
9712  if (IsUsingT32()) {
9713    // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9714    EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9715               rm.GetCode());
9716    AdvanceIT();
9717    return;
9718  } else {
9719    // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9720    if (cond.IsNotNever()) {
9721      EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9722              (rn.GetCode() << 16) | rm.GetCode());
9723      return;
9724    }
9725  }
9726  Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm);
9727}
9728
9729void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) {
9730  CheckIT(cond);
9731  if (IsUsingT32()) {
9732    // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9733    EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9734               rm.GetCode());
9735    AdvanceIT();
9736    return;
9737  } else {
9738    // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9739    if (cond.IsNotNever()) {
9740      EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9741              (rn.GetCode() << 16) | rm.GetCode());
9742      return;
9743    }
9744  }
9745  Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm);
9746}
9747
9748void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) {
9749  CheckIT(cond);
9750  if (operand.IsImmediateZero()) {
9751    Register rn = operand.GetBaseRegister();
9752    if (IsUsingT32()) {
9753      // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1
9754      if ((operand.GetAddrMode() == Offset) &&
9755          ((!rn.IsPC()) || AllowUnpredictable())) {
9756        EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
9757        AdvanceIT();
9758        return;
9759      }
9760    } else {
9761      // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1
9762      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
9763          ((!rn.IsPC()) || AllowUnpredictable())) {
9764        EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
9765                (rn.GetCode() << 16));
9766        return;
9767      }
9768    }
9769  }
9770  Delegate(kStl, &Assembler::stl, cond, rt, operand);
9771}
9772
9773void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) {
9774  CheckIT(cond);
9775  if (operand.IsImmediateZero()) {
9776    Register rn = operand.GetBaseRegister();
9777    if (IsUsingT32()) {
9778      // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1
9779      if ((operand.GetAddrMode() == Offset) &&
9780          ((!rn.IsPC()) || AllowUnpredictable())) {
9781        EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
9782        AdvanceIT();
9783        return;
9784      }
9785    } else {
9786      // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1
9787      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
9788          ((!rn.IsPC()) || AllowUnpredictable())) {
9789        EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
9790                (rn.GetCode() << 16));
9791        return;
9792      }
9793    }
9794  }
9795  Delegate(kStlb, &Assembler::stlb, cond, rt, operand);
9796}
9797
9798void Assembler::stlex(Condition cond,
9799                      Register rd,
9800                      Register rt,
9801                      const MemOperand& operand) {
9802  CheckIT(cond);
9803  if (operand.IsImmediateZero()) {
9804    Register rn = operand.GetBaseRegister();
9805    if (IsUsingT32()) {
9806      // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
9807      if ((operand.GetAddrMode() == Offset) &&
9808          ((!rn.IsPC()) || AllowUnpredictable())) {
9809        EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) |
9810                   (rn.GetCode() << 16));
9811        AdvanceIT();
9812        return;
9813      }
9814    } else {
9815      // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
9816      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
9817          ((!rn.IsPC()) || AllowUnpredictable())) {
9818        EmitA32(0x01800e90U | (cond.GetCondition() << 28) |
9819                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
9820        return;
9821      }
9822    }
9823  }
9824  Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand);
9825}
9826
9827void Assembler::stlexb(Condition cond,
9828                       Register rd,
9829                       Register rt,
9830                       const MemOperand& operand) {
9831  CheckIT(cond);
9832  if (operand.IsImmediateZero()) {
9833    Register rn = operand.GetBaseRegister();
9834    if (IsUsingT32()) {
9835      // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
9836      if ((operand.GetAddrMode() == Offset) &&
9837          ((!rn.IsPC()) || AllowUnpredictable())) {
9838        EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) |
9839                   (rn.GetCode() << 16));
9840        AdvanceIT();
9841        return;
9842      }
9843    } else {
9844      // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
9845      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
9846          ((!rn.IsPC()) || AllowUnpredictable())) {
9847        EmitA32(0x01c00e90U | (cond.GetCondition() << 28) |
9848                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
9849        return;
9850      }
9851    }
9852  }
9853  Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand);
9854}
9855
9856void Assembler::stlexd(Condition cond,
9857                       Register rd,
9858                       Register rt,
9859                       Register rt2,
9860                       const MemOperand& operand) {
9861  CheckIT(cond);
9862  if (operand.IsImmediateZero()) {
9863    Register rn = operand.GetBaseRegister();
9864    if (IsUsingT32()) {
9865      // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
9866      if ((operand.GetAddrMode() == Offset) &&
9867          ((!rn.IsPC()) || AllowUnpredictable())) {
9868        EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) |
9869                   (rt2.GetCode() << 8) | (rn.GetCode() << 16));
9870        AdvanceIT();
9871        return;
9872      }
9873    } else {
9874      // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
9875      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
9876          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
9877          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
9878           AllowUnpredictable())) {
9879        EmitA32(0x01a00e90U | (cond.GetCondition() << 28) |
9880                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
9881        return;
9882      }
9883    }
9884  }
9885  Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand);
9886}
9887
9888void Assembler::stlexh(Condition cond,
9889                       Register rd,
9890                       Register rt,
9891                       const MemOperand& operand) {
9892  CheckIT(cond);
9893  if (operand.IsImmediateZero()) {
9894    Register rn = operand.GetBaseRegister();
9895    if (IsUsingT32()) {
9896      // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
9897      if ((operand.GetAddrMode() == Offset) &&
9898          ((!rn.IsPC()) || AllowUnpredictable())) {
9899        EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) |
9900                   (rn.GetCode() << 16));
9901        AdvanceIT();
9902        return;
9903      }
9904    } else {
9905      // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
9906      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
9907          ((!rn.IsPC()) || AllowUnpredictable())) {
9908        EmitA32(0x01e00e90U | (cond.GetCondition() << 28) |
9909                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
9910        return;
9911      }
9912    }
9913  }
9914  Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand);
9915}
9916
9917void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) {
9918  CheckIT(cond);
9919  if (operand.IsImmediateZero()) {
9920    Register rn = operand.GetBaseRegister();
9921    if (IsUsingT32()) {
9922      // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1
9923      if ((operand.GetAddrMode() == Offset) &&
9924          ((!rn.IsPC()) || AllowUnpredictable())) {
9925        EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
9926        AdvanceIT();
9927        return;
9928      }
9929    } else {
9930      // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1
9931      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
9932          ((!rn.IsPC()) || AllowUnpredictable())) {
9933        EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
9934                (rn.GetCode() << 16));
9935        return;
9936      }
9937    }
9938  }
9939  Delegate(kStlh, &Assembler::stlh, cond, rt, operand);
9940}
9941
9942void Assembler::stm(Condition cond,
9943                    EncodingSize size,
9944                    Register rn,
9945                    WriteBack write_back,
9946                    RegisterList registers) {
9947  CheckIT(cond);
9948  if (IsUsingT32()) {
9949    // STM{<c>}{<q>} <Rn>!, <registers> ; T1
9950    if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
9951        ((registers.GetList() & ~0xff) == 0)) {
9952      EmitT32_16(0xc000 | (rn.GetCode() << 8) |
9953                 GetRegisterListEncoding(registers, 0, 8));
9954      AdvanceIT();
9955      return;
9956    }
9957    // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2
9958    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
9959      EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
9960                 (write_back.GetWriteBackUint32() << 21) |
9961                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
9962                 GetRegisterListEncoding(registers, 0, 13));
9963      AdvanceIT();
9964      return;
9965    }
9966  } else {
9967    // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1
9968    if (cond.IsNotNever()) {
9969      EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
9970              (write_back.GetWriteBackUint32() << 21) |
9971              GetRegisterListEncoding(registers, 0, 16));
9972      return;
9973    }
9974  }
9975  Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers);
9976}
9977
9978void Assembler::stmda(Condition cond,
9979                      Register rn,
9980                      WriteBack write_back,
9981                      RegisterList registers) {
9982  CheckIT(cond);
9983  if (IsUsingA32()) {
9984    // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
9985    if (cond.IsNotNever()) {
9986      EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
9987              (write_back.GetWriteBackUint32() << 21) |
9988              GetRegisterListEncoding(registers, 0, 16));
9989      return;
9990    }
9991  }
9992  Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers);
9993}
9994
9995void Assembler::stmdb(Condition cond,
9996                      EncodingSize size,
9997                      Register rn,
9998                      WriteBack write_back,
9999                      RegisterList registers) {
10000  CheckIT(cond);
10001  if (IsUsingT32()) {
10002    // STMDB{<c>}{<q>} SP!, <registers> ; T1
10003    if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
10004        ((registers.GetList() & ~0x40ff) == 0)) {
10005      EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
10006                 GetRegisterListEncoding(registers, 0, 8));
10007      AdvanceIT();
10008      return;
10009    }
10010    // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
10011    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10012      EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
10013                 (write_back.GetWriteBackUint32() << 21) |
10014                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10015                 GetRegisterListEncoding(registers, 0, 13));
10016      AdvanceIT();
10017      return;
10018    }
10019  } else {
10020    // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
10021    if (cond.IsNotNever()) {
10022      EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10023              (write_back.GetWriteBackUint32() << 21) |
10024              GetRegisterListEncoding(registers, 0, 16));
10025      return;
10026    }
10027  }
10028  Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers);
10029}
10030
10031void Assembler::stmea(Condition cond,
10032                      EncodingSize size,
10033                      Register rn,
10034                      WriteBack write_back,
10035                      RegisterList registers) {
10036  CheckIT(cond);
10037  if (IsUsingT32()) {
10038    // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1
10039    if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
10040        ((registers.GetList() & ~0xff) == 0)) {
10041      EmitT32_16(0xc000 | (rn.GetCode() << 8) |
10042                 GetRegisterListEncoding(registers, 0, 8));
10043      AdvanceIT();
10044      return;
10045    }
10046    // STMEA{<c>}.W <Rn>{!}, <registers> ; T2
10047    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10048      EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
10049                 (write_back.GetWriteBackUint32() << 21) |
10050                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10051                 GetRegisterListEncoding(registers, 0, 13));
10052      AdvanceIT();
10053      return;
10054    }
10055    // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2
10056    if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10057      EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
10058                 (write_back.GetWriteBackUint32() << 21) |
10059                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10060                 GetRegisterListEncoding(registers, 0, 13));
10061      AdvanceIT();
10062      return;
10063    }
10064  } else {
10065    // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
10066    if (cond.IsNotNever()) {
10067      EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10068              (write_back.GetWriteBackUint32() << 21) |
10069              GetRegisterListEncoding(registers, 0, 16));
10070      return;
10071    }
10072  }
10073  Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers);
10074}
10075
10076void Assembler::stmed(Condition cond,
10077                      Register rn,
10078                      WriteBack write_back,
10079                      RegisterList registers) {
10080  CheckIT(cond);
10081  if (IsUsingA32()) {
10082    // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
10083    if (cond.IsNotNever()) {
10084      EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10085              (write_back.GetWriteBackUint32() << 21) |
10086              GetRegisterListEncoding(registers, 0, 16));
10087      return;
10088    }
10089  }
10090  Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers);
10091}
10092
10093void Assembler::stmfa(Condition cond,
10094                      Register rn,
10095                      WriteBack write_back,
10096                      RegisterList registers) {
10097  CheckIT(cond);
10098  if (IsUsingA32()) {
10099    // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
10100    if (cond.IsNotNever()) {
10101      EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10102              (write_back.GetWriteBackUint32() << 21) |
10103              GetRegisterListEncoding(registers, 0, 16));
10104      return;
10105    }
10106  }
10107  Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers);
10108}
10109
10110void Assembler::stmfd(Condition cond,
10111                      Register rn,
10112                      WriteBack write_back,
10113                      RegisterList registers) {
10114  CheckIT(cond);
10115  if (IsUsingT32()) {
10116    // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
10117    if (((registers.GetList() & ~0x5fff) == 0)) {
10118      EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
10119                 (write_back.GetWriteBackUint32() << 21) |
10120                 (GetRegisterListEncoding(registers, 14, 1) << 14) |
10121                 GetRegisterListEncoding(registers, 0, 13));
10122      AdvanceIT();
10123      return;
10124    }
10125  } else {
10126    // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
10127    if (cond.IsNotNever()) {
10128      EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10129              (write_back.GetWriteBackUint32() << 21) |
10130              GetRegisterListEncoding(registers, 0, 16));
10131      return;
10132    }
10133  }
10134  Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers);
10135}
10136
10137void Assembler::stmib(Condition cond,
10138                      Register rn,
10139                      WriteBack write_back,
10140                      RegisterList registers) {
10141  CheckIT(cond);
10142  if (IsUsingA32()) {
10143    // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
10144    if (cond.IsNotNever()) {
10145      EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10146              (write_back.GetWriteBackUint32() << 21) |
10147              GetRegisterListEncoding(registers, 0, 16));
10148      return;
10149    }
10150  }
10151  Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers);
10152}
10153
10154void Assembler::str(Condition cond,
10155                    EncodingSize size,
10156                    Register rt,
10157                    const MemOperand& operand) {
10158  CheckIT(cond);
10159  if (operand.IsImmediate()) {
10160    Register rn = operand.GetBaseRegister();
10161    int32_t offset = operand.GetOffsetImmediate();
10162    if (IsUsingT32()) {
10163      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10164      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10165          (offset <= 124) && ((offset % 4) == 0) &&
10166          (operand.GetAddrMode() == Offset)) {
10167        int32_t offset_ = offset >> 2;
10168        EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) |
10169                   ((offset_ & 0x1f) << 6));
10170        AdvanceIT();
10171        return;
10172      }
10173      // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
10174      if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
10175          ((offset % 4) == 0) && rn.Is(sp) &&
10176          (operand.GetAddrMode() == Offset)) {
10177        int32_t offset_ = offset >> 2;
10178        EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff));
10179        AdvanceIT();
10180        return;
10181      }
10182      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
10183      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10184          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
10185        EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10186                   (offset & 0xfff));
10187        AdvanceIT();
10188        return;
10189      }
10190      // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
10191      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10192          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
10193        EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10194                   (-offset & 0xff));
10195        AdvanceIT();
10196        return;
10197      }
10198      // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
10199      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10200          (operand.GetAddrMode() == PostIndex) &&
10201          ((rn.GetCode() & 0xf) != 0xf)) {
10202        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10203        uint32_t offset_ = abs(offset);
10204        EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10205                   offset_ | (sign << 9));
10206        AdvanceIT();
10207        return;
10208      }
10209      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
10210      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10211          (operand.GetAddrMode() == PreIndex) &&
10212          ((rn.GetCode() & 0xf) != 0xf)) {
10213        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10214        uint32_t offset_ = abs(offset);
10215        EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10216                   offset_ | (sign << 9));
10217        AdvanceIT();
10218        return;
10219      }
10220    } else {
10221      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10222      if ((offset >= -4095) && (offset <= 4095) &&
10223          (operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
10224        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10225        uint32_t offset_ = abs(offset);
10226        EmitA32(0x05000000U | (cond.GetCondition() << 28) |
10227                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10228                (sign << 23));
10229        return;
10230      }
10231      // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10232      if ((offset >= -4095) && (offset <= 4095) &&
10233          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever()) {
10234        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10235        uint32_t offset_ = abs(offset);
10236        EmitA32(0x04000000U | (cond.GetCondition() << 28) |
10237                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10238                (sign << 23));
10239        return;
10240      }
10241      // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10242      if ((offset >= -4095) && (offset <= 4095) &&
10243          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever()) {
10244        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10245        uint32_t offset_ = abs(offset);
10246        EmitA32(0x05200000U | (cond.GetCondition() << 28) |
10247                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10248                (sign << 23));
10249        return;
10250      }
10251    }
10252  }
10253  if (operand.IsPlainRegister()) {
10254    Register rn = operand.GetBaseRegister();
10255    Sign sign = operand.GetSign();
10256    Register rm = operand.GetOffsetRegister();
10257    if (IsUsingT32()) {
10258      // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
10259      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
10260          sign.IsPlus() && (operand.GetAddrMode() == Offset)) {
10261        EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) |
10262                   (rm.GetCode() << 6));
10263        AdvanceIT();
10264        return;
10265      }
10266    }
10267  }
10268  if (operand.IsShiftedRegister()) {
10269    Register rn = operand.GetBaseRegister();
10270    Sign sign = operand.GetSign();
10271    Register rm = operand.GetOffsetRegister();
10272    Shift shift = operand.GetShift();
10273    uint32_t amount = operand.GetShiftAmount();
10274    if (IsUsingT32()) {
10275      // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
10276      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
10277          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
10278        EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10279                   rm.GetCode() | (amount << 4));
10280        AdvanceIT();
10281        return;
10282      }
10283    } else {
10284      // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
10285      if (operand.IsShiftValid() && (operand.GetAddrMode() == Offset) &&
10286          cond.IsNotNever()) {
10287        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10288        uint32_t shift_ = TypeEncodingValue(shift);
10289        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10290        EmitA32(0x07000000U | (cond.GetCondition() << 28) |
10291                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10292                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10293        return;
10294      }
10295      // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
10296      if (operand.IsShiftValid() && (operand.GetAddrMode() == PostIndex) &&
10297          cond.IsNotNever()) {
10298        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10299        uint32_t shift_ = TypeEncodingValue(shift);
10300        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10301        EmitA32(0x06000000U | (cond.GetCondition() << 28) |
10302                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10303                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10304        return;
10305      }
10306      // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
10307      if (operand.IsShiftValid() && (operand.GetAddrMode() == PreIndex) &&
10308          cond.IsNotNever()) {
10309        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10310        uint32_t shift_ = TypeEncodingValue(shift);
10311        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10312        EmitA32(0x07200000U | (cond.GetCondition() << 28) |
10313                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10314                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10315        return;
10316      }
10317    }
10318  }
10319  Delegate(kStr, &Assembler::str, cond, size, rt, operand);
10320}
10321
10322void Assembler::strb(Condition cond,
10323                     EncodingSize size,
10324                     Register rt,
10325                     const MemOperand& operand) {
10326  CheckIT(cond);
10327  if (operand.IsImmediate()) {
10328    Register rn = operand.GetBaseRegister();
10329    int32_t offset = operand.GetOffsetImmediate();
10330    if (IsUsingT32()) {
10331      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10332      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10333          (offset <= 31) && (operand.GetAddrMode() == Offset)) {
10334        EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) |
10335                   ((offset & 0x1f) << 6));
10336        AdvanceIT();
10337        return;
10338      }
10339      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
10340      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10341          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
10342        EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10343                   (offset & 0xfff));
10344        AdvanceIT();
10345        return;
10346      }
10347      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
10348      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10349          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
10350        EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10351                   (-offset & 0xff));
10352        AdvanceIT();
10353        return;
10354      }
10355      // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
10356      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10357          (operand.GetAddrMode() == PostIndex) &&
10358          ((rn.GetCode() & 0xf) != 0xf)) {
10359        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10360        uint32_t offset_ = abs(offset);
10361        EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10362                   offset_ | (sign << 9));
10363        AdvanceIT();
10364        return;
10365      }
10366      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
10367      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10368          (operand.GetAddrMode() == PreIndex) &&
10369          ((rn.GetCode() & 0xf) != 0xf)) {
10370        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10371        uint32_t offset_ = abs(offset);
10372        EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10373                   offset_ | (sign << 9));
10374        AdvanceIT();
10375        return;
10376      }
10377    } else {
10378      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10379      if ((offset >= -4095) && (offset <= 4095) &&
10380          (operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
10381        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10382        uint32_t offset_ = abs(offset);
10383        EmitA32(0x05400000U | (cond.GetCondition() << 28) |
10384                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10385                (sign << 23));
10386        return;
10387      }
10388      // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10389      if ((offset >= -4095) && (offset <= 4095) &&
10390          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever()) {
10391        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10392        uint32_t offset_ = abs(offset);
10393        EmitA32(0x04400000U | (cond.GetCondition() << 28) |
10394                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10395                (sign << 23));
10396        return;
10397      }
10398      // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10399      if ((offset >= -4095) && (offset <= 4095) &&
10400          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever()) {
10401        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10402        uint32_t offset_ = abs(offset);
10403        EmitA32(0x05600000U | (cond.GetCondition() << 28) |
10404                (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10405                (sign << 23));
10406        return;
10407      }
10408    }
10409  }
10410  if (operand.IsPlainRegister()) {
10411    Register rn = operand.GetBaseRegister();
10412    Sign sign = operand.GetSign();
10413    Register rm = operand.GetOffsetRegister();
10414    if (IsUsingT32()) {
10415      // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
10416      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
10417          sign.IsPlus() && (operand.GetAddrMode() == Offset)) {
10418        EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) |
10419                   (rm.GetCode() << 6));
10420        AdvanceIT();
10421        return;
10422      }
10423    }
10424  }
10425  if (operand.IsShiftedRegister()) {
10426    Register rn = operand.GetBaseRegister();
10427    Sign sign = operand.GetSign();
10428    Register rm = operand.GetOffsetRegister();
10429    Shift shift = operand.GetShift();
10430    uint32_t amount = operand.GetShiftAmount();
10431    if (IsUsingT32()) {
10432      // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
10433      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
10434          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
10435        EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10436                   rm.GetCode() | (amount << 4));
10437        AdvanceIT();
10438        return;
10439      }
10440    } else {
10441      // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
10442      if (operand.IsShiftValid() && (operand.GetAddrMode() == Offset) &&
10443          cond.IsNotNever()) {
10444        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10445        uint32_t shift_ = TypeEncodingValue(shift);
10446        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10447        EmitA32(0x07400000U | (cond.GetCondition() << 28) |
10448                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10449                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10450        return;
10451      }
10452      // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
10453      if (operand.IsShiftValid() && (operand.GetAddrMode() == PostIndex) &&
10454          cond.IsNotNever()) {
10455        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10456        uint32_t shift_ = TypeEncodingValue(shift);
10457        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10458        EmitA32(0x06400000U | (cond.GetCondition() << 28) |
10459                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10460                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10461        return;
10462      }
10463      // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
10464      if (operand.IsShiftValid() && (operand.GetAddrMode() == PreIndex) &&
10465          cond.IsNotNever()) {
10466        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10467        uint32_t shift_ = TypeEncodingValue(shift);
10468        uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10469        EmitA32(0x07600000U | (cond.GetCondition() << 28) |
10470                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10471                (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10472        return;
10473      }
10474    }
10475  }
10476  Delegate(kStrb, &Assembler::strb, cond, size, rt, operand);
10477}
10478
10479void Assembler::strd(Condition cond,
10480                     Register rt,
10481                     Register rt2,
10482                     const MemOperand& operand) {
10483  CheckIT(cond);
10484  if (operand.IsImmediate()) {
10485    Register rn = operand.GetBaseRegister();
10486    int32_t offset = operand.GetOffsetImmediate();
10487    if (IsUsingT32()) {
10488      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
10489      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10490          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
10491        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10492        uint32_t offset_ = abs(offset) >> 2;
10493        EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10494                   (rn.GetCode() << 16) | offset_ | (sign << 23));
10495        AdvanceIT();
10496        return;
10497      }
10498      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
10499      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10500          (operand.GetAddrMode() == PostIndex) &&
10501          ((rn.GetCode() & 0xf) != 0xf)) {
10502        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10503        uint32_t offset_ = abs(offset) >> 2;
10504        EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10505                   (rn.GetCode() << 16) | offset_ | (sign << 23));
10506        AdvanceIT();
10507        return;
10508      }
10509      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
10510      if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10511          (operand.GetAddrMode() == PreIndex) &&
10512          ((rn.GetCode() & 0xf) != 0xf)) {
10513        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10514        uint32_t offset_ = abs(offset) >> 2;
10515        EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10516                   (rn.GetCode() << 16) | offset_ | (sign << 23));
10517        AdvanceIT();
10518        return;
10519      }
10520    } else {
10521      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
10522      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10523          (offset >= -255) && (offset <= 255) &&
10524          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
10525          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10526        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10527        uint32_t offset_ = abs(offset);
10528        EmitA32(0x014000f0U | (cond.GetCondition() << 28) |
10529                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10530                ((offset_ & 0xf0) << 4) | (sign << 23));
10531        return;
10532      }
10533      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
10534      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10535          (offset >= -255) && (offset <= 255) &&
10536          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever() &&
10537          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10538        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10539        uint32_t offset_ = abs(offset);
10540        EmitA32(0x004000f0U | (cond.GetCondition() << 28) |
10541                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10542                ((offset_ & 0xf0) << 4) | (sign << 23));
10543        return;
10544      }
10545      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
10546      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10547          (offset >= -255) && (offset <= 255) &&
10548          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever() &&
10549          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10550        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10551        uint32_t offset_ = abs(offset);
10552        EmitA32(0x016000f0U | (cond.GetCondition() << 28) |
10553                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10554                ((offset_ & 0xf0) << 4) | (sign << 23));
10555        return;
10556      }
10557    }
10558  }
10559  if (operand.IsPlainRegister()) {
10560    Register rn = operand.GetBaseRegister();
10561    Sign sign = operand.GetSign();
10562    Register rm = operand.GetOffsetRegister();
10563    if (IsUsingA32()) {
10564      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
10565      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10566          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
10567          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10568        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10569        EmitA32(0x010000f0U | (cond.GetCondition() << 28) |
10570                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10571                (sign_ << 23));
10572        return;
10573      }
10574      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
10575      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10576          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever() &&
10577          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10578        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10579        EmitA32(0x000000f0U | (cond.GetCondition() << 28) |
10580                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10581                (sign_ << 23));
10582        return;
10583      }
10584      // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
10585      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10586          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever() &&
10587          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10588        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10589        EmitA32(0x012000f0U | (cond.GetCondition() << 28) |
10590                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10591                (sign_ << 23));
10592        return;
10593      }
10594    }
10595  }
10596  Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand);
10597}
10598
10599void Assembler::strex(Condition cond,
10600                      Register rd,
10601                      Register rt,
10602                      const MemOperand& operand) {
10603  CheckIT(cond);
10604  if (operand.IsImmediate()) {
10605    Register rn = operand.GetBaseRegister();
10606    int32_t offset = operand.GetOffsetImmediate();
10607    if (IsUsingT32()) {
10608      // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1
10609      if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
10610          (operand.GetAddrMode() == Offset)) {
10611        int32_t offset_ = offset >> 2;
10612        EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) |
10613                   (rn.GetCode() << 16) | (offset_ & 0xff));
10614        AdvanceIT();
10615        return;
10616      }
10617    } else {
10618      // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1
10619      if ((offset == 0) && (operand.GetAddrMode() == Offset) &&
10620          cond.IsNotNever()) {
10621        EmitA32(0x01800f90U | (cond.GetCondition() << 28) |
10622                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10623        return;
10624      }
10625    }
10626  }
10627  Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand);
10628}
10629
10630void Assembler::strexb(Condition cond,
10631                       Register rd,
10632                       Register rt,
10633                       const MemOperand& operand) {
10634  CheckIT(cond);
10635  if (operand.IsImmediateZero()) {
10636    Register rn = operand.GetBaseRegister();
10637    if (IsUsingT32()) {
10638      // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10639      if ((operand.GetAddrMode() == Offset) &&
10640          ((!rn.IsPC()) || AllowUnpredictable())) {
10641        EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) |
10642                   (rn.GetCode() << 16));
10643        AdvanceIT();
10644        return;
10645      }
10646    } else {
10647      // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10648      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
10649          ((!rn.IsPC()) || AllowUnpredictable())) {
10650        EmitA32(0x01c00f90U | (cond.GetCondition() << 28) |
10651                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10652        return;
10653      }
10654    }
10655  }
10656  Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand);
10657}
10658
10659void Assembler::strexd(Condition cond,
10660                       Register rd,
10661                       Register rt,
10662                       Register rt2,
10663                       const MemOperand& operand) {
10664  CheckIT(cond);
10665  if (operand.IsImmediateZero()) {
10666    Register rn = operand.GetBaseRegister();
10667    if (IsUsingT32()) {
10668      // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
10669      if ((operand.GetAddrMode() == Offset) &&
10670          ((!rn.IsPC()) || AllowUnpredictable())) {
10671        EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) |
10672                   (rt2.GetCode() << 8) | (rn.GetCode() << 16));
10673        AdvanceIT();
10674        return;
10675      }
10676    } else {
10677      // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
10678      if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10679          (operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
10680          ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
10681           AllowUnpredictable())) {
10682        EmitA32(0x01a00f90U | (cond.GetCondition() << 28) |
10683                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10684        return;
10685      }
10686    }
10687  }
10688  Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand);
10689}
10690
10691void Assembler::strexh(Condition cond,
10692                       Register rd,
10693                       Register rt,
10694                       const MemOperand& operand) {
10695  CheckIT(cond);
10696  if (operand.IsImmediateZero()) {
10697    Register rn = operand.GetBaseRegister();
10698    if (IsUsingT32()) {
10699      // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10700      if ((operand.GetAddrMode() == Offset) &&
10701          ((!rn.IsPC()) || AllowUnpredictable())) {
10702        EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) |
10703                   (rn.GetCode() << 16));
10704        AdvanceIT();
10705        return;
10706      }
10707    } else {
10708      // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10709      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever() &&
10710          ((!rn.IsPC()) || AllowUnpredictable())) {
10711        EmitA32(0x01e00f90U | (cond.GetCondition() << 28) |
10712                (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10713        return;
10714      }
10715    }
10716  }
10717  Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand);
10718}
10719
10720void Assembler::strh(Condition cond,
10721                     EncodingSize size,
10722                     Register rt,
10723                     const MemOperand& operand) {
10724  CheckIT(cond);
10725  if (operand.IsImmediate()) {
10726    Register rn = operand.GetBaseRegister();
10727    int32_t offset = operand.GetOffsetImmediate();
10728    if (IsUsingT32()) {
10729      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10730      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10731          (offset <= 62) && ((offset % 2) == 0) &&
10732          (operand.GetAddrMode() == Offset)) {
10733        int32_t offset_ = offset >> 1;
10734        EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) |
10735                   ((offset_ & 0x1f) << 6));
10736        AdvanceIT();
10737        return;
10738      }
10739      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
10740      if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10741          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
10742        EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10743                   (offset & 0xfff));
10744        AdvanceIT();
10745        return;
10746      }
10747      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
10748      if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10749          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
10750        EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10751                   (-offset & 0xff));
10752        AdvanceIT();
10753        return;
10754      }
10755      // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
10756      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10757          (operand.GetAddrMode() == PostIndex) &&
10758          ((rn.GetCode() & 0xf) != 0xf)) {
10759        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10760        uint32_t offset_ = abs(offset);
10761        EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10762                   offset_ | (sign << 9));
10763        AdvanceIT();
10764        return;
10765      }
10766      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
10767      if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10768          (operand.GetAddrMode() == PreIndex) &&
10769          ((rn.GetCode() & 0xf) != 0xf)) {
10770        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10771        uint32_t offset_ = abs(offset);
10772        EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10773                   offset_ | (sign << 9));
10774        AdvanceIT();
10775        return;
10776      }
10777    } else {
10778      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10779      if ((offset >= -255) && (offset <= 255) &&
10780          (operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
10781        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10782        uint32_t offset_ = abs(offset);
10783        EmitA32(0x014000b0U | (cond.GetCondition() << 28) |
10784                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10785                ((offset_ & 0xf0) << 4) | (sign << 23));
10786        return;
10787      }
10788      // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10789      if ((offset >= -255) && (offset <= 255) &&
10790          (operand.GetAddrMode() == PostIndex) && cond.IsNotNever()) {
10791        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10792        uint32_t offset_ = abs(offset);
10793        EmitA32(0x004000b0U | (cond.GetCondition() << 28) |
10794                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10795                ((offset_ & 0xf0) << 4) | (sign << 23));
10796        return;
10797      }
10798      // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10799      if ((offset >= -255) && (offset <= 255) &&
10800          (operand.GetAddrMode() == PreIndex) && cond.IsNotNever()) {
10801        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10802        uint32_t offset_ = abs(offset);
10803        EmitA32(0x016000b0U | (cond.GetCondition() << 28) |
10804                (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10805                ((offset_ & 0xf0) << 4) | (sign << 23));
10806        return;
10807      }
10808    }
10809  }
10810  if (operand.IsPlainRegister()) {
10811    Register rn = operand.GetBaseRegister();
10812    Sign sign = operand.GetSign();
10813    Register rm = operand.GetOffsetRegister();
10814    if (IsUsingT32()) {
10815      // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
10816      if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
10817          sign.IsPlus() && (operand.GetAddrMode() == Offset)) {
10818        EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) |
10819                   (rm.GetCode() << 6));
10820        AdvanceIT();
10821        return;
10822      }
10823    } else {
10824      // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
10825      if ((operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
10826        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10827        EmitA32(0x010000b0U | (cond.GetCondition() << 28) |
10828                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10829                (sign_ << 23));
10830        return;
10831      }
10832      // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
10833      if ((operand.GetAddrMode() == PostIndex) && cond.IsNotNever()) {
10834        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10835        EmitA32(0x000000b0U | (cond.GetCondition() << 28) |
10836                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10837                (sign_ << 23));
10838        return;
10839      }
10840      // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
10841      if ((operand.GetAddrMode() == PreIndex) && cond.IsNotNever()) {
10842        uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10843        EmitA32(0x012000b0U | (cond.GetCondition() << 28) |
10844                (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10845                (sign_ << 23));
10846        return;
10847      }
10848    }
10849  }
10850  if (operand.IsShiftedRegister()) {
10851    Register rn = operand.GetBaseRegister();
10852    Sign sign = operand.GetSign();
10853    Register rm = operand.GetOffsetRegister();
10854    Shift shift = operand.GetShift();
10855    uint32_t amount = operand.GetShiftAmount();
10856    if (IsUsingT32()) {
10857      // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
10858      if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
10859          (operand.GetAddrMode() == Offset) && ((rn.GetCode() & 0xf) != 0xf)) {
10860        EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10861                   rm.GetCode() | (amount << 4));
10862        AdvanceIT();
10863        return;
10864      }
10865    }
10866  }
10867  Delegate(kStrh, &Assembler::strh, cond, size, rt, operand);
10868}
10869
10870void Assembler::sub(Condition cond,
10871                    EncodingSize size,
10872                    Register rd,
10873                    Register rn,
10874                    const Operand& operand) {
10875  CheckIT(cond);
10876  if (operand.IsImmediate()) {
10877    uint32_t imm = operand.GetImmediate();
10878    if (IsUsingT32()) {
10879      ImmediateT32 immediate_t32(imm);
10880      // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
10881      if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
10882          (imm <= 7)) {
10883        EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
10884        AdvanceIT();
10885        return;
10886      }
10887      // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
10888      if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
10889          (imm <= 255)) {
10890        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
10891        AdvanceIT();
10892        return;
10893      }
10894      // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1
10895      if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
10896          ((imm % 4) == 0)) {
10897        uint32_t imm_ = imm >> 2;
10898        EmitT32_16(0xb080 | imm_);
10899        AdvanceIT();
10900        return;
10901      }
10902      // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2
10903      if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095)) {
10904        EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) |
10905                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
10906        AdvanceIT();
10907        return;
10908      }
10909      // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
10910      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp)) {
10911        EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10912                   (immediate_t32.GetEncodingValue() & 0xff) |
10913                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
10914                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
10915        AdvanceIT();
10916        return;
10917      }
10918      // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
10919      if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
10920        EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10921                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
10922        AdvanceIT();
10923        return;
10924      }
10925      // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
10926      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid()) {
10927        EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) |
10928                   (immediate_t32.GetEncodingValue() & 0xff) |
10929                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
10930                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
10931        AdvanceIT();
10932        return;
10933      }
10934      // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
10935      if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095)) {
10936        EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
10937                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
10938        AdvanceIT();
10939        return;
10940      }
10941    } else {
10942      ImmediateA32 immediate_a32(imm);
10943      // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2
10944      if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
10945        EmitA32(0x024f0000U | (cond.GetCondition() << 28) |
10946                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
10947        return;
10948      }
10949      // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
10950      if (immediate_a32.IsValid() && cond.IsNotNever() &&
10951          ((rn.GetCode() & 0xd) != 0xd)) {
10952        EmitA32(0x02400000U | (cond.GetCondition() << 28) |
10953                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
10954                immediate_a32.GetEncodingValue());
10955        return;
10956      }
10957      // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
10958      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
10959        EmitA32(0x024d0000U | (cond.GetCondition() << 28) |
10960                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
10961        return;
10962      }
10963    }
10964  }
10965  if (operand.IsImmediateShiftedRegister()) {
10966    Register rm = operand.GetBaseRegister();
10967    if (operand.IsPlainRegister()) {
10968      if (IsUsingT32()) {
10969        // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
10970        if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
10971            rm.IsLow()) {
10972          EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
10973                     (rm.GetCode() << 6));
10974          AdvanceIT();
10975          return;
10976        }
10977        // SUB{<c>} {<Rd>}, SP, <Rm> ; T1
10978        if (rn.Is(sp)) {
10979          EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode());
10980          AdvanceIT();
10981          return;
10982        }
10983      }
10984    }
10985    Shift shift = operand.GetShift();
10986    uint32_t amount = operand.GetShiftAmount();
10987    if (IsUsingT32()) {
10988      // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
10989      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp)) {
10990        uint32_t amount_ = amount % 32;
10991        EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10992                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
10993                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
10994        AdvanceIT();
10995        return;
10996      }
10997      // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
10998      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount)) {
10999        uint32_t amount_ = amount % 32;
11000        EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() |
11001                   (operand.GetTypeEncodingValue() << 4) |
11002                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11003        AdvanceIT();
11004        return;
11005      }
11006    } else {
11007      // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
11008      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
11009        uint32_t amount_ = amount % 32;
11010        EmitA32(0x00400000U | (cond.GetCondition() << 28) |
11011                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11012                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11013        return;
11014      }
11015      // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
11016      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
11017        uint32_t amount_ = amount % 32;
11018        EmitA32(0x004d0000U | (cond.GetCondition() << 28) |
11019                (rd.GetCode() << 12) | rm.GetCode() |
11020                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11021        return;
11022      }
11023    }
11024  }
11025  if (operand.IsRegisterShiftedRegister()) {
11026    Register rm = operand.GetBaseRegister();
11027    Shift shift = operand.GetShift();
11028    if (IsUsingA32()) {
11029      // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
11030      if (cond.IsNotNever()) {
11031        EmitA32(0x00400010U | (cond.GetCondition() << 28) |
11032                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11033                (shift.GetType() << 5) |
11034                (operand.GetShiftRegister().GetCode() << 8));
11035        return;
11036      }
11037    }
11038  }
11039  Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand);
11040}
11041
11042void Assembler::sub(Condition cond, Register rd, const Operand& operand) {
11043  CheckIT(cond);
11044  if (operand.IsImmediate()) {
11045    uint32_t imm = operand.GetImmediate();
11046    if (IsUsingT32()) {
11047      // SUB<c>{<q>} <Rdn>, #<imm8> ; T2
11048      if (InITBlock() && rd.IsLow() && (imm <= 255)) {
11049        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11050        AdvanceIT();
11051        return;
11052      }
11053    }
11054  }
11055  Delegate(kSub, &Assembler::sub, cond, rd, operand);
11056}
11057
11058void Assembler::subs(Condition cond,
11059                     EncodingSize size,
11060                     Register rd,
11061                     Register rn,
11062                     const Operand& operand) {
11063  CheckIT(cond);
11064  if (operand.IsImmediate()) {
11065    uint32_t imm = operand.GetImmediate();
11066    if (IsUsingT32()) {
11067      ImmediateT32 immediate_t32(imm);
11068      // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1
11069      if (OutsideITBlock() && !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      // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
11076      if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
11077          (imm <= 255)) {
11078        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11079        AdvanceIT();
11080        return;
11081      }
11082      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
11083      if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
11084          !rd.Is(pc)) {
11085        EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11086                   (immediate_t32.GetEncodingValue() & 0xff) |
11087                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11088                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11089        AdvanceIT();
11090        return;
11091      }
11092      // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5
11093      if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255)) {
11094        EmitT32_32(0xf3de8f00U | imm);
11095        AdvanceIT();
11096        return;
11097      }
11098      // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
11099      if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
11100          !rd.Is(pc)) {
11101        EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) |
11102                   (immediate_t32.GetEncodingValue() & 0xff) |
11103                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11104                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11105        AdvanceIT();
11106        return;
11107      }
11108    } else {
11109      ImmediateA32 immediate_a32(imm);
11110      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
11111      if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
11112        EmitA32(0x02500000U | (cond.GetCondition() << 28) |
11113                (rd.GetCode() << 12) | (rn.GetCode() << 16) |
11114                immediate_a32.GetEncodingValue());
11115        return;
11116      }
11117      // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
11118      if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
11119        EmitA32(0x025d0000U | (cond.GetCondition() << 28) |
11120                (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
11121        return;
11122      }
11123    }
11124  }
11125  if (operand.IsImmediateShiftedRegister()) {
11126    Register rm = operand.GetBaseRegister();
11127    if (operand.IsPlainRegister()) {
11128      if (IsUsingT32()) {
11129        // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11130        if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11131            rm.IsLow()) {
11132          EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
11133                     (rm.GetCode() << 6));
11134          AdvanceIT();
11135          return;
11136        }
11137      }
11138    }
11139    Shift shift = operand.GetShift();
11140    uint32_t amount = operand.GetShiftAmount();
11141    if (IsUsingT32()) {
11142      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
11143      if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
11144          !rd.Is(pc)) {
11145        uint32_t amount_ = amount % 32;
11146        EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11147                   rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
11148                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11149        AdvanceIT();
11150        return;
11151      }
11152      // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
11153      if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
11154          !rd.Is(pc)) {
11155        uint32_t amount_ = amount % 32;
11156        EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() |
11157                   (operand.GetTypeEncodingValue() << 4) |
11158                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11159        AdvanceIT();
11160        return;
11161      }
11162    } else {
11163      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
11164      if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
11165        uint32_t amount_ = amount % 32;
11166        EmitA32(0x00500000U | (cond.GetCondition() << 28) |
11167                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11168                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11169        return;
11170      }
11171      // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
11172      if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
11173        uint32_t amount_ = amount % 32;
11174        EmitA32(0x005d0000U | (cond.GetCondition() << 28) |
11175                (rd.GetCode() << 12) | rm.GetCode() |
11176                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11177        return;
11178      }
11179    }
11180  }
11181  if (operand.IsRegisterShiftedRegister()) {
11182    Register rm = operand.GetBaseRegister();
11183    Shift shift = operand.GetShift();
11184    if (IsUsingA32()) {
11185      // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
11186      if (cond.IsNotNever()) {
11187        EmitA32(0x00500010U | (cond.GetCondition() << 28) |
11188                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11189                (shift.GetType() << 5) |
11190                (operand.GetShiftRegister().GetCode() << 8));
11191        return;
11192      }
11193    }
11194  }
11195  Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand);
11196}
11197
11198void Assembler::subs(Register rd, const Operand& operand) {
11199  CheckIT(al);
11200  if (operand.IsImmediate()) {
11201    uint32_t imm = operand.GetImmediate();
11202    if (IsUsingT32()) {
11203      // SUBS{<q>} <Rdn>, #<imm8> ; T2
11204      if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
11205        EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11206        AdvanceIT();
11207        return;
11208      }
11209    }
11210  }
11211  Delegate(kSubs, &Assembler::subs, rd, operand);
11212}
11213
11214void Assembler::subw(Condition cond,
11215                     Register rd,
11216                     Register rn,
11217                     const Operand& operand) {
11218  CheckIT(cond);
11219  if (operand.IsImmediate()) {
11220    uint32_t imm = operand.GetImmediate();
11221    if (IsUsingT32()) {
11222      // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
11223      if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
11224        EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11225                   (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11226        AdvanceIT();
11227        return;
11228      }
11229      // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
11230      if (rn.Is(sp) && (imm <= 4095)) {
11231        EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
11232                   ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11233        AdvanceIT();
11234        return;
11235      }
11236    }
11237  }
11238  Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand);
11239}
11240
11241void Assembler::svc(Condition cond, uint32_t imm) {
11242  CheckIT(cond);
11243  if (IsUsingT32()) {
11244    // SVC{<c>}{<q>} {#}<imm> ; T1
11245    if ((imm <= 255)) {
11246      EmitT32_16(0xdf00 | imm);
11247      AdvanceIT();
11248      return;
11249    }
11250  } else {
11251    // SVC{<c>}{<q>} {#}<imm> ; A1
11252    if ((imm <= 16777215) && cond.IsNotNever()) {
11253      EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm);
11254      return;
11255    }
11256  }
11257  Delegate(kSvc, &Assembler::svc, cond, imm);
11258}
11259
11260void Assembler::sxtab(Condition cond,
11261                      Register rd,
11262                      Register rn,
11263                      const Operand& operand) {
11264  CheckIT(cond);
11265  if (operand.IsImmediateShiftedRegister()) {
11266    Register rm = operand.GetBaseRegister();
11267    Shift shift = operand.GetShift();
11268    uint32_t amount = operand.GetShiftAmount();
11269    if (IsUsingT32()) {
11270      // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11271      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11272          ((amount % 8) == 0) && !rn.Is(pc)) {
11273        uint32_t amount_ = amount / 8;
11274        EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11275                   rm.GetCode() | (amount_ << 4));
11276        AdvanceIT();
11277        return;
11278      }
11279    } else {
11280      // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11281      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11282          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11283        uint32_t amount_ = amount / 8;
11284        EmitA32(0x06a00070U | (cond.GetCondition() << 28) |
11285                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11286                (amount_ << 10));
11287        return;
11288      }
11289    }
11290  }
11291  Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand);
11292}
11293
11294void Assembler::sxtab16(Condition cond,
11295                        Register rd,
11296                        Register rn,
11297                        const Operand& operand) {
11298  CheckIT(cond);
11299  if (operand.IsImmediateShiftedRegister()) {
11300    Register rm = operand.GetBaseRegister();
11301    Shift shift = operand.GetShift();
11302    uint32_t amount = operand.GetShiftAmount();
11303    if (IsUsingT32()) {
11304      // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11305      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11306          ((amount % 8) == 0) && !rn.Is(pc)) {
11307        uint32_t amount_ = amount / 8;
11308        EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11309                   rm.GetCode() | (amount_ << 4));
11310        AdvanceIT();
11311        return;
11312      }
11313    } else {
11314      // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11315      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11316          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11317        uint32_t amount_ = amount / 8;
11318        EmitA32(0x06800070U | (cond.GetCondition() << 28) |
11319                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11320                (amount_ << 10));
11321        return;
11322      }
11323    }
11324  }
11325  Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand);
11326}
11327
11328void Assembler::sxtah(Condition cond,
11329                      Register rd,
11330                      Register rn,
11331                      const Operand& operand) {
11332  CheckIT(cond);
11333  if (operand.IsImmediateShiftedRegister()) {
11334    Register rm = operand.GetBaseRegister();
11335    Shift shift = operand.GetShift();
11336    uint32_t amount = operand.GetShiftAmount();
11337    if (IsUsingT32()) {
11338      // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11339      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11340          ((amount % 8) == 0) && !rn.Is(pc)) {
11341        uint32_t amount_ = amount / 8;
11342        EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11343                   rm.GetCode() | (amount_ << 4));
11344        AdvanceIT();
11345        return;
11346      }
11347    } else {
11348      // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11349      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11350          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11351        uint32_t amount_ = amount / 8;
11352        EmitA32(0x06b00070U | (cond.GetCondition() << 28) |
11353                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11354                (amount_ << 10));
11355        return;
11356      }
11357    }
11358  }
11359  Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand);
11360}
11361
11362void Assembler::sxtb(Condition cond,
11363                     EncodingSize size,
11364                     Register rd,
11365                     const Operand& operand) {
11366  CheckIT(cond);
11367  if (operand.IsImmediateShiftedRegister()) {
11368    Register rm = operand.GetBaseRegister();
11369    if (operand.IsPlainRegister()) {
11370      if (IsUsingT32()) {
11371        // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
11372        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
11373          EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3));
11374          AdvanceIT();
11375          return;
11376        }
11377      }
11378    }
11379    Shift shift = operand.GetShift();
11380    uint32_t amount = operand.GetShiftAmount();
11381    if (IsUsingT32()) {
11382      // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
11383      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
11384          (amount <= 24) && ((amount % 8) == 0)) {
11385        uint32_t amount_ = amount / 8;
11386        EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11387                   (amount_ << 4));
11388        AdvanceIT();
11389        return;
11390      }
11391    } else {
11392      // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11393      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11394          ((amount % 8) == 0) && cond.IsNotNever()) {
11395        uint32_t amount_ = amount / 8;
11396        EmitA32(0x06af0070U | (cond.GetCondition() << 28) |
11397                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11398        return;
11399      }
11400    }
11401  }
11402  Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand);
11403}
11404
11405void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) {
11406  CheckIT(cond);
11407  if (operand.IsImmediateShiftedRegister()) {
11408    Register rm = operand.GetBaseRegister();
11409    Shift shift = operand.GetShift();
11410    uint32_t amount = operand.GetShiftAmount();
11411    if (IsUsingT32()) {
11412      // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
11413      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11414          ((amount % 8) == 0)) {
11415        uint32_t amount_ = amount / 8;
11416        EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11417                   (amount_ << 4));
11418        AdvanceIT();
11419        return;
11420      }
11421    } else {
11422      // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11423      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11424          ((amount % 8) == 0) && cond.IsNotNever()) {
11425        uint32_t amount_ = amount / 8;
11426        EmitA32(0x068f0070U | (cond.GetCondition() << 28) |
11427                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11428        return;
11429      }
11430    }
11431  }
11432  Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand);
11433}
11434
11435void Assembler::sxth(Condition cond,
11436                     EncodingSize size,
11437                     Register rd,
11438                     const Operand& operand) {
11439  CheckIT(cond);
11440  if (operand.IsImmediateShiftedRegister()) {
11441    Register rm = operand.GetBaseRegister();
11442    if (operand.IsPlainRegister()) {
11443      if (IsUsingT32()) {
11444        // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
11445        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
11446          EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3));
11447          AdvanceIT();
11448          return;
11449        }
11450      }
11451    }
11452    Shift shift = operand.GetShift();
11453    uint32_t amount = operand.GetShiftAmount();
11454    if (IsUsingT32()) {
11455      // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
11456      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
11457          (amount <= 24) && ((amount % 8) == 0)) {
11458        uint32_t amount_ = amount / 8;
11459        EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11460                   (amount_ << 4));
11461        AdvanceIT();
11462        return;
11463      }
11464    } else {
11465      // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11466      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11467          ((amount % 8) == 0) && cond.IsNotNever()) {
11468        uint32_t amount_ = amount / 8;
11469        EmitA32(0x06bf0070U | (cond.GetCondition() << 28) |
11470                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11471        return;
11472      }
11473    }
11474  }
11475  Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand);
11476}
11477
11478void Assembler::tbb(Condition cond, Register rn, Register rm) {
11479  CheckIT(cond);
11480  if (IsUsingT32()) {
11481    // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1
11482    if (OutsideITBlockAndAlOrLast(cond) &&
11483        ((!rm.IsPC()) || AllowUnpredictable())) {
11484      EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode());
11485      AdvanceIT();
11486      return;
11487    }
11488  }
11489  Delegate(kTbb, &Assembler::tbb, cond, rn, rm);
11490}
11491
11492void Assembler::tbh(Condition cond, Register rn, Register rm) {
11493  CheckIT(cond);
11494  if (IsUsingT32()) {
11495    // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1
11496    if (OutsideITBlockAndAlOrLast(cond) &&
11497        ((!rm.IsPC()) || AllowUnpredictable())) {
11498      EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode());
11499      AdvanceIT();
11500      return;
11501    }
11502  }
11503  Delegate(kTbh, &Assembler::tbh, cond, rn, rm);
11504}
11505
11506void Assembler::teq(Condition cond, Register rn, const Operand& operand) {
11507  CheckIT(cond);
11508  if (operand.IsImmediate()) {
11509    uint32_t imm = operand.GetImmediate();
11510    if (IsUsingT32()) {
11511      ImmediateT32 immediate_t32(imm);
11512      // TEQ{<c>}{<q>} <Rn>, #<const> ; T1
11513      if (immediate_t32.IsValid()) {
11514        EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) |
11515                   (immediate_t32.GetEncodingValue() & 0xff) |
11516                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11517                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11518        AdvanceIT();
11519        return;
11520      }
11521    } else {
11522      ImmediateA32 immediate_a32(imm);
11523      // TEQ{<c>}{<q>} <Rn>, #<const> ; A1
11524      if (immediate_a32.IsValid() && cond.IsNotNever()) {
11525        EmitA32(0x03300000U | (cond.GetCondition() << 28) |
11526                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
11527        return;
11528      }
11529    }
11530  }
11531  if (operand.IsImmediateShiftedRegister()) {
11532    Register rm = operand.GetBaseRegister();
11533    Shift shift = operand.GetShift();
11534    uint32_t amount = operand.GetShiftAmount();
11535    if (IsUsingT32()) {
11536      // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1
11537      if (shift.IsValidAmount(amount)) {
11538        uint32_t amount_ = amount % 32;
11539        EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() |
11540                   (operand.GetTypeEncodingValue() << 4) |
11541                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11542        AdvanceIT();
11543        return;
11544      }
11545    } else {
11546      // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
11547      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
11548        uint32_t amount_ = amount % 32;
11549        EmitA32(0x01300000U | (cond.GetCondition() << 28) |
11550                (rn.GetCode() << 16) | rm.GetCode() |
11551                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11552        return;
11553      }
11554    }
11555  }
11556  if (operand.IsRegisterShiftedRegister()) {
11557    Register rm = operand.GetBaseRegister();
11558    Shift shift = operand.GetShift();
11559    if (IsUsingA32()) {
11560      // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
11561      if (cond.IsNotNever()) {
11562        EmitA32(0x01300010U | (cond.GetCondition() << 28) |
11563                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
11564                (operand.GetShiftRegister().GetCode() << 8));
11565        return;
11566      }
11567    }
11568  }
11569  Delegate(kTeq, &Assembler::teq, cond, rn, operand);
11570}
11571
11572void Assembler::tst(Condition cond,
11573                    EncodingSize size,
11574                    Register rn,
11575                    const Operand& operand) {
11576  CheckIT(cond);
11577  if (operand.IsImmediate()) {
11578    uint32_t imm = operand.GetImmediate();
11579    if (IsUsingT32()) {
11580      ImmediateT32 immediate_t32(imm);
11581      // TST{<c>}{<q>} <Rn>, #<const> ; T1
11582      if (!size.IsNarrow() && immediate_t32.IsValid()) {
11583        EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) |
11584                   (immediate_t32.GetEncodingValue() & 0xff) |
11585                   ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11586                   ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11587        AdvanceIT();
11588        return;
11589      }
11590    } else {
11591      ImmediateA32 immediate_a32(imm);
11592      // TST{<c>}{<q>} <Rn>, #<const> ; A1
11593      if (immediate_a32.IsValid() && cond.IsNotNever()) {
11594        EmitA32(0x03100000U | (cond.GetCondition() << 28) |
11595                (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
11596        return;
11597      }
11598    }
11599  }
11600  if (operand.IsImmediateShiftedRegister()) {
11601    Register rm = operand.GetBaseRegister();
11602    if (operand.IsPlainRegister()) {
11603      if (IsUsingT32()) {
11604        // TST{<c>}{<q>} <Rn>, <Rm> ; T1
11605        if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
11606          EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3));
11607          AdvanceIT();
11608          return;
11609        }
11610      }
11611    }
11612    Shift shift = operand.GetShift();
11613    uint32_t amount = operand.GetShiftAmount();
11614    if (IsUsingT32()) {
11615      // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
11616      if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
11617        uint32_t amount_ = amount % 32;
11618        EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() |
11619                   (operand.GetTypeEncodingValue() << 4) |
11620                   ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11621        AdvanceIT();
11622        return;
11623      }
11624    } else {
11625      // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
11626      if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
11627        uint32_t amount_ = amount % 32;
11628        EmitA32(0x01100000U | (cond.GetCondition() << 28) |
11629                (rn.GetCode() << 16) | rm.GetCode() |
11630                (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11631        return;
11632      }
11633    }
11634  }
11635  if (operand.IsRegisterShiftedRegister()) {
11636    Register rm = operand.GetBaseRegister();
11637    Shift shift = operand.GetShift();
11638    if (IsUsingA32()) {
11639      // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
11640      if (cond.IsNotNever()) {
11641        EmitA32(0x01100010U | (cond.GetCondition() << 28) |
11642                (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
11643                (operand.GetShiftRegister().GetCode() << 8));
11644        return;
11645      }
11646    }
11647  }
11648  Delegate(kTst, &Assembler::tst, cond, size, rn, operand);
11649}
11650
11651void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) {
11652  CheckIT(cond);
11653  if (IsUsingT32()) {
11654    // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11655    EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11656               rm.GetCode());
11657    AdvanceIT();
11658    return;
11659  } else {
11660    // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11661    if (cond.IsNotNever()) {
11662      EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11663              (rn.GetCode() << 16) | rm.GetCode());
11664      return;
11665    }
11666  }
11667  Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm);
11668}
11669
11670void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) {
11671  CheckIT(cond);
11672  if (IsUsingT32()) {
11673    // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11674    EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11675               rm.GetCode());
11676    AdvanceIT();
11677    return;
11678  } else {
11679    // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11680    if (cond.IsNotNever()) {
11681      EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11682              (rn.GetCode() << 16) | rm.GetCode());
11683      return;
11684    }
11685  }
11686  Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm);
11687}
11688
11689void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) {
11690  CheckIT(cond);
11691  if (IsUsingT32()) {
11692    // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11693    EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11694               rm.GetCode());
11695    AdvanceIT();
11696    return;
11697  } else {
11698    // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11699    if (cond.IsNotNever()) {
11700      EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11701              (rn.GetCode() << 16) | rm.GetCode());
11702      return;
11703    }
11704  }
11705  Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm);
11706}
11707
11708void Assembler::ubfx(Condition cond,
11709                     Register rd,
11710                     Register rn,
11711                     uint32_t lsb,
11712                     const Operand& operand) {
11713  CheckIT(cond);
11714  if (operand.IsImmediate()) {
11715    uint32_t width = operand.GetImmediate();
11716    if (IsUsingT32()) {
11717      // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
11718      if ((lsb <= 31) &&
11719          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
11720        uint32_t widthm1 = width - 1;
11721        EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11722                   ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
11723        AdvanceIT();
11724        return;
11725      }
11726    } else {
11727      // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
11728      if ((lsb <= 31) && cond.IsNotNever() &&
11729          (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
11730        uint32_t widthm1 = width - 1;
11731        EmitA32(0x07e00050U | (cond.GetCondition() << 28) |
11732                (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) |
11733                (widthm1 << 16));
11734        return;
11735      }
11736    }
11737  }
11738  Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, operand);
11739}
11740
11741void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) {
11742  CheckIT(cond);
11743  if (IsUsingT32()) {
11744    // UDF{<c>}{<q>} {#}<imm> ; T1
11745    if (!size.IsWide() && (imm <= 255)) {
11746      if (cond.Is(al) || AllowStronglyDiscouraged()) {
11747        EmitT32_16(0xde00 | imm);
11748        AdvanceIT();
11749        return;
11750      }
11751    }
11752    // UDF{<c>}{<q>} {#}<imm> ; T2
11753    if (!size.IsNarrow() && (imm <= 65535)) {
11754      if (cond.Is(al) || AllowStronglyDiscouraged()) {
11755        EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
11756        AdvanceIT();
11757        return;
11758      }
11759    }
11760  } else {
11761    // UDF{<c>}{<q>} {#}<imm> ; A1
11762    if ((imm <= 65535)) {
11763      if (cond.Is(al) || AllowStronglyDiscouraged()) {
11764        EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4));
11765        return;
11766      }
11767    }
11768  }
11769  Delegate(kUdf, &Assembler::udf, cond, size, imm);
11770}
11771
11772void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) {
11773  CheckIT(cond);
11774  if (IsUsingT32()) {
11775    // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11776    EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11777               rm.GetCode());
11778    AdvanceIT();
11779    return;
11780  } else {
11781    // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11782    if (cond.IsNotNever()) {
11783      EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
11784              rn.GetCode() | (rm.GetCode() << 8));
11785      return;
11786    }
11787  }
11788  Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm);
11789}
11790
11791void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) {
11792  CheckIT(cond);
11793  if (IsUsingT32()) {
11794    // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11795    EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11796               rm.GetCode());
11797    AdvanceIT();
11798    return;
11799  } else {
11800    // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11801    if (cond.IsNotNever()) {
11802      EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11803              (rn.GetCode() << 16) | rm.GetCode());
11804      return;
11805    }
11806  }
11807  Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm);
11808}
11809
11810void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) {
11811  CheckIT(cond);
11812  if (IsUsingT32()) {
11813    // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11814    EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11815               rm.GetCode());
11816    AdvanceIT();
11817    return;
11818  } else {
11819    // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11820    if (cond.IsNotNever()) {
11821      EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11822              (rn.GetCode() << 16) | rm.GetCode());
11823      return;
11824    }
11825  }
11826  Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm);
11827}
11828
11829void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) {
11830  CheckIT(cond);
11831  if (IsUsingT32()) {
11832    // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11833    EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11834               rm.GetCode());
11835    AdvanceIT();
11836    return;
11837  } else {
11838    // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11839    if (cond.IsNotNever()) {
11840      EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11841              (rn.GetCode() << 16) | rm.GetCode());
11842      return;
11843    }
11844  }
11845  Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm);
11846}
11847
11848void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) {
11849  CheckIT(cond);
11850  if (IsUsingT32()) {
11851    // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11852    EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11853               rm.GetCode());
11854    AdvanceIT();
11855    return;
11856  } else {
11857    // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11858    if (cond.IsNotNever()) {
11859      EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11860              (rn.GetCode() << 16) | rm.GetCode());
11861      return;
11862    }
11863  }
11864  Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm);
11865}
11866
11867void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) {
11868  CheckIT(cond);
11869  if (IsUsingT32()) {
11870    // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11871    EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11872               rm.GetCode());
11873    AdvanceIT();
11874    return;
11875  } else {
11876    // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11877    if (cond.IsNotNever()) {
11878      EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11879              (rn.GetCode() << 16) | rm.GetCode());
11880      return;
11881    }
11882  }
11883  Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm);
11884}
11885
11886void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) {
11887  CheckIT(cond);
11888  if (IsUsingT32()) {
11889    // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11890    EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11891               rm.GetCode());
11892    AdvanceIT();
11893    return;
11894  } else {
11895    // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11896    if (cond.IsNotNever()) {
11897      EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11898              (rn.GetCode() << 16) | rm.GetCode());
11899      return;
11900    }
11901  }
11902  Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm);
11903}
11904
11905void Assembler::umaal(
11906    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
11907  CheckIT(cond);
11908  if (IsUsingT32()) {
11909    // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
11910    EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
11911               (rn.GetCode() << 16) | rm.GetCode());
11912    AdvanceIT();
11913    return;
11914  } else {
11915    // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
11916    if (cond.IsNotNever()) {
11917      EmitA32(0x00400090U | (cond.GetCondition() << 28) |
11918              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
11919              (rm.GetCode() << 8));
11920      return;
11921    }
11922  }
11923  Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm);
11924}
11925
11926void Assembler::umlal(
11927    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
11928  CheckIT(cond);
11929  if (IsUsingT32()) {
11930    // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
11931    EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
11932               (rn.GetCode() << 16) | rm.GetCode());
11933    AdvanceIT();
11934    return;
11935  } else {
11936    // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
11937    if (cond.IsNotNever()) {
11938      EmitA32(0x00a00090U | (cond.GetCondition() << 28) |
11939              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
11940              (rm.GetCode() << 8));
11941      return;
11942    }
11943  }
11944  Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm);
11945}
11946
11947void Assembler::umlals(
11948    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
11949  CheckIT(cond);
11950  if (IsUsingA32()) {
11951    // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
11952    if (cond.IsNotNever()) {
11953      EmitA32(0x00b00090U | (cond.GetCondition() << 28) |
11954              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
11955              (rm.GetCode() << 8));
11956      return;
11957    }
11958  }
11959  Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm);
11960}
11961
11962void Assembler::umull(
11963    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
11964  CheckIT(cond);
11965  if (IsUsingT32()) {
11966    // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
11967    EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
11968               (rn.GetCode() << 16) | rm.GetCode());
11969    AdvanceIT();
11970    return;
11971  } else {
11972    // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
11973    if (cond.IsNotNever()) {
11974      EmitA32(0x00800090U | (cond.GetCondition() << 28) |
11975              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
11976              (rm.GetCode() << 8));
11977      return;
11978    }
11979  }
11980  Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm);
11981}
11982
11983void Assembler::umulls(
11984    Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
11985  CheckIT(cond);
11986  if (IsUsingA32()) {
11987    // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
11988    if (cond.IsNotNever()) {
11989      EmitA32(0x00900090U | (cond.GetCondition() << 28) |
11990              (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
11991              (rm.GetCode() << 8));
11992      return;
11993    }
11994  }
11995  Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm);
11996}
11997
11998void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) {
11999  CheckIT(cond);
12000  if (IsUsingT32()) {
12001    // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12002    EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12003               rm.GetCode());
12004    AdvanceIT();
12005    return;
12006  } else {
12007    // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12008    if (cond.IsNotNever()) {
12009      EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12010              (rn.GetCode() << 16) | rm.GetCode());
12011      return;
12012    }
12013  }
12014  Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm);
12015}
12016
12017void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) {
12018  CheckIT(cond);
12019  if (IsUsingT32()) {
12020    // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12021    EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12022               rm.GetCode());
12023    AdvanceIT();
12024    return;
12025  } else {
12026    // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12027    if (cond.IsNotNever()) {
12028      EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12029              (rn.GetCode() << 16) | rm.GetCode());
12030      return;
12031    }
12032  }
12033  Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm);
12034}
12035
12036void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) {
12037  CheckIT(cond);
12038  if (IsUsingT32()) {
12039    // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12040    EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12041               rm.GetCode());
12042    AdvanceIT();
12043    return;
12044  } else {
12045    // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12046    if (cond.IsNotNever()) {
12047      EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12048              (rn.GetCode() << 16) | rm.GetCode());
12049      return;
12050    }
12051  }
12052  Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm);
12053}
12054
12055void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) {
12056  CheckIT(cond);
12057  if (IsUsingT32()) {
12058    // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12059    EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12060               rm.GetCode());
12061    AdvanceIT();
12062    return;
12063  } else {
12064    // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12065    if (cond.IsNotNever()) {
12066      EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12067              (rn.GetCode() << 16) | rm.GetCode());
12068      return;
12069    }
12070  }
12071  Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm);
12072}
12073
12074void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) {
12075  CheckIT(cond);
12076  if (IsUsingT32()) {
12077    // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12078    EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12079               rm.GetCode());
12080    AdvanceIT();
12081    return;
12082  } else {
12083    // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12084    if (cond.IsNotNever()) {
12085      EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12086              (rn.GetCode() << 16) | rm.GetCode());
12087      return;
12088    }
12089  }
12090  Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm);
12091}
12092
12093void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) {
12094  CheckIT(cond);
12095  if (IsUsingT32()) {
12096    // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12097    EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12098               rm.GetCode());
12099    AdvanceIT();
12100    return;
12101  } else {
12102    // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12103    if (cond.IsNotNever()) {
12104      EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12105              (rn.GetCode() << 16) | rm.GetCode());
12106      return;
12107    }
12108  }
12109  Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm);
12110}
12111
12112void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) {
12113  CheckIT(cond);
12114  if (IsUsingT32()) {
12115    // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12116    EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12117               rm.GetCode());
12118    AdvanceIT();
12119    return;
12120  } else {
12121    // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12122    if (cond.IsNotNever()) {
12123      EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
12124              rn.GetCode() | (rm.GetCode() << 8));
12125      return;
12126    }
12127  }
12128  Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm);
12129}
12130
12131void Assembler::usada8(
12132    Condition cond, Register rd, Register rn, Register rm, Register ra) {
12133  CheckIT(cond);
12134  if (IsUsingT32()) {
12135    // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
12136    if (!ra.Is(pc)) {
12137      EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12138                 rm.GetCode() | (ra.GetCode() << 12));
12139      AdvanceIT();
12140      return;
12141    }
12142  } else {
12143    // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
12144    if (cond.IsNotNever() && !ra.Is(pc)) {
12145      EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
12146              rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
12147      return;
12148    }
12149  }
12150  Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra);
12151}
12152
12153void Assembler::usat(Condition cond,
12154                     Register rd,
12155                     uint32_t imm,
12156                     const Operand& operand) {
12157  CheckIT(cond);
12158  if (operand.IsImmediateShiftedRegister()) {
12159    Register rn = operand.GetBaseRegister();
12160    Shift shift = operand.GetShift();
12161    uint32_t amount = operand.GetShiftAmount();
12162    if (IsUsingT32()) {
12163      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
12164      if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31)) {
12165        EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
12166                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
12167                   ((amount & 0x1c) << 10));
12168        AdvanceIT();
12169        return;
12170      }
12171      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
12172      if ((imm <= 31) && shift.IsLSL() && (amount <= 31)) {
12173        EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm |
12174                   (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
12175                   ((amount & 0x1c) << 10));
12176        AdvanceIT();
12177        return;
12178      }
12179    } else {
12180      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
12181      if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) &&
12182          cond.IsNotNever()) {
12183        uint32_t amount_ = amount % 32;
12184        EmitA32(0x06e00050U | (cond.GetCondition() << 28) |
12185                (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
12186                (amount_ << 7));
12187        return;
12188      }
12189      // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
12190      if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever()) {
12191        EmitA32(0x06e00010U | (cond.GetCondition() << 28) |
12192                (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
12193                (amount << 7));
12194        return;
12195      }
12196    }
12197  }
12198  Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand);
12199}
12200
12201void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) {
12202  CheckIT(cond);
12203  if (IsUsingT32()) {
12204    // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
12205    if ((imm <= 15)) {
12206      EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
12207                 (rn.GetCode() << 16));
12208      AdvanceIT();
12209      return;
12210    }
12211  } else {
12212    // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
12213    if ((imm <= 15) && cond.IsNotNever()) {
12214      EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12215              (imm << 16) | rn.GetCode());
12216      return;
12217    }
12218  }
12219  Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn);
12220}
12221
12222void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) {
12223  CheckIT(cond);
12224  if (IsUsingT32()) {
12225    // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12226    EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12227               rm.GetCode());
12228    AdvanceIT();
12229    return;
12230  } else {
12231    // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12232    if (cond.IsNotNever()) {
12233      EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12234              (rn.GetCode() << 16) | rm.GetCode());
12235      return;
12236    }
12237  }
12238  Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm);
12239}
12240
12241void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) {
12242  CheckIT(cond);
12243  if (IsUsingT32()) {
12244    // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12245    EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12246               rm.GetCode());
12247    AdvanceIT();
12248    return;
12249  } else {
12250    // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12251    if (cond.IsNotNever()) {
12252      EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12253              (rn.GetCode() << 16) | rm.GetCode());
12254      return;
12255    }
12256  }
12257  Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm);
12258}
12259
12260void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) {
12261  CheckIT(cond);
12262  if (IsUsingT32()) {
12263    // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12264    EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12265               rm.GetCode());
12266    AdvanceIT();
12267    return;
12268  } else {
12269    // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12270    if (cond.IsNotNever()) {
12271      EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12272              (rn.GetCode() << 16) | rm.GetCode());
12273      return;
12274    }
12275  }
12276  Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm);
12277}
12278
12279void Assembler::uxtab(Condition cond,
12280                      Register rd,
12281                      Register rn,
12282                      const Operand& operand) {
12283  CheckIT(cond);
12284  if (operand.IsImmediateShiftedRegister()) {
12285    Register rm = operand.GetBaseRegister();
12286    Shift shift = operand.GetShift();
12287    uint32_t amount = operand.GetShiftAmount();
12288    if (IsUsingT32()) {
12289      // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12290      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12291          ((amount % 8) == 0) && !rn.Is(pc)) {
12292        uint32_t amount_ = amount / 8;
12293        EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12294                   rm.GetCode() | (amount_ << 4));
12295        AdvanceIT();
12296        return;
12297      }
12298    } else {
12299      // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12300      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12301          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12302        uint32_t amount_ = amount / 8;
12303        EmitA32(0x06e00070U | (cond.GetCondition() << 28) |
12304                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12305                (amount_ << 10));
12306        return;
12307      }
12308    }
12309  }
12310  Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand);
12311}
12312
12313void Assembler::uxtab16(Condition cond,
12314                        Register rd,
12315                        Register rn,
12316                        const Operand& operand) {
12317  CheckIT(cond);
12318  if (operand.IsImmediateShiftedRegister()) {
12319    Register rm = operand.GetBaseRegister();
12320    Shift shift = operand.GetShift();
12321    uint32_t amount = operand.GetShiftAmount();
12322    if (IsUsingT32()) {
12323      // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12324      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12325          ((amount % 8) == 0) && !rn.Is(pc)) {
12326        uint32_t amount_ = amount / 8;
12327        EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12328                   rm.GetCode() | (amount_ << 4));
12329        AdvanceIT();
12330        return;
12331      }
12332    } else {
12333      // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12334      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12335          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12336        uint32_t amount_ = amount / 8;
12337        EmitA32(0x06c00070U | (cond.GetCondition() << 28) |
12338                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12339                (amount_ << 10));
12340        return;
12341      }
12342    }
12343  }
12344  Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand);
12345}
12346
12347void Assembler::uxtah(Condition cond,
12348                      Register rd,
12349                      Register rn,
12350                      const Operand& operand) {
12351  CheckIT(cond);
12352  if (operand.IsImmediateShiftedRegister()) {
12353    Register rm = operand.GetBaseRegister();
12354    Shift shift = operand.GetShift();
12355    uint32_t amount = operand.GetShiftAmount();
12356    if (IsUsingT32()) {
12357      // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12358      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12359          ((amount % 8) == 0) && !rn.Is(pc)) {
12360        uint32_t amount_ = amount / 8;
12361        EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12362                   rm.GetCode() | (amount_ << 4));
12363        AdvanceIT();
12364        return;
12365      }
12366    } else {
12367      // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12368      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12369          ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12370        uint32_t amount_ = amount / 8;
12371        EmitA32(0x06f00070U | (cond.GetCondition() << 28) |
12372                (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12373                (amount_ << 10));
12374        return;
12375      }
12376    }
12377  }
12378  Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand);
12379}
12380
12381void Assembler::uxtb(Condition cond,
12382                     EncodingSize size,
12383                     Register rd,
12384                     const Operand& operand) {
12385  CheckIT(cond);
12386  if (operand.IsImmediateShiftedRegister()) {
12387    Register rm = operand.GetBaseRegister();
12388    if (operand.IsPlainRegister()) {
12389      if (IsUsingT32()) {
12390        // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
12391        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12392          EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3));
12393          AdvanceIT();
12394          return;
12395        }
12396      }
12397    }
12398    Shift shift = operand.GetShift();
12399    uint32_t amount = operand.GetShiftAmount();
12400    if (IsUsingT32()) {
12401      // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12402      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12403          (amount <= 24) && ((amount % 8) == 0)) {
12404        uint32_t amount_ = amount / 8;
12405        EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12406                   (amount_ << 4));
12407        AdvanceIT();
12408        return;
12409      }
12410    } else {
12411      // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12412      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12413          ((amount % 8) == 0) && cond.IsNotNever()) {
12414        uint32_t amount_ = amount / 8;
12415        EmitA32(0x06ef0070U | (cond.GetCondition() << 28) |
12416                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12417        return;
12418      }
12419    }
12420  }
12421  Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand);
12422}
12423
12424void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) {
12425  CheckIT(cond);
12426  if (operand.IsImmediateShiftedRegister()) {
12427    Register rm = operand.GetBaseRegister();
12428    Shift shift = operand.GetShift();
12429    uint32_t amount = operand.GetShiftAmount();
12430    if (IsUsingT32()) {
12431      // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
12432      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12433          ((amount % 8) == 0)) {
12434        uint32_t amount_ = amount / 8;
12435        EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12436                   (amount_ << 4));
12437        AdvanceIT();
12438        return;
12439      }
12440    } else {
12441      // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12442      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12443          ((amount % 8) == 0) && cond.IsNotNever()) {
12444        uint32_t amount_ = amount / 8;
12445        EmitA32(0x06cf0070U | (cond.GetCondition() << 28) |
12446                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12447        return;
12448      }
12449    }
12450  }
12451  Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand);
12452}
12453
12454void Assembler::uxth(Condition cond,
12455                     EncodingSize size,
12456                     Register rd,
12457                     const Operand& operand) {
12458  CheckIT(cond);
12459  if (operand.IsImmediateShiftedRegister()) {
12460    Register rm = operand.GetBaseRegister();
12461    if (operand.IsPlainRegister()) {
12462      if (IsUsingT32()) {
12463        // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
12464        if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12465          EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3));
12466          AdvanceIT();
12467          return;
12468        }
12469      }
12470    }
12471    Shift shift = operand.GetShift();
12472    uint32_t amount = operand.GetShiftAmount();
12473    if (IsUsingT32()) {
12474      // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12475      if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12476          (amount <= 24) && ((amount % 8) == 0)) {
12477        uint32_t amount_ = amount / 8;
12478        EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12479                   (amount_ << 4));
12480        AdvanceIT();
12481        return;
12482      }
12483    } else {
12484      // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12485      if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12486          ((amount % 8) == 0) && cond.IsNotNever()) {
12487        uint32_t amount_ = amount / 8;
12488        EmitA32(0x06ff0070U | (cond.GetCondition() << 28) |
12489                (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12490        return;
12491      }
12492    }
12493  }
12494  Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand);
12495}
12496
12497void Assembler::vaba(
12498    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12499  CheckIT(cond);
12500  Dt_U_size_1 encoded_dt(dt);
12501  if (IsUsingT32()) {
12502    // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1
12503    if (encoded_dt.IsValid()) {
12504      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12505        EmitT32_32(0xef000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12506                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12507                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12508        AdvanceIT();
12509        return;
12510      }
12511    }
12512  } else {
12513    // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1
12514    if (encoded_dt.IsValid()) {
12515      if (cond.Is(al)) {
12516        EmitA32(0xf2000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12517                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12518                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12519        return;
12520      }
12521    }
12522  }
12523  Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
12524}
12525
12526void Assembler::vaba(
12527    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12528  CheckIT(cond);
12529  Dt_U_size_1 encoded_dt(dt);
12530  if (IsUsingT32()) {
12531    // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1
12532    if (encoded_dt.IsValid()) {
12533      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12534        EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12535                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12536                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12537        AdvanceIT();
12538        return;
12539      }
12540    }
12541  } else {
12542    // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1
12543    if (encoded_dt.IsValid()) {
12544      if (cond.Is(al)) {
12545        EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12546                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12547                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12548        return;
12549      }
12550    }
12551  }
12552  Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
12553}
12554
12555void Assembler::vabal(
12556    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
12557  CheckIT(cond);
12558  Dt_U_size_1 encoded_dt(dt);
12559  if (IsUsingT32()) {
12560    // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
12561    if (encoded_dt.IsValid()) {
12562      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12563        EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12564                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12565                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12566        AdvanceIT();
12567        return;
12568      }
12569    }
12570  } else {
12571    // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
12572    if (encoded_dt.IsValid()) {
12573      if (cond.Is(al)) {
12574        EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12575                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12576                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12577        return;
12578      }
12579    }
12580  }
12581  Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm);
12582}
12583
12584void Assembler::vabd(
12585    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12586  CheckIT(cond);
12587  Dt_U_size_1 encoded_dt(dt);
12588  if (IsUsingT32()) {
12589    // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
12590    if (dt.Is(F32)) {
12591      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12592        EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12593                   rm.Encode(5, 0));
12594        AdvanceIT();
12595        return;
12596      }
12597    }
12598    // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
12599    if (encoded_dt.IsValid()) {
12600      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12601        EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12602                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12603                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12604        AdvanceIT();
12605        return;
12606      }
12607    }
12608  } else {
12609    // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
12610    if (dt.Is(F32)) {
12611      if (cond.Is(al)) {
12612        EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12613                rm.Encode(5, 0));
12614        return;
12615      }
12616    }
12617    // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
12618    if (encoded_dt.IsValid()) {
12619      if (cond.Is(al)) {
12620        EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12621                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12622                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12623        return;
12624      }
12625    }
12626  }
12627  Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
12628}
12629
12630void Assembler::vabd(
12631    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12632  CheckIT(cond);
12633  Dt_U_size_1 encoded_dt(dt);
12634  if (IsUsingT32()) {
12635    // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
12636    if (dt.Is(F32)) {
12637      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12638        EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12639                   rm.Encode(5, 0));
12640        AdvanceIT();
12641        return;
12642      }
12643    }
12644    // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
12645    if (encoded_dt.IsValid()) {
12646      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12647        EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12648                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12649                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12650        AdvanceIT();
12651        return;
12652      }
12653    }
12654  } else {
12655    // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
12656    if (dt.Is(F32)) {
12657      if (cond.Is(al)) {
12658        EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12659                rm.Encode(5, 0));
12660        return;
12661      }
12662    }
12663    // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
12664    if (encoded_dt.IsValid()) {
12665      if (cond.Is(al)) {
12666        EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12667                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12668                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12669        return;
12670      }
12671    }
12672  }
12673  Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
12674}
12675
12676void Assembler::vabdl(
12677    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
12678  CheckIT(cond);
12679  Dt_U_size_1 encoded_dt(dt);
12680  if (IsUsingT32()) {
12681    // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
12682    if (encoded_dt.IsValid()) {
12683      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12684        EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12685                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12686                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12687        AdvanceIT();
12688        return;
12689      }
12690    }
12691  } else {
12692    // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
12693    if (encoded_dt.IsValid()) {
12694      if (cond.Is(al)) {
12695        EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12696                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12697                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12698        return;
12699      }
12700    }
12701  }
12702  Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm);
12703}
12704
12705void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
12706  CheckIT(cond);
12707  Dt_F_size_1 encoded_dt(dt);
12708  if (IsUsingT32()) {
12709    // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
12710    if (encoded_dt.IsValid()) {
12711      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12712        EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12713                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12714                   rd.Encode(22, 12) | rm.Encode(5, 0));
12715        AdvanceIT();
12716        return;
12717      }
12718    }
12719    // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
12720    if (dt.Is(F64)) {
12721      EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
12722      AdvanceIT();
12723      return;
12724    }
12725  } else {
12726    // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
12727    if (encoded_dt.IsValid()) {
12728      if (cond.Is(al)) {
12729        EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12730                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12731                rd.Encode(22, 12) | rm.Encode(5, 0));
12732        return;
12733      }
12734    }
12735    // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
12736    if (dt.Is(F64) && cond.IsNotNever()) {
12737      EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
12738              rm.Encode(5, 0));
12739      return;
12740    }
12741  }
12742  Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
12743}
12744
12745void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
12746  CheckIT(cond);
12747  Dt_F_size_1 encoded_dt(dt);
12748  if (IsUsingT32()) {
12749    // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
12750    if (encoded_dt.IsValid()) {
12751      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12752        EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12753                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12754                   rd.Encode(22, 12) | rm.Encode(5, 0));
12755        AdvanceIT();
12756        return;
12757      }
12758    }
12759  } else {
12760    // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
12761    if (encoded_dt.IsValid()) {
12762      if (cond.Is(al)) {
12763        EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12764                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12765                rd.Encode(22, 12) | rm.Encode(5, 0));
12766        return;
12767      }
12768    }
12769  }
12770  Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
12771}
12772
12773void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) {
12774  CheckIT(cond);
12775  if (IsUsingT32()) {
12776    // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
12777    if (dt.Is(F32)) {
12778      EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
12779      AdvanceIT();
12780      return;
12781    }
12782  } else {
12783    // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
12784    if (dt.Is(F32) && cond.IsNotNever()) {
12785      EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
12786              rm.Encode(5, 0));
12787      return;
12788    }
12789  }
12790  Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
12791}
12792
12793void Assembler::vacge(
12794    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12795  CheckIT(cond);
12796  if (IsUsingT32()) {
12797    // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
12798    if (dt.Is(F32)) {
12799      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12800        EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12801                   rm.Encode(5, 0));
12802        AdvanceIT();
12803        return;
12804      }
12805    }
12806  } else {
12807    // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
12808    if (dt.Is(F32)) {
12809      if (cond.Is(al)) {
12810        EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12811                rm.Encode(5, 0));
12812        return;
12813      }
12814    }
12815  }
12816  Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
12817}
12818
12819void Assembler::vacge(
12820    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12821  CheckIT(cond);
12822  if (IsUsingT32()) {
12823    // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
12824    if (dt.Is(F32)) {
12825      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12826        EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12827                   rm.Encode(5, 0));
12828        AdvanceIT();
12829        return;
12830      }
12831    }
12832  } else {
12833    // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
12834    if (dt.Is(F32)) {
12835      if (cond.Is(al)) {
12836        EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12837                rm.Encode(5, 0));
12838        return;
12839      }
12840    }
12841  }
12842  Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
12843}
12844
12845void Assembler::vacgt(
12846    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12847  CheckIT(cond);
12848  if (IsUsingT32()) {
12849    // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
12850    if (dt.Is(F32)) {
12851      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12852        EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12853                   rm.Encode(5, 0));
12854        AdvanceIT();
12855        return;
12856      }
12857    }
12858  } else {
12859    // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
12860    if (dt.Is(F32)) {
12861      if (cond.Is(al)) {
12862        EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12863                rm.Encode(5, 0));
12864        return;
12865      }
12866    }
12867  }
12868  Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
12869}
12870
12871void Assembler::vacgt(
12872    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12873  CheckIT(cond);
12874  if (IsUsingT32()) {
12875    // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
12876    if (dt.Is(F32)) {
12877      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12878        EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12879                   rm.Encode(5, 0));
12880        AdvanceIT();
12881        return;
12882      }
12883    }
12884  } else {
12885    // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
12886    if (dt.Is(F32)) {
12887      if (cond.Is(al)) {
12888        EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12889                rm.Encode(5, 0));
12890        return;
12891      }
12892    }
12893  }
12894  Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
12895}
12896
12897void Assembler::vacle(
12898    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12899  CheckIT(cond);
12900  if (IsUsingT32()) {
12901    // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
12902    if (dt.Is(F32)) {
12903      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12904        EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12905                   rm.Encode(5, 0));
12906        AdvanceIT();
12907        return;
12908      }
12909    }
12910  } else {
12911    // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
12912    if (dt.Is(F32)) {
12913      if (cond.Is(al)) {
12914        EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12915                rm.Encode(5, 0));
12916        return;
12917      }
12918    }
12919  }
12920  Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
12921}
12922
12923void Assembler::vacle(
12924    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12925  CheckIT(cond);
12926  if (IsUsingT32()) {
12927    // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
12928    if (dt.Is(F32)) {
12929      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12930        EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12931                   rm.Encode(5, 0));
12932        AdvanceIT();
12933        return;
12934      }
12935    }
12936  } else {
12937    // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
12938    if (dt.Is(F32)) {
12939      if (cond.Is(al)) {
12940        EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12941                rm.Encode(5, 0));
12942        return;
12943      }
12944    }
12945  }
12946  Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
12947}
12948
12949void Assembler::vaclt(
12950    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12951  CheckIT(cond);
12952  if (IsUsingT32()) {
12953    // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
12954    if (dt.Is(F32)) {
12955      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12956        EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12957                   rm.Encode(5, 0));
12958        AdvanceIT();
12959        return;
12960      }
12961    }
12962  } else {
12963    // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
12964    if (dt.Is(F32)) {
12965      if (cond.Is(al)) {
12966        EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12967                rm.Encode(5, 0));
12968        return;
12969      }
12970    }
12971  }
12972  Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
12973}
12974
12975void Assembler::vaclt(
12976    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12977  CheckIT(cond);
12978  if (IsUsingT32()) {
12979    // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
12980    if (dt.Is(F32)) {
12981      if (cond.Is(al) || AllowStronglyDiscouraged()) {
12982        EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12983                   rm.Encode(5, 0));
12984        AdvanceIT();
12985        return;
12986      }
12987    }
12988  } else {
12989    // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
12990    if (dt.Is(F32)) {
12991      if (cond.Is(al)) {
12992        EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12993                rm.Encode(5, 0));
12994        return;
12995      }
12996    }
12997  }
12998  Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
12999}
13000
13001void Assembler::vadd(
13002    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13003  CheckIT(cond);
13004  Dt_size_2 encoded_dt(dt);
13005  if (IsUsingT32()) {
13006    // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13007    if (dt.Is(F32)) {
13008      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13009        EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13010                   rm.Encode(5, 0));
13011        AdvanceIT();
13012        return;
13013      }
13014    }
13015    // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
13016    if (dt.Is(F64)) {
13017      EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13018                 rm.Encode(5, 0));
13019      AdvanceIT();
13020      return;
13021    }
13022    // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
13023    if (encoded_dt.IsValid()) {
13024      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13025        EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) |
13026                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13027        AdvanceIT();
13028        return;
13029      }
13030    }
13031  } else {
13032    // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13033    if (dt.Is(F32)) {
13034      if (cond.Is(al)) {
13035        EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13036                rm.Encode(5, 0));
13037        return;
13038      }
13039    }
13040    // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
13041    if (dt.Is(F64) && cond.IsNotNever()) {
13042      EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
13043              rn.Encode(7, 16) | rm.Encode(5, 0));
13044      return;
13045    }
13046    // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
13047    if (encoded_dt.IsValid()) {
13048      if (cond.Is(al)) {
13049        EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) |
13050                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13051        return;
13052      }
13053    }
13054  }
13055  Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13056}
13057
13058void Assembler::vadd(
13059    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13060  CheckIT(cond);
13061  Dt_size_2 encoded_dt(dt);
13062  if (IsUsingT32()) {
13063    // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13064    if (dt.Is(F32)) {
13065      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13066        EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13067                   rm.Encode(5, 0));
13068        AdvanceIT();
13069        return;
13070      }
13071    }
13072    // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
13073    if (encoded_dt.IsValid()) {
13074      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13075        EmitT32_32(0xef000840U | (encoded_dt.GetEncodingValue() << 20) |
13076                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13077        AdvanceIT();
13078        return;
13079      }
13080    }
13081  } else {
13082    // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13083    if (dt.Is(F32)) {
13084      if (cond.Is(al)) {
13085        EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13086                rm.Encode(5, 0));
13087        return;
13088      }
13089    }
13090    // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
13091    if (encoded_dt.IsValid()) {
13092      if (cond.Is(al)) {
13093        EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) |
13094                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13095        return;
13096      }
13097    }
13098  }
13099  Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13100}
13101
13102void Assembler::vadd(
13103    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
13104  CheckIT(cond);
13105  if (IsUsingT32()) {
13106    // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
13107    if (dt.Is(F32)) {
13108      EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13109                 rm.Encode(5, 0));
13110      AdvanceIT();
13111      return;
13112    }
13113  } else {
13114    // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
13115    if (dt.Is(F32) && cond.IsNotNever()) {
13116      EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
13117              rn.Encode(7, 16) | rm.Encode(5, 0));
13118      return;
13119    }
13120  }
13121  Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13122}
13123
13124void Assembler::vaddhn(
13125    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
13126  CheckIT(cond);
13127  Dt_size_3 encoded_dt(dt);
13128  if (IsUsingT32()) {
13129    // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
13130    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
13131      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13132        EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) |
13133                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13134        AdvanceIT();
13135        return;
13136      }
13137    }
13138  } else {
13139    // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
13140    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
13141      if (cond.Is(al)) {
13142        EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) |
13143                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13144        return;
13145      }
13146    }
13147  }
13148  Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm);
13149}
13150
13151void Assembler::vaddl(
13152    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
13153  CheckIT(cond);
13154  Dt_U_size_1 encoded_dt(dt);
13155  if (IsUsingT32()) {
13156    // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
13157    if (encoded_dt.IsValid()) {
13158      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13159        EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13160                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13161                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13162        AdvanceIT();
13163        return;
13164      }
13165    }
13166  } else {
13167    // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
13168    if (encoded_dt.IsValid()) {
13169      if (cond.Is(al)) {
13170        EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13171                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13172                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13173        return;
13174      }
13175    }
13176  }
13177  Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm);
13178}
13179
13180void Assembler::vaddw(
13181    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
13182  CheckIT(cond);
13183  Dt_U_size_1 encoded_dt(dt);
13184  if (IsUsingT32()) {
13185    // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
13186    if (encoded_dt.IsValid()) {
13187      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13188        EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13189                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13190                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13191        AdvanceIT();
13192        return;
13193      }
13194    }
13195  } else {
13196    // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
13197    if (encoded_dt.IsValid()) {
13198      if (cond.Is(al)) {
13199        EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13200                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13201                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13202        return;
13203      }
13204    }
13205  }
13206  Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm);
13207}
13208
13209void Assembler::vand(Condition cond,
13210                     DataType dt,
13211                     DRegister rd,
13212                     DRegister rn,
13213                     const DOperand& operand) {
13214  CheckIT(cond);
13215  if (operand.IsImmediate()) {
13216    ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
13217    if (IsUsingT32()) {
13218      // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
13219      if (encoded_dt.IsValid() && rd.Is(rn)) {
13220        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13221          EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
13222                     rd.Encode(22, 12) |
13223                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13224                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13225                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13226          AdvanceIT();
13227          return;
13228        }
13229      }
13230    } else {
13231      // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
13232      if (encoded_dt.IsValid() && rd.Is(rn)) {
13233        if (cond.Is(al)) {
13234          EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
13235                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13236                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13237                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13238          return;
13239        }
13240      }
13241    }
13242  }
13243  if (operand.IsRegister()) {
13244    DRegister rm = operand.GetRegister();
13245    USE(dt);
13246    if (IsUsingT32()) {
13247      // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13248      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13249        EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13250                   rm.Encode(5, 0));
13251        AdvanceIT();
13252        return;
13253      }
13254    } else {
13255      // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13256      if (cond.Is(al)) {
13257        EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13258                rm.Encode(5, 0));
13259        return;
13260      }
13261    }
13262  }
13263  Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
13264}
13265
13266void Assembler::vand(Condition cond,
13267                     DataType dt,
13268                     QRegister rd,
13269                     QRegister rn,
13270                     const QOperand& operand) {
13271  CheckIT(cond);
13272  if (operand.IsImmediate()) {
13273    ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
13274    if (IsUsingT32()) {
13275      // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
13276      if (encoded_dt.IsValid() && rd.Is(rn)) {
13277        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13278          EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
13279                     rd.Encode(22, 12) |
13280                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13281                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13282                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13283          AdvanceIT();
13284          return;
13285        }
13286      }
13287    } else {
13288      // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
13289      if (encoded_dt.IsValid() && rd.Is(rn)) {
13290        if (cond.Is(al)) {
13291          EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
13292                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13293                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13294                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13295          return;
13296        }
13297      }
13298    }
13299  }
13300  if (operand.IsRegister()) {
13301    QRegister rm = operand.GetRegister();
13302    USE(dt);
13303    if (IsUsingT32()) {
13304      // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13305      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13306        EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13307                   rm.Encode(5, 0));
13308        AdvanceIT();
13309        return;
13310      }
13311    } else {
13312      // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13313      if (cond.Is(al)) {
13314        EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13315                rm.Encode(5, 0));
13316        return;
13317      }
13318    }
13319  }
13320  Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
13321}
13322
13323void Assembler::vbic(Condition cond,
13324                     DataType dt,
13325                     DRegister rd,
13326                     DRegister rn,
13327                     const DOperand& operand) {
13328  CheckIT(cond);
13329  if (operand.IsImmediate()) {
13330    ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
13331    if (IsUsingT32()) {
13332      // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
13333      if (encoded_dt.IsValid() && rd.Is(rn)) {
13334        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13335          EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
13336                     rd.Encode(22, 12) |
13337                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13338                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13339                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13340          AdvanceIT();
13341          return;
13342        }
13343      }
13344    } else {
13345      // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
13346      if (encoded_dt.IsValid() && rd.Is(rn)) {
13347        if (cond.Is(al)) {
13348          EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
13349                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13350                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13351                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13352          return;
13353        }
13354      }
13355    }
13356  }
13357  if (operand.IsRegister()) {
13358    DRegister rm = operand.GetRegister();
13359    USE(dt);
13360    if (IsUsingT32()) {
13361      // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13362      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13363        EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13364                   rm.Encode(5, 0));
13365        AdvanceIT();
13366        return;
13367      }
13368    } else {
13369      // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13370      if (cond.Is(al)) {
13371        EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13372                rm.Encode(5, 0));
13373        return;
13374      }
13375    }
13376  }
13377  Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
13378}
13379
13380void Assembler::vbic(Condition cond,
13381                     DataType dt,
13382                     QRegister rd,
13383                     QRegister rn,
13384                     const QOperand& operand) {
13385  CheckIT(cond);
13386  if (operand.IsImmediate()) {
13387    ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
13388    if (IsUsingT32()) {
13389      // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
13390      if (encoded_dt.IsValid() && rd.Is(rn)) {
13391        if (cond.Is(al) || AllowStronglyDiscouraged()) {
13392          EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
13393                     rd.Encode(22, 12) |
13394                     (encoded_dt.GetEncodedImmediate() & 0xf) |
13395                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13396                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13397          AdvanceIT();
13398          return;
13399        }
13400      }
13401    } else {
13402      // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
13403      if (encoded_dt.IsValid() && rd.Is(rn)) {
13404        if (cond.Is(al)) {
13405          EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
13406                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13407                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13408                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13409          return;
13410        }
13411      }
13412    }
13413  }
13414  if (operand.IsRegister()) {
13415    QRegister rm = operand.GetRegister();
13416    USE(dt);
13417    if (IsUsingT32()) {
13418      // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13419      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13420        EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13421                   rm.Encode(5, 0));
13422        AdvanceIT();
13423        return;
13424      }
13425    } else {
13426      // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13427      if (cond.Is(al)) {
13428        EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13429                rm.Encode(5, 0));
13430        return;
13431      }
13432    }
13433  }
13434  Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
13435}
13436
13437void Assembler::vbif(
13438    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13439  CheckIT(cond);
13440  USE(dt);
13441  if (IsUsingT32()) {
13442    // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13443    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13444      EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13445                 rm.Encode(5, 0));
13446      AdvanceIT();
13447      return;
13448    }
13449  } else {
13450    // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13451    if (cond.Is(al)) {
13452      EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13453              rm.Encode(5, 0));
13454      return;
13455    }
13456  }
13457  Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
13458}
13459
13460void Assembler::vbif(
13461    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13462  CheckIT(cond);
13463  USE(dt);
13464  if (IsUsingT32()) {
13465    // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13466    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13467      EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13468                 rm.Encode(5, 0));
13469      AdvanceIT();
13470      return;
13471    }
13472  } else {
13473    // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13474    if (cond.Is(al)) {
13475      EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13476              rm.Encode(5, 0));
13477      return;
13478    }
13479  }
13480  Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
13481}
13482
13483void Assembler::vbit(
13484    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13485  CheckIT(cond);
13486  USE(dt);
13487  if (IsUsingT32()) {
13488    // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13489    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13490      EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13491                 rm.Encode(5, 0));
13492      AdvanceIT();
13493      return;
13494    }
13495  } else {
13496    // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13497    if (cond.Is(al)) {
13498      EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13499              rm.Encode(5, 0));
13500      return;
13501    }
13502  }
13503  Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
13504}
13505
13506void Assembler::vbit(
13507    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13508  CheckIT(cond);
13509  USE(dt);
13510  if (IsUsingT32()) {
13511    // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13512    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13513      EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13514                 rm.Encode(5, 0));
13515      AdvanceIT();
13516      return;
13517    }
13518  } else {
13519    // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13520    if (cond.Is(al)) {
13521      EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13522              rm.Encode(5, 0));
13523      return;
13524    }
13525  }
13526  Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
13527}
13528
13529void Assembler::vbsl(
13530    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13531  CheckIT(cond);
13532  USE(dt);
13533  if (IsUsingT32()) {
13534    // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13535    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13536      EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13537                 rm.Encode(5, 0));
13538      AdvanceIT();
13539      return;
13540    }
13541  } else {
13542    // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13543    if (cond.Is(al)) {
13544      EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13545              rm.Encode(5, 0));
13546      return;
13547    }
13548  }
13549  Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
13550}
13551
13552void Assembler::vbsl(
13553    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13554  CheckIT(cond);
13555  USE(dt);
13556  if (IsUsingT32()) {
13557    // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13558    if (cond.Is(al) || AllowStronglyDiscouraged()) {
13559      EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13560                 rm.Encode(5, 0));
13561      AdvanceIT();
13562      return;
13563    }
13564  } else {
13565    // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13566    if (cond.Is(al)) {
13567      EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13568              rm.Encode(5, 0));
13569      return;
13570    }
13571  }
13572  Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
13573}
13574
13575void Assembler::vceq(Condition cond,
13576                     DataType dt,
13577                     DRegister rd,
13578                     DRegister rm,
13579                     const DOperand& operand) {
13580  CheckIT(cond);
13581  if (operand.IsImmediate()) {
13582    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13583      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13584      Dt_F_size_2 encoded_dt(dt);
13585      if (IsUsingT32()) {
13586        // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
13587        if (encoded_dt.IsValid() && (imm == 0)) {
13588          if (cond.Is(al) || AllowStronglyDiscouraged()) {
13589            EmitT32_32(0xffb10100U |
13590                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13591                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13592                       rd.Encode(22, 12) | rm.Encode(5, 0));
13593            AdvanceIT();
13594            return;
13595          }
13596        }
13597      } else {
13598        // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
13599        if (encoded_dt.IsValid() && (imm == 0)) {
13600          if (cond.Is(al)) {
13601            EmitA32(0xf3b10100U |
13602                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13603                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13604                    rd.Encode(22, 12) | rm.Encode(5, 0));
13605            return;
13606          }
13607        }
13608      }
13609    }
13610  }
13611  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
13612}
13613
13614void Assembler::vceq(Condition cond,
13615                     DataType dt,
13616                     QRegister rd,
13617                     QRegister rm,
13618                     const QOperand& operand) {
13619  CheckIT(cond);
13620  if (operand.IsImmediate()) {
13621    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13622      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13623      Dt_F_size_2 encoded_dt(dt);
13624      if (IsUsingT32()) {
13625        // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
13626        if (encoded_dt.IsValid() && (imm == 0)) {
13627          if (cond.Is(al) || AllowStronglyDiscouraged()) {
13628            EmitT32_32(0xffb10140U |
13629                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13630                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13631                       rd.Encode(22, 12) | rm.Encode(5, 0));
13632            AdvanceIT();
13633            return;
13634          }
13635        }
13636      } else {
13637        // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
13638        if (encoded_dt.IsValid() && (imm == 0)) {
13639          if (cond.Is(al)) {
13640            EmitA32(0xf3b10140U |
13641                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13642                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13643                    rd.Encode(22, 12) | rm.Encode(5, 0));
13644            return;
13645          }
13646        }
13647      }
13648    }
13649  }
13650  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
13651}
13652
13653void Assembler::vceq(
13654    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13655  CheckIT(cond);
13656  Dt_size_4 encoded_dt(dt);
13657  Dt_sz_1 encoded_dt_2(dt);
13658  if (IsUsingT32()) {
13659    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
13660    if (encoded_dt.IsValid()) {
13661      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13662        EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) |
13663                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13664        AdvanceIT();
13665        return;
13666      }
13667    }
13668    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2
13669    if (encoded_dt_2.IsValid()) {
13670      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13671        EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
13672                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13673        AdvanceIT();
13674        return;
13675      }
13676    }
13677  } else {
13678    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
13679    if (encoded_dt.IsValid()) {
13680      if (cond.Is(al)) {
13681        EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) |
13682                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13683        return;
13684      }
13685    }
13686    // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2
13687    if (encoded_dt_2.IsValid()) {
13688      if (cond.Is(al)) {
13689        EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
13690                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13691        return;
13692      }
13693    }
13694  }
13695  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
13696}
13697
13698void Assembler::vceq(
13699    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13700  CheckIT(cond);
13701  Dt_size_4 encoded_dt(dt);
13702  Dt_sz_1 encoded_dt_2(dt);
13703  if (IsUsingT32()) {
13704    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
13705    if (encoded_dt.IsValid()) {
13706      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13707        EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) |
13708                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13709        AdvanceIT();
13710        return;
13711      }
13712    }
13713    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2
13714    if (encoded_dt_2.IsValid()) {
13715      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13716        EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
13717                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13718        AdvanceIT();
13719        return;
13720      }
13721    }
13722  } else {
13723    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
13724    if (encoded_dt.IsValid()) {
13725      if (cond.Is(al)) {
13726        EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) |
13727                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13728        return;
13729      }
13730    }
13731    // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2
13732    if (encoded_dt_2.IsValid()) {
13733      if (cond.Is(al)) {
13734        EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
13735                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13736        return;
13737      }
13738    }
13739  }
13740  Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
13741}
13742
13743void Assembler::vcge(Condition cond,
13744                     DataType dt,
13745                     DRegister rd,
13746                     DRegister rm,
13747                     const DOperand& operand) {
13748  CheckIT(cond);
13749  if (operand.IsImmediate()) {
13750    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13751      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13752      Dt_F_size_1 encoded_dt(dt);
13753      if (IsUsingT32()) {
13754        // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
13755        if (encoded_dt.IsValid() && (imm == 0)) {
13756          if (cond.Is(al) || AllowStronglyDiscouraged()) {
13757            EmitT32_32(0xffb10080U |
13758                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13759                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13760                       rd.Encode(22, 12) | rm.Encode(5, 0));
13761            AdvanceIT();
13762            return;
13763          }
13764        }
13765      } else {
13766        // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
13767        if (encoded_dt.IsValid() && (imm == 0)) {
13768          if (cond.Is(al)) {
13769            EmitA32(0xf3b10080U |
13770                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13771                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13772                    rd.Encode(22, 12) | rm.Encode(5, 0));
13773            return;
13774          }
13775        }
13776      }
13777    }
13778  }
13779  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
13780}
13781
13782void Assembler::vcge(Condition cond,
13783                     DataType dt,
13784                     QRegister rd,
13785                     QRegister rm,
13786                     const QOperand& operand) {
13787  CheckIT(cond);
13788  if (operand.IsImmediate()) {
13789    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13790      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13791      Dt_F_size_1 encoded_dt(dt);
13792      if (IsUsingT32()) {
13793        // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
13794        if (encoded_dt.IsValid() && (imm == 0)) {
13795          if (cond.Is(al) || AllowStronglyDiscouraged()) {
13796            EmitT32_32(0xffb100c0U |
13797                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13798                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13799                       rd.Encode(22, 12) | rm.Encode(5, 0));
13800            AdvanceIT();
13801            return;
13802          }
13803        }
13804      } else {
13805        // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
13806        if (encoded_dt.IsValid() && (imm == 0)) {
13807          if (cond.Is(al)) {
13808            EmitA32(0xf3b100c0U |
13809                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13810                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13811                    rd.Encode(22, 12) | rm.Encode(5, 0));
13812            return;
13813          }
13814        }
13815      }
13816    }
13817  }
13818  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
13819}
13820
13821void Assembler::vcge(
13822    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13823  CheckIT(cond);
13824  Dt_U_size_1 encoded_dt(dt);
13825  if (IsUsingT32()) {
13826    // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
13827    if (encoded_dt.IsValid()) {
13828      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13829        EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13830                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13831                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13832        AdvanceIT();
13833        return;
13834      }
13835    }
13836    // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
13837    if (dt.Is(F32)) {
13838      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13839        EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13840                   rm.Encode(5, 0));
13841        AdvanceIT();
13842        return;
13843      }
13844    }
13845  } else {
13846    // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
13847    if (encoded_dt.IsValid()) {
13848      if (cond.Is(al)) {
13849        EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13850                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13851                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13852        return;
13853      }
13854    }
13855    // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
13856    if (dt.Is(F32)) {
13857      if (cond.Is(al)) {
13858        EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13859                rm.Encode(5, 0));
13860        return;
13861      }
13862    }
13863  }
13864  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
13865}
13866
13867void Assembler::vcge(
13868    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13869  CheckIT(cond);
13870  Dt_U_size_1 encoded_dt(dt);
13871  if (IsUsingT32()) {
13872    // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
13873    if (encoded_dt.IsValid()) {
13874      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13875        EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13876                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13877                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13878        AdvanceIT();
13879        return;
13880      }
13881    }
13882    // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
13883    if (dt.Is(F32)) {
13884      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13885        EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13886                   rm.Encode(5, 0));
13887        AdvanceIT();
13888        return;
13889      }
13890    }
13891  } else {
13892    // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
13893    if (encoded_dt.IsValid()) {
13894      if (cond.Is(al)) {
13895        EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13896                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13897                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13898        return;
13899      }
13900    }
13901    // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
13902    if (dt.Is(F32)) {
13903      if (cond.Is(al)) {
13904        EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13905                rm.Encode(5, 0));
13906        return;
13907      }
13908    }
13909  }
13910  Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
13911}
13912
13913void Assembler::vcgt(Condition cond,
13914                     DataType dt,
13915                     DRegister rd,
13916                     DRegister rm,
13917                     const DOperand& operand) {
13918  CheckIT(cond);
13919  if (operand.IsImmediate()) {
13920    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13921      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13922      Dt_F_size_1 encoded_dt(dt);
13923      if (IsUsingT32()) {
13924        // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
13925        if (encoded_dt.IsValid() && (imm == 0)) {
13926          if (cond.Is(al) || AllowStronglyDiscouraged()) {
13927            EmitT32_32(0xffb10000U |
13928                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13929                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13930                       rd.Encode(22, 12) | rm.Encode(5, 0));
13931            AdvanceIT();
13932            return;
13933          }
13934        }
13935      } else {
13936        // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
13937        if (encoded_dt.IsValid() && (imm == 0)) {
13938          if (cond.Is(al)) {
13939            EmitA32(0xf3b10000U |
13940                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13941                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13942                    rd.Encode(22, 12) | rm.Encode(5, 0));
13943            return;
13944          }
13945        }
13946      }
13947    }
13948  }
13949  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
13950}
13951
13952void Assembler::vcgt(Condition cond,
13953                     DataType dt,
13954                     QRegister rd,
13955                     QRegister rm,
13956                     const QOperand& operand) {
13957  CheckIT(cond);
13958  if (operand.IsImmediate()) {
13959    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13960      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13961      Dt_F_size_1 encoded_dt(dt);
13962      if (IsUsingT32()) {
13963        // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
13964        if (encoded_dt.IsValid() && (imm == 0)) {
13965          if (cond.Is(al) || AllowStronglyDiscouraged()) {
13966            EmitT32_32(0xffb10040U |
13967                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13968                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13969                       rd.Encode(22, 12) | rm.Encode(5, 0));
13970            AdvanceIT();
13971            return;
13972          }
13973        }
13974      } else {
13975        // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
13976        if (encoded_dt.IsValid() && (imm == 0)) {
13977          if (cond.Is(al)) {
13978            EmitA32(0xf3b10040U |
13979                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13980                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13981                    rd.Encode(22, 12) | rm.Encode(5, 0));
13982            return;
13983          }
13984        }
13985      }
13986    }
13987  }
13988  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
13989}
13990
13991void Assembler::vcgt(
13992    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13993  CheckIT(cond);
13994  Dt_U_size_1 encoded_dt(dt);
13995  if (IsUsingT32()) {
13996    // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
13997    if (encoded_dt.IsValid()) {
13998      if (cond.Is(al) || AllowStronglyDiscouraged()) {
13999        EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14000                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14001                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14002        AdvanceIT();
14003        return;
14004      }
14005    }
14006    // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14007    if (dt.Is(F32)) {
14008      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14009        EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14010                   rm.Encode(5, 0));
14011        AdvanceIT();
14012        return;
14013      }
14014    }
14015  } else {
14016    // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14017    if (encoded_dt.IsValid()) {
14018      if (cond.Is(al)) {
14019        EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14020                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14021                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14022        return;
14023      }
14024    }
14025    // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14026    if (dt.Is(F32)) {
14027      if (cond.Is(al)) {
14028        EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14029                rm.Encode(5, 0));
14030        return;
14031      }
14032    }
14033  }
14034  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
14035}
14036
14037void Assembler::vcgt(
14038    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14039  CheckIT(cond);
14040  Dt_U_size_1 encoded_dt(dt);
14041  if (IsUsingT32()) {
14042    // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14043    if (encoded_dt.IsValid()) {
14044      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14045        EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14046                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14047                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14048        AdvanceIT();
14049        return;
14050      }
14051    }
14052    // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14053    if (dt.Is(F32)) {
14054      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14055        EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14056                   rm.Encode(5, 0));
14057        AdvanceIT();
14058        return;
14059      }
14060    }
14061  } else {
14062    // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14063    if (encoded_dt.IsValid()) {
14064      if (cond.Is(al)) {
14065        EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14066                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14067                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14068        return;
14069      }
14070    }
14071    // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14072    if (dt.Is(F32)) {
14073      if (cond.Is(al)) {
14074        EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14075                rm.Encode(5, 0));
14076        return;
14077      }
14078    }
14079  }
14080  Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
14081}
14082
14083void Assembler::vcle(Condition cond,
14084                     DataType dt,
14085                     DRegister rd,
14086                     DRegister rm,
14087                     const DOperand& operand) {
14088  CheckIT(cond);
14089  if (operand.IsImmediate()) {
14090    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14091      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14092      Dt_F_size_1 encoded_dt(dt);
14093      if (IsUsingT32()) {
14094        // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14095        if (encoded_dt.IsValid() && (imm == 0)) {
14096          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14097            EmitT32_32(0xffb10180U |
14098                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14099                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14100                       rd.Encode(22, 12) | rm.Encode(5, 0));
14101            AdvanceIT();
14102            return;
14103          }
14104        }
14105      } else {
14106        // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14107        if (encoded_dt.IsValid() && (imm == 0)) {
14108          if (cond.Is(al)) {
14109            EmitA32(0xf3b10180U |
14110                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14111                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14112                    rd.Encode(22, 12) | rm.Encode(5, 0));
14113            return;
14114          }
14115        }
14116      }
14117    }
14118  }
14119  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
14120}
14121
14122void Assembler::vcle(Condition cond,
14123                     DataType dt,
14124                     QRegister rd,
14125                     QRegister rm,
14126                     const QOperand& operand) {
14127  CheckIT(cond);
14128  if (operand.IsImmediate()) {
14129    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14130      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14131      Dt_F_size_1 encoded_dt(dt);
14132      if (IsUsingT32()) {
14133        // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14134        if (encoded_dt.IsValid() && (imm == 0)) {
14135          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14136            EmitT32_32(0xffb101c0U |
14137                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14138                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14139                       rd.Encode(22, 12) | rm.Encode(5, 0));
14140            AdvanceIT();
14141            return;
14142          }
14143        }
14144      } else {
14145        // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14146        if (encoded_dt.IsValid() && (imm == 0)) {
14147          if (cond.Is(al)) {
14148            EmitA32(0xf3b101c0U |
14149                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14150                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14151                    rd.Encode(22, 12) | rm.Encode(5, 0));
14152            return;
14153          }
14154        }
14155      }
14156    }
14157  }
14158  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
14159}
14160
14161void Assembler::vcle(
14162    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14163  CheckIT(cond);
14164  Dt_U_size_1 encoded_dt(dt);
14165  if (IsUsingT32()) {
14166    // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14167    if (encoded_dt.IsValid()) {
14168      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14169        EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14170                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14171                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14172        AdvanceIT();
14173        return;
14174      }
14175    }
14176    // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14177    if (dt.Is(F32)) {
14178      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14179        EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14180                   rm.Encode(5, 0));
14181        AdvanceIT();
14182        return;
14183      }
14184    }
14185  } else {
14186    // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14187    if (encoded_dt.IsValid()) {
14188      if (cond.Is(al)) {
14189        EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14190                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14191                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14192        return;
14193      }
14194    }
14195    // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14196    if (dt.Is(F32)) {
14197      if (cond.Is(al)) {
14198        EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14199                rm.Encode(5, 0));
14200        return;
14201      }
14202    }
14203  }
14204  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
14205}
14206
14207void Assembler::vcle(
14208    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14209  CheckIT(cond);
14210  Dt_U_size_1 encoded_dt(dt);
14211  if (IsUsingT32()) {
14212    // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14213    if (encoded_dt.IsValid()) {
14214      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14215        EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14216                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14217                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14218        AdvanceIT();
14219        return;
14220      }
14221    }
14222    // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14223    if (dt.Is(F32)) {
14224      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14225        EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14226                   rm.Encode(5, 0));
14227        AdvanceIT();
14228        return;
14229      }
14230    }
14231  } else {
14232    // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14233    if (encoded_dt.IsValid()) {
14234      if (cond.Is(al)) {
14235        EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14236                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14237                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14238        return;
14239      }
14240    }
14241    // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14242    if (dt.Is(F32)) {
14243      if (cond.Is(al)) {
14244        EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14245                rm.Encode(5, 0));
14246        return;
14247      }
14248    }
14249  }
14250  Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
14251}
14252
14253void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14254  CheckIT(cond);
14255  Dt_size_5 encoded_dt(dt);
14256  if (IsUsingT32()) {
14257    // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
14258    if (encoded_dt.IsValid()) {
14259      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14260        EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) |
14261                   rd.Encode(22, 12) | rm.Encode(5, 0));
14262        AdvanceIT();
14263        return;
14264      }
14265    }
14266  } else {
14267    // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
14268    if (encoded_dt.IsValid()) {
14269      if (cond.Is(al)) {
14270        EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) |
14271                rd.Encode(22, 12) | rm.Encode(5, 0));
14272        return;
14273      }
14274    }
14275  }
14276  Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
14277}
14278
14279void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14280  CheckIT(cond);
14281  Dt_size_5 encoded_dt(dt);
14282  if (IsUsingT32()) {
14283    // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
14284    if (encoded_dt.IsValid()) {
14285      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14286        EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) |
14287                   rd.Encode(22, 12) | rm.Encode(5, 0));
14288        AdvanceIT();
14289        return;
14290      }
14291    }
14292  } else {
14293    // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
14294    if (encoded_dt.IsValid()) {
14295      if (cond.Is(al)) {
14296        EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) |
14297                rd.Encode(22, 12) | rm.Encode(5, 0));
14298        return;
14299      }
14300    }
14301  }
14302  Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
14303}
14304
14305void Assembler::vclt(Condition cond,
14306                     DataType dt,
14307                     DRegister rd,
14308                     DRegister rm,
14309                     const DOperand& operand) {
14310  CheckIT(cond);
14311  if (operand.IsImmediate()) {
14312    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14313      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14314      Dt_F_size_1 encoded_dt(dt);
14315      if (IsUsingT32()) {
14316        // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14317        if (encoded_dt.IsValid() && (imm == 0)) {
14318          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14319            EmitT32_32(0xffb10200U |
14320                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14321                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14322                       rd.Encode(22, 12) | rm.Encode(5, 0));
14323            AdvanceIT();
14324            return;
14325          }
14326        }
14327      } else {
14328        // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14329        if (encoded_dt.IsValid() && (imm == 0)) {
14330          if (cond.Is(al)) {
14331            EmitA32(0xf3b10200U |
14332                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14333                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14334                    rd.Encode(22, 12) | rm.Encode(5, 0));
14335            return;
14336          }
14337        }
14338      }
14339    }
14340  }
14341  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
14342}
14343
14344void Assembler::vclt(Condition cond,
14345                     DataType dt,
14346                     QRegister rd,
14347                     QRegister rm,
14348                     const QOperand& operand) {
14349  CheckIT(cond);
14350  if (operand.IsImmediate()) {
14351    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14352      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14353      Dt_F_size_1 encoded_dt(dt);
14354      if (IsUsingT32()) {
14355        // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14356        if (encoded_dt.IsValid() && (imm == 0)) {
14357          if (cond.Is(al) || AllowStronglyDiscouraged()) {
14358            EmitT32_32(0xffb10240U |
14359                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14360                       ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14361                       rd.Encode(22, 12) | rm.Encode(5, 0));
14362            AdvanceIT();
14363            return;
14364          }
14365        }
14366      } else {
14367        // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14368        if (encoded_dt.IsValid() && (imm == 0)) {
14369          if (cond.Is(al)) {
14370            EmitA32(0xf3b10240U |
14371                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14372                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14373                    rd.Encode(22, 12) | rm.Encode(5, 0));
14374            return;
14375          }
14376        }
14377      }
14378    }
14379  }
14380  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
14381}
14382
14383void Assembler::vclt(
14384    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14385  CheckIT(cond);
14386  Dt_U_size_1 encoded_dt(dt);
14387  if (IsUsingT32()) {
14388    // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14389    if (encoded_dt.IsValid()) {
14390      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14391        EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14392                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14393                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14394        AdvanceIT();
14395        return;
14396      }
14397    }
14398    // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14399    if (dt.Is(F32)) {
14400      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14401        EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14402                   rm.Encode(5, 0));
14403        AdvanceIT();
14404        return;
14405      }
14406    }
14407  } else {
14408    // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14409    if (encoded_dt.IsValid()) {
14410      if (cond.Is(al)) {
14411        EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14412                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14413                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14414        return;
14415      }
14416    }
14417    // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14418    if (dt.Is(F32)) {
14419      if (cond.Is(al)) {
14420        EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14421                rm.Encode(5, 0));
14422        return;
14423      }
14424    }
14425  }
14426  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
14427}
14428
14429void Assembler::vclt(
14430    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14431  CheckIT(cond);
14432  Dt_U_size_1 encoded_dt(dt);
14433  if (IsUsingT32()) {
14434    // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14435    if (encoded_dt.IsValid()) {
14436      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14437        EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14438                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14439                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14440        AdvanceIT();
14441        return;
14442      }
14443    }
14444    // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14445    if (dt.Is(F32)) {
14446      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14447        EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14448                   rm.Encode(5, 0));
14449        AdvanceIT();
14450        return;
14451      }
14452    }
14453  } else {
14454    // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14455    if (encoded_dt.IsValid()) {
14456      if (cond.Is(al)) {
14457        EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14458                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14459                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14460        return;
14461      }
14462    }
14463    // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14464    if (dt.Is(F32)) {
14465      if (cond.Is(al)) {
14466        EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14467                rm.Encode(5, 0));
14468        return;
14469      }
14470    }
14471  }
14472  Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
14473}
14474
14475void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14476  CheckIT(cond);
14477  Dt_size_4 encoded_dt(dt);
14478  if (IsUsingT32()) {
14479    // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
14480    if (encoded_dt.IsValid()) {
14481      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14482        EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) |
14483                   rd.Encode(22, 12) | rm.Encode(5, 0));
14484        AdvanceIT();
14485        return;
14486      }
14487    }
14488  } else {
14489    // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
14490    if (encoded_dt.IsValid()) {
14491      if (cond.Is(al)) {
14492        EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) |
14493                rd.Encode(22, 12) | rm.Encode(5, 0));
14494        return;
14495      }
14496    }
14497  }
14498  Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
14499}
14500
14501void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14502  CheckIT(cond);
14503  Dt_size_4 encoded_dt(dt);
14504  if (IsUsingT32()) {
14505    // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
14506    if (encoded_dt.IsValid()) {
14507      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14508        EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) |
14509                   rd.Encode(22, 12) | rm.Encode(5, 0));
14510        AdvanceIT();
14511        return;
14512      }
14513    }
14514  } else {
14515    // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
14516    if (encoded_dt.IsValid()) {
14517      if (cond.Is(al)) {
14518        EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) |
14519                rd.Encode(22, 12) | rm.Encode(5, 0));
14520        return;
14521      }
14522    }
14523  }
14524  Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
14525}
14526
14527void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, SRegister rm) {
14528  CheckIT(cond);
14529  if (IsUsingT32()) {
14530    // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
14531    if (dt.Is(F32)) {
14532      EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
14533      AdvanceIT();
14534      return;
14535    }
14536  } else {
14537    // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
14538    if (dt.Is(F32) && cond.IsNotNever()) {
14539      EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14540              rm.Encode(5, 0));
14541      return;
14542    }
14543  }
14544  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm);
14545}
14546
14547void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14548  CheckIT(cond);
14549  if (IsUsingT32()) {
14550    // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
14551    if (dt.Is(F64)) {
14552      EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
14553      AdvanceIT();
14554      return;
14555    }
14556  } else {
14557    // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
14558    if (dt.Is(F64) && cond.IsNotNever()) {
14559      EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14560              rm.Encode(5, 0));
14561      return;
14562    }
14563  }
14564  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm);
14565}
14566
14567void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, double imm) {
14568  CheckIT(cond);
14569  if (IsUsingT32()) {
14570    // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
14571    if (dt.Is(F32) && (imm == 0.0)) {
14572      EmitT32_32(0xeeb50a40U | rd.Encode(22, 12));
14573      AdvanceIT();
14574      return;
14575    }
14576  } else {
14577    // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
14578    if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) {
14579      EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14580      return;
14581    }
14582  }
14583  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm);
14584}
14585
14586void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, double imm) {
14587  CheckIT(cond);
14588  if (IsUsingT32()) {
14589    // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
14590    if (dt.Is(F64) && (imm == 0.0)) {
14591      EmitT32_32(0xeeb50b40U | rd.Encode(22, 12));
14592      AdvanceIT();
14593      return;
14594    }
14595  } else {
14596    // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
14597    if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) {
14598      EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14599      return;
14600    }
14601  }
14602  Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm);
14603}
14604
14605void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, SRegister rm) {
14606  CheckIT(cond);
14607  if (IsUsingT32()) {
14608    // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
14609    if (dt.Is(F32)) {
14610      EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14611      AdvanceIT();
14612      return;
14613    }
14614  } else {
14615    // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
14616    if (dt.Is(F32) && cond.IsNotNever()) {
14617      EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14618              rm.Encode(5, 0));
14619      return;
14620    }
14621  }
14622  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm);
14623}
14624
14625void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14626  CheckIT(cond);
14627  if (IsUsingT32()) {
14628    // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
14629    if (dt.Is(F64)) {
14630      EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14631      AdvanceIT();
14632      return;
14633    }
14634  } else {
14635    // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
14636    if (dt.Is(F64) && cond.IsNotNever()) {
14637      EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14638              rm.Encode(5, 0));
14639      return;
14640    }
14641  }
14642  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm);
14643}
14644
14645void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, double imm) {
14646  CheckIT(cond);
14647  if (IsUsingT32()) {
14648    // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
14649    if (dt.Is(F32) && (imm == 0.0)) {
14650      EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12));
14651      AdvanceIT();
14652      return;
14653    }
14654  } else {
14655    // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
14656    if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) {
14657      EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14658      return;
14659    }
14660  }
14661  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm);
14662}
14663
14664void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, double imm) {
14665  CheckIT(cond);
14666  if (IsUsingT32()) {
14667    // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
14668    if (dt.Is(F64) && (imm == 0.0)) {
14669      EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12));
14670      AdvanceIT();
14671      return;
14672    }
14673  } else {
14674    // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
14675    if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) {
14676      EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14677      return;
14678    }
14679  }
14680  Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm);
14681}
14682
14683void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14684  CheckIT(cond);
14685  if (IsUsingT32()) {
14686    // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1
14687    if (dt.Is(Untyped8)) {
14688      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14689        EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
14690        AdvanceIT();
14691        return;
14692      }
14693    }
14694  } else {
14695    // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1
14696    if (dt.Is(Untyped8)) {
14697      if (cond.Is(al)) {
14698        EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
14699        return;
14700      }
14701    }
14702  }
14703  Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
14704}
14705
14706void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14707  CheckIT(cond);
14708  if (IsUsingT32()) {
14709    // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1
14710    if (dt.Is(Untyped8)) {
14711      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14712        EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
14713        AdvanceIT();
14714        return;
14715      }
14716    }
14717  } else {
14718    // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1
14719    if (dt.Is(Untyped8)) {
14720      if (cond.Is(al)) {
14721        EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
14722        return;
14723      }
14724    }
14725  }
14726  Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
14727}
14728
14729void Assembler::vcvt(
14730    Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
14731  CheckIT(cond);
14732  Dt_op_2 encoded_dt(dt2);
14733  if (IsUsingT32()) {
14734    // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1
14735    if (dt1.Is(F64) && dt2.Is(F32)) {
14736      EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14737      AdvanceIT();
14738      return;
14739    }
14740    // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1
14741    if (dt1.Is(F64) && encoded_dt.IsValid()) {
14742      EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) |
14743                 rd.Encode(22, 12) | rm.Encode(5, 0));
14744      AdvanceIT();
14745      return;
14746    }
14747  } else {
14748    // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1
14749    if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) {
14750      EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14751              rm.Encode(5, 0));
14752      return;
14753    }
14754    // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1
14755    if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) {
14756      EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) |
14757              (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
14758              rm.Encode(5, 0));
14759      return;
14760    }
14761  }
14762  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
14763}
14764
14765void Assembler::vcvt(
14766    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
14767  CheckIT(cond);
14768  if (IsUsingT32()) {
14769    // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1
14770    if (dt1.Is(F32) && dt2.Is(F64)) {
14771      EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14772      AdvanceIT();
14773      return;
14774    }
14775    // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
14776    if (dt1.Is(U32) && dt2.Is(F64)) {
14777      EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14778      AdvanceIT();
14779      return;
14780    }
14781    // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
14782    if (dt1.Is(S32) && dt2.Is(F64)) {
14783      EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14784      AdvanceIT();
14785      return;
14786    }
14787  } else {
14788    // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1
14789    if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) {
14790      EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14791              rm.Encode(5, 0));
14792      return;
14793    }
14794    // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
14795    if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
14796      EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14797              rm.Encode(5, 0));
14798      return;
14799    }
14800    // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
14801    if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
14802      EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14803              rm.Encode(5, 0));
14804      return;
14805    }
14806  }
14807  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
14808}
14809
14810void Assembler::vcvt(Condition cond,
14811                     DataType dt1,
14812                     DataType dt2,
14813                     DRegister rd,
14814                     DRegister rm,
14815                     int32_t fbits) {
14816  CheckIT(cond);
14817  Dt_op_U_1 encoded_dt(dt1, dt2);
14818  Dt_U_sx_1 encoded_dt_2(dt2);
14819  Dt_U_sx_1 encoded_dt_3(dt1);
14820  if (IsUsingT32()) {
14821    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1
14822    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
14823      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14824        uint32_t fbits_ = 64 - fbits;
14825        EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
14826                   ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
14827                   rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
14828        AdvanceIT();
14829        return;
14830      }
14831    }
14832    // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1
14833    if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
14834        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
14835         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
14836      unsigned offset = 32;
14837      if (dt2.Is(S16) || dt2.Is(U16)) {
14838        offset = 16;
14839      }
14840      uint32_t fbits_ = offset - fbits;
14841      EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
14842                 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
14843                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
14844                 ((fbits_ & 0x1e) >> 1));
14845      AdvanceIT();
14846      return;
14847    }
14848    // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1
14849    if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
14850        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
14851         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
14852      unsigned offset = 32;
14853      if (dt1.Is(S16) || dt1.Is(U16)) {
14854        offset = 16;
14855      }
14856      uint32_t fbits_ = offset - fbits;
14857      EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
14858                 ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
14859                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
14860                 ((fbits_ & 0x1e) >> 1));
14861      AdvanceIT();
14862      return;
14863    }
14864  } else {
14865    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1
14866    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
14867      if (cond.Is(al)) {
14868        uint32_t fbits_ = 64 - fbits;
14869        EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
14870                ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
14871                rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
14872        return;
14873      }
14874    }
14875    // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1
14876    if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
14877        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
14878         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
14879        cond.IsNotNever()) {
14880      unsigned offset = 32;
14881      if (dt2.Is(S16) || dt2.Is(U16)) {
14882        offset = 16;
14883      }
14884      uint32_t fbits_ = offset - fbits;
14885      EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) |
14886              ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
14887              ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
14888              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
14889              ((fbits_ & 0x1e) >> 1));
14890      return;
14891    }
14892    // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1
14893    if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
14894        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
14895         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
14896        cond.IsNotNever()) {
14897      unsigned offset = 32;
14898      if (dt1.Is(S16) || dt1.Is(U16)) {
14899        offset = 16;
14900      }
14901      uint32_t fbits_ = offset - fbits;
14902      EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) |
14903              ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
14904              ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
14905              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
14906              ((fbits_ & 0x1e) >> 1));
14907      return;
14908    }
14909  }
14910  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
14911}
14912
14913void Assembler::vcvt(Condition cond,
14914                     DataType dt1,
14915                     DataType dt2,
14916                     QRegister rd,
14917                     QRegister rm,
14918                     int32_t fbits) {
14919  CheckIT(cond);
14920  Dt_op_U_1 encoded_dt(dt1, dt2);
14921  if (IsUsingT32()) {
14922    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1
14923    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
14924      if (cond.Is(al) || AllowStronglyDiscouraged()) {
14925        uint32_t fbits_ = 64 - fbits;
14926        EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
14927                   ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
14928                   rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
14929        AdvanceIT();
14930        return;
14931      }
14932    }
14933  } else {
14934    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1
14935    if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
14936      if (cond.Is(al)) {
14937        uint32_t fbits_ = 64 - fbits;
14938        EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
14939                ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
14940                rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
14941        return;
14942      }
14943    }
14944  }
14945  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
14946}
14947
14948void Assembler::vcvt(Condition cond,
14949                     DataType dt1,
14950                     DataType dt2,
14951                     SRegister rd,
14952                     SRegister rm,
14953                     int32_t fbits) {
14954  CheckIT(cond);
14955  Dt_U_sx_1 encoded_dt(dt2);
14956  Dt_U_sx_1 encoded_dt_2(dt1);
14957  if (IsUsingT32()) {
14958    // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1
14959    if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
14960        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
14961         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
14962      unsigned offset = 32;
14963      if (dt2.Is(S16) || dt2.Is(U16)) {
14964        offset = 16;
14965      }
14966      uint32_t fbits_ = offset - fbits;
14967      EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
14968                 ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
14969                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
14970                 ((fbits_ & 0x1e) >> 1));
14971      AdvanceIT();
14972      return;
14973    }
14974    // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1
14975    if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
14976        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
14977         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
14978      unsigned offset = 32;
14979      if (dt1.Is(S16) || dt1.Is(U16)) {
14980        offset = 16;
14981      }
14982      uint32_t fbits_ = offset - fbits;
14983      EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
14984                 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
14985                 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
14986                 ((fbits_ & 0x1e) >> 1));
14987      AdvanceIT();
14988      return;
14989    }
14990  } else {
14991    // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1
14992    if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
14993        (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
14994         ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
14995        cond.IsNotNever()) {
14996      unsigned offset = 32;
14997      if (dt2.Is(S16) || dt2.Is(U16)) {
14998        offset = 16;
14999      }
15000      uint32_t fbits_ = offset - fbits;
15001      EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) |
15002              ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
15003              ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
15004              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15005              ((fbits_ & 0x1e) >> 1));
15006      return;
15007    }
15008    // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1
15009    if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
15010        (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15011         ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15012        cond.IsNotNever()) {
15013      unsigned offset = 32;
15014      if (dt1.Is(S16) || dt1.Is(U16)) {
15015        offset = 16;
15016      }
15017      uint32_t fbits_ = offset - fbits;
15018      EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) |
15019              ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15020              ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15021              rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15022              ((fbits_ & 0x1e) >> 1));
15023      return;
15024    }
15025  }
15026  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
15027}
15028
15029void Assembler::vcvt(
15030    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15031  CheckIT(cond);
15032  Dt_op_1 encoded_dt(dt1, dt2);
15033  if (IsUsingT32()) {
15034    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1
15035    if (encoded_dt.IsValid()) {
15036      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15037        EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) |
15038                   rd.Encode(22, 12) | rm.Encode(5, 0));
15039        AdvanceIT();
15040        return;
15041      }
15042    }
15043  } else {
15044    // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1
15045    if (encoded_dt.IsValid()) {
15046      if (cond.Is(al)) {
15047        EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) |
15048                rd.Encode(22, 12) | rm.Encode(5, 0));
15049        return;
15050      }
15051    }
15052  }
15053  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15054}
15055
15056void Assembler::vcvt(
15057    Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15058  CheckIT(cond);
15059  Dt_op_1 encoded_dt(dt1, dt2);
15060  if (IsUsingT32()) {
15061    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1
15062    if (encoded_dt.IsValid()) {
15063      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15064        EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) |
15065                   rd.Encode(22, 12) | rm.Encode(5, 0));
15066        AdvanceIT();
15067        return;
15068      }
15069    }
15070  } else {
15071    // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1
15072    if (encoded_dt.IsValid()) {
15073      if (cond.Is(al)) {
15074        EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) |
15075                rd.Encode(22, 12) | rm.Encode(5, 0));
15076        return;
15077      }
15078    }
15079  }
15080  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15081}
15082
15083void Assembler::vcvt(
15084    Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) {
15085  CheckIT(cond);
15086  if (IsUsingT32()) {
15087    // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1
15088    if (dt1.Is(F16) && dt2.Is(F32)) {
15089      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15090        EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
15091        AdvanceIT();
15092        return;
15093      }
15094    }
15095  } else {
15096    // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1
15097    if (dt1.Is(F16) && dt2.Is(F32)) {
15098      if (cond.Is(al)) {
15099        EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
15100        return;
15101      }
15102    }
15103  }
15104  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15105}
15106
15107void Assembler::vcvt(
15108    Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) {
15109  CheckIT(cond);
15110  if (IsUsingT32()) {
15111    // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1
15112    if (dt1.Is(F32) && dt2.Is(F16)) {
15113      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15114        EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
15115        AdvanceIT();
15116        return;
15117      }
15118    }
15119  } else {
15120    // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1
15121    if (dt1.Is(F32) && dt2.Is(F16)) {
15122      if (cond.Is(al)) {
15123        EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
15124        return;
15125      }
15126    }
15127  }
15128  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15129}
15130
15131void Assembler::vcvt(
15132    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15133  CheckIT(cond);
15134  Dt_op_2 encoded_dt(dt2);
15135  if (IsUsingT32()) {
15136    // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
15137    if (dt1.Is(U32) && dt2.Is(F32)) {
15138      EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15139      AdvanceIT();
15140      return;
15141    }
15142    // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
15143    if (dt1.Is(S32) && dt2.Is(F32)) {
15144      EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15145      AdvanceIT();
15146      return;
15147    }
15148    // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1
15149    if (dt1.Is(F32) && encoded_dt.IsValid()) {
15150      EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) |
15151                 rd.Encode(22, 12) | rm.Encode(5, 0));
15152      AdvanceIT();
15153      return;
15154    }
15155  } else {
15156    // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
15157    if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
15158      EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15159              rm.Encode(5, 0));
15160      return;
15161    }
15162    // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
15163    if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
15164      EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15165              rm.Encode(5, 0));
15166      return;
15167    }
15168    // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1
15169    if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) {
15170      EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) |
15171              (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
15172              rm.Encode(5, 0));
15173      return;
15174    }
15175  }
15176  Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15177}
15178
15179void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15180  CheckIT(al);
15181  Dt_op_3 encoded_dt(dt1);
15182  if (IsUsingT32()) {
15183    // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15184    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15185      EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) |
15186                 rd.Encode(22, 12) | rm.Encode(5, 0));
15187      AdvanceIT();
15188      return;
15189    }
15190  } else {
15191    // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15192    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15193      EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) |
15194              rd.Encode(22, 12) | rm.Encode(5, 0));
15195      return;
15196    }
15197  }
15198  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15199}
15200
15201void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15202  CheckIT(al);
15203  Dt_op_3 encoded_dt(dt1);
15204  if (IsUsingT32()) {
15205    // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15206    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15207      EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) |
15208                 rd.Encode(22, 12) | rm.Encode(5, 0));
15209      AdvanceIT();
15210      return;
15211    }
15212  } else {
15213    // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15214    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15215      EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) |
15216              rd.Encode(22, 12) | rm.Encode(5, 0));
15217      return;
15218    }
15219  }
15220  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15221}
15222
15223void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15224  CheckIT(al);
15225  Dt_op_2 encoded_dt(dt1);
15226  if (IsUsingT32()) {
15227    // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15228    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15229      EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
15230                 rd.Encode(22, 12) | rm.Encode(5, 0));
15231      AdvanceIT();
15232      return;
15233    }
15234  } else {
15235    // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15236    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15237      EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
15238              rd.Encode(22, 12) | rm.Encode(5, 0));
15239      return;
15240    }
15241  }
15242  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15243}
15244
15245void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15246  CheckIT(al);
15247  Dt_op_2 encoded_dt(dt1);
15248  if (IsUsingT32()) {
15249    // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15250    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15251      EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
15252                 rd.Encode(22, 12) | rm.Encode(5, 0));
15253      AdvanceIT();
15254      return;
15255    }
15256  } else {
15257    // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15258    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15259      EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
15260              rd.Encode(22, 12) | rm.Encode(5, 0));
15261      return;
15262    }
15263  }
15264  Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15265}
15266
15267void Assembler::vcvtb(
15268    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15269  CheckIT(cond);
15270  if (IsUsingT32()) {
15271    // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
15272    if (dt1.Is(F32) && dt2.Is(F16)) {
15273      EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15274      AdvanceIT();
15275      return;
15276    }
15277    // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
15278    if (dt1.Is(F16) && dt2.Is(F32)) {
15279      EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15280      AdvanceIT();
15281      return;
15282    }
15283  } else {
15284    // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
15285    if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
15286      EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15287              rm.Encode(5, 0));
15288      return;
15289    }
15290    // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
15291    if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
15292      EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15293              rm.Encode(5, 0));
15294      return;
15295    }
15296  }
15297  Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15298}
15299
15300void Assembler::vcvtb(
15301    Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
15302  CheckIT(cond);
15303  if (IsUsingT32()) {
15304    // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
15305    if (dt1.Is(F64) && dt2.Is(F16)) {
15306      EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15307      AdvanceIT();
15308      return;
15309    }
15310  } else {
15311    // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
15312    if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
15313      EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15314              rm.Encode(5, 0));
15315      return;
15316    }
15317  }
15318  Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15319}
15320
15321void Assembler::vcvtb(
15322    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15323  CheckIT(cond);
15324  if (IsUsingT32()) {
15325    // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
15326    if (dt1.Is(F16) && dt2.Is(F64)) {
15327      EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15328      AdvanceIT();
15329      return;
15330    }
15331  } else {
15332    // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
15333    if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
15334      EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15335              rm.Encode(5, 0));
15336      return;
15337    }
15338  }
15339  Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15340}
15341
15342void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15343  CheckIT(al);
15344  Dt_op_3 encoded_dt(dt1);
15345  if (IsUsingT32()) {
15346    // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15347    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15348      EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) |
15349                 rd.Encode(22, 12) | rm.Encode(5, 0));
15350      AdvanceIT();
15351      return;
15352    }
15353  } else {
15354    // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15355    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15356      EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) |
15357              rd.Encode(22, 12) | rm.Encode(5, 0));
15358      return;
15359    }
15360  }
15361  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15362}
15363
15364void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15365  CheckIT(al);
15366  Dt_op_3 encoded_dt(dt1);
15367  if (IsUsingT32()) {
15368    // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15369    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15370      EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) |
15371                 rd.Encode(22, 12) | rm.Encode(5, 0));
15372      AdvanceIT();
15373      return;
15374    }
15375  } else {
15376    // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15377    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15378      EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) |
15379              rd.Encode(22, 12) | rm.Encode(5, 0));
15380      return;
15381    }
15382  }
15383  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15384}
15385
15386void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15387  CheckIT(al);
15388  Dt_op_2 encoded_dt(dt1);
15389  if (IsUsingT32()) {
15390    // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15391    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15392      EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
15393                 rd.Encode(22, 12) | rm.Encode(5, 0));
15394      AdvanceIT();
15395      return;
15396    }
15397  } else {
15398    // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15399    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15400      EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
15401              rd.Encode(22, 12) | rm.Encode(5, 0));
15402      return;
15403    }
15404  }
15405  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15406}
15407
15408void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15409  CheckIT(al);
15410  Dt_op_2 encoded_dt(dt1);
15411  if (IsUsingT32()) {
15412    // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15413    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15414      EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
15415                 rd.Encode(22, 12) | rm.Encode(5, 0));
15416      AdvanceIT();
15417      return;
15418    }
15419  } else {
15420    // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15421    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15422      EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
15423              rd.Encode(22, 12) | rm.Encode(5, 0));
15424      return;
15425    }
15426  }
15427  Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15428}
15429
15430void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15431  CheckIT(al);
15432  Dt_op_3 encoded_dt(dt1);
15433  if (IsUsingT32()) {
15434    // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15435    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15436      EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) |
15437                 rd.Encode(22, 12) | rm.Encode(5, 0));
15438      AdvanceIT();
15439      return;
15440    }
15441  } else {
15442    // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15443    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15444      EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) |
15445              rd.Encode(22, 12) | rm.Encode(5, 0));
15446      return;
15447    }
15448  }
15449  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15450}
15451
15452void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15453  CheckIT(al);
15454  Dt_op_3 encoded_dt(dt1);
15455  if (IsUsingT32()) {
15456    // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15457    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15458      EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) |
15459                 rd.Encode(22, 12) | rm.Encode(5, 0));
15460      AdvanceIT();
15461      return;
15462    }
15463  } else {
15464    // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15465    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15466      EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) |
15467              rd.Encode(22, 12) | rm.Encode(5, 0));
15468      return;
15469    }
15470  }
15471  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15472}
15473
15474void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15475  CheckIT(al);
15476  Dt_op_2 encoded_dt(dt1);
15477  if (IsUsingT32()) {
15478    // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15479    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15480      EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
15481                 rd.Encode(22, 12) | rm.Encode(5, 0));
15482      AdvanceIT();
15483      return;
15484    }
15485  } else {
15486    // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15487    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15488      EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
15489              rd.Encode(22, 12) | rm.Encode(5, 0));
15490      return;
15491    }
15492  }
15493  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15494}
15495
15496void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15497  CheckIT(al);
15498  Dt_op_2 encoded_dt(dt1);
15499  if (IsUsingT32()) {
15500    // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15501    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15502      EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
15503                 rd.Encode(22, 12) | rm.Encode(5, 0));
15504      AdvanceIT();
15505      return;
15506    }
15507  } else {
15508    // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15509    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15510      EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
15511              rd.Encode(22, 12) | rm.Encode(5, 0));
15512      return;
15513    }
15514  }
15515  Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15516}
15517
15518void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15519  CheckIT(al);
15520  Dt_op_3 encoded_dt(dt1);
15521  if (IsUsingT32()) {
15522    // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15523    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15524      EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) |
15525                 rd.Encode(22, 12) | rm.Encode(5, 0));
15526      AdvanceIT();
15527      return;
15528    }
15529  } else {
15530    // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15531    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15532      EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) |
15533              rd.Encode(22, 12) | rm.Encode(5, 0));
15534      return;
15535    }
15536  }
15537  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15538}
15539
15540void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15541  CheckIT(al);
15542  Dt_op_3 encoded_dt(dt1);
15543  if (IsUsingT32()) {
15544    // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15545    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15546      EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) |
15547                 rd.Encode(22, 12) | rm.Encode(5, 0));
15548      AdvanceIT();
15549      return;
15550    }
15551  } else {
15552    // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15553    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15554      EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) |
15555              rd.Encode(22, 12) | rm.Encode(5, 0));
15556      return;
15557    }
15558  }
15559  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15560}
15561
15562void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15563  CheckIT(al);
15564  Dt_op_2 encoded_dt(dt1);
15565  if (IsUsingT32()) {
15566    // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15567    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15568      EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
15569                 rd.Encode(22, 12) | rm.Encode(5, 0));
15570      AdvanceIT();
15571      return;
15572    }
15573  } else {
15574    // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15575    if (encoded_dt.IsValid() && dt2.Is(F32)) {
15576      EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
15577              rd.Encode(22, 12) | rm.Encode(5, 0));
15578      return;
15579    }
15580  }
15581  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15582}
15583
15584void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15585  CheckIT(al);
15586  Dt_op_2 encoded_dt(dt1);
15587  if (IsUsingT32()) {
15588    // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15589    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15590      EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
15591                 rd.Encode(22, 12) | rm.Encode(5, 0));
15592      AdvanceIT();
15593      return;
15594    }
15595  } else {
15596    // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15597    if (encoded_dt.IsValid() && dt2.Is(F64)) {
15598      EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
15599              rd.Encode(22, 12) | rm.Encode(5, 0));
15600      return;
15601    }
15602  }
15603  Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15604}
15605
15606void Assembler::vcvtr(
15607    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15608  CheckIT(cond);
15609  if (IsUsingT32()) {
15610    // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
15611    if (dt1.Is(U32) && dt2.Is(F32)) {
15612      EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15613      AdvanceIT();
15614      return;
15615    }
15616    // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
15617    if (dt1.Is(S32) && dt2.Is(F32)) {
15618      EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15619      AdvanceIT();
15620      return;
15621    }
15622  } else {
15623    // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
15624    if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
15625      EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15626              rm.Encode(5, 0));
15627      return;
15628    }
15629    // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
15630    if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
15631      EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15632              rm.Encode(5, 0));
15633      return;
15634    }
15635  }
15636  Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
15637}
15638
15639void Assembler::vcvtr(
15640    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15641  CheckIT(cond);
15642  if (IsUsingT32()) {
15643    // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
15644    if (dt1.Is(U32) && dt2.Is(F64)) {
15645      EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15646      AdvanceIT();
15647      return;
15648    }
15649    // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
15650    if (dt1.Is(S32) && dt2.Is(F64)) {
15651      EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15652      AdvanceIT();
15653      return;
15654    }
15655  } else {
15656    // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
15657    if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
15658      EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15659              rm.Encode(5, 0));
15660      return;
15661    }
15662    // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
15663    if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
15664      EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15665              rm.Encode(5, 0));
15666      return;
15667    }
15668  }
15669  Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
15670}
15671
15672void Assembler::vcvtt(
15673    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15674  CheckIT(cond);
15675  if (IsUsingT32()) {
15676    // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
15677    if (dt1.Is(F32) && dt2.Is(F16)) {
15678      EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15679      AdvanceIT();
15680      return;
15681    }
15682    // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
15683    if (dt1.Is(F16) && dt2.Is(F32)) {
15684      EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15685      AdvanceIT();
15686      return;
15687    }
15688  } else {
15689    // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
15690    if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
15691      EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15692              rm.Encode(5, 0));
15693      return;
15694    }
15695    // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
15696    if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
15697      EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15698              rm.Encode(5, 0));
15699      return;
15700    }
15701  }
15702  Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
15703}
15704
15705void Assembler::vcvtt(
15706    Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
15707  CheckIT(cond);
15708  if (IsUsingT32()) {
15709    // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
15710    if (dt1.Is(F64) && dt2.Is(F16)) {
15711      EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15712      AdvanceIT();
15713      return;
15714    }
15715  } else {
15716    // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
15717    if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
15718      EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15719              rm.Encode(5, 0));
15720      return;
15721    }
15722  }
15723  Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
15724}
15725
15726void Assembler::vcvtt(
15727    Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15728  CheckIT(cond);
15729  if (IsUsingT32()) {
15730    // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
15731    if (dt1.Is(F16) && dt2.Is(F64)) {
15732      EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15733      AdvanceIT();
15734      return;
15735    }
15736  } else {
15737    // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
15738    if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
15739      EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15740              rm.Encode(5, 0));
15741      return;
15742    }
15743  }
15744  Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
15745}
15746
15747void Assembler::vdiv(
15748    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
15749  CheckIT(cond);
15750  if (IsUsingT32()) {
15751    // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
15752    if (dt.Is(F32)) {
15753      EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15754                 rm.Encode(5, 0));
15755      AdvanceIT();
15756      return;
15757    }
15758  } else {
15759    // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
15760    if (dt.Is(F32) && cond.IsNotNever()) {
15761      EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15762              rn.Encode(7, 16) | rm.Encode(5, 0));
15763      return;
15764    }
15765  }
15766  Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
15767}
15768
15769void Assembler::vdiv(
15770    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15771  CheckIT(cond);
15772  if (IsUsingT32()) {
15773    // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
15774    if (dt.Is(F64)) {
15775      EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15776                 rm.Encode(5, 0));
15777      AdvanceIT();
15778      return;
15779    }
15780  } else {
15781    // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
15782    if (dt.Is(F64) && cond.IsNotNever()) {
15783      EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15784              rn.Encode(7, 16) | rm.Encode(5, 0));
15785      return;
15786    }
15787  }
15788  Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
15789}
15790
15791void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) {
15792  CheckIT(cond);
15793  Dt_B_E_1 encoded_dt(dt);
15794  if (IsUsingT32()) {
15795    // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1
15796    if (encoded_dt.IsValid()) {
15797      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15798        EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
15799                   ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
15800                   rd.Encode(7, 16) | (rt.GetCode() << 12));
15801        AdvanceIT();
15802        return;
15803      }
15804    }
15805  } else {
15806    // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1
15807    if (encoded_dt.IsValid() && cond.IsNotNever()) {
15808      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15809        EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) |
15810                ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
15811                ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
15812                rd.Encode(7, 16) | (rt.GetCode() << 12));
15813        return;
15814      }
15815    }
15816  }
15817  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
15818}
15819
15820void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) {
15821  CheckIT(cond);
15822  Dt_B_E_1 encoded_dt(dt);
15823  if (IsUsingT32()) {
15824    // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1
15825    if (encoded_dt.IsValid()) {
15826      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15827        EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
15828                   ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
15829                   rd.Encode(7, 16) | (rt.GetCode() << 12));
15830        AdvanceIT();
15831        return;
15832      }
15833    }
15834  } else {
15835    // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1
15836    if (encoded_dt.IsValid() && cond.IsNotNever()) {
15837      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15838        EmitA32(0x0e800b10U | (cond.GetCondition() << 28) |
15839                ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
15840                ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
15841                rd.Encode(7, 16) | (rt.GetCode() << 12));
15842        return;
15843      }
15844    }
15845  }
15846  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
15847}
15848
15849void Assembler::vdup(Condition cond,
15850                     DataType dt,
15851                     DRegister rd,
15852                     DRegisterLane rm) {
15853  CheckIT(cond);
15854  Dt_imm4_1 encoded_dt(dt, rm);
15855  if (IsUsingT32()) {
15856    // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1
15857    if (encoded_dt.IsValid()) {
15858      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15859        EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) |
15860                   rd.Encode(22, 12) | rm.Encode(5, 0));
15861        AdvanceIT();
15862        return;
15863      }
15864    }
15865  } else {
15866    // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1
15867    if (encoded_dt.IsValid()) {
15868      if (cond.Is(al)) {
15869        EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) |
15870                rd.Encode(22, 12) | rm.Encode(5, 0));
15871        return;
15872      }
15873    }
15874  }
15875  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
15876}
15877
15878void Assembler::vdup(Condition cond,
15879                     DataType dt,
15880                     QRegister rd,
15881                     DRegisterLane rm) {
15882  CheckIT(cond);
15883  Dt_imm4_1 encoded_dt(dt, rm);
15884  if (IsUsingT32()) {
15885    // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1
15886    if (encoded_dt.IsValid()) {
15887      if (cond.Is(al) || AllowStronglyDiscouraged()) {
15888        EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) |
15889                   rd.Encode(22, 12) | rm.Encode(5, 0));
15890        AdvanceIT();
15891        return;
15892      }
15893    }
15894  } else {
15895    // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1
15896    if (encoded_dt.IsValid()) {
15897      if (cond.Is(al)) {
15898        EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) |
15899                rd.Encode(22, 12) | rm.Encode(5, 0));
15900        return;
15901      }
15902    }
15903  }
15904  Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
15905}
15906
15907void Assembler::veor(
15908    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15909  CheckIT(cond);
15910  USE(dt);
15911  if (IsUsingT32()) {
15912    // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
15913    if (cond.Is(al) || AllowStronglyDiscouraged()) {
15914      EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15915                 rm.Encode(5, 0));
15916      AdvanceIT();
15917      return;
15918    }
15919  } else {
15920    // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
15921    if (cond.Is(al)) {
15922      EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15923              rm.Encode(5, 0));
15924      return;
15925    }
15926  }
15927  Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
15928}
15929
15930void Assembler::veor(
15931    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15932  CheckIT(cond);
15933  USE(dt);
15934  if (IsUsingT32()) {
15935    // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
15936    if (cond.Is(al) || AllowStronglyDiscouraged()) {
15937      EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15938                 rm.Encode(5, 0));
15939      AdvanceIT();
15940      return;
15941    }
15942  } else {
15943    // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
15944    if (cond.Is(al)) {
15945      EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15946              rm.Encode(5, 0));
15947      return;
15948    }
15949  }
15950  Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
15951}
15952
15953void Assembler::vext(Condition cond,
15954                     DataType dt,
15955                     DRegister rd,
15956                     DRegister rn,
15957                     DRegister rm,
15958                     const DOperand& operand) {
15959  CheckIT(cond);
15960  if (operand.IsImmediate()) {
15961    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15962      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15963      if (IsUsingT32()) {
15964        // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
15965        if (dt.Is(Untyped8) && (imm <= 7)) {
15966          if (cond.Is(al) || AllowStronglyDiscouraged()) {
15967            EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15968                       rm.Encode(5, 0) | (imm << 8));
15969            AdvanceIT();
15970            return;
15971          }
15972        }
15973        // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
15974        if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
15975            (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
15976          if (cond.Is(al) || AllowStronglyDiscouraged()) {
15977            uint32_t imm4 = imm / dt.GetSize();
15978            EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15979                       rm.Encode(5, 0) | (imm4 << 8));
15980            AdvanceIT();
15981            return;
15982          }
15983        }
15984      } else {
15985        // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
15986        if (dt.Is(Untyped8) && (imm <= 7)) {
15987          if (cond.Is(al)) {
15988            EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15989                    rm.Encode(5, 0) | (imm << 8));
15990            return;
15991          }
15992        }
15993        // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
15994        if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
15995            (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
15996          if (cond.Is(al)) {
15997            uint32_t imm4 = imm / dt.GetSize();
15998            EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15999                    rm.Encode(5, 0) | (imm4 << 8));
16000            return;
16001          }
16002        }
16003      }
16004    }
16005  }
16006  Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
16007}
16008
16009void Assembler::vext(Condition cond,
16010                     DataType dt,
16011                     QRegister rd,
16012                     QRegister rn,
16013                     QRegister rm,
16014                     const QOperand& operand) {
16015  CheckIT(cond);
16016  if (operand.IsImmediate()) {
16017    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
16018      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
16019      if (IsUsingT32()) {
16020        // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
16021        if (dt.Is(Untyped8) && (imm <= 15)) {
16022          if (cond.Is(al) || AllowStronglyDiscouraged()) {
16023            EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16024                       rm.Encode(5, 0) | (imm << 8));
16025            AdvanceIT();
16026            return;
16027          }
16028        }
16029        // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
16030        if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
16031            (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16032          if (cond.Is(al) || AllowStronglyDiscouraged()) {
16033            uint32_t imm4 = imm / dt.GetSize();
16034            EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16035                       rm.Encode(5, 0) | (imm4 << 8));
16036            AdvanceIT();
16037            return;
16038          }
16039        }
16040      } else {
16041        // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
16042        if (dt.Is(Untyped8) && (imm <= 15)) {
16043          if (cond.Is(al)) {
16044            EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16045                    rm.Encode(5, 0) | (imm << 8));
16046            return;
16047          }
16048        }
16049        // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
16050        if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
16051            (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16052          if (cond.Is(al)) {
16053            uint32_t imm4 = imm / dt.GetSize();
16054            EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16055                    rm.Encode(5, 0) | (imm4 << 8));
16056            return;
16057          }
16058        }
16059      }
16060    }
16061  }
16062  Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
16063}
16064
16065void Assembler::vfma(
16066    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16067  CheckIT(cond);
16068  if (IsUsingT32()) {
16069    // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
16070    if (dt.Is(F32)) {
16071      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16072        EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16073                   rm.Encode(5, 0));
16074        AdvanceIT();
16075        return;
16076      }
16077    }
16078    // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
16079    if (dt.Is(F64)) {
16080      EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16081                 rm.Encode(5, 0));
16082      AdvanceIT();
16083      return;
16084    }
16085  } else {
16086    // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
16087    if (dt.Is(F32)) {
16088      if (cond.Is(al)) {
16089        EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16090                rm.Encode(5, 0));
16091        return;
16092      }
16093    }
16094    // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
16095    if (dt.Is(F64) && cond.IsNotNever()) {
16096      EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16097              rn.Encode(7, 16) | rm.Encode(5, 0));
16098      return;
16099    }
16100  }
16101  Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16102}
16103
16104void Assembler::vfma(
16105    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16106  CheckIT(cond);
16107  if (IsUsingT32()) {
16108    // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
16109    if (dt.Is(F32)) {
16110      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16111        EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16112                   rm.Encode(5, 0));
16113        AdvanceIT();
16114        return;
16115      }
16116    }
16117  } else {
16118    // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
16119    if (dt.Is(F32)) {
16120      if (cond.Is(al)) {
16121        EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16122                rm.Encode(5, 0));
16123        return;
16124      }
16125    }
16126  }
16127  Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16128}
16129
16130void Assembler::vfma(
16131    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16132  CheckIT(cond);
16133  if (IsUsingT32()) {
16134    // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
16135    if (dt.Is(F32)) {
16136      EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16137                 rm.Encode(5, 0));
16138      AdvanceIT();
16139      return;
16140    }
16141  } else {
16142    // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
16143    if (dt.Is(F32) && cond.IsNotNever()) {
16144      EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16145              rn.Encode(7, 16) | rm.Encode(5, 0));
16146      return;
16147    }
16148  }
16149  Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16150}
16151
16152void Assembler::vfms(
16153    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16154  CheckIT(cond);
16155  if (IsUsingT32()) {
16156    // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
16157    if (dt.Is(F32)) {
16158      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16159        EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16160                   rm.Encode(5, 0));
16161        AdvanceIT();
16162        return;
16163      }
16164    }
16165    // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
16166    if (dt.Is(F64)) {
16167      EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16168                 rm.Encode(5, 0));
16169      AdvanceIT();
16170      return;
16171    }
16172  } else {
16173    // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
16174    if (dt.Is(F32)) {
16175      if (cond.Is(al)) {
16176        EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16177                rm.Encode(5, 0));
16178        return;
16179      }
16180    }
16181    // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
16182    if (dt.Is(F64) && cond.IsNotNever()) {
16183      EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16184              rn.Encode(7, 16) | rm.Encode(5, 0));
16185      return;
16186    }
16187  }
16188  Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16189}
16190
16191void Assembler::vfms(
16192    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16193  CheckIT(cond);
16194  if (IsUsingT32()) {
16195    // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
16196    if (dt.Is(F32)) {
16197      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16198        EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16199                   rm.Encode(5, 0));
16200        AdvanceIT();
16201        return;
16202      }
16203    }
16204  } else {
16205    // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
16206    if (dt.Is(F32)) {
16207      if (cond.Is(al)) {
16208        EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16209                rm.Encode(5, 0));
16210        return;
16211      }
16212    }
16213  }
16214  Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16215}
16216
16217void Assembler::vfms(
16218    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16219  CheckIT(cond);
16220  if (IsUsingT32()) {
16221    // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
16222    if (dt.Is(F32)) {
16223      EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16224                 rm.Encode(5, 0));
16225      AdvanceIT();
16226      return;
16227    }
16228  } else {
16229    // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
16230    if (dt.Is(F32) && cond.IsNotNever()) {
16231      EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16232              rn.Encode(7, 16) | rm.Encode(5, 0));
16233      return;
16234    }
16235  }
16236  Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16237}
16238
16239void Assembler::vfnma(
16240    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16241  CheckIT(cond);
16242  if (IsUsingT32()) {
16243    // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
16244    if (dt.Is(F32)) {
16245      EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16246                 rm.Encode(5, 0));
16247      AdvanceIT();
16248      return;
16249    }
16250  } else {
16251    // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
16252    if (dt.Is(F32) && cond.IsNotNever()) {
16253      EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16254              rn.Encode(7, 16) | rm.Encode(5, 0));
16255      return;
16256    }
16257  }
16258  Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
16259}
16260
16261void Assembler::vfnma(
16262    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16263  CheckIT(cond);
16264  if (IsUsingT32()) {
16265    // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
16266    if (dt.Is(F64)) {
16267      EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16268                 rm.Encode(5, 0));
16269      AdvanceIT();
16270      return;
16271    }
16272  } else {
16273    // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
16274    if (dt.Is(F64) && cond.IsNotNever()) {
16275      EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16276              rn.Encode(7, 16) | rm.Encode(5, 0));
16277      return;
16278    }
16279  }
16280  Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
16281}
16282
16283void Assembler::vfnms(
16284    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16285  CheckIT(cond);
16286  if (IsUsingT32()) {
16287    // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
16288    if (dt.Is(F32)) {
16289      EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16290                 rm.Encode(5, 0));
16291      AdvanceIT();
16292      return;
16293    }
16294  } else {
16295    // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
16296    if (dt.Is(F32) && cond.IsNotNever()) {
16297      EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16298              rn.Encode(7, 16) | rm.Encode(5, 0));
16299      return;
16300    }
16301  }
16302  Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
16303}
16304
16305void Assembler::vfnms(
16306    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16307  CheckIT(cond);
16308  if (IsUsingT32()) {
16309    // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
16310    if (dt.Is(F64)) {
16311      EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16312                 rm.Encode(5, 0));
16313      AdvanceIT();
16314      return;
16315    }
16316  } else {
16317    // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
16318    if (dt.Is(F64) && cond.IsNotNever()) {
16319      EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16320              rn.Encode(7, 16) | rm.Encode(5, 0));
16321      return;
16322    }
16323  }
16324  Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
16325}
16326
16327void Assembler::vhadd(
16328    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16329  CheckIT(cond);
16330  Dt_U_size_1 encoded_dt(dt);
16331  if (IsUsingT32()) {
16332    // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
16333    if (encoded_dt.IsValid()) {
16334      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16335        EmitT32_32(0xef000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16336                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16337                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16338        AdvanceIT();
16339        return;
16340      }
16341    }
16342  } else {
16343    // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
16344    if (encoded_dt.IsValid()) {
16345      if (cond.Is(al)) {
16346        EmitA32(0xf2000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16347                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16348                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16349        return;
16350      }
16351    }
16352  }
16353  Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
16354}
16355
16356void Assembler::vhadd(
16357    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16358  CheckIT(cond);
16359  Dt_U_size_1 encoded_dt(dt);
16360  if (IsUsingT32()) {
16361    // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
16362    if (encoded_dt.IsValid()) {
16363      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16364        EmitT32_32(0xef000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16365                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16366                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16367        AdvanceIT();
16368        return;
16369      }
16370    }
16371  } else {
16372    // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
16373    if (encoded_dt.IsValid()) {
16374      if (cond.Is(al)) {
16375        EmitA32(0xf2000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16376                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16377                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16378        return;
16379      }
16380    }
16381  }
16382  Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
16383}
16384
16385void Assembler::vhsub(
16386    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16387  CheckIT(cond);
16388  Dt_U_size_1 encoded_dt(dt);
16389  if (IsUsingT32()) {
16390    // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
16391    if (encoded_dt.IsValid()) {
16392      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16393        EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16394                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16395                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16396        AdvanceIT();
16397        return;
16398      }
16399    }
16400  } else {
16401    // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
16402    if (encoded_dt.IsValid()) {
16403      if (cond.Is(al)) {
16404        EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16405                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16406                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16407        return;
16408      }
16409    }
16410  }
16411  Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
16412}
16413
16414void Assembler::vhsub(
16415    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16416  CheckIT(cond);
16417  Dt_U_size_1 encoded_dt(dt);
16418  if (IsUsingT32()) {
16419    // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
16420    if (encoded_dt.IsValid()) {
16421      if (cond.Is(al) || AllowStronglyDiscouraged()) {
16422        EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16423                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16424                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16425        AdvanceIT();
16426        return;
16427      }
16428    }
16429  } else {
16430    // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
16431    if (encoded_dt.IsValid()) {
16432      if (cond.Is(al)) {
16433        EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16434                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16435                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16436        return;
16437      }
16438    }
16439  }
16440  Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
16441}
16442
16443void Assembler::vld1(Condition cond,
16444                     DataType dt,
16445                     const NeonRegisterList& nreglist,
16446                     const AlignedMemOperand& operand) {
16447  CheckIT(cond);
16448  if (operand.IsImmediateZero()) {
16449    Register rn = operand.GetBaseRegister();
16450    Alignment align = operand.GetAlignment();
16451    Dt_size_6 encoded_dt(dt);
16452    Dt_size_7 encoded_dt_2(dt);
16453    Align_align_1 encoded_align_1(align, nreglist);
16454    Align_a_1 encoded_align_2(align, dt);
16455    Align_index_align_1 encoded_align_3(align, nreglist, dt);
16456    if (IsUsingT32()) {
16457      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16458      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16459          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16460          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
16461          ((!rn.IsPC()) || AllowUnpredictable())) {
16462        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16463          const DRegister& first = nreglist.GetFirstDRegister();
16464          uint32_t len_encoding;
16465          switch (nreglist.GetLength()) {
16466            default:
16467              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16468            case 1:
16469              len_encoding = 0x7;
16470              break;
16471            case 2:
16472              len_encoding = 0xa;
16473              break;
16474            case 3:
16475              len_encoding = 0x6;
16476              break;
16477            case 4:
16478              len_encoding = 0x2;
16479              break;
16480          }
16481          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
16482                     (encoded_align_1.GetEncodingValue() << 4) |
16483                     first.Encode(22, 12) | (len_encoding << 8) |
16484                     (rn.GetCode() << 16));
16485          AdvanceIT();
16486          return;
16487        }
16488      }
16489      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16490      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16491          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16492          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
16493          ((!rn.IsPC()) || AllowUnpredictable())) {
16494        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16495          const DRegister& first = nreglist.GetFirstDRegister();
16496          uint32_t len_encoding;
16497          switch (nreglist.GetLength()) {
16498            default:
16499              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16500            case 1:
16501              len_encoding = 0x7;
16502              break;
16503            case 2:
16504              len_encoding = 0xa;
16505              break;
16506            case 3:
16507              len_encoding = 0x6;
16508              break;
16509            case 4:
16510              len_encoding = 0x2;
16511              break;
16512          }
16513          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
16514                     (encoded_align_1.GetEncodingValue() << 4) |
16515                     first.Encode(22, 12) | (len_encoding << 8) |
16516                     (rn.GetCode() << 16));
16517          AdvanceIT();
16518          return;
16519        }
16520      }
16521      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16522      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16523          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16524          (operand.GetAddrMode() == Offset) && encoded_align_2.IsValid() &&
16525          ((!rn.IsPC()) || AllowUnpredictable())) {
16526        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16527          const DRegister& first = nreglist.GetFirstDRegister();
16528          uint32_t len_encoding = nreglist.GetLength() - 1;
16529          EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
16530                     (encoded_align_2.GetEncodingValue() << 4) |
16531                     first.Encode(22, 12) | (len_encoding << 5) |
16532                     (rn.GetCode() << 16));
16533          AdvanceIT();
16534          return;
16535        }
16536      }
16537      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16538      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16539          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16540          (operand.GetAddrMode() == PostIndex) && encoded_align_2.IsValid() &&
16541          ((!rn.IsPC()) || AllowUnpredictable())) {
16542        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16543          const DRegister& first = nreglist.GetFirstDRegister();
16544          uint32_t len_encoding = nreglist.GetLength() - 1;
16545          EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
16546                     (encoded_align_2.GetEncodingValue() << 4) |
16547                     first.Encode(22, 12) | (len_encoding << 5) |
16548                     (rn.GetCode() << 16));
16549          AdvanceIT();
16550          return;
16551        }
16552      }
16553      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16554      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16555          (nreglist.GetLength() == 1) && (operand.GetAddrMode() == Offset) &&
16556          encoded_align_3.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
16557        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16558          const DRegister& first = nreglist.GetFirstDRegister();
16559          EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
16560                     (encoded_align_3.GetEncodingValue() << 4) |
16561                     first.Encode(22, 12) | (rn.GetCode() << 16));
16562          AdvanceIT();
16563          return;
16564        }
16565      }
16566      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16567      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16568          (nreglist.GetLength() == 1) && (operand.GetAddrMode() == PostIndex) &&
16569          encoded_align_3.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
16570        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16571          const DRegister& first = nreglist.GetFirstDRegister();
16572          EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
16573                     (encoded_align_3.GetEncodingValue() << 4) |
16574                     first.Encode(22, 12) | (rn.GetCode() << 16));
16575          AdvanceIT();
16576          return;
16577        }
16578      }
16579    } else {
16580      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
16581      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16582          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16583          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
16584          ((!rn.IsPC()) || AllowUnpredictable())) {
16585        if (cond.Is(al)) {
16586          const DRegister& first = nreglist.GetFirstDRegister();
16587          uint32_t len_encoding;
16588          switch (nreglist.GetLength()) {
16589            default:
16590              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16591            case 1:
16592              len_encoding = 0x7;
16593              break;
16594            case 2:
16595              len_encoding = 0xa;
16596              break;
16597            case 3:
16598              len_encoding = 0x6;
16599              break;
16600            case 4:
16601              len_encoding = 0x2;
16602              break;
16603          }
16604          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
16605                  (encoded_align_1.GetEncodingValue() << 4) |
16606                  first.Encode(22, 12) | (len_encoding << 8) |
16607                  (rn.GetCode() << 16));
16608          return;
16609        }
16610      }
16611      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
16612      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16613          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16614          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
16615          ((!rn.IsPC()) || AllowUnpredictable())) {
16616        if (cond.Is(al)) {
16617          const DRegister& first = nreglist.GetFirstDRegister();
16618          uint32_t len_encoding;
16619          switch (nreglist.GetLength()) {
16620            default:
16621              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16622            case 1:
16623              len_encoding = 0x7;
16624              break;
16625            case 2:
16626              len_encoding = 0xa;
16627              break;
16628            case 3:
16629              len_encoding = 0x6;
16630              break;
16631            case 4:
16632              len_encoding = 0x2;
16633              break;
16634          }
16635          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
16636                  (encoded_align_1.GetEncodingValue() << 4) |
16637                  first.Encode(22, 12) | (len_encoding << 8) |
16638                  (rn.GetCode() << 16));
16639          return;
16640        }
16641      }
16642      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
16643      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16644          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16645          (operand.GetAddrMode() == Offset) && encoded_align_2.IsValid() &&
16646          ((!rn.IsPC()) || AllowUnpredictable())) {
16647        if (cond.Is(al)) {
16648          const DRegister& first = nreglist.GetFirstDRegister();
16649          uint32_t len_encoding = nreglist.GetLength() - 1;
16650          EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
16651                  (encoded_align_2.GetEncodingValue() << 4) |
16652                  first.Encode(22, 12) | (len_encoding << 5) |
16653                  (rn.GetCode() << 16));
16654          return;
16655        }
16656      }
16657      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
16658      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16659          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16660          (operand.GetAddrMode() == PostIndex) && encoded_align_2.IsValid() &&
16661          ((!rn.IsPC()) || AllowUnpredictable())) {
16662        if (cond.Is(al)) {
16663          const DRegister& first = nreglist.GetFirstDRegister();
16664          uint32_t len_encoding = nreglist.GetLength() - 1;
16665          EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
16666                  (encoded_align_2.GetEncodingValue() << 4) |
16667                  first.Encode(22, 12) | (len_encoding << 5) |
16668                  (rn.GetCode() << 16));
16669          return;
16670        }
16671      }
16672      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
16673      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16674          (nreglist.GetLength() == 1) && (operand.GetAddrMode() == Offset) &&
16675          encoded_align_3.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
16676        if (cond.Is(al)) {
16677          const DRegister& first = nreglist.GetFirstDRegister();
16678          EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
16679                  (encoded_align_3.GetEncodingValue() << 4) |
16680                  first.Encode(22, 12) | (rn.GetCode() << 16));
16681          return;
16682        }
16683      }
16684      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
16685      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16686          (nreglist.GetLength() == 1) && (operand.GetAddrMode() == PostIndex) &&
16687          encoded_align_3.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
16688        if (cond.Is(al)) {
16689          const DRegister& first = nreglist.GetFirstDRegister();
16690          EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
16691                  (encoded_align_3.GetEncodingValue() << 4) |
16692                  first.Encode(22, 12) | (rn.GetCode() << 16));
16693          return;
16694        }
16695      }
16696    }
16697  }
16698  if (operand.IsPlainRegister()) {
16699    Register rn = operand.GetBaseRegister();
16700    Alignment align = operand.GetAlignment();
16701    Register rm = operand.GetOffsetRegister();
16702    Dt_size_6 encoded_dt(dt);
16703    Dt_size_7 encoded_dt_2(dt);
16704    Align_align_1 encoded_align_1(align, nreglist);
16705    Align_a_1 encoded_align_2(align, dt);
16706    Align_index_align_1 encoded_align_3(align, nreglist, dt);
16707    if (IsUsingT32()) {
16708      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
16709      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16710          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16711          !rm.IsPC() && !rm.IsSP()) {
16712        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16713          const DRegister& first = nreglist.GetFirstDRegister();
16714          uint32_t len_encoding;
16715          switch (nreglist.GetLength()) {
16716            default:
16717              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16718            case 1:
16719              len_encoding = 0x7;
16720              break;
16721            case 2:
16722              len_encoding = 0xa;
16723              break;
16724            case 3:
16725              len_encoding = 0x6;
16726              break;
16727            case 4:
16728              len_encoding = 0x2;
16729              break;
16730          }
16731          EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
16732                     (encoded_align_1.GetEncodingValue() << 4) |
16733                     first.Encode(22, 12) | (len_encoding << 8) |
16734                     (rn.GetCode() << 16) | rm.GetCode());
16735          AdvanceIT();
16736          return;
16737        }
16738      }
16739      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
16740      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16741          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16742          !rm.IsPC() && !rm.IsSP()) {
16743        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16744          const DRegister& first = nreglist.GetFirstDRegister();
16745          uint32_t len_encoding = nreglist.GetLength() - 1;
16746          EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
16747                     (encoded_align_2.GetEncodingValue() << 4) |
16748                     first.Encode(22, 12) | (len_encoding << 5) |
16749                     (rn.GetCode() << 16) | rm.GetCode());
16750          AdvanceIT();
16751          return;
16752        }
16753      }
16754      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
16755      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16756          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
16757        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16758          const DRegister& first = nreglist.GetFirstDRegister();
16759          EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
16760                     (encoded_align_3.GetEncodingValue() << 4) |
16761                     first.Encode(22, 12) | (rn.GetCode() << 16) |
16762                     rm.GetCode());
16763          AdvanceIT();
16764          return;
16765        }
16766      }
16767    } else {
16768      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
16769      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16770          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16771          !rm.IsPC() && !rm.IsSP()) {
16772        if (cond.Is(al)) {
16773          const DRegister& first = nreglist.GetFirstDRegister();
16774          uint32_t len_encoding;
16775          switch (nreglist.GetLength()) {
16776            default:
16777              VIXL_UNREACHABLE_OR_FALLTHROUGH();
16778            case 1:
16779              len_encoding = 0x7;
16780              break;
16781            case 2:
16782              len_encoding = 0xa;
16783              break;
16784            case 3:
16785              len_encoding = 0x6;
16786              break;
16787            case 4:
16788              len_encoding = 0x2;
16789              break;
16790          }
16791          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
16792                  (encoded_align_1.GetEncodingValue() << 4) |
16793                  first.Encode(22, 12) | (len_encoding << 8) |
16794                  (rn.GetCode() << 16) | rm.GetCode());
16795          return;
16796        }
16797      }
16798      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
16799      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16800          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16801          !rm.IsPC() && !rm.IsSP()) {
16802        if (cond.Is(al)) {
16803          const DRegister& first = nreglist.GetFirstDRegister();
16804          uint32_t len_encoding = nreglist.GetLength() - 1;
16805          EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
16806                  (encoded_align_2.GetEncodingValue() << 4) |
16807                  first.Encode(22, 12) | (len_encoding << 5) |
16808                  (rn.GetCode() << 16) | rm.GetCode());
16809          return;
16810        }
16811      }
16812      // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
16813      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16814          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
16815        if (cond.Is(al)) {
16816          const DRegister& first = nreglist.GetFirstDRegister();
16817          EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
16818                  (encoded_align_3.GetEncodingValue() << 4) |
16819                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
16820          return;
16821        }
16822      }
16823    }
16824  }
16825  Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand);
16826}
16827
16828void Assembler::vld2(Condition cond,
16829                     DataType dt,
16830                     const NeonRegisterList& nreglist,
16831                     const AlignedMemOperand& operand) {
16832  CheckIT(cond);
16833  if (operand.IsImmediateZero()) {
16834    Register rn = operand.GetBaseRegister();
16835    Alignment align = operand.GetAlignment();
16836    Dt_size_7 encoded_dt(dt);
16837    Align_align_2 encoded_align_1(align, nreglist);
16838    Align_a_2 encoded_align_2(align, dt);
16839    Align_index_align_2 encoded_align_3(align, nreglist, dt);
16840    if (IsUsingT32()) {
16841      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16842      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16843          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
16844           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
16845           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
16846          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
16847          ((!rn.IsPC()) || AllowUnpredictable())) {
16848        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16849          const DRegister& first = nreglist.GetFirstDRegister();
16850          uint32_t len_encoding;
16851          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
16852            len_encoding = 0x8;
16853          }
16854          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
16855            len_encoding = 0x9;
16856          }
16857          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
16858            len_encoding = 0x3;
16859          }
16860          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
16861                     (encoded_align_1.GetEncodingValue() << 4) |
16862                     first.Encode(22, 12) | (len_encoding << 8) |
16863                     (rn.GetCode() << 16));
16864          AdvanceIT();
16865          return;
16866        }
16867      }
16868      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16869      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16870          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
16871           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
16872           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
16873          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
16874          ((!rn.IsPC()) || AllowUnpredictable())) {
16875        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16876          const DRegister& first = nreglist.GetFirstDRegister();
16877          uint32_t len_encoding;
16878          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
16879            len_encoding = 0x8;
16880          }
16881          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
16882            len_encoding = 0x9;
16883          }
16884          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
16885            len_encoding = 0x3;
16886          }
16887          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
16888                     (encoded_align_1.GetEncodingValue() << 4) |
16889                     first.Encode(22, 12) | (len_encoding << 8) |
16890                     (rn.GetCode() << 16));
16891          AdvanceIT();
16892          return;
16893        }
16894      }
16895      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16896      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
16897          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
16898           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
16899          (operand.GetAddrMode() == Offset) && encoded_align_2.IsValid() &&
16900          ((!rn.IsPC()) || AllowUnpredictable())) {
16901        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16902          const DRegister& first = nreglist.GetFirstDRegister();
16903          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
16904          EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
16905                     (encoded_align_2.GetEncodingValue() << 4) |
16906                     first.Encode(22, 12) | (len_encoding << 5) |
16907                     (rn.GetCode() << 16));
16908          AdvanceIT();
16909          return;
16910        }
16911      }
16912      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16913      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
16914          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
16915           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
16916          (operand.GetAddrMode() == PostIndex) && encoded_align_2.IsValid() &&
16917          ((!rn.IsPC()) || AllowUnpredictable())) {
16918        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16919          const DRegister& first = nreglist.GetFirstDRegister();
16920          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
16921          EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
16922                     (encoded_align_2.GetEncodingValue() << 4) |
16923                     first.Encode(22, 12) | (len_encoding << 5) |
16924                     (rn.GetCode() << 16));
16925          AdvanceIT();
16926          return;
16927        }
16928      }
16929      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16930      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
16931          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
16932           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
16933          (operand.GetAddrMode() == Offset) && encoded_align_3.IsValid() &&
16934          ((!rn.IsPC()) || AllowUnpredictable())) {
16935        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16936          const DRegister& first = nreglist.GetFirstDRegister();
16937          EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) |
16938                     (encoded_align_3.GetEncodingValue() << 4) |
16939                     first.Encode(22, 12) | (rn.GetCode() << 16));
16940          AdvanceIT();
16941          return;
16942        }
16943      }
16944      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16945      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
16946          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
16947           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
16948          (operand.GetAddrMode() == PostIndex) && encoded_align_3.IsValid() &&
16949          ((!rn.IsPC()) || AllowUnpredictable())) {
16950        if (cond.Is(al) || AllowStronglyDiscouraged()) {
16951          const DRegister& first = nreglist.GetFirstDRegister();
16952          EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) |
16953                     (encoded_align_3.GetEncodingValue() << 4) |
16954                     first.Encode(22, 12) | (rn.GetCode() << 16));
16955          AdvanceIT();
16956          return;
16957        }
16958      }
16959    } else {
16960      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
16961      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16962          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
16963           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
16964           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
16965          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
16966          ((!rn.IsPC()) || AllowUnpredictable())) {
16967        if (cond.Is(al)) {
16968          const DRegister& first = nreglist.GetFirstDRegister();
16969          uint32_t len_encoding;
16970          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
16971            len_encoding = 0x8;
16972          }
16973          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
16974            len_encoding = 0x9;
16975          }
16976          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
16977            len_encoding = 0x3;
16978          }
16979          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
16980                  (encoded_align_1.GetEncodingValue() << 4) |
16981                  first.Encode(22, 12) | (len_encoding << 8) |
16982                  (rn.GetCode() << 16));
16983          return;
16984        }
16985      }
16986      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
16987      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16988          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
16989           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
16990           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
16991          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
16992          ((!rn.IsPC()) || AllowUnpredictable())) {
16993        if (cond.Is(al)) {
16994          const DRegister& first = nreglist.GetFirstDRegister();
16995          uint32_t len_encoding;
16996          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
16997            len_encoding = 0x8;
16998          }
16999          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17000            len_encoding = 0x9;
17001          }
17002          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17003            len_encoding = 0x3;
17004          }
17005          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17006                  (encoded_align_1.GetEncodingValue() << 4) |
17007                  first.Encode(22, 12) | (len_encoding << 8) |
17008                  (rn.GetCode() << 16));
17009          return;
17010        }
17011      }
17012      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17013      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17014          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17015           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17016          (operand.GetAddrMode() == Offset) && encoded_align_2.IsValid() &&
17017          ((!rn.IsPC()) || AllowUnpredictable())) {
17018        if (cond.Is(al)) {
17019          const DRegister& first = nreglist.GetFirstDRegister();
17020          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17021          EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
17022                  (encoded_align_2.GetEncodingValue() << 4) |
17023                  first.Encode(22, 12) | (len_encoding << 5) |
17024                  (rn.GetCode() << 16));
17025          return;
17026        }
17027      }
17028      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17029      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17030          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17031           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17032          (operand.GetAddrMode() == PostIndex) && encoded_align_2.IsValid() &&
17033          ((!rn.IsPC()) || AllowUnpredictable())) {
17034        if (cond.Is(al)) {
17035          const DRegister& first = nreglist.GetFirstDRegister();
17036          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17037          EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
17038                  (encoded_align_2.GetEncodingValue() << 4) |
17039                  first.Encode(22, 12) | (len_encoding << 5) |
17040                  (rn.GetCode() << 16));
17041          return;
17042        }
17043      }
17044      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17045      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17046          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17047           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17048          (operand.GetAddrMode() == Offset) && encoded_align_3.IsValid() &&
17049          ((!rn.IsPC()) || AllowUnpredictable())) {
17050        if (cond.Is(al)) {
17051          const DRegister& first = nreglist.GetFirstDRegister();
17052          EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) |
17053                  (encoded_align_3.GetEncodingValue() << 4) |
17054                  first.Encode(22, 12) | (rn.GetCode() << 16));
17055          return;
17056        }
17057      }
17058      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17059      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17060          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17061           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17062          (operand.GetAddrMode() == PostIndex) && encoded_align_3.IsValid() &&
17063          ((!rn.IsPC()) || AllowUnpredictable())) {
17064        if (cond.Is(al)) {
17065          const DRegister& first = nreglist.GetFirstDRegister();
17066          EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) |
17067                  (encoded_align_3.GetEncodingValue() << 4) |
17068                  first.Encode(22, 12) | (rn.GetCode() << 16));
17069          return;
17070        }
17071      }
17072    }
17073  }
17074  if (operand.IsPlainRegister()) {
17075    Register rn = operand.GetBaseRegister();
17076    Alignment align = operand.GetAlignment();
17077    Register rm = operand.GetOffsetRegister();
17078    Dt_size_7 encoded_dt(dt);
17079    Align_align_2 encoded_align_1(align, nreglist);
17080    Align_a_2 encoded_align_2(align, dt);
17081    Align_index_align_2 encoded_align_3(align, nreglist, dt);
17082    if (IsUsingT32()) {
17083      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17084      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17085          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17086           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17087           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17088          !rm.IsPC() && !rm.IsSP()) {
17089        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17090          const DRegister& first = nreglist.GetFirstDRegister();
17091          uint32_t len_encoding;
17092          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17093            len_encoding = 0x8;
17094          }
17095          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17096            len_encoding = 0x9;
17097          }
17098          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17099            len_encoding = 0x3;
17100          }
17101          EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
17102                     (encoded_align_1.GetEncodingValue() << 4) |
17103                     first.Encode(22, 12) | (len_encoding << 8) |
17104                     (rn.GetCode() << 16) | rm.GetCode());
17105          AdvanceIT();
17106          return;
17107        }
17108      }
17109      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17110      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17111          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17112           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17113          !rm.IsPC() && !rm.IsSP()) {
17114        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17115          const DRegister& first = nreglist.GetFirstDRegister();
17116          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17117          EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) |
17118                     (encoded_align_2.GetEncodingValue() << 4) |
17119                     first.Encode(22, 12) | (len_encoding << 5) |
17120                     (rn.GetCode() << 16) | rm.GetCode());
17121          AdvanceIT();
17122          return;
17123        }
17124      }
17125      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17126      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17127          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17128           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17129          !rm.IsPC() && !rm.IsSP()) {
17130        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17131          const DRegister& first = nreglist.GetFirstDRegister();
17132          EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) |
17133                     (encoded_align_3.GetEncodingValue() << 4) |
17134                     first.Encode(22, 12) | (rn.GetCode() << 16) |
17135                     rm.GetCode());
17136          AdvanceIT();
17137          return;
17138        }
17139      }
17140    } else {
17141      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17142      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17143          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17144           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17145           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17146          !rm.IsPC() && !rm.IsSP()) {
17147        if (cond.Is(al)) {
17148          const DRegister& first = nreglist.GetFirstDRegister();
17149          uint32_t len_encoding;
17150          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17151            len_encoding = 0x8;
17152          }
17153          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17154            len_encoding = 0x9;
17155          }
17156          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17157            len_encoding = 0x3;
17158          }
17159          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17160                  (encoded_align_1.GetEncodingValue() << 4) |
17161                  first.Encode(22, 12) | (len_encoding << 8) |
17162                  (rn.GetCode() << 16) | rm.GetCode());
17163          return;
17164        }
17165      }
17166      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17167      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17168          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17169           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17170          !rm.IsPC() && !rm.IsSP()) {
17171        if (cond.Is(al)) {
17172          const DRegister& first = nreglist.GetFirstDRegister();
17173          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17174          EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) |
17175                  (encoded_align_2.GetEncodingValue() << 4) |
17176                  first.Encode(22, 12) | (len_encoding << 5) |
17177                  (rn.GetCode() << 16) | rm.GetCode());
17178          return;
17179        }
17180      }
17181      // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17182      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17183          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17184           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17185          !rm.IsPC() && !rm.IsSP()) {
17186        if (cond.Is(al)) {
17187          const DRegister& first = nreglist.GetFirstDRegister();
17188          EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) |
17189                  (encoded_align_3.GetEncodingValue() << 4) |
17190                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17191          return;
17192        }
17193      }
17194    }
17195  }
17196  Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand);
17197}
17198
17199void Assembler::vld3(Condition cond,
17200                     DataType dt,
17201                     const NeonRegisterList& nreglist,
17202                     const AlignedMemOperand& operand) {
17203  CheckIT(cond);
17204  if (operand.IsImmediateZero()) {
17205    Register rn = operand.GetBaseRegister();
17206    Alignment align = operand.GetAlignment();
17207    Dt_size_7 encoded_dt(dt);
17208    Align_align_3 encoded_align_1(align);
17209    if (IsUsingT32()) {
17210      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17211      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17212          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17213           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17214          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
17215          ((!rn.IsPC()) || AllowUnpredictable())) {
17216        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17217          const DRegister& first = nreglist.GetFirstDRegister();
17218          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17219          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
17220                     (encoded_align_1.GetEncodingValue() << 4) |
17221                     first.Encode(22, 12) | (len_encoding << 8) |
17222                     (rn.GetCode() << 16));
17223          AdvanceIT();
17224          return;
17225        }
17226      }
17227      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17228      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17229          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17230           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17231          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
17232          ((!rn.IsPC()) || AllowUnpredictable())) {
17233        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17234          const DRegister& first = nreglist.GetFirstDRegister();
17235          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17236          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
17237                     (encoded_align_1.GetEncodingValue() << 4) |
17238                     first.Encode(22, 12) | (len_encoding << 8) |
17239                     (rn.GetCode() << 16));
17240          AdvanceIT();
17241          return;
17242        }
17243      }
17244    } else {
17245      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17246      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17247          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17248           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17249          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
17250          ((!rn.IsPC()) || AllowUnpredictable())) {
17251        if (cond.Is(al)) {
17252          const DRegister& first = nreglist.GetFirstDRegister();
17253          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17254          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
17255                  (encoded_align_1.GetEncodingValue() << 4) |
17256                  first.Encode(22, 12) | (len_encoding << 8) |
17257                  (rn.GetCode() << 16));
17258          return;
17259        }
17260      }
17261      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17262      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17263          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17264           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17265          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
17266          ((!rn.IsPC()) || AllowUnpredictable())) {
17267        if (cond.Is(al)) {
17268          const DRegister& first = nreglist.GetFirstDRegister();
17269          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17270          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17271                  (encoded_align_1.GetEncodingValue() << 4) |
17272                  first.Encode(22, 12) | (len_encoding << 8) |
17273                  (rn.GetCode() << 16));
17274          return;
17275        }
17276      }
17277    }
17278  }
17279  if (operand.IsPlainRegister()) {
17280    Register rn = operand.GetBaseRegister();
17281    Alignment align = operand.GetAlignment();
17282    Register rm = operand.GetOffsetRegister();
17283    Dt_size_7 encoded_dt(dt);
17284    Align_align_3 encoded_align_1(align);
17285    if (IsUsingT32()) {
17286      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17287      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17288          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17289           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17290          !rm.IsPC() && !rm.IsSP()) {
17291        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17292          const DRegister& first = nreglist.GetFirstDRegister();
17293          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17294          EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
17295                     (encoded_align_1.GetEncodingValue() << 4) |
17296                     first.Encode(22, 12) | (len_encoding << 8) |
17297                     (rn.GetCode() << 16) | rm.GetCode());
17298          AdvanceIT();
17299          return;
17300        }
17301      }
17302    } else {
17303      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17304      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17305          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17306           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17307          !rm.IsPC() && !rm.IsSP()) {
17308        if (cond.Is(al)) {
17309          const DRegister& first = nreglist.GetFirstDRegister();
17310          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17311          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17312                  (encoded_align_1.GetEncodingValue() << 4) |
17313                  first.Encode(22, 12) | (len_encoding << 8) |
17314                  (rn.GetCode() << 16) | rm.GetCode());
17315          return;
17316        }
17317      }
17318    }
17319  }
17320  Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
17321}
17322
17323void Assembler::vld3(Condition cond,
17324                     DataType dt,
17325                     const NeonRegisterList& nreglist,
17326                     const MemOperand& operand) {
17327  CheckIT(cond);
17328  if (operand.IsImmediateZero()) {
17329    Register rn = operand.GetBaseRegister();
17330    Dt_size_7 encoded_dt(dt);
17331    Index_1 encoded_align_1(nreglist, dt);
17332    if (IsUsingT32()) {
17333      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
17334      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17335          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17336           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17337          (operand.GetAddrMode() == Offset) &&
17338          ((!rn.IsPC()) || AllowUnpredictable())) {
17339        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17340          const DRegister& first = nreglist.GetFirstDRegister();
17341          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17342          EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
17343                     first.Encode(22, 12) | (len_encoding << 5) |
17344                     (rn.GetCode() << 16));
17345          AdvanceIT();
17346          return;
17347        }
17348      }
17349      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
17350      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17351          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17352           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17353          (operand.GetAddrMode() == PreIndex) &&
17354          ((!rn.IsPC()) || AllowUnpredictable())) {
17355        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17356          const DRegister& first = nreglist.GetFirstDRegister();
17357          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17358          EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
17359                     first.Encode(22, 12) | (len_encoding << 5) |
17360                     (rn.GetCode() << 16));
17361          AdvanceIT();
17362          return;
17363        }
17364      }
17365      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
17366      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17367          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17368           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17369          (operand.GetAddrMode() == Offset) &&
17370          ((!rn.IsPC()) || AllowUnpredictable())) {
17371        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17372          const DRegister& first = nreglist.GetFirstDRegister();
17373          EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) |
17374                     (encoded_align_1.GetEncodingValue() << 4) |
17375                     first.Encode(22, 12) | (rn.GetCode() << 16));
17376          AdvanceIT();
17377          return;
17378        }
17379      }
17380      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
17381      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17382          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17383           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17384          (operand.GetAddrMode() == PreIndex) &&
17385          ((!rn.IsPC()) || AllowUnpredictable())) {
17386        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17387          const DRegister& first = nreglist.GetFirstDRegister();
17388          EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) |
17389                     (encoded_align_1.GetEncodingValue() << 4) |
17390                     first.Encode(22, 12) | (rn.GetCode() << 16));
17391          AdvanceIT();
17392          return;
17393        }
17394      }
17395    } else {
17396      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
17397      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17398          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17399           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17400          (operand.GetAddrMode() == Offset) &&
17401          ((!rn.IsPC()) || AllowUnpredictable())) {
17402        if (cond.Is(al)) {
17403          const DRegister& first = nreglist.GetFirstDRegister();
17404          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17405          EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
17406                  first.Encode(22, 12) | (len_encoding << 5) |
17407                  (rn.GetCode() << 16));
17408          return;
17409        }
17410      }
17411      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
17412      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17413          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17414           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17415          (operand.GetAddrMode() == PreIndex) &&
17416          ((!rn.IsPC()) || AllowUnpredictable())) {
17417        if (cond.Is(al)) {
17418          const DRegister& first = nreglist.GetFirstDRegister();
17419          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17420          EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
17421                  first.Encode(22, 12) | (len_encoding << 5) |
17422                  (rn.GetCode() << 16));
17423          return;
17424        }
17425      }
17426      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
17427      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17428          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17429           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17430          (operand.GetAddrMode() == Offset) &&
17431          ((!rn.IsPC()) || AllowUnpredictable())) {
17432        if (cond.Is(al)) {
17433          const DRegister& first = nreglist.GetFirstDRegister();
17434          EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) |
17435                  (encoded_align_1.GetEncodingValue() << 4) |
17436                  first.Encode(22, 12) | (rn.GetCode() << 16));
17437          return;
17438        }
17439      }
17440      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
17441      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17442          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17443           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17444          (operand.GetAddrMode() == PreIndex) &&
17445          ((!rn.IsPC()) || AllowUnpredictable())) {
17446        if (cond.Is(al)) {
17447          const DRegister& first = nreglist.GetFirstDRegister();
17448          EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) |
17449                  (encoded_align_1.GetEncodingValue() << 4) |
17450                  first.Encode(22, 12) | (rn.GetCode() << 16));
17451          return;
17452        }
17453      }
17454    }
17455  }
17456  if (operand.IsPlainRegister()) {
17457    Register rn = operand.GetBaseRegister();
17458    Sign sign = operand.GetSign();
17459    Register rm = operand.GetOffsetRegister();
17460    Dt_size_7 encoded_dt(dt);
17461    Index_1 encoded_align_1(nreglist, dt);
17462    if (IsUsingT32()) {
17463      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
17464      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17465          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17466           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17467          sign.IsPlus() && (operand.GetAddrMode() == PostIndex)) {
17468        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17469          const DRegister& first = nreglist.GetFirstDRegister();
17470          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17471          EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) |
17472                     first.Encode(22, 12) | (len_encoding << 5) |
17473                     (rn.GetCode() << 16) | rm.GetCode());
17474          AdvanceIT();
17475          return;
17476        }
17477      }
17478      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
17479      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17480          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17481           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17482          sign.IsPlus() && (operand.GetAddrMode() == PostIndex)) {
17483        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17484          const DRegister& first = nreglist.GetFirstDRegister();
17485          EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) |
17486                     (encoded_align_1.GetEncodingValue() << 4) |
17487                     first.Encode(22, 12) | (rn.GetCode() << 16) |
17488                     rm.GetCode());
17489          AdvanceIT();
17490          return;
17491        }
17492      }
17493    } else {
17494      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
17495      if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17496          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17497           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17498          sign.IsPlus() && (operand.GetAddrMode() == PostIndex)) {
17499        if (cond.Is(al)) {
17500          const DRegister& first = nreglist.GetFirstDRegister();
17501          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17502          EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) |
17503                  first.Encode(22, 12) | (len_encoding << 5) |
17504                  (rn.GetCode() << 16) | rm.GetCode());
17505          return;
17506        }
17507      }
17508      // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
17509      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17510          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17511           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17512          sign.IsPlus() && (operand.GetAddrMode() == PostIndex)) {
17513        if (cond.Is(al)) {
17514          const DRegister& first = nreglist.GetFirstDRegister();
17515          EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) |
17516                  (encoded_align_1.GetEncodingValue() << 4) |
17517                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17518          return;
17519        }
17520      }
17521    }
17522  }
17523  Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
17524}
17525
17526void Assembler::vld4(Condition cond,
17527                     DataType dt,
17528                     const NeonRegisterList& nreglist,
17529                     const AlignedMemOperand& operand) {
17530  CheckIT(cond);
17531  if (operand.IsImmediateZero()) {
17532    Register rn = operand.GetBaseRegister();
17533    Alignment align = operand.GetAlignment();
17534    Dt_size_7 encoded_dt(dt);
17535    Dt_size_8 encoded_dt_2(dt, align);
17536    Align_align_4 encoded_align_1(align);
17537    Align_a_3 encoded_align_2(align, dt);
17538    Align_index_align_3 encoded_align_3(align, nreglist, dt);
17539    if (IsUsingT32()) {
17540      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17541      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17542          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17543           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17544          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
17545          ((!rn.IsPC()) || AllowUnpredictable())) {
17546        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17547          const DRegister& first = nreglist.GetFirstDRegister();
17548          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17549          EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
17550                     (encoded_align_1.GetEncodingValue() << 4) |
17551                     first.Encode(22, 12) | (len_encoding << 8) |
17552                     (rn.GetCode() << 16));
17553          AdvanceIT();
17554          return;
17555        }
17556      }
17557      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17558      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17559          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17560           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17561          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
17562          ((!rn.IsPC()) || AllowUnpredictable())) {
17563        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17564          const DRegister& first = nreglist.GetFirstDRegister();
17565          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17566          EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
17567                     (encoded_align_1.GetEncodingValue() << 4) |
17568                     first.Encode(22, 12) | (len_encoding << 8) |
17569                     (rn.GetCode() << 16));
17570          AdvanceIT();
17571          return;
17572        }
17573      }
17574      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17575      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17576          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17577           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17578          (operand.GetAddrMode() == Offset) && encoded_align_2.IsValid() &&
17579          ((!rn.IsPC()) || AllowUnpredictable())) {
17580        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17581          const DRegister& first = nreglist.GetFirstDRegister();
17582          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17583          EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
17584                     (encoded_align_2.GetEncodingValue() << 4) |
17585                     first.Encode(22, 12) | (len_encoding << 5) |
17586                     (rn.GetCode() << 16));
17587          AdvanceIT();
17588          return;
17589        }
17590      }
17591      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17592      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17593          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17594           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17595          (operand.GetAddrMode() == PostIndex) && encoded_align_2.IsValid() &&
17596          ((!rn.IsPC()) || AllowUnpredictable())) {
17597        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17598          const DRegister& first = nreglist.GetFirstDRegister();
17599          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17600          EmitT32_32(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
17601                     (encoded_align_2.GetEncodingValue() << 4) |
17602                     first.Encode(22, 12) | (len_encoding << 5) |
17603                     (rn.GetCode() << 16));
17604          AdvanceIT();
17605          return;
17606        }
17607      }
17608      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17609      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17610          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17611           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17612          (operand.GetAddrMode() == Offset) && encoded_align_3.IsValid() &&
17613          ((!rn.IsPC()) || AllowUnpredictable())) {
17614        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17615          const DRegister& first = nreglist.GetFirstDRegister();
17616          EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) |
17617                     (encoded_align_3.GetEncodingValue() << 4) |
17618                     first.Encode(22, 12) | (rn.GetCode() << 16));
17619          AdvanceIT();
17620          return;
17621        }
17622      }
17623      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17624      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17625          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17626           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17627          (operand.GetAddrMode() == PostIndex) && encoded_align_3.IsValid() &&
17628          ((!rn.IsPC()) || AllowUnpredictable())) {
17629        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17630          const DRegister& first = nreglist.GetFirstDRegister();
17631          EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) |
17632                     (encoded_align_3.GetEncodingValue() << 4) |
17633                     first.Encode(22, 12) | (rn.GetCode() << 16));
17634          AdvanceIT();
17635          return;
17636        }
17637      }
17638    } else {
17639      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17640      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17641          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17642           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17643          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
17644          ((!rn.IsPC()) || AllowUnpredictable())) {
17645        if (cond.Is(al)) {
17646          const DRegister& first = nreglist.GetFirstDRegister();
17647          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17648          EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
17649                  (encoded_align_1.GetEncodingValue() << 4) |
17650                  first.Encode(22, 12) | (len_encoding << 8) |
17651                  (rn.GetCode() << 16));
17652          return;
17653        }
17654      }
17655      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17656      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17657          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17658           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17659          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
17660          ((!rn.IsPC()) || AllowUnpredictable())) {
17661        if (cond.Is(al)) {
17662          const DRegister& first = nreglist.GetFirstDRegister();
17663          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17664          EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17665                  (encoded_align_1.GetEncodingValue() << 4) |
17666                  first.Encode(22, 12) | (len_encoding << 8) |
17667                  (rn.GetCode() << 16));
17668          return;
17669        }
17670      }
17671      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17672      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17673          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17674           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17675          (operand.GetAddrMode() == Offset) && encoded_align_2.IsValid() &&
17676          ((!rn.IsPC()) || AllowUnpredictable())) {
17677        if (cond.Is(al)) {
17678          const DRegister& first = nreglist.GetFirstDRegister();
17679          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17680          EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
17681                  (encoded_align_2.GetEncodingValue() << 4) |
17682                  first.Encode(22, 12) | (len_encoding << 5) |
17683                  (rn.GetCode() << 16));
17684          return;
17685        }
17686      }
17687      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17688      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17689          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17690           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17691          (operand.GetAddrMode() == PostIndex) && encoded_align_2.IsValid() &&
17692          ((!rn.IsPC()) || AllowUnpredictable())) {
17693        if (cond.Is(al)) {
17694          const DRegister& first = nreglist.GetFirstDRegister();
17695          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17696          EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
17697                  (encoded_align_2.GetEncodingValue() << 4) |
17698                  first.Encode(22, 12) | (len_encoding << 5) |
17699                  (rn.GetCode() << 16));
17700          return;
17701        }
17702      }
17703      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17704      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17705          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17706           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17707          (operand.GetAddrMode() == Offset) && encoded_align_3.IsValid() &&
17708          ((!rn.IsPC()) || AllowUnpredictable())) {
17709        if (cond.Is(al)) {
17710          const DRegister& first = nreglist.GetFirstDRegister();
17711          EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) |
17712                  (encoded_align_3.GetEncodingValue() << 4) |
17713                  first.Encode(22, 12) | (rn.GetCode() << 16));
17714          return;
17715        }
17716      }
17717      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17718      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17719          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17720           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17721          (operand.GetAddrMode() == PostIndex) && encoded_align_3.IsValid() &&
17722          ((!rn.IsPC()) || AllowUnpredictable())) {
17723        if (cond.Is(al)) {
17724          const DRegister& first = nreglist.GetFirstDRegister();
17725          EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) |
17726                  (encoded_align_3.GetEncodingValue() << 4) |
17727                  first.Encode(22, 12) | (rn.GetCode() << 16));
17728          return;
17729        }
17730      }
17731    }
17732  }
17733  if (operand.IsPlainRegister()) {
17734    Register rn = operand.GetBaseRegister();
17735    Alignment align = operand.GetAlignment();
17736    Register rm = operand.GetOffsetRegister();
17737    Dt_size_7 encoded_dt(dt);
17738    Dt_size_8 encoded_dt_2(dt, align);
17739    Align_align_4 encoded_align_1(align);
17740    Align_a_3 encoded_align_2(align, dt);
17741    Align_index_align_3 encoded_align_3(align, nreglist, dt);
17742    if (IsUsingT32()) {
17743      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17744      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17745          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17746           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17747          !rm.IsPC() && !rm.IsSP()) {
17748        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17749          const DRegister& first = nreglist.GetFirstDRegister();
17750          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17751          EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
17752                     (encoded_align_1.GetEncodingValue() << 4) |
17753                     first.Encode(22, 12) | (len_encoding << 8) |
17754                     (rn.GetCode() << 16) | rm.GetCode());
17755          AdvanceIT();
17756          return;
17757        }
17758      }
17759      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17760      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17761          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17762           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17763          !rm.IsPC() && !rm.IsSP()) {
17764        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17765          const DRegister& first = nreglist.GetFirstDRegister();
17766          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17767          EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
17768                     (encoded_align_2.GetEncodingValue() << 4) |
17769                     first.Encode(22, 12) | (len_encoding << 5) |
17770                     (rn.GetCode() << 16) | rm.GetCode());
17771          AdvanceIT();
17772          return;
17773        }
17774      }
17775      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17776      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17777          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17778           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17779          !rm.IsPC() && !rm.IsSP()) {
17780        if (cond.Is(al) || AllowStronglyDiscouraged()) {
17781          const DRegister& first = nreglist.GetFirstDRegister();
17782          EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) |
17783                     (encoded_align_3.GetEncodingValue() << 4) |
17784                     first.Encode(22, 12) | (rn.GetCode() << 16) |
17785                     rm.GetCode());
17786          AdvanceIT();
17787          return;
17788        }
17789      }
17790    } else {
17791      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17792      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17793          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17794           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17795          !rm.IsPC() && !rm.IsSP()) {
17796        if (cond.Is(al)) {
17797          const DRegister& first = nreglist.GetFirstDRegister();
17798          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17799          EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17800                  (encoded_align_1.GetEncodingValue() << 4) |
17801                  first.Encode(22, 12) | (len_encoding << 8) |
17802                  (rn.GetCode() << 16) | rm.GetCode());
17803          return;
17804        }
17805      }
17806      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17807      if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17808          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17809           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17810          !rm.IsPC() && !rm.IsSP()) {
17811        if (cond.Is(al)) {
17812          const DRegister& first = nreglist.GetFirstDRegister();
17813          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17814          EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
17815                  (encoded_align_2.GetEncodingValue() << 4) |
17816                  first.Encode(22, 12) | (len_encoding << 5) |
17817                  (rn.GetCode() << 16) | rm.GetCode());
17818          return;
17819        }
17820      }
17821      // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17822      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17823          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17824           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17825          !rm.IsPC() && !rm.IsSP()) {
17826        if (cond.Is(al)) {
17827          const DRegister& first = nreglist.GetFirstDRegister();
17828          EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) |
17829                  (encoded_align_3.GetEncodingValue() << 4) |
17830                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17831          return;
17832        }
17833      }
17834    }
17835  }
17836  Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand);
17837}
17838
17839void Assembler::vldm(Condition cond,
17840                     DataType dt,
17841                     Register rn,
17842                     WriteBack write_back,
17843                     DRegisterList dreglist) {
17844  CheckIT(cond);
17845  USE(dt);
17846  if (IsUsingT32()) {
17847    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
17848    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
17849      const DRegister& dreg = dreglist.GetFirstDRegister();
17850      unsigned len = dreglist.GetLength() * 2;
17851      EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
17852                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
17853                 (len & 0xff));
17854      AdvanceIT();
17855      return;
17856    }
17857  } else {
17858    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
17859    if (cond.IsNotNever() &&
17860        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
17861      const DRegister& dreg = dreglist.GetFirstDRegister();
17862      unsigned len = dreglist.GetLength() * 2;
17863      EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
17864              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
17865              (len & 0xff));
17866      return;
17867    }
17868  }
17869  Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist);
17870}
17871
17872void Assembler::vldm(Condition cond,
17873                     DataType dt,
17874                     Register rn,
17875                     WriteBack write_back,
17876                     SRegisterList sreglist) {
17877  CheckIT(cond);
17878  USE(dt);
17879  if (IsUsingT32()) {
17880    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
17881    const SRegister& sreg = sreglist.GetFirstSRegister();
17882    unsigned len = sreglist.GetLength();
17883    EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
17884               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
17885               (len & 0xff));
17886    AdvanceIT();
17887    return;
17888  } else {
17889    // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
17890    if (cond.IsNotNever()) {
17891      const SRegister& sreg = sreglist.GetFirstSRegister();
17892      unsigned len = sreglist.GetLength();
17893      EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
17894              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
17895              (len & 0xff));
17896      return;
17897    }
17898  }
17899  Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist);
17900}
17901
17902void Assembler::vldmdb(Condition cond,
17903                       DataType dt,
17904                       Register rn,
17905                       WriteBack write_back,
17906                       DRegisterList dreglist) {
17907  CheckIT(cond);
17908  USE(dt);
17909  if (IsUsingT32()) {
17910    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
17911    if (write_back.DoesWriteBack() &&
17912        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
17913      const DRegister& dreg = dreglist.GetFirstDRegister();
17914      unsigned len = dreglist.GetLength() * 2;
17915      EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
17916                 (len & 0xff));
17917      AdvanceIT();
17918      return;
17919    }
17920  } else {
17921    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
17922    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
17923        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
17924      const DRegister& dreg = dreglist.GetFirstDRegister();
17925      unsigned len = dreglist.GetLength() * 2;
17926      EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
17927              dreg.Encode(22, 12) | (len & 0xff));
17928      return;
17929    }
17930  }
17931  Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist);
17932}
17933
17934void Assembler::vldmdb(Condition cond,
17935                       DataType dt,
17936                       Register rn,
17937                       WriteBack write_back,
17938                       SRegisterList sreglist) {
17939  CheckIT(cond);
17940  USE(dt);
17941  if (IsUsingT32()) {
17942    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
17943    if (write_back.DoesWriteBack()) {
17944      const SRegister& sreg = sreglist.GetFirstSRegister();
17945      unsigned len = sreglist.GetLength();
17946      EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
17947                 (len & 0xff));
17948      AdvanceIT();
17949      return;
17950    }
17951  } else {
17952    // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
17953    if (write_back.DoesWriteBack() && cond.IsNotNever()) {
17954      const SRegister& sreg = sreglist.GetFirstSRegister();
17955      unsigned len = sreglist.GetLength();
17956      EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
17957              sreg.Encode(22, 12) | (len & 0xff));
17958      return;
17959    }
17960  }
17961  Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist);
17962}
17963
17964void Assembler::vldmia(Condition cond,
17965                       DataType dt,
17966                       Register rn,
17967                       WriteBack write_back,
17968                       DRegisterList dreglist) {
17969  CheckIT(cond);
17970  USE(dt);
17971  if (IsUsingT32()) {
17972    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
17973    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
17974      const DRegister& dreg = dreglist.GetFirstDRegister();
17975      unsigned len = dreglist.GetLength() * 2;
17976      EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
17977                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
17978                 (len & 0xff));
17979      AdvanceIT();
17980      return;
17981    }
17982  } else {
17983    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
17984    if (cond.IsNotNever() &&
17985        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
17986      const DRegister& dreg = dreglist.GetFirstDRegister();
17987      unsigned len = dreglist.GetLength() * 2;
17988      EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
17989              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
17990              (len & 0xff));
17991      return;
17992    }
17993  }
17994  Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist);
17995}
17996
17997void Assembler::vldmia(Condition cond,
17998                       DataType dt,
17999                       Register rn,
18000                       WriteBack write_back,
18001                       SRegisterList sreglist) {
18002  CheckIT(cond);
18003  USE(dt);
18004  if (IsUsingT32()) {
18005    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
18006    const SRegister& sreg = sreglist.GetFirstSRegister();
18007    unsigned len = sreglist.GetLength();
18008    EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
18009               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18010               (len & 0xff));
18011    AdvanceIT();
18012    return;
18013  } else {
18014    // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
18015    if (cond.IsNotNever()) {
18016      const SRegister& sreg = sreglist.GetFirstSRegister();
18017      unsigned len = sreglist.GetLength();
18018      EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18019              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18020              (len & 0xff));
18021      return;
18022    }
18023  }
18024  Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist);
18025}
18026
18027void Assembler::vldr(Condition cond, DataType dt, DRegister rd, Label* label) {
18028  CheckIT(cond);
18029  Label::Offset offset =
18030      label->IsBound()
18031          ? label->GetLocation() -
18032                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
18033          : 0;
18034  if (IsUsingT32()) {
18035    // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
18036    if (dt.IsNoneOr(Untyped64) &&
18037        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18038          ((offset & 0x3) == 0)) ||
18039         !label->IsBound())) {
18040      static class EmitOp : public Label::LabelEmitOperator {
18041       public:
18042        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18043        uint32_t Encode(uint32_t instr,
18044                        Label::Offset pc,
18045                        const Label* label) const {
18046          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18047          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18048                      ((offset & 0x3) == 0));
18049          int32_t target = offset >> 2;
18050          uint32_t U = (target >= 0) && !label->IsMinusZero();
18051          target = abs(target) | (U << 8);
18052          return instr | (target & 0xff) | ((target & 0x100) << 15);
18053        }
18054      } immop;
18055      EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12), label, immop));
18056      AdvanceIT();
18057      return;
18058    }
18059  } else {
18060    // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
18061    if (dt.IsNoneOr(Untyped64) &&
18062        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18063          ((offset & 0x3) == 0)) ||
18064         !label->IsBound()) &&
18065        cond.IsNotNever()) {
18066      static class EmitOp : public Label::LabelEmitOperator {
18067       public:
18068        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18069        uint32_t Encode(uint32_t instr,
18070                        Label::Offset pc,
18071                        const Label* label) const {
18072          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18073          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18074                      ((offset & 0x3) == 0));
18075          int32_t target = offset >> 2;
18076          uint32_t U = (target >= 0) && !label->IsMinusZero();
18077          target = abs(target) | (U << 8);
18078          return instr | (target & 0xff) | ((target & 0x100) << 15);
18079        }
18080      } immop;
18081      EmitA32(
18082          Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
18083               label,
18084               immop));
18085      return;
18086    }
18087  }
18088  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label);
18089}
18090
18091void Assembler::vldr(Condition cond,
18092                     DataType dt,
18093                     DRegister rd,
18094                     const MemOperand& operand) {
18095  CheckIT(cond);
18096  if (operand.IsImmediate()) {
18097    Register rn = operand.GetBaseRegister();
18098    int32_t offset = operand.GetOffsetImmediate();
18099    if (IsUsingT32()) {
18100      // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1
18101      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18102          ((offset % 4) == 0) && rn.Is(pc) &&
18103          (operand.GetAddrMode() == Offset)) {
18104        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18105        uint32_t offset_ = abs(offset) >> 2;
18106        EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23));
18107        AdvanceIT();
18108        return;
18109      }
18110      // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
18111      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18112          ((offset % 4) == 0) && (operand.GetAddrMode() == Offset) &&
18113          ((rn.GetCode() & 0xf) != 0xf)) {
18114        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18115        uint32_t offset_ = abs(offset) >> 2;
18116        EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
18117                   offset_ | (sign << 23));
18118        AdvanceIT();
18119        return;
18120      }
18121    } else {
18122      // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1
18123      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18124          ((offset % 4) == 0) && rn.Is(pc) &&
18125          (operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
18126        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18127        uint32_t offset_ = abs(offset) >> 2;
18128        EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18129                offset_ | (sign << 23));
18130        return;
18131      }
18132      // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
18133      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18134          ((offset % 4) == 0) && (operand.GetAddrMode() == Offset) &&
18135          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
18136        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18137        uint32_t offset_ = abs(offset) >> 2;
18138        EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18139                (rn.GetCode() << 16) | offset_ | (sign << 23));
18140        return;
18141      }
18142    }
18143  }
18144  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
18145}
18146
18147void Assembler::vldr(Condition cond, DataType dt, SRegister rd, Label* label) {
18148  CheckIT(cond);
18149  Label::Offset offset =
18150      label->IsBound()
18151          ? label->GetLocation() -
18152                AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
18153          : 0;
18154  if (IsUsingT32()) {
18155    // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
18156    if (dt.IsNoneOr(Untyped32) &&
18157        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18158          ((offset & 0x3) == 0)) ||
18159         !label->IsBound())) {
18160      static class EmitOp : public Label::LabelEmitOperator {
18161       public:
18162        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18163        uint32_t Encode(uint32_t instr,
18164                        Label::Offset pc,
18165                        const Label* label) const {
18166          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18167          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18168                      ((offset & 0x3) == 0));
18169          int32_t target = offset >> 2;
18170          uint32_t U = (target >= 0) && !label->IsMinusZero();
18171          target = abs(target) | (U << 8);
18172          return instr | (target & 0xff) | ((target & 0x100) << 15);
18173        }
18174      } immop;
18175      EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12), label, immop));
18176      AdvanceIT();
18177      return;
18178    }
18179  } else {
18180    // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
18181    if (dt.IsNoneOr(Untyped32) &&
18182        ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18183          ((offset & 0x3) == 0)) ||
18184         !label->IsBound()) &&
18185        cond.IsNotNever()) {
18186      static class EmitOp : public Label::LabelEmitOperator {
18187       public:
18188        EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18189        uint32_t Encode(uint32_t instr,
18190                        Label::Offset pc,
18191                        const Label* label) const {
18192          Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18193          VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18194                      ((offset & 0x3) == 0));
18195          int32_t target = offset >> 2;
18196          uint32_t U = (target >= 0) && !label->IsMinusZero();
18197          target = abs(target) | (U << 8);
18198          return instr | (target & 0xff) | ((target & 0x100) << 15);
18199        }
18200      } immop;
18201      EmitA32(
18202          Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
18203               label,
18204               immop));
18205      return;
18206    }
18207  }
18208  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label);
18209}
18210
18211void Assembler::vldr(Condition cond,
18212                     DataType dt,
18213                     SRegister rd,
18214                     const MemOperand& operand) {
18215  CheckIT(cond);
18216  if (operand.IsImmediate()) {
18217    Register rn = operand.GetBaseRegister();
18218    int32_t offset = operand.GetOffsetImmediate();
18219    if (IsUsingT32()) {
18220      // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2
18221      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18222          ((offset % 4) == 0) && rn.Is(pc) &&
18223          (operand.GetAddrMode() == Offset)) {
18224        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18225        uint32_t offset_ = abs(offset) >> 2;
18226        EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23));
18227        AdvanceIT();
18228        return;
18229      }
18230      // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
18231      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18232          ((offset % 4) == 0) && (operand.GetAddrMode() == Offset) &&
18233          ((rn.GetCode() & 0xf) != 0xf)) {
18234        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18235        uint32_t offset_ = abs(offset) >> 2;
18236        EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
18237                   offset_ | (sign << 23));
18238        AdvanceIT();
18239        return;
18240      }
18241    } else {
18242      // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2
18243      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18244          ((offset % 4) == 0) && rn.Is(pc) &&
18245          (operand.GetAddrMode() == Offset) && cond.IsNotNever()) {
18246        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18247        uint32_t offset_ = abs(offset) >> 2;
18248        EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18249                offset_ | (sign << 23));
18250        return;
18251      }
18252      // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
18253      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18254          ((offset % 4) == 0) && (operand.GetAddrMode() == Offset) &&
18255          cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
18256        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18257        uint32_t offset_ = abs(offset) >> 2;
18258        EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18259                (rn.GetCode() << 16) | offset_ | (sign << 23));
18260        return;
18261      }
18262    }
18263  }
18264  Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
18265}
18266
18267void Assembler::vmax(
18268    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18269  CheckIT(cond);
18270  Dt_U_size_1 encoded_dt(dt);
18271  if (IsUsingT32()) {
18272    // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
18273    if (dt.Is(F32)) {
18274      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18275        EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18276                   rm.Encode(5, 0));
18277        AdvanceIT();
18278        return;
18279      }
18280    }
18281    // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
18282    if (encoded_dt.IsValid()) {
18283      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18284        EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18285                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18286                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18287        AdvanceIT();
18288        return;
18289      }
18290    }
18291  } else {
18292    // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
18293    if (dt.Is(F32)) {
18294      if (cond.Is(al)) {
18295        EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18296                rm.Encode(5, 0));
18297        return;
18298      }
18299    }
18300    // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
18301    if (encoded_dt.IsValid()) {
18302      if (cond.Is(al)) {
18303        EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18304                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18305                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18306        return;
18307      }
18308    }
18309  }
18310  Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
18311}
18312
18313void Assembler::vmax(
18314    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18315  CheckIT(cond);
18316  Dt_U_size_1 encoded_dt(dt);
18317  if (IsUsingT32()) {
18318    // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
18319    if (dt.Is(F32)) {
18320      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18321        EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18322                   rm.Encode(5, 0));
18323        AdvanceIT();
18324        return;
18325      }
18326    }
18327    // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
18328    if (encoded_dt.IsValid()) {
18329      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18330        EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18331                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18332                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18333        AdvanceIT();
18334        return;
18335      }
18336    }
18337  } else {
18338    // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
18339    if (dt.Is(F32)) {
18340      if (cond.Is(al)) {
18341        EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18342                rm.Encode(5, 0));
18343        return;
18344      }
18345    }
18346    // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
18347    if (encoded_dt.IsValid()) {
18348      if (cond.Is(al)) {
18349        EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18350                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18351                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18352        return;
18353      }
18354    }
18355  }
18356  Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
18357}
18358
18359void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18360  CheckIT(al);
18361  if (IsUsingT32()) {
18362    // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
18363    if (OutsideITBlock() && dt.Is(F32)) {
18364      EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18365                 rm.Encode(5, 0));
18366      AdvanceIT();
18367      return;
18368    }
18369    // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
18370    if (OutsideITBlock() && dt.Is(F64)) {
18371      EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18372                 rm.Encode(5, 0));
18373      AdvanceIT();
18374      return;
18375    }
18376  } else {
18377    // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
18378    if (dt.Is(F32)) {
18379      EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18380              rm.Encode(5, 0));
18381      return;
18382    }
18383    // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
18384    if (dt.Is(F64)) {
18385      EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18386              rm.Encode(5, 0));
18387      return;
18388    }
18389  }
18390  Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18391}
18392
18393void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18394  CheckIT(al);
18395  if (IsUsingT32()) {
18396    // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
18397    if (OutsideITBlock() && dt.Is(F32)) {
18398      EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18399                 rm.Encode(5, 0));
18400      AdvanceIT();
18401      return;
18402    }
18403  } else {
18404    // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
18405    if (dt.Is(F32)) {
18406      EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18407              rm.Encode(5, 0));
18408      return;
18409    }
18410  }
18411  Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18412}
18413
18414void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
18415  CheckIT(al);
18416  if (IsUsingT32()) {
18417    // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
18418    if (OutsideITBlock() && dt.Is(F32)) {
18419      EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18420                 rm.Encode(5, 0));
18421      AdvanceIT();
18422      return;
18423    }
18424  } else {
18425    // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
18426    if (dt.Is(F32)) {
18427      EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18428              rm.Encode(5, 0));
18429      return;
18430    }
18431  }
18432  Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18433}
18434
18435void Assembler::vmin(
18436    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18437  CheckIT(cond);
18438  Dt_U_size_1 encoded_dt(dt);
18439  if (IsUsingT32()) {
18440    // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
18441    if (dt.Is(F32)) {
18442      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18443        EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18444                   rm.Encode(5, 0));
18445        AdvanceIT();
18446        return;
18447      }
18448    }
18449    // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
18450    if (encoded_dt.IsValid()) {
18451      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18452        EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18453                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18454                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18455        AdvanceIT();
18456        return;
18457      }
18458    }
18459  } else {
18460    // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
18461    if (dt.Is(F32)) {
18462      if (cond.Is(al)) {
18463        EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18464                rm.Encode(5, 0));
18465        return;
18466      }
18467    }
18468    // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
18469    if (encoded_dt.IsValid()) {
18470      if (cond.Is(al)) {
18471        EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18472                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18473                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18474        return;
18475      }
18476    }
18477  }
18478  Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
18479}
18480
18481void Assembler::vmin(
18482    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18483  CheckIT(cond);
18484  Dt_U_size_1 encoded_dt(dt);
18485  if (IsUsingT32()) {
18486    // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
18487    if (dt.Is(F32)) {
18488      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18489        EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18490                   rm.Encode(5, 0));
18491        AdvanceIT();
18492        return;
18493      }
18494    }
18495    // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
18496    if (encoded_dt.IsValid()) {
18497      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18498        EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18499                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18500                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18501        AdvanceIT();
18502        return;
18503      }
18504    }
18505  } else {
18506    // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
18507    if (dt.Is(F32)) {
18508      if (cond.Is(al)) {
18509        EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18510                rm.Encode(5, 0));
18511        return;
18512      }
18513    }
18514    // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
18515    if (encoded_dt.IsValid()) {
18516      if (cond.Is(al)) {
18517        EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18518                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18519                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18520        return;
18521      }
18522    }
18523  }
18524  Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
18525}
18526
18527void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18528  CheckIT(al);
18529  if (IsUsingT32()) {
18530    // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
18531    if (OutsideITBlock() && dt.Is(F32)) {
18532      EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18533                 rm.Encode(5, 0));
18534      AdvanceIT();
18535      return;
18536    }
18537    // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
18538    if (OutsideITBlock() && dt.Is(F64)) {
18539      EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18540                 rm.Encode(5, 0));
18541      AdvanceIT();
18542      return;
18543    }
18544  } else {
18545    // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
18546    if (dt.Is(F32)) {
18547      EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18548              rm.Encode(5, 0));
18549      return;
18550    }
18551    // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
18552    if (dt.Is(F64)) {
18553      EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18554              rm.Encode(5, 0));
18555      return;
18556    }
18557  }
18558  Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18559}
18560
18561void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18562  CheckIT(al);
18563  if (IsUsingT32()) {
18564    // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
18565    if (OutsideITBlock() && dt.Is(F32)) {
18566      EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18567                 rm.Encode(5, 0));
18568      AdvanceIT();
18569      return;
18570    }
18571  } else {
18572    // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
18573    if (dt.Is(F32)) {
18574      EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18575              rm.Encode(5, 0));
18576      return;
18577    }
18578  }
18579  Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18580}
18581
18582void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
18583  CheckIT(al);
18584  if (IsUsingT32()) {
18585    // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
18586    if (OutsideITBlock() && dt.Is(F32)) {
18587      EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18588                 rm.Encode(5, 0));
18589      AdvanceIT();
18590      return;
18591    }
18592  } else {
18593    // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
18594    if (dt.Is(F32)) {
18595      EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18596              rm.Encode(5, 0));
18597      return;
18598    }
18599  }
18600  Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18601}
18602
18603void Assembler::vmla(
18604    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
18605  CheckIT(cond);
18606  Dt_size_9 encoded_dt(dt);
18607  if (IsUsingT32()) {
18608    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
18609    if (encoded_dt.IsValid() &&
18610        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18611         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18612          (rm.GetLane() <= 1)))) {
18613      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18614        EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
18615                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18616                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18617        AdvanceIT();
18618        return;
18619      }
18620    }
18621  } else {
18622    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
18623    if (encoded_dt.IsValid() &&
18624        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18625         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18626          (rm.GetLane() <= 1)))) {
18627      if (cond.Is(al)) {
18628        EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
18629                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18630                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18631        return;
18632      }
18633    }
18634  }
18635  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
18636}
18637
18638void Assembler::vmla(
18639    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
18640  CheckIT(cond);
18641  Dt_size_9 encoded_dt(dt);
18642  if (IsUsingT32()) {
18643    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
18644    if (encoded_dt.IsValid() &&
18645        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18646         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18647          (rm.GetLane() <= 1)))) {
18648      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18649        EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
18650                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18651                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18652        AdvanceIT();
18653        return;
18654      }
18655    }
18656  } else {
18657    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
18658    if (encoded_dt.IsValid() &&
18659        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18660         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18661          (rm.GetLane() <= 1)))) {
18662      if (cond.Is(al)) {
18663        EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
18664                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18665                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18666        return;
18667      }
18668    }
18669  }
18670  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
18671}
18672
18673void Assembler::vmla(
18674    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18675  CheckIT(cond);
18676  Dt_size_10 encoded_dt(dt);
18677  if (IsUsingT32()) {
18678    // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
18679    if (dt.Is(F32)) {
18680      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18681        EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18682                   rm.Encode(5, 0));
18683        AdvanceIT();
18684        return;
18685      }
18686    }
18687    // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
18688    if (dt.Is(F64)) {
18689      EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18690                 rm.Encode(5, 0));
18691      AdvanceIT();
18692      return;
18693    }
18694    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
18695    if (encoded_dt.IsValid()) {
18696      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18697        EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) |
18698                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18699        AdvanceIT();
18700        return;
18701      }
18702    }
18703  } else {
18704    // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
18705    if (dt.Is(F32)) {
18706      if (cond.Is(al)) {
18707        EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18708                rm.Encode(5, 0));
18709        return;
18710      }
18711    }
18712    // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
18713    if (dt.Is(F64) && cond.IsNotNever()) {
18714      EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18715              rn.Encode(7, 16) | rm.Encode(5, 0));
18716      return;
18717    }
18718    // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
18719    if (encoded_dt.IsValid()) {
18720      if (cond.Is(al)) {
18721        EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) |
18722                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18723        return;
18724      }
18725    }
18726  }
18727  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
18728}
18729
18730void Assembler::vmla(
18731    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18732  CheckIT(cond);
18733  Dt_size_10 encoded_dt(dt);
18734  if (IsUsingT32()) {
18735    // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
18736    if (dt.Is(F32)) {
18737      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18738        EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18739                   rm.Encode(5, 0));
18740        AdvanceIT();
18741        return;
18742      }
18743    }
18744    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
18745    if (encoded_dt.IsValid()) {
18746      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18747        EmitT32_32(0xef000940U | (encoded_dt.GetEncodingValue() << 20) |
18748                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18749        AdvanceIT();
18750        return;
18751      }
18752    }
18753  } else {
18754    // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
18755    if (dt.Is(F32)) {
18756      if (cond.Is(al)) {
18757        EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18758                rm.Encode(5, 0));
18759        return;
18760      }
18761    }
18762    // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
18763    if (encoded_dt.IsValid()) {
18764      if (cond.Is(al)) {
18765        EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) |
18766                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18767        return;
18768      }
18769    }
18770  }
18771  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
18772}
18773
18774void Assembler::vmla(
18775    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
18776  CheckIT(cond);
18777  if (IsUsingT32()) {
18778    // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
18779    if (dt.Is(F32)) {
18780      EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18781                 rm.Encode(5, 0));
18782      AdvanceIT();
18783      return;
18784    }
18785  } else {
18786    // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
18787    if (dt.Is(F32) && cond.IsNotNever()) {
18788      EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18789              rn.Encode(7, 16) | rm.Encode(5, 0));
18790      return;
18791    }
18792  }
18793  Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
18794}
18795
18796void Assembler::vmlal(
18797    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
18798  CheckIT(cond);
18799  Dt_size_11 encoded_dt(dt);
18800  if (IsUsingT32()) {
18801    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
18802    if (encoded_dt.IsValid() &&
18803        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18804         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18805          (rm.GetLane() <= 1)))) {
18806      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18807        EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) |
18808                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18809                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18810        AdvanceIT();
18811        return;
18812      }
18813    }
18814  } else {
18815    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
18816    if (encoded_dt.IsValid() &&
18817        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18818         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18819          (rm.GetLane() <= 1)))) {
18820      if (cond.Is(al)) {
18821        EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) |
18822                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18823                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18824        return;
18825      }
18826    }
18827  }
18828  Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
18829}
18830
18831void Assembler::vmlal(
18832    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
18833  CheckIT(cond);
18834  Dt_size_12 encoded_dt(dt);
18835  if (IsUsingT32()) {
18836    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
18837    if (encoded_dt.IsValid()) {
18838      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18839        EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) |
18840                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18841                   rn.Encode(7, 16) | rm.Encode(5, 0));
18842        AdvanceIT();
18843        return;
18844      }
18845    }
18846  } else {
18847    // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
18848    if (encoded_dt.IsValid()) {
18849      if (cond.Is(al)) {
18850        EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) |
18851                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18852                rn.Encode(7, 16) | rm.Encode(5, 0));
18853        return;
18854      }
18855    }
18856  }
18857  Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
18858}
18859
18860void Assembler::vmls(
18861    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
18862  CheckIT(cond);
18863  Dt_size_9 encoded_dt(dt);
18864  if (IsUsingT32()) {
18865    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
18866    if (encoded_dt.IsValid() &&
18867        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18868         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18869          (rm.GetLane() <= 1)))) {
18870      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18871        EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
18872                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18873                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18874        AdvanceIT();
18875        return;
18876      }
18877    }
18878  } else {
18879    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
18880    if (encoded_dt.IsValid() &&
18881        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18882         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18883          (rm.GetLane() <= 1)))) {
18884      if (cond.Is(al)) {
18885        EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
18886                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18887                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18888        return;
18889      }
18890    }
18891  }
18892  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
18893}
18894
18895void Assembler::vmls(
18896    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
18897  CheckIT(cond);
18898  Dt_size_9 encoded_dt(dt);
18899  if (IsUsingT32()) {
18900    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
18901    if (encoded_dt.IsValid() &&
18902        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18903         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18904          (rm.GetLane() <= 1)))) {
18905      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18906        EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
18907                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18908                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18909        AdvanceIT();
18910        return;
18911      }
18912    }
18913  } else {
18914    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
18915    if (encoded_dt.IsValid() &&
18916        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18917         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18918          (rm.GetLane() <= 1)))) {
18919      if (cond.Is(al)) {
18920        EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
18921                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18922                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
18923        return;
18924      }
18925    }
18926  }
18927  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
18928}
18929
18930void Assembler::vmls(
18931    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18932  CheckIT(cond);
18933  Dt_size_10 encoded_dt(dt);
18934  if (IsUsingT32()) {
18935    // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
18936    if (dt.Is(F32)) {
18937      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18938        EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18939                   rm.Encode(5, 0));
18940        AdvanceIT();
18941        return;
18942      }
18943    }
18944    // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
18945    if (dt.Is(F64)) {
18946      EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18947                 rm.Encode(5, 0));
18948      AdvanceIT();
18949      return;
18950    }
18951    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
18952    if (encoded_dt.IsValid()) {
18953      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18954        EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) |
18955                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18956        AdvanceIT();
18957        return;
18958      }
18959    }
18960  } else {
18961    // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
18962    if (dt.Is(F32)) {
18963      if (cond.Is(al)) {
18964        EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18965                rm.Encode(5, 0));
18966        return;
18967      }
18968    }
18969    // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
18970    if (dt.Is(F64) && cond.IsNotNever()) {
18971      EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18972              rn.Encode(7, 16) | rm.Encode(5, 0));
18973      return;
18974    }
18975    // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
18976    if (encoded_dt.IsValid()) {
18977      if (cond.Is(al)) {
18978        EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) |
18979                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18980        return;
18981      }
18982    }
18983  }
18984  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
18985}
18986
18987void Assembler::vmls(
18988    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18989  CheckIT(cond);
18990  Dt_size_10 encoded_dt(dt);
18991  if (IsUsingT32()) {
18992    // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
18993    if (dt.Is(F32)) {
18994      if (cond.Is(al) || AllowStronglyDiscouraged()) {
18995        EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18996                   rm.Encode(5, 0));
18997        AdvanceIT();
18998        return;
18999      }
19000    }
19001    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
19002    if (encoded_dt.IsValid()) {
19003      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19004        EmitT32_32(0xff000940U | (encoded_dt.GetEncodingValue() << 20) |
19005                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19006        AdvanceIT();
19007        return;
19008      }
19009    }
19010  } else {
19011    // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
19012    if (dt.Is(F32)) {
19013      if (cond.Is(al)) {
19014        EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19015                rm.Encode(5, 0));
19016        return;
19017      }
19018    }
19019    // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
19020    if (encoded_dt.IsValid()) {
19021      if (cond.Is(al)) {
19022        EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) |
19023                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19024        return;
19025      }
19026    }
19027  }
19028  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19029}
19030
19031void Assembler::vmls(
19032    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
19033  CheckIT(cond);
19034  if (IsUsingT32()) {
19035    // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
19036    if (dt.Is(F32)) {
19037      EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19038                 rm.Encode(5, 0));
19039      AdvanceIT();
19040      return;
19041    }
19042  } else {
19043    // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
19044    if (dt.Is(F32) && cond.IsNotNever()) {
19045      EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19046              rn.Encode(7, 16) | rm.Encode(5, 0));
19047      return;
19048    }
19049  }
19050  Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19051}
19052
19053void Assembler::vmlsl(
19054    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
19055  CheckIT(cond);
19056  Dt_size_11 encoded_dt(dt);
19057  if (IsUsingT32()) {
19058    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
19059    if (encoded_dt.IsValid() &&
19060        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19061         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19062          (rm.GetLane() <= 1)))) {
19063      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19064        EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) |
19065                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19066                   rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19067        AdvanceIT();
19068        return;
19069      }
19070    }
19071  } else {
19072    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
19073    if (encoded_dt.IsValid() &&
19074        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19075         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19076          (rm.GetLane() <= 1)))) {
19077      if (cond.Is(al)) {
19078        EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) |
19079                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19080                rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19081        return;
19082      }
19083    }
19084  }
19085  Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
19086}
19087
19088void Assembler::vmlsl(
19089    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
19090  CheckIT(cond);
19091  Dt_size_12 encoded_dt(dt);
19092  if (IsUsingT32()) {
19093    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
19094    if (encoded_dt.IsValid()) {
19095      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19096        EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) |
19097                   (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19098                   rn.Encode(7, 16) | rm.Encode(5, 0));
19099        AdvanceIT();
19100        return;
19101      }
19102    }
19103  } else {
19104    // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
19105    if (encoded_dt.IsValid()) {
19106      if (cond.Is(al)) {
19107        EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) |
19108                (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19109                rn.Encode(7, 16) | rm.Encode(5, 0));
19110        return;
19111      }
19112    }
19113  }
19114  Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
19115}
19116
19117void Assembler::vmov(Condition cond, Register rt, SRegister rn) {
19118  CheckIT(cond);
19119  if (IsUsingT32()) {
19120    // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1
19121    EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16));
19122    AdvanceIT();
19123    return;
19124  } else {
19125    // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1
19126    if (cond.IsNotNever()) {
19127      EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19128              rn.Encode(7, 16));
19129      return;
19130    }
19131  }
19132  Delegate(kVmov, &Assembler::vmov, cond, rt, rn);
19133}
19134
19135void Assembler::vmov(Condition cond, SRegister rn, Register rt) {
19136  CheckIT(cond);
19137  if (IsUsingT32()) {
19138    // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1
19139    EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12));
19140    AdvanceIT();
19141    return;
19142  } else {
19143    // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1
19144    if (cond.IsNotNever()) {
19145      EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) |
19146              (rt.GetCode() << 12));
19147      return;
19148    }
19149  }
19150  Delegate(kVmov, &Assembler::vmov, cond, rn, rt);
19151}
19152
19153void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) {
19154  CheckIT(cond);
19155  if (IsUsingT32()) {
19156    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1
19157    EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
19158               rm.Encode(5, 0));
19159    AdvanceIT();
19160    return;
19161  } else {
19162    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1
19163    if (cond.IsNotNever()) {
19164      EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19165              (rt2.GetCode() << 16) | rm.Encode(5, 0));
19166      return;
19167    }
19168  }
19169  Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm);
19170}
19171
19172void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) {
19173  CheckIT(cond);
19174  if (IsUsingT32()) {
19175    // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1
19176    EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
19177               (rt2.GetCode() << 16));
19178    AdvanceIT();
19179    return;
19180  } else {
19181    // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1
19182    if (cond.IsNotNever()) {
19183      EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
19184              (rt.GetCode() << 12) | (rt2.GetCode() << 16));
19185      return;
19186    }
19187  }
19188  Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2);
19189}
19190
19191void Assembler::vmov(
19192    Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) {
19193  CheckIT(cond);
19194  if (IsUsingT32()) {
19195    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1
19196    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) {
19197      EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
19198                 rm.Encode(5, 0));
19199      AdvanceIT();
19200      return;
19201    }
19202  } else {
19203    // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1
19204    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
19205        cond.IsNotNever()) {
19206      EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19207              (rt2.GetCode() << 16) | rm.Encode(5, 0));
19208      return;
19209    }
19210  }
19211  Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1);
19212}
19213
19214void Assembler::vmov(
19215    Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) {
19216  CheckIT(cond);
19217  if (IsUsingT32()) {
19218    // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1
19219    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) {
19220      EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
19221                 (rt2.GetCode() << 16));
19222      AdvanceIT();
19223      return;
19224    }
19225  } else {
19226    // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1
19227    if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
19228        cond.IsNotNever()) {
19229      EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
19230              (rt.GetCode() << 12) | (rt2.GetCode() << 16));
19231      return;
19232    }
19233  }
19234  Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2);
19235}
19236
19237void Assembler::vmov(Condition cond,
19238                     DataType dt,
19239                     DRegisterLane rd,
19240                     Register rt) {
19241  CheckIT(cond);
19242  Dt_opc1_opc2_1 encoded_dt(dt, rd);
19243  if (IsUsingT32()) {
19244    // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1
19245    if (encoded_dt.IsValid()) {
19246      EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19247                 ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19248                 rd.Encode(7, 16) | (rt.GetCode() << 12));
19249      AdvanceIT();
19250      return;
19251    }
19252  } else {
19253    // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1
19254    if (encoded_dt.IsValid() && cond.IsNotNever()) {
19255      EmitA32(0x0e000b10U | (cond.GetCondition() << 28) |
19256              ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19257              ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) |
19258              (rt.GetCode() << 12));
19259      return;
19260    }
19261  }
19262  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt);
19263}
19264
19265void Assembler::vmov(Condition cond,
19266                     DataType dt,
19267                     DRegister rd,
19268                     const DOperand& operand) {
19269  CheckIT(cond);
19270  if (operand.IsImmediate()) {
19271    ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
19272    ImmediateVFP vfp(operand.GetNeonImmediate());
19273    if (IsUsingT32()) {
19274      // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
19275      if (encoded_dt.IsValid()) {
19276        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19277          EmitT32_32(
19278              0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19279              ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19280              rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19281              ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19282              ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
19283          AdvanceIT();
19284          return;
19285        }
19286      }
19287      // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2
19288      if (dt.Is(F64) && vfp.IsValid()) {
19289        EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) |
19290                   (vfp.GetEncodingValue() & 0xf) |
19291                   ((vfp.GetEncodingValue() & 0xf0) << 12));
19292        AdvanceIT();
19293        return;
19294      }
19295    } else {
19296      // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
19297      if (encoded_dt.IsValid()) {
19298        if (cond.Is(al)) {
19299          EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19300                  ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19301                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19302                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19303                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
19304          return;
19305        }
19306      }
19307      // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2
19308      if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) {
19309        EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19310                (vfp.GetEncodingValue() & 0xf) |
19311                ((vfp.GetEncodingValue() & 0xf0) << 12));
19312        return;
19313      }
19314    }
19315  }
19316  if (operand.IsRegister()) {
19317    DRegister rm = operand.GetRegister();
19318    if (IsUsingT32()) {
19319      // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
19320      if (dt.Is(F64)) {
19321        EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
19322        AdvanceIT();
19323        return;
19324      }
19325      // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
19326      if (!dt.Is(F64)) {
19327        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19328          EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19329                     rm.Encode(5, 0));
19330          AdvanceIT();
19331          return;
19332        }
19333      }
19334    } else {
19335      // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
19336      if (dt.Is(F64) && cond.IsNotNever()) {
19337        EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19338                rm.Encode(5, 0));
19339        return;
19340      }
19341      // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
19342      if (!dt.Is(F64)) {
19343        if (cond.Is(al)) {
19344          EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19345                  rm.Encode(5, 0));
19346          return;
19347        }
19348      }
19349    }
19350  }
19351  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19352}
19353
19354void Assembler::vmov(Condition cond,
19355                     DataType dt,
19356                     QRegister rd,
19357                     const QOperand& operand) {
19358  CheckIT(cond);
19359  if (operand.IsImmediate()) {
19360    ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
19361    if (IsUsingT32()) {
19362      // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
19363      if (encoded_dt.IsValid()) {
19364        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19365          EmitT32_32(
19366              0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19367              ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19368              rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19369              ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19370              ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
19371          AdvanceIT();
19372          return;
19373        }
19374      }
19375    } else {
19376      // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
19377      if (encoded_dt.IsValid()) {
19378        if (cond.Is(al)) {
19379          EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19380                  ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19381                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19382                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19383                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
19384          return;
19385        }
19386      }
19387    }
19388  }
19389  if (operand.IsRegister()) {
19390    QRegister rm = operand.GetRegister();
19391    if (IsUsingT32()) {
19392      // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
19393      if (!dt.Is(F64)) {
19394        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19395          EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19396                     rm.Encode(5, 0));
19397          AdvanceIT();
19398          return;
19399        }
19400      }
19401    } else {
19402      // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
19403      if (!dt.Is(F64)) {
19404        if (cond.Is(al)) {
19405          EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19406                  rm.Encode(5, 0));
19407          return;
19408        }
19409      }
19410    }
19411  }
19412  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19413}
19414
19415void Assembler::vmov(Condition cond,
19416                     DataType dt,
19417                     SRegister rd,
19418                     const SOperand& operand) {
19419  CheckIT(cond);
19420  if (operand.IsImmediate()) {
19421    ImmediateVFP vfp(operand.GetNeonImmediate());
19422    if (IsUsingT32()) {
19423      // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2
19424      if (dt.Is(F32) && vfp.IsValid()) {
19425        EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) |
19426                   (vfp.GetEncodingValue() & 0xf) |
19427                   ((vfp.GetEncodingValue() & 0xf0) << 12));
19428        AdvanceIT();
19429        return;
19430      }
19431    } else {
19432      // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2
19433      if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) {
19434        EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19435                (vfp.GetEncodingValue() & 0xf) |
19436                ((vfp.GetEncodingValue() & 0xf0) << 12));
19437        return;
19438      }
19439    }
19440  }
19441  if (operand.IsRegister()) {
19442    SRegister rm = operand.GetRegister();
19443    if (IsUsingT32()) {
19444      // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
19445      if (dt.Is(F32)) {
19446        EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
19447        AdvanceIT();
19448        return;
19449      }
19450    } else {
19451      // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
19452      if (dt.Is(F32) && cond.IsNotNever()) {
19453        EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19454                rm.Encode(5, 0));
19455        return;
19456      }
19457    }
19458  }
19459  Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19460}
19461
19462void Assembler::vmov(Condition cond,
19463                     DataType dt,
19464                     Register rt,
19465                     DRegisterLane rn) {
19466  CheckIT(cond);
19467  Dt_U_opc1_opc2_1 encoded_dt(dt, rn);
19468  if (IsUsingT32()) {
19469    // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1
19470    if (encoded_dt.IsValid()) {
19471      EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19472                 ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19473                 ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
19474                 (rt.GetCode() << 12) | rn.Encode(7, 16));
19475      AdvanceIT();
19476      return;
19477    }
19478  } else {
19479    // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1
19480    if (encoded_dt.IsValid() && cond.IsNotNever()) {
19481      EmitA32(0x0e100b10U | (cond.GetCondition() << 28) |
19482              ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19483              ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19484              ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
19485              (rt.GetCode() << 12) | rn.Encode(7, 16));
19486      return;
19487    }
19488  }
19489  Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn);
19490}
19491
19492void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) {
19493  CheckIT(cond);
19494  Dt_U_imm3H_1 encoded_dt(dt);
19495  if (IsUsingT32()) {
19496    // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1
19497    if (encoded_dt.IsValid()) {
19498      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19499        EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
19500                   ((encoded_dt.GetEncodingValue() & 0x8) << 25) |
19501                   rd.Encode(22, 12) | rm.Encode(5, 0));
19502        AdvanceIT();
19503        return;
19504      }
19505    }
19506  } else {
19507    // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
19508    if (encoded_dt.IsValid()) {
19509      if (cond.Is(al)) {
19510        EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
19511                ((encoded_dt.GetEncodingValue() & 0x8) << 21) |
19512                rd.Encode(22, 12) | rm.Encode(5, 0));
19513        return;
19514      }
19515    }
19516  }
19517  Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm);
19518}
19519
19520void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) {
19521  CheckIT(cond);
19522  Dt_size_3 encoded_dt(dt);
19523  if (IsUsingT32()) {
19524    // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
19525    if (encoded_dt.IsValid()) {
19526      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19527        EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) |
19528                   rd.Encode(22, 12) | rm.Encode(5, 0));
19529        AdvanceIT();
19530        return;
19531      }
19532    }
19533  } else {
19534    // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
19535    if (encoded_dt.IsValid()) {
19536      if (cond.Is(al)) {
19537        EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) |
19538                rd.Encode(22, 12) | rm.Encode(5, 0));
19539        return;
19540      }
19541    }
19542  }
19543  Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm);
19544}
19545
19546void Assembler::vmrs(Condition cond,
19547                     RegisterOrAPSR_nzcv rt,
19548                     SpecialFPRegister spec_reg) {
19549  CheckIT(cond);
19550  if (IsUsingT32()) {
19551    // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1
19552    EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16));
19553    AdvanceIT();
19554    return;
19555  } else {
19556    // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1
19557    if (cond.IsNotNever()) {
19558      EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19559              (spec_reg.GetReg() << 16));
19560      return;
19561    }
19562  }
19563  Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg);
19564}
19565
19566void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) {
19567  CheckIT(cond);
19568  if (IsUsingT32()) {
19569    // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1
19570    EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
19571    AdvanceIT();
19572    return;
19573  } else {
19574    // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1
19575    if (cond.IsNotNever()) {
19576      EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) |
19577              (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
19578      return;
19579    }
19580  }
19581  Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt);
19582}
19583
19584void Assembler::vmul(Condition cond,
19585                     DataType dt,
19586                     DRegister rd,
19587                     DRegister rn,
19588                     DRegister dm,
19589                     unsigned index) {
19590  CheckIT(cond);
19591  Dt_F_size_3 encoded_dt(dt);
19592  if (IsUsingT32()) {
19593    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1
19594    if (encoded_dt.IsValid() &&
19595        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
19596         (!dt.Is(I16) && (index <= 1)))) {
19597      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19598        uint32_t shift = 4;
19599        if (dt.Is(I16)) {
19600          shift = 3;
19601        }
19602        uint32_t mvm = dm.GetCode() | index << shift;
19603        EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19604                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
19605                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
19606                   ((mvm & 0x10) << 1));
19607        AdvanceIT();
19608        return;
19609      }
19610    }
19611  } else {
19612    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1
19613    if (encoded_dt.IsValid() &&
19614        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
19615         (!dt.Is(I16) && (index <= 1)))) {
19616      if (cond.Is(al)) {
19617        uint32_t shift = 4;
19618        if (dt.Is(I16)) {
19619          shift = 3;
19620        }
19621        uint32_t mvm = dm.GetCode() | index << shift;
19622        EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19623                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
19624                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
19625                ((mvm & 0x10) << 1));
19626        return;
19627      }
19628    }
19629  }
19630  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
19631}
19632
19633void Assembler::vmul(Condition cond,
19634                     DataType dt,
19635                     QRegister rd,
19636                     QRegister rn,
19637                     DRegister dm,
19638                     unsigned index) {
19639  CheckIT(cond);
19640  Dt_F_size_3 encoded_dt(dt);
19641  if (IsUsingT32()) {
19642    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1
19643    if (encoded_dt.IsValid() &&
19644        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
19645         (!dt.Is(I16) && (index <= 1)))) {
19646      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19647        uint32_t shift = 4;
19648        if (dt.Is(I16)) {
19649          shift = 3;
19650        }
19651        uint32_t mvm = dm.GetCode() | index << shift;
19652        EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19653                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
19654                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
19655                   ((mvm & 0x10) << 1));
19656        AdvanceIT();
19657        return;
19658      }
19659    }
19660  } else {
19661    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1
19662    if (encoded_dt.IsValid() &&
19663        ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
19664         (!dt.Is(I16) && (index <= 1)))) {
19665      if (cond.Is(al)) {
19666        uint32_t shift = 4;
19667        if (dt.Is(I16)) {
19668          shift = 3;
19669        }
19670        uint32_t mvm = dm.GetCode() | index << shift;
19671        EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19672                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
19673                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
19674                ((mvm & 0x10) << 1));
19675        return;
19676      }
19677    }
19678  }
19679  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
19680}
19681
19682void Assembler::vmul(
19683    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
19684  CheckIT(cond);
19685  Dt_op_size_1 encoded_dt(dt);
19686  if (IsUsingT32()) {
19687    // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
19688    if (dt.Is(F32)) {
19689      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19690        EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19691                   rm.Encode(5, 0));
19692        AdvanceIT();
19693        return;
19694      }
19695    }
19696    // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
19697    if (dt.Is(F64)) {
19698      EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19699                 rm.Encode(5, 0));
19700      AdvanceIT();
19701      return;
19702    }
19703    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
19704    if (encoded_dt.IsValid()) {
19705      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19706        EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19707                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
19708                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19709        AdvanceIT();
19710        return;
19711      }
19712    }
19713  } else {
19714    // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
19715    if (dt.Is(F32)) {
19716      if (cond.Is(al)) {
19717        EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19718                rm.Encode(5, 0));
19719        return;
19720      }
19721    }
19722    // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
19723    if (dt.Is(F64) && cond.IsNotNever()) {
19724      EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19725              rn.Encode(7, 16) | rm.Encode(5, 0));
19726      return;
19727    }
19728    // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
19729    if (encoded_dt.IsValid()) {
19730      if (cond.Is(al)) {
19731        EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19732                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
19733                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19734        return;
19735      }
19736    }
19737  }
19738  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
19739}
19740
19741void Assembler::vmul(
19742    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
19743  CheckIT(cond);
19744  Dt_op_size_1 encoded_dt(dt);
19745  if (IsUsingT32()) {
19746    // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
19747    if (dt.Is(F32)) {
19748      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19749        EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19750                   rm.Encode(5, 0));
19751        AdvanceIT();
19752        return;
19753      }
19754    }
19755    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
19756    if (encoded_dt.IsValid()) {
19757      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19758        EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19759                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
19760                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19761        AdvanceIT();
19762        return;
19763      }
19764    }
19765  } else {
19766    // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
19767    if (dt.Is(F32)) {
19768      if (cond.Is(al)) {
19769        EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19770                rm.Encode(5, 0));
19771        return;
19772      }
19773    }
19774    // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
19775    if (encoded_dt.IsValid()) {
19776      if (cond.Is(al)) {
19777        EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19778                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
19779                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19780        return;
19781      }
19782    }
19783  }
19784  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
19785}
19786
19787void Assembler::vmul(
19788    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
19789  CheckIT(cond);
19790  if (IsUsingT32()) {
19791    // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
19792    if (dt.Is(F32)) {
19793      EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19794                 rm.Encode(5, 0));
19795      AdvanceIT();
19796      return;
19797    }
19798  } else {
19799    // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
19800    if (dt.Is(F32) && cond.IsNotNever()) {
19801      EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19802              rn.Encode(7, 16) | rm.Encode(5, 0));
19803      return;
19804    }
19805  }
19806  Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
19807}
19808
19809void Assembler::vmull(Condition cond,
19810                      DataType dt,
19811                      QRegister rd,
19812                      DRegister rn,
19813                      DRegister dm,
19814                      unsigned index) {
19815  CheckIT(cond);
19816  Dt_U_size_2 encoded_dt(dt);
19817  if (IsUsingT32()) {
19818    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1
19819    if (encoded_dt.IsValid() &&
19820        (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
19821         (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) {
19822      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19823        uint32_t shift = 4;
19824        if (dt.Is(S16) || dt.Is(U16)) {
19825          shift = 3;
19826        }
19827        uint32_t mvm = dm.GetCode() | index << shift;
19828        EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19829                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
19830                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
19831                   ((mvm & 0x10) << 1));
19832        AdvanceIT();
19833        return;
19834      }
19835    }
19836  } else {
19837    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1
19838    if (encoded_dt.IsValid() &&
19839        (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
19840         (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) {
19841      if (cond.Is(al)) {
19842        uint32_t shift = 4;
19843        if (dt.Is(S16) || dt.Is(U16)) {
19844          shift = 3;
19845        }
19846        uint32_t mvm = dm.GetCode() | index << shift;
19847        EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19848                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
19849                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
19850                ((mvm & 0x10) << 1));
19851        return;
19852      }
19853    }
19854  }
19855  Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index);
19856}
19857
19858void Assembler::vmull(
19859    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
19860  CheckIT(cond);
19861  Dt_op_U_size_1 encoded_dt(dt);
19862  if (IsUsingT32()) {
19863    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
19864    if (encoded_dt.IsValid()) {
19865      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19866        EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19867                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
19868                   ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
19869                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19870        AdvanceIT();
19871        return;
19872      }
19873    }
19874  } else {
19875    // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
19876    if (encoded_dt.IsValid()) {
19877      if (cond.Is(al)) {
19878        EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19879                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
19880                ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
19881                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19882        return;
19883      }
19884    }
19885  }
19886  Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm);
19887}
19888
19889void Assembler::vmvn(Condition cond,
19890                     DataType dt,
19891                     DRegister rd,
19892                     const DOperand& operand) {
19893  CheckIT(cond);
19894  if (operand.IsImmediate()) {
19895    ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
19896    if (IsUsingT32()) {
19897      // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
19898      if (encoded_dt.IsValid()) {
19899        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19900          EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
19901                     rd.Encode(22, 12) |
19902                     (encoded_dt.GetEncodedImmediate() & 0xf) |
19903                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19904                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
19905          AdvanceIT();
19906          return;
19907        }
19908      }
19909    } else {
19910      // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
19911      if (encoded_dt.IsValid()) {
19912        if (cond.Is(al)) {
19913          EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
19914                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19915                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19916                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
19917          return;
19918        }
19919      }
19920    }
19921  }
19922  if (operand.IsRegister()) {
19923    DRegister rm = operand.GetRegister();
19924    USE(dt);
19925    if (IsUsingT32()) {
19926      // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
19927      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19928        EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
19929        AdvanceIT();
19930        return;
19931      }
19932    } else {
19933      // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
19934      if (cond.Is(al)) {
19935        EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
19936        return;
19937      }
19938    }
19939  }
19940  Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
19941}
19942
19943void Assembler::vmvn(Condition cond,
19944                     DataType dt,
19945                     QRegister rd,
19946                     const QOperand& operand) {
19947  CheckIT(cond);
19948  if (operand.IsImmediate()) {
19949    ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
19950    if (IsUsingT32()) {
19951      // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
19952      if (encoded_dt.IsValid()) {
19953        if (cond.Is(al) || AllowStronglyDiscouraged()) {
19954          EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
19955                     rd.Encode(22, 12) |
19956                     (encoded_dt.GetEncodedImmediate() & 0xf) |
19957                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19958                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
19959          AdvanceIT();
19960          return;
19961        }
19962      }
19963    } else {
19964      // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
19965      if (encoded_dt.IsValid()) {
19966        if (cond.Is(al)) {
19967          EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
19968                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19969                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19970                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
19971          return;
19972        }
19973      }
19974    }
19975  }
19976  if (operand.IsRegister()) {
19977    QRegister rm = operand.GetRegister();
19978    USE(dt);
19979    if (IsUsingT32()) {
19980      // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
19981      if (cond.Is(al) || AllowStronglyDiscouraged()) {
19982        EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
19983        AdvanceIT();
19984        return;
19985      }
19986    } else {
19987      // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
19988      if (cond.Is(al)) {
19989        EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
19990        return;
19991      }
19992    }
19993  }
19994  Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
19995}
19996
19997void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
19998  CheckIT(cond);
19999  Dt_F_size_1 encoded_dt(dt);
20000  if (IsUsingT32()) {
20001    // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20002    if (encoded_dt.IsValid()) {
20003      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20004        EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20005                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20006                   rd.Encode(22, 12) | rm.Encode(5, 0));
20007        AdvanceIT();
20008        return;
20009      }
20010    }
20011    // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
20012    if (dt.Is(F64)) {
20013      EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
20014      AdvanceIT();
20015      return;
20016    }
20017  } else {
20018    // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
20019    if (encoded_dt.IsValid()) {
20020      if (cond.Is(al)) {
20021        EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20022                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20023                rd.Encode(22, 12) | rm.Encode(5, 0));
20024        return;
20025      }
20026    }
20027    // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
20028    if (dt.Is(F64) && cond.IsNotNever()) {
20029      EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20030              rm.Encode(5, 0));
20031      return;
20032    }
20033  }
20034  Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20035}
20036
20037void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
20038  CheckIT(cond);
20039  Dt_F_size_1 encoded_dt(dt);
20040  if (IsUsingT32()) {
20041    // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
20042    if (encoded_dt.IsValid()) {
20043      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20044        EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20045                   ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20046                   rd.Encode(22, 12) | rm.Encode(5, 0));
20047        AdvanceIT();
20048        return;
20049      }
20050    }
20051  } else {
20052    // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
20053    if (encoded_dt.IsValid()) {
20054      if (cond.Is(al)) {
20055        EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20056                ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20057                rd.Encode(22, 12) | rm.Encode(5, 0));
20058        return;
20059      }
20060    }
20061  }
20062  Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20063}
20064
20065void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) {
20066  CheckIT(cond);
20067  if (IsUsingT32()) {
20068    // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
20069    if (dt.Is(F32)) {
20070      EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
20071      AdvanceIT();
20072      return;
20073    }
20074  } else {
20075    // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
20076    if (dt.Is(F32) && cond.IsNotNever()) {
20077      EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20078              rm.Encode(5, 0));
20079      return;
20080    }
20081  }
20082  Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20083}
20084
20085void Assembler::vnmla(
20086    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20087  CheckIT(cond);
20088  if (IsUsingT32()) {
20089    // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
20090    if (dt.Is(F32)) {
20091      EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20092                 rm.Encode(5, 0));
20093      AdvanceIT();
20094      return;
20095    }
20096  } else {
20097    // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
20098    if (dt.Is(F32) && cond.IsNotNever()) {
20099      EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20100              rn.Encode(7, 16) | rm.Encode(5, 0));
20101      return;
20102    }
20103  }
20104  Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
20105}
20106
20107void Assembler::vnmla(
20108    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20109  CheckIT(cond);
20110  if (IsUsingT32()) {
20111    // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
20112    if (dt.Is(F64)) {
20113      EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20114                 rm.Encode(5, 0));
20115      AdvanceIT();
20116      return;
20117    }
20118  } else {
20119    // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
20120    if (dt.Is(F64) && cond.IsNotNever()) {
20121      EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20122              rn.Encode(7, 16) | rm.Encode(5, 0));
20123      return;
20124    }
20125  }
20126  Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
20127}
20128
20129void Assembler::vnmls(
20130    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20131  CheckIT(cond);
20132  if (IsUsingT32()) {
20133    // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
20134    if (dt.Is(F32)) {
20135      EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20136                 rm.Encode(5, 0));
20137      AdvanceIT();
20138      return;
20139    }
20140  } else {
20141    // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
20142    if (dt.Is(F32) && cond.IsNotNever()) {
20143      EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20144              rn.Encode(7, 16) | rm.Encode(5, 0));
20145      return;
20146    }
20147  }
20148  Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
20149}
20150
20151void Assembler::vnmls(
20152    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20153  CheckIT(cond);
20154  if (IsUsingT32()) {
20155    // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
20156    if (dt.Is(F64)) {
20157      EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20158                 rm.Encode(5, 0));
20159      AdvanceIT();
20160      return;
20161    }
20162  } else {
20163    // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
20164    if (dt.Is(F64) && cond.IsNotNever()) {
20165      EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20166              rn.Encode(7, 16) | rm.Encode(5, 0));
20167      return;
20168    }
20169  }
20170  Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
20171}
20172
20173void Assembler::vnmul(
20174    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20175  CheckIT(cond);
20176  if (IsUsingT32()) {
20177    // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
20178    if (dt.Is(F32)) {
20179      EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20180                 rm.Encode(5, 0));
20181      AdvanceIT();
20182      return;
20183    }
20184  } else {
20185    // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
20186    if (dt.Is(F32) && cond.IsNotNever()) {
20187      EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20188              rn.Encode(7, 16) | rm.Encode(5, 0));
20189      return;
20190    }
20191  }
20192  Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
20193}
20194
20195void Assembler::vnmul(
20196    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20197  CheckIT(cond);
20198  if (IsUsingT32()) {
20199    // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
20200    if (dt.Is(F64)) {
20201      EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20202                 rm.Encode(5, 0));
20203      AdvanceIT();
20204      return;
20205    }
20206  } else {
20207    // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
20208    if (dt.Is(F64) && cond.IsNotNever()) {
20209      EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20210              rn.Encode(7, 16) | rm.Encode(5, 0));
20211      return;
20212    }
20213  }
20214  Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
20215}
20216
20217void Assembler::vorn(Condition cond,
20218                     DataType dt,
20219                     DRegister rd,
20220                     DRegister rn,
20221                     const DOperand& operand) {
20222  CheckIT(cond);
20223  if (operand.IsImmediate()) {
20224    ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
20225    if (IsUsingT32()) {
20226      // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
20227      if (encoded_dt.IsValid() && rd.Is(rn)) {
20228        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20229          EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
20230                     rd.Encode(22, 12) |
20231                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20232                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20233                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20234          AdvanceIT();
20235          return;
20236        }
20237      }
20238    } else {
20239      // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
20240      if (encoded_dt.IsValid() && rd.Is(rn)) {
20241        if (cond.Is(al)) {
20242          EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
20243                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20244                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20245                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20246          return;
20247        }
20248      }
20249    }
20250  }
20251  if (operand.IsRegister()) {
20252    DRegister rm = operand.GetRegister();
20253    USE(dt);
20254    if (IsUsingT32()) {
20255      // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
20256      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20257        EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20258                   rm.Encode(5, 0));
20259        AdvanceIT();
20260        return;
20261      }
20262    } else {
20263      // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
20264      if (cond.Is(al)) {
20265        EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20266                rm.Encode(5, 0));
20267        return;
20268      }
20269    }
20270  }
20271  Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
20272}
20273
20274void Assembler::vorn(Condition cond,
20275                     DataType dt,
20276                     QRegister rd,
20277                     QRegister rn,
20278                     const QOperand& operand) {
20279  CheckIT(cond);
20280  if (operand.IsImmediate()) {
20281    ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
20282    if (IsUsingT32()) {
20283      // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
20284      if (encoded_dt.IsValid() && rd.Is(rn)) {
20285        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20286          EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
20287                     rd.Encode(22, 12) |
20288                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20289                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20290                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20291          AdvanceIT();
20292          return;
20293        }
20294      }
20295    } else {
20296      // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
20297      if (encoded_dt.IsValid() && rd.Is(rn)) {
20298        if (cond.Is(al)) {
20299          EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
20300                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20301                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20302                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20303          return;
20304        }
20305      }
20306    }
20307  }
20308  if (operand.IsRegister()) {
20309    QRegister rm = operand.GetRegister();
20310    USE(dt);
20311    if (IsUsingT32()) {
20312      // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
20313      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20314        EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20315                   rm.Encode(5, 0));
20316        AdvanceIT();
20317        return;
20318      }
20319    } else {
20320      // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
20321      if (cond.Is(al)) {
20322        EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20323                rm.Encode(5, 0));
20324        return;
20325      }
20326    }
20327  }
20328  Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
20329}
20330
20331void Assembler::vorr(Condition cond,
20332                     DataType dt,
20333                     DRegister rd,
20334                     DRegister rn,
20335                     const DOperand& operand) {
20336  CheckIT(cond);
20337  if (operand.IsRegister()) {
20338    DRegister rm = operand.GetRegister();
20339    USE(dt);
20340    if (IsUsingT32()) {
20341      // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
20342      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20343        EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20344                   rm.Encode(5, 0));
20345        AdvanceIT();
20346        return;
20347      }
20348    } else {
20349      // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
20350      if (cond.Is(al)) {
20351        EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20352                rm.Encode(5, 0));
20353        return;
20354      }
20355    }
20356  }
20357  if (operand.IsImmediate()) {
20358    ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
20359    if (IsUsingT32()) {
20360      // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
20361      if (encoded_dt.IsValid() && rd.Is(rn)) {
20362        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20363          EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
20364                     rd.Encode(22, 12) |
20365                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20366                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20367                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20368          AdvanceIT();
20369          return;
20370        }
20371      }
20372    } else {
20373      // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
20374      if (encoded_dt.IsValid() && rd.Is(rn)) {
20375        if (cond.Is(al)) {
20376          EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
20377                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20378                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20379                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20380          return;
20381        }
20382      }
20383    }
20384  }
20385  Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
20386}
20387
20388void Assembler::vorr(Condition cond,
20389                     DataType dt,
20390                     QRegister rd,
20391                     QRegister rn,
20392                     const QOperand& operand) {
20393  CheckIT(cond);
20394  if (operand.IsRegister()) {
20395    QRegister rm = operand.GetRegister();
20396    USE(dt);
20397    if (IsUsingT32()) {
20398      // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
20399      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20400        EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20401                   rm.Encode(5, 0));
20402        AdvanceIT();
20403        return;
20404      }
20405    } else {
20406      // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
20407      if (cond.Is(al)) {
20408        EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20409                rm.Encode(5, 0));
20410        return;
20411      }
20412    }
20413  }
20414  if (operand.IsImmediate()) {
20415    ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
20416    if (IsUsingT32()) {
20417      // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
20418      if (encoded_dt.IsValid() && rd.Is(rn)) {
20419        if (cond.Is(al) || AllowStronglyDiscouraged()) {
20420          EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
20421                     rd.Encode(22, 12) |
20422                     (encoded_dt.GetEncodedImmediate() & 0xf) |
20423                     ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20424                     ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20425          AdvanceIT();
20426          return;
20427        }
20428      }
20429    } else {
20430      // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
20431      if (encoded_dt.IsValid() && rd.Is(rn)) {
20432        if (cond.Is(al)) {
20433          EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
20434                  rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20435                  ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20436                  ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20437          return;
20438        }
20439      }
20440    }
20441  }
20442  Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
20443}
20444
20445void Assembler::vpadal(Condition cond,
20446                       DataType dt,
20447                       DRegister rd,
20448                       DRegister rm) {
20449  CheckIT(cond);
20450  Dt_op_size_2 encoded_dt(dt);
20451  if (IsUsingT32()) {
20452    // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20453    if (encoded_dt.IsValid()) {
20454      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20455        EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20456                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20457                   rd.Encode(22, 12) | rm.Encode(5, 0));
20458        AdvanceIT();
20459        return;
20460      }
20461    }
20462  } else {
20463    // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
20464    if (encoded_dt.IsValid()) {
20465      if (cond.Is(al)) {
20466        EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20467                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20468                rd.Encode(22, 12) | rm.Encode(5, 0));
20469        return;
20470      }
20471    }
20472  }
20473  Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
20474}
20475
20476void Assembler::vpadal(Condition cond,
20477                       DataType dt,
20478                       QRegister rd,
20479                       QRegister rm) {
20480  CheckIT(cond);
20481  Dt_op_size_2 encoded_dt(dt);
20482  if (IsUsingT32()) {
20483    // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
20484    if (encoded_dt.IsValid()) {
20485      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20486        EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20487                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20488                   rd.Encode(22, 12) | rm.Encode(5, 0));
20489        AdvanceIT();
20490        return;
20491      }
20492    }
20493  } else {
20494    // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
20495    if (encoded_dt.IsValid()) {
20496      if (cond.Is(al)) {
20497        EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20498                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20499                rd.Encode(22, 12) | rm.Encode(5, 0));
20500        return;
20501      }
20502    }
20503  }
20504  Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
20505}
20506
20507void Assembler::vpadd(
20508    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20509  CheckIT(cond);
20510  Dt_size_4 encoded_dt(dt);
20511  if (IsUsingT32()) {
20512    // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20513    if (dt.Is(F32)) {
20514      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20515        EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20516                   rm.Encode(5, 0));
20517        AdvanceIT();
20518        return;
20519      }
20520    }
20521    // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20522    if (encoded_dt.IsValid()) {
20523      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20524        EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) |
20525                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20526        AdvanceIT();
20527        return;
20528      }
20529    }
20530  } else {
20531    // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
20532    if (dt.Is(F32)) {
20533      if (cond.Is(al)) {
20534        EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20535                rm.Encode(5, 0));
20536        return;
20537      }
20538    }
20539    // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20540    if (encoded_dt.IsValid()) {
20541      if (cond.Is(al)) {
20542        EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) |
20543                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20544        return;
20545      }
20546    }
20547  }
20548  Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm);
20549}
20550
20551void Assembler::vpaddl(Condition cond,
20552                       DataType dt,
20553                       DRegister rd,
20554                       DRegister rm) {
20555  CheckIT(cond);
20556  Dt_op_size_2 encoded_dt(dt);
20557  if (IsUsingT32()) {
20558    // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20559    if (encoded_dt.IsValid()) {
20560      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20561        EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20562                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20563                   rd.Encode(22, 12) | rm.Encode(5, 0));
20564        AdvanceIT();
20565        return;
20566      }
20567    }
20568  } else {
20569    // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
20570    if (encoded_dt.IsValid()) {
20571      if (cond.Is(al)) {
20572        EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20573                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20574                rd.Encode(22, 12) | rm.Encode(5, 0));
20575        return;
20576      }
20577    }
20578  }
20579  Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
20580}
20581
20582void Assembler::vpaddl(Condition cond,
20583                       DataType dt,
20584                       QRegister rd,
20585                       QRegister rm) {
20586  CheckIT(cond);
20587  Dt_op_size_2 encoded_dt(dt);
20588  if (IsUsingT32()) {
20589    // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
20590    if (encoded_dt.IsValid()) {
20591      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20592        EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20593                   ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20594                   rd.Encode(22, 12) | rm.Encode(5, 0));
20595        AdvanceIT();
20596        return;
20597      }
20598    }
20599  } else {
20600    // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
20601    if (encoded_dt.IsValid()) {
20602      if (cond.Is(al)) {
20603        EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20604                ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20605                rd.Encode(22, 12) | rm.Encode(5, 0));
20606        return;
20607      }
20608    }
20609  }
20610  Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
20611}
20612
20613void Assembler::vpmax(
20614    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20615  CheckIT(cond);
20616  Dt_U_size_1 encoded_dt(dt);
20617  if (IsUsingT32()) {
20618    // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20619    if (dt.Is(F32)) {
20620      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20621        EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20622                   rm.Encode(5, 0));
20623        AdvanceIT();
20624        return;
20625      }
20626    }
20627    // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20628    if (encoded_dt.IsValid()) {
20629      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20630        EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20631                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20632                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20633        AdvanceIT();
20634        return;
20635      }
20636    }
20637  } else {
20638    // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
20639    if (dt.Is(F32)) {
20640      if (cond.Is(al)) {
20641        EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20642                rm.Encode(5, 0));
20643        return;
20644      }
20645    }
20646    // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20647    if (encoded_dt.IsValid()) {
20648      if (cond.Is(al)) {
20649        EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20650                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20651                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20652        return;
20653      }
20654    }
20655  }
20656  Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm);
20657}
20658
20659void Assembler::vpmin(
20660    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20661  CheckIT(cond);
20662  Dt_U_size_1 encoded_dt(dt);
20663  if (IsUsingT32()) {
20664    // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20665    if (dt.Is(F32)) {
20666      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20667        EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20668                   rm.Encode(5, 0));
20669        AdvanceIT();
20670        return;
20671      }
20672    }
20673    // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20674    if (encoded_dt.IsValid()) {
20675      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20676        EmitT32_32(0xef000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20677                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20678                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20679        AdvanceIT();
20680        return;
20681      }
20682    }
20683  } else {
20684    // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
20685    if (dt.Is(F32)) {
20686      if (cond.Is(al)) {
20687        EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20688                rm.Encode(5, 0));
20689        return;
20690      }
20691    }
20692    // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20693    if (encoded_dt.IsValid()) {
20694      if (cond.Is(al)) {
20695        EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20696                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20697                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20698        return;
20699      }
20700    }
20701  }
20702  Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm);
20703}
20704
20705void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) {
20706  CheckIT(cond);
20707  USE(dt);
20708  if (IsUsingT32()) {
20709    // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1
20710    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
20711      const DRegister& dreg = dreglist.GetFirstDRegister();
20712      unsigned len = dreglist.GetLength() * 2;
20713      EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff));
20714      AdvanceIT();
20715      return;
20716    }
20717  } else {
20718    // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1
20719    if (cond.IsNotNever() &&
20720        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
20721      const DRegister& dreg = dreglist.GetFirstDRegister();
20722      unsigned len = dreglist.GetLength() * 2;
20723      EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
20724              (len & 0xff));
20725      return;
20726    }
20727  }
20728  Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist);
20729}
20730
20731void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) {
20732  CheckIT(cond);
20733  USE(dt);
20734  if (IsUsingT32()) {
20735    // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2
20736    const SRegister& sreg = sreglist.GetFirstSRegister();
20737    unsigned len = sreglist.GetLength();
20738    EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff));
20739    AdvanceIT();
20740    return;
20741  } else {
20742    // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2
20743    if (cond.IsNotNever()) {
20744      const SRegister& sreg = sreglist.GetFirstSRegister();
20745      unsigned len = sreglist.GetLength();
20746      EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
20747              (len & 0xff));
20748      return;
20749    }
20750  }
20751  Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist);
20752}
20753
20754void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) {
20755  CheckIT(cond);
20756  USE(dt);
20757  if (IsUsingT32()) {
20758    // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1
20759    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
20760      const DRegister& dreg = dreglist.GetFirstDRegister();
20761      unsigned len = dreglist.GetLength() * 2;
20762      EmitT32_32(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff));
20763      AdvanceIT();
20764      return;
20765    }
20766  } else {
20767    // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1
20768    if (cond.IsNotNever() &&
20769        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
20770      const DRegister& dreg = dreglist.GetFirstDRegister();
20771      unsigned len = dreglist.GetLength() * 2;
20772      EmitA32(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
20773              (len & 0xff));
20774      return;
20775    }
20776  }
20777  Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist);
20778}
20779
20780void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) {
20781  CheckIT(cond);
20782  USE(dt);
20783  if (IsUsingT32()) {
20784    // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2
20785    const SRegister& sreg = sreglist.GetFirstSRegister();
20786    unsigned len = sreglist.GetLength();
20787    EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff));
20788    AdvanceIT();
20789    return;
20790  } else {
20791    // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2
20792    if (cond.IsNotNever()) {
20793      const SRegister& sreg = sreglist.GetFirstSRegister();
20794      unsigned len = sreglist.GetLength();
20795      EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
20796              (len & 0xff));
20797      return;
20798    }
20799  }
20800  Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist);
20801}
20802
20803void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
20804  CheckIT(cond);
20805  Dt_size_5 encoded_dt(dt);
20806  if (IsUsingT32()) {
20807    // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20808    if (encoded_dt.IsValid()) {
20809      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20810        EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) |
20811                   rd.Encode(22, 12) | rm.Encode(5, 0));
20812        AdvanceIT();
20813        return;
20814      }
20815    }
20816  } else {
20817    // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
20818    if (encoded_dt.IsValid()) {
20819      if (cond.Is(al)) {
20820        EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) |
20821                rd.Encode(22, 12) | rm.Encode(5, 0));
20822        return;
20823      }
20824    }
20825  }
20826  Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
20827}
20828
20829void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
20830  CheckIT(cond);
20831  Dt_size_5 encoded_dt(dt);
20832  if (IsUsingT32()) {
20833    // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
20834    if (encoded_dt.IsValid()) {
20835      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20836        EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) |
20837                   rd.Encode(22, 12) | rm.Encode(5, 0));
20838        AdvanceIT();
20839        return;
20840      }
20841    }
20842  } else {
20843    // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
20844    if (encoded_dt.IsValid()) {
20845      if (cond.Is(al)) {
20846        EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) |
20847                rd.Encode(22, 12) | rm.Encode(5, 0));
20848        return;
20849      }
20850    }
20851  }
20852  Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
20853}
20854
20855void Assembler::vqadd(
20856    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20857  CheckIT(cond);
20858  Dt_U_size_3 encoded_dt(dt);
20859  if (IsUsingT32()) {
20860    // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20861    if (encoded_dt.IsValid()) {
20862      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20863        EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20864                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20865                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20866        AdvanceIT();
20867        return;
20868      }
20869    }
20870  } else {
20871    // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20872    if (encoded_dt.IsValid()) {
20873      if (cond.Is(al)) {
20874        EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20875                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20876                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20877        return;
20878      }
20879    }
20880  }
20881  Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
20882}
20883
20884void Assembler::vqadd(
20885    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20886  CheckIT(cond);
20887  Dt_U_size_3 encoded_dt(dt);
20888  if (IsUsingT32()) {
20889    // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
20890    if (encoded_dt.IsValid()) {
20891      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20892        EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20893                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20894                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20895        AdvanceIT();
20896        return;
20897      }
20898    }
20899  } else {
20900    // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
20901    if (encoded_dt.IsValid()) {
20902      if (cond.Is(al)) {
20903        EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20904                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20905                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20906        return;
20907      }
20908    }
20909  }
20910  Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
20911}
20912
20913void Assembler::vqdmlal(
20914    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
20915  CheckIT(cond);
20916  Dt_size_13 encoded_dt(dt);
20917  if (IsUsingT32()) {
20918    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
20919    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
20920      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20921        EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) |
20922                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20923        AdvanceIT();
20924        return;
20925      }
20926    }
20927  } else {
20928    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
20929    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
20930      if (cond.Is(al)) {
20931        EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) |
20932                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20933        return;
20934      }
20935    }
20936  }
20937  Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm);
20938}
20939
20940void Assembler::vqdmlal(Condition cond,
20941                        DataType dt,
20942                        QRegister rd,
20943                        DRegister rn,
20944                        DRegister dm,
20945                        unsigned index) {
20946  CheckIT(cond);
20947  Dt_size_13 encoded_dt(dt);
20948  if (IsUsingT32()) {
20949    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
20950    if (encoded_dt.IsValid() &&
20951        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
20952         (!dt.Is(S16) && (index <= 1))) &&
20953        (dt.Is(S16) || dt.Is(S32))) {
20954      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20955        uint32_t shift = 4;
20956        if (dt.Is(S16)) {
20957          shift = 3;
20958        }
20959        uint32_t mvm = dm.GetCode() | index << shift;
20960        EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) |
20961                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20962                   ((mvm & 0x10) << 1));
20963        AdvanceIT();
20964        return;
20965      }
20966    }
20967  } else {
20968    // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
20969    if (encoded_dt.IsValid() &&
20970        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
20971         (!dt.Is(S16) && (index <= 1))) &&
20972        (dt.Is(S16) || dt.Is(S32))) {
20973      if (cond.Is(al)) {
20974        uint32_t shift = 4;
20975        if (dt.Is(S16)) {
20976          shift = 3;
20977        }
20978        uint32_t mvm = dm.GetCode() | index << shift;
20979        EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) |
20980                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20981                ((mvm & 0x10) << 1));
20982        return;
20983      }
20984    }
20985  }
20986  Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index);
20987}
20988
20989void Assembler::vqdmlsl(
20990    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
20991  CheckIT(cond);
20992  Dt_size_13 encoded_dt(dt);
20993  if (IsUsingT32()) {
20994    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
20995    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
20996      if (cond.Is(al) || AllowStronglyDiscouraged()) {
20997        EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) |
20998                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20999        AdvanceIT();
21000        return;
21001      }
21002    }
21003  } else {
21004    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21005    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21006      if (cond.Is(al)) {
21007        EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) |
21008                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21009        return;
21010      }
21011    }
21012  }
21013  Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm);
21014}
21015
21016void Assembler::vqdmlsl(Condition cond,
21017                        DataType dt,
21018                        QRegister rd,
21019                        DRegister rn,
21020                        DRegister dm,
21021                        unsigned index) {
21022  CheckIT(cond);
21023  Dt_size_13 encoded_dt(dt);
21024  if (IsUsingT32()) {
21025    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
21026    if (encoded_dt.IsValid() &&
21027        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21028         (!dt.Is(S16) && (index <= 1))) &&
21029        (dt.Is(S16) || dt.Is(S32))) {
21030      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21031        uint32_t shift = 4;
21032        if (dt.Is(S16)) {
21033          shift = 3;
21034        }
21035        uint32_t mvm = dm.GetCode() | index << shift;
21036        EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) |
21037                   rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21038                   ((mvm & 0x10) << 1));
21039        AdvanceIT();
21040        return;
21041      }
21042    }
21043  } else {
21044    // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
21045    if (encoded_dt.IsValid() &&
21046        ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21047         (!dt.Is(S16) && (index <= 1))) &&
21048        (dt.Is(S16) || dt.Is(S32))) {
21049      if (cond.Is(al)) {
21050        uint32_t shift = 4;
21051        if (dt.Is(S16)) {
21052          shift = 3;
21053        }
21054        uint32_t mvm = dm.GetCode() | index << shift;
21055        EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) |
21056                rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21057                ((mvm & 0x10) << 1));
21058        return;
21059      }
21060    }
21061  }
21062  Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index);
21063}
21064
21065void Assembler::vqdmulh(
21066    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21067  CheckIT(cond);
21068  Dt_size_13 encoded_dt(dt);
21069  if (IsUsingT32()) {
21070    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21071    if (encoded_dt.IsValid()) {
21072      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21073        EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) |
21074                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21075        AdvanceIT();
21076        return;
21077      }
21078    }
21079  } else {
21080    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21081    if (encoded_dt.IsValid()) {
21082      if (cond.Is(al)) {
21083        EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) |
21084                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21085        return;
21086      }
21087    }
21088  }
21089  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21090}
21091
21092void Assembler::vqdmulh(
21093    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21094  CheckIT(cond);
21095  Dt_size_13 encoded_dt(dt);
21096  if (IsUsingT32()) {
21097    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21098    if (encoded_dt.IsValid()) {
21099      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21100        EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) |
21101                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21102        AdvanceIT();
21103        return;
21104      }
21105    }
21106  } else {
21107    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21108    if (encoded_dt.IsValid()) {
21109      if (cond.Is(al)) {
21110        EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) |
21111                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21112        return;
21113      }
21114    }
21115  }
21116  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21117}
21118
21119void Assembler::vqdmulh(
21120    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
21121  CheckIT(cond);
21122  Dt_size_13 encoded_dt(dt);
21123  if (IsUsingT32()) {
21124    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
21125    if (encoded_dt.IsValid() &&
21126        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21127         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21128          (rm.GetLane() <= 1))) &&
21129        (dt.Is(S16) || dt.Is(S32))) {
21130      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21131        EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) |
21132                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21133        AdvanceIT();
21134        return;
21135      }
21136    }
21137  } else {
21138    // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
21139    if (encoded_dt.IsValid() &&
21140        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21141         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21142          (rm.GetLane() <= 1))) &&
21143        (dt.Is(S16) || dt.Is(S32))) {
21144      if (cond.Is(al)) {
21145        EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) |
21146                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21147        return;
21148      }
21149    }
21150  }
21151  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21152}
21153
21154void Assembler::vqdmulh(
21155    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
21156  CheckIT(cond);
21157  Dt_size_13 encoded_dt(dt);
21158  if (IsUsingT32()) {
21159    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
21160    if (encoded_dt.IsValid() &&
21161        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21162         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21163          (rm.GetLane() <= 1))) &&
21164        (dt.Is(S16) || dt.Is(S32))) {
21165      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21166        EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) |
21167                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21168        AdvanceIT();
21169        return;
21170      }
21171    }
21172  } else {
21173    // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
21174    if (encoded_dt.IsValid() &&
21175        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21176         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21177          (rm.GetLane() <= 1))) &&
21178        (dt.Is(S16) || dt.Is(S32))) {
21179      if (cond.Is(al)) {
21180        EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) |
21181                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21182        return;
21183      }
21184    }
21185  }
21186  Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21187}
21188
21189void Assembler::vqdmull(
21190    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21191  CheckIT(cond);
21192  Dt_size_13 encoded_dt(dt);
21193  if (IsUsingT32()) {
21194    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21195    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21196      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21197        EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) |
21198                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21199        AdvanceIT();
21200        return;
21201      }
21202    }
21203  } else {
21204    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21205    if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21206      if (cond.Is(al)) {
21207        EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) |
21208                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21209        return;
21210      }
21211    }
21212  }
21213  Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
21214}
21215
21216void Assembler::vqdmull(
21217    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
21218  CheckIT(cond);
21219  Dt_size_13 encoded_dt(dt);
21220  if (IsUsingT32()) {
21221    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2
21222    if (encoded_dt.IsValid() &&
21223        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21224         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21225          (rm.GetLane() <= 1))) &&
21226        (dt.Is(S16) || dt.Is(S32))) {
21227      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21228        EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) |
21229                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21230        AdvanceIT();
21231        return;
21232      }
21233    }
21234  } else {
21235    // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2
21236    if (encoded_dt.IsValid() &&
21237        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21238         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21239          (rm.GetLane() <= 1))) &&
21240        (dt.Is(S16) || dt.Is(S32))) {
21241      if (cond.Is(al)) {
21242        EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) |
21243                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21244        return;
21245      }
21246    }
21247  }
21248  Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
21249}
21250
21251void Assembler::vqmovn(Condition cond,
21252                       DataType dt,
21253                       DRegister rd,
21254                       QRegister rm) {
21255  CheckIT(cond);
21256  Dt_op_size_3 encoded_dt(dt);
21257  if (IsUsingT32()) {
21258    // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
21259    if (encoded_dt.IsValid()) {
21260      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21261        EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21262                   ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21263                   rd.Encode(22, 12) | rm.Encode(5, 0));
21264        AdvanceIT();
21265        return;
21266      }
21267    }
21268  } else {
21269    // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
21270    if (encoded_dt.IsValid()) {
21271      if (cond.Is(al)) {
21272        EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21273                ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21274                rd.Encode(22, 12) | rm.Encode(5, 0));
21275        return;
21276      }
21277    }
21278  }
21279  Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm);
21280}
21281
21282void Assembler::vqmovun(Condition cond,
21283                        DataType dt,
21284                        DRegister rd,
21285                        QRegister rm) {
21286  CheckIT(cond);
21287  Dt_size_14 encoded_dt(dt);
21288  if (IsUsingT32()) {
21289    // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
21290    if (encoded_dt.IsValid()) {
21291      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21292        EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) |
21293                   rd.Encode(22, 12) | rm.Encode(5, 0));
21294        AdvanceIT();
21295        return;
21296      }
21297    }
21298  } else {
21299    // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
21300    if (encoded_dt.IsValid()) {
21301      if (cond.Is(al)) {
21302        EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) |
21303                rd.Encode(22, 12) | rm.Encode(5, 0));
21304        return;
21305      }
21306    }
21307  }
21308  Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm);
21309}
21310
21311void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
21312  CheckIT(cond);
21313  Dt_size_5 encoded_dt(dt);
21314  if (IsUsingT32()) {
21315    // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
21316    if (encoded_dt.IsValid()) {
21317      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21318        EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) |
21319                   rd.Encode(22, 12) | rm.Encode(5, 0));
21320        AdvanceIT();
21321        return;
21322      }
21323    }
21324  } else {
21325    // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
21326    if (encoded_dt.IsValid()) {
21327      if (cond.Is(al)) {
21328        EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) |
21329                rd.Encode(22, 12) | rm.Encode(5, 0));
21330        return;
21331      }
21332    }
21333  }
21334  Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
21335}
21336
21337void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
21338  CheckIT(cond);
21339  Dt_size_5 encoded_dt(dt);
21340  if (IsUsingT32()) {
21341    // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
21342    if (encoded_dt.IsValid()) {
21343      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21344        EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) |
21345                   rd.Encode(22, 12) | rm.Encode(5, 0));
21346        AdvanceIT();
21347        return;
21348      }
21349    }
21350  } else {
21351    // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
21352    if (encoded_dt.IsValid()) {
21353      if (cond.Is(al)) {
21354        EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) |
21355                rd.Encode(22, 12) | rm.Encode(5, 0));
21356        return;
21357      }
21358    }
21359  }
21360  Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
21361}
21362
21363void Assembler::vqrdmulh(
21364    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21365  CheckIT(cond);
21366  Dt_size_13 encoded_dt(dt);
21367  if (IsUsingT32()) {
21368    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21369    if (encoded_dt.IsValid()) {
21370      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21371        EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) |
21372                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21373        AdvanceIT();
21374        return;
21375      }
21376    }
21377  } else {
21378    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21379    if (encoded_dt.IsValid()) {
21380      if (cond.Is(al)) {
21381        EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) |
21382                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21383        return;
21384      }
21385    }
21386  }
21387  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21388}
21389
21390void Assembler::vqrdmulh(
21391    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21392  CheckIT(cond);
21393  Dt_size_13 encoded_dt(dt);
21394  if (IsUsingT32()) {
21395    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21396    if (encoded_dt.IsValid()) {
21397      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21398        EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) |
21399                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21400        AdvanceIT();
21401        return;
21402      }
21403    }
21404  } else {
21405    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21406    if (encoded_dt.IsValid()) {
21407      if (cond.Is(al)) {
21408        EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) |
21409                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21410        return;
21411      }
21412    }
21413  }
21414  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21415}
21416
21417void Assembler::vqrdmulh(
21418    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
21419  CheckIT(cond);
21420  Dt_size_13 encoded_dt(dt);
21421  if (IsUsingT32()) {
21422    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
21423    if (encoded_dt.IsValid() &&
21424        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21425         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21426          (rm.GetLane() <= 1))) &&
21427        (dt.Is(S16) || dt.Is(S32))) {
21428      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21429        EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) |
21430                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21431        AdvanceIT();
21432        return;
21433      }
21434    }
21435  } else {
21436    // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
21437    if (encoded_dt.IsValid() &&
21438        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21439         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21440          (rm.GetLane() <= 1))) &&
21441        (dt.Is(S16) || dt.Is(S32))) {
21442      if (cond.Is(al)) {
21443        EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) |
21444                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21445        return;
21446      }
21447    }
21448  }
21449  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21450}
21451
21452void Assembler::vqrdmulh(
21453    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
21454  CheckIT(cond);
21455  Dt_size_13 encoded_dt(dt);
21456  if (IsUsingT32()) {
21457    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
21458    if (encoded_dt.IsValid() &&
21459        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21460         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21461          (rm.GetLane() <= 1))) &&
21462        (dt.Is(S16) || dt.Is(S32))) {
21463      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21464        EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) |
21465                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21466        AdvanceIT();
21467        return;
21468      }
21469    }
21470  } else {
21471    // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
21472    if (encoded_dt.IsValid() &&
21473        (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21474         ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21475          (rm.GetLane() <= 1))) &&
21476        (dt.Is(S16) || dt.Is(S32))) {
21477      if (cond.Is(al)) {
21478        EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) |
21479                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21480        return;
21481      }
21482    }
21483  }
21484  Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21485}
21486
21487void Assembler::vqrshl(
21488    Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
21489  CheckIT(cond);
21490  Dt_U_size_3 encoded_dt(dt);
21491  if (IsUsingT32()) {
21492    // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
21493    if (encoded_dt.IsValid()) {
21494      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21495        EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21496                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21497                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21498        AdvanceIT();
21499        return;
21500      }
21501    }
21502  } else {
21503    // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
21504    if (encoded_dt.IsValid()) {
21505      if (cond.Is(al)) {
21506        EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21507                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21508                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21509        return;
21510      }
21511    }
21512  }
21513  Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
21514}
21515
21516void Assembler::vqrshl(
21517    Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
21518  CheckIT(cond);
21519  Dt_U_size_3 encoded_dt(dt);
21520  if (IsUsingT32()) {
21521    // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
21522    if (encoded_dt.IsValid()) {
21523      if (cond.Is(al) || AllowStronglyDiscouraged()) {
21524        EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21525                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21526                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21527        AdvanceIT();
21528        return;
21529      }
21530    }
21531  } else {
21532    // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
21533    if (encoded_dt.IsValid()) {
21534      if (cond.Is(al)) {
21535        EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21536                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21537                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21538        return;
21539      }
21540    }
21541  }
21542  Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
21543}
21544
21545void Assembler::vqrshrn(Condition cond,
21546                        DataType dt,
21547                        DRegister rd,
21548                        QRegister rm,
21549                        const QOperand& operand) {
21550  CheckIT(cond);
21551  if (operand.IsImmediate()) {
21552    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
21553      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
21554      Dt_op_size_3 encoded_dt(dt);
21555      Dt_imm6_1 encoded_dt_2(dt);
21556      if (IsUsingT32()) {
21557        // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
21558        if (encoded_dt.IsValid() && (imm == 0)) {
21559          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21560            EmitT32_32(0xffb20280U |
21561                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21562                       ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21563                       rd.Encode(22, 12) | rm.Encode(5, 0));
21564            AdvanceIT();
21565            return;
21566          }
21567        }
21568        // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
21569        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
21570          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21571            uint32_t imm6 = dt.GetSize() / 2 - imm;
21572            EmitT32_32(0xef800950U |
21573                       (encoded_dt_2.GetTypeEncodingValue() << 28) |
21574                       ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
21575                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21576            AdvanceIT();
21577            return;
21578          }
21579        }
21580      } else {
21581        // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
21582        if (encoded_dt.IsValid() && (imm == 0)) {
21583          if (cond.Is(al)) {
21584            EmitA32(0xf3b20280U |
21585                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21586                    ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21587                    rd.Encode(22, 12) | rm.Encode(5, 0));
21588            return;
21589          }
21590        }
21591        // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
21592        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
21593          if (cond.Is(al)) {
21594            uint32_t imm6 = dt.GetSize() / 2 - imm;
21595            EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
21596                    ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
21597                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21598            return;
21599          }
21600        }
21601      }
21602    }
21603  }
21604  Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand);
21605}
21606
21607void Assembler::vqrshrun(Condition cond,
21608                         DataType dt,
21609                         DRegister rd,
21610                         QRegister rm,
21611                         const QOperand& operand) {
21612  CheckIT(cond);
21613  if (operand.IsImmediate()) {
21614    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
21615      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
21616      Dt_imm6_2 encoded_dt(dt);
21617      Dt_size_14 encoded_dt_2(dt);
21618      if (IsUsingT32()) {
21619        // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
21620        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
21621          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21622            uint32_t imm6 = dt.GetSize() / 2 - imm;
21623            EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) |
21624                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21625                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21626            AdvanceIT();
21627            return;
21628          }
21629        }
21630        // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
21631        if (encoded_dt_2.IsValid() && (imm == 0)) {
21632          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21633            EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
21634                       rd.Encode(22, 12) | rm.Encode(5, 0));
21635            AdvanceIT();
21636            return;
21637          }
21638        }
21639      } else {
21640        // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
21641        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
21642          if (cond.Is(al)) {
21643            uint32_t imm6 = dt.GetSize() / 2 - imm;
21644            EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) |
21645                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21646                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21647            return;
21648          }
21649        }
21650        // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
21651        if (encoded_dt_2.IsValid() && (imm == 0)) {
21652          if (cond.Is(al)) {
21653            EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
21654                    rd.Encode(22, 12) | rm.Encode(5, 0));
21655            return;
21656          }
21657        }
21658      }
21659    }
21660  }
21661  Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand);
21662}
21663
21664void Assembler::vqshl(Condition cond,
21665                      DataType dt,
21666                      DRegister rd,
21667                      DRegister rm,
21668                      const DOperand& operand) {
21669  CheckIT(cond);
21670  if (operand.IsRegister()) {
21671    DRegister rn = operand.GetRegister();
21672    Dt_U_size_3 encoded_dt(dt);
21673    if (IsUsingT32()) {
21674      // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
21675      if (encoded_dt.IsValid()) {
21676        if (cond.Is(al) || AllowStronglyDiscouraged()) {
21677          EmitT32_32(0xef000410U |
21678                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21679                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21680                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21681          AdvanceIT();
21682          return;
21683        }
21684      }
21685    } else {
21686      // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
21687      if (encoded_dt.IsValid()) {
21688        if (cond.Is(al)) {
21689          EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21690                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21691                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21692          return;
21693        }
21694      }
21695    }
21696  }
21697  if (operand.IsImmediate()) {
21698    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
21699      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
21700      Dt_L_imm6_1 encoded_dt(dt);
21701      if (IsUsingT32()) {
21702        // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
21703        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
21704          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21705            uint32_t imm6 = imm;
21706            EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) |
21707                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21708                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
21709                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21710            AdvanceIT();
21711            return;
21712          }
21713        }
21714      } else {
21715        // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
21716        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
21717          if (cond.Is(al)) {
21718            uint32_t imm6 = imm;
21719            EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) |
21720                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21721                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
21722                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21723            return;
21724          }
21725        }
21726      }
21727    }
21728  }
21729  Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
21730}
21731
21732void Assembler::vqshl(Condition cond,
21733                      DataType dt,
21734                      QRegister rd,
21735                      QRegister rm,
21736                      const QOperand& operand) {
21737  CheckIT(cond);
21738  if (operand.IsRegister()) {
21739    QRegister rn = operand.GetRegister();
21740    Dt_U_size_3 encoded_dt(dt);
21741    if (IsUsingT32()) {
21742      // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
21743      if (encoded_dt.IsValid()) {
21744        if (cond.Is(al) || AllowStronglyDiscouraged()) {
21745          EmitT32_32(0xef000450U |
21746                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21747                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21748                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21749          AdvanceIT();
21750          return;
21751        }
21752      }
21753    } else {
21754      // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
21755      if (encoded_dt.IsValid()) {
21756        if (cond.Is(al)) {
21757          EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21758                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21759                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21760          return;
21761        }
21762      }
21763    }
21764  }
21765  if (operand.IsImmediate()) {
21766    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
21767      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
21768      Dt_L_imm6_1 encoded_dt(dt);
21769      if (IsUsingT32()) {
21770        // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
21771        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
21772          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21773            uint32_t imm6 = imm;
21774            EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) |
21775                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21776                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
21777                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21778            AdvanceIT();
21779            return;
21780          }
21781        }
21782      } else {
21783        // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
21784        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
21785          if (cond.Is(al)) {
21786            uint32_t imm6 = imm;
21787            EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) |
21788                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21789                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
21790                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21791            return;
21792          }
21793        }
21794      }
21795    }
21796  }
21797  Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
21798}
21799
21800void Assembler::vqshlu(Condition cond,
21801                       DataType dt,
21802                       DRegister rd,
21803                       DRegister rm,
21804                       const DOperand& operand) {
21805  CheckIT(cond);
21806  if (operand.IsImmediate()) {
21807    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
21808      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
21809      Dt_L_imm6_2 encoded_dt(dt);
21810      if (IsUsingT32()) {
21811        // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
21812        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
21813          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21814            uint32_t imm6 = imm;
21815            EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) |
21816                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21817                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
21818                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21819            AdvanceIT();
21820            return;
21821          }
21822        }
21823      } else {
21824        // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
21825        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
21826          if (cond.Is(al)) {
21827            uint32_t imm6 = imm;
21828            EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) |
21829                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21830                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
21831                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21832            return;
21833          }
21834        }
21835      }
21836    }
21837  }
21838  Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
21839}
21840
21841void Assembler::vqshlu(Condition cond,
21842                       DataType dt,
21843                       QRegister rd,
21844                       QRegister rm,
21845                       const QOperand& operand) {
21846  CheckIT(cond);
21847  if (operand.IsImmediate()) {
21848    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
21849      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
21850      Dt_L_imm6_2 encoded_dt(dt);
21851      if (IsUsingT32()) {
21852        // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
21853        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
21854          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21855            uint32_t imm6 = imm;
21856            EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) |
21857                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21858                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
21859                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21860            AdvanceIT();
21861            return;
21862          }
21863        }
21864      } else {
21865        // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
21866        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
21867          if (cond.Is(al)) {
21868            uint32_t imm6 = imm;
21869            EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) |
21870                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21871                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
21872                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21873            return;
21874          }
21875        }
21876      }
21877    }
21878  }
21879  Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
21880}
21881
21882void Assembler::vqshrn(Condition cond,
21883                       DataType dt,
21884                       DRegister rd,
21885                       QRegister rm,
21886                       const QOperand& operand) {
21887  CheckIT(cond);
21888  if (operand.IsImmediate()) {
21889    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
21890      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
21891      Dt_op_size_3 encoded_dt(dt);
21892      Dt_imm6_1 encoded_dt_2(dt);
21893      if (IsUsingT32()) {
21894        // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
21895        if (encoded_dt.IsValid() && (imm == 0)) {
21896          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21897            EmitT32_32(0xffb20280U |
21898                       ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21899                       ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21900                       rd.Encode(22, 12) | rm.Encode(5, 0));
21901            AdvanceIT();
21902            return;
21903          }
21904        }
21905        // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
21906        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
21907          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21908            uint32_t imm6 = dt.GetSize() / 2 - imm;
21909            EmitT32_32(0xef800910U |
21910                       (encoded_dt_2.GetTypeEncodingValue() << 28) |
21911                       ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
21912                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21913            AdvanceIT();
21914            return;
21915          }
21916        }
21917      } else {
21918        // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
21919        if (encoded_dt.IsValid() && (imm == 0)) {
21920          if (cond.Is(al)) {
21921            EmitA32(0xf3b20280U |
21922                    ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21923                    ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21924                    rd.Encode(22, 12) | rm.Encode(5, 0));
21925            return;
21926          }
21927        }
21928        // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
21929        if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
21930          if (cond.Is(al)) {
21931            uint32_t imm6 = dt.GetSize() / 2 - imm;
21932            EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
21933                    ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
21934                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21935            return;
21936          }
21937        }
21938      }
21939    }
21940  }
21941  Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand);
21942}
21943
21944void Assembler::vqshrun(Condition cond,
21945                        DataType dt,
21946                        DRegister rd,
21947                        QRegister rm,
21948                        const QOperand& operand) {
21949  CheckIT(cond);
21950  if (operand.IsImmediate()) {
21951    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
21952      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
21953      Dt_imm6_2 encoded_dt(dt);
21954      Dt_size_14 encoded_dt_2(dt);
21955      if (IsUsingT32()) {
21956        // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
21957        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
21958          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21959            uint32_t imm6 = dt.GetSize() / 2 - imm;
21960            EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) |
21961                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21962                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21963            AdvanceIT();
21964            return;
21965          }
21966        }
21967        // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
21968        if (encoded_dt_2.IsValid() && (imm == 0)) {
21969          if (cond.Is(al) || AllowStronglyDiscouraged()) {
21970            EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
21971                       rd.Encode(22, 12) | rm.Encode(5, 0));
21972            AdvanceIT();
21973            return;
21974          }
21975        }
21976      } else {
21977        // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
21978        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
21979          if (cond.Is(al)) {
21980            uint32_t imm6 = dt.GetSize() / 2 - imm;
21981            EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) |
21982                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21983                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
21984            return;
21985          }
21986        }
21987        // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
21988        if (encoded_dt_2.IsValid() && (imm == 0)) {
21989          if (cond.Is(al)) {
21990            EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
21991                    rd.Encode(22, 12) | rm.Encode(5, 0));
21992            return;
21993          }
21994        }
21995      }
21996    }
21997  }
21998  Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand);
21999}
22000
22001void Assembler::vqsub(
22002    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22003  CheckIT(cond);
22004  Dt_U_size_3 encoded_dt(dt);
22005  if (IsUsingT32()) {
22006    // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22007    if (encoded_dt.IsValid()) {
22008      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22009        EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22010                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22011                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22012        AdvanceIT();
22013        return;
22014      }
22015    }
22016  } else {
22017    // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22018    if (encoded_dt.IsValid()) {
22019      if (cond.Is(al)) {
22020        EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22021                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22022                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22023        return;
22024      }
22025    }
22026  }
22027  Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
22028}
22029
22030void Assembler::vqsub(
22031    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22032  CheckIT(cond);
22033  Dt_U_size_3 encoded_dt(dt);
22034  if (IsUsingT32()) {
22035    // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22036    if (encoded_dt.IsValid()) {
22037      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22038        EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22039                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22040                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22041        AdvanceIT();
22042        return;
22043      }
22044    }
22045  } else {
22046    // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22047    if (encoded_dt.IsValid()) {
22048      if (cond.Is(al)) {
22049        EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22050                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22051                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22052        return;
22053      }
22054    }
22055  }
22056  Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
22057}
22058
22059void Assembler::vraddhn(
22060    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
22061  CheckIT(cond);
22062  Dt_size_3 encoded_dt(dt);
22063  if (IsUsingT32()) {
22064    // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
22065    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
22066      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22067        EmitT32_32(0xff800400U | (encoded_dt.GetEncodingValue() << 20) |
22068                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22069        AdvanceIT();
22070        return;
22071      }
22072    }
22073  } else {
22074    // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
22075    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
22076      if (cond.Is(al)) {
22077        EmitA32(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) |
22078                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22079        return;
22080      }
22081    }
22082  }
22083  Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm);
22084}
22085
22086void Assembler::vrecpe(Condition cond,
22087                       DataType dt,
22088                       DRegister rd,
22089                       DRegister rm) {
22090  CheckIT(cond);
22091  Dt_F_size_4 encoded_dt(dt);
22092  if (IsUsingT32()) {
22093    // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22094    if (encoded_dt.IsValid()) {
22095      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22096        EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22097                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22098                   rd.Encode(22, 12) | rm.Encode(5, 0));
22099        AdvanceIT();
22100        return;
22101      }
22102    }
22103  } else {
22104    // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22105    if (encoded_dt.IsValid()) {
22106      if (cond.Is(al)) {
22107        EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22108                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22109                rd.Encode(22, 12) | rm.Encode(5, 0));
22110        return;
22111      }
22112    }
22113  }
22114  Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
22115}
22116
22117void Assembler::vrecpe(Condition cond,
22118                       DataType dt,
22119                       QRegister rd,
22120                       QRegister rm) {
22121  CheckIT(cond);
22122  Dt_F_size_4 encoded_dt(dt);
22123  if (IsUsingT32()) {
22124    // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22125    if (encoded_dt.IsValid()) {
22126      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22127        EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22128                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22129                   rd.Encode(22, 12) | rm.Encode(5, 0));
22130        AdvanceIT();
22131        return;
22132      }
22133    }
22134  } else {
22135    // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22136    if (encoded_dt.IsValid()) {
22137      if (cond.Is(al)) {
22138        EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22139                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22140                rd.Encode(22, 12) | rm.Encode(5, 0));
22141        return;
22142      }
22143    }
22144  }
22145  Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
22146}
22147
22148void Assembler::vrecps(
22149    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22150  CheckIT(cond);
22151  if (IsUsingT32()) {
22152    // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
22153    if (dt.Is(F32)) {
22154      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22155        EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22156                   rm.Encode(5, 0));
22157        AdvanceIT();
22158        return;
22159      }
22160    }
22161  } else {
22162    // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
22163    if (dt.Is(F32)) {
22164      if (cond.Is(al)) {
22165        EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22166                rm.Encode(5, 0));
22167        return;
22168      }
22169    }
22170  }
22171  Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
22172}
22173
22174void Assembler::vrecps(
22175    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22176  CheckIT(cond);
22177  if (IsUsingT32()) {
22178    // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
22179    if (dt.Is(F32)) {
22180      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22181        EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22182                   rm.Encode(5, 0));
22183        AdvanceIT();
22184        return;
22185      }
22186    }
22187  } else {
22188    // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
22189    if (dt.Is(F32)) {
22190      if (cond.Is(al)) {
22191        EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22192                rm.Encode(5, 0));
22193        return;
22194      }
22195    }
22196  }
22197  Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
22198}
22199
22200void Assembler::vrev16(Condition cond,
22201                       DataType dt,
22202                       DRegister rd,
22203                       DRegister rm) {
22204  CheckIT(cond);
22205  Dt_size_1 encoded_dt(dt);
22206  if (IsUsingT32()) {
22207    // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22208    if (encoded_dt.IsValid()) {
22209      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22210        EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) |
22211                   rd.Encode(22, 12) | rm.Encode(5, 0));
22212        AdvanceIT();
22213        return;
22214      }
22215    }
22216  } else {
22217    // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22218    if (encoded_dt.IsValid()) {
22219      if (cond.Is(al)) {
22220        EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) |
22221                rd.Encode(22, 12) | rm.Encode(5, 0));
22222        return;
22223      }
22224    }
22225  }
22226  Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
22227}
22228
22229void Assembler::vrev16(Condition cond,
22230                       DataType dt,
22231                       QRegister rd,
22232                       QRegister rm) {
22233  CheckIT(cond);
22234  Dt_size_1 encoded_dt(dt);
22235  if (IsUsingT32()) {
22236    // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22237    if (encoded_dt.IsValid()) {
22238      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22239        EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) |
22240                   rd.Encode(22, 12) | rm.Encode(5, 0));
22241        AdvanceIT();
22242        return;
22243      }
22244    }
22245  } else {
22246    // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22247    if (encoded_dt.IsValid()) {
22248      if (cond.Is(al)) {
22249        EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) |
22250                rd.Encode(22, 12) | rm.Encode(5, 0));
22251        return;
22252      }
22253    }
22254  }
22255  Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
22256}
22257
22258void Assembler::vrev32(Condition cond,
22259                       DataType dt,
22260                       DRegister rd,
22261                       DRegister rm) {
22262  CheckIT(cond);
22263  Dt_size_15 encoded_dt(dt);
22264  if (IsUsingT32()) {
22265    // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22266    if (encoded_dt.IsValid()) {
22267      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22268        EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) |
22269                   rd.Encode(22, 12) | rm.Encode(5, 0));
22270        AdvanceIT();
22271        return;
22272      }
22273    }
22274  } else {
22275    // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22276    if (encoded_dt.IsValid()) {
22277      if (cond.Is(al)) {
22278        EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) |
22279                rd.Encode(22, 12) | rm.Encode(5, 0));
22280        return;
22281      }
22282    }
22283  }
22284  Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
22285}
22286
22287void Assembler::vrev32(Condition cond,
22288                       DataType dt,
22289                       QRegister rd,
22290                       QRegister rm) {
22291  CheckIT(cond);
22292  Dt_size_15 encoded_dt(dt);
22293  if (IsUsingT32()) {
22294    // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22295    if (encoded_dt.IsValid()) {
22296      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22297        EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) |
22298                   rd.Encode(22, 12) | rm.Encode(5, 0));
22299        AdvanceIT();
22300        return;
22301      }
22302    }
22303  } else {
22304    // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22305    if (encoded_dt.IsValid()) {
22306      if (cond.Is(al)) {
22307        EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) |
22308                rd.Encode(22, 12) | rm.Encode(5, 0));
22309        return;
22310      }
22311    }
22312  }
22313  Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
22314}
22315
22316void Assembler::vrev64(Condition cond,
22317                       DataType dt,
22318                       DRegister rd,
22319                       DRegister rm) {
22320  CheckIT(cond);
22321  Dt_size_7 encoded_dt(dt);
22322  if (IsUsingT32()) {
22323    // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22324    if (encoded_dt.IsValid()) {
22325      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22326        EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) |
22327                   rd.Encode(22, 12) | rm.Encode(5, 0));
22328        AdvanceIT();
22329        return;
22330      }
22331    }
22332  } else {
22333    // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22334    if (encoded_dt.IsValid()) {
22335      if (cond.Is(al)) {
22336        EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) |
22337                rd.Encode(22, 12) | rm.Encode(5, 0));
22338        return;
22339      }
22340    }
22341  }
22342  Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
22343}
22344
22345void Assembler::vrev64(Condition cond,
22346                       DataType dt,
22347                       QRegister rd,
22348                       QRegister rm) {
22349  CheckIT(cond);
22350  Dt_size_7 encoded_dt(dt);
22351  if (IsUsingT32()) {
22352    // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22353    if (encoded_dt.IsValid()) {
22354      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22355        EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) |
22356                   rd.Encode(22, 12) | rm.Encode(5, 0));
22357        AdvanceIT();
22358        return;
22359      }
22360    }
22361  } else {
22362    // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22363    if (encoded_dt.IsValid()) {
22364      if (cond.Is(al)) {
22365        EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) |
22366                rd.Encode(22, 12) | rm.Encode(5, 0));
22367        return;
22368      }
22369    }
22370  }
22371  Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
22372}
22373
22374void Assembler::vrhadd(
22375    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22376  CheckIT(cond);
22377  Dt_U_size_1 encoded_dt(dt);
22378  if (IsUsingT32()) {
22379    // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22380    if (encoded_dt.IsValid()) {
22381      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22382        EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22383                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22384                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22385        AdvanceIT();
22386        return;
22387      }
22388    }
22389  } else {
22390    // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22391    if (encoded_dt.IsValid()) {
22392      if (cond.Is(al)) {
22393        EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22394                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22395                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22396        return;
22397      }
22398    }
22399  }
22400  Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
22401}
22402
22403void Assembler::vrhadd(
22404    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22405  CheckIT(cond);
22406  Dt_U_size_1 encoded_dt(dt);
22407  if (IsUsingT32()) {
22408    // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22409    if (encoded_dt.IsValid()) {
22410      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22411        EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22412                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22413                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22414        AdvanceIT();
22415        return;
22416      }
22417    }
22418  } else {
22419    // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22420    if (encoded_dt.IsValid()) {
22421      if (cond.Is(al)) {
22422        EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22423                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22424                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22425        return;
22426      }
22427    }
22428  }
22429  Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
22430}
22431
22432void Assembler::vrinta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22433  CheckIT(al);
22434  if (IsUsingT32()) {
22435    // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; T1
22436    if (dt1.Is(F32) && dt2.Is(F32)) {
22437      EmitT32_32(0xffba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
22438      AdvanceIT();
22439      return;
22440    }
22441    // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; T1
22442    if (dt1.Is(F64) && dt2.Is(F64)) {
22443      EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22444      AdvanceIT();
22445      return;
22446    }
22447  } else {
22448    // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; A1
22449    if (dt1.Is(F32) && dt2.Is(F32)) {
22450      EmitA32(0xf3ba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
22451      return;
22452    }
22453    // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; A1
22454    if (dt1.Is(F64) && dt2.Is(F64)) {
22455      EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22456      return;
22457    }
22458  }
22459  Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22460}
22461
22462void Assembler::vrinta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
22463  CheckIT(al);
22464  if (IsUsingT32()) {
22465    // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; T1
22466    if (dt1.Is(F32) && dt2.Is(F32)) {
22467      EmitT32_32(0xffba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
22468      AdvanceIT();
22469      return;
22470    }
22471  } else {
22472    // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; A1
22473    if (dt1.Is(F32) && dt2.Is(F32)) {
22474      EmitA32(0xf3ba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
22475      return;
22476    }
22477  }
22478  Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22479}
22480
22481void Assembler::vrinta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
22482  CheckIT(al);
22483  if (IsUsingT32()) {
22484    // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; T1
22485    if (dt1.Is(F32) && dt2.Is(F32)) {
22486      EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22487      AdvanceIT();
22488      return;
22489    }
22490  } else {
22491    // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; A1
22492    if (dt1.Is(F32) && dt2.Is(F32)) {
22493      EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22494      return;
22495    }
22496  }
22497  Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22498}
22499
22500void Assembler::vrintm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22501  CheckIT(al);
22502  if (IsUsingT32()) {
22503    // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; T1
22504    if (dt1.Is(F32) && dt2.Is(F32)) {
22505      EmitT32_32(0xffba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
22506      AdvanceIT();
22507      return;
22508    }
22509    // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; T1
22510    if (dt1.Is(F64) && dt2.Is(F64)) {
22511      EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22512      AdvanceIT();
22513      return;
22514    }
22515  } else {
22516    // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; A1
22517    if (dt1.Is(F32) && dt2.Is(F32)) {
22518      EmitA32(0xf3ba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
22519      return;
22520    }
22521    // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; A1
22522    if (dt1.Is(F64) && dt2.Is(F64)) {
22523      EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22524      return;
22525    }
22526  }
22527  Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
22528}
22529
22530void Assembler::vrintm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
22531  CheckIT(al);
22532  if (IsUsingT32()) {
22533    // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; T1
22534    if (dt1.Is(F32) && dt2.Is(F32)) {
22535      EmitT32_32(0xffba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22536      AdvanceIT();
22537      return;
22538    }
22539  } else {
22540    // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; A1
22541    if (dt1.Is(F32) && dt2.Is(F32)) {
22542      EmitA32(0xf3ba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22543      return;
22544    }
22545  }
22546  Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
22547}
22548
22549void Assembler::vrintm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
22550  CheckIT(al);
22551  if (IsUsingT32()) {
22552    // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; T1
22553    if (dt1.Is(F32) && dt2.Is(F32)) {
22554      EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22555      AdvanceIT();
22556      return;
22557    }
22558  } else {
22559    // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; A1
22560    if (dt1.Is(F32) && dt2.Is(F32)) {
22561      EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22562      return;
22563    }
22564  }
22565  Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
22566}
22567
22568void Assembler::vrintn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22569  CheckIT(al);
22570  if (IsUsingT32()) {
22571    // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; T1
22572    if (dt1.Is(F32) && dt2.Is(F32)) {
22573      EmitT32_32(0xffba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
22574      AdvanceIT();
22575      return;
22576    }
22577    // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; T1
22578    if (dt1.Is(F64) && dt2.Is(F64)) {
22579      EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22580      AdvanceIT();
22581      return;
22582    }
22583  } else {
22584    // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; A1
22585    if (dt1.Is(F32) && dt2.Is(F32)) {
22586      EmitA32(0xf3ba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
22587      return;
22588    }
22589    // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; A1
22590    if (dt1.Is(F64) && dt2.Is(F64)) {
22591      EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22592      return;
22593    }
22594  }
22595  Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
22596}
22597
22598void Assembler::vrintn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
22599  CheckIT(al);
22600  if (IsUsingT32()) {
22601    // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; T1
22602    if (dt1.Is(F32) && dt2.Is(F32)) {
22603      EmitT32_32(0xffba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
22604      AdvanceIT();
22605      return;
22606    }
22607  } else {
22608    // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; A1
22609    if (dt1.Is(F32) && dt2.Is(F32)) {
22610      EmitA32(0xf3ba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
22611      return;
22612    }
22613  }
22614  Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
22615}
22616
22617void Assembler::vrintn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
22618  CheckIT(al);
22619  if (IsUsingT32()) {
22620    // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; T1
22621    if (dt1.Is(F32) && dt2.Is(F32)) {
22622      EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22623      AdvanceIT();
22624      return;
22625    }
22626  } else {
22627    // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; A1
22628    if (dt1.Is(F32) && dt2.Is(F32)) {
22629      EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22630      return;
22631    }
22632  }
22633  Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
22634}
22635
22636void Assembler::vrintp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22637  CheckIT(al);
22638  if (IsUsingT32()) {
22639    // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; T1
22640    if (dt1.Is(F32) && dt2.Is(F32)) {
22641      EmitT32_32(0xffba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
22642      AdvanceIT();
22643      return;
22644    }
22645    // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; T1
22646    if (dt1.Is(F64) && dt2.Is(F64)) {
22647      EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22648      AdvanceIT();
22649      return;
22650    }
22651  } else {
22652    // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; A1
22653    if (dt1.Is(F32) && dt2.Is(F32)) {
22654      EmitA32(0xf3ba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
22655      return;
22656    }
22657    // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; A1
22658    if (dt1.Is(F64) && dt2.Is(F64)) {
22659      EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22660      return;
22661    }
22662  }
22663  Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
22664}
22665
22666void Assembler::vrintp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
22667  CheckIT(al);
22668  if (IsUsingT32()) {
22669    // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; T1
22670    if (dt1.Is(F32) && dt2.Is(F32)) {
22671      EmitT32_32(0xffba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22672      AdvanceIT();
22673      return;
22674    }
22675  } else {
22676    // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; A1
22677    if (dt1.Is(F32) && dt2.Is(F32)) {
22678      EmitA32(0xf3ba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22679      return;
22680    }
22681  }
22682  Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
22683}
22684
22685void Assembler::vrintp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
22686  CheckIT(al);
22687  if (IsUsingT32()) {
22688    // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; T1
22689    if (dt1.Is(F32) && dt2.Is(F32)) {
22690      EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22691      AdvanceIT();
22692      return;
22693    }
22694  } else {
22695    // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; A1
22696    if (dt1.Is(F32) && dt2.Is(F32)) {
22697      EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22698      return;
22699    }
22700  }
22701  Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
22702}
22703
22704void Assembler::vrintr(
22705    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
22706  CheckIT(cond);
22707  if (IsUsingT32()) {
22708    // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
22709    if (dt1.Is(F32) && dt2.Is(F32)) {
22710      EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22711      AdvanceIT();
22712      return;
22713    }
22714  } else {
22715    // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
22716    if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
22717      EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
22718              rm.Encode(5, 0));
22719      return;
22720    }
22721  }
22722  Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
22723}
22724
22725void Assembler::vrintr(
22726    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22727  CheckIT(cond);
22728  if (IsUsingT32()) {
22729    // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
22730    if (dt1.Is(F64) && dt2.Is(F64)) {
22731      EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22732      AdvanceIT();
22733      return;
22734    }
22735  } else {
22736    // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
22737    if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
22738      EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
22739              rm.Encode(5, 0));
22740      return;
22741    }
22742  }
22743  Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
22744}
22745
22746void Assembler::vrintx(
22747    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22748  CheckIT(cond);
22749  if (IsUsingT32()) {
22750    // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; T1
22751    if (dt1.Is(F32) && dt2.Is(F32)) {
22752      EmitT32_32(0xffba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
22753      AdvanceIT();
22754      return;
22755    }
22756    // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
22757    if (dt1.Is(F64) && dt2.Is(F64)) {
22758      EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22759      AdvanceIT();
22760      return;
22761    }
22762  } else {
22763    // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; A1
22764    if (dt1.Is(F32) && dt2.Is(F32)) {
22765      EmitA32(0xf3ba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
22766      return;
22767    }
22768    // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
22769    if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
22770      EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
22771              rm.Encode(5, 0));
22772      return;
22773    }
22774  }
22775  Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
22776}
22777
22778void Assembler::vrintx(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
22779  CheckIT(al);
22780  if (IsUsingT32()) {
22781    // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; T1
22782    if (dt1.Is(F32) && dt2.Is(F32)) {
22783      EmitT32_32(0xffba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22784      AdvanceIT();
22785      return;
22786    }
22787  } else {
22788    // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; A1
22789    if (dt1.Is(F32) && dt2.Is(F32)) {
22790      EmitA32(0xf3ba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22791      return;
22792    }
22793  }
22794  Delegate(kVrintx, &Assembler::vrintx, dt1, dt2, rd, rm);
22795}
22796
22797void Assembler::vrintx(
22798    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
22799  CheckIT(cond);
22800  if (IsUsingT32()) {
22801    // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
22802    if (dt1.Is(F32) && dt2.Is(F32)) {
22803      EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22804      AdvanceIT();
22805      return;
22806    }
22807  } else {
22808    // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
22809    if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
22810      EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
22811              rm.Encode(5, 0));
22812      return;
22813    }
22814  }
22815  Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
22816}
22817
22818void Assembler::vrintz(
22819    Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22820  CheckIT(cond);
22821  if (IsUsingT32()) {
22822    // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; T1
22823    if (dt1.Is(F32) && dt2.Is(F32)) {
22824      EmitT32_32(0xffba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
22825      AdvanceIT();
22826      return;
22827    }
22828    // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
22829    if (dt1.Is(F64) && dt2.Is(F64)) {
22830      EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22831      AdvanceIT();
22832      return;
22833    }
22834  } else {
22835    // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; A1
22836    if (dt1.Is(F32) && dt2.Is(F32)) {
22837      EmitA32(0xf3ba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
22838      return;
22839    }
22840    // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
22841    if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
22842      EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
22843              rm.Encode(5, 0));
22844      return;
22845    }
22846  }
22847  Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
22848}
22849
22850void Assembler::vrintz(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
22851  CheckIT(al);
22852  if (IsUsingT32()) {
22853    // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; T1
22854    if (dt1.Is(F32) && dt2.Is(F32)) {
22855      EmitT32_32(0xffba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22856      AdvanceIT();
22857      return;
22858    }
22859  } else {
22860    // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; A1
22861    if (dt1.Is(F32) && dt2.Is(F32)) {
22862      EmitA32(0xf3ba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22863      return;
22864    }
22865  }
22866  Delegate(kVrintz, &Assembler::vrintz, dt1, dt2, rd, rm);
22867}
22868
22869void Assembler::vrintz(
22870    Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
22871  CheckIT(cond);
22872  if (IsUsingT32()) {
22873    // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
22874    if (dt1.Is(F32) && dt2.Is(F32)) {
22875      EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
22876      AdvanceIT();
22877      return;
22878    }
22879  } else {
22880    // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
22881    if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
22882      EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
22883              rm.Encode(5, 0));
22884      return;
22885    }
22886  }
22887  Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
22888}
22889
22890void Assembler::vrshl(
22891    Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
22892  CheckIT(cond);
22893  Dt_U_size_3 encoded_dt(dt);
22894  if (IsUsingT32()) {
22895    // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
22896    if (encoded_dt.IsValid()) {
22897      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22898        EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22899                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22900                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22901        AdvanceIT();
22902        return;
22903      }
22904    }
22905  } else {
22906    // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
22907    if (encoded_dt.IsValid()) {
22908      if (cond.Is(al)) {
22909        EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22910                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22911                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22912        return;
22913      }
22914    }
22915  }
22916  Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
22917}
22918
22919void Assembler::vrshl(
22920    Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
22921  CheckIT(cond);
22922  Dt_U_size_3 encoded_dt(dt);
22923  if (IsUsingT32()) {
22924    // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
22925    if (encoded_dt.IsValid()) {
22926      if (cond.Is(al) || AllowStronglyDiscouraged()) {
22927        EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22928                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22929                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22930        AdvanceIT();
22931        return;
22932      }
22933    }
22934  } else {
22935    // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
22936    if (encoded_dt.IsValid()) {
22937      if (cond.Is(al)) {
22938        EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22939                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22940                rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22941        return;
22942      }
22943    }
22944  }
22945  Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
22946}
22947
22948void Assembler::vrshr(Condition cond,
22949                      DataType dt,
22950                      DRegister rd,
22951                      DRegister rm,
22952                      const DOperand& operand) {
22953  CheckIT(cond);
22954  if (operand.IsImmediate()) {
22955    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22956      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22957      Dt_L_imm6_1 encoded_dt(dt);
22958      if (IsUsingT32()) {
22959        // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
22960        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
22961          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22962            uint32_t imm6 = dt.GetSize() - imm;
22963            EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) |
22964                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22965                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22966                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22967            AdvanceIT();
22968            return;
22969          }
22970        }
22971        // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
22972        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
22973          if (cond.Is(al) || AllowStronglyDiscouraged()) {
22974            EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
22975                       rm.Encode(5, 0));
22976            AdvanceIT();
22977            return;
22978          }
22979        }
22980      } else {
22981        // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
22982        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
22983          if (cond.Is(al)) {
22984            uint32_t imm6 = dt.GetSize() - imm;
22985            EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) |
22986                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22987                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22988                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22989            return;
22990          }
22991        }
22992        // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
22993        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
22994          if (cond.Is(al)) {
22995            EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
22996                    rm.Encode(5, 0));
22997            return;
22998          }
22999        }
23000      }
23001    }
23002  }
23003  Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
23004}
23005
23006void Assembler::vrshr(Condition cond,
23007                      DataType dt,
23008                      QRegister rd,
23009                      QRegister rm,
23010                      const QOperand& operand) {
23011  CheckIT(cond);
23012  if (operand.IsImmediate()) {
23013    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23014      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23015      Dt_L_imm6_1 encoded_dt(dt);
23016      if (IsUsingT32()) {
23017        // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23018        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23019          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23020            uint32_t imm6 = dt.GetSize() - imm;
23021            EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) |
23022                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23023                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23024                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23025            AdvanceIT();
23026            return;
23027          }
23028        }
23029        // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
23030        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23031          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23032            EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23033                       rm.Encode(5, 0));
23034            AdvanceIT();
23035            return;
23036          }
23037        }
23038      } else {
23039        // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23040        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23041          if (cond.Is(al)) {
23042            uint32_t imm6 = dt.GetSize() - imm;
23043            EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) |
23044                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23045                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23046                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23047            return;
23048          }
23049        }
23050        // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
23051        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23052          if (cond.Is(al)) {
23053            EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23054                    rm.Encode(5, 0));
23055            return;
23056          }
23057        }
23058      }
23059    }
23060  }
23061  Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
23062}
23063
23064void Assembler::vrshrn(Condition cond,
23065                       DataType dt,
23066                       DRegister rd,
23067                       QRegister rm,
23068                       const QOperand& operand) {
23069  CheckIT(cond);
23070  if (operand.IsImmediate()) {
23071    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23072      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23073      Dt_imm6_3 encoded_dt(dt);
23074      Dt_size_3 encoded_dt_2(dt);
23075      if (IsUsingT32()) {
23076        // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
23077        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23078          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23079            uint32_t imm6 = dt.GetSize() / 2 - imm;
23080            EmitT32_32(0xef800850U |
23081                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23082                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23083            AdvanceIT();
23084            return;
23085          }
23086        }
23087        // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23088        if (encoded_dt_2.IsValid() && (imm == 0)) {
23089          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23090            EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
23091                       rd.Encode(22, 12) | rm.Encode(5, 0));
23092            AdvanceIT();
23093            return;
23094          }
23095        }
23096      } else {
23097        // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
23098        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23099          if (cond.Is(al)) {
23100            uint32_t imm6 = dt.GetSize() / 2 - imm;
23101            EmitA32(0xf2800850U |
23102                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23103                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23104            return;
23105          }
23106        }
23107        // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23108        if (encoded_dt_2.IsValid() && (imm == 0)) {
23109          if (cond.Is(al)) {
23110            EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
23111                    rd.Encode(22, 12) | rm.Encode(5, 0));
23112            return;
23113          }
23114        }
23115      }
23116    }
23117  }
23118  Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand);
23119}
23120
23121void Assembler::vrsqrte(Condition cond,
23122                        DataType dt,
23123                        DRegister rd,
23124                        DRegister rm) {
23125  CheckIT(cond);
23126  Dt_F_size_4 encoded_dt(dt);
23127  if (IsUsingT32()) {
23128    // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
23129    if (encoded_dt.IsValid()) {
23130      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23131        EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23132                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23133                   rd.Encode(22, 12) | rm.Encode(5, 0));
23134        AdvanceIT();
23135        return;
23136      }
23137    }
23138  } else {
23139    // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
23140    if (encoded_dt.IsValid()) {
23141      if (cond.Is(al)) {
23142        EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23143                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23144                rd.Encode(22, 12) | rm.Encode(5, 0));
23145        return;
23146      }
23147    }
23148  }
23149  Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
23150}
23151
23152void Assembler::vrsqrte(Condition cond,
23153                        DataType dt,
23154                        QRegister rd,
23155                        QRegister rm) {
23156  CheckIT(cond);
23157  Dt_F_size_4 encoded_dt(dt);
23158  if (IsUsingT32()) {
23159    // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
23160    if (encoded_dt.IsValid()) {
23161      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23162        EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23163                   ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23164                   rd.Encode(22, 12) | rm.Encode(5, 0));
23165        AdvanceIT();
23166        return;
23167      }
23168    }
23169  } else {
23170    // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
23171    if (encoded_dt.IsValid()) {
23172      if (cond.Is(al)) {
23173        EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23174                ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23175                rd.Encode(22, 12) | rm.Encode(5, 0));
23176        return;
23177      }
23178    }
23179  }
23180  Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
23181}
23182
23183void Assembler::vrsqrts(
23184    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23185  CheckIT(cond);
23186  if (IsUsingT32()) {
23187    // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
23188    if (dt.Is(F32)) {
23189      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23190        EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23191                   rm.Encode(5, 0));
23192        AdvanceIT();
23193        return;
23194      }
23195    }
23196  } else {
23197    // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
23198    if (dt.Is(F32)) {
23199      if (cond.Is(al)) {
23200        EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23201                rm.Encode(5, 0));
23202        return;
23203      }
23204    }
23205  }
23206  Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
23207}
23208
23209void Assembler::vrsqrts(
23210    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
23211  CheckIT(cond);
23212  if (IsUsingT32()) {
23213    // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
23214    if (dt.Is(F32)) {
23215      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23216        EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23217                   rm.Encode(5, 0));
23218        AdvanceIT();
23219        return;
23220      }
23221    }
23222  } else {
23223    // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
23224    if (dt.Is(F32)) {
23225      if (cond.Is(al)) {
23226        EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23227                rm.Encode(5, 0));
23228        return;
23229      }
23230    }
23231  }
23232  Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
23233}
23234
23235void Assembler::vrsra(Condition cond,
23236                      DataType dt,
23237                      DRegister rd,
23238                      DRegister rm,
23239                      const DOperand& operand) {
23240  CheckIT(cond);
23241  if (operand.IsImmediate()) {
23242    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23243      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23244      Dt_L_imm6_1 encoded_dt(dt);
23245      if (IsUsingT32()) {
23246        // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23247        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23248          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23249            uint32_t imm6 = dt.GetSize() - imm;
23250            EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) |
23251                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23252                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23253                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23254            AdvanceIT();
23255            return;
23256          }
23257        }
23258      } else {
23259        // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23260        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23261          if (cond.Is(al)) {
23262            uint32_t imm6 = dt.GetSize() - imm;
23263            EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) |
23264                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23265                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23266                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23267            return;
23268          }
23269        }
23270      }
23271    }
23272  }
23273  Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
23274}
23275
23276void Assembler::vrsra(Condition cond,
23277                      DataType dt,
23278                      QRegister rd,
23279                      QRegister rm,
23280                      const QOperand& operand) {
23281  CheckIT(cond);
23282  if (operand.IsImmediate()) {
23283    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23284      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23285      Dt_L_imm6_1 encoded_dt(dt);
23286      if (IsUsingT32()) {
23287        // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23288        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23289          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23290            uint32_t imm6 = dt.GetSize() - imm;
23291            EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) |
23292                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23293                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23294                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23295            AdvanceIT();
23296            return;
23297          }
23298        }
23299      } else {
23300        // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23301        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23302          if (cond.Is(al)) {
23303            uint32_t imm6 = dt.GetSize() - imm;
23304            EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) |
23305                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23306                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23307                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23308            return;
23309          }
23310        }
23311      }
23312    }
23313  }
23314  Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
23315}
23316
23317void Assembler::vrsubhn(
23318    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
23319  CheckIT(cond);
23320  Dt_size_3 encoded_dt(dt);
23321  if (IsUsingT32()) {
23322    // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
23323    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
23324      if (cond.Is(al) || AllowStronglyDiscouraged()) {
23325        EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) |
23326                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23327        AdvanceIT();
23328        return;
23329      }
23330    }
23331  } else {
23332    // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
23333    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
23334      if (cond.Is(al)) {
23335        EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) |
23336                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23337        return;
23338      }
23339    }
23340  }
23341  Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm);
23342}
23343
23344void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23345  CheckIT(al);
23346  if (IsUsingT32()) {
23347    // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1
23348    if (OutsideITBlock() && dt.Is(F64)) {
23349      EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23350                 rm.Encode(5, 0));
23351      AdvanceIT();
23352      return;
23353    }
23354  } else {
23355    // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1
23356    if (dt.Is(F64)) {
23357      EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23358              rm.Encode(5, 0));
23359      return;
23360    }
23361  }
23362  Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
23363}
23364
23365void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23366  CheckIT(al);
23367  if (IsUsingT32()) {
23368    // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1
23369    if (OutsideITBlock() && dt.Is(F32)) {
23370      EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23371                 rm.Encode(5, 0));
23372      AdvanceIT();
23373      return;
23374    }
23375  } else {
23376    // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1
23377    if (dt.Is(F32)) {
23378      EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23379              rm.Encode(5, 0));
23380      return;
23381    }
23382  }
23383  Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
23384}
23385
23386void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23387  CheckIT(al);
23388  if (IsUsingT32()) {
23389    // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1
23390    if (OutsideITBlock() && dt.Is(F64)) {
23391      EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23392                 rm.Encode(5, 0));
23393      AdvanceIT();
23394      return;
23395    }
23396  } else {
23397    // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1
23398    if (dt.Is(F64)) {
23399      EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23400              rm.Encode(5, 0));
23401      return;
23402    }
23403  }
23404  Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
23405}
23406
23407void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23408  CheckIT(al);
23409  if (IsUsingT32()) {
23410    // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1
23411    if (OutsideITBlock() && dt.Is(F32)) {
23412      EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23413                 rm.Encode(5, 0));
23414      AdvanceIT();
23415      return;
23416    }
23417  } else {
23418    // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1
23419    if (dt.Is(F32)) {
23420      EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23421              rm.Encode(5, 0));
23422      return;
23423    }
23424  }
23425  Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
23426}
23427
23428void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23429  CheckIT(al);
23430  if (IsUsingT32()) {
23431    // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1
23432    if (OutsideITBlock() && dt.Is(F64)) {
23433      EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23434                 rm.Encode(5, 0));
23435      AdvanceIT();
23436      return;
23437    }
23438  } else {
23439    // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1
23440    if (dt.Is(F64)) {
23441      EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23442              rm.Encode(5, 0));
23443      return;
23444    }
23445  }
23446  Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
23447}
23448
23449void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23450  CheckIT(al);
23451  if (IsUsingT32()) {
23452    // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1
23453    if (OutsideITBlock() && dt.Is(F32)) {
23454      EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23455                 rm.Encode(5, 0));
23456      AdvanceIT();
23457      return;
23458    }
23459  } else {
23460    // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1
23461    if (dt.Is(F32)) {
23462      EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23463              rm.Encode(5, 0));
23464      return;
23465    }
23466  }
23467  Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
23468}
23469
23470void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23471  CheckIT(al);
23472  if (IsUsingT32()) {
23473    // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1
23474    if (OutsideITBlock() && dt.Is(F64)) {
23475      EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23476                 rm.Encode(5, 0));
23477      AdvanceIT();
23478      return;
23479    }
23480  } else {
23481    // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1
23482    if (dt.Is(F64)) {
23483      EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23484              rm.Encode(5, 0));
23485      return;
23486    }
23487  }
23488  Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
23489}
23490
23491void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23492  CheckIT(al);
23493  if (IsUsingT32()) {
23494    // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1
23495    if (OutsideITBlock() && dt.Is(F32)) {
23496      EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23497                 rm.Encode(5, 0));
23498      AdvanceIT();
23499      return;
23500    }
23501  } else {
23502    // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1
23503    if (dt.Is(F32)) {
23504      EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23505              rm.Encode(5, 0));
23506      return;
23507    }
23508  }
23509  Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
23510}
23511
23512void Assembler::vshl(Condition cond,
23513                     DataType dt,
23514                     DRegister rd,
23515                     DRegister rm,
23516                     const DOperand& operand) {
23517  CheckIT(cond);
23518  if (operand.IsImmediate()) {
23519    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23520      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23521      Dt_L_imm6_3 encoded_dt(dt);
23522      if (IsUsingT32()) {
23523        // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1
23524        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23525          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23526            uint32_t imm6 = imm;
23527            EmitT32_32(0xef800510U |
23528                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23529                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23530                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23531            AdvanceIT();
23532            return;
23533          }
23534        }
23535      } else {
23536        // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1
23537        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23538          if (cond.Is(al)) {
23539            uint32_t imm6 = imm;
23540            EmitA32(0xf2800510U |
23541                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23542                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23543                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23544            return;
23545          }
23546        }
23547      }
23548    }
23549  }
23550  if (operand.IsRegister()) {
23551    DRegister rn = operand.GetRegister();
23552    Dt_U_size_3 encoded_dt(dt);
23553    if (IsUsingT32()) {
23554      // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
23555      if (encoded_dt.IsValid()) {
23556        if (cond.Is(al) || AllowStronglyDiscouraged()) {
23557          EmitT32_32(0xef000400U |
23558                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23559                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23560                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23561          AdvanceIT();
23562          return;
23563        }
23564      }
23565    } else {
23566      // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
23567      if (encoded_dt.IsValid()) {
23568        if (cond.Is(al)) {
23569          EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23570                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23571                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23572          return;
23573        }
23574      }
23575    }
23576  }
23577  Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
23578}
23579
23580void Assembler::vshl(Condition cond,
23581                     DataType dt,
23582                     QRegister rd,
23583                     QRegister rm,
23584                     const QOperand& operand) {
23585  CheckIT(cond);
23586  if (operand.IsImmediate()) {
23587    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23588      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23589      Dt_L_imm6_3 encoded_dt(dt);
23590      if (IsUsingT32()) {
23591        // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1
23592        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23593          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23594            uint32_t imm6 = imm;
23595            EmitT32_32(0xef800550U |
23596                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23597                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23598                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23599            AdvanceIT();
23600            return;
23601          }
23602        }
23603      } else {
23604        // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1
23605        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23606          if (cond.Is(al)) {
23607            uint32_t imm6 = imm;
23608            EmitA32(0xf2800550U |
23609                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23610                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23611                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23612            return;
23613          }
23614        }
23615      }
23616    }
23617  }
23618  if (operand.IsRegister()) {
23619    QRegister rn = operand.GetRegister();
23620    Dt_U_size_3 encoded_dt(dt);
23621    if (IsUsingT32()) {
23622      // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
23623      if (encoded_dt.IsValid()) {
23624        if (cond.Is(al) || AllowStronglyDiscouraged()) {
23625          EmitT32_32(0xef000440U |
23626                     ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23627                     ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23628                     rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23629          AdvanceIT();
23630          return;
23631        }
23632      }
23633    } else {
23634      // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
23635      if (encoded_dt.IsValid()) {
23636        if (cond.Is(al)) {
23637          EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23638                  ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23639                  rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23640          return;
23641        }
23642      }
23643    }
23644  }
23645  Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
23646}
23647
23648void Assembler::vshll(Condition cond,
23649                      DataType dt,
23650                      QRegister rd,
23651                      DRegister rm,
23652                      const DOperand& operand) {
23653  CheckIT(cond);
23654  if (operand.IsImmediate()) {
23655    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23656      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23657      Dt_imm6_4 encoded_dt(dt);
23658      Dt_size_16 encoded_dt_2(dt);
23659      if (IsUsingT32()) {
23660        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1
23661        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
23662          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23663            uint32_t imm6 = dt.GetSize() + imm;
23664            EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) |
23665                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23666                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23667            AdvanceIT();
23668            return;
23669          }
23670        }
23671        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2
23672        if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
23673          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23674            EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) |
23675                       rd.Encode(22, 12) | rm.Encode(5, 0));
23676            AdvanceIT();
23677            return;
23678          }
23679        }
23680      } else {
23681        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1
23682        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
23683          if (cond.Is(al)) {
23684            uint32_t imm6 = dt.GetSize() + imm;
23685            EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) |
23686                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23687                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23688            return;
23689          }
23690        }
23691        // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2
23692        if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
23693          if (cond.Is(al)) {
23694            EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) |
23695                    rd.Encode(22, 12) | rm.Encode(5, 0));
23696            return;
23697          }
23698        }
23699      }
23700    }
23701  }
23702  Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand);
23703}
23704
23705void Assembler::vshr(Condition cond,
23706                     DataType dt,
23707                     DRegister rd,
23708                     DRegister rm,
23709                     const DOperand& operand) {
23710  CheckIT(cond);
23711  if (operand.IsImmediate()) {
23712    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23713      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23714      Dt_L_imm6_1 encoded_dt(dt);
23715      if (IsUsingT32()) {
23716        // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23717        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23718          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23719            uint32_t imm6 = dt.GetSize() - imm;
23720            EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) |
23721                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23722                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23723                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23724            AdvanceIT();
23725            return;
23726          }
23727        }
23728        // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
23729        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23730          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23731            EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23732                       rm.Encode(5, 0));
23733            AdvanceIT();
23734            return;
23735          }
23736        }
23737      } else {
23738        // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23739        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23740          if (cond.Is(al)) {
23741            uint32_t imm6 = dt.GetSize() - imm;
23742            EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) |
23743                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23744                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23745                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23746            return;
23747          }
23748        }
23749        // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
23750        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23751          if (cond.Is(al)) {
23752            EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23753                    rm.Encode(5, 0));
23754            return;
23755          }
23756        }
23757      }
23758    }
23759  }
23760  Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
23761}
23762
23763void Assembler::vshr(Condition cond,
23764                     DataType dt,
23765                     QRegister rd,
23766                     QRegister rm,
23767                     const QOperand& operand) {
23768  CheckIT(cond);
23769  if (operand.IsImmediate()) {
23770    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23771      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23772      Dt_L_imm6_1 encoded_dt(dt);
23773      if (IsUsingT32()) {
23774        // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23775        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23776          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23777            uint32_t imm6 = dt.GetSize() - imm;
23778            EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) |
23779                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23780                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23781                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23782            AdvanceIT();
23783            return;
23784          }
23785        }
23786        // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
23787        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23788          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23789            EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23790                       rm.Encode(5, 0));
23791            AdvanceIT();
23792            return;
23793          }
23794        }
23795      } else {
23796        // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23797        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23798          if (cond.Is(al)) {
23799            uint32_t imm6 = dt.GetSize() - imm;
23800            EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) |
23801                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23802                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23803                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23804            return;
23805          }
23806        }
23807        // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
23808        if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23809          if (cond.Is(al)) {
23810            EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23811                    rm.Encode(5, 0));
23812            return;
23813          }
23814        }
23815      }
23816    }
23817  }
23818  Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
23819}
23820
23821void Assembler::vshrn(Condition cond,
23822                      DataType dt,
23823                      DRegister rd,
23824                      QRegister rm,
23825                      const QOperand& operand) {
23826  CheckIT(cond);
23827  if (operand.IsImmediate()) {
23828    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23829      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23830      Dt_imm6_3 encoded_dt(dt);
23831      Dt_size_3 encoded_dt_2(dt);
23832      if (IsUsingT32()) {
23833        // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
23834        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23835          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23836            uint32_t imm6 = dt.GetSize() / 2 - imm;
23837            EmitT32_32(0xef800810U |
23838                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23839                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23840            AdvanceIT();
23841            return;
23842          }
23843        }
23844        // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23845        if (encoded_dt_2.IsValid() && (imm == 0)) {
23846          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23847            EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
23848                       rd.Encode(22, 12) | rm.Encode(5, 0));
23849            AdvanceIT();
23850            return;
23851          }
23852        }
23853      } else {
23854        // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
23855        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23856          if (cond.Is(al)) {
23857            uint32_t imm6 = dt.GetSize() / 2 - imm;
23858            EmitA32(0xf2800810U |
23859                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23860                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23861            return;
23862          }
23863        }
23864        // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23865        if (encoded_dt_2.IsValid() && (imm == 0)) {
23866          if (cond.Is(al)) {
23867            EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
23868                    rd.Encode(22, 12) | rm.Encode(5, 0));
23869            return;
23870          }
23871        }
23872      }
23873    }
23874  }
23875  Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand);
23876}
23877
23878void Assembler::vsli(Condition cond,
23879                     DataType dt,
23880                     DRegister rd,
23881                     DRegister rm,
23882                     const DOperand& operand) {
23883  CheckIT(cond);
23884  if (operand.IsImmediate()) {
23885    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23886      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23887      Dt_L_imm6_4 encoded_dt(dt);
23888      if (IsUsingT32()) {
23889        // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
23890        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23891          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23892            uint32_t imm6 = imm;
23893            EmitT32_32(0xff800510U |
23894                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23895                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23896                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23897            AdvanceIT();
23898            return;
23899          }
23900        }
23901      } else {
23902        // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
23903        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23904          if (cond.Is(al)) {
23905            uint32_t imm6 = imm;
23906            EmitA32(0xf3800510U |
23907                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23908                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23909                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23910            return;
23911          }
23912        }
23913      }
23914    }
23915  }
23916  Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
23917}
23918
23919void Assembler::vsli(Condition cond,
23920                     DataType dt,
23921                     QRegister rd,
23922                     QRegister rm,
23923                     const QOperand& operand) {
23924  CheckIT(cond);
23925  if (operand.IsImmediate()) {
23926    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23927      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23928      Dt_L_imm6_4 encoded_dt(dt);
23929      if (IsUsingT32()) {
23930        // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
23931        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23932          if (cond.Is(al) || AllowStronglyDiscouraged()) {
23933            uint32_t imm6 = imm;
23934            EmitT32_32(0xff800550U |
23935                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23936                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23937                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23938            AdvanceIT();
23939            return;
23940          }
23941        }
23942      } else {
23943        // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
23944        if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23945          if (cond.Is(al)) {
23946            uint32_t imm6 = imm;
23947            EmitA32(0xf3800550U |
23948                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23949                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23950                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23951            return;
23952          }
23953        }
23954      }
23955    }
23956  }
23957  Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
23958}
23959
23960void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) {
23961  CheckIT(cond);
23962  if (IsUsingT32()) {
23963    // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
23964    if (dt.Is(F32)) {
23965      EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23966      AdvanceIT();
23967      return;
23968    }
23969  } else {
23970    // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
23971    if (dt.Is(F32) && cond.IsNotNever()) {
23972      EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23973              rm.Encode(5, 0));
23974      return;
23975    }
23976  }
23977  Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
23978}
23979
23980void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
23981  CheckIT(cond);
23982  if (IsUsingT32()) {
23983    // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
23984    if (dt.Is(F64)) {
23985      EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23986      AdvanceIT();
23987      return;
23988    }
23989  } else {
23990    // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
23991    if (dt.Is(F64) && cond.IsNotNever()) {
23992      EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23993              rm.Encode(5, 0));
23994      return;
23995    }
23996  }
23997  Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
23998}
23999
24000void Assembler::vsra(Condition cond,
24001                     DataType dt,
24002                     DRegister rd,
24003                     DRegister rm,
24004                     const DOperand& operand) {
24005  CheckIT(cond);
24006  if (operand.IsImmediate()) {
24007    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24008      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24009      Dt_L_imm6_1 encoded_dt(dt);
24010      if (IsUsingT32()) {
24011        // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
24012        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24013          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24014            uint32_t imm6 = dt.GetSize() - imm;
24015            EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) |
24016                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24017                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24018                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24019            AdvanceIT();
24020            return;
24021          }
24022        }
24023      } else {
24024        // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
24025        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24026          if (cond.Is(al)) {
24027            uint32_t imm6 = dt.GetSize() - imm;
24028            EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) |
24029                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24030                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24031                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24032            return;
24033          }
24034        }
24035      }
24036    }
24037  }
24038  Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
24039}
24040
24041void Assembler::vsra(Condition cond,
24042                     DataType dt,
24043                     QRegister rd,
24044                     QRegister rm,
24045                     const QOperand& operand) {
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_1 encoded_dt(dt);
24051      if (IsUsingT32()) {
24052        // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
24053        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24054          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24055            uint32_t imm6 = dt.GetSize() - imm;
24056            EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) |
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        // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
24066        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24067          if (cond.Is(al)) {
24068            uint32_t imm6 = dt.GetSize() - imm;
24069            EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) |
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  Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
24080}
24081
24082void Assembler::vsri(Condition cond,
24083                     DataType dt,
24084                     DRegister rd,
24085                     DRegister rm,
24086                     const DOperand& operand) {
24087  CheckIT(cond);
24088  if (operand.IsImmediate()) {
24089    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24090      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24091      Dt_L_imm6_4 encoded_dt(dt);
24092      if (IsUsingT32()) {
24093        // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
24094        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24095          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24096            uint32_t imm6 = dt.GetSize() - imm;
24097            EmitT32_32(0xff800410U |
24098                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24099                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24100                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24101            AdvanceIT();
24102            return;
24103          }
24104        }
24105      } else {
24106        // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
24107        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24108          if (cond.Is(al)) {
24109            uint32_t imm6 = dt.GetSize() - imm;
24110            EmitA32(0xf3800410U |
24111                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24112                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24113                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24114            return;
24115          }
24116        }
24117      }
24118    }
24119  }
24120  Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
24121}
24122
24123void Assembler::vsri(Condition cond,
24124                     DataType dt,
24125                     QRegister rd,
24126                     QRegister rm,
24127                     const QOperand& operand) {
24128  CheckIT(cond);
24129  if (operand.IsImmediate()) {
24130    if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24131      uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24132      Dt_L_imm6_4 encoded_dt(dt);
24133      if (IsUsingT32()) {
24134        // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
24135        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24136          if (cond.Is(al) || AllowStronglyDiscouraged()) {
24137            uint32_t imm6 = dt.GetSize() - imm;
24138            EmitT32_32(0xff800450U |
24139                       ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24140                       ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24141                       rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24142            AdvanceIT();
24143            return;
24144          }
24145        }
24146      } else {
24147        // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
24148        if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24149          if (cond.Is(al)) {
24150            uint32_t imm6 = dt.GetSize() - imm;
24151            EmitA32(0xf3800450U |
24152                    ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24153                    ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24154                    rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24155            return;
24156          }
24157        }
24158      }
24159    }
24160  }
24161  Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
24162}
24163
24164void Assembler::vst1(Condition cond,
24165                     DataType dt,
24166                     const NeonRegisterList& nreglist,
24167                     const AlignedMemOperand& operand) {
24168  CheckIT(cond);
24169  if (operand.IsImmediateZero()) {
24170    Register rn = operand.GetBaseRegister();
24171    Alignment align = operand.GetAlignment();
24172    Dt_size_6 encoded_dt(dt);
24173    Dt_size_7 encoded_dt_2(dt);
24174    Align_align_5 encoded_align_1(align, nreglist);
24175    Align_index_align_1 encoded_align_2(align, nreglist, dt);
24176    if (IsUsingT32()) {
24177      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24178      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24179          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24180          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
24181          ((!rn.IsPC()) || AllowUnpredictable())) {
24182        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24183          const DRegister& first = nreglist.GetFirstDRegister();
24184          uint32_t len_encoding;
24185          switch (nreglist.GetLength()) {
24186            default:
24187              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24188            case 1:
24189              len_encoding = 0x7;
24190              break;
24191            case 2:
24192              len_encoding = 0xa;
24193              break;
24194            case 3:
24195              len_encoding = 0x6;
24196              break;
24197            case 4:
24198              len_encoding = 0x2;
24199              break;
24200          }
24201          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
24202                     (encoded_align_1.GetEncodingValue() << 4) |
24203                     first.Encode(22, 12) | (len_encoding << 8) |
24204                     (rn.GetCode() << 16));
24205          AdvanceIT();
24206          return;
24207        }
24208      }
24209      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24210      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24211          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24212          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
24213          ((!rn.IsPC()) || AllowUnpredictable())) {
24214        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24215          const DRegister& first = nreglist.GetFirstDRegister();
24216          uint32_t len_encoding;
24217          switch (nreglist.GetLength()) {
24218            default:
24219              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24220            case 1:
24221              len_encoding = 0x7;
24222              break;
24223            case 2:
24224              len_encoding = 0xa;
24225              break;
24226            case 3:
24227              len_encoding = 0x6;
24228              break;
24229            case 4:
24230              len_encoding = 0x2;
24231              break;
24232          }
24233          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
24234                     (encoded_align_1.GetEncodingValue() << 4) |
24235                     first.Encode(22, 12) | (len_encoding << 8) |
24236                     (rn.GetCode() << 16));
24237          AdvanceIT();
24238          return;
24239        }
24240      }
24241      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24242      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24243          (nreglist.GetLength() == 1) && (operand.GetAddrMode() == Offset) &&
24244          encoded_align_2.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
24245        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24246          const DRegister& first = nreglist.GetFirstDRegister();
24247          EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) |
24248                     (encoded_align_2.GetEncodingValue() << 4) |
24249                     first.Encode(22, 12) | (rn.GetCode() << 16));
24250          AdvanceIT();
24251          return;
24252        }
24253      }
24254      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24255      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24256          (nreglist.GetLength() == 1) && (operand.GetAddrMode() == PostIndex) &&
24257          encoded_align_2.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
24258        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24259          const DRegister& first = nreglist.GetFirstDRegister();
24260          EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) |
24261                     (encoded_align_2.GetEncodingValue() << 4) |
24262                     first.Encode(22, 12) | (rn.GetCode() << 16));
24263          AdvanceIT();
24264          return;
24265        }
24266      }
24267    } else {
24268      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
24269      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24270          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24271          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
24272          ((!rn.IsPC()) || AllowUnpredictable())) {
24273        if (cond.Is(al)) {
24274          const DRegister& first = nreglist.GetFirstDRegister();
24275          uint32_t len_encoding;
24276          switch (nreglist.GetLength()) {
24277            default:
24278              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24279            case 1:
24280              len_encoding = 0x7;
24281              break;
24282            case 2:
24283              len_encoding = 0xa;
24284              break;
24285            case 3:
24286              len_encoding = 0x6;
24287              break;
24288            case 4:
24289              len_encoding = 0x2;
24290              break;
24291          }
24292          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
24293                  (encoded_align_1.GetEncodingValue() << 4) |
24294                  first.Encode(22, 12) | (len_encoding << 8) |
24295                  (rn.GetCode() << 16));
24296          return;
24297        }
24298      }
24299      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
24300      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24301          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24302          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
24303          ((!rn.IsPC()) || AllowUnpredictable())) {
24304        if (cond.Is(al)) {
24305          const DRegister& first = nreglist.GetFirstDRegister();
24306          uint32_t len_encoding;
24307          switch (nreglist.GetLength()) {
24308            default:
24309              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24310            case 1:
24311              len_encoding = 0x7;
24312              break;
24313            case 2:
24314              len_encoding = 0xa;
24315              break;
24316            case 3:
24317              len_encoding = 0x6;
24318              break;
24319            case 4:
24320              len_encoding = 0x2;
24321              break;
24322          }
24323          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
24324                  (encoded_align_1.GetEncodingValue() << 4) |
24325                  first.Encode(22, 12) | (len_encoding << 8) |
24326                  (rn.GetCode() << 16));
24327          return;
24328        }
24329      }
24330      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
24331      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24332          (nreglist.GetLength() == 1) && (operand.GetAddrMode() == Offset) &&
24333          encoded_align_2.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
24334        if (cond.Is(al)) {
24335          const DRegister& first = nreglist.GetFirstDRegister();
24336          EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) |
24337                  (encoded_align_2.GetEncodingValue() << 4) |
24338                  first.Encode(22, 12) | (rn.GetCode() << 16));
24339          return;
24340        }
24341      }
24342      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
24343      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24344          (nreglist.GetLength() == 1) && (operand.GetAddrMode() == PostIndex) &&
24345          encoded_align_2.IsValid() && ((!rn.IsPC()) || AllowUnpredictable())) {
24346        if (cond.Is(al)) {
24347          const DRegister& first = nreglist.GetFirstDRegister();
24348          EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) |
24349                  (encoded_align_2.GetEncodingValue() << 4) |
24350                  first.Encode(22, 12) | (rn.GetCode() << 16));
24351          return;
24352        }
24353      }
24354    }
24355  }
24356  if (operand.IsPlainRegister()) {
24357    Register rn = operand.GetBaseRegister();
24358    Alignment align = operand.GetAlignment();
24359    Register rm = operand.GetOffsetRegister();
24360    Dt_size_6 encoded_dt(dt);
24361    Dt_size_7 encoded_dt_2(dt);
24362    Align_align_5 encoded_align_1(align, nreglist);
24363    Align_index_align_1 encoded_align_2(align, nreglist, dt);
24364    if (IsUsingT32()) {
24365      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
24366      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24367          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24368          !rm.IsPC() && !rm.IsSP()) {
24369        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24370          const DRegister& first = nreglist.GetFirstDRegister();
24371          uint32_t len_encoding;
24372          switch (nreglist.GetLength()) {
24373            default:
24374              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24375            case 1:
24376              len_encoding = 0x7;
24377              break;
24378            case 2:
24379              len_encoding = 0xa;
24380              break;
24381            case 3:
24382              len_encoding = 0x6;
24383              break;
24384            case 4:
24385              len_encoding = 0x2;
24386              break;
24387          }
24388          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
24389                     (encoded_align_1.GetEncodingValue() << 4) |
24390                     first.Encode(22, 12) | (len_encoding << 8) |
24391                     (rn.GetCode() << 16) | rm.GetCode());
24392          AdvanceIT();
24393          return;
24394        }
24395      }
24396      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
24397      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24398          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
24399        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24400          const DRegister& first = nreglist.GetFirstDRegister();
24401          EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) |
24402                     (encoded_align_2.GetEncodingValue() << 4) |
24403                     first.Encode(22, 12) | (rn.GetCode() << 16) |
24404                     rm.GetCode());
24405          AdvanceIT();
24406          return;
24407        }
24408      }
24409    } else {
24410      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
24411      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24412          (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24413          !rm.IsPC() && !rm.IsSP()) {
24414        if (cond.Is(al)) {
24415          const DRegister& first = nreglist.GetFirstDRegister();
24416          uint32_t len_encoding;
24417          switch (nreglist.GetLength()) {
24418            default:
24419              VIXL_UNREACHABLE_OR_FALLTHROUGH();
24420            case 1:
24421              len_encoding = 0x7;
24422              break;
24423            case 2:
24424              len_encoding = 0xa;
24425              break;
24426            case 3:
24427              len_encoding = 0x6;
24428              break;
24429            case 4:
24430              len_encoding = 0x2;
24431              break;
24432          }
24433          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
24434                  (encoded_align_1.GetEncodingValue() << 4) |
24435                  first.Encode(22, 12) | (len_encoding << 8) |
24436                  (rn.GetCode() << 16) | rm.GetCode());
24437          return;
24438        }
24439      }
24440      // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
24441      if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24442          (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
24443        if (cond.Is(al)) {
24444          const DRegister& first = nreglist.GetFirstDRegister();
24445          EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) |
24446                  (encoded_align_2.GetEncodingValue() << 4) |
24447                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
24448          return;
24449        }
24450      }
24451    }
24452  }
24453  Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand);
24454}
24455
24456void Assembler::vst2(Condition cond,
24457                     DataType dt,
24458                     const NeonRegisterList& nreglist,
24459                     const AlignedMemOperand& operand) {
24460  CheckIT(cond);
24461  if (operand.IsImmediateZero()) {
24462    Register rn = operand.GetBaseRegister();
24463    Alignment align = operand.GetAlignment();
24464    Dt_size_7 encoded_dt(dt);
24465    Align_align_2 encoded_align_1(align, nreglist);
24466    Align_index_align_2 encoded_align_2(align, nreglist, dt);
24467    if (IsUsingT32()) {
24468      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24469      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24470          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24471           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
24472           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
24473          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
24474          ((!rn.IsPC()) || AllowUnpredictable())) {
24475        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24476          const DRegister& first = nreglist.GetFirstDRegister();
24477          uint32_t len_encoding;
24478          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
24479            len_encoding = 0x8;
24480          }
24481          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
24482            len_encoding = 0x9;
24483          }
24484          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
24485            len_encoding = 0x3;
24486          }
24487          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
24488                     (encoded_align_1.GetEncodingValue() << 4) |
24489                     first.Encode(22, 12) | (len_encoding << 8) |
24490                     (rn.GetCode() << 16));
24491          AdvanceIT();
24492          return;
24493        }
24494      }
24495      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24496      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24497          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24498           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
24499           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
24500          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
24501          ((!rn.IsPC()) || AllowUnpredictable())) {
24502        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24503          const DRegister& first = nreglist.GetFirstDRegister();
24504          uint32_t len_encoding;
24505          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
24506            len_encoding = 0x8;
24507          }
24508          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
24509            len_encoding = 0x9;
24510          }
24511          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
24512            len_encoding = 0x3;
24513          }
24514          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
24515                     (encoded_align_1.GetEncodingValue() << 4) |
24516                     first.Encode(22, 12) | (len_encoding << 8) |
24517                     (rn.GetCode() << 16));
24518          AdvanceIT();
24519          return;
24520        }
24521      }
24522      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24523      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24524          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24525           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
24526          (operand.GetAddrMode() == Offset) && encoded_align_2.IsValid() &&
24527          ((!rn.IsPC()) || AllowUnpredictable())) {
24528        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24529          const DRegister& first = nreglist.GetFirstDRegister();
24530          EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) |
24531                     (encoded_align_2.GetEncodingValue() << 4) |
24532                     first.Encode(22, 12) | (rn.GetCode() << 16));
24533          AdvanceIT();
24534          return;
24535        }
24536      }
24537      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24538      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24539          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24540           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
24541          (operand.GetAddrMode() == PostIndex) && encoded_align_2.IsValid() &&
24542          ((!rn.IsPC()) || AllowUnpredictable())) {
24543        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24544          const DRegister& first = nreglist.GetFirstDRegister();
24545          EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) |
24546                     (encoded_align_2.GetEncodingValue() << 4) |
24547                     first.Encode(22, 12) | (rn.GetCode() << 16));
24548          AdvanceIT();
24549          return;
24550        }
24551      }
24552    } else {
24553      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
24554      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24555          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24556           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
24557           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
24558          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
24559          ((!rn.IsPC()) || AllowUnpredictable())) {
24560        if (cond.Is(al)) {
24561          const DRegister& first = nreglist.GetFirstDRegister();
24562          uint32_t len_encoding;
24563          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
24564            len_encoding = 0x8;
24565          }
24566          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
24567            len_encoding = 0x9;
24568          }
24569          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
24570            len_encoding = 0x3;
24571          }
24572          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
24573                  (encoded_align_1.GetEncodingValue() << 4) |
24574                  first.Encode(22, 12) | (len_encoding << 8) |
24575                  (rn.GetCode() << 16));
24576          return;
24577        }
24578      }
24579      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
24580      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24581          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24582           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
24583           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
24584          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
24585          ((!rn.IsPC()) || AllowUnpredictable())) {
24586        if (cond.Is(al)) {
24587          const DRegister& first = nreglist.GetFirstDRegister();
24588          uint32_t len_encoding;
24589          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
24590            len_encoding = 0x8;
24591          }
24592          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
24593            len_encoding = 0x9;
24594          }
24595          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
24596            len_encoding = 0x3;
24597          }
24598          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
24599                  (encoded_align_1.GetEncodingValue() << 4) |
24600                  first.Encode(22, 12) | (len_encoding << 8) |
24601                  (rn.GetCode() << 16));
24602          return;
24603        }
24604      }
24605      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
24606      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24607          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24608           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
24609          (operand.GetAddrMode() == Offset) && encoded_align_2.IsValid() &&
24610          ((!rn.IsPC()) || AllowUnpredictable())) {
24611        if (cond.Is(al)) {
24612          const DRegister& first = nreglist.GetFirstDRegister();
24613          EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) |
24614                  (encoded_align_2.GetEncodingValue() << 4) |
24615                  first.Encode(22, 12) | (rn.GetCode() << 16));
24616          return;
24617        }
24618      }
24619      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
24620      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24621          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24622           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
24623          (operand.GetAddrMode() == PostIndex) && encoded_align_2.IsValid() &&
24624          ((!rn.IsPC()) || AllowUnpredictable())) {
24625        if (cond.Is(al)) {
24626          const DRegister& first = nreglist.GetFirstDRegister();
24627          EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) |
24628                  (encoded_align_2.GetEncodingValue() << 4) |
24629                  first.Encode(22, 12) | (rn.GetCode() << 16));
24630          return;
24631        }
24632      }
24633    }
24634  }
24635  if (operand.IsPlainRegister()) {
24636    Register rn = operand.GetBaseRegister();
24637    Alignment align = operand.GetAlignment();
24638    Register rm = operand.GetOffsetRegister();
24639    Dt_size_7 encoded_dt(dt);
24640    Align_align_2 encoded_align_1(align, nreglist);
24641    Align_index_align_2 encoded_align_2(align, nreglist, dt);
24642    if (IsUsingT32()) {
24643      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
24644      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24645          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24646           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
24647           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
24648          !rm.IsPC() && !rm.IsSP()) {
24649        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24650          const DRegister& first = nreglist.GetFirstDRegister();
24651          uint32_t len_encoding;
24652          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
24653            len_encoding = 0x8;
24654          }
24655          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
24656            len_encoding = 0x9;
24657          }
24658          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
24659            len_encoding = 0x3;
24660          }
24661          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
24662                     (encoded_align_1.GetEncodingValue() << 4) |
24663                     first.Encode(22, 12) | (len_encoding << 8) |
24664                     (rn.GetCode() << 16) | rm.GetCode());
24665          AdvanceIT();
24666          return;
24667        }
24668      }
24669      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
24670      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24671          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24672           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
24673          !rm.IsPC() && !rm.IsSP()) {
24674        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24675          const DRegister& first = nreglist.GetFirstDRegister();
24676          EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) |
24677                     (encoded_align_2.GetEncodingValue() << 4) |
24678                     first.Encode(22, 12) | (rn.GetCode() << 16) |
24679                     rm.GetCode());
24680          AdvanceIT();
24681          return;
24682        }
24683      }
24684    } else {
24685      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
24686      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24687          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24688           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
24689           (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
24690          !rm.IsPC() && !rm.IsSP()) {
24691        if (cond.Is(al)) {
24692          const DRegister& first = nreglist.GetFirstDRegister();
24693          uint32_t len_encoding;
24694          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
24695            len_encoding = 0x8;
24696          }
24697          if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
24698            len_encoding = 0x9;
24699          }
24700          if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
24701            len_encoding = 0x3;
24702          }
24703          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
24704                  (encoded_align_1.GetEncodingValue() << 4) |
24705                  first.Encode(22, 12) | (len_encoding << 8) |
24706                  (rn.GetCode() << 16) | rm.GetCode());
24707          return;
24708        }
24709      }
24710      // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
24711      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24712          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
24713           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
24714          !rm.IsPC() && !rm.IsSP()) {
24715        if (cond.Is(al)) {
24716          const DRegister& first = nreglist.GetFirstDRegister();
24717          EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) |
24718                  (encoded_align_2.GetEncodingValue() << 4) |
24719                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
24720          return;
24721        }
24722      }
24723    }
24724  }
24725  Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand);
24726}
24727
24728void Assembler::vst3(Condition cond,
24729                     DataType dt,
24730                     const NeonRegisterList& nreglist,
24731                     const AlignedMemOperand& operand) {
24732  CheckIT(cond);
24733  if (operand.IsImmediateZero()) {
24734    Register rn = operand.GetBaseRegister();
24735    Alignment align = operand.GetAlignment();
24736    Dt_size_7 encoded_dt(dt);
24737    Align_align_3 encoded_align_1(align);
24738    if (IsUsingT32()) {
24739      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24740      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24741          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24742           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24743          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
24744          ((!rn.IsPC()) || AllowUnpredictable())) {
24745        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24746          const DRegister& first = nreglist.GetFirstDRegister();
24747          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
24748          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
24749                     (encoded_align_1.GetEncodingValue() << 4) |
24750                     first.Encode(22, 12) | (len_encoding << 8) |
24751                     (rn.GetCode() << 16));
24752          AdvanceIT();
24753          return;
24754        }
24755      }
24756      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24757      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24758          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24759           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24760          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
24761          ((!rn.IsPC()) || AllowUnpredictable())) {
24762        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24763          const DRegister& first = nreglist.GetFirstDRegister();
24764          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
24765          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
24766                     (encoded_align_1.GetEncodingValue() << 4) |
24767                     first.Encode(22, 12) | (len_encoding << 8) |
24768                     (rn.GetCode() << 16));
24769          AdvanceIT();
24770          return;
24771        }
24772      }
24773    } else {
24774      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
24775      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24776          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24777           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24778          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
24779          ((!rn.IsPC()) || AllowUnpredictable())) {
24780        if (cond.Is(al)) {
24781          const DRegister& first = nreglist.GetFirstDRegister();
24782          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
24783          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
24784                  (encoded_align_1.GetEncodingValue() << 4) |
24785                  first.Encode(22, 12) | (len_encoding << 8) |
24786                  (rn.GetCode() << 16));
24787          return;
24788        }
24789      }
24790      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
24791      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24792          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24793           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24794          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
24795          ((!rn.IsPC()) || AllowUnpredictable())) {
24796        if (cond.Is(al)) {
24797          const DRegister& first = nreglist.GetFirstDRegister();
24798          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
24799          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
24800                  (encoded_align_1.GetEncodingValue() << 4) |
24801                  first.Encode(22, 12) | (len_encoding << 8) |
24802                  (rn.GetCode() << 16));
24803          return;
24804        }
24805      }
24806    }
24807  }
24808  if (operand.IsPlainRegister()) {
24809    Register rn = operand.GetBaseRegister();
24810    Alignment align = operand.GetAlignment();
24811    Register rm = operand.GetOffsetRegister();
24812    Dt_size_7 encoded_dt(dt);
24813    Align_align_3 encoded_align_1(align);
24814    if (IsUsingT32()) {
24815      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
24816      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24817          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24818           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24819          !rm.IsPC() && !rm.IsSP()) {
24820        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24821          const DRegister& first = nreglist.GetFirstDRegister();
24822          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
24823          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
24824                     (encoded_align_1.GetEncodingValue() << 4) |
24825                     first.Encode(22, 12) | (len_encoding << 8) |
24826                     (rn.GetCode() << 16) | rm.GetCode());
24827          AdvanceIT();
24828          return;
24829        }
24830      }
24831    } else {
24832      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
24833      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24834          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24835           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24836          !rm.IsPC() && !rm.IsSP()) {
24837        if (cond.Is(al)) {
24838          const DRegister& first = nreglist.GetFirstDRegister();
24839          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
24840          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
24841                  (encoded_align_1.GetEncodingValue() << 4) |
24842                  first.Encode(22, 12) | (len_encoding << 8) |
24843                  (rn.GetCode() << 16) | rm.GetCode());
24844          return;
24845        }
24846      }
24847    }
24848  }
24849  Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
24850}
24851
24852void Assembler::vst3(Condition cond,
24853                     DataType dt,
24854                     const NeonRegisterList& nreglist,
24855                     const MemOperand& operand) {
24856  CheckIT(cond);
24857  if (operand.IsImmediateZero()) {
24858    Register rn = operand.GetBaseRegister();
24859    Dt_size_7 encoded_dt(dt);
24860    Index_1 encoded_align_1(nreglist, dt);
24861    if (IsUsingT32()) {
24862      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
24863      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24864          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24865           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24866          (operand.GetAddrMode() == Offset) &&
24867          ((!rn.IsPC()) || AllowUnpredictable())) {
24868        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24869          const DRegister& first = nreglist.GetFirstDRegister();
24870          EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) |
24871                     (encoded_align_1.GetEncodingValue() << 4) |
24872                     first.Encode(22, 12) | (rn.GetCode() << 16));
24873          AdvanceIT();
24874          return;
24875        }
24876      }
24877      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
24878      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24879          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24880           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24881          (operand.GetAddrMode() == PreIndex) &&
24882          ((!rn.IsPC()) || AllowUnpredictable())) {
24883        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24884          const DRegister& first = nreglist.GetFirstDRegister();
24885          EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) |
24886                     (encoded_align_1.GetEncodingValue() << 4) |
24887                     first.Encode(22, 12) | (rn.GetCode() << 16));
24888          AdvanceIT();
24889          return;
24890        }
24891      }
24892    } else {
24893      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
24894      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24895          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24896           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24897          (operand.GetAddrMode() == Offset) &&
24898          ((!rn.IsPC()) || AllowUnpredictable())) {
24899        if (cond.Is(al)) {
24900          const DRegister& first = nreglist.GetFirstDRegister();
24901          EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) |
24902                  (encoded_align_1.GetEncodingValue() << 4) |
24903                  first.Encode(22, 12) | (rn.GetCode() << 16));
24904          return;
24905        }
24906      }
24907      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
24908      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24909          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24910           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24911          (operand.GetAddrMode() == PreIndex) &&
24912          ((!rn.IsPC()) || AllowUnpredictable())) {
24913        if (cond.Is(al)) {
24914          const DRegister& first = nreglist.GetFirstDRegister();
24915          EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) |
24916                  (encoded_align_1.GetEncodingValue() << 4) |
24917                  first.Encode(22, 12) | (rn.GetCode() << 16));
24918          return;
24919        }
24920      }
24921    }
24922  }
24923  if (operand.IsPlainRegister()) {
24924    Register rn = operand.GetBaseRegister();
24925    Sign sign = operand.GetSign();
24926    Register rm = operand.GetOffsetRegister();
24927    Dt_size_7 encoded_dt(dt);
24928    Index_1 encoded_align_1(nreglist, dt);
24929    if (IsUsingT32()) {
24930      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
24931      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24932          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24933           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24934          sign.IsPlus() && (operand.GetAddrMode() == PostIndex)) {
24935        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24936          const DRegister& first = nreglist.GetFirstDRegister();
24937          EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) |
24938                     (encoded_align_1.GetEncodingValue() << 4) |
24939                     first.Encode(22, 12) | (rn.GetCode() << 16) |
24940                     rm.GetCode());
24941          AdvanceIT();
24942          return;
24943        }
24944      }
24945    } else {
24946      // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
24947      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
24948          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
24949           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
24950          sign.IsPlus() && (operand.GetAddrMode() == PostIndex)) {
24951        if (cond.Is(al)) {
24952          const DRegister& first = nreglist.GetFirstDRegister();
24953          EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) |
24954                  (encoded_align_1.GetEncodingValue() << 4) |
24955                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
24956          return;
24957        }
24958      }
24959    }
24960  }
24961  Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
24962}
24963
24964void Assembler::vst4(Condition cond,
24965                     DataType dt,
24966                     const NeonRegisterList& nreglist,
24967                     const AlignedMemOperand& operand) {
24968  CheckIT(cond);
24969  if (operand.IsImmediateZero()) {
24970    Register rn = operand.GetBaseRegister();
24971    Alignment align = operand.GetAlignment();
24972    Dt_size_7 encoded_dt(dt);
24973    Align_align_4 encoded_align_1(align);
24974    Align_index_align_3 encoded_align_2(align, nreglist, dt);
24975    if (IsUsingT32()) {
24976      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24977      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24978          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
24979           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
24980          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
24981          ((!rn.IsPC()) || AllowUnpredictable())) {
24982        if (cond.Is(al) || AllowStronglyDiscouraged()) {
24983          const DRegister& first = nreglist.GetFirstDRegister();
24984          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
24985          EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
24986                     (encoded_align_1.GetEncodingValue() << 4) |
24987                     first.Encode(22, 12) | (len_encoding << 8) |
24988                     (rn.GetCode() << 16));
24989          AdvanceIT();
24990          return;
24991        }
24992      }
24993      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24994      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24995          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
24996           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
24997          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
24998          ((!rn.IsPC()) || AllowUnpredictable())) {
24999        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25000          const DRegister& first = nreglist.GetFirstDRegister();
25001          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25002          EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
25003                     (encoded_align_1.GetEncodingValue() << 4) |
25004                     first.Encode(22, 12) | (len_encoding << 8) |
25005                     (rn.GetCode() << 16));
25006          AdvanceIT();
25007          return;
25008        }
25009      }
25010      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25011      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25012          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25013           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25014          (operand.GetAddrMode() == Offset) && encoded_align_2.IsValid() &&
25015          ((!rn.IsPC()) || AllowUnpredictable())) {
25016        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25017          const DRegister& first = nreglist.GetFirstDRegister();
25018          EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) |
25019                     (encoded_align_2.GetEncodingValue() << 4) |
25020                     first.Encode(22, 12) | (rn.GetCode() << 16));
25021          AdvanceIT();
25022          return;
25023        }
25024      }
25025      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25026      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25027          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25028           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25029          (operand.GetAddrMode() == PostIndex) && encoded_align_2.IsValid() &&
25030          ((!rn.IsPC()) || AllowUnpredictable())) {
25031        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25032          const DRegister& first = nreglist.GetFirstDRegister();
25033          EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) |
25034                     (encoded_align_2.GetEncodingValue() << 4) |
25035                     first.Encode(22, 12) | (rn.GetCode() << 16));
25036          AdvanceIT();
25037          return;
25038        }
25039      }
25040    } else {
25041      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25042      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25043          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25044           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25045          (operand.GetAddrMode() == Offset) && encoded_align_1.IsValid() &&
25046          ((!rn.IsPC()) || AllowUnpredictable())) {
25047        if (cond.Is(al)) {
25048          const DRegister& first = nreglist.GetFirstDRegister();
25049          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25050          EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
25051                  (encoded_align_1.GetEncodingValue() << 4) |
25052                  first.Encode(22, 12) | (len_encoding << 8) |
25053                  (rn.GetCode() << 16));
25054          return;
25055        }
25056      }
25057      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25058      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25059          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25060           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25061          (operand.GetAddrMode() == PostIndex) && encoded_align_1.IsValid() &&
25062          ((!rn.IsPC()) || AllowUnpredictable())) {
25063        if (cond.Is(al)) {
25064          const DRegister& first = nreglist.GetFirstDRegister();
25065          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25066          EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
25067                  (encoded_align_1.GetEncodingValue() << 4) |
25068                  first.Encode(22, 12) | (len_encoding << 8) |
25069                  (rn.GetCode() << 16));
25070          return;
25071        }
25072      }
25073      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25074      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25075          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25076           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25077          (operand.GetAddrMode() == Offset) && encoded_align_2.IsValid() &&
25078          ((!rn.IsPC()) || AllowUnpredictable())) {
25079        if (cond.Is(al)) {
25080          const DRegister& first = nreglist.GetFirstDRegister();
25081          EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) |
25082                  (encoded_align_2.GetEncodingValue() << 4) |
25083                  first.Encode(22, 12) | (rn.GetCode() << 16));
25084          return;
25085        }
25086      }
25087      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25088      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25089          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25090           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25091          (operand.GetAddrMode() == PostIndex) && encoded_align_2.IsValid() &&
25092          ((!rn.IsPC()) || AllowUnpredictable())) {
25093        if (cond.Is(al)) {
25094          const DRegister& first = nreglist.GetFirstDRegister();
25095          EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) |
25096                  (encoded_align_2.GetEncodingValue() << 4) |
25097                  first.Encode(22, 12) | (rn.GetCode() << 16));
25098          return;
25099        }
25100      }
25101    }
25102  }
25103  if (operand.IsPlainRegister()) {
25104    Register rn = operand.GetBaseRegister();
25105    Alignment align = operand.GetAlignment();
25106    Register rm = operand.GetOffsetRegister();
25107    Dt_size_7 encoded_dt(dt);
25108    Align_align_4 encoded_align_1(align);
25109    Align_index_align_3 encoded_align_2(align, nreglist, dt);
25110    if (IsUsingT32()) {
25111      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25112      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25113          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25114           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25115          !rm.IsPC() && !rm.IsSP()) {
25116        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25117          const DRegister& first = nreglist.GetFirstDRegister();
25118          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25119          EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
25120                     (encoded_align_1.GetEncodingValue() << 4) |
25121                     first.Encode(22, 12) | (len_encoding << 8) |
25122                     (rn.GetCode() << 16) | rm.GetCode());
25123          AdvanceIT();
25124          return;
25125        }
25126      }
25127      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25128      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25129          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25130           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25131          !rm.IsPC() && !rm.IsSP()) {
25132        if (cond.Is(al) || AllowStronglyDiscouraged()) {
25133          const DRegister& first = nreglist.GetFirstDRegister();
25134          EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) |
25135                     (encoded_align_2.GetEncodingValue() << 4) |
25136                     first.Encode(22, 12) | (rn.GetCode() << 16) |
25137                     rm.GetCode());
25138          AdvanceIT();
25139          return;
25140        }
25141      }
25142    } else {
25143      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25144      if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25145          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25146           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25147          !rm.IsPC() && !rm.IsSP()) {
25148        if (cond.Is(al)) {
25149          const DRegister& first = nreglist.GetFirstDRegister();
25150          uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25151          EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
25152                  (encoded_align_1.GetEncodingValue() << 4) |
25153                  first.Encode(22, 12) | (len_encoding << 8) |
25154                  (rn.GetCode() << 16) | rm.GetCode());
25155          return;
25156        }
25157      }
25158      // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25159      if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25160          ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25161           (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25162          !rm.IsPC() && !rm.IsSP()) {
25163        if (cond.Is(al)) {
25164          const DRegister& first = nreglist.GetFirstDRegister();
25165          EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) |
25166                  (encoded_align_2.GetEncodingValue() << 4) |
25167                  first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
25168          return;
25169        }
25170      }
25171    }
25172  }
25173  Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand);
25174}
25175
25176void Assembler::vstm(Condition cond,
25177                     DataType dt,
25178                     Register rn,
25179                     WriteBack write_back,
25180                     DRegisterList dreglist) {
25181  CheckIT(cond);
25182  USE(dt);
25183  if (IsUsingT32()) {
25184    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
25185    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25186      const DRegister& dreg = dreglist.GetFirstDRegister();
25187      unsigned len = dreglist.GetLength() * 2;
25188      EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
25189                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25190                 (len & 0xff));
25191      AdvanceIT();
25192      return;
25193    }
25194  } else {
25195    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
25196    if (cond.IsNotNever() &&
25197        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25198      const DRegister& dreg = dreglist.GetFirstDRegister();
25199      unsigned len = dreglist.GetLength() * 2;
25200      EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25201              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25202              (len & 0xff));
25203      return;
25204    }
25205  }
25206  Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist);
25207}
25208
25209void Assembler::vstm(Condition cond,
25210                     DataType dt,
25211                     Register rn,
25212                     WriteBack write_back,
25213                     SRegisterList sreglist) {
25214  CheckIT(cond);
25215  USE(dt);
25216  if (IsUsingT32()) {
25217    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
25218    const SRegister& sreg = sreglist.GetFirstSRegister();
25219    unsigned len = sreglist.GetLength();
25220    EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
25221               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25222               (len & 0xff));
25223    AdvanceIT();
25224    return;
25225  } else {
25226    // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
25227    if (cond.IsNotNever()) {
25228      const SRegister& sreg = sreglist.GetFirstSRegister();
25229      unsigned len = sreglist.GetLength();
25230      EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25231              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25232              (len & 0xff));
25233      return;
25234    }
25235  }
25236  Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist);
25237}
25238
25239void Assembler::vstmdb(Condition cond,
25240                       DataType dt,
25241                       Register rn,
25242                       WriteBack write_back,
25243                       DRegisterList dreglist) {
25244  CheckIT(cond);
25245  USE(dt);
25246  if (IsUsingT32()) {
25247    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
25248    if (write_back.DoesWriteBack() &&
25249        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25250      const DRegister& dreg = dreglist.GetFirstDRegister();
25251      unsigned len = dreglist.GetLength() * 2;
25252      EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
25253                 (len & 0xff));
25254      AdvanceIT();
25255      return;
25256    }
25257  } else {
25258    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
25259    if (write_back.DoesWriteBack() && cond.IsNotNever() &&
25260        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25261      const DRegister& dreg = dreglist.GetFirstDRegister();
25262      unsigned len = dreglist.GetLength() * 2;
25263      EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25264              dreg.Encode(22, 12) | (len & 0xff));
25265      return;
25266    }
25267  }
25268  Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist);
25269}
25270
25271void Assembler::vstmdb(Condition cond,
25272                       DataType dt,
25273                       Register rn,
25274                       WriteBack write_back,
25275                       SRegisterList sreglist) {
25276  CheckIT(cond);
25277  USE(dt);
25278  if (IsUsingT32()) {
25279    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
25280    if (write_back.DoesWriteBack()) {
25281      const SRegister& sreg = sreglist.GetFirstSRegister();
25282      unsigned len = sreglist.GetLength();
25283      EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
25284                 (len & 0xff));
25285      AdvanceIT();
25286      return;
25287    }
25288  } else {
25289    // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
25290    if (write_back.DoesWriteBack() && cond.IsNotNever()) {
25291      const SRegister& sreg = sreglist.GetFirstSRegister();
25292      unsigned len = sreglist.GetLength();
25293      EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25294              sreg.Encode(22, 12) | (len & 0xff));
25295      return;
25296    }
25297  }
25298  Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist);
25299}
25300
25301void Assembler::vstmia(Condition cond,
25302                       DataType dt,
25303                       Register rn,
25304                       WriteBack write_back,
25305                       DRegisterList dreglist) {
25306  CheckIT(cond);
25307  USE(dt);
25308  if (IsUsingT32()) {
25309    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
25310    if ((((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25311      const DRegister& dreg = dreglist.GetFirstDRegister();
25312      unsigned len = dreglist.GetLength() * 2;
25313      EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
25314                 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25315                 (len & 0xff));
25316      AdvanceIT();
25317      return;
25318    }
25319  } else {
25320    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
25321    if (cond.IsNotNever() &&
25322        (((dreglist.GetLength() <= 16)) || AllowUnpredictable())) {
25323      const DRegister& dreg = dreglist.GetFirstDRegister();
25324      unsigned len = dreglist.GetLength() * 2;
25325      EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25326              (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25327              (len & 0xff));
25328      return;
25329    }
25330  }
25331  Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist);
25332}
25333
25334void Assembler::vstmia(Condition cond,
25335                       DataType dt,
25336                       Register rn,
25337                       WriteBack write_back,
25338                       SRegisterList sreglist) {
25339  CheckIT(cond);
25340  USE(dt);
25341  if (IsUsingT32()) {
25342    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
25343    const SRegister& sreg = sreglist.GetFirstSRegister();
25344    unsigned len = sreglist.GetLength();
25345    EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
25346               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25347               (len & 0xff));
25348    AdvanceIT();
25349    return;
25350  } else {
25351    // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
25352    if (cond.IsNotNever()) {
25353      const SRegister& sreg = sreglist.GetFirstSRegister();
25354      unsigned len = sreglist.GetLength();
25355      EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25356              (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25357              (len & 0xff));
25358      return;
25359    }
25360  }
25361  Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist);
25362}
25363
25364void Assembler::vstr(Condition cond,
25365                     DataType dt,
25366                     DRegister rd,
25367                     const MemOperand& operand) {
25368  CheckIT(cond);
25369  if (operand.IsImmediate()) {
25370    Register rn = operand.GetBaseRegister();
25371    int32_t offset = operand.GetOffsetImmediate();
25372    if (IsUsingT32()) {
25373      // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
25374      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
25375          ((offset % 4) == 0) && (operand.GetAddrMode() == Offset)) {
25376        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25377        uint32_t offset_ = abs(offset) >> 2;
25378        EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
25379                   offset_ | (sign << 23));
25380        AdvanceIT();
25381        return;
25382      }
25383    } else {
25384      // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
25385      if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
25386          ((offset % 4) == 0) && (operand.GetAddrMode() == Offset) &&
25387          cond.IsNotNever()) {
25388        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25389        uint32_t offset_ = abs(offset) >> 2;
25390        EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25391                (rn.GetCode() << 16) | offset_ | (sign << 23));
25392        return;
25393      }
25394    }
25395  }
25396  Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
25397}
25398
25399void Assembler::vstr(Condition cond,
25400                     DataType dt,
25401                     SRegister rd,
25402                     const MemOperand& operand) {
25403  CheckIT(cond);
25404  if (operand.IsImmediate()) {
25405    Register rn = operand.GetBaseRegister();
25406    int32_t offset = operand.GetOffsetImmediate();
25407    if (IsUsingT32()) {
25408      // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
25409      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
25410          ((offset % 4) == 0) && (operand.GetAddrMode() == Offset)) {
25411        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25412        uint32_t offset_ = abs(offset) >> 2;
25413        EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
25414                   offset_ | (sign << 23));
25415        AdvanceIT();
25416        return;
25417      }
25418    } else {
25419      // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
25420      if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
25421          ((offset % 4) == 0) && (operand.GetAddrMode() == Offset) &&
25422          cond.IsNotNever()) {
25423        uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25424        uint32_t offset_ = abs(offset) >> 2;
25425        EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25426                (rn.GetCode() << 16) | offset_ | (sign << 23));
25427        return;
25428      }
25429    }
25430  }
25431  Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
25432}
25433
25434void Assembler::vsub(
25435    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25436  CheckIT(cond);
25437  Dt_size_2 encoded_dt(dt);
25438  if (IsUsingT32()) {
25439    // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
25440    if (dt.Is(F32)) {
25441      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25442        EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25443                   rm.Encode(5, 0));
25444        AdvanceIT();
25445        return;
25446      }
25447    }
25448    // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
25449    if (dt.Is(F64)) {
25450      EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25451                 rm.Encode(5, 0));
25452      AdvanceIT();
25453      return;
25454    }
25455    // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
25456    if (encoded_dt.IsValid()) {
25457      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25458        EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) |
25459                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25460        AdvanceIT();
25461        return;
25462      }
25463    }
25464  } else {
25465    // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
25466    if (dt.Is(F32)) {
25467      if (cond.Is(al)) {
25468        EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25469                rm.Encode(5, 0));
25470        return;
25471      }
25472    }
25473    // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
25474    if (dt.Is(F64) && cond.IsNotNever()) {
25475      EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25476              rn.Encode(7, 16) | rm.Encode(5, 0));
25477      return;
25478    }
25479    // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
25480    if (encoded_dt.IsValid()) {
25481      if (cond.Is(al)) {
25482        EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) |
25483                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25484        return;
25485      }
25486    }
25487  }
25488  Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
25489}
25490
25491void Assembler::vsub(
25492    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
25493  CheckIT(cond);
25494  Dt_size_2 encoded_dt(dt);
25495  if (IsUsingT32()) {
25496    // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
25497    if (dt.Is(F32)) {
25498      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25499        EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25500                   rm.Encode(5, 0));
25501        AdvanceIT();
25502        return;
25503      }
25504    }
25505    // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
25506    if (encoded_dt.IsValid()) {
25507      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25508        EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) |
25509                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25510        AdvanceIT();
25511        return;
25512      }
25513    }
25514  } else {
25515    // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
25516    if (dt.Is(F32)) {
25517      if (cond.Is(al)) {
25518        EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25519                rm.Encode(5, 0));
25520        return;
25521      }
25522    }
25523    // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
25524    if (encoded_dt.IsValid()) {
25525      if (cond.Is(al)) {
25526        EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) |
25527                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25528        return;
25529      }
25530    }
25531  }
25532  Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
25533}
25534
25535void Assembler::vsub(
25536    Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
25537  CheckIT(cond);
25538  if (IsUsingT32()) {
25539    // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
25540    if (dt.Is(F32)) {
25541      EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25542                 rm.Encode(5, 0));
25543      AdvanceIT();
25544      return;
25545    }
25546  } else {
25547    // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
25548    if (dt.Is(F32) && cond.IsNotNever()) {
25549      EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25550              rn.Encode(7, 16) | rm.Encode(5, 0));
25551      return;
25552    }
25553  }
25554  Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
25555}
25556
25557void Assembler::vsubhn(
25558    Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
25559  CheckIT(cond);
25560  Dt_size_3 encoded_dt(dt);
25561  if (IsUsingT32()) {
25562    // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
25563    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
25564      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25565        EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) |
25566                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25567        AdvanceIT();
25568        return;
25569      }
25570    }
25571  } else {
25572    // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
25573    if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
25574      if (cond.Is(al)) {
25575        EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) |
25576                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25577        return;
25578      }
25579    }
25580  }
25581  Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm);
25582}
25583
25584void Assembler::vsubl(
25585    Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
25586  CheckIT(cond);
25587  Dt_U_size_1 encoded_dt(dt);
25588  if (IsUsingT32()) {
25589    // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
25590    if (encoded_dt.IsValid()) {
25591      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25592        EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25593                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
25594                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25595        AdvanceIT();
25596        return;
25597      }
25598    }
25599  } else {
25600    // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
25601    if (encoded_dt.IsValid()) {
25602      if (cond.Is(al)) {
25603        EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25604                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
25605                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25606        return;
25607      }
25608    }
25609  }
25610  Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm);
25611}
25612
25613void Assembler::vsubw(
25614    Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
25615  CheckIT(cond);
25616  Dt_U_size_1 encoded_dt(dt);
25617  if (IsUsingT32()) {
25618    // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
25619    if (encoded_dt.IsValid()) {
25620      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25621        EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25622                   ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
25623                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25624        AdvanceIT();
25625        return;
25626      }
25627    }
25628  } else {
25629    // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
25630    if (encoded_dt.IsValid()) {
25631      if (cond.Is(al)) {
25632        EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25633                ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
25634                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25635        return;
25636      }
25637    }
25638  }
25639  Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm);
25640}
25641
25642void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
25643  CheckIT(cond);
25644  USE(dt);
25645  if (IsUsingT32()) {
25646    // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
25647    if (cond.Is(al) || AllowStronglyDiscouraged()) {
25648      EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
25649      AdvanceIT();
25650      return;
25651    }
25652  } else {
25653    // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
25654    if (cond.Is(al)) {
25655      EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
25656      return;
25657    }
25658  }
25659  Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
25660}
25661
25662void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
25663  CheckIT(cond);
25664  USE(dt);
25665  if (IsUsingT32()) {
25666    // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
25667    if (cond.Is(al) || AllowStronglyDiscouraged()) {
25668      EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
25669      AdvanceIT();
25670      return;
25671    }
25672  } else {
25673    // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
25674    if (cond.Is(al)) {
25675      EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
25676      return;
25677    }
25678  }
25679  Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
25680}
25681
25682void Assembler::vtbl(Condition cond,
25683                     DataType dt,
25684                     DRegister rd,
25685                     const NeonRegisterList& nreglist,
25686                     DRegister rm) {
25687  CheckIT(cond);
25688  if (IsUsingT32()) {
25689    // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
25690    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
25691        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
25692      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25693        const DRegister& first = nreglist.GetFirstDRegister();
25694        uint32_t len_encoding = nreglist.GetLength() - 1;
25695        EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
25696                   (len_encoding << 8) | rm.Encode(5, 0));
25697        AdvanceIT();
25698        return;
25699      }
25700    }
25701  } else {
25702    // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
25703    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
25704        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
25705      if (cond.Is(al)) {
25706        const DRegister& first = nreglist.GetFirstDRegister();
25707        uint32_t len_encoding = nreglist.GetLength() - 1;
25708        EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
25709                (len_encoding << 8) | rm.Encode(5, 0));
25710        return;
25711      }
25712    }
25713  }
25714  Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm);
25715}
25716
25717void Assembler::vtbx(Condition cond,
25718                     DataType dt,
25719                     DRegister rd,
25720                     const NeonRegisterList& nreglist,
25721                     DRegister rm) {
25722  CheckIT(cond);
25723  if (IsUsingT32()) {
25724    // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
25725    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
25726        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
25727      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25728        const DRegister& first = nreglist.GetFirstDRegister();
25729        uint32_t len_encoding = nreglist.GetLength() - 1;
25730        EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
25731                   (len_encoding << 8) | rm.Encode(5, 0));
25732        AdvanceIT();
25733        return;
25734      }
25735    }
25736  } else {
25737    // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
25738    if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
25739        (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
25740      if (cond.Is(al)) {
25741        const DRegister& first = nreglist.GetFirstDRegister();
25742        uint32_t len_encoding = nreglist.GetLength() - 1;
25743        EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
25744                (len_encoding << 8) | rm.Encode(5, 0));
25745        return;
25746      }
25747    }
25748  }
25749  Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm);
25750}
25751
25752void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) {
25753  CheckIT(cond);
25754  Dt_size_7 encoded_dt(dt);
25755  if (IsUsingT32()) {
25756    // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
25757    if (encoded_dt.IsValid()) {
25758      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25759        EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) |
25760                   rd.Encode(22, 12) | rm.Encode(5, 0));
25761        AdvanceIT();
25762        return;
25763      }
25764    }
25765  } else {
25766    // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
25767    if (encoded_dt.IsValid()) {
25768      if (cond.Is(al)) {
25769        EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) |
25770                rd.Encode(22, 12) | rm.Encode(5, 0));
25771        return;
25772      }
25773    }
25774  }
25775  Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
25776}
25777
25778void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) {
25779  CheckIT(cond);
25780  Dt_size_7 encoded_dt(dt);
25781  if (IsUsingT32()) {
25782    // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
25783    if (encoded_dt.IsValid()) {
25784      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25785        EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) |
25786                   rd.Encode(22, 12) | rm.Encode(5, 0));
25787        AdvanceIT();
25788        return;
25789      }
25790    }
25791  } else {
25792    // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
25793    if (encoded_dt.IsValid()) {
25794      if (cond.Is(al)) {
25795        EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) |
25796                rd.Encode(22, 12) | rm.Encode(5, 0));
25797        return;
25798      }
25799    }
25800  }
25801  Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
25802}
25803
25804void Assembler::vtst(
25805    Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25806  CheckIT(cond);
25807  Dt_size_7 encoded_dt(dt);
25808  if (IsUsingT32()) {
25809    // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
25810    if (encoded_dt.IsValid()) {
25811      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25812        EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) |
25813                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25814        AdvanceIT();
25815        return;
25816      }
25817    }
25818  } else {
25819    // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
25820    if (encoded_dt.IsValid()) {
25821      if (cond.Is(al)) {
25822        EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) |
25823                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25824        return;
25825      }
25826    }
25827  }
25828  Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
25829}
25830
25831void Assembler::vtst(
25832    Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
25833  CheckIT(cond);
25834  Dt_size_7 encoded_dt(dt);
25835  if (IsUsingT32()) {
25836    // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
25837    if (encoded_dt.IsValid()) {
25838      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25839        EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) |
25840                   rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25841        AdvanceIT();
25842        return;
25843      }
25844    }
25845  } else {
25846    // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
25847    if (encoded_dt.IsValid()) {
25848      if (cond.Is(al)) {
25849        EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) |
25850                rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25851        return;
25852      }
25853    }
25854  }
25855  Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
25856}
25857
25858void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
25859  CheckIT(cond);
25860  Dt_size_15 encoded_dt(dt);
25861  if (IsUsingT32()) {
25862    // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
25863    if (encoded_dt.IsValid()) {
25864      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25865        EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) |
25866                   rd.Encode(22, 12) | rm.Encode(5, 0));
25867        AdvanceIT();
25868        return;
25869      }
25870    }
25871    // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
25872    if (dt.Is(Untyped32)) {
25873      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25874        EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
25875        AdvanceIT();
25876        return;
25877      }
25878    }
25879  } else {
25880    // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
25881    if (encoded_dt.IsValid()) {
25882      if (cond.Is(al)) {
25883        EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) |
25884                rd.Encode(22, 12) | rm.Encode(5, 0));
25885        return;
25886      }
25887    }
25888    // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
25889    if (dt.Is(Untyped32)) {
25890      if (cond.Is(al)) {
25891        EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
25892        return;
25893      }
25894    }
25895  }
25896  Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
25897}
25898
25899void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
25900  CheckIT(cond);
25901  Dt_size_7 encoded_dt(dt);
25902  if (IsUsingT32()) {
25903    // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
25904    if (encoded_dt.IsValid()) {
25905      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25906        EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) |
25907                   rd.Encode(22, 12) | rm.Encode(5, 0));
25908        AdvanceIT();
25909        return;
25910      }
25911    }
25912  } else {
25913    // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
25914    if (encoded_dt.IsValid()) {
25915      if (cond.Is(al)) {
25916        EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) |
25917                rd.Encode(22, 12) | rm.Encode(5, 0));
25918        return;
25919      }
25920    }
25921  }
25922  Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
25923}
25924
25925void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) {
25926  CheckIT(cond);
25927  Dt_size_15 encoded_dt(dt);
25928  if (IsUsingT32()) {
25929    // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
25930    if (encoded_dt.IsValid()) {
25931      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25932        EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) |
25933                   rd.Encode(22, 12) | rm.Encode(5, 0));
25934        AdvanceIT();
25935        return;
25936      }
25937    }
25938    // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
25939    if (dt.Is(Untyped32)) {
25940      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25941        EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
25942        AdvanceIT();
25943        return;
25944      }
25945    }
25946  } else {
25947    // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
25948    if (encoded_dt.IsValid()) {
25949      if (cond.Is(al)) {
25950        EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) |
25951                rd.Encode(22, 12) | rm.Encode(5, 0));
25952        return;
25953      }
25954    }
25955    // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
25956    if (dt.Is(Untyped32)) {
25957      if (cond.Is(al)) {
25958        EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
25959        return;
25960      }
25961    }
25962  }
25963  Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
25964}
25965
25966void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) {
25967  CheckIT(cond);
25968  Dt_size_7 encoded_dt(dt);
25969  if (IsUsingT32()) {
25970    // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
25971    if (encoded_dt.IsValid()) {
25972      if (cond.Is(al) || AllowStronglyDiscouraged()) {
25973        EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) |
25974                   rd.Encode(22, 12) | rm.Encode(5, 0));
25975        AdvanceIT();
25976        return;
25977      }
25978    }
25979  } else {
25980    // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
25981    if (encoded_dt.IsValid()) {
25982      if (cond.Is(al)) {
25983        EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) |
25984                rd.Encode(22, 12) | rm.Encode(5, 0));
25985        return;
25986      }
25987    }
25988  }
25989  Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
25990}
25991
25992void Assembler::yield(Condition cond, EncodingSize size) {
25993  CheckIT(cond);
25994  if (IsUsingT32()) {
25995    // YIELD{<c>}{<q>} ; T1
25996    if (!size.IsWide()) {
25997      EmitT32_16(0xbf10);
25998      AdvanceIT();
25999      return;
26000    }
26001    // YIELD{<c>}.W ; T2
26002    if (!size.IsNarrow()) {
26003      EmitT32_32(0xf3af8001U);
26004      AdvanceIT();
26005      return;
26006    }
26007  } else {
26008    // YIELD{<c>}{<q>} ; A1
26009    if (cond.IsNotNever()) {
26010      EmitA32(0x0320f001U | (cond.GetCondition() << 28));
26011      return;
26012    }
26013  }
26014  Delegate(kYield, &Assembler::yield, cond, size);
26015}
26016// End of generated code.
26017
26018}  // namespace aarch32
26019}  // namespace vixl
26020