• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017, VIXL authors
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 extern "C" {
28 #include <stdint.h>
29 }
30 
31 #include <cassert>
32 #include <cstdio>
33 #include <cstdlib>
34 #include <cstring>
35 #include <iostream>
36 
37 #include "utils-vixl.h"
38 #include "aarch32/assembler-aarch32.h"
39 #include "aarch32/constants-aarch32.h"
40 #include "aarch32/instructions-aarch32.h"
41 #include "aarch32/operands-aarch32.h"
42 
43 namespace vixl {
44 namespace aarch32 {
45 
EmitT32_16(uint16_t instr)46 void Assembler::EmitT32_16(uint16_t instr) {
47   VIXL_ASSERT(buffer_.Is16bitAligned());
48   buffer_.Emit16(instr);
49 }
50 
51 
EmitT32_32(uint32_t instr)52 void Assembler::EmitT32_32(uint32_t instr) {
53   VIXL_ASSERT(buffer_.Is16bitAligned());
54   buffer_.Emit16(static_cast<uint16_t>(instr >> 16));
55   buffer_.Emit16(static_cast<uint16_t>(instr & 0xffff));
56 }
57 
58 
EmitA32(uint32_t instr)59 void Assembler::EmitA32(uint32_t instr) {
60   VIXL_ASSERT(buffer_.Is32bitAligned());
61   buffer_.Emit32(instr);
62 }
63 
64 
65 #ifdef VIXL_DEBUG
PerformCheckIT(Condition condition)66 void Assembler::PerformCheckIT(Condition condition) {
67   if (it_mask_ == 0) {
68     VIXL_ASSERT(IsUsingA32() || condition.Is(al));
69   } else {
70     VIXL_ASSERT(condition.Is(first_condition_));
71     // For A32, AdavanceIT() is not called by the assembler. We must call it
72     // in order to check that IT instructions are used consistently with
73     // the following conditional instructions.
74     if (IsUsingA32()) AdvanceIT();
75   }
76 }
77 #endif
78 
79 
BindHelper(Label * label)80 void Assembler::BindHelper(Label* label) {
81   VIXL_ASSERT(!label->IsBound());
82   label->SetLocation(this, GetCursorOffset());
83   label->MarkBound();
84 }
85 
Link(uint32_t instr,Location * location,const Location::EmitOperator & op,const ReferenceInfo * info)86 uint32_t Assembler::Link(uint32_t instr,
87                          Location* location,
88                          const Location::EmitOperator& op,
89                          const ReferenceInfo* info) {
90   location->SetReferenced();
91   if (location->IsBound()) {
92     return op.Encode(instr, GetCursorOffset(), location);
93   }
94   location->AddForwardRef(GetCursorOffset(), op, info);
95   return instr;
96 }
97 
98 
99 // Start of generated code.
100 class Dt_L_imm6_1 : public EncodingValue {
101   uint32_t type_;
102 
103  public:
104   explicit Dt_L_imm6_1(DataType dt);
GetTypeEncodingValue() const105   uint32_t GetTypeEncodingValue() const { return type_; }
106 };
107 
Dt_L_imm6_1(DataType dt)108 Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) {
109   switch (dt.GetValue()) {
110     case S8:
111       type_ = 0x0;
112       SetEncodingValue(0x1);
113       break;
114     case U8:
115       type_ = 0x1;
116       SetEncodingValue(0x1);
117       break;
118     case S16:
119       type_ = 0x0;
120       SetEncodingValue(0x2);
121       break;
122     case U16:
123       type_ = 0x1;
124       SetEncodingValue(0x2);
125       break;
126     case S32:
127       type_ = 0x0;
128       SetEncodingValue(0x4);
129       break;
130     case U32:
131       type_ = 0x1;
132       SetEncodingValue(0x4);
133       break;
134     case S64:
135       type_ = 0x0;
136       SetEncodingValue(0x8);
137       break;
138     case U64:
139       type_ = 0x1;
140       SetEncodingValue(0x8);
141       break;
142     default:
143       VIXL_UNREACHABLE();
144       type_ = 0x0;
145       break;
146   }
147 }
148 
149 class Dt_L_imm6_2 : public EncodingValue {
150   uint32_t type_;
151 
152  public:
153   explicit Dt_L_imm6_2(DataType dt);
GetTypeEncodingValue() const154   uint32_t GetTypeEncodingValue() const { return type_; }
155 };
156 
Dt_L_imm6_2(DataType dt)157 Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) {
158   switch (dt.GetValue()) {
159     case S8:
160       type_ = 0x1;
161       SetEncodingValue(0x1);
162       break;
163     case S16:
164       type_ = 0x1;
165       SetEncodingValue(0x2);
166       break;
167     case S32:
168       type_ = 0x1;
169       SetEncodingValue(0x4);
170       break;
171     case S64:
172       type_ = 0x1;
173       SetEncodingValue(0x8);
174       break;
175     default:
176       VIXL_UNREACHABLE();
177       type_ = 0x0;
178       break;
179   }
180 }
181 
182 class Dt_L_imm6_3 : public EncodingValue {
183  public:
184   explicit Dt_L_imm6_3(DataType dt);
185 };
186 
Dt_L_imm6_3(DataType dt)187 Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) {
188   switch (dt.GetValue()) {
189     case I8:
190       SetEncodingValue(0x1);
191       break;
192     case I16:
193       SetEncodingValue(0x2);
194       break;
195     case I32:
196       SetEncodingValue(0x4);
197       break;
198     case I64:
199       SetEncodingValue(0x8);
200       break;
201     default:
202       break;
203   }
204 }
205 
206 class Dt_L_imm6_4 : public EncodingValue {
207  public:
208   explicit Dt_L_imm6_4(DataType dt);
209 };
210 
Dt_L_imm6_4(DataType dt)211 Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) {
212   switch (dt.GetValue()) {
213     case Untyped8:
214       SetEncodingValue(0x1);
215       break;
216     case Untyped16:
217       SetEncodingValue(0x2);
218       break;
219     case Untyped32:
220       SetEncodingValue(0x4);
221       break;
222     case Untyped64:
223       SetEncodingValue(0x8);
224       break;
225     default:
226       break;
227   }
228 }
229 
230 class Dt_imm6_1 : public EncodingValue {
231   uint32_t type_;
232 
233  public:
234   explicit Dt_imm6_1(DataType dt);
GetTypeEncodingValue() const235   uint32_t GetTypeEncodingValue() const { return type_; }
236 };
237 
Dt_imm6_1(DataType dt)238 Dt_imm6_1::Dt_imm6_1(DataType dt) {
239   switch (dt.GetValue()) {
240     case S16:
241       type_ = 0x0;
242       SetEncodingValue(0x1);
243       break;
244     case U16:
245       type_ = 0x1;
246       SetEncodingValue(0x1);
247       break;
248     case S32:
249       type_ = 0x0;
250       SetEncodingValue(0x2);
251       break;
252     case U32:
253       type_ = 0x1;
254       SetEncodingValue(0x2);
255       break;
256     case S64:
257       type_ = 0x0;
258       SetEncodingValue(0x4);
259       break;
260     case U64:
261       type_ = 0x1;
262       SetEncodingValue(0x4);
263       break;
264     default:
265       VIXL_UNREACHABLE();
266       type_ = 0x0;
267       break;
268   }
269 }
270 
271 class Dt_imm6_2 : public EncodingValue {
272   uint32_t type_;
273 
274  public:
275   explicit Dt_imm6_2(DataType dt);
GetTypeEncodingValue() const276   uint32_t GetTypeEncodingValue() const { return type_; }
277 };
278 
Dt_imm6_2(DataType dt)279 Dt_imm6_2::Dt_imm6_2(DataType dt) {
280   switch (dt.GetValue()) {
281     case S16:
282       type_ = 0x1;
283       SetEncodingValue(0x1);
284       break;
285     case S32:
286       type_ = 0x1;
287       SetEncodingValue(0x2);
288       break;
289     case S64:
290       type_ = 0x1;
291       SetEncodingValue(0x4);
292       break;
293     default:
294       VIXL_UNREACHABLE();
295       type_ = 0x0;
296       break;
297   }
298 }
299 
300 class Dt_imm6_3 : public EncodingValue {
301  public:
302   explicit Dt_imm6_3(DataType dt);
303 };
304 
Dt_imm6_3(DataType dt)305 Dt_imm6_3::Dt_imm6_3(DataType dt) {
306   switch (dt.GetValue()) {
307     case I16:
308       SetEncodingValue(0x1);
309       break;
310     case I32:
311       SetEncodingValue(0x2);
312       break;
313     case I64:
314       SetEncodingValue(0x4);
315       break;
316     default:
317       break;
318   }
319 }
320 
321 class Dt_imm6_4 : public EncodingValue {
322   uint32_t type_;
323 
324  public:
325   explicit Dt_imm6_4(DataType dt);
GetTypeEncodingValue() const326   uint32_t GetTypeEncodingValue() const { return type_; }
327 };
328 
Dt_imm6_4(DataType dt)329 Dt_imm6_4::Dt_imm6_4(DataType dt) {
330   switch (dt.GetValue()) {
331     case S8:
332       type_ = 0x0;
333       SetEncodingValue(0x1);
334       break;
335     case U8:
336       type_ = 0x1;
337       SetEncodingValue(0x1);
338       break;
339     case S16:
340       type_ = 0x0;
341       SetEncodingValue(0x2);
342       break;
343     case U16:
344       type_ = 0x1;
345       SetEncodingValue(0x2);
346       break;
347     case S32:
348       type_ = 0x0;
349       SetEncodingValue(0x4);
350       break;
351     case U32:
352       type_ = 0x1;
353       SetEncodingValue(0x4);
354       break;
355     default:
356       VIXL_UNREACHABLE();
357       type_ = 0x0;
358       break;
359   }
360 }
361 
362 class Dt_op_U_size_1 : public EncodingValue {
363  public:
364   explicit Dt_op_U_size_1(DataType dt);
365 };
366 
Dt_op_U_size_1(DataType dt)367 Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) {
368   switch (dt.GetValue()) {
369     case S8:
370       SetEncodingValue(0x0);
371       break;
372     case S16:
373       SetEncodingValue(0x1);
374       break;
375     case S32:
376       SetEncodingValue(0x2);
377       break;
378     case U8:
379       SetEncodingValue(0x4);
380       break;
381     case U16:
382       SetEncodingValue(0x5);
383       break;
384     case U32:
385       SetEncodingValue(0x6);
386       break;
387     case P8:
388       SetEncodingValue(0x8);
389       break;
390     case P64:
391       SetEncodingValue(0xa);
392       break;
393     default:
394       break;
395   }
396 }
397 
398 class Dt_op_size_1 : public EncodingValue {
399  public:
400   explicit Dt_op_size_1(DataType dt);
401 };
402 
Dt_op_size_1(DataType dt)403 Dt_op_size_1::Dt_op_size_1(DataType dt) {
404   switch (dt.GetValue()) {
405     case I8:
406       SetEncodingValue(0x0);
407       break;
408     case I16:
409       SetEncodingValue(0x1);
410       break;
411     case I32:
412       SetEncodingValue(0x2);
413       break;
414     case P8:
415       SetEncodingValue(0x4);
416       break;
417     default:
418       break;
419   }
420 }
421 
422 class Dt_op_size_2 : public EncodingValue {
423  public:
424   explicit Dt_op_size_2(DataType dt);
425 };
426 
Dt_op_size_2(DataType dt)427 Dt_op_size_2::Dt_op_size_2(DataType dt) {
428   switch (dt.GetValue()) {
429     case S8:
430       SetEncodingValue(0x0);
431       break;
432     case S16:
433       SetEncodingValue(0x1);
434       break;
435     case S32:
436       SetEncodingValue(0x2);
437       break;
438     case U8:
439       SetEncodingValue(0x4);
440       break;
441     case U16:
442       SetEncodingValue(0x5);
443       break;
444     case U32:
445       SetEncodingValue(0x6);
446       break;
447     default:
448       break;
449   }
450 }
451 
452 class Dt_op_size_3 : public EncodingValue {
453  public:
454   explicit Dt_op_size_3(DataType dt);
455 };
456 
Dt_op_size_3(DataType dt)457 Dt_op_size_3::Dt_op_size_3(DataType dt) {
458   switch (dt.GetValue()) {
459     case S16:
460       SetEncodingValue(0x0);
461       break;
462     case S32:
463       SetEncodingValue(0x1);
464       break;
465     case S64:
466       SetEncodingValue(0x2);
467       break;
468     case U16:
469       SetEncodingValue(0x4);
470       break;
471     case U32:
472       SetEncodingValue(0x5);
473       break;
474     case U64:
475       SetEncodingValue(0x6);
476       break;
477     default:
478       break;
479   }
480 }
481 
482 class Dt_U_imm3H_1 : public EncodingValue {
483  public:
484   explicit Dt_U_imm3H_1(DataType dt);
485 };
486 
Dt_U_imm3H_1(DataType dt)487 Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) {
488   switch (dt.GetValue()) {
489     case S8:
490       SetEncodingValue(0x1);
491       break;
492     case S16:
493       SetEncodingValue(0x2);
494       break;
495     case S32:
496       SetEncodingValue(0x4);
497       break;
498     case U8:
499       SetEncodingValue(0x9);
500       break;
501     case U16:
502       SetEncodingValue(0xa);
503       break;
504     case U32:
505       SetEncodingValue(0xc);
506       break;
507     default:
508       break;
509   }
510 }
511 
512 class Dt_U_opc1_opc2_1 : public EncodingValue {
513  public:
514   explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
515 };
516 
Dt_U_opc1_opc2_1(DataType dt,const DRegisterLane & lane)517 Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
518   switch (dt.GetValue()) {
519     case S8:
520       if ((lane.GetLane() & 7) != lane.GetLane()) {
521         return;
522       }
523       SetEncodingValue(0x8 | lane.GetLane());
524       break;
525     case S16:
526       if ((lane.GetLane() & 3) != lane.GetLane()) {
527         return;
528       }
529       SetEncodingValue(0x1 | (lane.GetLane() << 1));
530       break;
531     case U8:
532       if ((lane.GetLane() & 7) != lane.GetLane()) {
533         return;
534       }
535       SetEncodingValue(0x18 | lane.GetLane());
536       break;
537     case U16:
538       if ((lane.GetLane() & 3) != lane.GetLane()) {
539         return;
540       }
541       SetEncodingValue(0x11 | (lane.GetLane() << 1));
542       break;
543     case Untyped32:
544       if ((lane.GetLane() & 1) != lane.GetLane()) {
545         return;
546       }
547       SetEncodingValue(0x0 | (lane.GetLane() << 2));
548       break;
549     case kDataTypeValueNone:
550       if ((lane.GetLane() & 1) != lane.GetLane()) {
551         return;
552       }
553       SetEncodingValue(0x0 | (lane.GetLane() << 2));
554       break;
555     default:
556       break;
557   }
558 }
559 
560 class Dt_opc1_opc2_1 : public EncodingValue {
561  public:
562   explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
563 };
564 
Dt_opc1_opc2_1(DataType dt,const DRegisterLane & lane)565 Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
566   switch (dt.GetValue()) {
567     case Untyped8:
568       if ((lane.GetLane() & 7) != lane.GetLane()) {
569         return;
570       }
571       SetEncodingValue(0x8 | lane.GetLane());
572       break;
573     case Untyped16:
574       if ((lane.GetLane() & 3) != lane.GetLane()) {
575         return;
576       }
577       SetEncodingValue(0x1 | (lane.GetLane() << 1));
578       break;
579     case Untyped32:
580       if ((lane.GetLane() & 1) != lane.GetLane()) {
581         return;
582       }
583       SetEncodingValue(0x0 | (lane.GetLane() << 2));
584       break;
585     case kDataTypeValueNone:
586       if ((lane.GetLane() & 1) != lane.GetLane()) {
587         return;
588       }
589       SetEncodingValue(0x0 | (lane.GetLane() << 2));
590       break;
591     default:
592       break;
593   }
594 }
595 
596 class Dt_imm4_1 : public EncodingValue {
597  public:
598   explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane);
599 };
600 
Dt_imm4_1(DataType dt,const DRegisterLane & lane)601 Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) {
602   switch (dt.GetValue()) {
603     case Untyped8:
604       if ((lane.GetLane() & 7) != lane.GetLane()) {
605         return;
606       }
607       SetEncodingValue(0x1 | (lane.GetLane() << 1));
608       break;
609     case Untyped16:
610       if ((lane.GetLane() & 3) != lane.GetLane()) {
611         return;
612       }
613       SetEncodingValue(0x2 | (lane.GetLane() << 2));
614       break;
615     case Untyped32:
616       if ((lane.GetLane() & 1) != lane.GetLane()) {
617         return;
618       }
619       SetEncodingValue(0x4 | (lane.GetLane() << 3));
620       break;
621     default:
622       break;
623   }
624 }
625 
626 class Dt_B_E_1 : public EncodingValue {
627  public:
628   explicit Dt_B_E_1(DataType dt);
629 };
630 
Dt_B_E_1(DataType dt)631 Dt_B_E_1::Dt_B_E_1(DataType dt) {
632   switch (dt.GetValue()) {
633     case Untyped8:
634       SetEncodingValue(0x2);
635       break;
636     case Untyped16:
637       SetEncodingValue(0x1);
638       break;
639     case Untyped32:
640       SetEncodingValue(0x0);
641       break;
642     default:
643       break;
644   }
645 }
646 
647 class Dt_op_1 : public EncodingValue {
648  public:
649   Dt_op_1(DataType dt1, DataType dt2);
650 };
651 
Dt_op_1(DataType dt1,DataType dt2)652 Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) {
653   if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
654     SetEncodingValue(0x0);
655     return;
656   }
657   if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
658     SetEncodingValue(0x1);
659     return;
660   }
661   if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
662     SetEncodingValue(0x2);
663     return;
664   }
665   if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
666     SetEncodingValue(0x3);
667     return;
668   }
669 }
670 
671 class Dt_op_2 : public EncodingValue {
672  public:
673   explicit Dt_op_2(DataType dt);
674 };
675 
Dt_op_2(DataType dt)676 Dt_op_2::Dt_op_2(DataType dt) {
677   switch (dt.GetValue()) {
678     case U32:
679       SetEncodingValue(0x0);
680       break;
681     case S32:
682       SetEncodingValue(0x1);
683       break;
684     default:
685       break;
686   }
687 }
688 
689 class Dt_op_3 : public EncodingValue {
690  public:
691   explicit Dt_op_3(DataType dt);
692 };
693 
Dt_op_3(DataType dt)694 Dt_op_3::Dt_op_3(DataType dt) {
695   switch (dt.GetValue()) {
696     case S32:
697       SetEncodingValue(0x0);
698       break;
699     case U32:
700       SetEncodingValue(0x1);
701       break;
702     default:
703       break;
704   }
705 }
706 
707 class Dt_U_sx_1 : public EncodingValue {
708  public:
709   explicit Dt_U_sx_1(DataType dt);
710 };
711 
Dt_U_sx_1(DataType dt)712 Dt_U_sx_1::Dt_U_sx_1(DataType dt) {
713   switch (dt.GetValue()) {
714     case S16:
715       SetEncodingValue(0x0);
716       break;
717     case S32:
718       SetEncodingValue(0x1);
719       break;
720     case U16:
721       SetEncodingValue(0x2);
722       break;
723     case U32:
724       SetEncodingValue(0x3);
725       break;
726     default:
727       break;
728   }
729 }
730 
731 class Dt_op_U_1 : public EncodingValue {
732  public:
733   Dt_op_U_1(DataType dt1, DataType dt2);
734 };
735 
Dt_op_U_1(DataType dt1,DataType dt2)736 Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) {
737   if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
738     SetEncodingValue(0x0);
739     return;
740   }
741   if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
742     SetEncodingValue(0x1);
743     return;
744   }
745   if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
746     SetEncodingValue(0x2);
747     return;
748   }
749   if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
750     SetEncodingValue(0x3);
751     return;
752   }
753 }
754 
755 class Dt_sz_1 : public EncodingValue {
756  public:
757   explicit Dt_sz_1(DataType dt);
758 };
759 
Dt_sz_1(DataType dt)760 Dt_sz_1::Dt_sz_1(DataType dt) {
761   switch (dt.GetValue()) {
762     case F32:
763       SetEncodingValue(0x0);
764       break;
765     default:
766       break;
767   }
768 }
769 
770 class Dt_F_size_1 : public EncodingValue {
771  public:
772   explicit Dt_F_size_1(DataType dt);
773 };
774 
Dt_F_size_1(DataType dt)775 Dt_F_size_1::Dt_F_size_1(DataType dt) {
776   switch (dt.GetValue()) {
777     case S8:
778       SetEncodingValue(0x0);
779       break;
780     case S16:
781       SetEncodingValue(0x1);
782       break;
783     case S32:
784       SetEncodingValue(0x2);
785       break;
786     case F32:
787       SetEncodingValue(0x6);
788       break;
789     default:
790       break;
791   }
792 }
793 
794 class Dt_F_size_2 : public EncodingValue {
795  public:
796   explicit Dt_F_size_2(DataType dt);
797 };
798 
Dt_F_size_2(DataType dt)799 Dt_F_size_2::Dt_F_size_2(DataType dt) {
800   switch (dt.GetValue()) {
801     case I8:
802       SetEncodingValue(0x0);
803       break;
804     case I16:
805       SetEncodingValue(0x1);
806       break;
807     case I32:
808       SetEncodingValue(0x2);
809       break;
810     case F32:
811       SetEncodingValue(0x6);
812       break;
813     default:
814       break;
815   }
816 }
817 
818 class Dt_F_size_3 : public EncodingValue {
819  public:
820   explicit Dt_F_size_3(DataType dt);
821 };
822 
Dt_F_size_3(DataType dt)823 Dt_F_size_3::Dt_F_size_3(DataType dt) {
824   switch (dt.GetValue()) {
825     case I16:
826       SetEncodingValue(0x1);
827       break;
828     case I32:
829       SetEncodingValue(0x2);
830       break;
831     case F32:
832       SetEncodingValue(0x6);
833       break;
834     default:
835       break;
836   }
837 }
838 
839 class Dt_F_size_4 : public EncodingValue {
840  public:
841   explicit Dt_F_size_4(DataType dt);
842 };
843 
Dt_F_size_4(DataType dt)844 Dt_F_size_4::Dt_F_size_4(DataType dt) {
845   switch (dt.GetValue()) {
846     case U32:
847       SetEncodingValue(0x2);
848       break;
849     case F32:
850       SetEncodingValue(0x6);
851       break;
852     default:
853       break;
854   }
855 }
856 
857 class Dt_U_size_1 : public EncodingValue {
858  public:
859   explicit Dt_U_size_1(DataType dt);
860 };
861 
Dt_U_size_1(DataType dt)862 Dt_U_size_1::Dt_U_size_1(DataType dt) {
863   switch (dt.GetValue()) {
864     case S8:
865       SetEncodingValue(0x0);
866       break;
867     case S16:
868       SetEncodingValue(0x1);
869       break;
870     case S32:
871       SetEncodingValue(0x2);
872       break;
873     case U8:
874       SetEncodingValue(0x4);
875       break;
876     case U16:
877       SetEncodingValue(0x5);
878       break;
879     case U32:
880       SetEncodingValue(0x6);
881       break;
882     default:
883       break;
884   }
885 }
886 
887 class Dt_U_size_2 : public EncodingValue {
888  public:
889   explicit Dt_U_size_2(DataType dt);
890 };
891 
Dt_U_size_2(DataType dt)892 Dt_U_size_2::Dt_U_size_2(DataType dt) {
893   switch (dt.GetValue()) {
894     case S16:
895       SetEncodingValue(0x1);
896       break;
897     case S32:
898       SetEncodingValue(0x2);
899       break;
900     case U16:
901       SetEncodingValue(0x5);
902       break;
903     case U32:
904       SetEncodingValue(0x6);
905       break;
906     default:
907       break;
908   }
909 }
910 
911 class Dt_U_size_3 : public EncodingValue {
912  public:
913   explicit Dt_U_size_3(DataType dt);
914 };
915 
Dt_U_size_3(DataType dt)916 Dt_U_size_3::Dt_U_size_3(DataType dt) {
917   switch (dt.GetValue()) {
918     case S8:
919       SetEncodingValue(0x0);
920       break;
921     case S16:
922       SetEncodingValue(0x1);
923       break;
924     case S32:
925       SetEncodingValue(0x2);
926       break;
927     case S64:
928       SetEncodingValue(0x3);
929       break;
930     case U8:
931       SetEncodingValue(0x4);
932       break;
933     case U16:
934       SetEncodingValue(0x5);
935       break;
936     case U32:
937       SetEncodingValue(0x6);
938       break;
939     case U64:
940       SetEncodingValue(0x7);
941       break;
942     default:
943       break;
944   }
945 }
946 
947 class Dt_size_1 : public EncodingValue {
948  public:
949   explicit Dt_size_1(DataType dt);
950 };
951 
Dt_size_1(DataType dt)952 Dt_size_1::Dt_size_1(DataType dt) {
953   switch (dt.GetValue()) {
954     case Untyped8:
955       SetEncodingValue(0x0);
956       break;
957     default:
958       break;
959   }
960 }
961 
962 class Dt_size_2 : public EncodingValue {
963  public:
964   explicit Dt_size_2(DataType dt);
965 };
966 
Dt_size_2(DataType dt)967 Dt_size_2::Dt_size_2(DataType dt) {
968   switch (dt.GetValue()) {
969     case I8:
970       SetEncodingValue(0x0);
971       break;
972     case I16:
973       SetEncodingValue(0x1);
974       break;
975     case I32:
976       SetEncodingValue(0x2);
977       break;
978     case I64:
979       SetEncodingValue(0x3);
980       break;
981     default:
982       break;
983   }
984 }
985 
986 class Dt_size_3 : public EncodingValue {
987  public:
988   explicit Dt_size_3(DataType dt);
989 };
990 
Dt_size_3(DataType dt)991 Dt_size_3::Dt_size_3(DataType dt) {
992   switch (dt.GetValue()) {
993     case I16:
994       SetEncodingValue(0x0);
995       break;
996     case I32:
997       SetEncodingValue(0x1);
998       break;
999     case I64:
1000       SetEncodingValue(0x2);
1001       break;
1002     default:
1003       break;
1004   }
1005 }
1006 
1007 class Dt_size_4 : public EncodingValue {
1008  public:
1009   explicit Dt_size_4(DataType dt);
1010 };
1011 
Dt_size_4(DataType dt)1012 Dt_size_4::Dt_size_4(DataType dt) {
1013   switch (dt.GetValue()) {
1014     case I8:
1015       SetEncodingValue(0x0);
1016       break;
1017     case I16:
1018       SetEncodingValue(0x1);
1019       break;
1020     case I32:
1021       SetEncodingValue(0x2);
1022       break;
1023     default:
1024       break;
1025   }
1026 }
1027 
1028 class Dt_size_5 : public EncodingValue {
1029  public:
1030   explicit Dt_size_5(DataType dt);
1031 };
1032 
Dt_size_5(DataType dt)1033 Dt_size_5::Dt_size_5(DataType dt) {
1034   switch (dt.GetValue()) {
1035     case S8:
1036       SetEncodingValue(0x0);
1037       break;
1038     case S16:
1039       SetEncodingValue(0x1);
1040       break;
1041     case S32:
1042       SetEncodingValue(0x2);
1043       break;
1044     default:
1045       break;
1046   }
1047 }
1048 
1049 class Dt_size_6 : public EncodingValue {
1050  public:
1051   explicit Dt_size_6(DataType dt);
1052 };
1053 
Dt_size_6(DataType dt)1054 Dt_size_6::Dt_size_6(DataType dt) {
1055   switch (dt.GetValue()) {
1056     case Untyped8:
1057       SetEncodingValue(0x0);
1058       break;
1059     case Untyped16:
1060       SetEncodingValue(0x1);
1061       break;
1062     case Untyped32:
1063       SetEncodingValue(0x2);
1064       break;
1065     case Untyped64:
1066       SetEncodingValue(0x3);
1067       break;
1068     default:
1069       break;
1070   }
1071 }
1072 
1073 class Dt_size_7 : public EncodingValue {
1074  public:
1075   explicit Dt_size_7(DataType dt);
1076 };
1077 
Dt_size_7(DataType dt)1078 Dt_size_7::Dt_size_7(DataType dt) {
1079   switch (dt.GetValue()) {
1080     case Untyped8:
1081       SetEncodingValue(0x0);
1082       break;
1083     case Untyped16:
1084       SetEncodingValue(0x1);
1085       break;
1086     case Untyped32:
1087       SetEncodingValue(0x2);
1088       break;
1089     default:
1090       break;
1091   }
1092 }
1093 
1094 class Dt_size_8 : public EncodingValue {
1095  public:
1096   Dt_size_8(DataType dt, Alignment align);
1097 };
1098 
Dt_size_8(DataType dt,Alignment align)1099 Dt_size_8::Dt_size_8(DataType dt, Alignment align) {
1100   switch (dt.GetValue()) {
1101     case Untyped8:
1102       SetEncodingValue(0x0);
1103       break;
1104     case Untyped16:
1105       SetEncodingValue(0x1);
1106       break;
1107     case Untyped32:
1108       if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) {
1109         SetEncodingValue(0x2);
1110       } else if (align.Is(k128BitAlign)) {
1111         SetEncodingValue(0x3);
1112       }
1113       break;
1114     default:
1115       break;
1116   }
1117 }
1118 
1119 class Dt_size_9 : public EncodingValue {
1120   uint32_t type_;
1121 
1122  public:
1123   explicit Dt_size_9(DataType dt);
GetTypeEncodingValue() const1124   uint32_t GetTypeEncodingValue() const { return type_; }
1125 };
1126 
Dt_size_9(DataType dt)1127 Dt_size_9::Dt_size_9(DataType dt) {
1128   switch (dt.GetValue()) {
1129     case I16:
1130       type_ = 0x0;
1131       SetEncodingValue(0x1);
1132       break;
1133     case I32:
1134       type_ = 0x0;
1135       SetEncodingValue(0x2);
1136       break;
1137     case F32:
1138       type_ = 0x1;
1139       SetEncodingValue(0x2);
1140       break;
1141     default:
1142       VIXL_UNREACHABLE();
1143       type_ = 0x0;
1144       break;
1145   }
1146 }
1147 
1148 class Dt_size_10 : public EncodingValue {
1149  public:
1150   explicit Dt_size_10(DataType dt);
1151 };
1152 
Dt_size_10(DataType dt)1153 Dt_size_10::Dt_size_10(DataType dt) {
1154   switch (dt.GetValue()) {
1155     case S8:
1156     case U8:
1157     case I8:
1158       SetEncodingValue(0x0);
1159       break;
1160     case S16:
1161     case U16:
1162     case I16:
1163       SetEncodingValue(0x1);
1164       break;
1165     case S32:
1166     case U32:
1167     case I32:
1168       SetEncodingValue(0x2);
1169       break;
1170     default:
1171       break;
1172   }
1173 }
1174 
1175 class Dt_size_11 : public EncodingValue {
1176   uint32_t type_;
1177 
1178  public:
1179   explicit Dt_size_11(DataType dt);
GetTypeEncodingValue() const1180   uint32_t GetTypeEncodingValue() const { return type_; }
1181 };
1182 
Dt_size_11(DataType dt)1183 Dt_size_11::Dt_size_11(DataType dt) {
1184   switch (dt.GetValue()) {
1185     case S16:
1186       type_ = 0x0;
1187       SetEncodingValue(0x1);
1188       break;
1189     case U16:
1190       type_ = 0x1;
1191       SetEncodingValue(0x1);
1192       break;
1193     case S32:
1194       type_ = 0x0;
1195       SetEncodingValue(0x2);
1196       break;
1197     case U32:
1198       type_ = 0x1;
1199       SetEncodingValue(0x2);
1200       break;
1201     default:
1202       VIXL_UNREACHABLE();
1203       type_ = 0x0;
1204       break;
1205   }
1206 }
1207 
1208 class Dt_size_12 : public EncodingValue {
1209   uint32_t type_;
1210 
1211  public:
1212   explicit Dt_size_12(DataType dt);
GetTypeEncodingValue() const1213   uint32_t GetTypeEncodingValue() const { return type_; }
1214 };
1215 
Dt_size_12(DataType dt)1216 Dt_size_12::Dt_size_12(DataType dt) {
1217   switch (dt.GetValue()) {
1218     case S8:
1219       type_ = 0x0;
1220       SetEncodingValue(0x0);
1221       break;
1222     case U8:
1223       type_ = 0x1;
1224       SetEncodingValue(0x0);
1225       break;
1226     case S16:
1227       type_ = 0x0;
1228       SetEncodingValue(0x1);
1229       break;
1230     case U16:
1231       type_ = 0x1;
1232       SetEncodingValue(0x1);
1233       break;
1234     case S32:
1235       type_ = 0x0;
1236       SetEncodingValue(0x2);
1237       break;
1238     case U32:
1239       type_ = 0x1;
1240       SetEncodingValue(0x2);
1241       break;
1242     default:
1243       VIXL_UNREACHABLE();
1244       type_ = 0x0;
1245       break;
1246   }
1247 }
1248 
1249 class Dt_size_13 : public EncodingValue {
1250  public:
1251   explicit Dt_size_13(DataType dt);
1252 };
1253 
Dt_size_13(DataType dt)1254 Dt_size_13::Dt_size_13(DataType dt) {
1255   switch (dt.GetValue()) {
1256     case S16:
1257       SetEncodingValue(0x1);
1258       break;
1259     case S32:
1260       SetEncodingValue(0x2);
1261       break;
1262     default:
1263       break;
1264   }
1265 }
1266 
1267 class Dt_size_14 : public EncodingValue {
1268  public:
1269   explicit Dt_size_14(DataType dt);
1270 };
1271 
Dt_size_14(DataType dt)1272 Dt_size_14::Dt_size_14(DataType dt) {
1273   switch (dt.GetValue()) {
1274     case S16:
1275       SetEncodingValue(0x0);
1276       break;
1277     case S32:
1278       SetEncodingValue(0x1);
1279       break;
1280     case S64:
1281       SetEncodingValue(0x2);
1282       break;
1283     default:
1284       break;
1285   }
1286 }
1287 
1288 class Dt_size_15 : public EncodingValue {
1289  public:
1290   explicit Dt_size_15(DataType dt);
1291 };
1292 
Dt_size_15(DataType dt)1293 Dt_size_15::Dt_size_15(DataType dt) {
1294   switch (dt.GetValue()) {
1295     case Untyped8:
1296       SetEncodingValue(0x0);
1297       break;
1298     case Untyped16:
1299       SetEncodingValue(0x1);
1300       break;
1301     default:
1302       break;
1303   }
1304 }
1305 
1306 class Dt_size_16 : public EncodingValue {
1307  public:
1308   explicit Dt_size_16(DataType dt);
1309 };
1310 
Dt_size_16(DataType dt)1311 Dt_size_16::Dt_size_16(DataType dt) {
1312   switch (dt.GetValue()) {
1313     case F32:
1314       SetEncodingValue(0x2);
1315       break;
1316     default:
1317       break;
1318   }
1319 }
1320 
1321 class Dt_size_17 : public EncodingValue {
1322  public:
1323   explicit Dt_size_17(DataType dt);
1324 };
1325 
Dt_size_17(DataType dt)1326 Dt_size_17::Dt_size_17(DataType dt) {
1327   switch (dt.GetValue()) {
1328     case I8:
1329       SetEncodingValue(0x0);
1330       break;
1331     case I16:
1332       SetEncodingValue(0x1);
1333       break;
1334     case I32:
1335       SetEncodingValue(0x2);
1336       break;
1337     default:
1338       break;
1339   }
1340 }
1341 
1342 class Index_1 : public EncodingValue {
1343  public:
1344   Index_1(const NeonRegisterList& nreglist, DataType dt);
1345 };
1346 
Index_1(const NeonRegisterList & nreglist,DataType dt)1347 Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) {
1348   switch (dt.GetValue()) {
1349     case Untyped8: {
1350       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1351         return;
1352       }
1353       uint32_t value = nreglist.GetTransferLane() << 1;
1354       if (!nreglist.IsSingleSpaced()) return;
1355       SetEncodingValue(value);
1356       break;
1357     }
1358     case Untyped16: {
1359       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1360         return;
1361       }
1362       uint32_t value = nreglist.GetTransferLane() << 2;
1363       if (nreglist.IsDoubleSpaced()) value |= 2;
1364       SetEncodingValue(value);
1365       break;
1366     }
1367     case Untyped32: {
1368       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1369         return;
1370       }
1371       uint32_t value = nreglist.GetTransferLane() << 3;
1372       if (nreglist.IsDoubleSpaced()) value |= 4;
1373       SetEncodingValue(value);
1374       break;
1375     }
1376     default:
1377       break;
1378   }
1379 }
1380 
1381 class Align_index_align_1 : public EncodingValue {
1382  public:
1383   Align_index_align_1(Alignment align,
1384                       const NeonRegisterList& nreglist,
1385                       DataType dt);
1386 };
1387 
Align_index_align_1(Alignment align,const NeonRegisterList & nreglist,DataType dt)1388 Align_index_align_1::Align_index_align_1(Alignment align,
1389                                          const NeonRegisterList& nreglist,
1390                                          DataType dt) {
1391   switch (dt.GetValue()) {
1392     case Untyped8: {
1393       uint32_t value;
1394       if (align.GetType() == kNoAlignment) {
1395         value = 0;
1396       } else {
1397         return;
1398       }
1399       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1400         return;
1401       }
1402       value |= nreglist.GetTransferLane() << 1;
1403       SetEncodingValue(value);
1404       break;
1405     }
1406     case Untyped16: {
1407       uint32_t value;
1408       if (align.GetType() == k16BitAlign) {
1409         value = 1;
1410       } else if (align.GetType() == kNoAlignment) {
1411         value = 0;
1412       } else {
1413         return;
1414       }
1415       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1416         return;
1417       }
1418       value |= nreglist.GetTransferLane() << 2;
1419       SetEncodingValue(value);
1420       break;
1421     }
1422     case Untyped32: {
1423       uint32_t value;
1424       if (align.GetType() == k32BitAlign) {
1425         value = 3;
1426       } else if (align.GetType() == kNoAlignment) {
1427         value = 0;
1428       } else {
1429         return;
1430       }
1431       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1432         return;
1433       }
1434       value |= nreglist.GetTransferLane() << 3;
1435       SetEncodingValue(value);
1436       break;
1437     }
1438     default:
1439       break;
1440   }
1441 }
1442 
1443 class Align_index_align_2 : public EncodingValue {
1444  public:
1445   Align_index_align_2(Alignment align,
1446                       const NeonRegisterList& nreglist,
1447                       DataType dt);
1448 };
1449 
Align_index_align_2(Alignment align,const NeonRegisterList & nreglist,DataType dt)1450 Align_index_align_2::Align_index_align_2(Alignment align,
1451                                          const NeonRegisterList& nreglist,
1452                                          DataType dt) {
1453   switch (dt.GetValue()) {
1454     case Untyped8: {
1455       uint32_t value;
1456       if (align.GetType() == k16BitAlign) {
1457         value = 1;
1458       } else if (align.GetType() == kNoAlignment) {
1459         value = 0;
1460       } else {
1461         return;
1462       }
1463       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1464         return;
1465       }
1466       value |= nreglist.GetTransferLane() << 1;
1467       if (!nreglist.IsSingleSpaced()) return;
1468       SetEncodingValue(value);
1469       break;
1470     }
1471     case Untyped16: {
1472       uint32_t value;
1473       if (align.GetType() == k32BitAlign) {
1474         value = 1;
1475       } else if (align.GetType() == kNoAlignment) {
1476         value = 0;
1477       } else {
1478         return;
1479       }
1480       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1481         return;
1482       }
1483       value |= nreglist.GetTransferLane() << 2;
1484       if (nreglist.IsDoubleSpaced()) value |= 2;
1485       SetEncodingValue(value);
1486       break;
1487     }
1488     case Untyped32: {
1489       uint32_t value;
1490       if (align.GetType() == k64BitAlign) {
1491         value = 1;
1492       } else if (align.GetType() == kNoAlignment) {
1493         value = 0;
1494       } else {
1495         return;
1496       }
1497       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1498         return;
1499       }
1500       value |= nreglist.GetTransferLane() << 3;
1501       if (nreglist.IsDoubleSpaced()) value |= 4;
1502       SetEncodingValue(value);
1503       break;
1504     }
1505     default:
1506       break;
1507   }
1508 }
1509 
1510 class Align_index_align_3 : public EncodingValue {
1511  public:
1512   Align_index_align_3(Alignment align,
1513                       const NeonRegisterList& nreglist,
1514                       DataType dt);
1515 };
1516 
Align_index_align_3(Alignment align,const NeonRegisterList & nreglist,DataType dt)1517 Align_index_align_3::Align_index_align_3(Alignment align,
1518                                          const NeonRegisterList& nreglist,
1519                                          DataType dt) {
1520   switch (dt.GetValue()) {
1521     case Untyped8: {
1522       uint32_t value;
1523       if (align.GetType() == k32BitAlign) {
1524         value = 1;
1525       } else if (align.GetType() == kNoAlignment) {
1526         value = 0;
1527       } else {
1528         return;
1529       }
1530       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1531         return;
1532       }
1533       value |= nreglist.GetTransferLane() << 1;
1534       if (!nreglist.IsSingleSpaced()) return;
1535       SetEncodingValue(value);
1536       break;
1537     }
1538     case Untyped16: {
1539       uint32_t value;
1540       if (align.GetType() == k64BitAlign) {
1541         value = 1;
1542       } else if (align.GetType() == kNoAlignment) {
1543         value = 0;
1544       } else {
1545         return;
1546       }
1547       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1548         return;
1549       }
1550       value |= nreglist.GetTransferLane() << 2;
1551       if (nreglist.IsDoubleSpaced()) value |= 2;
1552       SetEncodingValue(value);
1553       break;
1554     }
1555     case Untyped32: {
1556       uint32_t value;
1557       if (align.GetType() == k64BitAlign) {
1558         value = 1;
1559       } else if (align.GetType() == k128BitAlign) {
1560         value = 2;
1561       } else if (align.GetType() == kNoAlignment) {
1562         value = 0;
1563       } else {
1564         return;
1565       }
1566       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1567         return;
1568       }
1569       value |= nreglist.GetTransferLane() << 3;
1570       if (nreglist.IsDoubleSpaced()) value |= 4;
1571       SetEncodingValue(value);
1572       break;
1573     }
1574     default:
1575       break;
1576   }
1577 }
1578 
1579 class Align_a_1 : public EncodingValue {
1580  public:
1581   Align_a_1(Alignment align, DataType dt);
1582 };
1583 
Align_a_1(Alignment align,DataType dt)1584 Align_a_1::Align_a_1(Alignment align, DataType dt) {
1585   switch (align.GetType()) {
1586     case k16BitAlign:
1587       if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1588       break;
1589     case k32BitAlign:
1590       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1591       break;
1592     case kNoAlignment:
1593       SetEncodingValue(0x0);
1594       break;
1595     default:
1596       break;
1597   }
1598 }
1599 
1600 class Align_a_2 : public EncodingValue {
1601  public:
1602   Align_a_2(Alignment align, DataType dt);
1603 };
1604 
Align_a_2(Alignment align,DataType dt)1605 Align_a_2::Align_a_2(Alignment align, DataType dt) {
1606   switch (align.GetType()) {
1607     case k16BitAlign:
1608       if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1609       break;
1610     case k32BitAlign:
1611       if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1612       break;
1613     case k64BitAlign:
1614       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1615       break;
1616     case kNoAlignment:
1617       SetEncodingValue(0x0);
1618       break;
1619     default:
1620       break;
1621   }
1622 }
1623 
1624 class Align_a_3 : public EncodingValue {
1625  public:
1626   Align_a_3(Alignment align, DataType dt);
1627 };
1628 
Align_a_3(Alignment align,DataType dt)1629 Align_a_3::Align_a_3(Alignment align, DataType dt) {
1630   switch (align.GetType()) {
1631     case k32BitAlign:
1632       if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1633       break;
1634     case k64BitAlign:
1635       if (dt.Is(Untyped16))
1636         SetEncodingValue(0x1);
1637       else if (dt.Is(Untyped32))
1638         SetEncodingValue(0x1);
1639       break;
1640     case k128BitAlign:
1641       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1642       break;
1643     case kNoAlignment:
1644       SetEncodingValue(0x0);
1645       break;
1646     default:
1647       break;
1648   }
1649 }
1650 
1651 class Align_align_1 : public EncodingValue {
1652  public:
1653   Align_align_1(Alignment align, const NeonRegisterList& nreglist);
1654 };
1655 
Align_align_1(Alignment align,const NeonRegisterList & nreglist)1656 Align_align_1::Align_align_1(Alignment align,
1657                              const NeonRegisterList& nreglist) {
1658   switch (align.GetType()) {
1659     case k64BitAlign:
1660       SetEncodingValue(0x1);
1661       break;
1662     case k128BitAlign:
1663       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1664         SetEncodingValue(0x2);
1665       break;
1666     case k256BitAlign:
1667       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1668         SetEncodingValue(0x3);
1669       break;
1670     case kNoAlignment:
1671       SetEncodingValue(0x0);
1672       break;
1673     default:
1674       break;
1675   }
1676 }
1677 
1678 class Align_align_2 : public EncodingValue {
1679  public:
1680   Align_align_2(Alignment align, const NeonRegisterList& nreglist);
1681 };
1682 
Align_align_2(Alignment align,const NeonRegisterList & nreglist)1683 Align_align_2::Align_align_2(Alignment align,
1684                              const NeonRegisterList& nreglist) {
1685   switch (align.GetType()) {
1686     case k64BitAlign:
1687       SetEncodingValue(0x1);
1688       break;
1689     case k128BitAlign:
1690       SetEncodingValue(0x2);
1691       break;
1692     case k256BitAlign:
1693       if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1694       break;
1695     case kNoAlignment:
1696       SetEncodingValue(0x0);
1697       break;
1698     default:
1699       break;
1700   }
1701 }
1702 
1703 class Align_align_3 : public EncodingValue {
1704  public:
1705   explicit Align_align_3(Alignment align);
1706 };
1707 
Align_align_3(Alignment align)1708 Align_align_3::Align_align_3(Alignment align) {
1709   switch (align.GetType()) {
1710     case k64BitAlign:
1711       SetEncodingValue(0x1);
1712       break;
1713     case kNoAlignment:
1714       SetEncodingValue(0x0);
1715       break;
1716     default:
1717       break;
1718   }
1719 }
1720 
1721 class Align_align_4 : public EncodingValue {
1722  public:
1723   explicit Align_align_4(Alignment align);
1724 };
1725 
Align_align_4(Alignment align)1726 Align_align_4::Align_align_4(Alignment align) {
1727   switch (align.GetType()) {
1728     case k64BitAlign:
1729       SetEncodingValue(0x1);
1730       break;
1731     case k128BitAlign:
1732       SetEncodingValue(0x2);
1733       break;
1734     case k256BitAlign:
1735       SetEncodingValue(0x3);
1736       break;
1737     case kNoAlignment:
1738       SetEncodingValue(0x0);
1739       break;
1740     default:
1741       break;
1742   }
1743 }
1744 
1745 class Align_align_5 : public EncodingValue {
1746  public:
1747   Align_align_5(Alignment align, const NeonRegisterList& nreglist);
1748 };
1749 
Align_align_5(Alignment align,const NeonRegisterList & nreglist)1750 Align_align_5::Align_align_5(Alignment align,
1751                              const NeonRegisterList& nreglist) {
1752   switch (align.GetType()) {
1753     case k64BitAlign:
1754       SetEncodingValue(0x1);
1755       break;
1756     case k128BitAlign:
1757       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1758         SetEncodingValue(0x2);
1759       break;
1760     case k256BitAlign:
1761       if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1762       break;
1763     case kNoAlignment:
1764       SetEncodingValue(0x0);
1765       break;
1766     default:
1767       break;
1768   }
1769 }
1770 
1771 
1772 // CBNZ{<q>} <Rn>, <label> ; T1
1773 // CBZ{<q>} <Rn>, <label> ; T1
1774 static const struct ReferenceInfo kT16CbzInfo =
1775     {k16BitT32InstructionSizeInBytes,
1776      0,    // Min offset.
1777      126,  // Max offset.
1778      2,    // Alignment.
1779      ReferenceInfo::kDontAlignPc};
1780 
1781 
1782 // B<c>{<q>} <label> ; T1
1783 static const struct ReferenceInfo kT16ConditionalBranchInfo =
1784     {k16BitT32InstructionSizeInBytes,
1785      -256,  // Min offset.
1786      254,   // Max offset.
1787      2,     // Alignment.
1788      ReferenceInfo::kDontAlignPc};
1789 
1790 
1791 // ADR{<c>}{<q>} <Rd>, <label> ; T1
1792 // LDR{<c>}{<q>} <Rt>, <label> ; T1
1793 static const struct ReferenceInfo kT16DataInfo =
1794     {k16BitT32InstructionSizeInBytes,
1795      0,     // Min offset.
1796      1020,  // Max offset.
1797      4,     // Alignment.
1798      ReferenceInfo::kAlignPc};
1799 
1800 
1801 // B{<c>}{<q>} <label> ; T2
1802 static const struct ReferenceInfo kT16BranchInfo =
1803     {k16BitT32InstructionSizeInBytes,
1804      -2048,  // Min offset.
1805      2046,   // Max offset.
1806      2,      // Alignment.
1807      ReferenceInfo::kDontAlignPc};
1808 
1809 
1810 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
1811 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
1812 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
1813 static const struct ReferenceInfo kT32DataInfo =
1814     {k32BitT32InstructionSizeInBytes,
1815      -1020,  // Min offset.
1816      1020,   // Max offset.
1817      4,      // Alignment.
1818      ReferenceInfo::kAlignPc};
1819 
1820 
1821 // ADR{<c>}{<q>} <Rd>, <label> ; T3
1822 // LDR{<c>}{<q>} <Rt>, <label> ; T2
1823 // LDRB{<c>}{<q>} <Rt>, <label> ; T1
1824 // LDRH{<c>}{<q>} <Rt>, <label> ; T1
1825 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
1826 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
1827 // PLD{<c>}{<q>} <label> ; T1
1828 // PLI{<c>}{<q>} <label> ; T3
1829 static const struct ReferenceInfo kT32FarDataInfo =
1830     {k32BitT32InstructionSizeInBytes,
1831      -4095,  // Min offset.
1832      4095,   // Max offset.
1833      1,      // Alignment.
1834      ReferenceInfo::kAlignPc};
1835 
1836 
1837 // B<c>{<q>} <label> ; T3
1838 static const struct ReferenceInfo kT32ConditionalBranchInfo =
1839     {k32BitT32InstructionSizeInBytes,
1840      -1048576,  // Min offset.
1841      1048574,   // Max offset.
1842      2,         // Alignment.
1843      ReferenceInfo::kDontAlignPc};
1844 
1845 
1846 // B{<c>}{<q>} <label> ; T4
1847 // BL{<c>}{<q>} <label> ; T1
1848 static const struct ReferenceInfo kT32BranchInfo =
1849     {k32BitT32InstructionSizeInBytes,
1850      -16777216,  // Min offset.
1851      16777214,   // Max offset.
1852      2,          // Alignment.
1853      ReferenceInfo::kDontAlignPc};
1854 
1855 
1856 // BLX{<c>}{<q>} <label> ; T2
1857 static const struct ReferenceInfo kT32BlxInfo =
1858     {k32BitT32InstructionSizeInBytes,
1859      -16777216,  // Min offset.
1860      16777212,   // Max offset.
1861      4,          // Alignment.
1862      ReferenceInfo::kAlignPc};
1863 
1864 
1865 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
1866 // LDRH{<c>}{<q>} <Rt>, <label> ; A1
1867 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
1868 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
1869 static const struct ReferenceInfo kA32VeryNearDataInfo =
1870     {kA32InstructionSizeInBytes,
1871      -255,  // Min offset.
1872      255,   // Max offset.
1873      1,     // Alignment.
1874      ReferenceInfo::kAlignPc};
1875 
1876 
1877 // ADR{<c>}{<q>} <Rd>, <label> ; A1
1878 static const struct ReferenceInfo kA32AdrInfo = {kA32InstructionSizeInBytes,
1879                                                  -256,  // Min offset.
1880                                                  256,   // Max offset.
1881                                                  1,     // Alignment.
1882                                                  ReferenceInfo::kAlignPc};
1883 
1884 
1885 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
1886 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
1887 static const struct ReferenceInfo kA32DataInfo = {kA32InstructionSizeInBytes,
1888                                                   -1020,  // Min offset.
1889                                                   1020,   // Max offset.
1890                                                   4,      // Alignment.
1891                                                   ReferenceInfo::kAlignPc};
1892 
1893 
1894 // LDR{<c>}{<q>} <Rt>, <label> ; A1
1895 // LDRB{<c>}{<q>} <Rt>, <label> ; A1
1896 // PLD{<c>}{<q>} <label> ; A1
1897 // PLI{<c>}{<q>} <label> ; A1
1898 static const struct ReferenceInfo kA32FarDataInfo = {kA32InstructionSizeInBytes,
1899                                                      -4095,  // Min offset.
1900                                                      4095,   // Max offset.
1901                                                      1,      // Alignment.
1902                                                      ReferenceInfo::kAlignPc};
1903 
1904 
1905 // B{<c>}{<q>} <label> ; A1
1906 // BL{<c>}{<q>} <label> ; A1
1907 static const struct ReferenceInfo kA32BranchInfo =
1908     {kA32InstructionSizeInBytes,
1909      -33554432,  // Min offset.
1910      33554428,   // Max offset.
1911      4,          // Alignment.
1912      ReferenceInfo::kDontAlignPc};
1913 
1914 
1915 // BLX{<c>}{<q>} <label> ; A2
1916 static const struct ReferenceInfo kA32BlxInfo = {kA32InstructionSizeInBytes,
1917                                                  -33554432,  // Min offset.
1918                                                  33554430,   // Max offset.
1919                                                  2,          // Alignment.
1920                                                  ReferenceInfo::kAlignPc};
1921 
1922 
adc(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)1923 void Assembler::adc(Condition cond,
1924                     EncodingSize size,
1925                     Register rd,
1926                     Register rn,
1927                     const Operand& operand) {
1928   VIXL_ASSERT(AllowAssembler());
1929   CheckIT(cond);
1930   if (operand.IsImmediate()) {
1931     uint32_t imm = operand.GetImmediate();
1932     if (IsUsingT32()) {
1933       ImmediateT32 immediate_t32(imm);
1934       // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
1935       if (!size.IsNarrow() && immediate_t32.IsValid() &&
1936           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
1937         EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1938                    (immediate_t32.GetEncodingValue() & 0xff) |
1939                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
1940                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
1941         AdvanceIT();
1942         return;
1943       }
1944     } else {
1945       ImmediateA32 immediate_a32(imm);
1946       // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
1947       if (immediate_a32.IsValid() && cond.IsNotNever()) {
1948         EmitA32(0x02a00000U | (cond.GetCondition() << 28) |
1949                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
1950                 immediate_a32.GetEncodingValue());
1951         return;
1952       }
1953     }
1954   }
1955   if (operand.IsImmediateShiftedRegister()) {
1956     Register rm = operand.GetBaseRegister();
1957     if (operand.IsPlainRegister()) {
1958       if (IsUsingT32()) {
1959         // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
1960         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1961             rm.IsLow()) {
1962           EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
1963           AdvanceIT();
1964           return;
1965         }
1966       }
1967     }
1968     Shift shift = operand.GetShift();
1969     uint32_t amount = operand.GetShiftAmount();
1970     if (IsUsingT32()) {
1971       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
1972       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
1973           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
1974         uint32_t amount_ = amount % 32;
1975         EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1976                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
1977                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
1978         AdvanceIT();
1979         return;
1980       }
1981     } else {
1982       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
1983       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
1984         uint32_t amount_ = amount % 32;
1985         EmitA32(0x00a00000U | (cond.GetCondition() << 28) |
1986                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1987                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
1988         return;
1989       }
1990     }
1991   }
1992   if (operand.IsRegisterShiftedRegister()) {
1993     Register rm = operand.GetBaseRegister();
1994     Shift shift = operand.GetShift();
1995     Register rs = operand.GetShiftRegister();
1996     if (IsUsingA32()) {
1997       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
1998       if (cond.IsNotNever() &&
1999           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2000            AllowUnpredictable())) {
2001         EmitA32(0x00a00010U | (cond.GetCondition() << 28) |
2002                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2003                 (shift.GetType() << 5) | (rs.GetCode() << 8));
2004         return;
2005       }
2006     }
2007   }
2008   Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand);
2009 }
2010 
adcs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2011 void Assembler::adcs(Condition cond,
2012                      EncodingSize size,
2013                      Register rd,
2014                      Register rn,
2015                      const Operand& operand) {
2016   VIXL_ASSERT(AllowAssembler());
2017   CheckIT(cond);
2018   if (operand.IsImmediate()) {
2019     uint32_t imm = operand.GetImmediate();
2020     if (IsUsingT32()) {
2021       ImmediateT32 immediate_t32(imm);
2022       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2023       if (!size.IsNarrow() && immediate_t32.IsValid() &&
2024           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
2025         EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2026                    (immediate_t32.GetEncodingValue() & 0xff) |
2027                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2028                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2029         AdvanceIT();
2030         return;
2031       }
2032     } else {
2033       ImmediateA32 immediate_a32(imm);
2034       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2035       if (immediate_a32.IsValid() && cond.IsNotNever()) {
2036         EmitA32(0x02b00000U | (cond.GetCondition() << 28) |
2037                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2038                 immediate_a32.GetEncodingValue());
2039         return;
2040       }
2041     }
2042   }
2043   if (operand.IsImmediateShiftedRegister()) {
2044     Register rm = operand.GetBaseRegister();
2045     if (operand.IsPlainRegister()) {
2046       if (IsUsingT32()) {
2047         // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2048         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2049             rm.IsLow()) {
2050           EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
2051           AdvanceIT();
2052           return;
2053         }
2054       }
2055     }
2056     Shift shift = operand.GetShift();
2057     uint32_t amount = operand.GetShiftAmount();
2058     if (IsUsingT32()) {
2059       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2060       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
2061           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2062         uint32_t amount_ = amount % 32;
2063         EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2064                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2065                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2066         AdvanceIT();
2067         return;
2068       }
2069     } else {
2070       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2071       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2072         uint32_t amount_ = amount % 32;
2073         EmitA32(0x00b00000U | (cond.GetCondition() << 28) |
2074                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2075                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2076         return;
2077       }
2078     }
2079   }
2080   if (operand.IsRegisterShiftedRegister()) {
2081     Register rm = operand.GetBaseRegister();
2082     Shift shift = operand.GetShift();
2083     Register rs = operand.GetShiftRegister();
2084     if (IsUsingA32()) {
2085       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2086       if (cond.IsNotNever() &&
2087           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2088            AllowUnpredictable())) {
2089         EmitA32(0x00b00010U | (cond.GetCondition() << 28) |
2090                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2091                 (shift.GetType() << 5) | (rs.GetCode() << 8));
2092         return;
2093       }
2094     }
2095   }
2096   Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand);
2097 }
2098 
add(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2099 void Assembler::add(Condition cond,
2100                     EncodingSize size,
2101                     Register rd,
2102                     Register rn,
2103                     const Operand& operand) {
2104   VIXL_ASSERT(AllowAssembler());
2105   CheckIT(cond);
2106   if (operand.IsImmediate()) {
2107     uint32_t imm = operand.GetImmediate();
2108     if (IsUsingT32()) {
2109       ImmediateT32 immediate_t32(imm);
2110       // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1
2111       if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) &&
2112           ((imm % 4) == 0)) {
2113         uint32_t imm_ = imm >> 2;
2114         EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_);
2115         AdvanceIT();
2116         return;
2117       }
2118       // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
2119       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2120           (imm <= 7)) {
2121         EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
2122         AdvanceIT();
2123         return;
2124       }
2125       // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
2126       if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2127           (imm <= 255)) {
2128         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2129         AdvanceIT();
2130         return;
2131       }
2132       // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1
2133       if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) &&
2134           ((imm % 4) == 0)) {
2135         uint32_t imm_ = imm >> 2;
2136         EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_);
2137         AdvanceIT();
2138         return;
2139       }
2140       // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2
2141       if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
2142           ((imm % 4) == 0)) {
2143         uint32_t imm_ = imm >> 2;
2144         EmitT32_16(0xb000 | imm_);
2145         AdvanceIT();
2146         return;
2147       }
2148       // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2149       if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
2150           (!rd.IsPC() || AllowUnpredictable())) {
2151         EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2152                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2153         AdvanceIT();
2154         return;
2155       }
2156       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2157       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
2158           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
2159         EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2160                    (immediate_t32.GetEncodingValue() & 0xff) |
2161                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2162                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2163         AdvanceIT();
2164         return;
2165       }
2166       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2167       if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
2168           (!rd.IsPC() || AllowUnpredictable())) {
2169         EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2170                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2171         AdvanceIT();
2172         return;
2173       }
2174       // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2175       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
2176           (!rd.IsPC() || AllowUnpredictable())) {
2177         EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) |
2178                    (immediate_t32.GetEncodingValue() & 0xff) |
2179                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2180                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2181         AdvanceIT();
2182         return;
2183       }
2184       // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2185       if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
2186           (!rd.IsPC() || AllowUnpredictable())) {
2187         EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2188                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2189         AdvanceIT();
2190         return;
2191       }
2192     } else {
2193       ImmediateA32 immediate_a32(imm);
2194       // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1
2195       if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
2196         EmitA32(0x028f0000U | (cond.GetCondition() << 28) |
2197                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2198         return;
2199       }
2200       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2201       if (immediate_a32.IsValid() && cond.IsNotNever() &&
2202           ((rn.GetCode() & 0xd) != 0xd)) {
2203         EmitA32(0x02800000U | (cond.GetCondition() << 28) |
2204                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2205                 immediate_a32.GetEncodingValue());
2206         return;
2207       }
2208       // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2209       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2210         EmitA32(0x028d0000U | (cond.GetCondition() << 28) |
2211                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2212         return;
2213       }
2214     }
2215   }
2216   if (operand.IsImmediateShiftedRegister()) {
2217     Register rm = operand.GetBaseRegister();
2218     if (operand.IsPlainRegister()) {
2219       if (IsUsingT32()) {
2220         // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
2221         if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2222             rm.IsLow()) {
2223           EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2224                      (rm.GetCode() << 6));
2225           AdvanceIT();
2226           return;
2227         }
2228         // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2
2229         if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) &&
2230             (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
2231               (!rd.IsPC() || !rm.IsPC())) ||
2232              AllowUnpredictable())) {
2233           EmitT32_16(0x4400 | (rd.GetCode() & 0x7) |
2234                      ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
2235           AdvanceIT();
2236           return;
2237         }
2238         // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1
2239         if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) &&
2240             ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
2241              AllowUnpredictable())) {
2242           EmitT32_16(0x4468 | (rd.GetCode() & 0x7) |
2243                      ((rd.GetCode() & 0x8) << 4));
2244           AdvanceIT();
2245           return;
2246         }
2247         // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2
2248         if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) {
2249           EmitT32_16(0x4485 | (rm.GetCode() << 3));
2250           AdvanceIT();
2251           return;
2252         }
2253       }
2254     }
2255     Shift shift = operand.GetShift();
2256     uint32_t amount = operand.GetShiftAmount();
2257     if (IsUsingT32()) {
2258       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2259       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
2260           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2261         uint32_t amount_ = amount % 32;
2262         EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2263                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2264                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2265         AdvanceIT();
2266         return;
2267       }
2268       // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2269       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
2270           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2271         uint32_t amount_ = amount % 32;
2272         EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2273                    (operand.GetTypeEncodingValue() << 4) |
2274                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2275         AdvanceIT();
2276         return;
2277       }
2278     } else {
2279       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2280       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2281         uint32_t amount_ = amount % 32;
2282         EmitA32(0x00800000U | (cond.GetCondition() << 28) |
2283                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2284                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2285         return;
2286       }
2287       // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2288       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2289         uint32_t amount_ = amount % 32;
2290         EmitA32(0x008d0000U | (cond.GetCondition() << 28) |
2291                 (rd.GetCode() << 12) | rm.GetCode() |
2292                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2293         return;
2294       }
2295     }
2296   }
2297   if (operand.IsRegisterShiftedRegister()) {
2298     Register rm = operand.GetBaseRegister();
2299     Shift shift = operand.GetShift();
2300     Register rs = operand.GetShiftRegister();
2301     if (IsUsingA32()) {
2302       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2303       if (cond.IsNotNever() &&
2304           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2305            AllowUnpredictable())) {
2306         EmitA32(0x00800010U | (cond.GetCondition() << 28) |
2307                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2308                 (shift.GetType() << 5) | (rs.GetCode() << 8));
2309         return;
2310       }
2311     }
2312   }
2313   Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand);
2314 }
2315 
add(Condition cond,Register rd,const Operand & operand)2316 void Assembler::add(Condition cond, Register rd, const Operand& operand) {
2317   VIXL_ASSERT(AllowAssembler());
2318   CheckIT(cond);
2319   if (operand.IsImmediate()) {
2320     uint32_t imm = operand.GetImmediate();
2321     if (IsUsingT32()) {
2322       // ADD<c>{<q>} <Rdn>, #<imm8> ; T2
2323       if (InITBlock() && rd.IsLow() && (imm <= 255)) {
2324         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2325         AdvanceIT();
2326         return;
2327       }
2328     }
2329   }
2330   if (operand.IsPlainRegister()) {
2331     Register rm = operand.GetBaseRegister();
2332     if (IsUsingT32()) {
2333       // ADD<c>{<q>} <Rdn>, <Rm> ; T2
2334       if (InITBlock() && !rm.Is(sp) &&
2335           (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
2336             (!rd.IsPC() || !rm.IsPC())) ||
2337            AllowUnpredictable())) {
2338         EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) |
2339                    (rm.GetCode() << 3));
2340         AdvanceIT();
2341         return;
2342       }
2343     }
2344   }
2345   Delegate(kAdd, &Assembler::add, cond, rd, operand);
2346 }
2347 
adds(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2348 void Assembler::adds(Condition cond,
2349                      EncodingSize size,
2350                      Register rd,
2351                      Register rn,
2352                      const Operand& operand) {
2353   VIXL_ASSERT(AllowAssembler());
2354   CheckIT(cond);
2355   if (operand.IsImmediate()) {
2356     uint32_t imm = operand.GetImmediate();
2357     if (IsUsingT32()) {
2358       ImmediateT32 immediate_t32(imm);
2359       // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1
2360       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2361           (imm <= 7)) {
2362         EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
2363         AdvanceIT();
2364         return;
2365       }
2366       // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
2367       if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2368           (imm <= 255)) {
2369         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2370         AdvanceIT();
2371         return;
2372       }
2373       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2374       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
2375           !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) {
2376         EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2377                    (immediate_t32.GetEncodingValue() & 0xff) |
2378                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2379                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2380         AdvanceIT();
2381         return;
2382       }
2383       // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2384       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
2385           !rd.Is(pc)) {
2386         EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) |
2387                    (immediate_t32.GetEncodingValue() & 0xff) |
2388                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2389                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2390         AdvanceIT();
2391         return;
2392       }
2393     } else {
2394       ImmediateA32 immediate_a32(imm);
2395       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2396       if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
2397         EmitA32(0x02900000U | (cond.GetCondition() << 28) |
2398                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2399                 immediate_a32.GetEncodingValue());
2400         return;
2401       }
2402       // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2403       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2404         EmitA32(0x029d0000U | (cond.GetCondition() << 28) |
2405                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2406         return;
2407       }
2408     }
2409   }
2410   if (operand.IsImmediateShiftedRegister()) {
2411     Register rm = operand.GetBaseRegister();
2412     if (operand.IsPlainRegister()) {
2413       if (IsUsingT32()) {
2414         // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
2415         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2416             rm.IsLow()) {
2417           EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2418                      (rm.GetCode() << 6));
2419           AdvanceIT();
2420           return;
2421         }
2422       }
2423     }
2424     Shift shift = operand.GetShift();
2425     uint32_t amount = operand.GetShiftAmount();
2426     if (IsUsingT32()) {
2427       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2428       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
2429           !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2430         uint32_t amount_ = amount % 32;
2431         EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2432                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2433                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2434         AdvanceIT();
2435         return;
2436       }
2437       // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2438       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
2439           !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) {
2440         uint32_t amount_ = amount % 32;
2441         EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2442                    (operand.GetTypeEncodingValue() << 4) |
2443                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2444         AdvanceIT();
2445         return;
2446       }
2447     } else {
2448       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2449       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2450         uint32_t amount_ = amount % 32;
2451         EmitA32(0x00900000U | (cond.GetCondition() << 28) |
2452                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2453                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2454         return;
2455       }
2456       // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2457       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2458         uint32_t amount_ = amount % 32;
2459         EmitA32(0x009d0000U | (cond.GetCondition() << 28) |
2460                 (rd.GetCode() << 12) | rm.GetCode() |
2461                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2462         return;
2463       }
2464     }
2465   }
2466   if (operand.IsRegisterShiftedRegister()) {
2467     Register rm = operand.GetBaseRegister();
2468     Shift shift = operand.GetShift();
2469     Register rs = operand.GetShiftRegister();
2470     if (IsUsingA32()) {
2471       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2472       if (cond.IsNotNever() &&
2473           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2474            AllowUnpredictable())) {
2475         EmitA32(0x00900010U | (cond.GetCondition() << 28) |
2476                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2477                 (shift.GetType() << 5) | (rs.GetCode() << 8));
2478         return;
2479       }
2480     }
2481   }
2482   Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand);
2483 }
2484 
adds(Register rd,const Operand & operand)2485 void Assembler::adds(Register rd, const Operand& operand) {
2486   VIXL_ASSERT(AllowAssembler());
2487   CheckIT(al);
2488   if (operand.IsImmediate()) {
2489     uint32_t imm = operand.GetImmediate();
2490     if (IsUsingT32()) {
2491       // ADDS{<q>} <Rdn>, #<imm8> ; T2
2492       if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
2493         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2494         AdvanceIT();
2495         return;
2496       }
2497     }
2498   }
2499   Delegate(kAdds, &Assembler::adds, rd, operand);
2500 }
2501 
addw(Condition cond,Register rd,Register rn,const Operand & operand)2502 void Assembler::addw(Condition cond,
2503                      Register rd,
2504                      Register rn,
2505                      const Operand& operand) {
2506   VIXL_ASSERT(AllowAssembler());
2507   CheckIT(cond);
2508   if (operand.IsImmediate()) {
2509     uint32_t imm = operand.GetImmediate();
2510     if (IsUsingT32()) {
2511       // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2512       if (rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2513         EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2514                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2515         AdvanceIT();
2516         return;
2517       }
2518       // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2519       if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
2520           (!rd.IsPC() || AllowUnpredictable())) {
2521         EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2522                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2523         AdvanceIT();
2524         return;
2525       }
2526       // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2527       if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2528         EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2529                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2530         AdvanceIT();
2531         return;
2532       }
2533     }
2534   }
2535   Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand);
2536 }
2537 
adr(Condition cond,EncodingSize size,Register rd,Location * location)2538 void Assembler::adr(Condition cond,
2539                     EncodingSize size,
2540                     Register rd,
2541                     Location* location) {
2542   VIXL_ASSERT(AllowAssembler());
2543   CheckIT(cond);
2544   Location::Offset offset =
2545       location->IsBound()
2546           ? location->GetLocation() -
2547                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
2548           : 0;
2549   if (IsUsingT32()) {
2550     int32_t neg_offset = -offset;
2551     // ADR{<c>}{<q>} <Rd>, <label> ; T1
2552     if (!size.IsWide() && rd.IsLow() &&
2553         ((location->IsBound() && (offset >= 0) && (offset <= 1020) &&
2554           ((offset & 0x3) == 0)) ||
2555          (!location->IsBound() && size.IsNarrow()))) {
2556       static class EmitOp : public Location::EmitOperator {
2557        public:
2558         EmitOp() : Location::EmitOperator(T32) {}
2559         virtual uint32_t Encode(uint32_t instr,
2560                                 Location::Offset pc,
2561                                 const Location* location) const VIXL_OVERRIDE {
2562           pc += kT32PcDelta;
2563           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
2564           VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
2565                       ((offset & 0x3) == 0));
2566           const int32_t target = offset >> 2;
2567           return instr | (target & 0xff);
2568         }
2569       } immop;
2570       EmitT32_16(
2571           Link(0xa000 | (rd.GetCode() << 8), location, immop, &kT16DataInfo));
2572       AdvanceIT();
2573       return;
2574     }
2575     // ADR{<c>}{<q>} <Rd>, <label> ; T2
2576     if (!size.IsNarrow() && location->IsBound() && (neg_offset > 0) &&
2577         (neg_offset <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2578       EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) |
2579                  ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15));
2580       AdvanceIT();
2581       return;
2582     }
2583     // ADR{<c>}{<q>} <Rd>, <label> ; T3
2584     if (!size.IsNarrow() &&
2585         (!location->IsBound() || ((offset >= 0) && (offset <= 4095))) &&
2586         (!rd.IsPC() || AllowUnpredictable())) {
2587       static class EmitOp : public Location::EmitOperator {
2588        public:
2589         EmitOp() : Location::EmitOperator(T32) {}
2590         virtual uint32_t Encode(uint32_t instr,
2591                                 Location::Offset pc,
2592                                 const Location* location) const VIXL_OVERRIDE {
2593           pc += kT32PcDelta;
2594           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
2595           int32_t target;
2596           if ((offset >= 0) && (offset <= 4095)) {
2597             target = offset;
2598           } else {
2599             target = -offset;
2600             VIXL_ASSERT((target >= 0) && (target <= 4095));
2601             // Emit the T2 encoding.
2602             instr |= 0x00a00000;
2603           }
2604           return instr | (target & 0xff) | ((target & 0x700) << 4) |
2605                  ((target & 0x800) << 15);
2606         }
2607       } immop;
2608       EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8),
2609                       location,
2610                       immop,
2611                       &kT32FarDataInfo));
2612       AdvanceIT();
2613       return;
2614     }
2615   } else {
2616     ImmediateA32 positive_immediate_a32(offset);
2617     ImmediateA32 negative_immediate_a32(-offset);
2618     // ADR{<c>}{<q>} <Rd>, <label> ; A1
2619     if ((!location->IsBound() || positive_immediate_a32.IsValid()) &&
2620         cond.IsNotNever()) {
2621       static class EmitOp : public Location::EmitOperator {
2622        public:
2623         EmitOp() : Location::EmitOperator(A32) {}
2624         virtual uint32_t Encode(uint32_t instr,
2625                                 Location::Offset pc,
2626                                 const Location* location) const VIXL_OVERRIDE {
2627           pc += kA32PcDelta;
2628           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
2629           int32_t target;
2630           ImmediateA32 positive_immediate_a32(offset);
2631           if (positive_immediate_a32.IsValid()) {
2632             target = positive_immediate_a32.GetEncodingValue();
2633           } else {
2634             ImmediateA32 negative_immediate_a32(-offset);
2635             VIXL_ASSERT(negative_immediate_a32.IsValid());
2636             // Emit the A2 encoding.
2637             target = negative_immediate_a32.GetEncodingValue();
2638             instr = (instr & ~0x00f00000) | 0x00400000;
2639           }
2640           return instr | (target & 0xfff);
2641         }
2642       } immop;
2643       EmitA32(
2644           Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12),
2645                location,
2646                immop,
2647                &kA32AdrInfo));
2648       return;
2649     }
2650     // ADR{<c>}{<q>} <Rd>, <label> ; A2
2651     if (location->IsBound() && negative_immediate_a32.IsValid() &&
2652         cond.IsNotNever()) {
2653       EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
2654               negative_immediate_a32.GetEncodingValue());
2655       return;
2656     }
2657   }
2658   Delegate(kAdr, &Assembler::adr, cond, size, rd, location);
2659 }
2660 
adr_info(Condition cond,EncodingSize size,Register rd,Location * location,const struct ReferenceInfo ** info)2661 bool Assembler::adr_info(Condition cond,
2662                          EncodingSize size,
2663                          Register rd,
2664                          Location* location,
2665                          const struct ReferenceInfo** info) {
2666   VIXL_ASSERT(!location->IsBound());
2667   USE(location);
2668   if (IsUsingT32()) {
2669     // ADR{<c>}{<q>} <Rd>, <label> ; T1
2670     if (!size.IsWide() && rd.IsLow() && size.IsNarrow()) {
2671       *info = &kT16DataInfo;
2672       return true;
2673     }
2674     // Skipped T2, as it is a negative offset variant.
2675     // The minimum offset is included in the corresponding
2676     // positive variant.
2677     // ADR{<c>}{<q>} <Rd>, <label> ; T3
2678     if (!size.IsNarrow()) {
2679       *info = &kT32FarDataInfo;
2680       return true;
2681     }
2682   } else {
2683     // ADR{<c>}{<q>} <Rd>, <label> ; A1
2684     if (cond.IsNotNever()) {
2685       *info = &kA32AdrInfo;
2686       return true;
2687     }
2688     // Skipped A2, as it is a negative offset variant.
2689     // The minimum offset is included in the corresponding
2690     // positive variant.
2691   }
2692   return false;
2693 }
2694 
and_(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2695 void Assembler::and_(Condition cond,
2696                      EncodingSize size,
2697                      Register rd,
2698                      Register rn,
2699                      const Operand& operand) {
2700   VIXL_ASSERT(AllowAssembler());
2701   CheckIT(cond);
2702   if (operand.IsImmediate()) {
2703     uint32_t imm = operand.GetImmediate();
2704     if (IsUsingT32()) {
2705       ImmediateT32 immediate_t32(imm);
2706       // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2707       if (!size.IsNarrow() && immediate_t32.IsValid() &&
2708           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
2709         EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2710                    (immediate_t32.GetEncodingValue() & 0xff) |
2711                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2712                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2713         AdvanceIT();
2714         return;
2715       }
2716     } else {
2717       ImmediateA32 immediate_a32(imm);
2718       // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2719       if (immediate_a32.IsValid() && cond.IsNotNever()) {
2720         EmitA32(0x02000000U | (cond.GetCondition() << 28) |
2721                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2722                 immediate_a32.GetEncodingValue());
2723         return;
2724       }
2725     }
2726   }
2727   if (operand.IsImmediateShiftedRegister()) {
2728     Register rm = operand.GetBaseRegister();
2729     if (operand.IsPlainRegister()) {
2730       if (IsUsingT32()) {
2731         // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2732         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2733             rm.IsLow()) {
2734           EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2735           AdvanceIT();
2736           return;
2737         }
2738       }
2739     }
2740     Shift shift = operand.GetShift();
2741     uint32_t amount = operand.GetShiftAmount();
2742     if (IsUsingT32()) {
2743       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2744       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
2745           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2746         uint32_t amount_ = amount % 32;
2747         EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2748                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2749                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2750         AdvanceIT();
2751         return;
2752       }
2753     } else {
2754       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2755       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2756         uint32_t amount_ = amount % 32;
2757         EmitA32(0x00000000U | (cond.GetCondition() << 28) |
2758                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2759                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2760         return;
2761       }
2762     }
2763   }
2764   if (operand.IsRegisterShiftedRegister()) {
2765     Register rm = operand.GetBaseRegister();
2766     Shift shift = operand.GetShift();
2767     Register rs = operand.GetShiftRegister();
2768     if (IsUsingA32()) {
2769       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2770       if (cond.IsNotNever() &&
2771           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2772            AllowUnpredictable())) {
2773         EmitA32(0x00000010U | (cond.GetCondition() << 28) |
2774                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2775                 (shift.GetType() << 5) | (rs.GetCode() << 8));
2776         return;
2777       }
2778     }
2779   }
2780   Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand);
2781 }
2782 
ands(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2783 void Assembler::ands(Condition cond,
2784                      EncodingSize size,
2785                      Register rd,
2786                      Register rn,
2787                      const Operand& operand) {
2788   VIXL_ASSERT(AllowAssembler());
2789   CheckIT(cond);
2790   if (operand.IsImmediate()) {
2791     uint32_t imm = operand.GetImmediate();
2792     if (IsUsingT32()) {
2793       ImmediateT32 immediate_t32(imm);
2794       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2795       if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) &&
2796           (!rn.IsPC() || AllowUnpredictable())) {
2797         EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2798                    (immediate_t32.GetEncodingValue() & 0xff) |
2799                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2800                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2801         AdvanceIT();
2802         return;
2803       }
2804     } else {
2805       ImmediateA32 immediate_a32(imm);
2806       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2807       if (immediate_a32.IsValid() && cond.IsNotNever()) {
2808         EmitA32(0x02100000U | (cond.GetCondition() << 28) |
2809                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2810                 immediate_a32.GetEncodingValue());
2811         return;
2812       }
2813     }
2814   }
2815   if (operand.IsImmediateShiftedRegister()) {
2816     Register rm = operand.GetBaseRegister();
2817     if (operand.IsPlainRegister()) {
2818       if (IsUsingT32()) {
2819         // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2820         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2821             rm.IsLow()) {
2822           EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2823           AdvanceIT();
2824           return;
2825         }
2826       }
2827     }
2828     Shift shift = operand.GetShift();
2829     uint32_t amount = operand.GetShiftAmount();
2830     if (IsUsingT32()) {
2831       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2832       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) &&
2833           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2834         uint32_t amount_ = amount % 32;
2835         EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2836                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2837                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2838         AdvanceIT();
2839         return;
2840       }
2841     } else {
2842       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2843       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2844         uint32_t amount_ = amount % 32;
2845         EmitA32(0x00100000U | (cond.GetCondition() << 28) |
2846                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2847                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2848         return;
2849       }
2850     }
2851   }
2852   if (operand.IsRegisterShiftedRegister()) {
2853     Register rm = operand.GetBaseRegister();
2854     Shift shift = operand.GetShift();
2855     Register rs = operand.GetShiftRegister();
2856     if (IsUsingA32()) {
2857       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2858       if (cond.IsNotNever() &&
2859           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2860            AllowUnpredictable())) {
2861         EmitA32(0x00100010U | (cond.GetCondition() << 28) |
2862                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2863                 (shift.GetType() << 5) | (rs.GetCode() << 8));
2864         return;
2865       }
2866     }
2867   }
2868   Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand);
2869 }
2870 
asr(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)2871 void Assembler::asr(Condition cond,
2872                     EncodingSize size,
2873                     Register rd,
2874                     Register rm,
2875                     const Operand& operand) {
2876   VIXL_ASSERT(AllowAssembler());
2877   CheckIT(cond);
2878   if (operand.IsImmediate()) {
2879     uint32_t imm = operand.GetImmediate();
2880     if (IsUsingT32()) {
2881       // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2882       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2883           (imm >= 1) && (imm <= 32)) {
2884         uint32_t amount_ = imm % 32;
2885         EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2886                    (amount_ << 6));
2887         AdvanceIT();
2888         return;
2889       }
2890       // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2891       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
2892           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2893         uint32_t amount_ = imm % 32;
2894         EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2895                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2896         AdvanceIT();
2897         return;
2898       }
2899     } else {
2900       // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2901       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2902         uint32_t amount_ = imm % 32;
2903         EmitA32(0x01a00040U | (cond.GetCondition() << 28) |
2904                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2905         return;
2906       }
2907     }
2908   }
2909   if (operand.IsPlainRegister()) {
2910     Register rs = operand.GetBaseRegister();
2911     if (IsUsingT32()) {
2912       // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2913       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2914           rs.IsLow()) {
2915         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2916         AdvanceIT();
2917         return;
2918       }
2919       // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2920       if (!size.IsNarrow() &&
2921           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
2922         EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2923                    rs.GetCode());
2924         AdvanceIT();
2925         return;
2926       }
2927     } else {
2928       // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
2929       if (cond.IsNotNever() &&
2930           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
2931         EmitA32(0x01a00050U | (cond.GetCondition() << 28) |
2932                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
2933         return;
2934       }
2935     }
2936   }
2937   Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand);
2938 }
2939 
asrs(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)2940 void Assembler::asrs(Condition cond,
2941                      EncodingSize size,
2942                      Register rd,
2943                      Register rm,
2944                      const Operand& operand) {
2945   VIXL_ASSERT(AllowAssembler());
2946   CheckIT(cond);
2947   if (operand.IsImmediate()) {
2948     uint32_t imm = operand.GetImmediate();
2949     if (IsUsingT32()) {
2950       // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2951       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2952           (imm >= 1) && (imm <= 32)) {
2953         uint32_t amount_ = imm % 32;
2954         EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2955                    (amount_ << 6));
2956         AdvanceIT();
2957         return;
2958       }
2959       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2960       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
2961           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2962         uint32_t amount_ = imm % 32;
2963         EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2964                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2965         AdvanceIT();
2966         return;
2967       }
2968     } else {
2969       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2970       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2971         uint32_t amount_ = imm % 32;
2972         EmitA32(0x01b00040U | (cond.GetCondition() << 28) |
2973                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2974         return;
2975       }
2976     }
2977   }
2978   if (operand.IsPlainRegister()) {
2979     Register rs = operand.GetBaseRegister();
2980     if (IsUsingT32()) {
2981       // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2982       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2983           rs.IsLow()) {
2984         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2985         AdvanceIT();
2986         return;
2987       }
2988       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2989       if (!size.IsNarrow() &&
2990           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
2991         EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2992                    rs.GetCode());
2993         AdvanceIT();
2994         return;
2995       }
2996     } else {
2997       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
2998       if (cond.IsNotNever() &&
2999           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
3000         EmitA32(0x01b00050U | (cond.GetCondition() << 28) |
3001                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
3002         return;
3003       }
3004     }
3005   }
3006   Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand);
3007 }
3008 
b(Condition cond,EncodingSize size,Location * location)3009 void Assembler::b(Condition cond, EncodingSize size, Location* location) {
3010   VIXL_ASSERT(AllowAssembler());
3011   Location::Offset offset =
3012       location->IsBound()
3013           ? location->GetLocation() -
3014                 (GetCursorOffset() + GetArchitectureStatePCOffset())
3015           : 0;
3016   if (IsUsingT32()) {
3017     // B<c>{<q>} <label> ; T1
3018     if (OutsideITBlock() && !size.IsWide() &&
3019         ((location->IsBound() && (offset >= -256) && (offset <= 254) &&
3020           ((offset & 0x1) == 0)) ||
3021          (!location->IsBound() && size.IsNarrow())) &&
3022         !cond.Is(al) && cond.IsNotNever()) {
3023       static class EmitOp : public Location::EmitOperator {
3024        public:
3025         EmitOp() : Location::EmitOperator(T32) {}
3026         virtual uint32_t Encode(uint32_t instr,
3027                                 Location::Offset pc,
3028                                 const Location* location) const VIXL_OVERRIDE {
3029           pc += kT32PcDelta;
3030           Location::Offset offset = location->GetLocation() - pc;
3031           VIXL_ASSERT((offset >= -256) && (offset <= 254) &&
3032                       ((offset & 0x1) == 0));
3033           const int32_t target = offset >> 1;
3034           return instr | (target & 0xff);
3035         }
3036       } immop;
3037       EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8),
3038                       location,
3039                       immop,
3040                       &kT16ConditionalBranchInfo));
3041       AdvanceIT();
3042       return;
3043     }
3044     // B{<c>}{<q>} <label> ; T2
3045     if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() &&
3046         ((location->IsBound() && (offset >= -2048) && (offset <= 2046) &&
3047           ((offset & 0x1) == 0)) ||
3048          (!location->IsBound() && size.IsNarrow()))) {
3049       CheckIT(cond);
3050       static class EmitOp : public Location::EmitOperator {
3051        public:
3052         EmitOp() : Location::EmitOperator(T32) {}
3053         virtual uint32_t Encode(uint32_t instr,
3054                                 Location::Offset pc,
3055                                 const Location* location) const VIXL_OVERRIDE {
3056           pc += kT32PcDelta;
3057           Location::Offset offset = location->GetLocation() - pc;
3058           VIXL_ASSERT((offset >= -2048) && (offset <= 2046) &&
3059                       ((offset & 0x1) == 0));
3060           const int32_t target = offset >> 1;
3061           return instr | (target & 0x7ff);
3062         }
3063       } immop;
3064       EmitT32_16(Link(0xe000, location, immop, &kT16BranchInfo));
3065       AdvanceIT();
3066       return;
3067     }
3068     // B<c>{<q>} <label> ; T3
3069     if (OutsideITBlock() && !size.IsNarrow() &&
3070         ((location->IsBound() && (offset >= -1048576) && (offset <= 1048574) &&
3071           ((offset & 0x1) == 0)) ||
3072          !location->IsBound()) &&
3073         !cond.Is(al) && cond.IsNotNever()) {
3074       static class EmitOp : public Location::EmitOperator {
3075        public:
3076         EmitOp() : Location::EmitOperator(T32) {}
3077         virtual uint32_t Encode(uint32_t instr,
3078                                 Location::Offset pc,
3079                                 const Location* location) const VIXL_OVERRIDE {
3080           pc += kT32PcDelta;
3081           Location::Offset offset = location->GetLocation() - pc;
3082           VIXL_ASSERT((offset >= -1048576) && (offset <= 1048574) &&
3083                       ((offset & 0x1) == 0));
3084           const int32_t target = offset >> 1;
3085           return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) |
3086                  ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) |
3087                  ((target & 0x80000) << 7);
3088         }
3089       } immop;
3090       EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22),
3091                       location,
3092                       immop,
3093                       &kT32ConditionalBranchInfo));
3094       AdvanceIT();
3095       return;
3096     }
3097     // B{<c>}{<q>} <label> ; T4
3098     if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() &&
3099         ((location->IsBound() && (offset >= -16777216) &&
3100           (offset <= 16777214) && ((offset & 0x1) == 0)) ||
3101          !location->IsBound())) {
3102       CheckIT(cond);
3103       static class EmitOp : public Location::EmitOperator {
3104        public:
3105         EmitOp() : Location::EmitOperator(T32) {}
3106         virtual uint32_t Encode(uint32_t instr,
3107                                 Location::Offset pc,
3108                                 const Location* location) const VIXL_OVERRIDE {
3109           pc += kT32PcDelta;
3110           Location::Offset offset = location->GetLocation() - pc;
3111           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
3112                       ((offset & 0x1) == 0));
3113           int32_t target = offset >> 1;
3114           uint32_t S = target & (1 << 23);
3115           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
3116           return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
3117                  ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
3118                  ((target & 0x800000) << 3);
3119         }
3120       } immop;
3121       EmitT32_32(Link(0xf0009000U, location, immop, &kT32BranchInfo));
3122       AdvanceIT();
3123       return;
3124     }
3125   } else {
3126     // B{<c>}{<q>} <label> ; A1
3127     if (((location->IsBound() && (offset >= -33554432) &&
3128           (offset <= 33554428) && ((offset & 0x3) == 0)) ||
3129          !location->IsBound()) &&
3130         cond.IsNotNever()) {
3131       static class EmitOp : public Location::EmitOperator {
3132        public:
3133         EmitOp() : Location::EmitOperator(A32) {}
3134         virtual uint32_t Encode(uint32_t instr,
3135                                 Location::Offset pc,
3136                                 const Location* location) const VIXL_OVERRIDE {
3137           pc += kA32PcDelta;
3138           Location::Offset offset = location->GetLocation() - pc;
3139           VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
3140                       ((offset & 0x3) == 0));
3141           const int32_t target = offset >> 2;
3142           return instr | (target & 0xffffff);
3143         }
3144       } immop;
3145       EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28),
3146                    location,
3147                    immop,
3148                    &kA32BranchInfo));
3149       return;
3150     }
3151   }
3152   Delegate(kB, &Assembler::b, cond, size, location);
3153 }
3154 
b_info(Condition cond,EncodingSize size,Location * location,const struct ReferenceInfo ** info)3155 bool Assembler::b_info(Condition cond,
3156                        EncodingSize size,
3157                        Location* location,
3158                        const struct ReferenceInfo** info) {
3159   VIXL_ASSERT(!location->IsBound());
3160   USE(location);
3161   if (IsUsingT32()) {
3162     // B<c>{<q>} <label> ; T1
3163     if (OutsideITBlock() && !size.IsWide() && size.IsNarrow() && !cond.Is(al) &&
3164         cond.IsNotNever()) {
3165       *info = &kT16ConditionalBranchInfo;
3166       return true;
3167     }
3168     // B{<c>}{<q>} <label> ; T2
3169     if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() && size.IsNarrow()) {
3170       *info = &kT16BranchInfo;
3171       return true;
3172     }
3173     // B<c>{<q>} <label> ; T3
3174     if (OutsideITBlock() && !size.IsNarrow() && !cond.Is(al) &&
3175         cond.IsNotNever()) {
3176       *info = &kT32ConditionalBranchInfo;
3177       return true;
3178     }
3179     // B{<c>}{<q>} <label> ; T4
3180     if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow()) {
3181       *info = &kT32BranchInfo;
3182       return true;
3183     }
3184   } else {
3185     // B{<c>}{<q>} <label> ; A1
3186     if (cond.IsNotNever()) {
3187       *info = &kA32BranchInfo;
3188       return true;
3189     }
3190   }
3191   return false;
3192 }
3193 
bfc(Condition cond,Register rd,uint32_t lsb,uint32_t width)3194 void Assembler::bfc(Condition cond, Register rd, uint32_t lsb, uint32_t width) {
3195   VIXL_ASSERT(AllowAssembler());
3196   CheckIT(cond);
3197   if (IsUsingT32()) {
3198     // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1
3199     if ((lsb <= 31) && (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
3200                         AllowUnpredictable())) {
3201       uint32_t msb = lsb + width - 1;
3202       EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) |
3203                  ((lsb & 0x1c) << 10) | msb);
3204       AdvanceIT();
3205       return;
3206     }
3207   } else {
3208     // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1
3209     if ((lsb <= 31) && cond.IsNotNever() &&
3210         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
3211          AllowUnpredictable())) {
3212       uint32_t msb = lsb + width - 1;
3213       EmitA32(0x07c0001fU | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3214               (lsb << 7) | (msb << 16));
3215       return;
3216     }
3217   }
3218   Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, width);
3219 }
3220 
bfi(Condition cond,Register rd,Register rn,uint32_t lsb,uint32_t width)3221 void Assembler::bfi(
3222     Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
3223   VIXL_ASSERT(AllowAssembler());
3224   CheckIT(cond);
3225   if (IsUsingT32()) {
3226     // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
3227     if ((lsb <= 31) && !rn.Is(pc) &&
3228         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
3229          AllowUnpredictable())) {
3230       uint32_t msb = lsb + width - 1;
3231       EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3232                  ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb);
3233       AdvanceIT();
3234       return;
3235     }
3236   } else {
3237     // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
3238     if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) &&
3239         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
3240          AllowUnpredictable())) {
3241       uint32_t msb = lsb + width - 1;
3242       EmitA32(0x07c00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3243               rn.GetCode() | (lsb << 7) | (msb << 16));
3244       return;
3245     }
3246   }
3247   Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, width);
3248 }
3249 
bic(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)3250 void Assembler::bic(Condition cond,
3251                     EncodingSize size,
3252                     Register rd,
3253                     Register rn,
3254                     const Operand& operand) {
3255   VIXL_ASSERT(AllowAssembler());
3256   CheckIT(cond);
3257   if (operand.IsImmediate()) {
3258     uint32_t imm = operand.GetImmediate();
3259     if (IsUsingT32()) {
3260       ImmediateT32 immediate_t32(imm);
3261       // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3262       if (!size.IsNarrow() && immediate_t32.IsValid() &&
3263           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
3264         EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3265                    (immediate_t32.GetEncodingValue() & 0xff) |
3266                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3267                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3268         AdvanceIT();
3269         return;
3270       }
3271     } else {
3272       ImmediateA32 immediate_a32(imm);
3273       // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3274       if (immediate_a32.IsValid() && cond.IsNotNever()) {
3275         EmitA32(0x03c00000U | (cond.GetCondition() << 28) |
3276                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3277                 immediate_a32.GetEncodingValue());
3278         return;
3279       }
3280     }
3281   }
3282   if (operand.IsImmediateShiftedRegister()) {
3283     Register rm = operand.GetBaseRegister();
3284     if (operand.IsPlainRegister()) {
3285       if (IsUsingT32()) {
3286         // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3287         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3288             rm.IsLow()) {
3289           EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3290           AdvanceIT();
3291           return;
3292         }
3293       }
3294     }
3295     Shift shift = operand.GetShift();
3296     uint32_t amount = operand.GetShiftAmount();
3297     if (IsUsingT32()) {
3298       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3299       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
3300           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3301         uint32_t amount_ = amount % 32;
3302         EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3303                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3304                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3305         AdvanceIT();
3306         return;
3307       }
3308     } else {
3309       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3310       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3311         uint32_t amount_ = amount % 32;
3312         EmitA32(0x01c00000U | (cond.GetCondition() << 28) |
3313                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3314                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3315         return;
3316       }
3317     }
3318   }
3319   if (operand.IsRegisterShiftedRegister()) {
3320     Register rm = operand.GetBaseRegister();
3321     Shift shift = operand.GetShift();
3322     Register rs = operand.GetShiftRegister();
3323     if (IsUsingA32()) {
3324       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3325       if (cond.IsNotNever() &&
3326           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
3327            AllowUnpredictable())) {
3328         EmitA32(0x01c00010U | (cond.GetCondition() << 28) |
3329                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3330                 (shift.GetType() << 5) | (rs.GetCode() << 8));
3331         return;
3332       }
3333     }
3334   }
3335   Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand);
3336 }
3337 
bics(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)3338 void Assembler::bics(Condition cond,
3339                      EncodingSize size,
3340                      Register rd,
3341                      Register rn,
3342                      const Operand& operand) {
3343   VIXL_ASSERT(AllowAssembler());
3344   CheckIT(cond);
3345   if (operand.IsImmediate()) {
3346     uint32_t imm = operand.GetImmediate();
3347     if (IsUsingT32()) {
3348       ImmediateT32 immediate_t32(imm);
3349       // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3350       if (!size.IsNarrow() && immediate_t32.IsValid() &&
3351           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
3352         EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3353                    (immediate_t32.GetEncodingValue() & 0xff) |
3354                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3355                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3356         AdvanceIT();
3357         return;
3358       }
3359     } else {
3360       ImmediateA32 immediate_a32(imm);
3361       // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3362       if (immediate_a32.IsValid() && cond.IsNotNever()) {
3363         EmitA32(0x03d00000U | (cond.GetCondition() << 28) |
3364                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3365                 immediate_a32.GetEncodingValue());
3366         return;
3367       }
3368     }
3369   }
3370   if (operand.IsImmediateShiftedRegister()) {
3371     Register rm = operand.GetBaseRegister();
3372     if (operand.IsPlainRegister()) {
3373       if (IsUsingT32()) {
3374         // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3375         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3376             rm.IsLow()) {
3377           EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3378           AdvanceIT();
3379           return;
3380         }
3381       }
3382     }
3383     Shift shift = operand.GetShift();
3384     uint32_t amount = operand.GetShiftAmount();
3385     if (IsUsingT32()) {
3386       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3387       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
3388           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3389         uint32_t amount_ = amount % 32;
3390         EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3391                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3392                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3393         AdvanceIT();
3394         return;
3395       }
3396     } else {
3397       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3398       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3399         uint32_t amount_ = amount % 32;
3400         EmitA32(0x01d00000U | (cond.GetCondition() << 28) |
3401                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3402                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3403         return;
3404       }
3405     }
3406   }
3407   if (operand.IsRegisterShiftedRegister()) {
3408     Register rm = operand.GetBaseRegister();
3409     Shift shift = operand.GetShift();
3410     Register rs = operand.GetShiftRegister();
3411     if (IsUsingA32()) {
3412       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3413       if (cond.IsNotNever() &&
3414           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
3415            AllowUnpredictable())) {
3416         EmitA32(0x01d00010U | (cond.GetCondition() << 28) |
3417                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3418                 (shift.GetType() << 5) | (rs.GetCode() << 8));
3419         return;
3420       }
3421     }
3422   }
3423   Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand);
3424 }
3425 
bkpt(Condition cond,uint32_t imm)3426 void Assembler::bkpt(Condition cond, uint32_t imm) {
3427   VIXL_ASSERT(AllowAssembler());
3428   CheckIT(cond);
3429   if (IsUsingT32()) {
3430     // BKPT{<q>} {#}<imm> ; T1
3431     if ((imm <= 255)) {
3432       EmitT32_16(0xbe00 | imm);
3433       AdvanceIT();
3434       return;
3435     }
3436   } else {
3437     // BKPT{<q>} {#}<imm> ; A1
3438     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
3439       EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) |
3440               ((imm & 0xfff0) << 4));
3441       return;
3442     }
3443   }
3444   Delegate(kBkpt, &Assembler::bkpt, cond, imm);
3445 }
3446 
bl(Condition cond,Location * location)3447 void Assembler::bl(Condition cond, Location* location) {
3448   VIXL_ASSERT(AllowAssembler());
3449   CheckIT(cond);
3450   Location::Offset offset =
3451       location->IsBound()
3452           ? location->GetLocation() -
3453                 (GetCursorOffset() + GetArchitectureStatePCOffset())
3454           : 0;
3455   if (IsUsingT32()) {
3456     // BL{<c>}{<q>} <label> ; T1
3457     if (((location->IsBound() && (offset >= -16777216) &&
3458           (offset <= 16777214) && ((offset & 0x1) == 0)) ||
3459          !location->IsBound()) &&
3460         (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
3461       static class EmitOp : public Location::EmitOperator {
3462        public:
3463         EmitOp() : Location::EmitOperator(T32) {}
3464         virtual uint32_t Encode(uint32_t instr,
3465                                 Location::Offset pc,
3466                                 const Location* location) const VIXL_OVERRIDE {
3467           pc += kT32PcDelta;
3468           Location::Offset offset = location->GetLocation() - pc;
3469           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
3470                       ((offset & 0x1) == 0));
3471           int32_t target = offset >> 1;
3472           uint32_t S = target & (1 << 23);
3473           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
3474           return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
3475                  ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
3476                  ((target & 0x800000) << 3);
3477         }
3478       } immop;
3479       EmitT32_32(Link(0xf000d000U, location, immop, &kT32BranchInfo));
3480       AdvanceIT();
3481       return;
3482     }
3483   } else {
3484     // BL{<c>}{<q>} <label> ; A1
3485     if (((location->IsBound() && (offset >= -33554432) &&
3486           (offset <= 33554428) && ((offset & 0x3) == 0)) ||
3487          !location->IsBound()) &&
3488         cond.IsNotNever()) {
3489       static class EmitOp : public Location::EmitOperator {
3490        public:
3491         EmitOp() : Location::EmitOperator(A32) {}
3492         virtual uint32_t Encode(uint32_t instr,
3493                                 Location::Offset pc,
3494                                 const Location* location) const VIXL_OVERRIDE {
3495           pc += kA32PcDelta;
3496           Location::Offset offset = location->GetLocation() - pc;
3497           VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
3498                       ((offset & 0x3) == 0));
3499           const int32_t target = offset >> 2;
3500           return instr | (target & 0xffffff);
3501         }
3502       } immop;
3503       EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28),
3504                    location,
3505                    immop,
3506                    &kA32BranchInfo));
3507       return;
3508     }
3509   }
3510   Delegate(kBl, &Assembler::bl, cond, location);
3511 }
3512 
bl_info(Condition cond,Location * location,const struct ReferenceInfo ** info)3513 bool Assembler::bl_info(Condition cond,
3514                         Location* location,
3515                         const struct ReferenceInfo** info) {
3516   VIXL_ASSERT(!location->IsBound());
3517   USE(location);
3518   if (IsUsingT32()) {
3519     // BL{<c>}{<q>} <label> ; T1
3520     if (true) {
3521       *info = &kT32BranchInfo;
3522       return true;
3523     }
3524   } else {
3525     // BL{<c>}{<q>} <label> ; A1
3526     if (cond.IsNotNever()) {
3527       *info = &kA32BranchInfo;
3528       return true;
3529     }
3530   }
3531   return false;
3532 }
3533 
blx(Condition cond,Location * location)3534 void Assembler::blx(Condition cond, Location* location) {
3535   VIXL_ASSERT(AllowAssembler());
3536   CheckIT(cond);
3537   Location::Offset offset =
3538       location->IsBound()
3539           ? location->GetLocation() -
3540                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
3541           : 0;
3542   if (IsUsingT32()) {
3543     // BLX{<c>}{<q>} <label> ; T2
3544     if (((location->IsBound() && (offset >= -16777216) &&
3545           (offset <= 16777212) && ((offset & 0x3) == 0)) ||
3546          !location->IsBound()) &&
3547         (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
3548       static class EmitOp : public Location::EmitOperator {
3549        public:
3550         EmitOp() : Location::EmitOperator(T32) {}
3551         virtual uint32_t Encode(uint32_t instr,
3552                                 Location::Offset pc,
3553                                 const Location* location) const VIXL_OVERRIDE {
3554           pc += kT32PcDelta;
3555           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
3556           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777212) &&
3557                       ((offset & 0x3) == 0));
3558           int32_t target = offset >> 2;
3559           uint32_t S = target & (1 << 22);
3560           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20);
3561           return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) |
3562                  ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) |
3563                  ((target & 0x400000) << 4);
3564         }
3565       } immop;
3566       EmitT32_32(Link(0xf000c000U, location, immop, &kT32BlxInfo));
3567       AdvanceIT();
3568       return;
3569     }
3570   } else {
3571     // BLX{<c>}{<q>} <label> ; A2
3572     if (((location->IsBound() && (offset >= -33554432) &&
3573           (offset <= 33554430) && ((offset & 0x1) == 0)) ||
3574          !location->IsBound())) {
3575       if (cond.Is(al) || AllowStronglyDiscouraged()) {
3576         static class EmitOp : public Location::EmitOperator {
3577          public:
3578           EmitOp() : Location::EmitOperator(A32) {}
3579           virtual uint32_t Encode(uint32_t instr,
3580                                   Location::Offset pc,
3581                                   const Location* location) const
3582               VIXL_OVERRIDE {
3583             pc += kA32PcDelta;
3584             Location::Offset offset =
3585                 location->GetLocation() - AlignDown(pc, 4);
3586             VIXL_ASSERT((offset >= -33554432) && (offset <= 33554430) &&
3587                         ((offset & 0x1) == 0));
3588             const int32_t target = offset >> 1;
3589             return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1);
3590           }
3591         } immop;
3592         EmitA32(Link(0xfa000000U, location, immop, &kA32BlxInfo));
3593         return;
3594       }
3595     }
3596   }
3597   Delegate(kBlx, &Assembler::blx, cond, location);
3598 }
3599 
blx_info(Condition cond,Location * location,const struct ReferenceInfo ** info)3600 bool Assembler::blx_info(Condition cond,
3601                          Location* location,
3602                          const struct ReferenceInfo** info) {
3603   VIXL_ASSERT(!location->IsBound());
3604   USE(location);
3605   USE(cond);
3606   if (IsUsingT32()) {
3607     // BLX{<c>}{<q>} <label> ; T2
3608     if (true) {
3609       *info = &kT32BlxInfo;
3610       return true;
3611     }
3612   } else {
3613     // BLX{<c>}{<q>} <label> ; A2
3614     if (true) {
3615       *info = &kA32BlxInfo;
3616       return true;
3617     }
3618   }
3619   return false;
3620 }
3621 
blx(Condition cond,Register rm)3622 void Assembler::blx(Condition cond, Register rm) {
3623   VIXL_ASSERT(AllowAssembler());
3624   CheckIT(cond);
3625   if (IsUsingT32()) {
3626     // BLX{<c>}{<q>} <Rm> ; T1
3627     if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) ||
3628          AllowUnpredictable())) {
3629       EmitT32_16(0x4780 | (rm.GetCode() << 3));
3630       AdvanceIT();
3631       return;
3632     }
3633   } else {
3634     // BLX{<c>}{<q>} <Rm> ; A1
3635     if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
3636       EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode());
3637       return;
3638     }
3639   }
3640   Delegate(kBlx, &Assembler::blx, cond, rm);
3641 }
3642 
bx(Condition cond,Register rm)3643 void Assembler::bx(Condition cond, Register rm) {
3644   VIXL_ASSERT(AllowAssembler());
3645   CheckIT(cond);
3646   if (IsUsingT32()) {
3647     // BX{<c>}{<q>} <Rm> ; T1
3648     if ((OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
3649       EmitT32_16(0x4700 | (rm.GetCode() << 3));
3650       AdvanceIT();
3651       return;
3652     }
3653   } else {
3654     // BX{<c>}{<q>} <Rm> ; A1
3655     if (cond.IsNotNever()) {
3656       EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode());
3657       return;
3658     }
3659   }
3660   Delegate(kBx, &Assembler::bx, cond, rm);
3661 }
3662 
bxj(Condition cond,Register rm)3663 void Assembler::bxj(Condition cond, Register rm) {
3664   VIXL_ASSERT(AllowAssembler());
3665   CheckIT(cond);
3666   if (IsUsingT32()) {
3667     // BXJ{<c>}{<q>} <Rm> ; T1
3668     if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) ||
3669          AllowUnpredictable())) {
3670       EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16));
3671       AdvanceIT();
3672       return;
3673     }
3674   } else {
3675     // BXJ{<c>}{<q>} <Rm> ; A1
3676     if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
3677       EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode());
3678       return;
3679     }
3680   }
3681   Delegate(kBxj, &Assembler::bxj, cond, rm);
3682 }
3683 
cbnz(Register rn,Location * location)3684 void Assembler::cbnz(Register rn, Location* location) {
3685   VIXL_ASSERT(AllowAssembler());
3686   CheckIT(al);
3687   Location::Offset offset =
3688       location->IsBound()
3689           ? location->GetLocation() -
3690                 (GetCursorOffset() + GetArchitectureStatePCOffset())
3691           : 0;
3692   if (IsUsingT32()) {
3693     // CBNZ{<q>} <Rn>, <label> ; T1
3694     if (rn.IsLow() && ((location->IsBound() && (offset >= 0) &&
3695                         (offset <= 126) && ((offset & 0x1) == 0)) ||
3696                        !location->IsBound())) {
3697       static class EmitOp : public Location::EmitOperator {
3698        public:
3699         EmitOp() : Location::EmitOperator(T32) {}
3700         virtual uint32_t Encode(uint32_t instr,
3701                                 Location::Offset pc,
3702                                 const Location* location) const VIXL_OVERRIDE {
3703           pc += kT32PcDelta;
3704           Location::Offset offset = location->GetLocation() - pc;
3705           VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
3706                       ((offset & 0x1) == 0));
3707           const int32_t target = offset >> 1;
3708           return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3709         }
3710       } immop;
3711       EmitT32_16(Link(0xb900 | rn.GetCode(), location, immop, &kT16CbzInfo));
3712       AdvanceIT();
3713       return;
3714     }
3715   }
3716   Delegate(kCbnz, &Assembler::cbnz, rn, location);
3717 }
3718 
cbnz_info(Register rn,Location * location,const struct ReferenceInfo ** info)3719 bool Assembler::cbnz_info(Register rn,
3720                           Location* location,
3721                           const struct ReferenceInfo** info) {
3722   VIXL_ASSERT(!location->IsBound());
3723   USE(location);
3724   if (IsUsingT32()) {
3725     // CBNZ{<q>} <Rn>, <label> ; T1
3726     if (rn.IsLow()) {
3727       *info = &kT16CbzInfo;
3728       return true;
3729     }
3730   }
3731   return false;
3732 }
3733 
cbz(Register rn,Location * location)3734 void Assembler::cbz(Register rn, Location* location) {
3735   VIXL_ASSERT(AllowAssembler());
3736   CheckIT(al);
3737   Location::Offset offset =
3738       location->IsBound()
3739           ? location->GetLocation() -
3740                 (GetCursorOffset() + GetArchitectureStatePCOffset())
3741           : 0;
3742   if (IsUsingT32()) {
3743     // CBZ{<q>} <Rn>, <label> ; T1
3744     if (rn.IsLow() && ((location->IsBound() && (offset >= 0) &&
3745                         (offset <= 126) && ((offset & 0x1) == 0)) ||
3746                        !location->IsBound())) {
3747       static class EmitOp : public Location::EmitOperator {
3748        public:
3749         EmitOp() : Location::EmitOperator(T32) {}
3750         virtual uint32_t Encode(uint32_t instr,
3751                                 Location::Offset pc,
3752                                 const Location* location) const VIXL_OVERRIDE {
3753           pc += kT32PcDelta;
3754           Location::Offset offset = location->GetLocation() - pc;
3755           VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
3756                       ((offset & 0x1) == 0));
3757           const int32_t target = offset >> 1;
3758           return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3759         }
3760       } immop;
3761       EmitT32_16(Link(0xb100 | rn.GetCode(), location, immop, &kT16CbzInfo));
3762       AdvanceIT();
3763       return;
3764     }
3765   }
3766   Delegate(kCbz, &Assembler::cbz, rn, location);
3767 }
3768 
cbz_info(Register rn,Location * location,const struct ReferenceInfo ** info)3769 bool Assembler::cbz_info(Register rn,
3770                          Location* location,
3771                          const struct ReferenceInfo** info) {
3772   VIXL_ASSERT(!location->IsBound());
3773   USE(location);
3774   if (IsUsingT32()) {
3775     // CBZ{<q>} <Rn>, <label> ; T1
3776     if (rn.IsLow()) {
3777       *info = &kT16CbzInfo;
3778       return true;
3779     }
3780   }
3781   return false;
3782 }
3783 
clrex(Condition cond)3784 void Assembler::clrex(Condition cond) {
3785   VIXL_ASSERT(AllowAssembler());
3786   CheckIT(cond);
3787   if (IsUsingT32()) {
3788     // CLREX{<c>}{<q>} ; T1
3789     EmitT32_32(0xf3bf8f2fU);
3790     AdvanceIT();
3791     return;
3792   } else {
3793     // CLREX{<c>}{<q>} ; A1
3794     if (cond.Is(al)) {
3795       EmitA32(0xf57ff01fU);
3796       return;
3797     }
3798   }
3799   Delegate(kClrex, &Assembler::clrex, cond);
3800 }
3801 
clz(Condition cond,Register rd,Register rm)3802 void Assembler::clz(Condition cond, Register rd, Register rm) {
3803   VIXL_ASSERT(AllowAssembler());
3804   CheckIT(cond);
3805   if (IsUsingT32()) {
3806     // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1
3807     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3808       EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() |
3809                  (rm.GetCode() << 16));
3810       AdvanceIT();
3811       return;
3812     }
3813   } else {
3814     // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1
3815     if (cond.IsNotNever() &&
3816         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3817       EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3818               rm.GetCode());
3819       return;
3820     }
3821   }
3822   Delegate(kClz, &Assembler::clz, cond, rd, rm);
3823 }
3824 
cmn(Condition cond,EncodingSize size,Register rn,const Operand & operand)3825 void Assembler::cmn(Condition cond,
3826                     EncodingSize size,
3827                     Register rn,
3828                     const Operand& operand) {
3829   VIXL_ASSERT(AllowAssembler());
3830   CheckIT(cond);
3831   if (operand.IsImmediate()) {
3832     uint32_t imm = operand.GetImmediate();
3833     if (IsUsingT32()) {
3834       ImmediateT32 immediate_t32(imm);
3835       // CMN{<c>}{<q>} <Rn>, #<const> ; T1
3836       if (!size.IsNarrow() && immediate_t32.IsValid() &&
3837           (!rn.IsPC() || AllowUnpredictable())) {
3838         EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) |
3839                    (immediate_t32.GetEncodingValue() & 0xff) |
3840                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3841                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3842         AdvanceIT();
3843         return;
3844       }
3845     } else {
3846       ImmediateA32 immediate_a32(imm);
3847       // CMN{<c>}{<q>} <Rn>, #<const> ; A1
3848       if (immediate_a32.IsValid() && cond.IsNotNever()) {
3849         EmitA32(0x03700000U | (cond.GetCondition() << 28) |
3850                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3851         return;
3852       }
3853     }
3854   }
3855   if (operand.IsImmediateShiftedRegister()) {
3856     Register rm = operand.GetBaseRegister();
3857     if (operand.IsPlainRegister()) {
3858       if (IsUsingT32()) {
3859         // CMN{<c>}{<q>} <Rn>, <Rm> ; T1
3860         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3861           EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3));
3862           AdvanceIT();
3863           return;
3864         }
3865       }
3866     }
3867     Shift shift = operand.GetShift();
3868     uint32_t amount = operand.GetShiftAmount();
3869     if (IsUsingT32()) {
3870       // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
3871       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
3872           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3873         uint32_t amount_ = amount % 32;
3874         EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() |
3875                    (operand.GetTypeEncodingValue() << 4) |
3876                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3877         AdvanceIT();
3878         return;
3879       }
3880     } else {
3881       // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3882       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3883         uint32_t amount_ = amount % 32;
3884         EmitA32(0x01700000U | (cond.GetCondition() << 28) |
3885                 (rn.GetCode() << 16) | rm.GetCode() |
3886                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3887         return;
3888       }
3889     }
3890   }
3891   if (operand.IsRegisterShiftedRegister()) {
3892     Register rm = operand.GetBaseRegister();
3893     Shift shift = operand.GetShift();
3894     Register rs = operand.GetShiftRegister();
3895     if (IsUsingA32()) {
3896       // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3897       if (cond.IsNotNever() &&
3898           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
3899         EmitA32(0x01700010U | (cond.GetCondition() << 28) |
3900                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3901                 (rs.GetCode() << 8));
3902         return;
3903       }
3904     }
3905   }
3906   Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand);
3907 }
3908 
cmp(Condition cond,EncodingSize size,Register rn,const Operand & operand)3909 void Assembler::cmp(Condition cond,
3910                     EncodingSize size,
3911                     Register rn,
3912                     const Operand& operand) {
3913   VIXL_ASSERT(AllowAssembler());
3914   CheckIT(cond);
3915   if (operand.IsImmediate()) {
3916     uint32_t imm = operand.GetImmediate();
3917     if (IsUsingT32()) {
3918       ImmediateT32 immediate_t32(imm);
3919       // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1
3920       if (!size.IsWide() && rn.IsLow() && (imm <= 255)) {
3921         EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm);
3922         AdvanceIT();
3923         return;
3924       }
3925       // CMP{<c>}{<q>} <Rn>, #<const> ; T2
3926       if (!size.IsNarrow() && immediate_t32.IsValid() &&
3927           (!rn.IsPC() || AllowUnpredictable())) {
3928         EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) |
3929                    (immediate_t32.GetEncodingValue() & 0xff) |
3930                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3931                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3932         AdvanceIT();
3933         return;
3934       }
3935     } else {
3936       ImmediateA32 immediate_a32(imm);
3937       // CMP{<c>}{<q>} <Rn>, #<const> ; A1
3938       if (immediate_a32.IsValid() && cond.IsNotNever()) {
3939         EmitA32(0x03500000U | (cond.GetCondition() << 28) |
3940                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3941         return;
3942       }
3943     }
3944   }
3945   if (operand.IsImmediateShiftedRegister()) {
3946     Register rm = operand.GetBaseRegister();
3947     if (operand.IsPlainRegister()) {
3948       if (IsUsingT32()) {
3949         // CMP{<c>}{<q>} <Rn>, <Rm> ; T1
3950         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3951           EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3));
3952           AdvanceIT();
3953           return;
3954         }
3955         // CMP{<c>}{<q>} <Rn>, <Rm> ; T2
3956         if (!size.IsWide() &&
3957             ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3958           EmitT32_16(0x4500 | (rn.GetCode() & 0x7) |
3959                      ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
3960           AdvanceIT();
3961           return;
3962         }
3963       }
3964     }
3965     Shift shift = operand.GetShift();
3966     uint32_t amount = operand.GetShiftAmount();
3967     if (IsUsingT32()) {
3968       // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3
3969       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
3970           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3971         uint32_t amount_ = amount % 32;
3972         EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() |
3973                    (operand.GetTypeEncodingValue() << 4) |
3974                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3975         AdvanceIT();
3976         return;
3977       }
3978     } else {
3979       // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3980       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3981         uint32_t amount_ = amount % 32;
3982         EmitA32(0x01500000U | (cond.GetCondition() << 28) |
3983                 (rn.GetCode() << 16) | rm.GetCode() |
3984                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3985         return;
3986       }
3987     }
3988   }
3989   if (operand.IsRegisterShiftedRegister()) {
3990     Register rm = operand.GetBaseRegister();
3991     Shift shift = operand.GetShift();
3992     Register rs = operand.GetShiftRegister();
3993     if (IsUsingA32()) {
3994       // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3995       if (cond.IsNotNever() &&
3996           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
3997         EmitA32(0x01500010U | (cond.GetCondition() << 28) |
3998                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3999                 (rs.GetCode() << 8));
4000         return;
4001       }
4002     }
4003   }
4004   Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand);
4005 }
4006 
crc32b(Condition cond,Register rd,Register rn,Register rm)4007 void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) {
4008   VIXL_ASSERT(AllowAssembler());
4009   CheckIT(cond);
4010   if (IsUsingT32()) {
4011     // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1
4012     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4013          AllowUnpredictable())) {
4014       EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4015                  rm.GetCode());
4016       AdvanceIT();
4017       return;
4018     }
4019   } else {
4020     // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1
4021     if ((cond.Is(al) || AllowUnpredictable()) &&
4022         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4023       EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4024               (rn.GetCode() << 16) | rm.GetCode());
4025       return;
4026     }
4027   }
4028   Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm);
4029 }
4030 
crc32cb(Condition cond,Register rd,Register rn,Register rm)4031 void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) {
4032   VIXL_ASSERT(AllowAssembler());
4033   CheckIT(cond);
4034   if (IsUsingT32()) {
4035     // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1
4036     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4037          AllowUnpredictable())) {
4038       EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4039                  rm.GetCode());
4040       AdvanceIT();
4041       return;
4042     }
4043   } else {
4044     // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1
4045     if ((cond.Is(al) || AllowUnpredictable()) &&
4046         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4047       EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4048               (rn.GetCode() << 16) | rm.GetCode());
4049       return;
4050     }
4051   }
4052   Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm);
4053 }
4054 
crc32ch(Condition cond,Register rd,Register rn,Register rm)4055 void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) {
4056   VIXL_ASSERT(AllowAssembler());
4057   CheckIT(cond);
4058   if (IsUsingT32()) {
4059     // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1
4060     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4061          AllowUnpredictable())) {
4062       EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4063                  rm.GetCode());
4064       AdvanceIT();
4065       return;
4066     }
4067   } else {
4068     // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1
4069     if ((cond.Is(al) || AllowUnpredictable()) &&
4070         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4071       EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4072               (rn.GetCode() << 16) | rm.GetCode());
4073       return;
4074     }
4075   }
4076   Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm);
4077 }
4078 
crc32cw(Condition cond,Register rd,Register rn,Register rm)4079 void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) {
4080   VIXL_ASSERT(AllowAssembler());
4081   CheckIT(cond);
4082   if (IsUsingT32()) {
4083     // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1
4084     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4085          AllowUnpredictable())) {
4086       EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4087                  rm.GetCode());
4088       AdvanceIT();
4089       return;
4090     }
4091   } else {
4092     // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1
4093     if ((cond.Is(al) || AllowUnpredictable()) &&
4094         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4095       EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4096               (rn.GetCode() << 16) | rm.GetCode());
4097       return;
4098     }
4099   }
4100   Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm);
4101 }
4102 
crc32h(Condition cond,Register rd,Register rn,Register rm)4103 void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) {
4104   VIXL_ASSERT(AllowAssembler());
4105   CheckIT(cond);
4106   if (IsUsingT32()) {
4107     // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1
4108     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4109          AllowUnpredictable())) {
4110       EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4111                  rm.GetCode());
4112       AdvanceIT();
4113       return;
4114     }
4115   } else {
4116     // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1
4117     if ((cond.Is(al) || AllowUnpredictable()) &&
4118         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4119       EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4120               (rn.GetCode() << 16) | rm.GetCode());
4121       return;
4122     }
4123   }
4124   Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm);
4125 }
4126 
crc32w(Condition cond,Register rd,Register rn,Register rm)4127 void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) {
4128   VIXL_ASSERT(AllowAssembler());
4129   CheckIT(cond);
4130   if (IsUsingT32()) {
4131     // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1
4132     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4133          AllowUnpredictable())) {
4134       EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4135                  rm.GetCode());
4136       AdvanceIT();
4137       return;
4138     }
4139   } else {
4140     // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1
4141     if ((cond.Is(al) || AllowUnpredictable()) &&
4142         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4143       EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4144               (rn.GetCode() << 16) | rm.GetCode());
4145       return;
4146     }
4147   }
4148   Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm);
4149 }
4150 
dmb(Condition cond,MemoryBarrier option)4151 void Assembler::dmb(Condition cond, MemoryBarrier option) {
4152   VIXL_ASSERT(AllowAssembler());
4153   CheckIT(cond);
4154   if (IsUsingT32()) {
4155     // DMB{<c>}{<q>} {<option>} ; T1
4156     EmitT32_32(0xf3bf8f50U | option.GetType());
4157     AdvanceIT();
4158     return;
4159   } else {
4160     // DMB{<c>}{<q>} {<option>} ; A1
4161     if (cond.Is(al)) {
4162       EmitA32(0xf57ff050U | option.GetType());
4163       return;
4164     }
4165   }
4166   Delegate(kDmb, &Assembler::dmb, cond, option);
4167 }
4168 
dsb(Condition cond,MemoryBarrier option)4169 void Assembler::dsb(Condition cond, MemoryBarrier option) {
4170   VIXL_ASSERT(AllowAssembler());
4171   CheckIT(cond);
4172   if (IsUsingT32()) {
4173     // DSB{<c>}{<q>} {<option>} ; T1
4174     EmitT32_32(0xf3bf8f40U | option.GetType());
4175     AdvanceIT();
4176     return;
4177   } else {
4178     // DSB{<c>}{<q>} {<option>} ; A1
4179     if (cond.Is(al)) {
4180       EmitA32(0xf57ff040U | option.GetType());
4181       return;
4182     }
4183   }
4184   Delegate(kDsb, &Assembler::dsb, cond, option);
4185 }
4186 
eor(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)4187 void Assembler::eor(Condition cond,
4188                     EncodingSize size,
4189                     Register rd,
4190                     Register rn,
4191                     const Operand& operand) {
4192   VIXL_ASSERT(AllowAssembler());
4193   CheckIT(cond);
4194   if (operand.IsImmediate()) {
4195     uint32_t imm = operand.GetImmediate();
4196     if (IsUsingT32()) {
4197       ImmediateT32 immediate_t32(imm);
4198       // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
4199       if (!size.IsNarrow() && immediate_t32.IsValid() &&
4200           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4201         EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4202                    (immediate_t32.GetEncodingValue() & 0xff) |
4203                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
4204                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
4205         AdvanceIT();
4206         return;
4207       }
4208     } else {
4209       ImmediateA32 immediate_a32(imm);
4210       // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
4211       if (immediate_a32.IsValid() && cond.IsNotNever()) {
4212         EmitA32(0x02200000U | (cond.GetCondition() << 28) |
4213                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
4214                 immediate_a32.GetEncodingValue());
4215         return;
4216       }
4217     }
4218   }
4219   if (operand.IsImmediateShiftedRegister()) {
4220     Register rm = operand.GetBaseRegister();
4221     if (operand.IsPlainRegister()) {
4222       if (IsUsingT32()) {
4223         // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
4224         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
4225             rm.IsLow()) {
4226           EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
4227           AdvanceIT();
4228           return;
4229         }
4230       }
4231     }
4232     Shift shift = operand.GetShift();
4233     uint32_t amount = operand.GetShiftAmount();
4234     if (IsUsingT32()) {
4235       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
4236       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
4237           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4238         uint32_t amount_ = amount % 32;
4239         EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4240                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
4241                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
4242         AdvanceIT();
4243         return;
4244       }
4245     } else {
4246       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
4247       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
4248         uint32_t amount_ = amount % 32;
4249         EmitA32(0x00200000U | (cond.GetCondition() << 28) |
4250                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4251                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
4252         return;
4253       }
4254     }
4255   }
4256   if (operand.IsRegisterShiftedRegister()) {
4257     Register rm = operand.GetBaseRegister();
4258     Shift shift = operand.GetShift();
4259     Register rs = operand.GetShiftRegister();
4260     if (IsUsingA32()) {
4261       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
4262       if (cond.IsNotNever() &&
4263           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
4264            AllowUnpredictable())) {
4265         EmitA32(0x00200010U | (cond.GetCondition() << 28) |
4266                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4267                 (shift.GetType() << 5) | (rs.GetCode() << 8));
4268         return;
4269       }
4270     }
4271   }
4272   Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand);
4273 }
4274 
eors(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)4275 void Assembler::eors(Condition cond,
4276                      EncodingSize size,
4277                      Register rd,
4278                      Register rn,
4279                      const Operand& operand) {
4280   VIXL_ASSERT(AllowAssembler());
4281   CheckIT(cond);
4282   if (operand.IsImmediate()) {
4283     uint32_t imm = operand.GetImmediate();
4284     if (IsUsingT32()) {
4285       ImmediateT32 immediate_t32(imm);
4286       // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
4287       if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) &&
4288           (!rn.IsPC() || AllowUnpredictable())) {
4289         EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4290                    (immediate_t32.GetEncodingValue() & 0xff) |
4291                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
4292                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
4293         AdvanceIT();
4294         return;
4295       }
4296     } else {
4297       ImmediateA32 immediate_a32(imm);
4298       // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
4299       if (immediate_a32.IsValid() && cond.IsNotNever()) {
4300         EmitA32(0x02300000U | (cond.GetCondition() << 28) |
4301                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
4302                 immediate_a32.GetEncodingValue());
4303         return;
4304       }
4305     }
4306   }
4307   if (operand.IsImmediateShiftedRegister()) {
4308     Register rm = operand.GetBaseRegister();
4309     if (operand.IsPlainRegister()) {
4310       if (IsUsingT32()) {
4311         // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
4312         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
4313             rm.IsLow()) {
4314           EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
4315           AdvanceIT();
4316           return;
4317         }
4318       }
4319     }
4320     Shift shift = operand.GetShift();
4321     uint32_t amount = operand.GetShiftAmount();
4322     if (IsUsingT32()) {
4323       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
4324       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) &&
4325           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4326         uint32_t amount_ = amount % 32;
4327         EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4328                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
4329                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
4330         AdvanceIT();
4331         return;
4332       }
4333     } else {
4334       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
4335       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
4336         uint32_t amount_ = amount % 32;
4337         EmitA32(0x00300000U | (cond.GetCondition() << 28) |
4338                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4339                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
4340         return;
4341       }
4342     }
4343   }
4344   if (operand.IsRegisterShiftedRegister()) {
4345     Register rm = operand.GetBaseRegister();
4346     Shift shift = operand.GetShift();
4347     Register rs = operand.GetShiftRegister();
4348     if (IsUsingA32()) {
4349       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
4350       if (cond.IsNotNever() &&
4351           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
4352            AllowUnpredictable())) {
4353         EmitA32(0x00300010U | (cond.GetCondition() << 28) |
4354                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4355                 (shift.GetType() << 5) | (rs.GetCode() << 8));
4356         return;
4357       }
4358     }
4359   }
4360   Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand);
4361 }
4362 
fldmdbx(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)4363 void Assembler::fldmdbx(Condition cond,
4364                         Register rn,
4365                         WriteBack write_back,
4366                         DRegisterList dreglist) {
4367   VIXL_ASSERT(AllowAssembler());
4368   CheckIT(cond);
4369   if (IsUsingT32()) {
4370     // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
4371     if (write_back.DoesWriteBack() &&
4372         (((dreglist.GetLength() <= 16) &&
4373           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4374          AllowUnpredictable())) {
4375       const DRegister& dreg = dreglist.GetFirstDRegister();
4376       unsigned len = dreglist.GetLength() * 2;
4377       EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
4378                  (len & 0xff));
4379       AdvanceIT();
4380       return;
4381     }
4382   } else {
4383     // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
4384     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
4385         (((dreglist.GetLength() <= 16) &&
4386           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4387          AllowUnpredictable())) {
4388       const DRegister& dreg = dreglist.GetFirstDRegister();
4389       unsigned len = dreglist.GetLength() * 2;
4390       EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4391               dreg.Encode(22, 12) | (len & 0xff));
4392       return;
4393     }
4394   }
4395   Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist);
4396 }
4397 
fldmiax(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)4398 void Assembler::fldmiax(Condition cond,
4399                         Register rn,
4400                         WriteBack write_back,
4401                         DRegisterList dreglist) {
4402   VIXL_ASSERT(AllowAssembler());
4403   CheckIT(cond);
4404   if (IsUsingT32()) {
4405     // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
4406     if ((((dreglist.GetLength() <= 16) &&
4407           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4408          AllowUnpredictable())) {
4409       const DRegister& dreg = dreglist.GetFirstDRegister();
4410       unsigned len = dreglist.GetLength() * 2;
4411       EmitT32_32(0xec900b01U | (rn.GetCode() << 16) |
4412                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4413                  (len & 0xff));
4414       AdvanceIT();
4415       return;
4416     }
4417   } else {
4418     // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
4419     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
4420                                (dreglist.GetLastDRegister().GetCode() < 16) &&
4421                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
4422                               AllowUnpredictable())) {
4423       const DRegister& dreg = dreglist.GetFirstDRegister();
4424       unsigned len = dreglist.GetLength() * 2;
4425       EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4426               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4427               (len & 0xff));
4428       return;
4429     }
4430   }
4431   Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist);
4432 }
4433 
fstmdbx(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)4434 void Assembler::fstmdbx(Condition cond,
4435                         Register rn,
4436                         WriteBack write_back,
4437                         DRegisterList dreglist) {
4438   VIXL_ASSERT(AllowAssembler());
4439   CheckIT(cond);
4440   if (IsUsingT32()) {
4441     // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
4442     if (write_back.DoesWriteBack() &&
4443         (((dreglist.GetLength() <= 16) &&
4444           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4445          AllowUnpredictable())) {
4446       const DRegister& dreg = dreglist.GetFirstDRegister();
4447       unsigned len = dreglist.GetLength() * 2;
4448       EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
4449                  (len & 0xff));
4450       AdvanceIT();
4451       return;
4452     }
4453   } else {
4454     // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
4455     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
4456         (((dreglist.GetLength() <= 16) &&
4457           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4458          AllowUnpredictable())) {
4459       const DRegister& dreg = dreglist.GetFirstDRegister();
4460       unsigned len = dreglist.GetLength() * 2;
4461       EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4462               dreg.Encode(22, 12) | (len & 0xff));
4463       return;
4464     }
4465   }
4466   Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist);
4467 }
4468 
fstmiax(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)4469 void Assembler::fstmiax(Condition cond,
4470                         Register rn,
4471                         WriteBack write_back,
4472                         DRegisterList dreglist) {
4473   VIXL_ASSERT(AllowAssembler());
4474   CheckIT(cond);
4475   if (IsUsingT32()) {
4476     // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
4477     if ((((dreglist.GetLength() <= 16) &&
4478           (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4479          AllowUnpredictable())) {
4480       const DRegister& dreg = dreglist.GetFirstDRegister();
4481       unsigned len = dreglist.GetLength() * 2;
4482       EmitT32_32(0xec800b01U | (rn.GetCode() << 16) |
4483                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4484                  (len & 0xff));
4485       AdvanceIT();
4486       return;
4487     }
4488   } else {
4489     // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
4490     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
4491                                (dreglist.GetLastDRegister().GetCode() < 16) &&
4492                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
4493                               AllowUnpredictable())) {
4494       const DRegister& dreg = dreglist.GetFirstDRegister();
4495       unsigned len = dreglist.GetLength() * 2;
4496       EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4497               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4498               (len & 0xff));
4499       return;
4500     }
4501   }
4502   Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist);
4503 }
4504 
hlt(Condition cond,uint32_t imm)4505 void Assembler::hlt(Condition cond, uint32_t imm) {
4506   VIXL_ASSERT(AllowAssembler());
4507   CheckIT(cond);
4508   if (IsUsingT32()) {
4509     // HLT{<q>} {#}<imm> ; T1
4510     if ((imm <= 63)) {
4511       EmitT32_16(0xba80 | imm);
4512       AdvanceIT();
4513       return;
4514     }
4515   } else {
4516     // HLT{<q>} {#}<imm> ; A1
4517     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4518       EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4519               ((imm & 0xfff0) << 4));
4520       return;
4521     }
4522   }
4523   Delegate(kHlt, &Assembler::hlt, cond, imm);
4524 }
4525 
hvc(Condition cond,uint32_t imm)4526 void Assembler::hvc(Condition cond, uint32_t imm) {
4527   VIXL_ASSERT(AllowAssembler());
4528   CheckIT(cond);
4529   if (IsUsingT32()) {
4530     // HVC{<q>} {#}<imm16> ; T1
4531     if ((imm <= 65535) && (OutsideITBlock() || AllowUnpredictable())) {
4532       EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
4533       AdvanceIT();
4534       return;
4535     }
4536   } else {
4537     // HVC{<q>} {#}<imm16> ; A1
4538     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4539       EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4540               ((imm & 0xfff0) << 4));
4541       return;
4542     }
4543   }
4544   Delegate(kHvc, &Assembler::hvc, cond, imm);
4545 }
4546 
isb(Condition cond,MemoryBarrier option)4547 void Assembler::isb(Condition cond, MemoryBarrier option) {
4548   VIXL_ASSERT(AllowAssembler());
4549   CheckIT(cond);
4550   if (IsUsingT32()) {
4551     // ISB{<c>}{<q>} {<option>} ; T1
4552     EmitT32_32(0xf3bf8f60U | option.GetType());
4553     AdvanceIT();
4554     return;
4555   } else {
4556     // ISB{<c>}{<q>} {<option>} ; A1
4557     if (cond.Is(al)) {
4558       EmitA32(0xf57ff060U | option.GetType());
4559       return;
4560     }
4561   }
4562   Delegate(kIsb, &Assembler::isb, cond, option);
4563 }
4564 
it(Condition cond,uint16_t mask)4565 void Assembler::it(Condition cond, uint16_t mask) {
4566   VIXL_ASSERT(AllowAssembler());
4567   CheckNotIT();
4568   if (mask != 0) {
4569     if ((cond.GetCondition() & 0x1) != 0) {
4570       if ((mask & 0x1) != 0) {
4571         mask ^= 0xE;
4572       } else if ((mask & 0x2) != 0) {
4573         mask ^= 0xC;
4574       } else if ((mask & 0x4) != 0) {
4575         mask ^= 0x8;
4576       }
4577     }
4578     if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask);
4579     SetIT(cond, mask);
4580     return;
4581   }
4582   DelegateIt(cond, mask);
4583 }
4584 
lda(Condition cond,Register rt,const MemOperand & operand)4585 void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) {
4586   VIXL_ASSERT(AllowAssembler());
4587   CheckIT(cond);
4588   if (operand.IsImmediateZero()) {
4589     Register rn = operand.GetBaseRegister();
4590     if (IsUsingT32()) {
4591       // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1
4592       if (operand.IsOffset() &&
4593           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4594         EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4595         AdvanceIT();
4596         return;
4597       }
4598     } else {
4599       // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1
4600       if (operand.IsOffset() && cond.IsNotNever() &&
4601           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4602         EmitA32(0x01900c9fU | (cond.GetCondition() << 28) |
4603                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4604         return;
4605       }
4606     }
4607   }
4608   Delegate(kLda, &Assembler::lda, cond, rt, operand);
4609 }
4610 
ldab(Condition cond,Register rt,const MemOperand & operand)4611 void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) {
4612   VIXL_ASSERT(AllowAssembler());
4613   CheckIT(cond);
4614   if (operand.IsImmediateZero()) {
4615     Register rn = operand.GetBaseRegister();
4616     if (IsUsingT32()) {
4617       // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4618       if (operand.IsOffset() &&
4619           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4620         EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4621         AdvanceIT();
4622         return;
4623       }
4624     } else {
4625       // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4626       if (operand.IsOffset() && cond.IsNotNever() &&
4627           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4628         EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) |
4629                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4630         return;
4631       }
4632     }
4633   }
4634   Delegate(kLdab, &Assembler::ldab, cond, rt, operand);
4635 }
4636 
ldaex(Condition cond,Register rt,const MemOperand & operand)4637 void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) {
4638   VIXL_ASSERT(AllowAssembler());
4639   CheckIT(cond);
4640   if (operand.IsImmediateZero()) {
4641     Register rn = operand.GetBaseRegister();
4642     if (IsUsingT32()) {
4643       // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1
4644       if (operand.IsOffset() &&
4645           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4646         EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4647         AdvanceIT();
4648         return;
4649       }
4650     } else {
4651       // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1
4652       if (operand.IsOffset() && cond.IsNotNever() &&
4653           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4654         EmitA32(0x01900e9fU | (cond.GetCondition() << 28) |
4655                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4656         return;
4657       }
4658     }
4659   }
4660   Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand);
4661 }
4662 
ldaexb(Condition cond,Register rt,const MemOperand & operand)4663 void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) {
4664   VIXL_ASSERT(AllowAssembler());
4665   CheckIT(cond);
4666   if (operand.IsImmediateZero()) {
4667     Register rn = operand.GetBaseRegister();
4668     if (IsUsingT32()) {
4669       // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4670       if (operand.IsOffset() &&
4671           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4672         EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4673         AdvanceIT();
4674         return;
4675       }
4676     } else {
4677       // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4678       if (operand.IsOffset() && cond.IsNotNever() &&
4679           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4680         EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) |
4681                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4682         return;
4683       }
4684     }
4685   }
4686   Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand);
4687 }
4688 
ldaexd(Condition cond,Register rt,Register rt2,const MemOperand & operand)4689 void Assembler::ldaexd(Condition cond,
4690                        Register rt,
4691                        Register rt2,
4692                        const MemOperand& operand) {
4693   VIXL_ASSERT(AllowAssembler());
4694   CheckIT(cond);
4695   if (operand.IsImmediateZero()) {
4696     Register rn = operand.GetBaseRegister();
4697     if (IsUsingT32()) {
4698       // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
4699       if (operand.IsOffset() &&
4700           ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4701         EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
4702                    (rn.GetCode() << 16));
4703         AdvanceIT();
4704         return;
4705       }
4706     } else {
4707       // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
4708       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
4709           operand.IsOffset() && cond.IsNotNever() &&
4710           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) ||
4711            AllowUnpredictable())) {
4712         EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) |
4713                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4714         return;
4715       }
4716     }
4717   }
4718   Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand);
4719 }
4720 
ldaexh(Condition cond,Register rt,const MemOperand & operand)4721 void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) {
4722   VIXL_ASSERT(AllowAssembler());
4723   CheckIT(cond);
4724   if (operand.IsImmediateZero()) {
4725     Register rn = operand.GetBaseRegister();
4726     if (IsUsingT32()) {
4727       // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4728       if (operand.IsOffset() &&
4729           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4730         EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4731         AdvanceIT();
4732         return;
4733       }
4734     } else {
4735       // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4736       if (operand.IsOffset() && cond.IsNotNever() &&
4737           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4738         EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) |
4739                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4740         return;
4741       }
4742     }
4743   }
4744   Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand);
4745 }
4746 
ldah(Condition cond,Register rt,const MemOperand & operand)4747 void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) {
4748   VIXL_ASSERT(AllowAssembler());
4749   CheckIT(cond);
4750   if (operand.IsImmediateZero()) {
4751     Register rn = operand.GetBaseRegister();
4752     if (IsUsingT32()) {
4753       // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4754       if (operand.IsOffset() &&
4755           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4756         EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4757         AdvanceIT();
4758         return;
4759       }
4760     } else {
4761       // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4762       if (operand.IsOffset() && cond.IsNotNever() &&
4763           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4764         EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) |
4765                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4766         return;
4767       }
4768     }
4769   }
4770   Delegate(kLdah, &Assembler::ldah, cond, rt, operand);
4771 }
4772 
ldm(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)4773 void Assembler::ldm(Condition cond,
4774                     EncodingSize size,
4775                     Register rn,
4776                     WriteBack write_back,
4777                     RegisterList registers) {
4778   VIXL_ASSERT(AllowAssembler());
4779   CheckIT(cond);
4780   if (IsUsingT32()) {
4781     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1
4782     if (!size.IsWide() && rn.IsLow() &&
4783         (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4784          write_back.DoesWriteBack()) &&
4785         ((registers.GetList() & ~0xff) == 0)) {
4786       EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4787                  GetRegisterListEncoding(registers, 0, 8));
4788       AdvanceIT();
4789       return;
4790     }
4791     // LDM{<c>}{<q>} SP!, <registers> ; T1
4792     if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
4793         ((registers.GetList() & ~0x80ff) == 0)) {
4794       EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
4795                  GetRegisterListEncoding(registers, 0, 8));
4796       AdvanceIT();
4797       return;
4798     }
4799     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2
4800     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) &&
4801         (!rn.IsPC() || AllowUnpredictable())) {
4802       EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4803                  (write_back.GetWriteBackUint32() << 21) |
4804                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
4805                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
4806                  GetRegisterListEncoding(registers, 0, 13));
4807       AdvanceIT();
4808       return;
4809     }
4810   } else {
4811     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1
4812     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4813       EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4814               (write_back.GetWriteBackUint32() << 21) |
4815               GetRegisterListEncoding(registers, 0, 16));
4816       return;
4817     }
4818   }
4819   Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers);
4820 }
4821 
ldmda(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4822 void Assembler::ldmda(Condition cond,
4823                       Register rn,
4824                       WriteBack write_back,
4825                       RegisterList registers) {
4826   VIXL_ASSERT(AllowAssembler());
4827   CheckIT(cond);
4828   if (IsUsingA32()) {
4829     // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4830     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4831       EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4832               (write_back.GetWriteBackUint32() << 21) |
4833               GetRegisterListEncoding(registers, 0, 16));
4834       return;
4835     }
4836   }
4837   Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers);
4838 }
4839 
ldmdb(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4840 void Assembler::ldmdb(Condition cond,
4841                       Register rn,
4842                       WriteBack write_back,
4843                       RegisterList registers) {
4844   VIXL_ASSERT(AllowAssembler());
4845   CheckIT(cond);
4846   if (IsUsingT32()) {
4847     // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
4848     if (((registers.GetList() & ~0xdfff) == 0) &&
4849         (!rn.IsPC() || AllowUnpredictable())) {
4850       EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4851                  (write_back.GetWriteBackUint32() << 21) |
4852                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
4853                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
4854                  GetRegisterListEncoding(registers, 0, 13));
4855       AdvanceIT();
4856       return;
4857     }
4858   } else {
4859     // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4860     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4861       EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4862               (write_back.GetWriteBackUint32() << 21) |
4863               GetRegisterListEncoding(registers, 0, 16));
4864       return;
4865     }
4866   }
4867   Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers);
4868 }
4869 
ldmea(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4870 void Assembler::ldmea(Condition cond,
4871                       Register rn,
4872                       WriteBack write_back,
4873                       RegisterList registers) {
4874   VIXL_ASSERT(AllowAssembler());
4875   CheckIT(cond);
4876   if (IsUsingT32()) {
4877     // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1
4878     if (((registers.GetList() & ~0xdfff) == 0) &&
4879         (!rn.IsPC() || AllowUnpredictable())) {
4880       EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4881                  (write_back.GetWriteBackUint32() << 21) |
4882                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
4883                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
4884                  GetRegisterListEncoding(registers, 0, 13));
4885       AdvanceIT();
4886       return;
4887     }
4888   } else {
4889     // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4890     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4891       EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4892               (write_back.GetWriteBackUint32() << 21) |
4893               GetRegisterListEncoding(registers, 0, 16));
4894       return;
4895     }
4896   }
4897   Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers);
4898 }
4899 
ldmed(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4900 void Assembler::ldmed(Condition cond,
4901                       Register rn,
4902                       WriteBack write_back,
4903                       RegisterList registers) {
4904   VIXL_ASSERT(AllowAssembler());
4905   CheckIT(cond);
4906   if (IsUsingA32()) {
4907     // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
4908     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4909       EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4910               (write_back.GetWriteBackUint32() << 21) |
4911               GetRegisterListEncoding(registers, 0, 16));
4912       return;
4913     }
4914   }
4915   Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers);
4916 }
4917 
ldmfa(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4918 void Assembler::ldmfa(Condition cond,
4919                       Register rn,
4920                       WriteBack write_back,
4921                       RegisterList registers) {
4922   VIXL_ASSERT(AllowAssembler());
4923   CheckIT(cond);
4924   if (IsUsingA32()) {
4925     // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4926     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4927       EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4928               (write_back.GetWriteBackUint32() << 21) |
4929               GetRegisterListEncoding(registers, 0, 16));
4930       return;
4931     }
4932   }
4933   Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers);
4934 }
4935 
ldmfd(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)4936 void Assembler::ldmfd(Condition cond,
4937                       EncodingSize size,
4938                       Register rn,
4939                       WriteBack write_back,
4940                       RegisterList registers) {
4941   VIXL_ASSERT(AllowAssembler());
4942   CheckIT(cond);
4943   if (IsUsingT32()) {
4944     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
4945     if (!size.IsWide() && rn.IsLow() &&
4946         (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4947          write_back.DoesWriteBack()) &&
4948         ((registers.GetList() & ~0xff) == 0)) {
4949       EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4950                  GetRegisterListEncoding(registers, 0, 8));
4951       AdvanceIT();
4952       return;
4953     }
4954     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2
4955     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) &&
4956         (!rn.IsPC() || AllowUnpredictable())) {
4957       EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4958                  (write_back.GetWriteBackUint32() << 21) |
4959                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
4960                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
4961                  GetRegisterListEncoding(registers, 0, 13));
4962       AdvanceIT();
4963       return;
4964     }
4965   } else {
4966     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
4967     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4968       EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4969               (write_back.GetWriteBackUint32() << 21) |
4970               GetRegisterListEncoding(registers, 0, 16));
4971       return;
4972     }
4973   }
4974   Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers);
4975 }
4976 
ldmib(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4977 void Assembler::ldmib(Condition cond,
4978                       Register rn,
4979                       WriteBack write_back,
4980                       RegisterList registers) {
4981   VIXL_ASSERT(AllowAssembler());
4982   CheckIT(cond);
4983   if (IsUsingA32()) {
4984     // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4985     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4986       EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4987               (write_back.GetWriteBackUint32() << 21) |
4988               GetRegisterListEncoding(registers, 0, 16));
4989       return;
4990     }
4991   }
4992   Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers);
4993 }
4994 
ldr(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)4995 void Assembler::ldr(Condition cond,
4996                     EncodingSize size,
4997                     Register rt,
4998                     const MemOperand& operand) {
4999   VIXL_ASSERT(AllowAssembler());
5000   CheckIT(cond);
5001   if (operand.IsImmediate()) {
5002     Register rn = operand.GetBaseRegister();
5003     int32_t offset = operand.GetOffsetImmediate();
5004     if (IsUsingT32()) {
5005       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5006       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
5007           (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
5008         int32_t offset_ = offset >> 2;
5009         EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) |
5010                    ((offset_ & 0x1f) << 6));
5011         AdvanceIT();
5012         return;
5013       }
5014       // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
5015       if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
5016           ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
5017         int32_t offset_ = offset >> 2;
5018         EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff));
5019         AdvanceIT();
5020         return;
5021       }
5022       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
5023       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5024           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
5025           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5026            AllowUnpredictable())) {
5027         EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5028                    (offset & 0xfff));
5029         AdvanceIT();
5030         return;
5031       }
5032       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
5033       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5034           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
5035           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5036            AllowUnpredictable())) {
5037         EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5038                    (-offset & 0xff));
5039         AdvanceIT();
5040         return;
5041       }
5042       // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
5043       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5044           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
5045           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5046            AllowUnpredictable())) {
5047         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5048         uint32_t offset_ = abs(offset);
5049         EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5050                    offset_ | (sign << 9));
5051         AdvanceIT();
5052         return;
5053       }
5054       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
5055       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5056           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
5057           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5058            AllowUnpredictable())) {
5059         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5060         uint32_t offset_ = abs(offset);
5061         EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5062                    offset_ | (sign << 9));
5063         AdvanceIT();
5064         return;
5065       }
5066       // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2
5067       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5068           rn.Is(pc) && operand.IsOffset() &&
5069           ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5070            AllowUnpredictable())) {
5071         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5072         uint32_t offset_ = abs(offset);
5073         EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5074         AdvanceIT();
5075         return;
5076       }
5077     } else {
5078       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
5079       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
5080           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5081         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5082         uint32_t offset_ = abs(offset);
5083         EmitA32(0x05100000U | (cond.GetCondition() << 28) |
5084                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5085                 (sign << 23));
5086         return;
5087       }
5088       // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
5089       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
5090           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5091         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5092         uint32_t offset_ = abs(offset);
5093         EmitA32(0x04100000U | (cond.GetCondition() << 28) |
5094                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5095                 (sign << 23));
5096         return;
5097       }
5098       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
5099       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
5100           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5101         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5102         uint32_t offset_ = abs(offset);
5103         EmitA32(0x05300000U | (cond.GetCondition() << 28) |
5104                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5105                 (sign << 23));
5106         return;
5107       }
5108       // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5109       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
5110           operand.IsOffset() && cond.IsNotNever()) {
5111         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5112         uint32_t offset_ = abs(offset);
5113         EmitA32(0x051f0000U | (cond.GetCondition() << 28) |
5114                 (rt.GetCode() << 12) | offset_ | (sign << 23));
5115         return;
5116       }
5117     }
5118   }
5119   if (operand.IsPlainRegister()) {
5120     Register rn = operand.GetBaseRegister();
5121     Sign sign = operand.GetSign();
5122     Register rm = operand.GetOffsetRegister();
5123     if (IsUsingT32()) {
5124       // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5125       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5126           sign.IsPlus() && operand.IsOffset()) {
5127         EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) |
5128                    (rm.GetCode() << 6));
5129         AdvanceIT();
5130         return;
5131       }
5132     }
5133   }
5134   if (operand.IsShiftedRegister()) {
5135     Register rn = operand.GetBaseRegister();
5136     Sign sign = operand.GetSign();
5137     Register rm = operand.GetOffsetRegister();
5138     Shift shift = operand.GetShift();
5139     uint32_t amount = operand.GetShiftAmount();
5140     if (IsUsingT32()) {
5141       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5142       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5143           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
5144           ((!rm.IsPC() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) ||
5145            AllowUnpredictable())) {
5146         EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5147                    rm.GetCode() | (amount << 4));
5148         AdvanceIT();
5149         return;
5150       }
5151     } else {
5152       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
5153       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
5154           (!rm.IsPC() || AllowUnpredictable())) {
5155         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5156         uint32_t shift_ = TypeEncodingValue(shift);
5157         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5158         EmitA32(0x07100000U | (cond.GetCondition() << 28) |
5159                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5160                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5161         return;
5162       }
5163       // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
5164       if (operand.IsShiftValid() && operand.IsPostIndex() &&
5165           cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
5166         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5167         uint32_t shift_ = TypeEncodingValue(shift);
5168         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5169         EmitA32(0x06100000U | (cond.GetCondition() << 28) |
5170                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5171                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5172         return;
5173       }
5174       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
5175       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
5176           (!rm.IsPC() || AllowUnpredictable())) {
5177         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5178         uint32_t shift_ = TypeEncodingValue(shift);
5179         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5180         EmitA32(0x07300000U | (cond.GetCondition() << 28) |
5181                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5182                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5183         return;
5184       }
5185     }
5186   }
5187   Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand);
5188 }
5189 
ldr(Condition cond,EncodingSize size,Register rt,Location * location)5190 void Assembler::ldr(Condition cond,
5191                     EncodingSize size,
5192                     Register rt,
5193                     Location* location) {
5194   VIXL_ASSERT(AllowAssembler());
5195   CheckIT(cond);
5196   Location::Offset offset =
5197       location->IsBound()
5198           ? location->GetLocation() -
5199                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5200           : 0;
5201   if (IsUsingT32()) {
5202     // LDR{<c>}{<q>} <Rt>, <label> ; T1
5203     if (!size.IsWide() && rt.IsLow() &&
5204         ((location->IsBound() && (offset >= 0) && (offset <= 1020) &&
5205           ((offset & 0x3) == 0)) ||
5206          (!location->IsBound() && size.IsNarrow()))) {
5207       static class EmitOp : public Location::EmitOperator {
5208        public:
5209         EmitOp() : Location::EmitOperator(T32) {}
5210         virtual uint32_t Encode(uint32_t instr,
5211                                 Location::Offset pc,
5212                                 const Location* location) const VIXL_OVERRIDE {
5213           pc += kT32PcDelta;
5214           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
5215           VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
5216                       ((offset & 0x3) == 0));
5217           const int32_t target = offset >> 2;
5218           return instr | (target & 0xff);
5219         }
5220       } immop;
5221       EmitT32_16(
5222           Link(0x4800 | (rt.GetCode() << 8), location, immop, &kT16DataInfo));
5223       AdvanceIT();
5224       return;
5225     }
5226     // LDR{<c>}{<q>} <Rt>, <label> ; T2
5227     if (!size.IsNarrow() &&
5228         ((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5229          !location->IsBound()) &&
5230         ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5231          AllowUnpredictable())) {
5232       static class EmitOp : public Location::EmitOperator {
5233        public:
5234         EmitOp() : Location::EmitOperator(T32) {}
5235         virtual uint32_t Encode(uint32_t instr,
5236                                 Location::Offset pc,
5237                                 const Location* location) const VIXL_OVERRIDE {
5238           pc += kT32PcDelta;
5239           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
5240           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5241           uint32_t U = (offset >= 0);
5242           int32_t target = abs(offset) | (U << 12);
5243           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5244         }
5245       } immop;
5246       EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12),
5247                       location,
5248                       immop,
5249                       &kT32FarDataInfo));
5250       AdvanceIT();
5251       return;
5252     }
5253   } else {
5254     // LDR{<c>}{<q>} <Rt>, <label> ; A1
5255     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5256          !location->IsBound()) &&
5257         cond.IsNotNever()) {
5258       static class EmitOp : public Location::EmitOperator {
5259        public:
5260         EmitOp() : Location::EmitOperator(A32) {}
5261         virtual uint32_t Encode(uint32_t instr,
5262                                 Location::Offset pc,
5263                                 const Location* location) const VIXL_OVERRIDE {
5264           pc += kA32PcDelta;
5265           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
5266           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5267           uint32_t U = (offset >= 0);
5268           int32_t target = abs(offset) | (U << 12);
5269           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5270         }
5271       } immop;
5272       EmitA32(
5273           Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5274                location,
5275                immop,
5276                &kA32FarDataInfo));
5277       return;
5278     }
5279   }
5280   Delegate(kLdr, &Assembler::ldr, cond, size, rt, location);
5281 }
5282 
ldr_info(Condition cond,EncodingSize size,Register rt,Location * location,const struct ReferenceInfo ** info)5283 bool Assembler::ldr_info(Condition cond,
5284                          EncodingSize size,
5285                          Register rt,
5286                          Location* location,
5287                          const struct ReferenceInfo** info) {
5288   VIXL_ASSERT(!location->IsBound());
5289   USE(location);
5290   if (IsUsingT32()) {
5291     // LDR{<c>}{<q>} <Rt>, <label> ; T1
5292     if (!size.IsWide() && rt.IsLow() && size.IsNarrow()) {
5293       *info = &kT16DataInfo;
5294       return true;
5295     }
5296     // LDR{<c>}{<q>} <Rt>, <label> ; T2
5297     if (!size.IsNarrow()) {
5298       *info = &kT32FarDataInfo;
5299       return true;
5300     }
5301   } else {
5302     // LDR{<c>}{<q>} <Rt>, <label> ; A1
5303     if (cond.IsNotNever()) {
5304       *info = &kA32FarDataInfo;
5305       return true;
5306     }
5307   }
5308   return false;
5309 }
5310 
ldrb(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)5311 void Assembler::ldrb(Condition cond,
5312                      EncodingSize size,
5313                      Register rt,
5314                      const MemOperand& operand) {
5315   VIXL_ASSERT(AllowAssembler());
5316   CheckIT(cond);
5317   if (operand.IsImmediate()) {
5318     Register rn = operand.GetBaseRegister();
5319     int32_t offset = operand.GetOffsetImmediate();
5320     if (IsUsingT32()) {
5321       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5322       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
5323           (offset <= 31) && operand.IsOffset()) {
5324         EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) |
5325                    ((offset & 0x1f) << 6));
5326         AdvanceIT();
5327         return;
5328       }
5329       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
5330       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5331           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5332         EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5333                    (offset & 0xfff));
5334         AdvanceIT();
5335         return;
5336       }
5337       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
5338       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5339           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5340         EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5341                    (-offset & 0xff));
5342         AdvanceIT();
5343         return;
5344       }
5345       // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
5346       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5347           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5348         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5349         uint32_t offset_ = abs(offset);
5350         EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5351                    offset_ | (sign << 9));
5352         AdvanceIT();
5353         return;
5354       }
5355       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
5356       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5357           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5358         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5359         uint32_t offset_ = abs(offset);
5360         EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5361                    offset_ | (sign << 9));
5362         AdvanceIT();
5363         return;
5364       }
5365       // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5366       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5367           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5368         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5369         uint32_t offset_ = abs(offset);
5370         EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5371         AdvanceIT();
5372         return;
5373       }
5374     } else {
5375       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
5376       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
5377           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5378           (!rt.IsPC() || AllowUnpredictable())) {
5379         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5380         uint32_t offset_ = abs(offset);
5381         EmitA32(0x05500000U | (cond.GetCondition() << 28) |
5382                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5383                 (sign << 23));
5384         return;
5385       }
5386       // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
5387       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
5388           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5389           (!rt.IsPC() || AllowUnpredictable())) {
5390         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5391         uint32_t offset_ = abs(offset);
5392         EmitA32(0x04500000U | (cond.GetCondition() << 28) |
5393                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5394                 (sign << 23));
5395         return;
5396       }
5397       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
5398       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
5399           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5400           (!rt.IsPC() || AllowUnpredictable())) {
5401         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5402         uint32_t offset_ = abs(offset);
5403         EmitA32(0x05700000U | (cond.GetCondition() << 28) |
5404                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5405                 (sign << 23));
5406         return;
5407       }
5408       // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5409       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
5410           operand.IsOffset() && cond.IsNotNever() &&
5411           (!rt.IsPC() || AllowUnpredictable())) {
5412         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5413         uint32_t offset_ = abs(offset);
5414         EmitA32(0x055f0000U | (cond.GetCondition() << 28) |
5415                 (rt.GetCode() << 12) | offset_ | (sign << 23));
5416         return;
5417       }
5418     }
5419   }
5420   if (operand.IsPlainRegister()) {
5421     Register rn = operand.GetBaseRegister();
5422     Sign sign = operand.GetSign();
5423     Register rm = operand.GetOffsetRegister();
5424     if (IsUsingT32()) {
5425       // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5426       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5427           sign.IsPlus() && operand.IsOffset()) {
5428         EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) |
5429                    (rm.GetCode() << 6));
5430         AdvanceIT();
5431         return;
5432       }
5433     }
5434   }
5435   if (operand.IsShiftedRegister()) {
5436     Register rn = operand.GetBaseRegister();
5437     Sign sign = operand.GetSign();
5438     Register rm = operand.GetOffsetRegister();
5439     Shift shift = operand.GetShift();
5440     uint32_t amount = operand.GetShiftAmount();
5441     if (IsUsingT32()) {
5442       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5443       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5444           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
5445           (!rm.IsPC() || AllowUnpredictable())) {
5446         EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5447                    rm.GetCode() | (amount << 4));
5448         AdvanceIT();
5449         return;
5450       }
5451     } else {
5452       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
5453       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
5454           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
5455         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5456         uint32_t shift_ = TypeEncodingValue(shift);
5457         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5458         EmitA32(0x07500000U | (cond.GetCondition() << 28) |
5459                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5460                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5461         return;
5462       }
5463       // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
5464       if (operand.IsShiftValid() && operand.IsPostIndex() &&
5465           cond.IsNotNever() &&
5466           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
5467         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5468         uint32_t shift_ = TypeEncodingValue(shift);
5469         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5470         EmitA32(0x06500000U | (cond.GetCondition() << 28) |
5471                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5472                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5473         return;
5474       }
5475       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
5476       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
5477           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
5478         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5479         uint32_t shift_ = TypeEncodingValue(shift);
5480         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5481         EmitA32(0x07700000U | (cond.GetCondition() << 28) |
5482                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5483                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5484         return;
5485       }
5486     }
5487   }
5488   Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand);
5489 }
5490 
ldrb(Condition cond,Register rt,Location * location)5491 void Assembler::ldrb(Condition cond, Register rt, Location* location) {
5492   VIXL_ASSERT(AllowAssembler());
5493   CheckIT(cond);
5494   Location::Offset offset =
5495       location->IsBound()
5496           ? location->GetLocation() -
5497                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5498           : 0;
5499   if (IsUsingT32()) {
5500     // LDRB{<c>}{<q>} <Rt>, <label> ; T1
5501     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5502          !location->IsBound()) &&
5503         !rt.Is(pc)) {
5504       static class EmitOp : public Location::EmitOperator {
5505        public:
5506         EmitOp() : Location::EmitOperator(T32) {}
5507         virtual uint32_t Encode(uint32_t instr,
5508                                 Location::Offset pc,
5509                                 const Location* location) const VIXL_OVERRIDE {
5510           pc += kT32PcDelta;
5511           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
5512           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5513           uint32_t U = (offset >= 0);
5514           int32_t target = abs(offset) | (U << 12);
5515           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5516         }
5517       } immop;
5518       EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12),
5519                       location,
5520                       immop,
5521                       &kT32FarDataInfo));
5522       AdvanceIT();
5523       return;
5524     }
5525   } else {
5526     // LDRB{<c>}{<q>} <Rt>, <label> ; A1
5527     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5528          !location->IsBound()) &&
5529         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
5530       static class EmitOp : public Location::EmitOperator {
5531        public:
5532         EmitOp() : Location::EmitOperator(A32) {}
5533         virtual uint32_t Encode(uint32_t instr,
5534                                 Location::Offset pc,
5535                                 const Location* location) const VIXL_OVERRIDE {
5536           pc += kA32PcDelta;
5537           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
5538           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5539           uint32_t U = (offset >= 0);
5540           int32_t target = abs(offset) | (U << 12);
5541           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5542         }
5543       } immop;
5544       EmitA32(
5545           Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5546                location,
5547                immop,
5548                &kA32FarDataInfo));
5549       return;
5550     }
5551   }
5552   Delegate(kLdrb, &Assembler::ldrb, cond, rt, location);
5553 }
5554 
ldrb_info(Condition cond,Register rt,Location * location,const struct ReferenceInfo ** info)5555 bool Assembler::ldrb_info(Condition cond,
5556                           Register rt,
5557                           Location* location,
5558                           const struct ReferenceInfo** info) {
5559   VIXL_ASSERT(!location->IsBound());
5560   USE(location);
5561   if (IsUsingT32()) {
5562     // LDRB{<c>}{<q>} <Rt>, <label> ; T1
5563     if (!rt.Is(pc)) {
5564       *info = &kT32FarDataInfo;
5565       return true;
5566     }
5567   } else {
5568     // LDRB{<c>}{<q>} <Rt>, <label> ; A1
5569     if (cond.IsNotNever()) {
5570       *info = &kA32FarDataInfo;
5571       return true;
5572     }
5573   }
5574   return false;
5575 }
5576 
ldrd(Condition cond,Register rt,Register rt2,const MemOperand & operand)5577 void Assembler::ldrd(Condition cond,
5578                      Register rt,
5579                      Register rt2,
5580                      const MemOperand& operand) {
5581   VIXL_ASSERT(AllowAssembler());
5582   CheckIT(cond);
5583   if (operand.IsImmediate()) {
5584     Register rn = operand.GetBaseRegister();
5585     int32_t offset = operand.GetOffsetImmediate();
5586     if (IsUsingT32()) {
5587       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
5588       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5589           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
5590           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
5591         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5592         uint32_t offset_ = abs(offset) >> 2;
5593         EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5594                    (rn.GetCode() << 16) | offset_ | (sign << 23));
5595         AdvanceIT();
5596         return;
5597       }
5598       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
5599       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5600           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
5601           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
5602         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5603         uint32_t offset_ = abs(offset) >> 2;
5604         EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5605                    (rn.GetCode() << 16) | offset_ | (sign << 23));
5606         AdvanceIT();
5607         return;
5608       }
5609       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
5610       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5611           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
5612           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
5613         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5614         uint32_t offset_ = abs(offset) >> 2;
5615         EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5616                    (rn.GetCode() << 16) | offset_ | (sign << 23));
5617         AdvanceIT();
5618         return;
5619       }
5620       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1
5621       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5622           operand.IsOffset() &&
5623           ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
5624         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5625         uint32_t offset_ = abs(offset);
5626         EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5627                    offset_ | (sign << 23));
5628         AdvanceIT();
5629         return;
5630       }
5631     } else {
5632       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
5633       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5634           (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5635           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5636           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
5637            AllowUnpredictable())) {
5638         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5639         uint32_t offset_ = abs(offset);
5640         EmitA32(0x014000d0U | (cond.GetCondition() << 28) |
5641                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5642                 ((offset_ & 0xf0) << 4) | (sign << 23));
5643         return;
5644       }
5645       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
5646       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5647           (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5648           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5649           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
5650            AllowUnpredictable())) {
5651         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5652         uint32_t offset_ = abs(offset);
5653         EmitA32(0x004000d0U | (cond.GetCondition() << 28) |
5654                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5655                 ((offset_ & 0xf0) << 4) | (sign << 23));
5656         return;
5657       }
5658       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
5659       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5660           (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5661           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5662           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
5663            AllowUnpredictable())) {
5664         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5665         uint32_t offset_ = abs(offset);
5666         EmitA32(0x016000d0U | (cond.GetCondition() << 28) |
5667                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5668                 ((offset_ & 0xf0) << 4) | (sign << 23));
5669         return;
5670       }
5671       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1
5672       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5673           (offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5674           operand.IsOffset() && cond.IsNotNever() &&
5675           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
5676            AllowUnpredictable())) {
5677         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5678         uint32_t offset_ = abs(offset);
5679         EmitA32(0x014f00d0U | (cond.GetCondition() << 28) |
5680                 (rt.GetCode() << 12) | (offset_ & 0xf) |
5681                 ((offset_ & 0xf0) << 4) | (sign << 23));
5682         return;
5683       }
5684     }
5685   }
5686   if (operand.IsPlainRegister()) {
5687     Register rn = operand.GetBaseRegister();
5688     Sign sign = operand.GetSign();
5689     Register rm = operand.GetOffsetRegister();
5690     if (IsUsingA32()) {
5691       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
5692       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5693           operand.IsOffset() && cond.IsNotNever() &&
5694           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
5695            AllowUnpredictable())) {
5696         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5697         EmitA32(0x010000d0U | (cond.GetCondition() << 28) |
5698                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5699                 (sign_ << 23));
5700         return;
5701       }
5702       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
5703       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5704           operand.IsPostIndex() && cond.IsNotNever() &&
5705           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
5706            AllowUnpredictable())) {
5707         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5708         EmitA32(0x000000d0U | (cond.GetCondition() << 28) |
5709                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5710                 (sign_ << 23));
5711         return;
5712       }
5713       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
5714       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5715           operand.IsPreIndex() && cond.IsNotNever() &&
5716           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
5717            AllowUnpredictable())) {
5718         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5719         EmitA32(0x012000d0U | (cond.GetCondition() << 28) |
5720                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5721                 (sign_ << 23));
5722         return;
5723       }
5724     }
5725   }
5726   Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand);
5727 }
5728 
ldrd(Condition cond,Register rt,Register rt2,Location * location)5729 void Assembler::ldrd(Condition cond,
5730                      Register rt,
5731                      Register rt2,
5732                      Location* location) {
5733   VIXL_ASSERT(AllowAssembler());
5734   CheckIT(cond);
5735   Location::Offset offset =
5736       location->IsBound()
5737           ? location->GetLocation() -
5738                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5739           : 0;
5740   if (IsUsingT32()) {
5741     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
5742     if (((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
5743           ((offset & 0x3) == 0)) ||
5744          !location->IsBound()) &&
5745         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
5746       static class EmitOp : public Location::EmitOperator {
5747        public:
5748         EmitOp() : Location::EmitOperator(T32) {}
5749         virtual uint32_t Encode(uint32_t instr,
5750                                 Location::Offset pc,
5751                                 const Location* location) const VIXL_OVERRIDE {
5752           pc += kT32PcDelta;
5753           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
5754           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
5755                       ((offset & 0x3) == 0));
5756           int32_t target = offset >> 2;
5757           uint32_t U = (target >= 0);
5758           target = abs(target) | (U << 8);
5759           return instr | (target & 0xff) | ((target & 0x100) << 15);
5760         }
5761       } immop;
5762       EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8),
5763                       location,
5764                       immop,
5765                       &kT32DataInfo));
5766       AdvanceIT();
5767       return;
5768     }
5769   } else {
5770     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
5771     if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5772         ((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
5773          !location->IsBound()) &&
5774         cond.IsNotNever() &&
5775         ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || AllowUnpredictable())) {
5776       static class EmitOp : public Location::EmitOperator {
5777        public:
5778         EmitOp() : Location::EmitOperator(A32) {}
5779         virtual uint32_t Encode(uint32_t instr,
5780                                 Location::Offset pc,
5781                                 const Location* location) const VIXL_OVERRIDE {
5782           pc += kA32PcDelta;
5783           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
5784           VIXL_ASSERT((offset >= -255) && (offset <= 255));
5785           uint32_t U = (offset >= 0);
5786           int32_t target = abs(offset) | (U << 8);
5787           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5788                  ((target & 0x100) << 15);
5789         }
5790       } immop;
5791       EmitA32(
5792           Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5793                location,
5794                immop,
5795                &kA32VeryNearDataInfo));
5796       return;
5797     }
5798   }
5799   Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, location);
5800 }
5801 
ldrd_info(Condition cond,Register rt,Register rt2,Location * location,const struct ReferenceInfo ** info)5802 bool Assembler::ldrd_info(Condition cond,
5803                           Register rt,
5804                           Register rt2,
5805                           Location* location,
5806                           const struct ReferenceInfo** info) {
5807   VIXL_ASSERT(!location->IsBound());
5808   USE(location);
5809   if (IsUsingT32()) {
5810     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
5811     if (true) {
5812       *info = &kT32DataInfo;
5813       return true;
5814     }
5815   } else {
5816     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
5817     if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5818         cond.IsNotNever()) {
5819       *info = &kA32VeryNearDataInfo;
5820       return true;
5821     }
5822   }
5823   return false;
5824 }
5825 
ldrex(Condition cond,Register rt,const MemOperand & operand)5826 void Assembler::ldrex(Condition cond, Register rt, const MemOperand& operand) {
5827   VIXL_ASSERT(AllowAssembler());
5828   CheckIT(cond);
5829   if (operand.IsImmediate()) {
5830     Register rn = operand.GetBaseRegister();
5831     int32_t offset = operand.GetOffsetImmediate();
5832     if (IsUsingT32()) {
5833       // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1
5834       if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
5835           operand.IsOffset() &&
5836           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5837         int32_t offset_ = offset >> 2;
5838         EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5839                    (offset_ & 0xff));
5840         AdvanceIT();
5841         return;
5842       }
5843     } else {
5844       // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1
5845       if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() &&
5846           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5847         EmitA32(0x01900f9fU | (cond.GetCondition() << 28) |
5848                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5849         return;
5850       }
5851     }
5852   }
5853   Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand);
5854 }
5855 
ldrexb(Condition cond,Register rt,const MemOperand & operand)5856 void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) {
5857   VIXL_ASSERT(AllowAssembler());
5858   CheckIT(cond);
5859   if (operand.IsImmediateZero()) {
5860     Register rn = operand.GetBaseRegister();
5861     if (IsUsingT32()) {
5862       // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
5863       if (operand.IsOffset() &&
5864           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5865         EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5866         AdvanceIT();
5867         return;
5868       }
5869     } else {
5870       // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
5871       if (operand.IsOffset() && cond.IsNotNever() &&
5872           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5873         EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) |
5874                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5875         return;
5876       }
5877     }
5878   }
5879   Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand);
5880 }
5881 
ldrexd(Condition cond,Register rt,Register rt2,const MemOperand & operand)5882 void Assembler::ldrexd(Condition cond,
5883                        Register rt,
5884                        Register rt2,
5885                        const MemOperand& operand) {
5886   VIXL_ASSERT(AllowAssembler());
5887   CheckIT(cond);
5888   if (operand.IsImmediateZero()) {
5889     Register rn = operand.GetBaseRegister();
5890     if (IsUsingT32()) {
5891       // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
5892       if (operand.IsOffset() &&
5893           ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5894         EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5895                    (rn.GetCode() << 16));
5896         AdvanceIT();
5897         return;
5898       }
5899     } else {
5900       // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
5901       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5902           operand.IsOffset() && cond.IsNotNever() &&
5903           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) ||
5904            AllowUnpredictable())) {
5905         EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) |
5906                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5907         return;
5908       }
5909     }
5910   }
5911   Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand);
5912 }
5913 
ldrexh(Condition cond,Register rt,const MemOperand & operand)5914 void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) {
5915   VIXL_ASSERT(AllowAssembler());
5916   CheckIT(cond);
5917   if (operand.IsImmediateZero()) {
5918     Register rn = operand.GetBaseRegister();
5919     if (IsUsingT32()) {
5920       // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
5921       if (operand.IsOffset() &&
5922           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5923         EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5924         AdvanceIT();
5925         return;
5926       }
5927     } else {
5928       // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
5929       if (operand.IsOffset() && cond.IsNotNever() &&
5930           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5931         EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) |
5932                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5933         return;
5934       }
5935     }
5936   }
5937   Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand);
5938 }
5939 
ldrh(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)5940 void Assembler::ldrh(Condition cond,
5941                      EncodingSize size,
5942                      Register rt,
5943                      const MemOperand& operand) {
5944   VIXL_ASSERT(AllowAssembler());
5945   CheckIT(cond);
5946   if (operand.IsImmediate()) {
5947     Register rn = operand.GetBaseRegister();
5948     int32_t offset = operand.GetOffsetImmediate();
5949     if (IsUsingT32()) {
5950       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5951       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
5952           (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
5953         int32_t offset_ = offset >> 1;
5954         EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) |
5955                    ((offset_ & 0x1f) << 6));
5956         AdvanceIT();
5957         return;
5958       }
5959       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
5960       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5961           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5962         EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5963                    (offset & 0xfff));
5964         AdvanceIT();
5965         return;
5966       }
5967       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
5968       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5969           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5970         EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5971                    (-offset & 0xff));
5972         AdvanceIT();
5973         return;
5974       }
5975       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
5976       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5977           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5978         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5979         uint32_t offset_ = abs(offset);
5980         EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5981                    offset_ | (sign << 9));
5982         AdvanceIT();
5983         return;
5984       }
5985       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
5986       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5987           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5988         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5989         uint32_t offset_ = abs(offset);
5990         EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5991                    offset_ | (sign << 9));
5992         AdvanceIT();
5993         return;
5994       }
5995       // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5996       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5997           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5998         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5999         uint32_t offset_ = abs(offset);
6000         EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
6001         AdvanceIT();
6002         return;
6003       }
6004     } else {
6005       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
6006       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
6007           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6008           (!rt.IsPC() || AllowUnpredictable())) {
6009         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6010         uint32_t offset_ = abs(offset);
6011         EmitA32(0x015000b0U | (cond.GetCondition() << 28) |
6012                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6013                 ((offset_ & 0xf0) << 4) | (sign << 23));
6014         return;
6015       }
6016       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
6017       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
6018           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6019           (!rt.IsPC() || AllowUnpredictable())) {
6020         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6021         uint32_t offset_ = abs(offset);
6022         EmitA32(0x005000b0U | (cond.GetCondition() << 28) |
6023                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6024                 ((offset_ & 0xf0) << 4) | (sign << 23));
6025         return;
6026       }
6027       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
6028       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
6029           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6030           (!rt.IsPC() || AllowUnpredictable())) {
6031         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6032         uint32_t offset_ = abs(offset);
6033         EmitA32(0x017000b0U | (cond.GetCondition() << 28) |
6034                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6035                 ((offset_ & 0xf0) << 4) | (sign << 23));
6036         return;
6037       }
6038       // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
6039       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
6040           operand.IsOffset() && cond.IsNotNever() &&
6041           (!rt.IsPC() || AllowUnpredictable())) {
6042         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6043         uint32_t offset_ = abs(offset);
6044         EmitA32(0x015f00b0U | (cond.GetCondition() << 28) |
6045                 (rt.GetCode() << 12) | (offset_ & 0xf) |
6046                 ((offset_ & 0xf0) << 4) | (sign << 23));
6047         return;
6048       }
6049     }
6050   }
6051   if (operand.IsPlainRegister()) {
6052     Register rn = operand.GetBaseRegister();
6053     Sign sign = operand.GetSign();
6054     Register rm = operand.GetOffsetRegister();
6055     if (IsUsingT32()) {
6056       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
6057       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
6058           sign.IsPlus() && operand.IsOffset()) {
6059         EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) |
6060                    (rm.GetCode() << 6));
6061         AdvanceIT();
6062         return;
6063       }
6064     } else {
6065       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
6066       if (operand.IsOffset() && cond.IsNotNever() &&
6067           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6068         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6069         EmitA32(0x011000b0U | (cond.GetCondition() << 28) |
6070                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6071                 (sign_ << 23));
6072         return;
6073       }
6074       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
6075       if (operand.IsPostIndex() && cond.IsNotNever() &&
6076           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6077         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6078         EmitA32(0x001000b0U | (cond.GetCondition() << 28) |
6079                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6080                 (sign_ << 23));
6081         return;
6082       }
6083       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
6084       if (operand.IsPreIndex() && cond.IsNotNever() &&
6085           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6086         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6087         EmitA32(0x013000b0U | (cond.GetCondition() << 28) |
6088                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6089                 (sign_ << 23));
6090         return;
6091       }
6092     }
6093   }
6094   if (operand.IsShiftedRegister()) {
6095     Register rn = operand.GetBaseRegister();
6096     Sign sign = operand.GetSign();
6097     Register rm = operand.GetOffsetRegister();
6098     Shift shift = operand.GetShift();
6099     uint32_t amount = operand.GetShiftAmount();
6100     if (IsUsingT32()) {
6101       // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
6102       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
6103           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
6104           (!rm.IsPC() || AllowUnpredictable())) {
6105         EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6106                    rm.GetCode() | (amount << 4));
6107         AdvanceIT();
6108         return;
6109       }
6110     }
6111   }
6112   Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand);
6113 }
6114 
ldrh(Condition cond,Register rt,Location * location)6115 void Assembler::ldrh(Condition cond, Register rt, Location* location) {
6116   VIXL_ASSERT(AllowAssembler());
6117   CheckIT(cond);
6118   Location::Offset offset =
6119       location->IsBound()
6120           ? location->GetLocation() -
6121                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
6122           : 0;
6123   if (IsUsingT32()) {
6124     // LDRH{<c>}{<q>} <Rt>, <label> ; T1
6125     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
6126          !location->IsBound()) &&
6127         !rt.Is(pc)) {
6128       static class EmitOp : public Location::EmitOperator {
6129        public:
6130         EmitOp() : Location::EmitOperator(T32) {}
6131         virtual uint32_t Encode(uint32_t instr,
6132                                 Location::Offset pc,
6133                                 const Location* location) const VIXL_OVERRIDE {
6134           pc += kT32PcDelta;
6135           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
6136           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
6137           uint32_t U = (offset >= 0);
6138           int32_t target = abs(offset) | (U << 12);
6139           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
6140         }
6141       } immop;
6142       EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12),
6143                       location,
6144                       immop,
6145                       &kT32FarDataInfo));
6146       AdvanceIT();
6147       return;
6148     }
6149   } else {
6150     // LDRH{<c>}{<q>} <Rt>, <label> ; A1
6151     if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
6152          !location->IsBound()) &&
6153         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
6154       static class EmitOp : public Location::EmitOperator {
6155        public:
6156         EmitOp() : Location::EmitOperator(A32) {}
6157         virtual uint32_t Encode(uint32_t instr,
6158                                 Location::Offset pc,
6159                                 const Location* location) const VIXL_OVERRIDE {
6160           pc += kA32PcDelta;
6161           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
6162           VIXL_ASSERT((offset >= -255) && (offset <= 255));
6163           uint32_t U = (offset >= 0);
6164           int32_t target = abs(offset) | (U << 8);
6165           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
6166                  ((target & 0x100) << 15);
6167         }
6168       } immop;
6169       EmitA32(
6170           Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
6171                location,
6172                immop,
6173                &kA32VeryNearDataInfo));
6174       return;
6175     }
6176   }
6177   Delegate(kLdrh, &Assembler::ldrh, cond, rt, location);
6178 }
6179 
ldrh_info(Condition cond,Register rt,Location * location,const struct ReferenceInfo ** info)6180 bool Assembler::ldrh_info(Condition cond,
6181                           Register rt,
6182                           Location* location,
6183                           const struct ReferenceInfo** info) {
6184   VIXL_ASSERT(!location->IsBound());
6185   USE(location);
6186   if (IsUsingT32()) {
6187     // LDRH{<c>}{<q>} <Rt>, <label> ; T1
6188     if (!rt.Is(pc)) {
6189       *info = &kT32FarDataInfo;
6190       return true;
6191     }
6192   } else {
6193     // LDRH{<c>}{<q>} <Rt>, <label> ; A1
6194     if (cond.IsNotNever()) {
6195       *info = &kA32VeryNearDataInfo;
6196       return true;
6197     }
6198   }
6199   return false;
6200 }
6201 
ldrsb(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)6202 void Assembler::ldrsb(Condition cond,
6203                       EncodingSize size,
6204                       Register rt,
6205                       const MemOperand& operand) {
6206   VIXL_ASSERT(AllowAssembler());
6207   CheckIT(cond);
6208   if (operand.IsImmediate()) {
6209     Register rn = operand.GetBaseRegister();
6210     int32_t offset = operand.GetOffsetImmediate();
6211     if (IsUsingT32()) {
6212       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
6213       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
6214           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
6215         EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6216                    (offset & 0xfff));
6217         AdvanceIT();
6218         return;
6219       }
6220       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
6221       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
6222           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
6223         EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6224                    (-offset & 0xff));
6225         AdvanceIT();
6226         return;
6227       }
6228       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
6229       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
6230           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
6231         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6232         uint32_t offset_ = abs(offset);
6233         EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6234                    offset_ | (sign << 9));
6235         AdvanceIT();
6236         return;
6237       }
6238       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
6239       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
6240           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
6241         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6242         uint32_t offset_ = abs(offset);
6243         EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6244                    offset_ | (sign << 9));
6245         AdvanceIT();
6246         return;
6247       }
6248       // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
6249       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
6250           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
6251         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6252         uint32_t offset_ = abs(offset);
6253         EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
6254         AdvanceIT();
6255         return;
6256       }
6257     } else {
6258       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
6259       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
6260           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6261           (!rt.IsPC() || AllowUnpredictable())) {
6262         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6263         uint32_t offset_ = abs(offset);
6264         EmitA32(0x015000d0U | (cond.GetCondition() << 28) |
6265                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6266                 ((offset_ & 0xf0) << 4) | (sign << 23));
6267         return;
6268       }
6269       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
6270       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
6271           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6272           (!rt.IsPC() || AllowUnpredictable())) {
6273         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6274         uint32_t offset_ = abs(offset);
6275         EmitA32(0x005000d0U | (cond.GetCondition() << 28) |
6276                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6277                 ((offset_ & 0xf0) << 4) | (sign << 23));
6278         return;
6279       }
6280       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
6281       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
6282           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6283           (!rt.IsPC() || AllowUnpredictable())) {
6284         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6285         uint32_t offset_ = abs(offset);
6286         EmitA32(0x017000d0U | (cond.GetCondition() << 28) |
6287                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6288                 ((offset_ & 0xf0) << 4) | (sign << 23));
6289         return;
6290       }
6291       // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
6292       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
6293           operand.IsOffset() && cond.IsNotNever() &&
6294           (!rt.IsPC() || AllowUnpredictable())) {
6295         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6296         uint32_t offset_ = abs(offset);
6297         EmitA32(0x015f00d0U | (cond.GetCondition() << 28) |
6298                 (rt.GetCode() << 12) | (offset_ & 0xf) |
6299                 ((offset_ & 0xf0) << 4) | (sign << 23));
6300         return;
6301       }
6302     }
6303   }
6304   if (operand.IsPlainRegister()) {
6305     Register rn = operand.GetBaseRegister();
6306     Sign sign = operand.GetSign();
6307     Register rm = operand.GetOffsetRegister();
6308     if (IsUsingT32()) {
6309       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
6310       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
6311           sign.IsPlus() && operand.IsOffset()) {
6312         EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) |
6313                    (rm.GetCode() << 6));
6314         AdvanceIT();
6315         return;
6316       }
6317     } else {
6318       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
6319       if (operand.IsOffset() && cond.IsNotNever() &&
6320           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6321         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6322         EmitA32(0x011000d0U | (cond.GetCondition() << 28) |
6323                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6324                 (sign_ << 23));
6325         return;
6326       }
6327       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
6328       if (operand.IsPostIndex() && cond.IsNotNever() &&
6329           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6330         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6331         EmitA32(0x001000d0U | (cond.GetCondition() << 28) |
6332                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6333                 (sign_ << 23));
6334         return;
6335       }
6336       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
6337       if (operand.IsPreIndex() && cond.IsNotNever() &&
6338           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6339         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6340         EmitA32(0x013000d0U | (cond.GetCondition() << 28) |
6341                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6342                 (sign_ << 23));
6343         return;
6344       }
6345     }
6346   }
6347   if (operand.IsShiftedRegister()) {
6348     Register rn = operand.GetBaseRegister();
6349     Sign sign = operand.GetSign();
6350     Register rm = operand.GetOffsetRegister();
6351     Shift shift = operand.GetShift();
6352     uint32_t amount = operand.GetShiftAmount();
6353     if (IsUsingT32()) {
6354       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
6355       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
6356           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
6357           (!rm.IsPC() || AllowUnpredictable())) {
6358         EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6359                    rm.GetCode() | (amount << 4));
6360         AdvanceIT();
6361         return;
6362       }
6363     }
6364   }
6365   Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand);
6366 }
6367 
ldrsb(Condition cond,Register rt,Location * location)6368 void Assembler::ldrsb(Condition cond, Register rt, Location* location) {
6369   VIXL_ASSERT(AllowAssembler());
6370   CheckIT(cond);
6371   Location::Offset offset =
6372       location->IsBound()
6373           ? location->GetLocation() -
6374                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
6375           : 0;
6376   if (IsUsingT32()) {
6377     // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
6378     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
6379          !location->IsBound()) &&
6380         !rt.Is(pc)) {
6381       static class EmitOp : public Location::EmitOperator {
6382        public:
6383         EmitOp() : Location::EmitOperator(T32) {}
6384         virtual uint32_t Encode(uint32_t instr,
6385                                 Location::Offset pc,
6386                                 const Location* location) const VIXL_OVERRIDE {
6387           pc += kT32PcDelta;
6388           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
6389           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
6390           uint32_t U = (offset >= 0);
6391           int32_t target = abs(offset) | (U << 12);
6392           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
6393         }
6394       } immop;
6395       EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12),
6396                       location,
6397                       immop,
6398                       &kT32FarDataInfo));
6399       AdvanceIT();
6400       return;
6401     }
6402   } else {
6403     // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
6404     if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
6405          !location->IsBound()) &&
6406         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
6407       static class EmitOp : public Location::EmitOperator {
6408        public:
6409         EmitOp() : Location::EmitOperator(A32) {}
6410         virtual uint32_t Encode(uint32_t instr,
6411                                 Location::Offset pc,
6412                                 const Location* location) const VIXL_OVERRIDE {
6413           pc += kA32PcDelta;
6414           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
6415           VIXL_ASSERT((offset >= -255) && (offset <= 255));
6416           uint32_t U = (offset >= 0);
6417           int32_t target = abs(offset) | (U << 8);
6418           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
6419                  ((target & 0x100) << 15);
6420         }
6421       } immop;
6422       EmitA32(
6423           Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
6424                location,
6425                immop,
6426                &kA32VeryNearDataInfo));
6427       return;
6428     }
6429   }
6430   Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, location);
6431 }
6432 
ldrsb_info(Condition cond,Register rt,Location * location,const struct ReferenceInfo ** info)6433 bool Assembler::ldrsb_info(Condition cond,
6434                            Register rt,
6435                            Location* location,
6436                            const struct ReferenceInfo** info) {
6437   VIXL_ASSERT(!location->IsBound());
6438   USE(location);
6439   if (IsUsingT32()) {
6440     // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
6441     if (!rt.Is(pc)) {
6442       *info = &kT32FarDataInfo;
6443       return true;
6444     }
6445   } else {
6446     // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
6447     if (cond.IsNotNever()) {
6448       *info = &kA32VeryNearDataInfo;
6449       return true;
6450     }
6451   }
6452   return false;
6453 }
6454 
ldrsh(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)6455 void Assembler::ldrsh(Condition cond,
6456                       EncodingSize size,
6457                       Register rt,
6458                       const MemOperand& operand) {
6459   VIXL_ASSERT(AllowAssembler());
6460   CheckIT(cond);
6461   if (operand.IsImmediate()) {
6462     Register rn = operand.GetBaseRegister();
6463     int32_t offset = operand.GetOffsetImmediate();
6464     if (IsUsingT32()) {
6465       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
6466       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
6467           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
6468         EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6469                    (offset & 0xfff));
6470         AdvanceIT();
6471         return;
6472       }
6473       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
6474       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
6475           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
6476         EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6477                    (-offset & 0xff));
6478         AdvanceIT();
6479         return;
6480       }
6481       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
6482       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
6483           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
6484         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6485         uint32_t offset_ = abs(offset);
6486         EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6487                    offset_ | (sign << 9));
6488         AdvanceIT();
6489         return;
6490       }
6491       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
6492       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
6493           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
6494         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6495         uint32_t offset_ = abs(offset);
6496         EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6497                    offset_ | (sign << 9));
6498         AdvanceIT();
6499         return;
6500       }
6501       // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
6502       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
6503           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
6504         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6505         uint32_t offset_ = abs(offset);
6506         EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
6507         AdvanceIT();
6508         return;
6509       }
6510     } else {
6511       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
6512       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
6513           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6514           (!rt.IsPC() || AllowUnpredictable())) {
6515         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6516         uint32_t offset_ = abs(offset);
6517         EmitA32(0x015000f0U | (cond.GetCondition() << 28) |
6518                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6519                 ((offset_ & 0xf0) << 4) | (sign << 23));
6520         return;
6521       }
6522       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
6523       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
6524           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6525           (!rt.IsPC() || AllowUnpredictable())) {
6526         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6527         uint32_t offset_ = abs(offset);
6528         EmitA32(0x005000f0U | (cond.GetCondition() << 28) |
6529                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6530                 ((offset_ & 0xf0) << 4) | (sign << 23));
6531         return;
6532       }
6533       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
6534       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
6535           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6536           (!rt.IsPC() || AllowUnpredictable())) {
6537         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6538         uint32_t offset_ = abs(offset);
6539         EmitA32(0x017000f0U | (cond.GetCondition() << 28) |
6540                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6541                 ((offset_ & 0xf0) << 4) | (sign << 23));
6542         return;
6543       }
6544       // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
6545       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
6546           operand.IsOffset() && cond.IsNotNever() &&
6547           (!rt.IsPC() || AllowUnpredictable())) {
6548         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6549         uint32_t offset_ = abs(offset);
6550         EmitA32(0x015f00f0U | (cond.GetCondition() << 28) |
6551                 (rt.GetCode() << 12) | (offset_ & 0xf) |
6552                 ((offset_ & 0xf0) << 4) | (sign << 23));
6553         return;
6554       }
6555     }
6556   }
6557   if (operand.IsPlainRegister()) {
6558     Register rn = operand.GetBaseRegister();
6559     Sign sign = operand.GetSign();
6560     Register rm = operand.GetOffsetRegister();
6561     if (IsUsingT32()) {
6562       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
6563       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
6564           sign.IsPlus() && operand.IsOffset()) {
6565         EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) |
6566                    (rm.GetCode() << 6));
6567         AdvanceIT();
6568         return;
6569       }
6570     } else {
6571       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
6572       if (operand.IsOffset() && cond.IsNotNever() &&
6573           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6574         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6575         EmitA32(0x011000f0U | (cond.GetCondition() << 28) |
6576                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6577                 (sign_ << 23));
6578         return;
6579       }
6580       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
6581       if (operand.IsPostIndex() && cond.IsNotNever() &&
6582           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6583         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6584         EmitA32(0x001000f0U | (cond.GetCondition() << 28) |
6585                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6586                 (sign_ << 23));
6587         return;
6588       }
6589       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
6590       if (operand.IsPreIndex() && cond.IsNotNever() &&
6591           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6592         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6593         EmitA32(0x013000f0U | (cond.GetCondition() << 28) |
6594                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6595                 (sign_ << 23));
6596         return;
6597       }
6598     }
6599   }
6600   if (operand.IsShiftedRegister()) {
6601     Register rn = operand.GetBaseRegister();
6602     Sign sign = operand.GetSign();
6603     Register rm = operand.GetOffsetRegister();
6604     Shift shift = operand.GetShift();
6605     uint32_t amount = operand.GetShiftAmount();
6606     if (IsUsingT32()) {
6607       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
6608       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
6609           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
6610           (!rm.IsPC() || AllowUnpredictable())) {
6611         EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6612                    rm.GetCode() | (amount << 4));
6613         AdvanceIT();
6614         return;
6615       }
6616     }
6617   }
6618   Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand);
6619 }
6620 
ldrsh(Condition cond,Register rt,Location * location)6621 void Assembler::ldrsh(Condition cond, Register rt, Location* location) {
6622   VIXL_ASSERT(AllowAssembler());
6623   CheckIT(cond);
6624   Location::Offset offset =
6625       location->IsBound()
6626           ? location->GetLocation() -
6627                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
6628           : 0;
6629   if (IsUsingT32()) {
6630     // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
6631     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
6632          !location->IsBound()) &&
6633         !rt.Is(pc)) {
6634       static class EmitOp : public Location::EmitOperator {
6635        public:
6636         EmitOp() : Location::EmitOperator(T32) {}
6637         virtual uint32_t Encode(uint32_t instr,
6638                                 Location::Offset pc,
6639                                 const Location* location) const VIXL_OVERRIDE {
6640           pc += kT32PcDelta;
6641           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
6642           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
6643           uint32_t U = (offset >= 0);
6644           int32_t target = abs(offset) | (U << 12);
6645           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
6646         }
6647       } immop;
6648       EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12),
6649                       location,
6650                       immop,
6651                       &kT32FarDataInfo));
6652       AdvanceIT();
6653       return;
6654     }
6655   } else {
6656     // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
6657     if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
6658          !location->IsBound()) &&
6659         cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
6660       static class EmitOp : public Location::EmitOperator {
6661        public:
6662         EmitOp() : Location::EmitOperator(A32) {}
6663         virtual uint32_t Encode(uint32_t instr,
6664                                 Location::Offset pc,
6665                                 const Location* location) const VIXL_OVERRIDE {
6666           pc += kA32PcDelta;
6667           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
6668           VIXL_ASSERT((offset >= -255) && (offset <= 255));
6669           uint32_t U = (offset >= 0);
6670           int32_t target = abs(offset) | (U << 8);
6671           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
6672                  ((target & 0x100) << 15);
6673         }
6674       } immop;
6675       EmitA32(
6676           Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
6677                location,
6678                immop,
6679                &kA32VeryNearDataInfo));
6680       return;
6681     }
6682   }
6683   Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, location);
6684 }
6685 
ldrsh_info(Condition cond,Register rt,Location * location,const struct ReferenceInfo ** info)6686 bool Assembler::ldrsh_info(Condition cond,
6687                            Register rt,
6688                            Location* location,
6689                            const struct ReferenceInfo** info) {
6690   VIXL_ASSERT(!location->IsBound());
6691   USE(location);
6692   if (IsUsingT32()) {
6693     // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
6694     if (!rt.Is(pc)) {
6695       *info = &kT32FarDataInfo;
6696       return true;
6697     }
6698   } else {
6699     // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
6700     if (cond.IsNotNever()) {
6701       *info = &kA32VeryNearDataInfo;
6702       return true;
6703     }
6704   }
6705   return false;
6706 }
6707 
lsl(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6708 void Assembler::lsl(Condition cond,
6709                     EncodingSize size,
6710                     Register rd,
6711                     Register rm,
6712                     const Operand& operand) {
6713   VIXL_ASSERT(AllowAssembler());
6714   CheckIT(cond);
6715   if (operand.IsImmediate()) {
6716     uint32_t imm = operand.GetImmediate();
6717     if (IsUsingT32()) {
6718       // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6719       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6720           (imm >= 1) && (imm <= 31)) {
6721         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6722         AdvanceIT();
6723         return;
6724       }
6725       // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6726       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
6727           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6728         EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6729                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6730         AdvanceIT();
6731         return;
6732       }
6733     } else {
6734       // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6735       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6736         EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
6737                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6738         return;
6739       }
6740     }
6741   }
6742   if (operand.IsPlainRegister()) {
6743     Register rs = operand.GetBaseRegister();
6744     if (IsUsingT32()) {
6745       // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6746       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6747           rs.IsLow()) {
6748         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6749         AdvanceIT();
6750         return;
6751       }
6752       // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6753       if (!size.IsNarrow() &&
6754           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6755         EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6756                    rs.GetCode());
6757         AdvanceIT();
6758         return;
6759       }
6760     } else {
6761       // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6762       if (cond.IsNotNever() &&
6763           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6764         EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
6765                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6766         return;
6767       }
6768     }
6769   }
6770   Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand);
6771 }
6772 
lsls(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6773 void Assembler::lsls(Condition cond,
6774                      EncodingSize size,
6775                      Register rd,
6776                      Register rm,
6777                      const Operand& operand) {
6778   VIXL_ASSERT(AllowAssembler());
6779   CheckIT(cond);
6780   if (operand.IsImmediate()) {
6781     uint32_t imm = operand.GetImmediate();
6782     if (IsUsingT32()) {
6783       // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6784       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6785           (imm >= 1) && (imm <= 31)) {
6786         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6787         AdvanceIT();
6788         return;
6789       }
6790       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6791       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
6792           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6793         EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6794                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6795         AdvanceIT();
6796         return;
6797       }
6798     } else {
6799       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6800       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6801         EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
6802                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6803         return;
6804       }
6805     }
6806   }
6807   if (operand.IsPlainRegister()) {
6808     Register rs = operand.GetBaseRegister();
6809     if (IsUsingT32()) {
6810       // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6811       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6812           rs.IsLow()) {
6813         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6814         AdvanceIT();
6815         return;
6816       }
6817       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6818       if (!size.IsNarrow() &&
6819           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6820         EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6821                    rs.GetCode());
6822         AdvanceIT();
6823         return;
6824       }
6825     } else {
6826       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6827       if (cond.IsNotNever() &&
6828           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6829         EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
6830                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6831         return;
6832       }
6833     }
6834   }
6835   Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand);
6836 }
6837 
lsr(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6838 void Assembler::lsr(Condition cond,
6839                     EncodingSize size,
6840                     Register rd,
6841                     Register rm,
6842                     const Operand& operand) {
6843   VIXL_ASSERT(AllowAssembler());
6844   CheckIT(cond);
6845   if (operand.IsImmediate()) {
6846     uint32_t imm = operand.GetImmediate();
6847     if (IsUsingT32()) {
6848       // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6849       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6850           (imm >= 1) && (imm <= 32)) {
6851         uint32_t amount_ = imm % 32;
6852         EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6853                    (amount_ << 6));
6854         AdvanceIT();
6855         return;
6856       }
6857       // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6858       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
6859           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6860         uint32_t amount_ = imm % 32;
6861         EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6862                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6863         AdvanceIT();
6864         return;
6865       }
6866     } else {
6867       // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6868       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6869         uint32_t amount_ = imm % 32;
6870         EmitA32(0x01a00020U | (cond.GetCondition() << 28) |
6871                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6872         return;
6873       }
6874     }
6875   }
6876   if (operand.IsPlainRegister()) {
6877     Register rs = operand.GetBaseRegister();
6878     if (IsUsingT32()) {
6879       // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6880       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6881           rs.IsLow()) {
6882         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6883         AdvanceIT();
6884         return;
6885       }
6886       // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6887       if (!size.IsNarrow() &&
6888           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6889         EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6890                    rs.GetCode());
6891         AdvanceIT();
6892         return;
6893       }
6894     } else {
6895       // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6896       if (cond.IsNotNever() &&
6897           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6898         EmitA32(0x01a00030U | (cond.GetCondition() << 28) |
6899                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6900         return;
6901       }
6902     }
6903   }
6904   Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand);
6905 }
6906 
lsrs(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6907 void Assembler::lsrs(Condition cond,
6908                      EncodingSize size,
6909                      Register rd,
6910                      Register rm,
6911                      const Operand& operand) {
6912   VIXL_ASSERT(AllowAssembler());
6913   CheckIT(cond);
6914   if (operand.IsImmediate()) {
6915     uint32_t imm = operand.GetImmediate();
6916     if (IsUsingT32()) {
6917       // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6918       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6919           (imm >= 1) && (imm <= 32)) {
6920         uint32_t amount_ = imm % 32;
6921         EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6922                    (amount_ << 6));
6923         AdvanceIT();
6924         return;
6925       }
6926       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6927       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
6928           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6929         uint32_t amount_ = imm % 32;
6930         EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6931                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6932         AdvanceIT();
6933         return;
6934       }
6935     } else {
6936       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6937       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6938         uint32_t amount_ = imm % 32;
6939         EmitA32(0x01b00020U | (cond.GetCondition() << 28) |
6940                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6941         return;
6942       }
6943     }
6944   }
6945   if (operand.IsPlainRegister()) {
6946     Register rs = operand.GetBaseRegister();
6947     if (IsUsingT32()) {
6948       // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6949       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6950           rs.IsLow()) {
6951         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6952         AdvanceIT();
6953         return;
6954       }
6955       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6956       if (!size.IsNarrow() &&
6957           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6958         EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6959                    rs.GetCode());
6960         AdvanceIT();
6961         return;
6962       }
6963     } else {
6964       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6965       if (cond.IsNotNever() &&
6966           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6967         EmitA32(0x01b00030U | (cond.GetCondition() << 28) |
6968                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6969         return;
6970       }
6971     }
6972   }
6973   Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand);
6974 }
6975 
mla(Condition cond,Register rd,Register rn,Register rm,Register ra)6976 void Assembler::mla(
6977     Condition cond, Register rd, Register rn, Register rm, Register ra) {
6978   VIXL_ASSERT(AllowAssembler());
6979   CheckIT(cond);
6980   if (IsUsingT32()) {
6981     // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
6982     if (!ra.Is(pc) &&
6983         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6984       EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6985                  rm.GetCode() | (ra.GetCode() << 12));
6986       AdvanceIT();
6987       return;
6988     }
6989   } else {
6990     // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6991     if (cond.IsNotNever() &&
6992         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
6993          AllowUnpredictable())) {
6994       EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6995               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6996       return;
6997     }
6998   }
6999   Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra);
7000 }
7001 
mlas(Condition cond,Register rd,Register rn,Register rm,Register ra)7002 void Assembler::mlas(
7003     Condition cond, Register rd, Register rn, Register rm, Register ra) {
7004   VIXL_ASSERT(AllowAssembler());
7005   CheckIT(cond);
7006   if (IsUsingA32()) {
7007     // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
7008     if (cond.IsNotNever() &&
7009         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
7010          AllowUnpredictable())) {
7011       EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
7012               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
7013       return;
7014     }
7015   }
7016   Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra);
7017 }
7018 
mls(Condition cond,Register rd,Register rn,Register rm,Register ra)7019 void Assembler::mls(
7020     Condition cond, Register rd, Register rn, Register rm, Register ra) {
7021   VIXL_ASSERT(AllowAssembler());
7022   CheckIT(cond);
7023   if (IsUsingT32()) {
7024     // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
7025     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
7026          AllowUnpredictable())) {
7027       EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7028                  rm.GetCode() | (ra.GetCode() << 12));
7029       AdvanceIT();
7030       return;
7031     }
7032   } else {
7033     // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
7034     if (cond.IsNotNever() &&
7035         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
7036          AllowUnpredictable())) {
7037       EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
7038               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
7039       return;
7040     }
7041   }
7042   Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra);
7043 }
7044 
mov(Condition cond,EncodingSize size,Register rd,const Operand & operand)7045 void Assembler::mov(Condition cond,
7046                     EncodingSize size,
7047                     Register rd,
7048                     const Operand& operand) {
7049   VIXL_ASSERT(AllowAssembler());
7050   CheckIT(cond);
7051   if (operand.IsImmediateShiftedRegister()) {
7052     Register rm = operand.GetBaseRegister();
7053     if (operand.IsPlainRegister()) {
7054       if (IsUsingT32()) {
7055         // MOV{<c>}{<q>} <Rd>, <Rm> ; T1
7056         if (!size.IsWide() &&
7057             ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
7058              AllowUnpredictable())) {
7059           EmitT32_16(0x4600 | (rd.GetCode() & 0x7) |
7060                      ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
7061           AdvanceIT();
7062           return;
7063         }
7064       }
7065     }
7066     Shift shift = operand.GetShift();
7067     uint32_t amount = operand.GetShiftAmount();
7068     if (IsUsingT32()) {
7069       // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
7070       if (InITBlock() && !size.IsWide() && rd.IsLow() &&
7071           shift.IsValidAmount(amount) && rm.IsLow() &&
7072           (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR)) &&
7073           ((!shift.Is(LSL) || (amount != 0)) || AllowUnpredictable())) {
7074         uint32_t amount_ = amount % 32;
7075         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
7076                    (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
7077         AdvanceIT();
7078         return;
7079       }
7080       // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
7081       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
7082           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7083         uint32_t amount_ = amount % 32;
7084         EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
7085                    (operand.GetTypeEncodingValue() << 4) |
7086                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7087         AdvanceIT();
7088         return;
7089       }
7090     } else {
7091       // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
7092       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7093         uint32_t amount_ = amount % 32;
7094         EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
7095                 (rd.GetCode() << 12) | rm.GetCode() |
7096                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7097         return;
7098       }
7099     }
7100   }
7101   if (operand.IsRegisterShiftedRegister()) {
7102     Register rm = operand.GetBaseRegister();
7103     Shift shift = operand.GetShift();
7104     Register rs = operand.GetShiftRegister();
7105     if (IsUsingT32()) {
7106       // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
7107       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7108           shift.IsASR() && rs.IsLow()) {
7109         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
7110         AdvanceIT();
7111         return;
7112       }
7113       // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
7114       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7115           shift.IsLSL() && rs.IsLow()) {
7116         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
7117         AdvanceIT();
7118         return;
7119       }
7120       // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
7121       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7122           shift.IsLSR() && rs.IsLow()) {
7123         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
7124         AdvanceIT();
7125         return;
7126       }
7127       // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
7128       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7129           shift.IsROR() && rs.IsLow()) {
7130         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
7131         AdvanceIT();
7132         return;
7133       }
7134       // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
7135       if (!size.IsNarrow() &&
7136           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7137         EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
7138                    (shift.GetType() << 21) | rs.GetCode());
7139         AdvanceIT();
7140         return;
7141       }
7142     } else {
7143       // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
7144       if (cond.IsNotNever() &&
7145           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7146         EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
7147                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
7148                 (rs.GetCode() << 8));
7149         return;
7150       }
7151     }
7152   }
7153   if (operand.IsImmediate()) {
7154     uint32_t imm = operand.GetImmediate();
7155     if (IsUsingT32()) {
7156       ImmediateT32 immediate_t32(imm);
7157       // MOV<c>{<q>} <Rd>, #<imm8> ; T1
7158       if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
7159         EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
7160         AdvanceIT();
7161         return;
7162       }
7163       // MOV{<c>}{<q>} <Rd>, #<const> ; T2
7164       if (!size.IsNarrow() && immediate_t32.IsValid() &&
7165           (!rd.IsPC() || AllowUnpredictable())) {
7166         EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) |
7167                    (immediate_t32.GetEncodingValue() & 0xff) |
7168                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7169                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7170         AdvanceIT();
7171         return;
7172       }
7173       // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3
7174       if (!size.IsNarrow() && (imm <= 65535) &&
7175           (!rd.IsPC() || AllowUnpredictable())) {
7176         EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
7177                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
7178                    ((imm & 0xf000) << 4));
7179         AdvanceIT();
7180         return;
7181       }
7182     } else {
7183       ImmediateA32 immediate_a32(imm);
7184       // MOV{<c>}{<q>} <Rd>, #<const> ; A1
7185       if (immediate_a32.IsValid() && cond.IsNotNever()) {
7186         EmitA32(0x03a00000U | (cond.GetCondition() << 28) |
7187                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
7188         return;
7189       }
7190       // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2
7191       if ((imm <= 65535) && cond.IsNotNever() &&
7192           (!rd.IsPC() || AllowUnpredictable())) {
7193         EmitA32(0x03000000U | (cond.GetCondition() << 28) |
7194                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
7195         return;
7196       }
7197     }
7198   }
7199   Delegate(kMov, &Assembler::mov, cond, size, rd, operand);
7200 }
7201 
movs(Condition cond,EncodingSize size,Register rd,const Operand & operand)7202 void Assembler::movs(Condition cond,
7203                      EncodingSize size,
7204                      Register rd,
7205                      const Operand& operand) {
7206   VIXL_ASSERT(AllowAssembler());
7207   CheckIT(cond);
7208   if (operand.IsImmediateShiftedRegister()) {
7209     Register rm = operand.GetBaseRegister();
7210     Shift shift = operand.GetShift();
7211     uint32_t amount = operand.GetShiftAmount();
7212     if (IsUsingT32()) {
7213       // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
7214       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() &&
7215           shift.IsValidAmount(amount) && rm.IsLow() &&
7216           (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) {
7217         uint32_t amount_ = amount % 32;
7218         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
7219                    (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
7220         AdvanceIT();
7221         return;
7222       }
7223       // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
7224       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
7225           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7226         uint32_t amount_ = amount % 32;
7227         EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
7228                    (operand.GetTypeEncodingValue() << 4) |
7229                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7230         AdvanceIT();
7231         return;
7232       }
7233     } else {
7234       // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
7235       if (shift.IsValidAmount(amount) && cond.IsNotNever() &&
7236           (!rd.IsPC() || AllowUnpredictable())) {
7237         uint32_t amount_ = amount % 32;
7238         EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
7239                 (rd.GetCode() << 12) | rm.GetCode() |
7240                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7241         return;
7242       }
7243     }
7244   }
7245   if (operand.IsRegisterShiftedRegister()) {
7246     Register rm = operand.GetBaseRegister();
7247     Shift shift = operand.GetShift();
7248     Register rs = operand.GetShiftRegister();
7249     if (IsUsingT32()) {
7250       // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
7251       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7252           shift.IsASR() && rs.IsLow()) {
7253         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
7254         AdvanceIT();
7255         return;
7256       }
7257       // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
7258       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7259           shift.IsLSL() && rs.IsLow()) {
7260         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
7261         AdvanceIT();
7262         return;
7263       }
7264       // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
7265       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7266           shift.IsLSR() && rs.IsLow()) {
7267         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
7268         AdvanceIT();
7269         return;
7270       }
7271       // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
7272       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7273           shift.IsROR() && rs.IsLow()) {
7274         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
7275         AdvanceIT();
7276         return;
7277       }
7278       // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
7279       if (!size.IsNarrow() &&
7280           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7281         EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
7282                    (shift.GetType() << 21) | rs.GetCode());
7283         AdvanceIT();
7284         return;
7285       }
7286     } else {
7287       // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
7288       if (cond.IsNotNever() &&
7289           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7290         EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
7291                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
7292                 (rs.GetCode() << 8));
7293         return;
7294       }
7295     }
7296   }
7297   if (operand.IsImmediate()) {
7298     uint32_t imm = operand.GetImmediate();
7299     if (IsUsingT32()) {
7300       ImmediateT32 immediate_t32(imm);
7301       // MOVS{<q>} <Rd>, #<imm8> ; T1
7302       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
7303         EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
7304         AdvanceIT();
7305         return;
7306       }
7307       // MOVS{<c>}{<q>} <Rd>, #<const> ; T2
7308       if (!size.IsNarrow() && immediate_t32.IsValid() &&
7309           (!rd.IsPC() || AllowUnpredictable())) {
7310         EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) |
7311                    (immediate_t32.GetEncodingValue() & 0xff) |
7312                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7313                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7314         AdvanceIT();
7315         return;
7316       }
7317     } else {
7318       ImmediateA32 immediate_a32(imm);
7319       // MOVS{<c>}{<q>} <Rd>, #<const> ; A1
7320       if (immediate_a32.IsValid() && cond.IsNotNever()) {
7321         EmitA32(0x03b00000U | (cond.GetCondition() << 28) |
7322                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
7323         return;
7324       }
7325     }
7326   }
7327   Delegate(kMovs, &Assembler::movs, cond, size, rd, operand);
7328 }
7329 
movt(Condition cond,Register rd,const Operand & operand)7330 void Assembler::movt(Condition cond, Register rd, const Operand& operand) {
7331   VIXL_ASSERT(AllowAssembler());
7332   CheckIT(cond);
7333   if (operand.IsImmediate()) {
7334     uint32_t imm = operand.GetImmediate();
7335     if (IsUsingT32()) {
7336       // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1
7337       if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
7338         EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) |
7339                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
7340                    ((imm & 0xf000) << 4));
7341         AdvanceIT();
7342         return;
7343       }
7344     } else {
7345       // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1
7346       if ((imm <= 65535) && cond.IsNotNever() &&
7347           (!rd.IsPC() || AllowUnpredictable())) {
7348         EmitA32(0x03400000U | (cond.GetCondition() << 28) |
7349                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
7350         return;
7351       }
7352     }
7353   }
7354   Delegate(kMovt, &Assembler::movt, cond, rd, operand);
7355 }
7356 
movw(Condition cond,Register rd,const Operand & operand)7357 void Assembler::movw(Condition cond, Register rd, const Operand& operand) {
7358   VIXL_ASSERT(AllowAssembler());
7359   CheckIT(cond);
7360   if (operand.IsImmediate()) {
7361     uint32_t imm = operand.GetImmediate();
7362     if (IsUsingT32()) {
7363       // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3
7364       if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
7365         EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
7366                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
7367                    ((imm & 0xf000) << 4));
7368         AdvanceIT();
7369         return;
7370       }
7371     } else {
7372       // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2
7373       if ((imm <= 65535) && cond.IsNotNever() &&
7374           (!rd.IsPC() || AllowUnpredictable())) {
7375         EmitA32(0x03000000U | (cond.GetCondition() << 28) |
7376                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
7377         return;
7378       }
7379     }
7380   }
7381   Delegate(kMovw, &Assembler::movw, cond, rd, operand);
7382 }
7383 
mrs(Condition cond,Register rd,SpecialRegister spec_reg)7384 void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) {
7385   VIXL_ASSERT(AllowAssembler());
7386   CheckIT(cond);
7387   if (IsUsingT32()) {
7388     // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1
7389     if ((!rd.IsPC() || AllowUnpredictable())) {
7390       EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20));
7391       AdvanceIT();
7392       return;
7393     }
7394   } else {
7395     // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1
7396     if (cond.IsNotNever() && (!rd.IsPC() || AllowUnpredictable())) {
7397       EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7398               (spec_reg.GetReg() << 22));
7399       return;
7400     }
7401   }
7402   Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg);
7403 }
7404 
msr(Condition cond,MaskedSpecialRegister spec_reg,const Operand & operand)7405 void Assembler::msr(Condition cond,
7406                     MaskedSpecialRegister spec_reg,
7407                     const Operand& operand) {
7408   VIXL_ASSERT(AllowAssembler());
7409   CheckIT(cond);
7410   if (operand.IsImmediate()) {
7411     uint32_t imm = operand.GetImmediate();
7412     if (IsUsingA32()) {
7413       ImmediateA32 immediate_a32(imm);
7414       // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1
7415       if (immediate_a32.IsValid() && cond.IsNotNever()) {
7416         EmitA32(0x0320f000U | (cond.GetCondition() << 28) |
7417                 ((spec_reg.GetReg() & 0xf) << 16) |
7418                 ((spec_reg.GetReg() & 0x10) << 18) |
7419                 immediate_a32.GetEncodingValue());
7420         return;
7421       }
7422     }
7423   }
7424   if (operand.IsPlainRegister()) {
7425     Register rn = operand.GetBaseRegister();
7426     if (IsUsingT32()) {
7427       // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1
7428       if ((!rn.IsPC() || AllowUnpredictable())) {
7429         EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) |
7430                    ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16));
7431         AdvanceIT();
7432         return;
7433       }
7434     } else {
7435       // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1
7436       if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
7437         EmitA32(0x0120f000U | (cond.GetCondition() << 28) |
7438                 ((spec_reg.GetReg() & 0xf) << 16) |
7439                 ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode());
7440         return;
7441       }
7442     }
7443   }
7444   Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand);
7445 }
7446 
mul(Condition cond,EncodingSize size,Register rd,Register rn,Register rm)7447 void Assembler::mul(
7448     Condition cond, EncodingSize size, Register rd, Register rn, Register rm) {
7449   VIXL_ASSERT(AllowAssembler());
7450   CheckIT(cond);
7451   if (IsUsingT32()) {
7452     // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
7453     if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() &&
7454         rm.IsLow()) {
7455       EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
7456       AdvanceIT();
7457       return;
7458     }
7459     // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2
7460     if (!size.IsNarrow() &&
7461         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7462       EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7463                  rm.GetCode());
7464       AdvanceIT();
7465       return;
7466     }
7467   } else {
7468     // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
7469     if (cond.IsNotNever() &&
7470         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7471       EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
7472               rn.GetCode() | (rm.GetCode() << 8));
7473       return;
7474     }
7475   }
7476   Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm);
7477 }
7478 
muls(Condition cond,Register rd,Register rn,Register rm)7479 void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) {
7480   VIXL_ASSERT(AllowAssembler());
7481   CheckIT(cond);
7482   if (IsUsingT32()) {
7483     // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
7484     if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) {
7485       EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
7486       AdvanceIT();
7487       return;
7488     }
7489   } else {
7490     // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
7491     if (cond.IsNotNever() &&
7492         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7493       EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
7494               rn.GetCode() | (rm.GetCode() << 8));
7495       return;
7496     }
7497   }
7498   Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm);
7499 }
7500 
mvn(Condition cond,EncodingSize size,Register rd,const Operand & operand)7501 void Assembler::mvn(Condition cond,
7502                     EncodingSize size,
7503                     Register rd,
7504                     const Operand& operand) {
7505   VIXL_ASSERT(AllowAssembler());
7506   CheckIT(cond);
7507   if (operand.IsImmediate()) {
7508     uint32_t imm = operand.GetImmediate();
7509     if (IsUsingT32()) {
7510       ImmediateT32 immediate_t32(imm);
7511       // MVN{<c>}{<q>} <Rd>, #<const> ; T1
7512       if (!size.IsNarrow() && immediate_t32.IsValid() &&
7513           (!rd.IsPC() || AllowUnpredictable())) {
7514         EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) |
7515                    (immediate_t32.GetEncodingValue() & 0xff) |
7516                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7517                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7518         AdvanceIT();
7519         return;
7520       }
7521     } else {
7522       ImmediateA32 immediate_a32(imm);
7523       // MVN{<c>}{<q>} <Rd>, #<const> ; A1
7524       if (immediate_a32.IsValid() && cond.IsNotNever()) {
7525         EmitA32(0x03e00000U | (cond.GetCondition() << 28) |
7526                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
7527         return;
7528       }
7529     }
7530   }
7531   if (operand.IsImmediateShiftedRegister()) {
7532     Register rm = operand.GetBaseRegister();
7533     if (operand.IsPlainRegister()) {
7534       if (IsUsingT32()) {
7535         // MVN<c>{<q>} <Rd>, <Rm> ; T1
7536         if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
7537           EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
7538           AdvanceIT();
7539           return;
7540         }
7541       }
7542     }
7543     Shift shift = operand.GetShift();
7544     uint32_t amount = operand.GetShiftAmount();
7545     if (IsUsingT32()) {
7546       // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
7547       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
7548           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7549         uint32_t amount_ = amount % 32;
7550         EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() |
7551                    (operand.GetTypeEncodingValue() << 4) |
7552                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7553         AdvanceIT();
7554         return;
7555       }
7556     } else {
7557       // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
7558       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7559         uint32_t amount_ = amount % 32;
7560         EmitA32(0x01e00000U | (cond.GetCondition() << 28) |
7561                 (rd.GetCode() << 12) | rm.GetCode() |
7562                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7563         return;
7564       }
7565     }
7566   }
7567   if (operand.IsRegisterShiftedRegister()) {
7568     Register rm = operand.GetBaseRegister();
7569     Shift shift = operand.GetShift();
7570     Register rs = operand.GetShiftRegister();
7571     if (IsUsingA32()) {
7572       // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
7573       if (cond.IsNotNever() &&
7574           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7575         EmitA32(0x01e00010U | (cond.GetCondition() << 28) |
7576                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
7577                 (rs.GetCode() << 8));
7578         return;
7579       }
7580     }
7581   }
7582   Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand);
7583 }
7584 
mvns(Condition cond,EncodingSize size,Register rd,const Operand & operand)7585 void Assembler::mvns(Condition cond,
7586                      EncodingSize size,
7587                      Register rd,
7588                      const Operand& operand) {
7589   VIXL_ASSERT(AllowAssembler());
7590   CheckIT(cond);
7591   if (operand.IsImmediate()) {
7592     uint32_t imm = operand.GetImmediate();
7593     if (IsUsingT32()) {
7594       ImmediateT32 immediate_t32(imm);
7595       // MVNS{<c>}{<q>} <Rd>, #<const> ; T1
7596       if (!size.IsNarrow() && immediate_t32.IsValid() &&
7597           (!rd.IsPC() || AllowUnpredictable())) {
7598         EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) |
7599                    (immediate_t32.GetEncodingValue() & 0xff) |
7600                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7601                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7602         AdvanceIT();
7603         return;
7604       }
7605     } else {
7606       ImmediateA32 immediate_a32(imm);
7607       // MVNS{<c>}{<q>} <Rd>, #<const> ; A1
7608       if (immediate_a32.IsValid() && cond.IsNotNever()) {
7609         EmitA32(0x03f00000U | (cond.GetCondition() << 28) |
7610                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
7611         return;
7612       }
7613     }
7614   }
7615   if (operand.IsImmediateShiftedRegister()) {
7616     Register rm = operand.GetBaseRegister();
7617     if (operand.IsPlainRegister()) {
7618       if (IsUsingT32()) {
7619         // MVNS{<q>} <Rd>, <Rm> ; T1
7620         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
7621           EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
7622           AdvanceIT();
7623           return;
7624         }
7625       }
7626     }
7627     Shift shift = operand.GetShift();
7628     uint32_t amount = operand.GetShiftAmount();
7629     if (IsUsingT32()) {
7630       // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
7631       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
7632           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7633         uint32_t amount_ = amount % 32;
7634         EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() |
7635                    (operand.GetTypeEncodingValue() << 4) |
7636                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7637         AdvanceIT();
7638         return;
7639       }
7640     } else {
7641       // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
7642       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7643         uint32_t amount_ = amount % 32;
7644         EmitA32(0x01f00000U | (cond.GetCondition() << 28) |
7645                 (rd.GetCode() << 12) | rm.GetCode() |
7646                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7647         return;
7648       }
7649     }
7650   }
7651   if (operand.IsRegisterShiftedRegister()) {
7652     Register rm = operand.GetBaseRegister();
7653     Shift shift = operand.GetShift();
7654     Register rs = operand.GetShiftRegister();
7655     if (IsUsingA32()) {
7656       // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
7657       if (cond.IsNotNever() &&
7658           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7659         EmitA32(0x01f00010U | (cond.GetCondition() << 28) |
7660                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
7661                 (rs.GetCode() << 8));
7662         return;
7663       }
7664     }
7665   }
7666   Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand);
7667 }
7668 
nop(Condition cond,EncodingSize size)7669 void Assembler::nop(Condition cond, EncodingSize size) {
7670   VIXL_ASSERT(AllowAssembler());
7671   CheckIT(cond);
7672   if (IsUsingT32()) {
7673     // NOP{<c>}{<q>} ; T1
7674     if (!size.IsWide()) {
7675       EmitT32_16(0xbf00);
7676       AdvanceIT();
7677       return;
7678     }
7679     // NOP{<c>}.W ; T2
7680     if (!size.IsNarrow()) {
7681       EmitT32_32(0xf3af8000U);
7682       AdvanceIT();
7683       return;
7684     }
7685   } else {
7686     // NOP{<c>}{<q>} ; A1
7687     if (cond.IsNotNever()) {
7688       EmitA32(0x0320f000U | (cond.GetCondition() << 28));
7689       return;
7690     }
7691   }
7692   Delegate(kNop, &Assembler::nop, cond, size);
7693 }
7694 
orn(Condition cond,Register rd,Register rn,const Operand & operand)7695 void Assembler::orn(Condition cond,
7696                     Register rd,
7697                     Register rn,
7698                     const Operand& operand) {
7699   VIXL_ASSERT(AllowAssembler());
7700   CheckIT(cond);
7701   if (operand.IsImmediate()) {
7702     uint32_t imm = operand.GetImmediate();
7703     if (IsUsingT32()) {
7704       ImmediateT32 immediate_t32(imm);
7705       // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7706       if (immediate_t32.IsValid() && !rn.Is(pc) &&
7707           (!rd.IsPC() || AllowUnpredictable())) {
7708         EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7709                    (immediate_t32.GetEncodingValue() & 0xff) |
7710                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7711                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7712         AdvanceIT();
7713         return;
7714       }
7715     }
7716   }
7717   if (operand.IsImmediateShiftedRegister()) {
7718     Register rm = operand.GetBaseRegister();
7719     Shift shift = operand.GetShift();
7720     uint32_t amount = operand.GetShiftAmount();
7721     if (IsUsingT32()) {
7722       // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
7723       if (shift.IsValidAmount(amount) && !rn.Is(pc) &&
7724           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7725         uint32_t amount_ = amount % 32;
7726         EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7727                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7728                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7729         AdvanceIT();
7730         return;
7731       }
7732     }
7733   }
7734   Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand);
7735 }
7736 
orns(Condition cond,Register rd,Register rn,const Operand & operand)7737 void Assembler::orns(Condition cond,
7738                      Register rd,
7739                      Register rn,
7740                      const Operand& operand) {
7741   VIXL_ASSERT(AllowAssembler());
7742   CheckIT(cond);
7743   if (operand.IsImmediate()) {
7744     uint32_t imm = operand.GetImmediate();
7745     if (IsUsingT32()) {
7746       ImmediateT32 immediate_t32(imm);
7747       // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7748       if (immediate_t32.IsValid() && !rn.Is(pc) &&
7749           (!rd.IsPC() || AllowUnpredictable())) {
7750         EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7751                    (immediate_t32.GetEncodingValue() & 0xff) |
7752                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7753                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7754         AdvanceIT();
7755         return;
7756       }
7757     }
7758   }
7759   if (operand.IsImmediateShiftedRegister()) {
7760     Register rm = operand.GetBaseRegister();
7761     Shift shift = operand.GetShift();
7762     uint32_t amount = operand.GetShiftAmount();
7763     if (IsUsingT32()) {
7764       // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
7765       if (shift.IsValidAmount(amount) && !rn.Is(pc) &&
7766           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7767         uint32_t amount_ = amount % 32;
7768         EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7769                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7770                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7771         AdvanceIT();
7772         return;
7773       }
7774     }
7775   }
7776   Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand);
7777 }
7778 
orr(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)7779 void Assembler::orr(Condition cond,
7780                     EncodingSize size,
7781                     Register rd,
7782                     Register rn,
7783                     const Operand& operand) {
7784   VIXL_ASSERT(AllowAssembler());
7785   CheckIT(cond);
7786   if (operand.IsImmediate()) {
7787     uint32_t imm = operand.GetImmediate();
7788     if (IsUsingT32()) {
7789       ImmediateT32 immediate_t32(imm);
7790       // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7791       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) &&
7792           (!rd.IsPC() || AllowUnpredictable())) {
7793         EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7794                    (immediate_t32.GetEncodingValue() & 0xff) |
7795                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7796                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7797         AdvanceIT();
7798         return;
7799       }
7800     } else {
7801       ImmediateA32 immediate_a32(imm);
7802       // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7803       if (immediate_a32.IsValid() && cond.IsNotNever()) {
7804         EmitA32(0x03800000U | (cond.GetCondition() << 28) |
7805                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7806                 immediate_a32.GetEncodingValue());
7807         return;
7808       }
7809     }
7810   }
7811   if (operand.IsImmediateShiftedRegister()) {
7812     Register rm = operand.GetBaseRegister();
7813     if (operand.IsPlainRegister()) {
7814       if (IsUsingT32()) {
7815         // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7816         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7817             rm.IsLow()) {
7818           EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7819           AdvanceIT();
7820           return;
7821         }
7822       }
7823     }
7824     Shift shift = operand.GetShift();
7825     uint32_t amount = operand.GetShiftAmount();
7826     if (IsUsingT32()) {
7827       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7828       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) &&
7829           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7830         uint32_t amount_ = amount % 32;
7831         EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7832                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7833                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7834         AdvanceIT();
7835         return;
7836       }
7837     } else {
7838       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7839       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7840         uint32_t amount_ = amount % 32;
7841         EmitA32(0x01800000U | (cond.GetCondition() << 28) |
7842                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7843                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7844         return;
7845       }
7846     }
7847   }
7848   if (operand.IsRegisterShiftedRegister()) {
7849     Register rm = operand.GetBaseRegister();
7850     Shift shift = operand.GetShift();
7851     Register rs = operand.GetShiftRegister();
7852     if (IsUsingA32()) {
7853       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7854       if (cond.IsNotNever() &&
7855           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
7856            AllowUnpredictable())) {
7857         EmitA32(0x01800010U | (cond.GetCondition() << 28) |
7858                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7859                 (shift.GetType() << 5) | (rs.GetCode() << 8));
7860         return;
7861       }
7862     }
7863   }
7864   Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand);
7865 }
7866 
orrs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)7867 void Assembler::orrs(Condition cond,
7868                      EncodingSize size,
7869                      Register rd,
7870                      Register rn,
7871                      const Operand& operand) {
7872   VIXL_ASSERT(AllowAssembler());
7873   CheckIT(cond);
7874   if (operand.IsImmediate()) {
7875     uint32_t imm = operand.GetImmediate();
7876     if (IsUsingT32()) {
7877       ImmediateT32 immediate_t32(imm);
7878       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7879       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) &&
7880           (!rd.IsPC() || AllowUnpredictable())) {
7881         EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7882                    (immediate_t32.GetEncodingValue() & 0xff) |
7883                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7884                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7885         AdvanceIT();
7886         return;
7887       }
7888     } else {
7889       ImmediateA32 immediate_a32(imm);
7890       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7891       if (immediate_a32.IsValid() && cond.IsNotNever()) {
7892         EmitA32(0x03900000U | (cond.GetCondition() << 28) |
7893                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7894                 immediate_a32.GetEncodingValue());
7895         return;
7896       }
7897     }
7898   }
7899   if (operand.IsImmediateShiftedRegister()) {
7900     Register rm = operand.GetBaseRegister();
7901     if (operand.IsPlainRegister()) {
7902       if (IsUsingT32()) {
7903         // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7904         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7905             rm.IsLow()) {
7906           EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7907           AdvanceIT();
7908           return;
7909         }
7910       }
7911     }
7912     Shift shift = operand.GetShift();
7913     uint32_t amount = operand.GetShiftAmount();
7914     if (IsUsingT32()) {
7915       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7916       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) &&
7917           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7918         uint32_t amount_ = amount % 32;
7919         EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7920                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7921                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7922         AdvanceIT();
7923         return;
7924       }
7925     } else {
7926       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7927       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7928         uint32_t amount_ = amount % 32;
7929         EmitA32(0x01900000U | (cond.GetCondition() << 28) |
7930                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7931                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7932         return;
7933       }
7934     }
7935   }
7936   if (operand.IsRegisterShiftedRegister()) {
7937     Register rm = operand.GetBaseRegister();
7938     Shift shift = operand.GetShift();
7939     Register rs = operand.GetShiftRegister();
7940     if (IsUsingA32()) {
7941       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7942       if (cond.IsNotNever() &&
7943           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
7944            AllowUnpredictable())) {
7945         EmitA32(0x01900010U | (cond.GetCondition() << 28) |
7946                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7947                 (shift.GetType() << 5) | (rs.GetCode() << 8));
7948         return;
7949       }
7950     }
7951   }
7952   Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand);
7953 }
7954 
pkhbt(Condition cond,Register rd,Register rn,const Operand & operand)7955 void Assembler::pkhbt(Condition cond,
7956                       Register rd,
7957                       Register rn,
7958                       const Operand& operand) {
7959   VIXL_ASSERT(AllowAssembler());
7960   CheckIT(cond);
7961   if (operand.IsImmediateShiftedRegister()) {
7962     Register rm = operand.GetBaseRegister();
7963     Shift shift = operand.GetShift();
7964     uint32_t amount = operand.GetShiftAmount();
7965     if (IsUsingT32()) {
7966       // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1
7967       if (shift.IsLSL() && shift.IsValidAmount(amount) &&
7968           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7969         EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7970                    rm.GetCode() | ((amount & 0x3) << 6) |
7971                    ((amount & 0x1c) << 10));
7972         AdvanceIT();
7973         return;
7974       }
7975     } else {
7976       // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1
7977       if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever() &&
7978           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7979         EmitA32(0x06800010U | (cond.GetCondition() << 28) |
7980                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7981                 (amount << 7));
7982         return;
7983       }
7984     }
7985   }
7986   Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand);
7987 }
7988 
pkhtb(Condition cond,Register rd,Register rn,const Operand & operand)7989 void Assembler::pkhtb(Condition cond,
7990                       Register rd,
7991                       Register rn,
7992                       const Operand& operand) {
7993   VIXL_ASSERT(AllowAssembler());
7994   CheckIT(cond);
7995   if (operand.IsImmediateShiftedRegister()) {
7996     Register rm = operand.GetBaseRegister();
7997     Shift shift = operand.GetShift();
7998     uint32_t amount = operand.GetShiftAmount();
7999     if (IsUsingT32()) {
8000       // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1
8001       if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
8002           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8003         uint32_t amount_ = amount % 32;
8004         EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8005                    rm.GetCode() | ((amount_ & 0x3) << 6) |
8006                    ((amount_ & 0x1c) << 10));
8007         AdvanceIT();
8008         return;
8009       }
8010     } else {
8011       // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1
8012       if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
8013           cond.IsNotNever() &&
8014           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8015         uint32_t amount_ = amount % 32;
8016         EmitA32(0x06800050U | (cond.GetCondition() << 28) |
8017                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8018                 (amount_ << 7));
8019         return;
8020       }
8021     }
8022   }
8023   Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand);
8024 }
8025 
pld(Condition cond,Location * location)8026 void Assembler::pld(Condition cond, Location* location) {
8027   VIXL_ASSERT(AllowAssembler());
8028   CheckIT(cond);
8029   Location::Offset offset =
8030       location->IsBound()
8031           ? location->GetLocation() -
8032                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
8033           : 0;
8034   if (IsUsingT32()) {
8035     // PLD{<c>}{<q>} <label> ; T1
8036     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
8037          !location->IsBound())) {
8038       static class EmitOp : public Location::EmitOperator {
8039        public:
8040         EmitOp() : Location::EmitOperator(T32) {}
8041         virtual uint32_t Encode(uint32_t instr,
8042                                 Location::Offset pc,
8043                                 const Location* location) const VIXL_OVERRIDE {
8044           pc += kT32PcDelta;
8045           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
8046           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
8047           uint32_t U = (offset >= 0);
8048           int32_t target = abs(offset) | (U << 12);
8049           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
8050         }
8051       } immop;
8052       EmitT32_32(Link(0xf81ff000U, location, immop, &kT32FarDataInfo));
8053       AdvanceIT();
8054       return;
8055     }
8056   } else {
8057     // PLD{<c>}{<q>} <label> ; A1
8058     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
8059          !location->IsBound())) {
8060       if (cond.Is(al)) {
8061         static class EmitOp : public Location::EmitOperator {
8062          public:
8063           EmitOp() : Location::EmitOperator(A32) {}
8064           virtual uint32_t Encode(uint32_t instr,
8065                                   Location::Offset pc,
8066                                   const Location* location) const
8067               VIXL_OVERRIDE {
8068             pc += kA32PcDelta;
8069             Location::Offset offset =
8070                 location->GetLocation() - AlignDown(pc, 4);
8071             VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
8072             uint32_t U = (offset >= 0);
8073             int32_t target = abs(offset) | (U << 12);
8074             return instr | (target & 0xfff) | ((target & 0x1000) << 11);
8075           }
8076         } immop;
8077         EmitA32(Link(0xf55ff000U, location, immop, &kA32FarDataInfo));
8078         return;
8079       }
8080     }
8081   }
8082   Delegate(kPld, &Assembler::pld, cond, location);
8083 }
8084 
pld_info(Condition cond,Location * location,const struct ReferenceInfo ** info)8085 bool Assembler::pld_info(Condition cond,
8086                          Location* location,
8087                          const struct ReferenceInfo** info) {
8088   VIXL_ASSERT(!location->IsBound());
8089   USE(location);
8090   USE(cond);
8091   if (IsUsingT32()) {
8092     // PLD{<c>}{<q>} <label> ; T1
8093     if (true) {
8094       *info = &kT32FarDataInfo;
8095       return true;
8096     }
8097   } else {
8098     // PLD{<c>}{<q>} <label> ; A1
8099     if (true) {
8100       *info = &kA32FarDataInfo;
8101       return true;
8102     }
8103   }
8104   return false;
8105 }
8106 
pld(Condition cond,const MemOperand & operand)8107 void Assembler::pld(Condition cond, const MemOperand& operand) {
8108   VIXL_ASSERT(AllowAssembler());
8109   CheckIT(cond);
8110   if (operand.IsImmediate()) {
8111     Register rn = operand.GetBaseRegister();
8112     int32_t offset = operand.GetOffsetImmediate();
8113     if (IsUsingT32()) {
8114       // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1
8115       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
8116           operand.IsOffset()) {
8117         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8118         uint32_t offset_ = abs(offset);
8119         EmitT32_32(0xf81ff000U | offset_ | (sign << 23));
8120         AdvanceIT();
8121         return;
8122       }
8123     } else {
8124       // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1
8125       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
8126           operand.IsOffset()) {
8127         if (cond.Is(al)) {
8128           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8129           uint32_t offset_ = abs(offset);
8130           EmitA32(0xf55ff000U | offset_ | (sign << 23));
8131           return;
8132         }
8133       }
8134     }
8135   }
8136   if (operand.IsImmediate()) {
8137     Register rn = operand.GetBaseRegister();
8138     int32_t offset = operand.GetOffsetImmediate();
8139     if (IsUsingT32()) {
8140       // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
8141       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
8142           ((rn.GetCode() & 0xf) != 0xf)) {
8143         EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff));
8144         AdvanceIT();
8145         return;
8146       }
8147       // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
8148       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
8149           ((rn.GetCode() & 0xf) != 0xf)) {
8150         EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
8151         AdvanceIT();
8152         return;
8153       }
8154     } else {
8155       // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
8156       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
8157           ((rn.GetCode() & 0xf) != 0xf)) {
8158         if (cond.Is(al)) {
8159           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8160           uint32_t offset_ = abs(offset);
8161           EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
8162           return;
8163         }
8164       }
8165     }
8166   }
8167   if (operand.IsShiftedRegister()) {
8168     Register rn = operand.GetBaseRegister();
8169     Sign sign = operand.GetSign();
8170     Register rm = operand.GetOffsetRegister();
8171     Shift shift = operand.GetShift();
8172     uint32_t amount = operand.GetShiftAmount();
8173     if (IsUsingT32()) {
8174       // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
8175       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
8176           ((rn.GetCode() & 0xf) != 0xf) &&
8177           (!rm.IsPC() || AllowUnpredictable())) {
8178         EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() |
8179                    (amount << 4));
8180         AdvanceIT();
8181         return;
8182       }
8183     } else {
8184       // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
8185       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
8186           (!rm.IsPC() || AllowUnpredictable())) {
8187         if (cond.Is(al)) {
8188           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8189           uint32_t amount_ = amount % 32;
8190           EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() |
8191                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
8192           return;
8193         }
8194       }
8195       // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
8196       if (shift.IsRRX() && operand.IsOffset() &&
8197           (!rm.IsPC() || AllowUnpredictable())) {
8198         if (cond.Is(al)) {
8199           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8200           EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() |
8201                   (sign_ << 23));
8202           return;
8203         }
8204       }
8205     }
8206   }
8207   Delegate(kPld, &Assembler::pld, cond, operand);
8208 }
8209 
pldw(Condition cond,const MemOperand & operand)8210 void Assembler::pldw(Condition cond, const MemOperand& operand) {
8211   VIXL_ASSERT(AllowAssembler());
8212   CheckIT(cond);
8213   if (operand.IsImmediate()) {
8214     Register rn = operand.GetBaseRegister();
8215     int32_t offset = operand.GetOffsetImmediate();
8216     if (IsUsingT32()) {
8217       // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
8218       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
8219           ((rn.GetCode() & 0xf) != 0xf)) {
8220         EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff));
8221         AdvanceIT();
8222         return;
8223       }
8224       // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
8225       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
8226           ((rn.GetCode() & 0xf) != 0xf)) {
8227         EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
8228         AdvanceIT();
8229         return;
8230       }
8231     } else {
8232       // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
8233       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
8234           ((rn.GetCode() & 0xf) != 0xf)) {
8235         if (cond.Is(al)) {
8236           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8237           uint32_t offset_ = abs(offset);
8238           EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
8239           return;
8240         }
8241       }
8242     }
8243   }
8244   if (operand.IsShiftedRegister()) {
8245     Register rn = operand.GetBaseRegister();
8246     Sign sign = operand.GetSign();
8247     Register rm = operand.GetOffsetRegister();
8248     Shift shift = operand.GetShift();
8249     uint32_t amount = operand.GetShiftAmount();
8250     if (IsUsingT32()) {
8251       // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
8252       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
8253           ((rn.GetCode() & 0xf) != 0xf) &&
8254           (!rm.IsPC() || AllowUnpredictable())) {
8255         EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() |
8256                    (amount << 4));
8257         AdvanceIT();
8258         return;
8259       }
8260     } else {
8261       // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
8262       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
8263           (!rm.IsPC() || AllowUnpredictable())) {
8264         if (cond.Is(al)) {
8265           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8266           uint32_t amount_ = amount % 32;
8267           EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() |
8268                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
8269           return;
8270         }
8271       }
8272       // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
8273       if (shift.IsRRX() && operand.IsOffset() &&
8274           (!rm.IsPC() || AllowUnpredictable())) {
8275         if (cond.Is(al)) {
8276           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8277           EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() |
8278                   (sign_ << 23));
8279           return;
8280         }
8281       }
8282     }
8283   }
8284   Delegate(kPldw, &Assembler::pldw, cond, operand);
8285 }
8286 
pli(Condition cond,const MemOperand & operand)8287 void Assembler::pli(Condition cond, const MemOperand& operand) {
8288   VIXL_ASSERT(AllowAssembler());
8289   CheckIT(cond);
8290   if (operand.IsImmediate()) {
8291     Register rn = operand.GetBaseRegister();
8292     int32_t offset = operand.GetOffsetImmediate();
8293     if (IsUsingT32()) {
8294       // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
8295       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
8296           ((rn.GetCode() & 0xf) != 0xf)) {
8297         EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff));
8298         AdvanceIT();
8299         return;
8300       }
8301       // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
8302       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
8303           ((rn.GetCode() & 0xf) != 0xf)) {
8304         EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
8305         AdvanceIT();
8306         return;
8307       }
8308     } else {
8309       // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1
8310       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
8311           ((rn.GetCode() & 0xf) != 0xf)) {
8312         if (cond.Is(al)) {
8313           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8314           uint32_t offset_ = abs(offset);
8315           EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
8316           return;
8317         }
8318       }
8319     }
8320   }
8321   if (operand.IsImmediate()) {
8322     Register rn = operand.GetBaseRegister();
8323     int32_t offset = operand.GetOffsetImmediate();
8324     if (IsUsingT32()) {
8325       // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3
8326       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
8327           operand.IsOffset()) {
8328         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8329         uint32_t offset_ = abs(offset);
8330         EmitT32_32(0xf91ff000U | offset_ | (sign << 23));
8331         AdvanceIT();
8332         return;
8333       }
8334     } else {
8335       // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1
8336       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
8337           operand.IsOffset()) {
8338         if (cond.Is(al)) {
8339           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8340           uint32_t offset_ = abs(offset);
8341           EmitA32(0xf45ff000U | offset_ | (sign << 23));
8342           return;
8343         }
8344       }
8345     }
8346   }
8347   if (operand.IsShiftedRegister()) {
8348     Register rn = operand.GetBaseRegister();
8349     Sign sign = operand.GetSign();
8350     Register rm = operand.GetOffsetRegister();
8351     Shift shift = operand.GetShift();
8352     uint32_t amount = operand.GetShiftAmount();
8353     if (IsUsingT32()) {
8354       // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
8355       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
8356           ((rn.GetCode() & 0xf) != 0xf) &&
8357           (!rm.IsPC() || AllowUnpredictable())) {
8358         EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() |
8359                    (amount << 4));
8360         AdvanceIT();
8361         return;
8362       }
8363     } else {
8364       // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
8365       if (shift.IsRRX() && operand.IsOffset() &&
8366           (!rm.IsPC() || AllowUnpredictable())) {
8367         if (cond.Is(al)) {
8368           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8369           EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() |
8370                   (sign_ << 23));
8371           return;
8372         }
8373       }
8374       // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
8375       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
8376           (!rm.IsPC() || AllowUnpredictable())) {
8377         if (cond.Is(al)) {
8378           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8379           uint32_t amount_ = amount % 32;
8380           EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() |
8381                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
8382           return;
8383         }
8384       }
8385     }
8386   }
8387   Delegate(kPli, &Assembler::pli, cond, operand);
8388 }
8389 
pli(Condition cond,Location * location)8390 void Assembler::pli(Condition cond, Location* location) {
8391   VIXL_ASSERT(AllowAssembler());
8392   CheckIT(cond);
8393   Location::Offset offset =
8394       location->IsBound()
8395           ? location->GetLocation() -
8396                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
8397           : 0;
8398   if (IsUsingT32()) {
8399     // PLI{<c>}{<q>} <label> ; T3
8400     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
8401          !location->IsBound())) {
8402       static class EmitOp : public Location::EmitOperator {
8403        public:
8404         EmitOp() : Location::EmitOperator(T32) {}
8405         virtual uint32_t Encode(uint32_t instr,
8406                                 Location::Offset pc,
8407                                 const Location* location) const VIXL_OVERRIDE {
8408           pc += kT32PcDelta;
8409           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
8410           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
8411           uint32_t U = (offset >= 0);
8412           int32_t target = abs(offset) | (U << 12);
8413           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
8414         }
8415       } immop;
8416       EmitT32_32(Link(0xf91ff000U, location, immop, &kT32FarDataInfo));
8417       AdvanceIT();
8418       return;
8419     }
8420   } else {
8421     // PLI{<c>}{<q>} <label> ; A1
8422     if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
8423          !location->IsBound())) {
8424       if (cond.Is(al)) {
8425         static class EmitOp : public Location::EmitOperator {
8426          public:
8427           EmitOp() : Location::EmitOperator(A32) {}
8428           virtual uint32_t Encode(uint32_t instr,
8429                                   Location::Offset pc,
8430                                   const Location* location) const
8431               VIXL_OVERRIDE {
8432             pc += kA32PcDelta;
8433             Location::Offset offset =
8434                 location->GetLocation() - AlignDown(pc, 4);
8435             VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
8436             uint32_t U = (offset >= 0);
8437             int32_t target = abs(offset) | (U << 12);
8438             return instr | (target & 0xfff) | ((target & 0x1000) << 11);
8439           }
8440         } immop;
8441         EmitA32(Link(0xf45ff000U, location, immop, &kA32FarDataInfo));
8442         return;
8443       }
8444     }
8445   }
8446   Delegate(kPli, &Assembler::pli, cond, location);
8447 }
8448 
pli_info(Condition cond,Location * location,const struct ReferenceInfo ** info)8449 bool Assembler::pli_info(Condition cond,
8450                          Location* location,
8451                          const struct ReferenceInfo** info) {
8452   VIXL_ASSERT(!location->IsBound());
8453   USE(location);
8454   USE(cond);
8455   if (IsUsingT32()) {
8456     // PLI{<c>}{<q>} <label> ; T3
8457     if (true) {
8458       *info = &kT32FarDataInfo;
8459       return true;
8460     }
8461   } else {
8462     // PLI{<c>}{<q>} <label> ; A1
8463     if (true) {
8464       *info = &kA32FarDataInfo;
8465       return true;
8466     }
8467   }
8468   return false;
8469 }
8470 
pop(Condition cond,EncodingSize size,RegisterList registers)8471 void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) {
8472   VIXL_ASSERT(AllowAssembler());
8473   CheckIT(cond);
8474   if (IsUsingT32()) {
8475     // POP{<c>}{<q>} <registers> ; T1
8476     if (!size.IsWide() && ((registers.GetList() & ~0x80ff) == 0)) {
8477       EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
8478                  GetRegisterListEncoding(registers, 0, 8));
8479       AdvanceIT();
8480       return;
8481     }
8482     // POP{<c>}{<q>} <registers> ; T2
8483     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
8484       EmitT32_32(0xe8bd0000U |
8485                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
8486                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
8487                  GetRegisterListEncoding(registers, 0, 13));
8488       AdvanceIT();
8489       return;
8490     }
8491   } else {
8492     // POP{<c>}{<q>} <registers> ; A1
8493     if (cond.IsNotNever()) {
8494       EmitA32(0x08bd0000U | (cond.GetCondition() << 28) |
8495               GetRegisterListEncoding(registers, 0, 16));
8496       return;
8497     }
8498   }
8499   Delegate(kPop, &Assembler::pop, cond, size, registers);
8500 }
8501 
pop(Condition cond,EncodingSize size,Register rt)8502 void Assembler::pop(Condition cond, EncodingSize size, Register rt) {
8503   VIXL_ASSERT(AllowAssembler());
8504   CheckIT(cond);
8505   if (IsUsingT32()) {
8506     // POP{<c>}{<q>} <single_register_list> ; T4
8507     if (!size.IsNarrow() && ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
8508                              AllowUnpredictable())) {
8509       EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12));
8510       AdvanceIT();
8511       return;
8512     }
8513   } else {
8514     // POP{<c>}{<q>} <single_register_list> ; A1
8515     if (cond.IsNotNever()) {
8516       EmitA32(0x049d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
8517       return;
8518     }
8519   }
8520   Delegate(kPop, &Assembler::pop, cond, size, rt);
8521 }
8522 
push(Condition cond,EncodingSize size,RegisterList registers)8523 void Assembler::push(Condition cond,
8524                      EncodingSize size,
8525                      RegisterList registers) {
8526   VIXL_ASSERT(AllowAssembler());
8527   CheckIT(cond);
8528   if (IsUsingT32()) {
8529     // PUSH{<c>}{<q>} <registers> ; T1
8530     if (!size.IsWide() && ((registers.GetList() & ~0x40ff) == 0)) {
8531       EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
8532                  GetRegisterListEncoding(registers, 0, 8));
8533       AdvanceIT();
8534       return;
8535     }
8536     // PUSH{<c>}{<q>} <registers> ; T1
8537     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
8538       EmitT32_32(0xe92d0000U |
8539                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
8540                  GetRegisterListEncoding(registers, 0, 13));
8541       AdvanceIT();
8542       return;
8543     }
8544   } else {
8545     // PUSH{<c>}{<q>} <registers> ; A1
8546     if (cond.IsNotNever()) {
8547       EmitA32(0x092d0000U | (cond.GetCondition() << 28) |
8548               GetRegisterListEncoding(registers, 0, 16));
8549       return;
8550     }
8551   }
8552   Delegate(kPush, &Assembler::push, cond, size, registers);
8553 }
8554 
push(Condition cond,EncodingSize size,Register rt)8555 void Assembler::push(Condition cond, EncodingSize size, Register rt) {
8556   VIXL_ASSERT(AllowAssembler());
8557   CheckIT(cond);
8558   if (IsUsingT32()) {
8559     // PUSH{<c>}{<q>} <single_register_list> ; T4
8560     if (!size.IsNarrow() && (!rt.IsPC() || AllowUnpredictable())) {
8561       EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12));
8562       AdvanceIT();
8563       return;
8564     }
8565   } else {
8566     // PUSH{<c>}{<q>} <single_register_list> ; A1
8567     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
8568       EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
8569       return;
8570     }
8571   }
8572   Delegate(kPush, &Assembler::push, cond, size, rt);
8573 }
8574 
qadd(Condition cond,Register rd,Register rm,Register rn)8575 void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) {
8576   VIXL_ASSERT(AllowAssembler());
8577   CheckIT(cond);
8578   if (IsUsingT32()) {
8579     // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
8580     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8581       EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() |
8582                  (rn.GetCode() << 16));
8583       AdvanceIT();
8584       return;
8585     }
8586   } else {
8587     // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
8588     if (cond.IsNotNever() &&
8589         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8590       EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8591               rm.GetCode() | (rn.GetCode() << 16));
8592       return;
8593     }
8594   }
8595   Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn);
8596 }
8597 
qadd16(Condition cond,Register rd,Register rn,Register rm)8598 void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) {
8599   VIXL_ASSERT(AllowAssembler());
8600   CheckIT(cond);
8601   if (IsUsingT32()) {
8602     // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8603     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8604       EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8605                  rm.GetCode());
8606       AdvanceIT();
8607       return;
8608     }
8609   } else {
8610     // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8611     if (cond.IsNotNever() &&
8612         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8613       EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8614               (rn.GetCode() << 16) | rm.GetCode());
8615       return;
8616     }
8617   }
8618   Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm);
8619 }
8620 
qadd8(Condition cond,Register rd,Register rn,Register rm)8621 void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) {
8622   VIXL_ASSERT(AllowAssembler());
8623   CheckIT(cond);
8624   if (IsUsingT32()) {
8625     // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8626     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8627       EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8628                  rm.GetCode());
8629       AdvanceIT();
8630       return;
8631     }
8632   } else {
8633     // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8634     if (cond.IsNotNever() &&
8635         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8636       EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8637               (rn.GetCode() << 16) | rm.GetCode());
8638       return;
8639     }
8640   }
8641   Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm);
8642 }
8643 
qasx(Condition cond,Register rd,Register rn,Register rm)8644 void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) {
8645   VIXL_ASSERT(AllowAssembler());
8646   CheckIT(cond);
8647   if (IsUsingT32()) {
8648     // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8649     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8650       EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8651                  rm.GetCode());
8652       AdvanceIT();
8653       return;
8654     }
8655   } else {
8656     // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8657     if (cond.IsNotNever() &&
8658         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8659       EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8660               (rn.GetCode() << 16) | rm.GetCode());
8661       return;
8662     }
8663   }
8664   Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm);
8665 }
8666 
qdadd(Condition cond,Register rd,Register rm,Register rn)8667 void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) {
8668   VIXL_ASSERT(AllowAssembler());
8669   CheckIT(cond);
8670   if (IsUsingT32()) {
8671     // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
8672     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8673       EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() |
8674                  (rn.GetCode() << 16));
8675       AdvanceIT();
8676       return;
8677     }
8678   } else {
8679     // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
8680     if (cond.IsNotNever() &&
8681         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8682       EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8683               rm.GetCode() | (rn.GetCode() << 16));
8684       return;
8685     }
8686   }
8687   Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn);
8688 }
8689 
qdsub(Condition cond,Register rd,Register rm,Register rn)8690 void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) {
8691   VIXL_ASSERT(AllowAssembler());
8692   CheckIT(cond);
8693   if (IsUsingT32()) {
8694     // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
8695     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8696       EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
8697                  (rn.GetCode() << 16));
8698       AdvanceIT();
8699       return;
8700     }
8701   } else {
8702     // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
8703     if (cond.IsNotNever() &&
8704         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8705       EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8706               rm.GetCode() | (rn.GetCode() << 16));
8707       return;
8708     }
8709   }
8710   Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn);
8711 }
8712 
qsax(Condition cond,Register rd,Register rn,Register rm)8713 void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) {
8714   VIXL_ASSERT(AllowAssembler());
8715   CheckIT(cond);
8716   if (IsUsingT32()) {
8717     // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8718     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8719       EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8720                  rm.GetCode());
8721       AdvanceIT();
8722       return;
8723     }
8724   } else {
8725     // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8726     if (cond.IsNotNever() &&
8727         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8728       EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8729               (rn.GetCode() << 16) | rm.GetCode());
8730       return;
8731     }
8732   }
8733   Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm);
8734 }
8735 
qsub(Condition cond,Register rd,Register rm,Register rn)8736 void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) {
8737   VIXL_ASSERT(AllowAssembler());
8738   CheckIT(cond);
8739   if (IsUsingT32()) {
8740     // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
8741     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8742       EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
8743                  (rn.GetCode() << 16));
8744       AdvanceIT();
8745       return;
8746     }
8747   } else {
8748     // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
8749     if (cond.IsNotNever() &&
8750         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8751       EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8752               rm.GetCode() | (rn.GetCode() << 16));
8753       return;
8754     }
8755   }
8756   Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn);
8757 }
8758 
qsub16(Condition cond,Register rd,Register rn,Register rm)8759 void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) {
8760   VIXL_ASSERT(AllowAssembler());
8761   CheckIT(cond);
8762   if (IsUsingT32()) {
8763     // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8764     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8765       EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8766                  rm.GetCode());
8767       AdvanceIT();
8768       return;
8769     }
8770   } else {
8771     // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8772     if (cond.IsNotNever() &&
8773         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8774       EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8775               (rn.GetCode() << 16) | rm.GetCode());
8776       return;
8777     }
8778   }
8779   Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm);
8780 }
8781 
qsub8(Condition cond,Register rd,Register rn,Register rm)8782 void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) {
8783   VIXL_ASSERT(AllowAssembler());
8784   CheckIT(cond);
8785   if (IsUsingT32()) {
8786     // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8787     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8788       EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8789                  rm.GetCode());
8790       AdvanceIT();
8791       return;
8792     }
8793   } else {
8794     // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8795     if (cond.IsNotNever() &&
8796         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8797       EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8798               (rn.GetCode() << 16) | rm.GetCode());
8799       return;
8800     }
8801   }
8802   Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm);
8803 }
8804 
rbit(Condition cond,Register rd,Register rm)8805 void Assembler::rbit(Condition cond, Register rd, Register rm) {
8806   VIXL_ASSERT(AllowAssembler());
8807   CheckIT(cond);
8808   if (IsUsingT32()) {
8809     // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1
8810     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8811       EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
8812                  (rm.GetCode() << 16));
8813       AdvanceIT();
8814       return;
8815     }
8816   } else {
8817     // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1
8818     if (cond.IsNotNever() &&
8819         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8820       EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8821               rm.GetCode());
8822       return;
8823     }
8824   }
8825   Delegate(kRbit, &Assembler::rbit, cond, rd, rm);
8826 }
8827 
rev(Condition cond,EncodingSize size,Register rd,Register rm)8828 void Assembler::rev(Condition cond,
8829                     EncodingSize size,
8830                     Register rd,
8831                     Register rm) {
8832   VIXL_ASSERT(AllowAssembler());
8833   CheckIT(cond);
8834   if (IsUsingT32()) {
8835     // REV{<c>}{<q>} <Rd>, <Rm> ; T1
8836     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8837       EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3));
8838       AdvanceIT();
8839       return;
8840     }
8841     // REV{<c>}{<q>} <Rd>, <Rm> ; T2
8842     if (!size.IsNarrow() &&
8843         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8844       EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() |
8845                  (rm.GetCode() << 16));
8846       AdvanceIT();
8847       return;
8848     }
8849   } else {
8850     // REV{<c>}{<q>} <Rd>, <Rm> ; A1
8851     if (cond.IsNotNever() &&
8852         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8853       EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8854               rm.GetCode());
8855       return;
8856     }
8857   }
8858   Delegate(kRev, &Assembler::rev, cond, size, rd, rm);
8859 }
8860 
rev16(Condition cond,EncodingSize size,Register rd,Register rm)8861 void Assembler::rev16(Condition cond,
8862                       EncodingSize size,
8863                       Register rd,
8864                       Register rm) {
8865   VIXL_ASSERT(AllowAssembler());
8866   CheckIT(cond);
8867   if (IsUsingT32()) {
8868     // REV16{<c>}{<q>} <Rd>, <Rm> ; T1
8869     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8870       EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3));
8871       AdvanceIT();
8872       return;
8873     }
8874     // REV16{<c>}{<q>} <Rd>, <Rm> ; T2
8875     if (!size.IsNarrow() &&
8876         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8877       EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() |
8878                  (rm.GetCode() << 16));
8879       AdvanceIT();
8880       return;
8881     }
8882   } else {
8883     // REV16{<c>}{<q>} <Rd>, <Rm> ; A1
8884     if (cond.IsNotNever() &&
8885         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8886       EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8887               rm.GetCode());
8888       return;
8889     }
8890   }
8891   Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm);
8892 }
8893 
revsh(Condition cond,EncodingSize size,Register rd,Register rm)8894 void Assembler::revsh(Condition cond,
8895                       EncodingSize size,
8896                       Register rd,
8897                       Register rm) {
8898   VIXL_ASSERT(AllowAssembler());
8899   CheckIT(cond);
8900   if (IsUsingT32()) {
8901     // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1
8902     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8903       EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3));
8904       AdvanceIT();
8905       return;
8906     }
8907     // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2
8908     if (!size.IsNarrow() &&
8909         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8910       EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
8911                  (rm.GetCode() << 16));
8912       AdvanceIT();
8913       return;
8914     }
8915   } else {
8916     // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1
8917     if (cond.IsNotNever() &&
8918         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8919       EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8920               rm.GetCode());
8921       return;
8922     }
8923   }
8924   Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm);
8925 }
8926 
ror(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)8927 void Assembler::ror(Condition cond,
8928                     EncodingSize size,
8929                     Register rd,
8930                     Register rm,
8931                     const Operand& operand) {
8932   VIXL_ASSERT(AllowAssembler());
8933   CheckIT(cond);
8934   if (operand.IsImmediate()) {
8935     uint32_t imm = operand.GetImmediate();
8936     if (IsUsingT32()) {
8937       // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
8938       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
8939           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8940         EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() |
8941                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
8942         AdvanceIT();
8943         return;
8944       }
8945     } else {
8946       // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
8947       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
8948         EmitA32(0x01a00060U | (cond.GetCondition() << 28) |
8949                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
8950         return;
8951       }
8952     }
8953   }
8954   if (operand.IsPlainRegister()) {
8955     Register rs = operand.GetBaseRegister();
8956     if (IsUsingT32()) {
8957       // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
8958       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
8959           rs.IsLow()) {
8960         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
8961         AdvanceIT();
8962         return;
8963       }
8964       // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
8965       if (!size.IsNarrow() &&
8966           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
8967         EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
8968                    rs.GetCode());
8969         AdvanceIT();
8970         return;
8971       }
8972     } else {
8973       // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
8974       if (cond.IsNotNever() &&
8975           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
8976         EmitA32(0x01a00070U | (cond.GetCondition() << 28) |
8977                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
8978         return;
8979       }
8980     }
8981   }
8982   Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand);
8983 }
8984 
rors(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)8985 void Assembler::rors(Condition cond,
8986                      EncodingSize size,
8987                      Register rd,
8988                      Register rm,
8989                      const Operand& operand) {
8990   VIXL_ASSERT(AllowAssembler());
8991   CheckIT(cond);
8992   if (operand.IsImmediate()) {
8993     uint32_t imm = operand.GetImmediate();
8994     if (IsUsingT32()) {
8995       // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
8996       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
8997           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8998         EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() |
8999                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
9000         AdvanceIT();
9001         return;
9002       }
9003     } else {
9004       // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
9005       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
9006         EmitA32(0x01b00060U | (cond.GetCondition() << 28) |
9007                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
9008         return;
9009       }
9010     }
9011   }
9012   if (operand.IsPlainRegister()) {
9013     Register rs = operand.GetBaseRegister();
9014     if (IsUsingT32()) {
9015       // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
9016       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
9017           rs.IsLow()) {
9018         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
9019         AdvanceIT();
9020         return;
9021       }
9022       // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
9023       if (!size.IsNarrow() &&
9024           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
9025         EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
9026                    rs.GetCode());
9027         AdvanceIT();
9028         return;
9029       }
9030     } else {
9031       // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
9032       if (cond.IsNotNever() &&
9033           ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
9034         EmitA32(0x01b00070U | (cond.GetCondition() << 28) |
9035                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
9036         return;
9037       }
9038     }
9039   }
9040   Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand);
9041 }
9042 
rrx(Condition cond,Register rd,Register rm)9043 void Assembler::rrx(Condition cond, Register rd, Register rm) {
9044   VIXL_ASSERT(AllowAssembler());
9045   CheckIT(cond);
9046   if (IsUsingT32()) {
9047     // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3
9048     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9049       EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode());
9050       AdvanceIT();
9051       return;
9052     }
9053   } else {
9054     // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1
9055     if (cond.IsNotNever()) {
9056       EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9057               rm.GetCode());
9058       return;
9059     }
9060   }
9061   Delegate(kRrx, &Assembler::rrx, cond, rd, rm);
9062 }
9063 
rrxs(Condition cond,Register rd,Register rm)9064 void Assembler::rrxs(Condition cond, Register rd, Register rm) {
9065   VIXL_ASSERT(AllowAssembler());
9066   CheckIT(cond);
9067   if (IsUsingT32()) {
9068     // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3
9069     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9070       EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode());
9071       AdvanceIT();
9072       return;
9073     }
9074   } else {
9075     // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1
9076     if (cond.IsNotNever()) {
9077       EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9078               rm.GetCode());
9079       return;
9080     }
9081   }
9082   Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm);
9083 }
9084 
rsb(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)9085 void Assembler::rsb(Condition cond,
9086                     EncodingSize size,
9087                     Register rd,
9088                     Register rn,
9089                     const Operand& operand) {
9090   VIXL_ASSERT(AllowAssembler());
9091   CheckIT(cond);
9092   if (operand.IsImmediate()) {
9093     uint32_t imm = operand.GetImmediate();
9094     if (IsUsingT32()) {
9095       ImmediateT32 immediate_t32(imm);
9096       // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1
9097       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
9098           (imm == 0)) {
9099         EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
9100         AdvanceIT();
9101         return;
9102       }
9103       // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
9104       if (!size.IsNarrow() && immediate_t32.IsValid() &&
9105           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
9106         EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9107                    (immediate_t32.GetEncodingValue() & 0xff) |
9108                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
9109                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
9110         AdvanceIT();
9111         return;
9112       }
9113     } else {
9114       ImmediateA32 immediate_a32(imm);
9115       // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9116       if (immediate_a32.IsValid() && cond.IsNotNever()) {
9117         EmitA32(0x02600000U | (cond.GetCondition() << 28) |
9118                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9119                 immediate_a32.GetEncodingValue());
9120         return;
9121       }
9122     }
9123   }
9124   if (operand.IsImmediateShiftedRegister()) {
9125     Register rm = operand.GetBaseRegister();
9126     Shift shift = operand.GetShift();
9127     uint32_t amount = operand.GetShiftAmount();
9128     if (IsUsingT32()) {
9129       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
9130       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
9131           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9132         uint32_t amount_ = amount % 32;
9133         EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9134                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
9135                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
9136         AdvanceIT();
9137         return;
9138       }
9139     } else {
9140       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9141       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9142         uint32_t amount_ = amount % 32;
9143         EmitA32(0x00600000U | (cond.GetCondition() << 28) |
9144                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9145                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9146         return;
9147       }
9148     }
9149   }
9150   if (operand.IsRegisterShiftedRegister()) {
9151     Register rm = operand.GetBaseRegister();
9152     Shift shift = operand.GetShift();
9153     Register rs = operand.GetShiftRegister();
9154     if (IsUsingA32()) {
9155       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9156       if (cond.IsNotNever() &&
9157           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9158            AllowUnpredictable())) {
9159         EmitA32(0x00600010U | (cond.GetCondition() << 28) |
9160                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9161                 (shift.GetType() << 5) | (rs.GetCode() << 8));
9162         return;
9163       }
9164     }
9165   }
9166   Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand);
9167 }
9168 
rsbs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)9169 void Assembler::rsbs(Condition cond,
9170                      EncodingSize size,
9171                      Register rd,
9172                      Register rn,
9173                      const Operand& operand) {
9174   VIXL_ASSERT(AllowAssembler());
9175   CheckIT(cond);
9176   if (operand.IsImmediate()) {
9177     uint32_t imm = operand.GetImmediate();
9178     if (IsUsingT32()) {
9179       ImmediateT32 immediate_t32(imm);
9180       // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1
9181       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
9182           (imm == 0)) {
9183         EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
9184         AdvanceIT();
9185         return;
9186       }
9187       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
9188       if (!size.IsNarrow() && immediate_t32.IsValid() &&
9189           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
9190         EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9191                    (immediate_t32.GetEncodingValue() & 0xff) |
9192                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
9193                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
9194         AdvanceIT();
9195         return;
9196       }
9197     } else {
9198       ImmediateA32 immediate_a32(imm);
9199       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9200       if (immediate_a32.IsValid() && cond.IsNotNever()) {
9201         EmitA32(0x02700000U | (cond.GetCondition() << 28) |
9202                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9203                 immediate_a32.GetEncodingValue());
9204         return;
9205       }
9206     }
9207   }
9208   if (operand.IsImmediateShiftedRegister()) {
9209     Register rm = operand.GetBaseRegister();
9210     Shift shift = operand.GetShift();
9211     uint32_t amount = operand.GetShiftAmount();
9212     if (IsUsingT32()) {
9213       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
9214       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
9215           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9216         uint32_t amount_ = amount % 32;
9217         EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9218                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
9219                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
9220         AdvanceIT();
9221         return;
9222       }
9223     } else {
9224       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9225       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9226         uint32_t amount_ = amount % 32;
9227         EmitA32(0x00700000U | (cond.GetCondition() << 28) |
9228                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9229                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9230         return;
9231       }
9232     }
9233   }
9234   if (operand.IsRegisterShiftedRegister()) {
9235     Register rm = operand.GetBaseRegister();
9236     Shift shift = operand.GetShift();
9237     Register rs = operand.GetShiftRegister();
9238     if (IsUsingA32()) {
9239       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9240       if (cond.IsNotNever() &&
9241           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9242            AllowUnpredictable())) {
9243         EmitA32(0x00700010U | (cond.GetCondition() << 28) |
9244                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9245                 (shift.GetType() << 5) | (rs.GetCode() << 8));
9246         return;
9247       }
9248     }
9249   }
9250   Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand);
9251 }
9252 
rsc(Condition cond,Register rd,Register rn,const Operand & operand)9253 void Assembler::rsc(Condition cond,
9254                     Register rd,
9255                     Register rn,
9256                     const Operand& operand) {
9257   VIXL_ASSERT(AllowAssembler());
9258   CheckIT(cond);
9259   if (operand.IsImmediate()) {
9260     uint32_t imm = operand.GetImmediate();
9261     if (IsUsingA32()) {
9262       ImmediateA32 immediate_a32(imm);
9263       // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9264       if (immediate_a32.IsValid() && cond.IsNotNever()) {
9265         EmitA32(0x02e00000U | (cond.GetCondition() << 28) |
9266                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9267                 immediate_a32.GetEncodingValue());
9268         return;
9269       }
9270     }
9271   }
9272   if (operand.IsImmediateShiftedRegister()) {
9273     Register rm = operand.GetBaseRegister();
9274     Shift shift = operand.GetShift();
9275     uint32_t amount = operand.GetShiftAmount();
9276     if (IsUsingA32()) {
9277       // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9278       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9279         uint32_t amount_ = amount % 32;
9280         EmitA32(0x00e00000U | (cond.GetCondition() << 28) |
9281                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9282                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9283         return;
9284       }
9285     }
9286   }
9287   if (operand.IsRegisterShiftedRegister()) {
9288     Register rm = operand.GetBaseRegister();
9289     Shift shift = operand.GetShift();
9290     Register rs = operand.GetShiftRegister();
9291     if (IsUsingA32()) {
9292       // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9293       if (cond.IsNotNever() &&
9294           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9295            AllowUnpredictable())) {
9296         EmitA32(0x00e00010U | (cond.GetCondition() << 28) |
9297                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9298                 (shift.GetType() << 5) | (rs.GetCode() << 8));
9299         return;
9300       }
9301     }
9302   }
9303   Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand);
9304 }
9305 
rscs(Condition cond,Register rd,Register rn,const Operand & operand)9306 void Assembler::rscs(Condition cond,
9307                      Register rd,
9308                      Register rn,
9309                      const Operand& operand) {
9310   VIXL_ASSERT(AllowAssembler());
9311   CheckIT(cond);
9312   if (operand.IsImmediate()) {
9313     uint32_t imm = operand.GetImmediate();
9314     if (IsUsingA32()) {
9315       ImmediateA32 immediate_a32(imm);
9316       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9317       if (immediate_a32.IsValid() && cond.IsNotNever()) {
9318         EmitA32(0x02f00000U | (cond.GetCondition() << 28) |
9319                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9320                 immediate_a32.GetEncodingValue());
9321         return;
9322       }
9323     }
9324   }
9325   if (operand.IsImmediateShiftedRegister()) {
9326     Register rm = operand.GetBaseRegister();
9327     Shift shift = operand.GetShift();
9328     uint32_t amount = operand.GetShiftAmount();
9329     if (IsUsingA32()) {
9330       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9331       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9332         uint32_t amount_ = amount % 32;
9333         EmitA32(0x00f00000U | (cond.GetCondition() << 28) |
9334                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9335                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9336         return;
9337       }
9338     }
9339   }
9340   if (operand.IsRegisterShiftedRegister()) {
9341     Register rm = operand.GetBaseRegister();
9342     Shift shift = operand.GetShift();
9343     Register rs = operand.GetShiftRegister();
9344     if (IsUsingA32()) {
9345       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9346       if (cond.IsNotNever() &&
9347           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9348            AllowUnpredictable())) {
9349         EmitA32(0x00f00010U | (cond.GetCondition() << 28) |
9350                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9351                 (shift.GetType() << 5) | (rs.GetCode() << 8));
9352         return;
9353       }
9354     }
9355   }
9356   Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand);
9357 }
9358 
sadd16(Condition cond,Register rd,Register rn,Register rm)9359 void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) {
9360   VIXL_ASSERT(AllowAssembler());
9361   CheckIT(cond);
9362   if (IsUsingT32()) {
9363     // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9364     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9365       EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9366                  rm.GetCode());
9367       AdvanceIT();
9368       return;
9369     }
9370   } else {
9371     // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9372     if (cond.IsNotNever() &&
9373         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9374       EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9375               (rn.GetCode() << 16) | rm.GetCode());
9376       return;
9377     }
9378   }
9379   Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm);
9380 }
9381 
sadd8(Condition cond,Register rd,Register rn,Register rm)9382 void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) {
9383   VIXL_ASSERT(AllowAssembler());
9384   CheckIT(cond);
9385   if (IsUsingT32()) {
9386     // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9387     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9388       EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9389                  rm.GetCode());
9390       AdvanceIT();
9391       return;
9392     }
9393   } else {
9394     // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9395     if (cond.IsNotNever() &&
9396         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9397       EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9398               (rn.GetCode() << 16) | rm.GetCode());
9399       return;
9400     }
9401   }
9402   Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm);
9403 }
9404 
sasx(Condition cond,Register rd,Register rn,Register rm)9405 void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) {
9406   VIXL_ASSERT(AllowAssembler());
9407   CheckIT(cond);
9408   if (IsUsingT32()) {
9409     // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9410     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9411       EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9412                  rm.GetCode());
9413       AdvanceIT();
9414       return;
9415     }
9416   } else {
9417     // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9418     if (cond.IsNotNever() &&
9419         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9420       EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9421               (rn.GetCode() << 16) | rm.GetCode());
9422       return;
9423     }
9424   }
9425   Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm);
9426 }
9427 
sbc(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)9428 void Assembler::sbc(Condition cond,
9429                     EncodingSize size,
9430                     Register rd,
9431                     Register rn,
9432                     const Operand& operand) {
9433   VIXL_ASSERT(AllowAssembler());
9434   CheckIT(cond);
9435   if (operand.IsImmediate()) {
9436     uint32_t imm = operand.GetImmediate();
9437     if (IsUsingT32()) {
9438       ImmediateT32 immediate_t32(imm);
9439       // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
9440       if (!size.IsNarrow() && immediate_t32.IsValid() &&
9441           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
9442         EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9443                    (immediate_t32.GetEncodingValue() & 0xff) |
9444                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
9445                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
9446         AdvanceIT();
9447         return;
9448       }
9449     } else {
9450       ImmediateA32 immediate_a32(imm);
9451       // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9452       if (immediate_a32.IsValid() && cond.IsNotNever()) {
9453         EmitA32(0x02c00000U | (cond.GetCondition() << 28) |
9454                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9455                 immediate_a32.GetEncodingValue());
9456         return;
9457       }
9458     }
9459   }
9460   if (operand.IsImmediateShiftedRegister()) {
9461     Register rm = operand.GetBaseRegister();
9462     if (operand.IsPlainRegister()) {
9463       if (IsUsingT32()) {
9464         // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
9465         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
9466             rm.IsLow()) {
9467           EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
9468           AdvanceIT();
9469           return;
9470         }
9471       }
9472     }
9473     Shift shift = operand.GetShift();
9474     uint32_t amount = operand.GetShiftAmount();
9475     if (IsUsingT32()) {
9476       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
9477       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
9478           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9479         uint32_t amount_ = amount % 32;
9480         EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9481                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
9482                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
9483         AdvanceIT();
9484         return;
9485       }
9486     } else {
9487       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9488       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9489         uint32_t amount_ = amount % 32;
9490         EmitA32(0x00c00000U | (cond.GetCondition() << 28) |
9491                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9492                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9493         return;
9494       }
9495     }
9496   }
9497   if (operand.IsRegisterShiftedRegister()) {
9498     Register rm = operand.GetBaseRegister();
9499     Shift shift = operand.GetShift();
9500     Register rs = operand.GetShiftRegister();
9501     if (IsUsingA32()) {
9502       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9503       if (cond.IsNotNever() &&
9504           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9505            AllowUnpredictable())) {
9506         EmitA32(0x00c00010U | (cond.GetCondition() << 28) |
9507                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9508                 (shift.GetType() << 5) | (rs.GetCode() << 8));
9509         return;
9510       }
9511     }
9512   }
9513   Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand);
9514 }
9515 
sbcs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)9516 void Assembler::sbcs(Condition cond,
9517                      EncodingSize size,
9518                      Register rd,
9519                      Register rn,
9520                      const Operand& operand) {
9521   VIXL_ASSERT(AllowAssembler());
9522   CheckIT(cond);
9523   if (operand.IsImmediate()) {
9524     uint32_t imm = operand.GetImmediate();
9525     if (IsUsingT32()) {
9526       ImmediateT32 immediate_t32(imm);
9527       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
9528       if (!size.IsNarrow() && immediate_t32.IsValid() &&
9529           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
9530         EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9531                    (immediate_t32.GetEncodingValue() & 0xff) |
9532                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
9533                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
9534         AdvanceIT();
9535         return;
9536       }
9537     } else {
9538       ImmediateA32 immediate_a32(imm);
9539       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9540       if (immediate_a32.IsValid() && cond.IsNotNever()) {
9541         EmitA32(0x02d00000U | (cond.GetCondition() << 28) |
9542                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9543                 immediate_a32.GetEncodingValue());
9544         return;
9545       }
9546     }
9547   }
9548   if (operand.IsImmediateShiftedRegister()) {
9549     Register rm = operand.GetBaseRegister();
9550     if (operand.IsPlainRegister()) {
9551       if (IsUsingT32()) {
9552         // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
9553         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
9554             rm.IsLow()) {
9555           EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
9556           AdvanceIT();
9557           return;
9558         }
9559       }
9560     }
9561     Shift shift = operand.GetShift();
9562     uint32_t amount = operand.GetShiftAmount();
9563     if (IsUsingT32()) {
9564       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
9565       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
9566           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9567         uint32_t amount_ = amount % 32;
9568         EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9569                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
9570                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
9571         AdvanceIT();
9572         return;
9573       }
9574     } else {
9575       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9576       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9577         uint32_t amount_ = amount % 32;
9578         EmitA32(0x00d00000U | (cond.GetCondition() << 28) |
9579                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9580                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9581         return;
9582       }
9583     }
9584   }
9585   if (operand.IsRegisterShiftedRegister()) {
9586     Register rm = operand.GetBaseRegister();
9587     Shift shift = operand.GetShift();
9588     Register rs = operand.GetShiftRegister();
9589     if (IsUsingA32()) {
9590       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9591       if (cond.IsNotNever() &&
9592           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9593            AllowUnpredictable())) {
9594         EmitA32(0x00d00010U | (cond.GetCondition() << 28) |
9595                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9596                 (shift.GetType() << 5) | (rs.GetCode() << 8));
9597         return;
9598       }
9599     }
9600   }
9601   Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand);
9602 }
9603 
sbfx(Condition cond,Register rd,Register rn,uint32_t lsb,uint32_t width)9604 void Assembler::sbfx(
9605     Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
9606   VIXL_ASSERT(AllowAssembler());
9607   CheckIT(cond);
9608   if (IsUsingT32()) {
9609     // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
9610     if ((lsb <= 31) &&
9611         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
9612          AllowUnpredictable())) {
9613       uint32_t widthm1 = width - 1;
9614       EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9615                  ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
9616       AdvanceIT();
9617       return;
9618     }
9619   } else {
9620     // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
9621     if ((lsb <= 31) && cond.IsNotNever() &&
9622         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
9623          AllowUnpredictable())) {
9624       uint32_t widthm1 = width - 1;
9625       EmitA32(0x07a00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9626               rn.GetCode() | (lsb << 7) | (widthm1 << 16));
9627       return;
9628     }
9629   }
9630   Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, width);
9631 }
9632 
sdiv(Condition cond,Register rd,Register rn,Register rm)9633 void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) {
9634   VIXL_ASSERT(AllowAssembler());
9635   CheckIT(cond);
9636   if (IsUsingT32()) {
9637     // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9638     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9639       EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9640                  rm.GetCode());
9641       AdvanceIT();
9642       return;
9643     }
9644   } else {
9645     // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9646     if (cond.IsNotNever() &&
9647         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9648       EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9649               rn.GetCode() | (rm.GetCode() << 8));
9650       return;
9651     }
9652   }
9653   Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm);
9654 }
9655 
sel(Condition cond,Register rd,Register rn,Register rm)9656 void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) {
9657   VIXL_ASSERT(AllowAssembler());
9658   CheckIT(cond);
9659   if (IsUsingT32()) {
9660     // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9661     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9662       EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9663                  rm.GetCode());
9664       AdvanceIT();
9665       return;
9666     }
9667   } else {
9668     // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9669     if (cond.IsNotNever() &&
9670         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9671       EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9672               (rn.GetCode() << 16) | rm.GetCode());
9673       return;
9674     }
9675   }
9676   Delegate(kSel, &Assembler::sel, cond, rd, rn, rm);
9677 }
9678 
shadd16(Condition cond,Register rd,Register rn,Register rm)9679 void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) {
9680   VIXL_ASSERT(AllowAssembler());
9681   CheckIT(cond);
9682   if (IsUsingT32()) {
9683     // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9684     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9685       EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9686                  rm.GetCode());
9687       AdvanceIT();
9688       return;
9689     }
9690   } else {
9691     // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9692     if (cond.IsNotNever() &&
9693         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9694       EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9695               (rn.GetCode() << 16) | rm.GetCode());
9696       return;
9697     }
9698   }
9699   Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm);
9700 }
9701 
shadd8(Condition cond,Register rd,Register rn,Register rm)9702 void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) {
9703   VIXL_ASSERT(AllowAssembler());
9704   CheckIT(cond);
9705   if (IsUsingT32()) {
9706     // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9707     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9708       EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9709                  rm.GetCode());
9710       AdvanceIT();
9711       return;
9712     }
9713   } else {
9714     // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9715     if (cond.IsNotNever() &&
9716         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9717       EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9718               (rn.GetCode() << 16) | rm.GetCode());
9719       return;
9720     }
9721   }
9722   Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm);
9723 }
9724 
shasx(Condition cond,Register rd,Register rn,Register rm)9725 void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) {
9726   VIXL_ASSERT(AllowAssembler());
9727   CheckIT(cond);
9728   if (IsUsingT32()) {
9729     // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9730     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9731       EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9732                  rm.GetCode());
9733       AdvanceIT();
9734       return;
9735     }
9736   } else {
9737     // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9738     if (cond.IsNotNever() &&
9739         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9740       EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9741               (rn.GetCode() << 16) | rm.GetCode());
9742       return;
9743     }
9744   }
9745   Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm);
9746 }
9747 
shsax(Condition cond,Register rd,Register rn,Register rm)9748 void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) {
9749   VIXL_ASSERT(AllowAssembler());
9750   CheckIT(cond);
9751   if (IsUsingT32()) {
9752     // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9753     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9754       EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9755                  rm.GetCode());
9756       AdvanceIT();
9757       return;
9758     }
9759   } else {
9760     // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9761     if (cond.IsNotNever() &&
9762         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9763       EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9764               (rn.GetCode() << 16) | rm.GetCode());
9765       return;
9766     }
9767   }
9768   Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm);
9769 }
9770 
shsub16(Condition cond,Register rd,Register rn,Register rm)9771 void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) {
9772   VIXL_ASSERT(AllowAssembler());
9773   CheckIT(cond);
9774   if (IsUsingT32()) {
9775     // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9776     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9777       EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9778                  rm.GetCode());
9779       AdvanceIT();
9780       return;
9781     }
9782   } else {
9783     // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9784     if (cond.IsNotNever() &&
9785         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9786       EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9787               (rn.GetCode() << 16) | rm.GetCode());
9788       return;
9789     }
9790   }
9791   Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm);
9792 }
9793 
shsub8(Condition cond,Register rd,Register rn,Register rm)9794 void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) {
9795   VIXL_ASSERT(AllowAssembler());
9796   CheckIT(cond);
9797   if (IsUsingT32()) {
9798     // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9799     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9800       EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9801                  rm.GetCode());
9802       AdvanceIT();
9803       return;
9804     }
9805   } else {
9806     // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9807     if (cond.IsNotNever() &&
9808         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9809       EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9810               (rn.GetCode() << 16) | rm.GetCode());
9811       return;
9812     }
9813   }
9814   Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm);
9815 }
9816 
smlabb(Condition cond,Register rd,Register rn,Register rm,Register ra)9817 void Assembler::smlabb(
9818     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9819   VIXL_ASSERT(AllowAssembler());
9820   CheckIT(cond);
9821   if (IsUsingT32()) {
9822     // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9823     if (!ra.Is(pc) &&
9824         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9825       EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9826                  rm.GetCode() | (ra.GetCode() << 12));
9827       AdvanceIT();
9828       return;
9829     }
9830   } else {
9831     // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9832     if (cond.IsNotNever() &&
9833         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
9834          AllowUnpredictable())) {
9835       EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9836               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9837       return;
9838     }
9839   }
9840   Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra);
9841 }
9842 
smlabt(Condition cond,Register rd,Register rn,Register rm,Register ra)9843 void Assembler::smlabt(
9844     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9845   VIXL_ASSERT(AllowAssembler());
9846   CheckIT(cond);
9847   if (IsUsingT32()) {
9848     // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9849     if (!ra.Is(pc) &&
9850         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9851       EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9852                  rm.GetCode() | (ra.GetCode() << 12));
9853       AdvanceIT();
9854       return;
9855     }
9856   } else {
9857     // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9858     if (cond.IsNotNever() &&
9859         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
9860          AllowUnpredictable())) {
9861       EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9862               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9863       return;
9864     }
9865   }
9866   Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra);
9867 }
9868 
smlad(Condition cond,Register rd,Register rn,Register rm,Register ra)9869 void Assembler::smlad(
9870     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9871   VIXL_ASSERT(AllowAssembler());
9872   CheckIT(cond);
9873   if (IsUsingT32()) {
9874     // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9875     if (!ra.Is(pc) &&
9876         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9877       EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9878                  rm.GetCode() | (ra.GetCode() << 12));
9879       AdvanceIT();
9880       return;
9881     }
9882   } else {
9883     // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9884     if (cond.IsNotNever() && !ra.Is(pc) &&
9885         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9886       EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9887               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9888       return;
9889     }
9890   }
9891   Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra);
9892 }
9893 
smladx(Condition cond,Register rd,Register rn,Register rm,Register ra)9894 void Assembler::smladx(
9895     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9896   VIXL_ASSERT(AllowAssembler());
9897   CheckIT(cond);
9898   if (IsUsingT32()) {
9899     // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9900     if (!ra.Is(pc) &&
9901         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9902       EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9903                  rm.GetCode() | (ra.GetCode() << 12));
9904       AdvanceIT();
9905       return;
9906     }
9907   } else {
9908     // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9909     if (cond.IsNotNever() && !ra.Is(pc) &&
9910         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9911       EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9912               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9913       return;
9914     }
9915   }
9916   Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra);
9917 }
9918 
smlal(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9919 void Assembler::smlal(
9920     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9921   VIXL_ASSERT(AllowAssembler());
9922   CheckIT(cond);
9923   if (IsUsingT32()) {
9924     // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9925     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
9926          AllowUnpredictable())) {
9927       EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9928                  (rn.GetCode() << 16) | rm.GetCode());
9929       AdvanceIT();
9930       return;
9931     }
9932   } else {
9933     // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9934     if (cond.IsNotNever() &&
9935         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
9936          AllowUnpredictable())) {
9937       EmitA32(0x00e00090U | (cond.GetCondition() << 28) |
9938               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9939               (rm.GetCode() << 8));
9940       return;
9941     }
9942   }
9943   Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm);
9944 }
9945 
smlalbb(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9946 void Assembler::smlalbb(
9947     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9948   VIXL_ASSERT(AllowAssembler());
9949   CheckIT(cond);
9950   if (IsUsingT32()) {
9951     // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9952     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
9953          AllowUnpredictable())) {
9954       EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9955                  (rn.GetCode() << 16) | rm.GetCode());
9956       AdvanceIT();
9957       return;
9958     }
9959   } else {
9960     // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9961     if (cond.IsNotNever() &&
9962         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
9963          AllowUnpredictable())) {
9964       EmitA32(0x01400080U | (cond.GetCondition() << 28) |
9965               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9966               (rm.GetCode() << 8));
9967       return;
9968     }
9969   }
9970   Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm);
9971 }
9972 
smlalbt(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9973 void Assembler::smlalbt(
9974     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9975   VIXL_ASSERT(AllowAssembler());
9976   CheckIT(cond);
9977   if (IsUsingT32()) {
9978     // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9979     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
9980          AllowUnpredictable())) {
9981       EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9982                  (rn.GetCode() << 16) | rm.GetCode());
9983       AdvanceIT();
9984       return;
9985     }
9986   } else {
9987     // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9988     if (cond.IsNotNever() &&
9989         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
9990          AllowUnpredictable())) {
9991       EmitA32(0x014000c0U | (cond.GetCondition() << 28) |
9992               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9993               (rm.GetCode() << 8));
9994       return;
9995     }
9996   }
9997   Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm);
9998 }
9999 
smlald(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10000 void Assembler::smlald(
10001     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10002   VIXL_ASSERT(AllowAssembler());
10003   CheckIT(cond);
10004   if (IsUsingT32()) {
10005     // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10006     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10007          AllowUnpredictable())) {
10008       EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10009                  (rn.GetCode() << 16) | rm.GetCode());
10010       AdvanceIT();
10011       return;
10012     }
10013   } else {
10014     // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10015     if (cond.IsNotNever() &&
10016         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10017          AllowUnpredictable())) {
10018       EmitA32(0x07400010U | (cond.GetCondition() << 28) |
10019               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10020               (rm.GetCode() << 8));
10021       return;
10022     }
10023   }
10024   Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm);
10025 }
10026 
smlaldx(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10027 void Assembler::smlaldx(
10028     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10029   VIXL_ASSERT(AllowAssembler());
10030   CheckIT(cond);
10031   if (IsUsingT32()) {
10032     // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10033     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10034          AllowUnpredictable())) {
10035       EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10036                  (rn.GetCode() << 16) | rm.GetCode());
10037       AdvanceIT();
10038       return;
10039     }
10040   } else {
10041     // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10042     if (cond.IsNotNever() &&
10043         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10044          AllowUnpredictable())) {
10045       EmitA32(0x07400030U | (cond.GetCondition() << 28) |
10046               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10047               (rm.GetCode() << 8));
10048       return;
10049     }
10050   }
10051   Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm);
10052 }
10053 
smlals(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10054 void Assembler::smlals(
10055     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10056   VIXL_ASSERT(AllowAssembler());
10057   CheckIT(cond);
10058   if (IsUsingA32()) {
10059     // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10060     if (cond.IsNotNever() &&
10061         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10062          AllowUnpredictable())) {
10063       EmitA32(0x00f00090U | (cond.GetCondition() << 28) |
10064               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10065               (rm.GetCode() << 8));
10066       return;
10067     }
10068   }
10069   Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm);
10070 }
10071 
smlaltb(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10072 void Assembler::smlaltb(
10073     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10074   VIXL_ASSERT(AllowAssembler());
10075   CheckIT(cond);
10076   if (IsUsingT32()) {
10077     // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10078     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10079          AllowUnpredictable())) {
10080       EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10081                  (rn.GetCode() << 16) | rm.GetCode());
10082       AdvanceIT();
10083       return;
10084     }
10085   } else {
10086     // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10087     if (cond.IsNotNever() &&
10088         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10089          AllowUnpredictable())) {
10090       EmitA32(0x014000a0U | (cond.GetCondition() << 28) |
10091               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10092               (rm.GetCode() << 8));
10093       return;
10094     }
10095   }
10096   Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm);
10097 }
10098 
smlaltt(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10099 void Assembler::smlaltt(
10100     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10101   VIXL_ASSERT(AllowAssembler());
10102   CheckIT(cond);
10103   if (IsUsingT32()) {
10104     // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10105     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10106          AllowUnpredictable())) {
10107       EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10108                  (rn.GetCode() << 16) | rm.GetCode());
10109       AdvanceIT();
10110       return;
10111     }
10112   } else {
10113     // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10114     if (cond.IsNotNever() &&
10115         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10116          AllowUnpredictable())) {
10117       EmitA32(0x014000e0U | (cond.GetCondition() << 28) |
10118               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10119               (rm.GetCode() << 8));
10120       return;
10121     }
10122   }
10123   Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm);
10124 }
10125 
smlatb(Condition cond,Register rd,Register rn,Register rm,Register ra)10126 void Assembler::smlatb(
10127     Condition cond, Register rd, Register rn, Register rm, Register ra) {
10128   VIXL_ASSERT(AllowAssembler());
10129   CheckIT(cond);
10130   if (IsUsingT32()) {
10131     // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10132     if (!ra.Is(pc) &&
10133         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10134       EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10135                  rm.GetCode() | (ra.GetCode() << 12));
10136       AdvanceIT();
10137       return;
10138     }
10139   } else {
10140     // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10141     if (cond.IsNotNever() &&
10142         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10143          AllowUnpredictable())) {
10144       EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10145               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10146       return;
10147     }
10148   }
10149   Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra);
10150 }
10151 
smlatt(Condition cond,Register rd,Register rn,Register rm,Register ra)10152 void Assembler::smlatt(
10153     Condition cond, Register rd, Register rn, Register rm, Register ra) {
10154   VIXL_ASSERT(AllowAssembler());
10155   CheckIT(cond);
10156   if (IsUsingT32()) {
10157     // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10158     if (!ra.Is(pc) &&
10159         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10160       EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10161                  rm.GetCode() | (ra.GetCode() << 12));
10162       AdvanceIT();
10163       return;
10164     }
10165   } else {
10166     // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10167     if (cond.IsNotNever() &&
10168         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10169          AllowUnpredictable())) {
10170       EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10171               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10172       return;
10173     }
10174   }
10175   Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra);
10176 }
10177 
smlawb(Condition cond,Register rd,Register rn,Register rm,Register ra)10178 void Assembler::smlawb(
10179     Condition cond, Register rd, Register rn, Register rm, Register ra) {
10180   VIXL_ASSERT(AllowAssembler());
10181   CheckIT(cond);
10182   if (IsUsingT32()) {
10183     // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10184     if (!ra.Is(pc) &&
10185         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10186       EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10187                  rm.GetCode() | (ra.GetCode() << 12));
10188       AdvanceIT();
10189       return;
10190     }
10191   } else {
10192     // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10193     if (cond.IsNotNever() &&
10194         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10195          AllowUnpredictable())) {
10196       EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10197               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10198       return;
10199     }
10200   }
10201   Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra);
10202 }
10203 
smlawt(Condition cond,Register rd,Register rn,Register rm,Register ra)10204 void Assembler::smlawt(
10205     Condition cond, Register rd, Register rn, Register rm, Register ra) {
10206   VIXL_ASSERT(AllowAssembler());
10207   CheckIT(cond);
10208   if (IsUsingT32()) {
10209     // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10210     if (!ra.Is(pc) &&
10211         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10212       EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10213                  rm.GetCode() | (ra.GetCode() << 12));
10214       AdvanceIT();
10215       return;
10216     }
10217   } else {
10218     // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10219     if (cond.IsNotNever() &&
10220         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10221          AllowUnpredictable())) {
10222       EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10223               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10224       return;
10225     }
10226   }
10227   Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra);
10228 }
10229 
smlsd(Condition cond,Register rd,Register rn,Register rm,Register ra)10230 void Assembler::smlsd(
10231     Condition cond, Register rd, Register rn, Register rm, Register ra) {
10232   VIXL_ASSERT(AllowAssembler());
10233   CheckIT(cond);
10234   if (IsUsingT32()) {
10235     // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10236     if (!ra.Is(pc) &&
10237         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10238       EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10239                  rm.GetCode() | (ra.GetCode() << 12));
10240       AdvanceIT();
10241       return;
10242     }
10243   } else {
10244     // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10245     if (cond.IsNotNever() && !ra.Is(pc) &&
10246         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10247       EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10248               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10249       return;
10250     }
10251   }
10252   Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra);
10253 }
10254 
smlsdx(Condition cond,Register rd,Register rn,Register rm,Register ra)10255 void Assembler::smlsdx(
10256     Condition cond, Register rd, Register rn, Register rm, Register ra) {
10257   VIXL_ASSERT(AllowAssembler());
10258   CheckIT(cond);
10259   if (IsUsingT32()) {
10260     // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10261     if (!ra.Is(pc) &&
10262         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10263       EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10264                  rm.GetCode() | (ra.GetCode() << 12));
10265       AdvanceIT();
10266       return;
10267     }
10268   } else {
10269     // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10270     if (cond.IsNotNever() && !ra.Is(pc) &&
10271         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10272       EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10273               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10274       return;
10275     }
10276   }
10277   Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra);
10278 }
10279 
smlsld(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10280 void Assembler::smlsld(
10281     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10282   VIXL_ASSERT(AllowAssembler());
10283   CheckIT(cond);
10284   if (IsUsingT32()) {
10285     // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10286     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10287          AllowUnpredictable())) {
10288       EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10289                  (rn.GetCode() << 16) | rm.GetCode());
10290       AdvanceIT();
10291       return;
10292     }
10293   } else {
10294     // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10295     if (cond.IsNotNever() &&
10296         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10297          AllowUnpredictable())) {
10298       EmitA32(0x07400050U | (cond.GetCondition() << 28) |
10299               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10300               (rm.GetCode() << 8));
10301       return;
10302     }
10303   }
10304   Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm);
10305 }
10306 
smlsldx(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10307 void Assembler::smlsldx(
10308     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10309   VIXL_ASSERT(AllowAssembler());
10310   CheckIT(cond);
10311   if (IsUsingT32()) {
10312     // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10313     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10314          AllowUnpredictable())) {
10315       EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10316                  (rn.GetCode() << 16) | rm.GetCode());
10317       AdvanceIT();
10318       return;
10319     }
10320   } else {
10321     // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10322     if (cond.IsNotNever() &&
10323         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10324          AllowUnpredictable())) {
10325       EmitA32(0x07400070U | (cond.GetCondition() << 28) |
10326               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10327               (rm.GetCode() << 8));
10328       return;
10329     }
10330   }
10331   Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm);
10332 }
10333 
smmla(Condition cond,Register rd,Register rn,Register rm,Register ra)10334 void Assembler::smmla(
10335     Condition cond, Register rd, Register rn, Register rm, Register ra) {
10336   VIXL_ASSERT(AllowAssembler());
10337   CheckIT(cond);
10338   if (IsUsingT32()) {
10339     // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10340     if (!ra.Is(pc) &&
10341         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10342       EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10343                  rm.GetCode() | (ra.GetCode() << 12));
10344       AdvanceIT();
10345       return;
10346     }
10347   } else {
10348     // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10349     if (cond.IsNotNever() && !ra.Is(pc) &&
10350         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10351       EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10352               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10353       return;
10354     }
10355   }
10356   Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra);
10357 }
10358 
smmlar(Condition cond,Register rd,Register rn,Register rm,Register ra)10359 void Assembler::smmlar(
10360     Condition cond, Register rd, Register rn, Register rm, Register ra) {
10361   VIXL_ASSERT(AllowAssembler());
10362   CheckIT(cond);
10363   if (IsUsingT32()) {
10364     // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10365     if (!ra.Is(pc) &&
10366         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10367       EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10368                  rm.GetCode() | (ra.GetCode() << 12));
10369       AdvanceIT();
10370       return;
10371     }
10372   } else {
10373     // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10374     if (cond.IsNotNever() && !ra.Is(pc) &&
10375         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10376       EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10377               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10378       return;
10379     }
10380   }
10381   Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra);
10382 }
10383 
smmls(Condition cond,Register rd,Register rn,Register rm,Register ra)10384 void Assembler::smmls(
10385     Condition cond, Register rd, Register rn, Register rm, Register ra) {
10386   VIXL_ASSERT(AllowAssembler());
10387   CheckIT(cond);
10388   if (IsUsingT32()) {
10389     // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10390     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10391          AllowUnpredictable())) {
10392       EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10393                  rm.GetCode() | (ra.GetCode() << 12));
10394       AdvanceIT();
10395       return;
10396     }
10397   } else {
10398     // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10399     if (cond.IsNotNever() &&
10400         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10401          AllowUnpredictable())) {
10402       EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10403               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10404       return;
10405     }
10406   }
10407   Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra);
10408 }
10409 
smmlsr(Condition cond,Register rd,Register rn,Register rm,Register ra)10410 void Assembler::smmlsr(
10411     Condition cond, Register rd, Register rn, Register rm, Register ra) {
10412   VIXL_ASSERT(AllowAssembler());
10413   CheckIT(cond);
10414   if (IsUsingT32()) {
10415     // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10416     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10417          AllowUnpredictable())) {
10418       EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10419                  rm.GetCode() | (ra.GetCode() << 12));
10420       AdvanceIT();
10421       return;
10422     }
10423   } else {
10424     // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10425     if (cond.IsNotNever() &&
10426         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10427          AllowUnpredictable())) {
10428       EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10429               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10430       return;
10431     }
10432   }
10433   Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra);
10434 }
10435 
smmul(Condition cond,Register rd,Register rn,Register rm)10436 void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) {
10437   VIXL_ASSERT(AllowAssembler());
10438   CheckIT(cond);
10439   if (IsUsingT32()) {
10440     // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10441     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10442       EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10443                  rm.GetCode());
10444       AdvanceIT();
10445       return;
10446     }
10447   } else {
10448     // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10449     if (cond.IsNotNever() &&
10450         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10451       EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10452               rn.GetCode() | (rm.GetCode() << 8));
10453       return;
10454     }
10455   }
10456   Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm);
10457 }
10458 
smmulr(Condition cond,Register rd,Register rn,Register rm)10459 void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) {
10460   VIXL_ASSERT(AllowAssembler());
10461   CheckIT(cond);
10462   if (IsUsingT32()) {
10463     // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10464     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10465       EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10466                  rm.GetCode());
10467       AdvanceIT();
10468       return;
10469     }
10470   } else {
10471     // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10472     if (cond.IsNotNever() &&
10473         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10474       EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10475               rn.GetCode() | (rm.GetCode() << 8));
10476       return;
10477     }
10478   }
10479   Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm);
10480 }
10481 
smuad(Condition cond,Register rd,Register rn,Register rm)10482 void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) {
10483   VIXL_ASSERT(AllowAssembler());
10484   CheckIT(cond);
10485   if (IsUsingT32()) {
10486     // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10487     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10488       EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10489                  rm.GetCode());
10490       AdvanceIT();
10491       return;
10492     }
10493   } else {
10494     // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10495     if (cond.IsNotNever() &&
10496         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10497       EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10498               rn.GetCode() | (rm.GetCode() << 8));
10499       return;
10500     }
10501   }
10502   Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm);
10503 }
10504 
smuadx(Condition cond,Register rd,Register rn,Register rm)10505 void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) {
10506   VIXL_ASSERT(AllowAssembler());
10507   CheckIT(cond);
10508   if (IsUsingT32()) {
10509     // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10510     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10511       EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10512                  rm.GetCode());
10513       AdvanceIT();
10514       return;
10515     }
10516   } else {
10517     // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10518     if (cond.IsNotNever() &&
10519         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10520       EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10521               rn.GetCode() | (rm.GetCode() << 8));
10522       return;
10523     }
10524   }
10525   Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm);
10526 }
10527 
smulbb(Condition cond,Register rd,Register rn,Register rm)10528 void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) {
10529   VIXL_ASSERT(AllowAssembler());
10530   CheckIT(cond);
10531   if (IsUsingT32()) {
10532     // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10533     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10534       EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10535                  rm.GetCode());
10536       AdvanceIT();
10537       return;
10538     }
10539   } else {
10540     // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10541     if (cond.IsNotNever() &&
10542         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10543       EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10544               rn.GetCode() | (rm.GetCode() << 8));
10545       return;
10546     }
10547   }
10548   Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm);
10549 }
10550 
smulbt(Condition cond,Register rd,Register rn,Register rm)10551 void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) {
10552   VIXL_ASSERT(AllowAssembler());
10553   CheckIT(cond);
10554   if (IsUsingT32()) {
10555     // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10556     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10557       EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10558                  rm.GetCode());
10559       AdvanceIT();
10560       return;
10561     }
10562   } else {
10563     // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10564     if (cond.IsNotNever() &&
10565         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10566       EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10567               rn.GetCode() | (rm.GetCode() << 8));
10568       return;
10569     }
10570   }
10571   Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm);
10572 }
10573 
smull(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10574 void Assembler::smull(
10575     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10576   VIXL_ASSERT(AllowAssembler());
10577   CheckIT(cond);
10578   if (IsUsingT32()) {
10579     // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10580     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10581          AllowUnpredictable())) {
10582       EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10583                  (rn.GetCode() << 16) | rm.GetCode());
10584       AdvanceIT();
10585       return;
10586     }
10587   } else {
10588     // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10589     if (cond.IsNotNever() &&
10590         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10591          AllowUnpredictable())) {
10592       EmitA32(0x00c00090U | (cond.GetCondition() << 28) |
10593               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10594               (rm.GetCode() << 8));
10595       return;
10596     }
10597   }
10598   Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm);
10599 }
10600 
smulls(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10601 void Assembler::smulls(
10602     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10603   VIXL_ASSERT(AllowAssembler());
10604   CheckIT(cond);
10605   if (IsUsingA32()) {
10606     // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10607     if (cond.IsNotNever() &&
10608         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10609          AllowUnpredictable())) {
10610       EmitA32(0x00d00090U | (cond.GetCondition() << 28) |
10611               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10612               (rm.GetCode() << 8));
10613       return;
10614     }
10615   }
10616   Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm);
10617 }
10618 
smultb(Condition cond,Register rd,Register rn,Register rm)10619 void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) {
10620   VIXL_ASSERT(AllowAssembler());
10621   CheckIT(cond);
10622   if (IsUsingT32()) {
10623     // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10624     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10625       EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10626                  rm.GetCode());
10627       AdvanceIT();
10628       return;
10629     }
10630   } else {
10631     // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10632     if (cond.IsNotNever() &&
10633         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10634       EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10635               rn.GetCode() | (rm.GetCode() << 8));
10636       return;
10637     }
10638   }
10639   Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm);
10640 }
10641 
smultt(Condition cond,Register rd,Register rn,Register rm)10642 void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) {
10643   VIXL_ASSERT(AllowAssembler());
10644   CheckIT(cond);
10645   if (IsUsingT32()) {
10646     // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10647     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10648       EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10649                  rm.GetCode());
10650       AdvanceIT();
10651       return;
10652     }
10653   } else {
10654     // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10655     if (cond.IsNotNever() &&
10656         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10657       EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10658               rn.GetCode() | (rm.GetCode() << 8));
10659       return;
10660     }
10661   }
10662   Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm);
10663 }
10664 
smulwb(Condition cond,Register rd,Register rn,Register rm)10665 void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) {
10666   VIXL_ASSERT(AllowAssembler());
10667   CheckIT(cond);
10668   if (IsUsingT32()) {
10669     // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10670     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10671       EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10672                  rm.GetCode());
10673       AdvanceIT();
10674       return;
10675     }
10676   } else {
10677     // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10678     if (cond.IsNotNever() &&
10679         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10680       EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10681               rn.GetCode() | (rm.GetCode() << 8));
10682       return;
10683     }
10684   }
10685   Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm);
10686 }
10687 
smulwt(Condition cond,Register rd,Register rn,Register rm)10688 void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) {
10689   VIXL_ASSERT(AllowAssembler());
10690   CheckIT(cond);
10691   if (IsUsingT32()) {
10692     // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10693     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10694       EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10695                  rm.GetCode());
10696       AdvanceIT();
10697       return;
10698     }
10699   } else {
10700     // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10701     if (cond.IsNotNever() &&
10702         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10703       EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10704               rn.GetCode() | (rm.GetCode() << 8));
10705       return;
10706     }
10707   }
10708   Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm);
10709 }
10710 
smusd(Condition cond,Register rd,Register rn,Register rm)10711 void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) {
10712   VIXL_ASSERT(AllowAssembler());
10713   CheckIT(cond);
10714   if (IsUsingT32()) {
10715     // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10716     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10717       EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10718                  rm.GetCode());
10719       AdvanceIT();
10720       return;
10721     }
10722   } else {
10723     // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10724     if (cond.IsNotNever() &&
10725         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10726       EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10727               rn.GetCode() | (rm.GetCode() << 8));
10728       return;
10729     }
10730   }
10731   Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm);
10732 }
10733 
smusdx(Condition cond,Register rd,Register rn,Register rm)10734 void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) {
10735   VIXL_ASSERT(AllowAssembler());
10736   CheckIT(cond);
10737   if (IsUsingT32()) {
10738     // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10739     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10740       EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10741                  rm.GetCode());
10742       AdvanceIT();
10743       return;
10744     }
10745   } else {
10746     // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10747     if (cond.IsNotNever() &&
10748         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10749       EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10750               rn.GetCode() | (rm.GetCode() << 8));
10751       return;
10752     }
10753   }
10754   Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm);
10755 }
10756 
ssat(Condition cond,Register rd,uint32_t imm,const Operand & operand)10757 void Assembler::ssat(Condition cond,
10758                      Register rd,
10759                      uint32_t imm,
10760                      const Operand& operand) {
10761   VIXL_ASSERT(AllowAssembler());
10762   CheckIT(cond);
10763   if (operand.IsImmediateShiftedRegister()) {
10764     Register rn = operand.GetBaseRegister();
10765     Shift shift = operand.GetShift();
10766     uint32_t amount = operand.GetShiftAmount();
10767     if (IsUsingT32()) {
10768       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
10769       if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
10770           (amount <= 31) &&
10771           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10772         uint32_t imm_ = imm - 1;
10773         EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
10774                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
10775                    ((amount & 0x1c) << 10));
10776         AdvanceIT();
10777         return;
10778       }
10779       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
10780       if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
10781           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10782         uint32_t imm_ = imm - 1;
10783         EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ |
10784                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
10785                    ((amount & 0x1c) << 10));
10786         AdvanceIT();
10787         return;
10788       }
10789     } else {
10790       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
10791       if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
10792           (amount <= 32) && cond.IsNotNever() &&
10793           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10794         uint32_t imm_ = imm - 1;
10795         uint32_t amount_ = amount % 32;
10796         EmitA32(0x06a00050U | (cond.GetCondition() << 28) |
10797                 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
10798                 (amount_ << 7));
10799         return;
10800       }
10801       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
10802       if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
10803           cond.IsNotNever() &&
10804           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10805         uint32_t imm_ = imm - 1;
10806         EmitA32(0x06a00010U | (cond.GetCondition() << 28) |
10807                 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
10808                 (amount << 7));
10809         return;
10810       }
10811     }
10812   }
10813   Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand);
10814 }
10815 
ssat16(Condition cond,Register rd,uint32_t imm,Register rn)10816 void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) {
10817   VIXL_ASSERT(AllowAssembler());
10818   CheckIT(cond);
10819   if (IsUsingT32()) {
10820     // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
10821     if ((imm >= 1) && (imm <= 16) &&
10822         ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10823       uint32_t imm_ = imm - 1;
10824       EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
10825                  (rn.GetCode() << 16));
10826       AdvanceIT();
10827       return;
10828     }
10829   } else {
10830     // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
10831     if ((imm >= 1) && (imm <= 16) && cond.IsNotNever() &&
10832         ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10833       uint32_t imm_ = imm - 1;
10834       EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
10835               (imm_ << 16) | rn.GetCode());
10836       return;
10837     }
10838   }
10839   Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn);
10840 }
10841 
ssax(Condition cond,Register rd,Register rn,Register rm)10842 void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) {
10843   VIXL_ASSERT(AllowAssembler());
10844   CheckIT(cond);
10845   if (IsUsingT32()) {
10846     // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10847     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10848       EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10849                  rm.GetCode());
10850       AdvanceIT();
10851       return;
10852     }
10853   } else {
10854     // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10855     if (cond.IsNotNever() &&
10856         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10857       EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
10858               (rn.GetCode() << 16) | rm.GetCode());
10859       return;
10860     }
10861   }
10862   Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm);
10863 }
10864 
ssub16(Condition cond,Register rd,Register rn,Register rm)10865 void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) {
10866   VIXL_ASSERT(AllowAssembler());
10867   CheckIT(cond);
10868   if (IsUsingT32()) {
10869     // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10870     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10871       EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10872                  rm.GetCode());
10873       AdvanceIT();
10874       return;
10875     }
10876   } else {
10877     // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10878     if (cond.IsNotNever() &&
10879         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10880       EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
10881               (rn.GetCode() << 16) | rm.GetCode());
10882       return;
10883     }
10884   }
10885   Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm);
10886 }
10887 
ssub8(Condition cond,Register rd,Register rn,Register rm)10888 void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) {
10889   VIXL_ASSERT(AllowAssembler());
10890   CheckIT(cond);
10891   if (IsUsingT32()) {
10892     // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10893     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10894       EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10895                  rm.GetCode());
10896       AdvanceIT();
10897       return;
10898     }
10899   } else {
10900     // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10901     if (cond.IsNotNever() &&
10902         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10903       EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
10904               (rn.GetCode() << 16) | rm.GetCode());
10905       return;
10906     }
10907   }
10908   Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm);
10909 }
10910 
stl(Condition cond,Register rt,const MemOperand & operand)10911 void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) {
10912   VIXL_ASSERT(AllowAssembler());
10913   CheckIT(cond);
10914   if (operand.IsImmediateZero()) {
10915     Register rn = operand.GetBaseRegister();
10916     if (IsUsingT32()) {
10917       // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1
10918       if (operand.IsOffset() &&
10919           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10920         EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
10921         AdvanceIT();
10922         return;
10923       }
10924     } else {
10925       // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1
10926       if (operand.IsOffset() && cond.IsNotNever() &&
10927           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10928         EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
10929                 (rn.GetCode() << 16));
10930         return;
10931       }
10932     }
10933   }
10934   Delegate(kStl, &Assembler::stl, cond, rt, operand);
10935 }
10936 
stlb(Condition cond,Register rt,const MemOperand & operand)10937 void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) {
10938   VIXL_ASSERT(AllowAssembler());
10939   CheckIT(cond);
10940   if (operand.IsImmediateZero()) {
10941     Register rn = operand.GetBaseRegister();
10942     if (IsUsingT32()) {
10943       // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1
10944       if (operand.IsOffset() &&
10945           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10946         EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
10947         AdvanceIT();
10948         return;
10949       }
10950     } else {
10951       // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1
10952       if (operand.IsOffset() && cond.IsNotNever() &&
10953           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10954         EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
10955                 (rn.GetCode() << 16));
10956         return;
10957       }
10958     }
10959   }
10960   Delegate(kStlb, &Assembler::stlb, cond, rt, operand);
10961 }
10962 
stlex(Condition cond,Register rd,Register rt,const MemOperand & operand)10963 void Assembler::stlex(Condition cond,
10964                       Register rd,
10965                       Register rt,
10966                       const MemOperand& operand) {
10967   VIXL_ASSERT(AllowAssembler());
10968   CheckIT(cond);
10969   if (operand.IsImmediateZero()) {
10970     Register rn = operand.GetBaseRegister();
10971     if (IsUsingT32()) {
10972       // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10973       if (operand.IsOffset() &&
10974           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10975         EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) |
10976                    (rn.GetCode() << 16));
10977         AdvanceIT();
10978         return;
10979       }
10980     } else {
10981       // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10982       if (operand.IsOffset() && cond.IsNotNever() &&
10983           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10984         EmitA32(0x01800e90U | (cond.GetCondition() << 28) |
10985                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10986         return;
10987       }
10988     }
10989   }
10990   Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand);
10991 }
10992 
stlexb(Condition cond,Register rd,Register rt,const MemOperand & operand)10993 void Assembler::stlexb(Condition cond,
10994                        Register rd,
10995                        Register rt,
10996                        const MemOperand& operand) {
10997   VIXL_ASSERT(AllowAssembler());
10998   CheckIT(cond);
10999   if (operand.IsImmediateZero()) {
11000     Register rn = operand.GetBaseRegister();
11001     if (IsUsingT32()) {
11002       // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
11003       if (operand.IsOffset() &&
11004           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11005         EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) |
11006                    (rn.GetCode() << 16));
11007         AdvanceIT();
11008         return;
11009       }
11010     } else {
11011       // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
11012       if (operand.IsOffset() && cond.IsNotNever() &&
11013           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11014         EmitA32(0x01c00e90U | (cond.GetCondition() << 28) |
11015                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11016         return;
11017       }
11018     }
11019   }
11020   Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand);
11021 }
11022 
stlexd(Condition cond,Register rd,Register rt,Register rt2,const MemOperand & operand)11023 void Assembler::stlexd(Condition cond,
11024                        Register rd,
11025                        Register rt,
11026                        Register rt2,
11027                        const MemOperand& operand) {
11028   VIXL_ASSERT(AllowAssembler());
11029   CheckIT(cond);
11030   if (operand.IsImmediateZero()) {
11031     Register rn = operand.GetBaseRegister();
11032     if (IsUsingT32()) {
11033       // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
11034       if (operand.IsOffset() &&
11035           ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) ||
11036            AllowUnpredictable())) {
11037         EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) |
11038                    (rt2.GetCode() << 8) | (rn.GetCode() << 16));
11039         AdvanceIT();
11040         return;
11041       }
11042     } else {
11043       // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
11044       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11045           operand.IsOffset() && cond.IsNotNever() &&
11046           ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() &&
11047             !rn.IsPC()) ||
11048            AllowUnpredictable())) {
11049         EmitA32(0x01a00e90U | (cond.GetCondition() << 28) |
11050                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11051         return;
11052       }
11053     }
11054   }
11055   Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand);
11056 }
11057 
stlexh(Condition cond,Register rd,Register rt,const MemOperand & operand)11058 void Assembler::stlexh(Condition cond,
11059                        Register rd,
11060                        Register rt,
11061                        const MemOperand& operand) {
11062   VIXL_ASSERT(AllowAssembler());
11063   CheckIT(cond);
11064   if (operand.IsImmediateZero()) {
11065     Register rn = operand.GetBaseRegister();
11066     if (IsUsingT32()) {
11067       // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
11068       if (operand.IsOffset() &&
11069           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11070         EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) |
11071                    (rn.GetCode() << 16));
11072         AdvanceIT();
11073         return;
11074       }
11075     } else {
11076       // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
11077       if (operand.IsOffset() && cond.IsNotNever() &&
11078           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11079         EmitA32(0x01e00e90U | (cond.GetCondition() << 28) |
11080                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11081         return;
11082       }
11083     }
11084   }
11085   Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand);
11086 }
11087 
stlh(Condition cond,Register rt,const MemOperand & operand)11088 void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) {
11089   VIXL_ASSERT(AllowAssembler());
11090   CheckIT(cond);
11091   if (operand.IsImmediateZero()) {
11092     Register rn = operand.GetBaseRegister();
11093     if (IsUsingT32()) {
11094       // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1
11095       if (operand.IsOffset() &&
11096           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11097         EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
11098         AdvanceIT();
11099         return;
11100       }
11101     } else {
11102       // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1
11103       if (operand.IsOffset() && cond.IsNotNever() &&
11104           ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11105         EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
11106                 (rn.GetCode() << 16));
11107         return;
11108       }
11109     }
11110   }
11111   Delegate(kStlh, &Assembler::stlh, cond, rt, operand);
11112 }
11113 
stm(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)11114 void Assembler::stm(Condition cond,
11115                     EncodingSize size,
11116                     Register rn,
11117                     WriteBack write_back,
11118                     RegisterList registers) {
11119   VIXL_ASSERT(AllowAssembler());
11120   CheckIT(cond);
11121   if (IsUsingT32()) {
11122     // STM{<c>}{<q>} <Rn>!, <registers> ; T1
11123     if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
11124         ((registers.GetList() & ~0xff) == 0)) {
11125       EmitT32_16(0xc000 | (rn.GetCode() << 8) |
11126                  GetRegisterListEncoding(registers, 0, 8));
11127       AdvanceIT();
11128       return;
11129     }
11130     // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2
11131     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
11132         (!rn.IsPC() || AllowUnpredictable())) {
11133       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
11134                  (write_back.GetWriteBackUint32() << 21) |
11135                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
11136                  GetRegisterListEncoding(registers, 0, 13));
11137       AdvanceIT();
11138       return;
11139     }
11140   } else {
11141     // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1
11142     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11143       EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11144               (write_back.GetWriteBackUint32() << 21) |
11145               GetRegisterListEncoding(registers, 0, 16));
11146       return;
11147     }
11148   }
11149   Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers);
11150 }
11151 
stmda(Condition cond,Register rn,WriteBack write_back,RegisterList registers)11152 void Assembler::stmda(Condition cond,
11153                       Register rn,
11154                       WriteBack write_back,
11155                       RegisterList registers) {
11156   VIXL_ASSERT(AllowAssembler());
11157   CheckIT(cond);
11158   if (IsUsingA32()) {
11159     // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
11160     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11161       EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11162               (write_back.GetWriteBackUint32() << 21) |
11163               GetRegisterListEncoding(registers, 0, 16));
11164       return;
11165     }
11166   }
11167   Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers);
11168 }
11169 
stmdb(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)11170 void Assembler::stmdb(Condition cond,
11171                       EncodingSize size,
11172                       Register rn,
11173                       WriteBack write_back,
11174                       RegisterList registers) {
11175   VIXL_ASSERT(AllowAssembler());
11176   CheckIT(cond);
11177   if (IsUsingT32()) {
11178     // STMDB{<c>}{<q>} SP!, <registers> ; T1
11179     if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
11180         ((registers.GetList() & ~0x40ff) == 0)) {
11181       EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
11182                  GetRegisterListEncoding(registers, 0, 8));
11183       AdvanceIT();
11184       return;
11185     }
11186     // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
11187     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
11188         (!rn.IsPC() || AllowUnpredictable())) {
11189       EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
11190                  (write_back.GetWriteBackUint32() << 21) |
11191                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
11192                  GetRegisterListEncoding(registers, 0, 13));
11193       AdvanceIT();
11194       return;
11195     }
11196   } else {
11197     // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
11198     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11199       EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11200               (write_back.GetWriteBackUint32() << 21) |
11201               GetRegisterListEncoding(registers, 0, 16));
11202       return;
11203     }
11204   }
11205   Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers);
11206 }
11207 
stmea(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)11208 void Assembler::stmea(Condition cond,
11209                       EncodingSize size,
11210                       Register rn,
11211                       WriteBack write_back,
11212                       RegisterList registers) {
11213   VIXL_ASSERT(AllowAssembler());
11214   CheckIT(cond);
11215   if (IsUsingT32()) {
11216     // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1
11217     if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
11218         ((registers.GetList() & ~0xff) == 0)) {
11219       EmitT32_16(0xc000 | (rn.GetCode() << 8) |
11220                  GetRegisterListEncoding(registers, 0, 8));
11221       AdvanceIT();
11222       return;
11223     }
11224     // STMEA{<c>}.W <Rn>{!}, <registers> ; T2
11225     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
11226         (!rn.IsPC() || AllowUnpredictable())) {
11227       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
11228                  (write_back.GetWriteBackUint32() << 21) |
11229                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
11230                  GetRegisterListEncoding(registers, 0, 13));
11231       AdvanceIT();
11232       return;
11233     }
11234     // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2
11235     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
11236         (!rn.IsPC() || AllowUnpredictable())) {
11237       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
11238                  (write_back.GetWriteBackUint32() << 21) |
11239                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
11240                  GetRegisterListEncoding(registers, 0, 13));
11241       AdvanceIT();
11242       return;
11243     }
11244   } else {
11245     // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
11246     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11247       EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11248               (write_back.GetWriteBackUint32() << 21) |
11249               GetRegisterListEncoding(registers, 0, 16));
11250       return;
11251     }
11252   }
11253   Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers);
11254 }
11255 
stmed(Condition cond,Register rn,WriteBack write_back,RegisterList registers)11256 void Assembler::stmed(Condition cond,
11257                       Register rn,
11258                       WriteBack write_back,
11259                       RegisterList registers) {
11260   VIXL_ASSERT(AllowAssembler());
11261   CheckIT(cond);
11262   if (IsUsingA32()) {
11263     // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
11264     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11265       EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11266               (write_back.GetWriteBackUint32() << 21) |
11267               GetRegisterListEncoding(registers, 0, 16));
11268       return;
11269     }
11270   }
11271   Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers);
11272 }
11273 
stmfa(Condition cond,Register rn,WriteBack write_back,RegisterList registers)11274 void Assembler::stmfa(Condition cond,
11275                       Register rn,
11276                       WriteBack write_back,
11277                       RegisterList registers) {
11278   VIXL_ASSERT(AllowAssembler());
11279   CheckIT(cond);
11280   if (IsUsingA32()) {
11281     // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
11282     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11283       EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11284               (write_back.GetWriteBackUint32() << 21) |
11285               GetRegisterListEncoding(registers, 0, 16));
11286       return;
11287     }
11288   }
11289   Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers);
11290 }
11291 
stmfd(Condition cond,Register rn,WriteBack write_back,RegisterList registers)11292 void Assembler::stmfd(Condition cond,
11293                       Register rn,
11294                       WriteBack write_back,
11295                       RegisterList registers) {
11296   VIXL_ASSERT(AllowAssembler());
11297   CheckIT(cond);
11298   if (IsUsingT32()) {
11299     // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
11300     if (((registers.GetList() & ~0x5fff) == 0) &&
11301         (!rn.IsPC() || AllowUnpredictable())) {
11302       EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
11303                  (write_back.GetWriteBackUint32() << 21) |
11304                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
11305                  GetRegisterListEncoding(registers, 0, 13));
11306       AdvanceIT();
11307       return;
11308     }
11309   } else {
11310     // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
11311     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11312       EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11313               (write_back.GetWriteBackUint32() << 21) |
11314               GetRegisterListEncoding(registers, 0, 16));
11315       return;
11316     }
11317   }
11318   Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers);
11319 }
11320 
stmib(Condition cond,Register rn,WriteBack write_back,RegisterList registers)11321 void Assembler::stmib(Condition cond,
11322                       Register rn,
11323                       WriteBack write_back,
11324                       RegisterList registers) {
11325   VIXL_ASSERT(AllowAssembler());
11326   CheckIT(cond);
11327   if (IsUsingA32()) {
11328     // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
11329     if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11330       EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11331               (write_back.GetWriteBackUint32() << 21) |
11332               GetRegisterListEncoding(registers, 0, 16));
11333       return;
11334     }
11335   }
11336   Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers);
11337 }
11338 
str(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)11339 void Assembler::str(Condition cond,
11340                     EncodingSize size,
11341                     Register rt,
11342                     const MemOperand& operand) {
11343   VIXL_ASSERT(AllowAssembler());
11344   CheckIT(cond);
11345   if (operand.IsImmediate()) {
11346     Register rn = operand.GetBaseRegister();
11347     int32_t offset = operand.GetOffsetImmediate();
11348     if (IsUsingT32()) {
11349       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
11350       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
11351           (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
11352         int32_t offset_ = offset >> 2;
11353         EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) |
11354                    ((offset_ & 0x1f) << 6));
11355         AdvanceIT();
11356         return;
11357       }
11358       // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
11359       if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
11360           ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
11361         int32_t offset_ = offset >> 2;
11362         EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff));
11363         AdvanceIT();
11364         return;
11365       }
11366       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
11367       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
11368           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11369           (!rt.IsPC() || AllowUnpredictable())) {
11370         EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11371                    (offset & 0xfff));
11372         AdvanceIT();
11373         return;
11374       }
11375       // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
11376       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
11377           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11378           (!rt.IsPC() || AllowUnpredictable())) {
11379         EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11380                    (-offset & 0xff));
11381         AdvanceIT();
11382         return;
11383       }
11384       // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
11385       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
11386           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11387           (!rt.IsPC() || AllowUnpredictable())) {
11388         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11389         uint32_t offset_ = abs(offset);
11390         EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11391                    offset_ | (sign << 9));
11392         AdvanceIT();
11393         return;
11394       }
11395       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
11396       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
11397           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11398           (!rt.IsPC() || AllowUnpredictable())) {
11399         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11400         uint32_t offset_ = abs(offset);
11401         EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11402                    offset_ | (sign << 9));
11403         AdvanceIT();
11404         return;
11405       }
11406     } else {
11407       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
11408       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
11409           cond.IsNotNever()) {
11410         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11411         uint32_t offset_ = abs(offset);
11412         EmitA32(0x05000000U | (cond.GetCondition() << 28) |
11413                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11414                 (sign << 23));
11415         return;
11416       }
11417       // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
11418       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
11419           cond.IsNotNever()) {
11420         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11421         uint32_t offset_ = abs(offset);
11422         EmitA32(0x04000000U | (cond.GetCondition() << 28) |
11423                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11424                 (sign << 23));
11425         return;
11426       }
11427       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
11428       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
11429           cond.IsNotNever()) {
11430         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11431         uint32_t offset_ = abs(offset);
11432         EmitA32(0x05200000U | (cond.GetCondition() << 28) |
11433                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11434                 (sign << 23));
11435         return;
11436       }
11437     }
11438   }
11439   if (operand.IsPlainRegister()) {
11440     Register rn = operand.GetBaseRegister();
11441     Sign sign = operand.GetSign();
11442     Register rm = operand.GetOffsetRegister();
11443     if (IsUsingT32()) {
11444       // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
11445       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
11446           sign.IsPlus() && operand.IsOffset()) {
11447         EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) |
11448                    (rm.GetCode() << 6));
11449         AdvanceIT();
11450         return;
11451       }
11452     }
11453   }
11454   if (operand.IsShiftedRegister()) {
11455     Register rn = operand.GetBaseRegister();
11456     Sign sign = operand.GetSign();
11457     Register rm = operand.GetOffsetRegister();
11458     Shift shift = operand.GetShift();
11459     uint32_t amount = operand.GetShiftAmount();
11460     if (IsUsingT32()) {
11461       // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
11462       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
11463           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11464           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
11465         EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11466                    rm.GetCode() | (amount << 4));
11467         AdvanceIT();
11468         return;
11469       }
11470     } else {
11471       // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
11472       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
11473           (!rm.IsPC() || AllowUnpredictable())) {
11474         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11475         uint32_t shift_ = TypeEncodingValue(shift);
11476         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11477         EmitA32(0x07000000U | (cond.GetCondition() << 28) |
11478                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11479                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11480         return;
11481       }
11482       // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
11483       if (operand.IsShiftValid() && operand.IsPostIndex() &&
11484           cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
11485         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11486         uint32_t shift_ = TypeEncodingValue(shift);
11487         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11488         EmitA32(0x06000000U | (cond.GetCondition() << 28) |
11489                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11490                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11491         return;
11492       }
11493       // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
11494       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
11495           (!rm.IsPC() || AllowUnpredictable())) {
11496         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11497         uint32_t shift_ = TypeEncodingValue(shift);
11498         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11499         EmitA32(0x07200000U | (cond.GetCondition() << 28) |
11500                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11501                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11502         return;
11503       }
11504     }
11505   }
11506   Delegate(kStr, &Assembler::str, cond, size, rt, operand);
11507 }
11508 
strb(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)11509 void Assembler::strb(Condition cond,
11510                      EncodingSize size,
11511                      Register rt,
11512                      const MemOperand& operand) {
11513   VIXL_ASSERT(AllowAssembler());
11514   CheckIT(cond);
11515   if (operand.IsImmediate()) {
11516     Register rn = operand.GetBaseRegister();
11517     int32_t offset = operand.GetOffsetImmediate();
11518     if (IsUsingT32()) {
11519       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
11520       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
11521           (offset <= 31) && operand.IsOffset()) {
11522         EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) |
11523                    ((offset & 0x1f) << 6));
11524         AdvanceIT();
11525         return;
11526       }
11527       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
11528       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
11529           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11530           (!rt.IsPC() || AllowUnpredictable())) {
11531         EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11532                    (offset & 0xfff));
11533         AdvanceIT();
11534         return;
11535       }
11536       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
11537       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
11538           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11539           (!rt.IsPC() || AllowUnpredictable())) {
11540         EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11541                    (-offset & 0xff));
11542         AdvanceIT();
11543         return;
11544       }
11545       // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
11546       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
11547           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11548           (!rt.IsPC() || AllowUnpredictable())) {
11549         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11550         uint32_t offset_ = abs(offset);
11551         EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11552                    offset_ | (sign << 9));
11553         AdvanceIT();
11554         return;
11555       }
11556       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
11557       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
11558           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11559           (!rt.IsPC() || AllowUnpredictable())) {
11560         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11561         uint32_t offset_ = abs(offset);
11562         EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11563                    offset_ | (sign << 9));
11564         AdvanceIT();
11565         return;
11566       }
11567     } else {
11568       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
11569       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
11570           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
11571         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11572         uint32_t offset_ = abs(offset);
11573         EmitA32(0x05400000U | (cond.GetCondition() << 28) |
11574                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11575                 (sign << 23));
11576         return;
11577       }
11578       // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
11579       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
11580           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
11581         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11582         uint32_t offset_ = abs(offset);
11583         EmitA32(0x04400000U | (cond.GetCondition() << 28) |
11584                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11585                 (sign << 23));
11586         return;
11587       }
11588       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
11589       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
11590           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
11591         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11592         uint32_t offset_ = abs(offset);
11593         EmitA32(0x05600000U | (cond.GetCondition() << 28) |
11594                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11595                 (sign << 23));
11596         return;
11597       }
11598     }
11599   }
11600   if (operand.IsPlainRegister()) {
11601     Register rn = operand.GetBaseRegister();
11602     Sign sign = operand.GetSign();
11603     Register rm = operand.GetOffsetRegister();
11604     if (IsUsingT32()) {
11605       // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
11606       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
11607           sign.IsPlus() && operand.IsOffset()) {
11608         EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) |
11609                    (rm.GetCode() << 6));
11610         AdvanceIT();
11611         return;
11612       }
11613     }
11614   }
11615   if (operand.IsShiftedRegister()) {
11616     Register rn = operand.GetBaseRegister();
11617     Sign sign = operand.GetSign();
11618     Register rm = operand.GetOffsetRegister();
11619     Shift shift = operand.GetShift();
11620     uint32_t amount = operand.GetShiftAmount();
11621     if (IsUsingT32()) {
11622       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
11623       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
11624           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11625           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
11626         EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11627                    rm.GetCode() | (amount << 4));
11628         AdvanceIT();
11629         return;
11630       }
11631     } else {
11632       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
11633       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
11634           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
11635         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11636         uint32_t shift_ = TypeEncodingValue(shift);
11637         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11638         EmitA32(0x07400000U | (cond.GetCondition() << 28) |
11639                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11640                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11641         return;
11642       }
11643       // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
11644       if (operand.IsShiftValid() && operand.IsPostIndex() &&
11645           cond.IsNotNever() &&
11646           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
11647         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11648         uint32_t shift_ = TypeEncodingValue(shift);
11649         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11650         EmitA32(0x06400000U | (cond.GetCondition() << 28) |
11651                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11652                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11653         return;
11654       }
11655       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
11656       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
11657           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
11658         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11659         uint32_t shift_ = TypeEncodingValue(shift);
11660         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11661         EmitA32(0x07600000U | (cond.GetCondition() << 28) |
11662                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11663                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11664         return;
11665       }
11666     }
11667   }
11668   Delegate(kStrb, &Assembler::strb, cond, size, rt, operand);
11669 }
11670 
strd(Condition cond,Register rt,Register rt2,const MemOperand & operand)11671 void Assembler::strd(Condition cond,
11672                      Register rt,
11673                      Register rt2,
11674                      const MemOperand& operand) {
11675   VIXL_ASSERT(AllowAssembler());
11676   CheckIT(cond);
11677   if (operand.IsImmediate()) {
11678     Register rn = operand.GetBaseRegister();
11679     int32_t offset = operand.GetOffsetImmediate();
11680     if (IsUsingT32()) {
11681       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
11682       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
11683           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11684           ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
11685         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11686         uint32_t offset_ = abs(offset) >> 2;
11687         EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
11688                    (rn.GetCode() << 16) | offset_ | (sign << 23));
11689         AdvanceIT();
11690         return;
11691       }
11692       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
11693       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
11694           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11695           ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
11696         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11697         uint32_t offset_ = abs(offset) >> 2;
11698         EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
11699                    (rn.GetCode() << 16) | offset_ | (sign << 23));
11700         AdvanceIT();
11701         return;
11702       }
11703       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
11704       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
11705           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11706           ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
11707         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11708         uint32_t offset_ = abs(offset) >> 2;
11709         EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
11710                    (rn.GetCode() << 16) | offset_ | (sign << 23));
11711         AdvanceIT();
11712         return;
11713       }
11714     } else {
11715       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
11716       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11717           (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
11718           cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
11719                                 AllowUnpredictable())) {
11720         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11721         uint32_t offset_ = abs(offset);
11722         EmitA32(0x014000f0U | (cond.GetCondition() << 28) |
11723                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
11724                 ((offset_ & 0xf0) << 4) | (sign << 23));
11725         return;
11726       }
11727       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
11728       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11729           (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
11730           cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
11731                                 AllowUnpredictable())) {
11732         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11733         uint32_t offset_ = abs(offset);
11734         EmitA32(0x004000f0U | (cond.GetCondition() << 28) |
11735                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
11736                 ((offset_ & 0xf0) << 4) | (sign << 23));
11737         return;
11738       }
11739       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
11740       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11741           (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
11742           cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
11743                                 AllowUnpredictable())) {
11744         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11745         uint32_t offset_ = abs(offset);
11746         EmitA32(0x016000f0U | (cond.GetCondition() << 28) |
11747                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
11748                 ((offset_ & 0xf0) << 4) | (sign << 23));
11749         return;
11750       }
11751     }
11752   }
11753   if (operand.IsPlainRegister()) {
11754     Register rn = operand.GetBaseRegister();
11755     Sign sign = operand.GetSign();
11756     Register rm = operand.GetOffsetRegister();
11757     if (IsUsingA32()) {
11758       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
11759       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11760           operand.IsOffset() && cond.IsNotNever() &&
11761           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
11762            AllowUnpredictable())) {
11763         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11764         EmitA32(0x010000f0U | (cond.GetCondition() << 28) |
11765                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11766                 (sign_ << 23));
11767         return;
11768       }
11769       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
11770       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11771           operand.IsPostIndex() && cond.IsNotNever() &&
11772           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
11773            AllowUnpredictable())) {
11774         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11775         EmitA32(0x000000f0U | (cond.GetCondition() << 28) |
11776                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11777                 (sign_ << 23));
11778         return;
11779       }
11780       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
11781       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11782           operand.IsPreIndex() && cond.IsNotNever() &&
11783           ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
11784            AllowUnpredictable())) {
11785         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11786         EmitA32(0x012000f0U | (cond.GetCondition() << 28) |
11787                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11788                 (sign_ << 23));
11789         return;
11790       }
11791     }
11792   }
11793   Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand);
11794 }
11795 
strex(Condition cond,Register rd,Register rt,const MemOperand & operand)11796 void Assembler::strex(Condition cond,
11797                       Register rd,
11798                       Register rt,
11799                       const MemOperand& operand) {
11800   VIXL_ASSERT(AllowAssembler());
11801   CheckIT(cond);
11802   if (operand.IsImmediate()) {
11803     Register rn = operand.GetBaseRegister();
11804     int32_t offset = operand.GetOffsetImmediate();
11805     if (IsUsingT32()) {
11806       // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1
11807       if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
11808           operand.IsOffset() &&
11809           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11810         int32_t offset_ = offset >> 2;
11811         EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) |
11812                    (rn.GetCode() << 16) | (offset_ & 0xff));
11813         AdvanceIT();
11814         return;
11815       }
11816     } else {
11817       // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1
11818       if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() &&
11819           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11820         EmitA32(0x01800f90U | (cond.GetCondition() << 28) |
11821                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11822         return;
11823       }
11824     }
11825   }
11826   Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand);
11827 }
11828 
strexb(Condition cond,Register rd,Register rt,const MemOperand & operand)11829 void Assembler::strexb(Condition cond,
11830                        Register rd,
11831                        Register rt,
11832                        const MemOperand& operand) {
11833   VIXL_ASSERT(AllowAssembler());
11834   CheckIT(cond);
11835   if (operand.IsImmediateZero()) {
11836     Register rn = operand.GetBaseRegister();
11837     if (IsUsingT32()) {
11838       // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
11839       if (operand.IsOffset() &&
11840           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11841         EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) |
11842                    (rn.GetCode() << 16));
11843         AdvanceIT();
11844         return;
11845       }
11846     } else {
11847       // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
11848       if (operand.IsOffset() && cond.IsNotNever() &&
11849           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11850         EmitA32(0x01c00f90U | (cond.GetCondition() << 28) |
11851                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11852         return;
11853       }
11854     }
11855   }
11856   Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand);
11857 }
11858 
strexd(Condition cond,Register rd,Register rt,Register rt2,const MemOperand & operand)11859 void Assembler::strexd(Condition cond,
11860                        Register rd,
11861                        Register rt,
11862                        Register rt2,
11863                        const MemOperand& operand) {
11864   VIXL_ASSERT(AllowAssembler());
11865   CheckIT(cond);
11866   if (operand.IsImmediateZero()) {
11867     Register rn = operand.GetBaseRegister();
11868     if (IsUsingT32()) {
11869       // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
11870       if (operand.IsOffset() &&
11871           ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) ||
11872            AllowUnpredictable())) {
11873         EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) |
11874                    (rt2.GetCode() << 8) | (rn.GetCode() << 16));
11875         AdvanceIT();
11876         return;
11877       }
11878     } else {
11879       // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
11880       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11881           operand.IsOffset() && cond.IsNotNever() &&
11882           ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() &&
11883             !rn.IsPC()) ||
11884            AllowUnpredictable())) {
11885         EmitA32(0x01a00f90U | (cond.GetCondition() << 28) |
11886                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11887         return;
11888       }
11889     }
11890   }
11891   Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand);
11892 }
11893 
strexh(Condition cond,Register rd,Register rt,const MemOperand & operand)11894 void Assembler::strexh(Condition cond,
11895                        Register rd,
11896                        Register rt,
11897                        const MemOperand& operand) {
11898   VIXL_ASSERT(AllowAssembler());
11899   CheckIT(cond);
11900   if (operand.IsImmediateZero()) {
11901     Register rn = operand.GetBaseRegister();
11902     if (IsUsingT32()) {
11903       // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
11904       if (operand.IsOffset() &&
11905           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11906         EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) |
11907                    (rn.GetCode() << 16));
11908         AdvanceIT();
11909         return;
11910       }
11911     } else {
11912       // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
11913       if (operand.IsOffset() && cond.IsNotNever() &&
11914           ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11915         EmitA32(0x01e00f90U | (cond.GetCondition() << 28) |
11916                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11917         return;
11918       }
11919     }
11920   }
11921   Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand);
11922 }
11923 
strh(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)11924 void Assembler::strh(Condition cond,
11925                      EncodingSize size,
11926                      Register rt,
11927                      const MemOperand& operand) {
11928   VIXL_ASSERT(AllowAssembler());
11929   CheckIT(cond);
11930   if (operand.IsImmediate()) {
11931     Register rn = operand.GetBaseRegister();
11932     int32_t offset = operand.GetOffsetImmediate();
11933     if (IsUsingT32()) {
11934       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
11935       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
11936           (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
11937         int32_t offset_ = offset >> 1;
11938         EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) |
11939                    ((offset_ & 0x1f) << 6));
11940         AdvanceIT();
11941         return;
11942       }
11943       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
11944       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
11945           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11946           (!rt.IsPC() || AllowUnpredictable())) {
11947         EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11948                    (offset & 0xfff));
11949         AdvanceIT();
11950         return;
11951       }
11952       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
11953       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
11954           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11955           (!rt.IsPC() || AllowUnpredictable())) {
11956         EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11957                    (-offset & 0xff));
11958         AdvanceIT();
11959         return;
11960       }
11961       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
11962       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
11963           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11964           (!rt.IsPC() || AllowUnpredictable())) {
11965         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11966         uint32_t offset_ = abs(offset);
11967         EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11968                    offset_ | (sign << 9));
11969         AdvanceIT();
11970         return;
11971       }
11972       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
11973       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
11974           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11975           (!rt.IsPC() || AllowUnpredictable())) {
11976         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11977         uint32_t offset_ = abs(offset);
11978         EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11979                    offset_ | (sign << 9));
11980         AdvanceIT();
11981         return;
11982       }
11983     } else {
11984       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
11985       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
11986           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
11987         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11988         uint32_t offset_ = abs(offset);
11989         EmitA32(0x014000b0U | (cond.GetCondition() << 28) |
11990                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
11991                 ((offset_ & 0xf0) << 4) | (sign << 23));
11992         return;
11993       }
11994       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
11995       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
11996           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
11997         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11998         uint32_t offset_ = abs(offset);
11999         EmitA32(0x004000b0U | (cond.GetCondition() << 28) |
12000                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
12001                 ((offset_ & 0xf0) << 4) | (sign << 23));
12002         return;
12003       }
12004       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
12005       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
12006           cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
12007         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
12008         uint32_t offset_ = abs(offset);
12009         EmitA32(0x016000b0U | (cond.GetCondition() << 28) |
12010                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
12011                 ((offset_ & 0xf0) << 4) | (sign << 23));
12012         return;
12013       }
12014     }
12015   }
12016   if (operand.IsPlainRegister()) {
12017     Register rn = operand.GetBaseRegister();
12018     Sign sign = operand.GetSign();
12019     Register rm = operand.GetOffsetRegister();
12020     if (IsUsingT32()) {
12021       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
12022       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
12023           sign.IsPlus() && operand.IsOffset()) {
12024         EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) |
12025                    (rm.GetCode() << 6));
12026         AdvanceIT();
12027         return;
12028       }
12029     } else {
12030       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
12031       if (operand.IsOffset() && cond.IsNotNever() &&
12032           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12033         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
12034         EmitA32(0x010000b0U | (cond.GetCondition() << 28) |
12035                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12036                 (sign_ << 23));
12037         return;
12038       }
12039       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
12040       if (operand.IsPostIndex() && cond.IsNotNever() &&
12041           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12042         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
12043         EmitA32(0x000000b0U | (cond.GetCondition() << 28) |
12044                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12045                 (sign_ << 23));
12046         return;
12047       }
12048       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
12049       if (operand.IsPreIndex() && cond.IsNotNever() &&
12050           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12051         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
12052         EmitA32(0x012000b0U | (cond.GetCondition() << 28) |
12053                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12054                 (sign_ << 23));
12055         return;
12056       }
12057     }
12058   }
12059   if (operand.IsShiftedRegister()) {
12060     Register rn = operand.GetBaseRegister();
12061     Sign sign = operand.GetSign();
12062     Register rm = operand.GetOffsetRegister();
12063     Shift shift = operand.GetShift();
12064     uint32_t amount = operand.GetShiftAmount();
12065     if (IsUsingT32()) {
12066       // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
12067       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
12068           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
12069           ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12070         EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
12071                    rm.GetCode() | (amount << 4));
12072         AdvanceIT();
12073         return;
12074       }
12075     }
12076   }
12077   Delegate(kStrh, &Assembler::strh, cond, size, rt, operand);
12078 }
12079 
sub(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)12080 void Assembler::sub(Condition cond,
12081                     EncodingSize size,
12082                     Register rd,
12083                     Register rn,
12084                     const Operand& operand) {
12085   VIXL_ASSERT(AllowAssembler());
12086   CheckIT(cond);
12087   if (operand.IsImmediate()) {
12088     uint32_t imm = operand.GetImmediate();
12089     if (IsUsingT32()) {
12090       ImmediateT32 immediate_t32(imm);
12091       // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
12092       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
12093           (imm <= 7)) {
12094         EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
12095         AdvanceIT();
12096         return;
12097       }
12098       // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
12099       if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
12100           (imm <= 255)) {
12101         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
12102         AdvanceIT();
12103         return;
12104       }
12105       // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1
12106       if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
12107           ((imm % 4) == 0)) {
12108         uint32_t imm_ = imm >> 2;
12109         EmitT32_16(0xb080 | imm_);
12110         AdvanceIT();
12111         return;
12112       }
12113       // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2
12114       if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
12115           (!rd.IsPC() || AllowUnpredictable())) {
12116         EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) |
12117                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
12118         AdvanceIT();
12119         return;
12120       }
12121       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
12122       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
12123           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
12124         EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12125                    (immediate_t32.GetEncodingValue() & 0xff) |
12126                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12127                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12128         AdvanceIT();
12129         return;
12130       }
12131       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
12132       if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
12133           (!rd.IsPC() || AllowUnpredictable())) {
12134         EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12135                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
12136         AdvanceIT();
12137         return;
12138       }
12139       // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
12140       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
12141           (!rd.IsPC() || AllowUnpredictable())) {
12142         EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) |
12143                    (immediate_t32.GetEncodingValue() & 0xff) |
12144                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12145                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12146         AdvanceIT();
12147         return;
12148       }
12149       // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
12150       if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
12151           (!rd.IsPC() || AllowUnpredictable())) {
12152         EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
12153                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
12154         AdvanceIT();
12155         return;
12156       }
12157     } else {
12158       ImmediateA32 immediate_a32(imm);
12159       // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2
12160       if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
12161         EmitA32(0x024f0000U | (cond.GetCondition() << 28) |
12162                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
12163         return;
12164       }
12165       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
12166       if (immediate_a32.IsValid() && cond.IsNotNever() &&
12167           ((rn.GetCode() & 0xd) != 0xd)) {
12168         EmitA32(0x02400000U | (cond.GetCondition() << 28) |
12169                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
12170                 immediate_a32.GetEncodingValue());
12171         return;
12172       }
12173       // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
12174       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
12175         EmitA32(0x024d0000U | (cond.GetCondition() << 28) |
12176                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
12177         return;
12178       }
12179     }
12180   }
12181   if (operand.IsImmediateShiftedRegister()) {
12182     Register rm = operand.GetBaseRegister();
12183     if (operand.IsPlainRegister()) {
12184       if (IsUsingT32()) {
12185         // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
12186         if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
12187             rm.IsLow()) {
12188           EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
12189                      (rm.GetCode() << 6));
12190           AdvanceIT();
12191           return;
12192         }
12193         // SUB{<c>} {<Rd>}, SP, <Rm> ; T1
12194         if (rn.Is(sp) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12195           EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode());
12196           AdvanceIT();
12197           return;
12198         }
12199       }
12200     }
12201     Shift shift = operand.GetShift();
12202     uint32_t amount = operand.GetShiftAmount();
12203     if (IsUsingT32()) {
12204       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
12205       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
12206           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12207         uint32_t amount_ = amount % 32;
12208         EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12209                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
12210                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12211         AdvanceIT();
12212         return;
12213       }
12214       // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
12215       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
12216           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12217         uint32_t amount_ = amount % 32;
12218         EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() |
12219                    (operand.GetTypeEncodingValue() << 4) |
12220                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12221         AdvanceIT();
12222         return;
12223       }
12224     } else {
12225       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
12226       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
12227         uint32_t amount_ = amount % 32;
12228         EmitA32(0x00400000U | (cond.GetCondition() << 28) |
12229                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12230                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12231         return;
12232       }
12233       // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
12234       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
12235         uint32_t amount_ = amount % 32;
12236         EmitA32(0x004d0000U | (cond.GetCondition() << 28) |
12237                 (rd.GetCode() << 12) | rm.GetCode() |
12238                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12239         return;
12240       }
12241     }
12242   }
12243   if (operand.IsRegisterShiftedRegister()) {
12244     Register rm = operand.GetBaseRegister();
12245     Shift shift = operand.GetShift();
12246     Register rs = operand.GetShiftRegister();
12247     if (IsUsingA32()) {
12248       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
12249       if (cond.IsNotNever() &&
12250           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
12251            AllowUnpredictable())) {
12252         EmitA32(0x00400010U | (cond.GetCondition() << 28) |
12253                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12254                 (shift.GetType() << 5) | (rs.GetCode() << 8));
12255         return;
12256       }
12257     }
12258   }
12259   Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand);
12260 }
12261 
sub(Condition cond,Register rd,const Operand & operand)12262 void Assembler::sub(Condition cond, Register rd, const Operand& operand) {
12263   VIXL_ASSERT(AllowAssembler());
12264   CheckIT(cond);
12265   if (operand.IsImmediate()) {
12266     uint32_t imm = operand.GetImmediate();
12267     if (IsUsingT32()) {
12268       // SUB<c>{<q>} <Rdn>, #<imm8> ; T2
12269       if (InITBlock() && rd.IsLow() && (imm <= 255)) {
12270         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
12271         AdvanceIT();
12272         return;
12273       }
12274     }
12275   }
12276   Delegate(kSub, &Assembler::sub, cond, rd, operand);
12277 }
12278 
subs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)12279 void Assembler::subs(Condition cond,
12280                      EncodingSize size,
12281                      Register rd,
12282                      Register rn,
12283                      const Operand& operand) {
12284   VIXL_ASSERT(AllowAssembler());
12285   CheckIT(cond);
12286   if (operand.IsImmediate()) {
12287     uint32_t imm = operand.GetImmediate();
12288     if (IsUsingT32()) {
12289       ImmediateT32 immediate_t32(imm);
12290       // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1
12291       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
12292           (imm <= 7)) {
12293         EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
12294         AdvanceIT();
12295         return;
12296       }
12297       // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
12298       if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
12299           (imm <= 255)) {
12300         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
12301         AdvanceIT();
12302         return;
12303       }
12304       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
12305       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
12306           !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) {
12307         EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12308                    (immediate_t32.GetEncodingValue() & 0xff) |
12309                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12310                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12311         AdvanceIT();
12312         return;
12313       }
12314       // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5
12315       if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255) &&
12316           (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
12317         EmitT32_32(0xf3de8f00U | imm);
12318         AdvanceIT();
12319         return;
12320       }
12321       // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
12322       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
12323           !rd.Is(pc)) {
12324         EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) |
12325                    (immediate_t32.GetEncodingValue() & 0xff) |
12326                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12327                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12328         AdvanceIT();
12329         return;
12330       }
12331     } else {
12332       ImmediateA32 immediate_a32(imm);
12333       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
12334       if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
12335         EmitA32(0x02500000U | (cond.GetCondition() << 28) |
12336                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
12337                 immediate_a32.GetEncodingValue());
12338         return;
12339       }
12340       // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
12341       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
12342         EmitA32(0x025d0000U | (cond.GetCondition() << 28) |
12343                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
12344         return;
12345       }
12346     }
12347   }
12348   if (operand.IsImmediateShiftedRegister()) {
12349     Register rm = operand.GetBaseRegister();
12350     if (operand.IsPlainRegister()) {
12351       if (IsUsingT32()) {
12352         // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12353         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
12354             rm.IsLow()) {
12355           EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
12356                      (rm.GetCode() << 6));
12357           AdvanceIT();
12358           return;
12359         }
12360       }
12361     }
12362     Shift shift = operand.GetShift();
12363     uint32_t amount = operand.GetShiftAmount();
12364     if (IsUsingT32()) {
12365       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
12366       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
12367           !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12368         uint32_t amount_ = amount % 32;
12369         EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12370                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
12371                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12372         AdvanceIT();
12373         return;
12374       }
12375       // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
12376       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
12377           !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) {
12378         uint32_t amount_ = amount % 32;
12379         EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() |
12380                    (operand.GetTypeEncodingValue() << 4) |
12381                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12382         AdvanceIT();
12383         return;
12384       }
12385     } else {
12386       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
12387       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
12388         uint32_t amount_ = amount % 32;
12389         EmitA32(0x00500000U | (cond.GetCondition() << 28) |
12390                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12391                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12392         return;
12393       }
12394       // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
12395       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
12396         uint32_t amount_ = amount % 32;
12397         EmitA32(0x005d0000U | (cond.GetCondition() << 28) |
12398                 (rd.GetCode() << 12) | rm.GetCode() |
12399                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12400         return;
12401       }
12402     }
12403   }
12404   if (operand.IsRegisterShiftedRegister()) {
12405     Register rm = operand.GetBaseRegister();
12406     Shift shift = operand.GetShift();
12407     Register rs = operand.GetShiftRegister();
12408     if (IsUsingA32()) {
12409       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
12410       if (cond.IsNotNever() &&
12411           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
12412            AllowUnpredictable())) {
12413         EmitA32(0x00500010U | (cond.GetCondition() << 28) |
12414                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12415                 (shift.GetType() << 5) | (rs.GetCode() << 8));
12416         return;
12417       }
12418     }
12419   }
12420   Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand);
12421 }
12422 
subs(Register rd,const Operand & operand)12423 void Assembler::subs(Register rd, const Operand& operand) {
12424   VIXL_ASSERT(AllowAssembler());
12425   CheckIT(al);
12426   if (operand.IsImmediate()) {
12427     uint32_t imm = operand.GetImmediate();
12428     if (IsUsingT32()) {
12429       // SUBS{<q>} <Rdn>, #<imm8> ; T2
12430       if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
12431         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
12432         AdvanceIT();
12433         return;
12434       }
12435     }
12436   }
12437   Delegate(kSubs, &Assembler::subs, rd, operand);
12438 }
12439 
subw(Condition cond,Register rd,Register rn,const Operand & operand)12440 void Assembler::subw(Condition cond,
12441                      Register rd,
12442                      Register rn,
12443                      const Operand& operand) {
12444   VIXL_ASSERT(AllowAssembler());
12445   CheckIT(cond);
12446   if (operand.IsImmediate()) {
12447     uint32_t imm = operand.GetImmediate();
12448     if (IsUsingT32()) {
12449       // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
12450       if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
12451           (!rd.IsPC() || AllowUnpredictable())) {
12452         EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12453                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
12454         AdvanceIT();
12455         return;
12456       }
12457       // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
12458       if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
12459         EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
12460                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
12461         AdvanceIT();
12462         return;
12463       }
12464     }
12465   }
12466   Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand);
12467 }
12468 
svc(Condition cond,uint32_t imm)12469 void Assembler::svc(Condition cond, uint32_t imm) {
12470   VIXL_ASSERT(AllowAssembler());
12471   CheckIT(cond);
12472   if (IsUsingT32()) {
12473     // SVC{<c>}{<q>} {#}<imm> ; T1
12474     if ((imm <= 255)) {
12475       EmitT32_16(0xdf00 | imm);
12476       AdvanceIT();
12477       return;
12478     }
12479   } else {
12480     // SVC{<c>}{<q>} {#}<imm> ; A1
12481     if ((imm <= 16777215) && cond.IsNotNever()) {
12482       EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm);
12483       return;
12484     }
12485   }
12486   Delegate(kSvc, &Assembler::svc, cond, imm);
12487 }
12488 
sxtab(Condition cond,Register rd,Register rn,const Operand & operand)12489 void Assembler::sxtab(Condition cond,
12490                       Register rd,
12491                       Register rn,
12492                       const Operand& operand) {
12493   VIXL_ASSERT(AllowAssembler());
12494   CheckIT(cond);
12495   if (operand.IsImmediateShiftedRegister()) {
12496     Register rm = operand.GetBaseRegister();
12497     Shift shift = operand.GetShift();
12498     uint32_t amount = operand.GetShiftAmount();
12499     if (IsUsingT32()) {
12500       // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12501       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12502           ((amount % 8) == 0) && !rn.Is(pc) &&
12503           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12504         uint32_t amount_ = amount / 8;
12505         EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12506                    rm.GetCode() | (amount_ << 4));
12507         AdvanceIT();
12508         return;
12509       }
12510     } else {
12511       // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12512       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12513           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
12514           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12515         uint32_t amount_ = amount / 8;
12516         EmitA32(0x06a00070U | (cond.GetCondition() << 28) |
12517                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12518                 (amount_ << 10));
12519         return;
12520       }
12521     }
12522   }
12523   Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand);
12524 }
12525 
sxtab16(Condition cond,Register rd,Register rn,const Operand & operand)12526 void Assembler::sxtab16(Condition cond,
12527                         Register rd,
12528                         Register rn,
12529                         const Operand& operand) {
12530   VIXL_ASSERT(AllowAssembler());
12531   CheckIT(cond);
12532   if (operand.IsImmediateShiftedRegister()) {
12533     Register rm = operand.GetBaseRegister();
12534     Shift shift = operand.GetShift();
12535     uint32_t amount = operand.GetShiftAmount();
12536     if (IsUsingT32()) {
12537       // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12538       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12539           ((amount % 8) == 0) && !rn.Is(pc) &&
12540           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12541         uint32_t amount_ = amount / 8;
12542         EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12543                    rm.GetCode() | (amount_ << 4));
12544         AdvanceIT();
12545         return;
12546       }
12547     } else {
12548       // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12549       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12550           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
12551           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12552         uint32_t amount_ = amount / 8;
12553         EmitA32(0x06800070U | (cond.GetCondition() << 28) |
12554                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12555                 (amount_ << 10));
12556         return;
12557       }
12558     }
12559   }
12560   Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand);
12561 }
12562 
sxtah(Condition cond,Register rd,Register rn,const Operand & operand)12563 void Assembler::sxtah(Condition cond,
12564                       Register rd,
12565                       Register rn,
12566                       const Operand& operand) {
12567   VIXL_ASSERT(AllowAssembler());
12568   CheckIT(cond);
12569   if (operand.IsImmediateShiftedRegister()) {
12570     Register rm = operand.GetBaseRegister();
12571     Shift shift = operand.GetShift();
12572     uint32_t amount = operand.GetShiftAmount();
12573     if (IsUsingT32()) {
12574       // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12575       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12576           ((amount % 8) == 0) && !rn.Is(pc) &&
12577           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12578         uint32_t amount_ = amount / 8;
12579         EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12580                    rm.GetCode() | (amount_ << 4));
12581         AdvanceIT();
12582         return;
12583       }
12584     } else {
12585       // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12586       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12587           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
12588           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12589         uint32_t amount_ = amount / 8;
12590         EmitA32(0x06b00070U | (cond.GetCondition() << 28) |
12591                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12592                 (amount_ << 10));
12593         return;
12594       }
12595     }
12596   }
12597   Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand);
12598 }
12599 
sxtb(Condition cond,EncodingSize size,Register rd,const Operand & operand)12600 void Assembler::sxtb(Condition cond,
12601                      EncodingSize size,
12602                      Register rd,
12603                      const Operand& operand) {
12604   VIXL_ASSERT(AllowAssembler());
12605   CheckIT(cond);
12606   if (operand.IsImmediateShiftedRegister()) {
12607     Register rm = operand.GetBaseRegister();
12608     if (operand.IsPlainRegister()) {
12609       if (IsUsingT32()) {
12610         // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
12611         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12612           EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3));
12613           AdvanceIT();
12614           return;
12615         }
12616       }
12617     }
12618     Shift shift = operand.GetShift();
12619     uint32_t amount = operand.GetShiftAmount();
12620     if (IsUsingT32()) {
12621       // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12622       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12623           (amount <= 24) && ((amount % 8) == 0) &&
12624           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12625         uint32_t amount_ = amount / 8;
12626         EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12627                    (amount_ << 4));
12628         AdvanceIT();
12629         return;
12630       }
12631     } else {
12632       // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12633       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12634           ((amount % 8) == 0) && cond.IsNotNever() &&
12635           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12636         uint32_t amount_ = amount / 8;
12637         EmitA32(0x06af0070U | (cond.GetCondition() << 28) |
12638                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12639         return;
12640       }
12641     }
12642   }
12643   Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand);
12644 }
12645 
sxtb16(Condition cond,Register rd,const Operand & operand)12646 void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) {
12647   VIXL_ASSERT(AllowAssembler());
12648   CheckIT(cond);
12649   if (operand.IsImmediateShiftedRegister()) {
12650     Register rm = operand.GetBaseRegister();
12651     Shift shift = operand.GetShift();
12652     uint32_t amount = operand.GetShiftAmount();
12653     if (IsUsingT32()) {
12654       // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
12655       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12656           ((amount % 8) == 0) &&
12657           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12658         uint32_t amount_ = amount / 8;
12659         EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12660                    (amount_ << 4));
12661         AdvanceIT();
12662         return;
12663       }
12664     } else {
12665       // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12666       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12667           ((amount % 8) == 0) && cond.IsNotNever() &&
12668           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12669         uint32_t amount_ = amount / 8;
12670         EmitA32(0x068f0070U | (cond.GetCondition() << 28) |
12671                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12672         return;
12673       }
12674     }
12675   }
12676   Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand);
12677 }
12678 
sxth(Condition cond,EncodingSize size,Register rd,const Operand & operand)12679 void Assembler::sxth(Condition cond,
12680                      EncodingSize size,
12681                      Register rd,
12682                      const Operand& operand) {
12683   VIXL_ASSERT(AllowAssembler());
12684   CheckIT(cond);
12685   if (operand.IsImmediateShiftedRegister()) {
12686     Register rm = operand.GetBaseRegister();
12687     if (operand.IsPlainRegister()) {
12688       if (IsUsingT32()) {
12689         // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
12690         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12691           EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3));
12692           AdvanceIT();
12693           return;
12694         }
12695       }
12696     }
12697     Shift shift = operand.GetShift();
12698     uint32_t amount = operand.GetShiftAmount();
12699     if (IsUsingT32()) {
12700       // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12701       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12702           (amount <= 24) && ((amount % 8) == 0) &&
12703           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12704         uint32_t amount_ = amount / 8;
12705         EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12706                    (amount_ << 4));
12707         AdvanceIT();
12708         return;
12709       }
12710     } else {
12711       // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12712       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12713           ((amount % 8) == 0) && cond.IsNotNever() &&
12714           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12715         uint32_t amount_ = amount / 8;
12716         EmitA32(0x06bf0070U | (cond.GetCondition() << 28) |
12717                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12718         return;
12719       }
12720     }
12721   }
12722   Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand);
12723 }
12724 
tbb(Condition cond,Register rn,Register rm)12725 void Assembler::tbb(Condition cond, Register rn, Register rm) {
12726   VIXL_ASSERT(AllowAssembler());
12727   CheckIT(cond);
12728   if (IsUsingT32()) {
12729     // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1
12730     if (OutsideITBlockAndAlOrLast(cond) &&
12731         (!rm.IsPC() || AllowUnpredictable())) {
12732       EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode());
12733       AdvanceIT();
12734       return;
12735     }
12736   }
12737   Delegate(kTbb, &Assembler::tbb, cond, rn, rm);
12738 }
12739 
tbh(Condition cond,Register rn,Register rm)12740 void Assembler::tbh(Condition cond, Register rn, Register rm) {
12741   VIXL_ASSERT(AllowAssembler());
12742   CheckIT(cond);
12743   if (IsUsingT32()) {
12744     // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1
12745     if (OutsideITBlockAndAlOrLast(cond) &&
12746         (!rm.IsPC() || AllowUnpredictable())) {
12747       EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode());
12748       AdvanceIT();
12749       return;
12750     }
12751   }
12752   Delegate(kTbh, &Assembler::tbh, cond, rn, rm);
12753 }
12754 
teq(Condition cond,Register rn,const Operand & operand)12755 void Assembler::teq(Condition cond, Register rn, const Operand& operand) {
12756   VIXL_ASSERT(AllowAssembler());
12757   CheckIT(cond);
12758   if (operand.IsImmediate()) {
12759     uint32_t imm = operand.GetImmediate();
12760     if (IsUsingT32()) {
12761       ImmediateT32 immediate_t32(imm);
12762       // TEQ{<c>}{<q>} <Rn>, #<const> ; T1
12763       if (immediate_t32.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
12764         EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) |
12765                    (immediate_t32.GetEncodingValue() & 0xff) |
12766                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12767                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12768         AdvanceIT();
12769         return;
12770       }
12771     } else {
12772       ImmediateA32 immediate_a32(imm);
12773       // TEQ{<c>}{<q>} <Rn>, #<const> ; A1
12774       if (immediate_a32.IsValid() && cond.IsNotNever()) {
12775         EmitA32(0x03300000U | (cond.GetCondition() << 28) |
12776                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
12777         return;
12778       }
12779     }
12780   }
12781   if (operand.IsImmediateShiftedRegister()) {
12782     Register rm = operand.GetBaseRegister();
12783     Shift shift = operand.GetShift();
12784     uint32_t amount = operand.GetShiftAmount();
12785     if (IsUsingT32()) {
12786       // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1
12787       if (shift.IsValidAmount(amount) &&
12788           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12789         uint32_t amount_ = amount % 32;
12790         EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() |
12791                    (operand.GetTypeEncodingValue() << 4) |
12792                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12793         AdvanceIT();
12794         return;
12795       }
12796     } else {
12797       // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
12798       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
12799         uint32_t amount_ = amount % 32;
12800         EmitA32(0x01300000U | (cond.GetCondition() << 28) |
12801                 (rn.GetCode() << 16) | rm.GetCode() |
12802                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12803         return;
12804       }
12805     }
12806   }
12807   if (operand.IsRegisterShiftedRegister()) {
12808     Register rm = operand.GetBaseRegister();
12809     Shift shift = operand.GetShift();
12810     Register rs = operand.GetShiftRegister();
12811     if (IsUsingA32()) {
12812       // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
12813       if (cond.IsNotNever() &&
12814           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
12815         EmitA32(0x01300010U | (cond.GetCondition() << 28) |
12816                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
12817                 (rs.GetCode() << 8));
12818         return;
12819       }
12820     }
12821   }
12822   Delegate(kTeq, &Assembler::teq, cond, rn, operand);
12823 }
12824 
tst(Condition cond,EncodingSize size,Register rn,const Operand & operand)12825 void Assembler::tst(Condition cond,
12826                     EncodingSize size,
12827                     Register rn,
12828                     const Operand& operand) {
12829   VIXL_ASSERT(AllowAssembler());
12830   CheckIT(cond);
12831   if (operand.IsImmediate()) {
12832     uint32_t imm = operand.GetImmediate();
12833     if (IsUsingT32()) {
12834       ImmediateT32 immediate_t32(imm);
12835       // TST{<c>}{<q>} <Rn>, #<const> ; T1
12836       if (!size.IsNarrow() && immediate_t32.IsValid() &&
12837           (!rn.IsPC() || AllowUnpredictable())) {
12838         EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) |
12839                    (immediate_t32.GetEncodingValue() & 0xff) |
12840                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12841                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12842         AdvanceIT();
12843         return;
12844       }
12845     } else {
12846       ImmediateA32 immediate_a32(imm);
12847       // TST{<c>}{<q>} <Rn>, #<const> ; A1
12848       if (immediate_a32.IsValid() && cond.IsNotNever()) {
12849         EmitA32(0x03100000U | (cond.GetCondition() << 28) |
12850                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
12851         return;
12852       }
12853     }
12854   }
12855   if (operand.IsImmediateShiftedRegister()) {
12856     Register rm = operand.GetBaseRegister();
12857     if (operand.IsPlainRegister()) {
12858       if (IsUsingT32()) {
12859         // TST{<c>}{<q>} <Rn>, <Rm> ; T1
12860         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
12861           EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3));
12862           AdvanceIT();
12863           return;
12864         }
12865       }
12866     }
12867     Shift shift = operand.GetShift();
12868     uint32_t amount = operand.GetShiftAmount();
12869     if (IsUsingT32()) {
12870       // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
12871       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
12872           ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12873         uint32_t amount_ = amount % 32;
12874         EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() |
12875                    (operand.GetTypeEncodingValue() << 4) |
12876                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12877         AdvanceIT();
12878         return;
12879       }
12880     } else {
12881       // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
12882       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
12883         uint32_t amount_ = amount % 32;
12884         EmitA32(0x01100000U | (cond.GetCondition() << 28) |
12885                 (rn.GetCode() << 16) | rm.GetCode() |
12886                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12887         return;
12888       }
12889     }
12890   }
12891   if (operand.IsRegisterShiftedRegister()) {
12892     Register rm = operand.GetBaseRegister();
12893     Shift shift = operand.GetShift();
12894     Register rs = operand.GetShiftRegister();
12895     if (IsUsingA32()) {
12896       // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
12897       if (cond.IsNotNever() &&
12898           ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
12899         EmitA32(0x01100010U | (cond.GetCondition() << 28) |
12900                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
12901                 (rs.GetCode() << 8));
12902         return;
12903       }
12904     }
12905   }
12906   Delegate(kTst, &Assembler::tst, cond, size, rn, operand);
12907 }
12908 
uadd16(Condition cond,Register rd,Register rn,Register rm)12909 void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) {
12910   VIXL_ASSERT(AllowAssembler());
12911   CheckIT(cond);
12912   if (IsUsingT32()) {
12913     // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12914     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12915       EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12916                  rm.GetCode());
12917       AdvanceIT();
12918       return;
12919     }
12920   } else {
12921     // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12922     if (cond.IsNotNever() &&
12923         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12924       EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12925               (rn.GetCode() << 16) | rm.GetCode());
12926       return;
12927     }
12928   }
12929   Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm);
12930 }
12931 
uadd8(Condition cond,Register rd,Register rn,Register rm)12932 void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) {
12933   VIXL_ASSERT(AllowAssembler());
12934   CheckIT(cond);
12935   if (IsUsingT32()) {
12936     // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12937     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12938       EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12939                  rm.GetCode());
12940       AdvanceIT();
12941       return;
12942     }
12943   } else {
12944     // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12945     if (cond.IsNotNever() &&
12946         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12947       EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12948               (rn.GetCode() << 16) | rm.GetCode());
12949       return;
12950     }
12951   }
12952   Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm);
12953 }
12954 
uasx(Condition cond,Register rd,Register rn,Register rm)12955 void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) {
12956   VIXL_ASSERT(AllowAssembler());
12957   CheckIT(cond);
12958   if (IsUsingT32()) {
12959     // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12960     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12961       EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12962                  rm.GetCode());
12963       AdvanceIT();
12964       return;
12965     }
12966   } else {
12967     // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12968     if (cond.IsNotNever() &&
12969         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12970       EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12971               (rn.GetCode() << 16) | rm.GetCode());
12972       return;
12973     }
12974   }
12975   Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm);
12976 }
12977 
ubfx(Condition cond,Register rd,Register rn,uint32_t lsb,uint32_t width)12978 void Assembler::ubfx(
12979     Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
12980   VIXL_ASSERT(AllowAssembler());
12981   CheckIT(cond);
12982   if (IsUsingT32()) {
12983     // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
12984     if ((lsb <= 31) &&
12985         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
12986          AllowUnpredictable())) {
12987       uint32_t widthm1 = width - 1;
12988       EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12989                  ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
12990       AdvanceIT();
12991       return;
12992     }
12993   } else {
12994     // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
12995     if ((lsb <= 31) && cond.IsNotNever() &&
12996         (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
12997          AllowUnpredictable())) {
12998       uint32_t widthm1 = width - 1;
12999       EmitA32(0x07e00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13000               rn.GetCode() | (lsb << 7) | (widthm1 << 16));
13001       return;
13002     }
13003   }
13004   Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, width);
13005 }
13006 
udf(Condition cond,EncodingSize size,uint32_t imm)13007 void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) {
13008   VIXL_ASSERT(AllowAssembler());
13009   CheckIT(cond);
13010   if (IsUsingT32()) {
13011     // UDF{<c>}{<q>} {#}<imm> ; T1
13012     if (!size.IsWide() && (imm <= 255)) {
13013       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13014         EmitT32_16(0xde00 | imm);
13015         AdvanceIT();
13016         return;
13017       }
13018     }
13019     // UDF{<c>}{<q>} {#}<imm> ; T2
13020     if (!size.IsNarrow() && (imm <= 65535)) {
13021       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13022         EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
13023         AdvanceIT();
13024         return;
13025       }
13026     }
13027   } else {
13028     // UDF{<c>}{<q>} {#}<imm> ; A1
13029     if ((imm <= 65535)) {
13030       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13031         EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4));
13032         return;
13033       }
13034     }
13035   }
13036   Delegate(kUdf, &Assembler::udf, cond, size, imm);
13037 }
13038 
udiv(Condition cond,Register rd,Register rn,Register rm)13039 void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) {
13040   VIXL_ASSERT(AllowAssembler());
13041   CheckIT(cond);
13042   if (IsUsingT32()) {
13043     // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13044     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13045       EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13046                  rm.GetCode());
13047       AdvanceIT();
13048       return;
13049     }
13050   } else {
13051     // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13052     if (cond.IsNotNever() &&
13053         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13054       EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
13055               rn.GetCode() | (rm.GetCode() << 8));
13056       return;
13057     }
13058   }
13059   Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm);
13060 }
13061 
uhadd16(Condition cond,Register rd,Register rn,Register rm)13062 void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) {
13063   VIXL_ASSERT(AllowAssembler());
13064   CheckIT(cond);
13065   if (IsUsingT32()) {
13066     // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13067     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13068       EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13069                  rm.GetCode());
13070       AdvanceIT();
13071       return;
13072     }
13073   } else {
13074     // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13075     if (cond.IsNotNever() &&
13076         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13077       EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13078               (rn.GetCode() << 16) | rm.GetCode());
13079       return;
13080     }
13081   }
13082   Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm);
13083 }
13084 
uhadd8(Condition cond,Register rd,Register rn,Register rm)13085 void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) {
13086   VIXL_ASSERT(AllowAssembler());
13087   CheckIT(cond);
13088   if (IsUsingT32()) {
13089     // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13090     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13091       EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13092                  rm.GetCode());
13093       AdvanceIT();
13094       return;
13095     }
13096   } else {
13097     // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13098     if (cond.IsNotNever() &&
13099         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13100       EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13101               (rn.GetCode() << 16) | rm.GetCode());
13102       return;
13103     }
13104   }
13105   Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm);
13106 }
13107 
uhasx(Condition cond,Register rd,Register rn,Register rm)13108 void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) {
13109   VIXL_ASSERT(AllowAssembler());
13110   CheckIT(cond);
13111   if (IsUsingT32()) {
13112     // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13113     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13114       EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13115                  rm.GetCode());
13116       AdvanceIT();
13117       return;
13118     }
13119   } else {
13120     // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13121     if (cond.IsNotNever() &&
13122         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13123       EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13124               (rn.GetCode() << 16) | rm.GetCode());
13125       return;
13126     }
13127   }
13128   Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm);
13129 }
13130 
uhsax(Condition cond,Register rd,Register rn,Register rm)13131 void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) {
13132   VIXL_ASSERT(AllowAssembler());
13133   CheckIT(cond);
13134   if (IsUsingT32()) {
13135     // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13136     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13137       EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13138                  rm.GetCode());
13139       AdvanceIT();
13140       return;
13141     }
13142   } else {
13143     // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13144     if (cond.IsNotNever() &&
13145         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13146       EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13147               (rn.GetCode() << 16) | rm.GetCode());
13148       return;
13149     }
13150   }
13151   Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm);
13152 }
13153 
uhsub16(Condition cond,Register rd,Register rn,Register rm)13154 void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) {
13155   VIXL_ASSERT(AllowAssembler());
13156   CheckIT(cond);
13157   if (IsUsingT32()) {
13158     // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13159     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13160       EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13161                  rm.GetCode());
13162       AdvanceIT();
13163       return;
13164     }
13165   } else {
13166     // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13167     if (cond.IsNotNever() &&
13168         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13169       EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13170               (rn.GetCode() << 16) | rm.GetCode());
13171       return;
13172     }
13173   }
13174   Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm);
13175 }
13176 
uhsub8(Condition cond,Register rd,Register rn,Register rm)13177 void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) {
13178   VIXL_ASSERT(AllowAssembler());
13179   CheckIT(cond);
13180   if (IsUsingT32()) {
13181     // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13182     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13183       EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13184                  rm.GetCode());
13185       AdvanceIT();
13186       return;
13187     }
13188   } else {
13189     // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13190     if (cond.IsNotNever() &&
13191         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13192       EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13193               (rn.GetCode() << 16) | rm.GetCode());
13194       return;
13195     }
13196   }
13197   Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm);
13198 }
13199 
umaal(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)13200 void Assembler::umaal(
13201     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
13202   VIXL_ASSERT(AllowAssembler());
13203   CheckIT(cond);
13204   if (IsUsingT32()) {
13205     // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
13206     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13207          AllowUnpredictable())) {
13208       EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
13209                  (rn.GetCode() << 16) | rm.GetCode());
13210       AdvanceIT();
13211       return;
13212     }
13213   } else {
13214     // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
13215     if (cond.IsNotNever() &&
13216         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13217          AllowUnpredictable())) {
13218       EmitA32(0x00400090U | (cond.GetCondition() << 28) |
13219               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
13220               (rm.GetCode() << 8));
13221       return;
13222     }
13223   }
13224   Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm);
13225 }
13226 
umlal(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)13227 void Assembler::umlal(
13228     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
13229   VIXL_ASSERT(AllowAssembler());
13230   CheckIT(cond);
13231   if (IsUsingT32()) {
13232     // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
13233     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13234          AllowUnpredictable())) {
13235       EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
13236                  (rn.GetCode() << 16) | rm.GetCode());
13237       AdvanceIT();
13238       return;
13239     }
13240   } else {
13241     // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
13242     if (cond.IsNotNever() &&
13243         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13244          AllowUnpredictable())) {
13245       EmitA32(0x00a00090U | (cond.GetCondition() << 28) |
13246               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
13247               (rm.GetCode() << 8));
13248       return;
13249     }
13250   }
13251   Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm);
13252 }
13253 
umlals(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)13254 void Assembler::umlals(
13255     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
13256   VIXL_ASSERT(AllowAssembler());
13257   CheckIT(cond);
13258   if (IsUsingA32()) {
13259     // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
13260     if (cond.IsNotNever() &&
13261         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13262          AllowUnpredictable())) {
13263       EmitA32(0x00b00090U | (cond.GetCondition() << 28) |
13264               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
13265               (rm.GetCode() << 8));
13266       return;
13267     }
13268   }
13269   Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm);
13270 }
13271 
umull(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)13272 void Assembler::umull(
13273     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
13274   VIXL_ASSERT(AllowAssembler());
13275   CheckIT(cond);
13276   if (IsUsingT32()) {
13277     // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
13278     if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13279          AllowUnpredictable())) {
13280       EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
13281                  (rn.GetCode() << 16) | rm.GetCode());
13282       AdvanceIT();
13283       return;
13284     }
13285   } else {
13286     // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
13287     if (cond.IsNotNever() &&
13288         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13289          AllowUnpredictable())) {
13290       EmitA32(0x00800090U | (cond.GetCondition() << 28) |
13291               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
13292               (rm.GetCode() << 8));
13293       return;
13294     }
13295   }
13296   Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm);
13297 }
13298 
umulls(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)13299 void Assembler::umulls(
13300     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
13301   VIXL_ASSERT(AllowAssembler());
13302   CheckIT(cond);
13303   if (IsUsingA32()) {
13304     // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
13305     if (cond.IsNotNever() &&
13306         ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13307          AllowUnpredictable())) {
13308       EmitA32(0x00900090U | (cond.GetCondition() << 28) |
13309               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
13310               (rm.GetCode() << 8));
13311       return;
13312     }
13313   }
13314   Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm);
13315 }
13316 
uqadd16(Condition cond,Register rd,Register rn,Register rm)13317 void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) {
13318   VIXL_ASSERT(AllowAssembler());
13319   CheckIT(cond);
13320   if (IsUsingT32()) {
13321     // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13322     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13323       EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13324                  rm.GetCode());
13325       AdvanceIT();
13326       return;
13327     }
13328   } else {
13329     // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13330     if (cond.IsNotNever() &&
13331         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13332       EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13333               (rn.GetCode() << 16) | rm.GetCode());
13334       return;
13335     }
13336   }
13337   Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm);
13338 }
13339 
uqadd8(Condition cond,Register rd,Register rn,Register rm)13340 void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) {
13341   VIXL_ASSERT(AllowAssembler());
13342   CheckIT(cond);
13343   if (IsUsingT32()) {
13344     // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13345     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13346       EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13347                  rm.GetCode());
13348       AdvanceIT();
13349       return;
13350     }
13351   } else {
13352     // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13353     if (cond.IsNotNever() &&
13354         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13355       EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13356               (rn.GetCode() << 16) | rm.GetCode());
13357       return;
13358     }
13359   }
13360   Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm);
13361 }
13362 
uqasx(Condition cond,Register rd,Register rn,Register rm)13363 void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) {
13364   VIXL_ASSERT(AllowAssembler());
13365   CheckIT(cond);
13366   if (IsUsingT32()) {
13367     // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13368     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13369       EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13370                  rm.GetCode());
13371       AdvanceIT();
13372       return;
13373     }
13374   } else {
13375     // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13376     if (cond.IsNotNever() &&
13377         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13378       EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13379               (rn.GetCode() << 16) | rm.GetCode());
13380       return;
13381     }
13382   }
13383   Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm);
13384 }
13385 
uqsax(Condition cond,Register rd,Register rn,Register rm)13386 void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) {
13387   VIXL_ASSERT(AllowAssembler());
13388   CheckIT(cond);
13389   if (IsUsingT32()) {
13390     // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13391     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13392       EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13393                  rm.GetCode());
13394       AdvanceIT();
13395       return;
13396     }
13397   } else {
13398     // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13399     if (cond.IsNotNever() &&
13400         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13401       EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13402               (rn.GetCode() << 16) | rm.GetCode());
13403       return;
13404     }
13405   }
13406   Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm);
13407 }
13408 
uqsub16(Condition cond,Register rd,Register rn,Register rm)13409 void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) {
13410   VIXL_ASSERT(AllowAssembler());
13411   CheckIT(cond);
13412   if (IsUsingT32()) {
13413     // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13414     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13415       EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13416                  rm.GetCode());
13417       AdvanceIT();
13418       return;
13419     }
13420   } else {
13421     // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13422     if (cond.IsNotNever() &&
13423         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13424       EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13425               (rn.GetCode() << 16) | rm.GetCode());
13426       return;
13427     }
13428   }
13429   Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm);
13430 }
13431 
uqsub8(Condition cond,Register rd,Register rn,Register rm)13432 void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) {
13433   VIXL_ASSERT(AllowAssembler());
13434   CheckIT(cond);
13435   if (IsUsingT32()) {
13436     // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13437     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13438       EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13439                  rm.GetCode());
13440       AdvanceIT();
13441       return;
13442     }
13443   } else {
13444     // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13445     if (cond.IsNotNever() &&
13446         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13447       EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13448               (rn.GetCode() << 16) | rm.GetCode());
13449       return;
13450     }
13451   }
13452   Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm);
13453 }
13454 
usad8(Condition cond,Register rd,Register rn,Register rm)13455 void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) {
13456   VIXL_ASSERT(AllowAssembler());
13457   CheckIT(cond);
13458   if (IsUsingT32()) {
13459     // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13460     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13461       EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13462                  rm.GetCode());
13463       AdvanceIT();
13464       return;
13465     }
13466   } else {
13467     // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13468     if (cond.IsNotNever() &&
13469         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13470       EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
13471               rn.GetCode() | (rm.GetCode() << 8));
13472       return;
13473     }
13474   }
13475   Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm);
13476 }
13477 
usada8(Condition cond,Register rd,Register rn,Register rm,Register ra)13478 void Assembler::usada8(
13479     Condition cond, Register rd, Register rn, Register rm, Register ra) {
13480   VIXL_ASSERT(AllowAssembler());
13481   CheckIT(cond);
13482   if (IsUsingT32()) {
13483     // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
13484     if (!ra.Is(pc) &&
13485         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13486       EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13487                  rm.GetCode() | (ra.GetCode() << 12));
13488       AdvanceIT();
13489       return;
13490     }
13491   } else {
13492     // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
13493     if (cond.IsNotNever() && !ra.Is(pc) &&
13494         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13495       EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
13496               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
13497       return;
13498     }
13499   }
13500   Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra);
13501 }
13502 
usat(Condition cond,Register rd,uint32_t imm,const Operand & operand)13503 void Assembler::usat(Condition cond,
13504                      Register rd,
13505                      uint32_t imm,
13506                      const Operand& operand) {
13507   VIXL_ASSERT(AllowAssembler());
13508   CheckIT(cond);
13509   if (operand.IsImmediateShiftedRegister()) {
13510     Register rn = operand.GetBaseRegister();
13511     Shift shift = operand.GetShift();
13512     uint32_t amount = operand.GetShiftAmount();
13513     if (IsUsingT32()) {
13514       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
13515       if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31) &&
13516           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13517         EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
13518                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
13519                    ((amount & 0x1c) << 10));
13520         AdvanceIT();
13521         return;
13522       }
13523       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
13524       if ((imm <= 31) && shift.IsLSL() && (amount <= 31) &&
13525           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13526         EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm |
13527                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
13528                    ((amount & 0x1c) << 10));
13529         AdvanceIT();
13530         return;
13531       }
13532     } else {
13533       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
13534       if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) &&
13535           cond.IsNotNever() &&
13536           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13537         uint32_t amount_ = amount % 32;
13538         EmitA32(0x06e00050U | (cond.GetCondition() << 28) |
13539                 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
13540                 (amount_ << 7));
13541         return;
13542       }
13543       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
13544       if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever() &&
13545           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13546         EmitA32(0x06e00010U | (cond.GetCondition() << 28) |
13547                 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
13548                 (amount << 7));
13549         return;
13550       }
13551     }
13552   }
13553   Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand);
13554 }
13555 
usat16(Condition cond,Register rd,uint32_t imm,Register rn)13556 void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) {
13557   VIXL_ASSERT(AllowAssembler());
13558   CheckIT(cond);
13559   if (IsUsingT32()) {
13560     // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
13561     if ((imm <= 15) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13562       EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
13563                  (rn.GetCode() << 16));
13564       AdvanceIT();
13565       return;
13566     }
13567   } else {
13568     // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
13569     if ((imm <= 15) && cond.IsNotNever() &&
13570         ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13571       EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13572               (imm << 16) | rn.GetCode());
13573       return;
13574     }
13575   }
13576   Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn);
13577 }
13578 
usax(Condition cond,Register rd,Register rn,Register rm)13579 void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) {
13580   VIXL_ASSERT(AllowAssembler());
13581   CheckIT(cond);
13582   if (IsUsingT32()) {
13583     // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13584     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13585       EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13586                  rm.GetCode());
13587       AdvanceIT();
13588       return;
13589     }
13590   } else {
13591     // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13592     if (cond.IsNotNever() &&
13593         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13594       EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13595               (rn.GetCode() << 16) | rm.GetCode());
13596       return;
13597     }
13598   }
13599   Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm);
13600 }
13601 
usub16(Condition cond,Register rd,Register rn,Register rm)13602 void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) {
13603   VIXL_ASSERT(AllowAssembler());
13604   CheckIT(cond);
13605   if (IsUsingT32()) {
13606     // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13607     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13608       EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13609                  rm.GetCode());
13610       AdvanceIT();
13611       return;
13612     }
13613   } else {
13614     // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13615     if (cond.IsNotNever() &&
13616         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13617       EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13618               (rn.GetCode() << 16) | rm.GetCode());
13619       return;
13620     }
13621   }
13622   Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm);
13623 }
13624 
usub8(Condition cond,Register rd,Register rn,Register rm)13625 void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) {
13626   VIXL_ASSERT(AllowAssembler());
13627   CheckIT(cond);
13628   if (IsUsingT32()) {
13629     // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13630     if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13631       EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13632                  rm.GetCode());
13633       AdvanceIT();
13634       return;
13635     }
13636   } else {
13637     // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13638     if (cond.IsNotNever() &&
13639         ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13640       EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13641               (rn.GetCode() << 16) | rm.GetCode());
13642       return;
13643     }
13644   }
13645   Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm);
13646 }
13647 
uxtab(Condition cond,Register rd,Register rn,const Operand & operand)13648 void Assembler::uxtab(Condition cond,
13649                       Register rd,
13650                       Register rn,
13651                       const Operand& operand) {
13652   VIXL_ASSERT(AllowAssembler());
13653   CheckIT(cond);
13654   if (operand.IsImmediateShiftedRegister()) {
13655     Register rm = operand.GetBaseRegister();
13656     Shift shift = operand.GetShift();
13657     uint32_t amount = operand.GetShiftAmount();
13658     if (IsUsingT32()) {
13659       // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
13660       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13661           ((amount % 8) == 0) && !rn.Is(pc) &&
13662           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13663         uint32_t amount_ = amount / 8;
13664         EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13665                    rm.GetCode() | (amount_ << 4));
13666         AdvanceIT();
13667         return;
13668       }
13669     } else {
13670       // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
13671       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13672           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
13673           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13674         uint32_t amount_ = amount / 8;
13675         EmitA32(0x06e00070U | (cond.GetCondition() << 28) |
13676                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
13677                 (amount_ << 10));
13678         return;
13679       }
13680     }
13681   }
13682   Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand);
13683 }
13684 
uxtab16(Condition cond,Register rd,Register rn,const Operand & operand)13685 void Assembler::uxtab16(Condition cond,
13686                         Register rd,
13687                         Register rn,
13688                         const Operand& operand) {
13689   VIXL_ASSERT(AllowAssembler());
13690   CheckIT(cond);
13691   if (operand.IsImmediateShiftedRegister()) {
13692     Register rm = operand.GetBaseRegister();
13693     Shift shift = operand.GetShift();
13694     uint32_t amount = operand.GetShiftAmount();
13695     if (IsUsingT32()) {
13696       // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
13697       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13698           ((amount % 8) == 0) && !rn.Is(pc) &&
13699           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13700         uint32_t amount_ = amount / 8;
13701         EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13702                    rm.GetCode() | (amount_ << 4));
13703         AdvanceIT();
13704         return;
13705       }
13706     } else {
13707       // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
13708       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13709           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
13710           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13711         uint32_t amount_ = amount / 8;
13712         EmitA32(0x06c00070U | (cond.GetCondition() << 28) |
13713                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
13714                 (amount_ << 10));
13715         return;
13716       }
13717     }
13718   }
13719   Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand);
13720 }
13721 
uxtah(Condition cond,Register rd,Register rn,const Operand & operand)13722 void Assembler::uxtah(Condition cond,
13723                       Register rd,
13724                       Register rn,
13725                       const Operand& operand) {
13726   VIXL_ASSERT(AllowAssembler());
13727   CheckIT(cond);
13728   if (operand.IsImmediateShiftedRegister()) {
13729     Register rm = operand.GetBaseRegister();
13730     Shift shift = operand.GetShift();
13731     uint32_t amount = operand.GetShiftAmount();
13732     if (IsUsingT32()) {
13733       // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
13734       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13735           ((amount % 8) == 0) && !rn.Is(pc) &&
13736           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13737         uint32_t amount_ = amount / 8;
13738         EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13739                    rm.GetCode() | (amount_ << 4));
13740         AdvanceIT();
13741         return;
13742       }
13743     } else {
13744       // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
13745       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13746           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
13747           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13748         uint32_t amount_ = amount / 8;
13749         EmitA32(0x06f00070U | (cond.GetCondition() << 28) |
13750                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
13751                 (amount_ << 10));
13752         return;
13753       }
13754     }
13755   }
13756   Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand);
13757 }
13758 
uxtb(Condition cond,EncodingSize size,Register rd,const Operand & operand)13759 void Assembler::uxtb(Condition cond,
13760                      EncodingSize size,
13761                      Register rd,
13762                      const Operand& operand) {
13763   VIXL_ASSERT(AllowAssembler());
13764   CheckIT(cond);
13765   if (operand.IsImmediateShiftedRegister()) {
13766     Register rm = operand.GetBaseRegister();
13767     if (operand.IsPlainRegister()) {
13768       if (IsUsingT32()) {
13769         // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
13770         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
13771           EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3));
13772           AdvanceIT();
13773           return;
13774         }
13775       }
13776     }
13777     Shift shift = operand.GetShift();
13778     uint32_t amount = operand.GetShiftAmount();
13779     if (IsUsingT32()) {
13780       // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
13781       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
13782           (amount <= 24) && ((amount % 8) == 0) &&
13783           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13784         uint32_t amount_ = amount / 8;
13785         EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() |
13786                    (amount_ << 4));
13787         AdvanceIT();
13788         return;
13789       }
13790     } else {
13791       // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
13792       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13793           ((amount % 8) == 0) && cond.IsNotNever() &&
13794           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13795         uint32_t amount_ = amount / 8;
13796         EmitA32(0x06ef0070U | (cond.GetCondition() << 28) |
13797                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
13798         return;
13799       }
13800     }
13801   }
13802   Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand);
13803 }
13804 
uxtb16(Condition cond,Register rd,const Operand & operand)13805 void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) {
13806   VIXL_ASSERT(AllowAssembler());
13807   CheckIT(cond);
13808   if (operand.IsImmediateShiftedRegister()) {
13809     Register rm = operand.GetBaseRegister();
13810     Shift shift = operand.GetShift();
13811     uint32_t amount = operand.GetShiftAmount();
13812     if (IsUsingT32()) {
13813       // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
13814       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13815           ((amount % 8) == 0) &&
13816           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13817         uint32_t amount_ = amount / 8;
13818         EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() |
13819                    (amount_ << 4));
13820         AdvanceIT();
13821         return;
13822       }
13823     } else {
13824       // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
13825       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13826           ((amount % 8) == 0) && cond.IsNotNever() &&
13827           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13828         uint32_t amount_ = amount / 8;
13829         EmitA32(0x06cf0070U | (cond.GetCondition() << 28) |
13830                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
13831         return;
13832       }
13833     }
13834   }
13835   Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand);
13836 }
13837 
uxth(Condition cond,EncodingSize size,Register rd,const Operand & operand)13838 void Assembler::uxth(Condition cond,
13839                      EncodingSize size,
13840                      Register rd,
13841                      const Operand& operand) {
13842   VIXL_ASSERT(AllowAssembler());
13843   CheckIT(cond);
13844   if (operand.IsImmediateShiftedRegister()) {
13845     Register rm = operand.GetBaseRegister();
13846     if (operand.IsPlainRegister()) {
13847       if (IsUsingT32()) {
13848         // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
13849         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
13850           EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3));
13851           AdvanceIT();
13852           return;
13853         }
13854       }
13855     }
13856     Shift shift = operand.GetShift();
13857     uint32_t amount = operand.GetShiftAmount();
13858     if (IsUsingT32()) {
13859       // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
13860       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
13861           (amount <= 24) && ((amount % 8) == 0) &&
13862           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13863         uint32_t amount_ = amount / 8;
13864         EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() |
13865                    (amount_ << 4));
13866         AdvanceIT();
13867         return;
13868       }
13869     } else {
13870       // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
13871       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13872           ((amount % 8) == 0) && cond.IsNotNever() &&
13873           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13874         uint32_t amount_ = amount / 8;
13875         EmitA32(0x06ff0070U | (cond.GetCondition() << 28) |
13876                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
13877         return;
13878       }
13879     }
13880   }
13881   Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand);
13882 }
13883 
vaba(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13884 void Assembler::vaba(
13885     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13886   VIXL_ASSERT(AllowAssembler());
13887   CheckIT(cond);
13888   Dt_U_size_1 encoded_dt(dt);
13889   if (IsUsingT32()) {
13890     // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1
13891     if (encoded_dt.IsValid()) {
13892       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13893         EmitT32_32(0xef000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13894                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13895                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13896         AdvanceIT();
13897         return;
13898       }
13899     }
13900   } else {
13901     // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1
13902     if (encoded_dt.IsValid()) {
13903       if (cond.Is(al)) {
13904         EmitA32(0xf2000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13905                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13906                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13907         return;
13908       }
13909     }
13910   }
13911   Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
13912 }
13913 
vaba(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)13914 void Assembler::vaba(
13915     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13916   VIXL_ASSERT(AllowAssembler());
13917   CheckIT(cond);
13918   Dt_U_size_1 encoded_dt(dt);
13919   if (IsUsingT32()) {
13920     // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1
13921     if (encoded_dt.IsValid()) {
13922       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13923         EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13924                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13925                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13926         AdvanceIT();
13927         return;
13928       }
13929     }
13930   } else {
13931     // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1
13932     if (encoded_dt.IsValid()) {
13933       if (cond.Is(al)) {
13934         EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13935                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13936                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13937         return;
13938       }
13939     }
13940   }
13941   Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
13942 }
13943 
vabal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)13944 void Assembler::vabal(
13945     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
13946   VIXL_ASSERT(AllowAssembler());
13947   CheckIT(cond);
13948   Dt_U_size_1 encoded_dt(dt);
13949   if (IsUsingT32()) {
13950     // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
13951     if (encoded_dt.IsValid()) {
13952       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13953         EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13954                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13955                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13956         AdvanceIT();
13957         return;
13958       }
13959     }
13960   } else {
13961     // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
13962     if (encoded_dt.IsValid()) {
13963       if (cond.Is(al)) {
13964         EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13965                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13966                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13967         return;
13968       }
13969     }
13970   }
13971   Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm);
13972 }
13973 
vabd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13974 void Assembler::vabd(
13975     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13976   VIXL_ASSERT(AllowAssembler());
13977   CheckIT(cond);
13978   Dt_U_size_1 encoded_dt(dt);
13979   if (IsUsingT32()) {
13980     // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13981     if (dt.Is(F32)) {
13982       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13983         EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13984                    rm.Encode(5, 0));
13985         AdvanceIT();
13986         return;
13987       }
13988     }
13989     // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
13990     if (encoded_dt.IsValid()) {
13991       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13992         EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13993                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13994                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13995         AdvanceIT();
13996         return;
13997       }
13998     }
13999   } else {
14000     // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14001     if (dt.Is(F32)) {
14002       if (cond.Is(al)) {
14003         EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14004                 rm.Encode(5, 0));
14005         return;
14006       }
14007     }
14008     // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14009     if (encoded_dt.IsValid()) {
14010       if (cond.Is(al)) {
14011         EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14012                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14013                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14014         return;
14015       }
14016     }
14017   }
14018   Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
14019 }
14020 
vabd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14021 void Assembler::vabd(
14022     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14023   VIXL_ASSERT(AllowAssembler());
14024   CheckIT(cond);
14025   Dt_U_size_1 encoded_dt(dt);
14026   if (IsUsingT32()) {
14027     // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14028     if (dt.Is(F32)) {
14029       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14030         EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14031                    rm.Encode(5, 0));
14032         AdvanceIT();
14033         return;
14034       }
14035     }
14036     // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14037     if (encoded_dt.IsValid()) {
14038       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14039         EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14040                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14041                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14042         AdvanceIT();
14043         return;
14044       }
14045     }
14046   } else {
14047     // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14048     if (dt.Is(F32)) {
14049       if (cond.Is(al)) {
14050         EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14051                 rm.Encode(5, 0));
14052         return;
14053       }
14054     }
14055     // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14056     if (encoded_dt.IsValid()) {
14057       if (cond.Is(al)) {
14058         EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14059                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14060                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14061         return;
14062       }
14063     }
14064   }
14065   Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
14066 }
14067 
vabdl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)14068 void Assembler::vabdl(
14069     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
14070   VIXL_ASSERT(AllowAssembler());
14071   CheckIT(cond);
14072   Dt_U_size_1 encoded_dt(dt);
14073   if (IsUsingT32()) {
14074     // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
14075     if (encoded_dt.IsValid()) {
14076       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14077         EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14078                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14079                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14080         AdvanceIT();
14081         return;
14082       }
14083     }
14084   } else {
14085     // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
14086     if (encoded_dt.IsValid()) {
14087       if (cond.Is(al)) {
14088         EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14089                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14090                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14091         return;
14092       }
14093     }
14094   }
14095   Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm);
14096 }
14097 
vabs(Condition cond,DataType dt,DRegister rd,DRegister rm)14098 void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14099   VIXL_ASSERT(AllowAssembler());
14100   CheckIT(cond);
14101   Dt_F_size_1 encoded_dt(dt);
14102   if (IsUsingT32()) {
14103     // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
14104     if (encoded_dt.IsValid()) {
14105       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14106         EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14107                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14108                    rd.Encode(22, 12) | rm.Encode(5, 0));
14109         AdvanceIT();
14110         return;
14111       }
14112     }
14113     // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
14114     if (dt.Is(F64)) {
14115       EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14116       AdvanceIT();
14117       return;
14118     }
14119   } else {
14120     // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
14121     if (encoded_dt.IsValid()) {
14122       if (cond.Is(al)) {
14123         EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14124                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14125                 rd.Encode(22, 12) | rm.Encode(5, 0));
14126         return;
14127       }
14128     }
14129     // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
14130     if (dt.Is(F64) && cond.IsNotNever()) {
14131       EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14132               rm.Encode(5, 0));
14133       return;
14134     }
14135   }
14136   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
14137 }
14138 
vabs(Condition cond,DataType dt,QRegister rd,QRegister rm)14139 void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14140   VIXL_ASSERT(AllowAssembler());
14141   CheckIT(cond);
14142   Dt_F_size_1 encoded_dt(dt);
14143   if (IsUsingT32()) {
14144     // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
14145     if (encoded_dt.IsValid()) {
14146       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14147         EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14148                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14149                    rd.Encode(22, 12) | rm.Encode(5, 0));
14150         AdvanceIT();
14151         return;
14152       }
14153     }
14154   } else {
14155     // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
14156     if (encoded_dt.IsValid()) {
14157       if (cond.Is(al)) {
14158         EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14159                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14160                 rd.Encode(22, 12) | rm.Encode(5, 0));
14161         return;
14162       }
14163     }
14164   }
14165   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
14166 }
14167 
vabs(Condition cond,DataType dt,SRegister rd,SRegister rm)14168 void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) {
14169   VIXL_ASSERT(AllowAssembler());
14170   CheckIT(cond);
14171   if (IsUsingT32()) {
14172     // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
14173     if (dt.Is(F32)) {
14174       EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14175       AdvanceIT();
14176       return;
14177     }
14178   } else {
14179     // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
14180     if (dt.Is(F32) && cond.IsNotNever()) {
14181       EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14182               rm.Encode(5, 0));
14183       return;
14184     }
14185   }
14186   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
14187 }
14188 
vacge(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14189 void Assembler::vacge(
14190     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14191   VIXL_ASSERT(AllowAssembler());
14192   CheckIT(cond);
14193   if (IsUsingT32()) {
14194     // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
14195     if (dt.Is(F32)) {
14196       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14197         EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14198                    rm.Encode(5, 0));
14199         AdvanceIT();
14200         return;
14201       }
14202     }
14203   } else {
14204     // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14205     if (dt.Is(F32)) {
14206       if (cond.Is(al)) {
14207         EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14208                 rm.Encode(5, 0));
14209         return;
14210       }
14211     }
14212   }
14213   Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
14214 }
14215 
vacge(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14216 void Assembler::vacge(
14217     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14218   VIXL_ASSERT(AllowAssembler());
14219   CheckIT(cond);
14220   if (IsUsingT32()) {
14221     // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14222     if (dt.Is(F32)) {
14223       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14224         EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14225                    rm.Encode(5, 0));
14226         AdvanceIT();
14227         return;
14228       }
14229     }
14230   } else {
14231     // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14232     if (dt.Is(F32)) {
14233       if (cond.Is(al)) {
14234         EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14235                 rm.Encode(5, 0));
14236         return;
14237       }
14238     }
14239   }
14240   Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
14241 }
14242 
vacgt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14243 void Assembler::vacgt(
14244     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14245   VIXL_ASSERT(AllowAssembler());
14246   CheckIT(cond);
14247   if (IsUsingT32()) {
14248     // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
14249     if (dt.Is(F32)) {
14250       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14251         EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14252                    rm.Encode(5, 0));
14253         AdvanceIT();
14254         return;
14255       }
14256     }
14257   } else {
14258     // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14259     if (dt.Is(F32)) {
14260       if (cond.Is(al)) {
14261         EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14262                 rm.Encode(5, 0));
14263         return;
14264       }
14265     }
14266   }
14267   Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
14268 }
14269 
vacgt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14270 void Assembler::vacgt(
14271     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14272   VIXL_ASSERT(AllowAssembler());
14273   CheckIT(cond);
14274   if (IsUsingT32()) {
14275     // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14276     if (dt.Is(F32)) {
14277       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14278         EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14279                    rm.Encode(5, 0));
14280         AdvanceIT();
14281         return;
14282       }
14283     }
14284   } else {
14285     // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14286     if (dt.Is(F32)) {
14287       if (cond.Is(al)) {
14288         EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14289                 rm.Encode(5, 0));
14290         return;
14291       }
14292     }
14293   }
14294   Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
14295 }
14296 
vacle(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14297 void Assembler::vacle(
14298     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14299   VIXL_ASSERT(AllowAssembler());
14300   CheckIT(cond);
14301   if (IsUsingT32()) {
14302     // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
14303     if (dt.Is(F32)) {
14304       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14305         EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14306                    rm.Encode(5, 0));
14307         AdvanceIT();
14308         return;
14309       }
14310     }
14311   } else {
14312     // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14313     if (dt.Is(F32)) {
14314       if (cond.Is(al)) {
14315         EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14316                 rm.Encode(5, 0));
14317         return;
14318       }
14319     }
14320   }
14321   Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
14322 }
14323 
vacle(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14324 void Assembler::vacle(
14325     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14326   VIXL_ASSERT(AllowAssembler());
14327   CheckIT(cond);
14328   if (IsUsingT32()) {
14329     // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14330     if (dt.Is(F32)) {
14331       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14332         EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14333                    rm.Encode(5, 0));
14334         AdvanceIT();
14335         return;
14336       }
14337     }
14338   } else {
14339     // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14340     if (dt.Is(F32)) {
14341       if (cond.Is(al)) {
14342         EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14343                 rm.Encode(5, 0));
14344         return;
14345       }
14346     }
14347   }
14348   Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
14349 }
14350 
vaclt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14351 void Assembler::vaclt(
14352     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14353   VIXL_ASSERT(AllowAssembler());
14354   CheckIT(cond);
14355   if (IsUsingT32()) {
14356     // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
14357     if (dt.Is(F32)) {
14358       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14359         EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14360                    rm.Encode(5, 0));
14361         AdvanceIT();
14362         return;
14363       }
14364     }
14365   } else {
14366     // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14367     if (dt.Is(F32)) {
14368       if (cond.Is(al)) {
14369         EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14370                 rm.Encode(5, 0));
14371         return;
14372       }
14373     }
14374   }
14375   Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
14376 }
14377 
vaclt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14378 void Assembler::vaclt(
14379     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14380   VIXL_ASSERT(AllowAssembler());
14381   CheckIT(cond);
14382   if (IsUsingT32()) {
14383     // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14384     if (dt.Is(F32)) {
14385       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14386         EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14387                    rm.Encode(5, 0));
14388         AdvanceIT();
14389         return;
14390       }
14391     }
14392   } else {
14393     // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14394     if (dt.Is(F32)) {
14395       if (cond.Is(al)) {
14396         EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14397                 rm.Encode(5, 0));
14398         return;
14399       }
14400     }
14401   }
14402   Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
14403 }
14404 
vadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14405 void Assembler::vadd(
14406     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14407   VIXL_ASSERT(AllowAssembler());
14408   CheckIT(cond);
14409   Dt_size_2 encoded_dt(dt);
14410   if (IsUsingT32()) {
14411     // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
14412     if (dt.Is(F32)) {
14413       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14414         EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14415                    rm.Encode(5, 0));
14416         AdvanceIT();
14417         return;
14418       }
14419     }
14420     // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
14421     if (dt.Is(F64)) {
14422       EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14423                  rm.Encode(5, 0));
14424       AdvanceIT();
14425       return;
14426     }
14427     // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14428     if (encoded_dt.IsValid()) {
14429       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14430         EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) |
14431                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14432         AdvanceIT();
14433         return;
14434       }
14435     }
14436   } else {
14437     // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14438     if (dt.Is(F32)) {
14439       if (cond.Is(al)) {
14440         EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14441                 rm.Encode(5, 0));
14442         return;
14443       }
14444     }
14445     // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
14446     if (dt.Is(F64) && cond.IsNotNever()) {
14447       EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14448               rn.Encode(7, 16) | rm.Encode(5, 0));
14449       return;
14450     }
14451     // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14452     if (encoded_dt.IsValid()) {
14453       if (cond.Is(al)) {
14454         EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) |
14455                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14456         return;
14457       }
14458     }
14459   }
14460   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
14461 }
14462 
vadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14463 void Assembler::vadd(
14464     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14465   VIXL_ASSERT(AllowAssembler());
14466   CheckIT(cond);
14467   Dt_size_2 encoded_dt(dt);
14468   if (IsUsingT32()) {
14469     // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14470     if (dt.Is(F32)) {
14471       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14472         EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14473                    rm.Encode(5, 0));
14474         AdvanceIT();
14475         return;
14476       }
14477     }
14478     // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14479     if (encoded_dt.IsValid()) {
14480       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14481         EmitT32_32(0xef000840U | (encoded_dt.GetEncodingValue() << 20) |
14482                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14483         AdvanceIT();
14484         return;
14485       }
14486     }
14487   } else {
14488     // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14489     if (dt.Is(F32)) {
14490       if (cond.Is(al)) {
14491         EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14492                 rm.Encode(5, 0));
14493         return;
14494       }
14495     }
14496     // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14497     if (encoded_dt.IsValid()) {
14498       if (cond.Is(al)) {
14499         EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) |
14500                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14501         return;
14502       }
14503     }
14504   }
14505   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
14506 }
14507 
vadd(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)14508 void Assembler::vadd(
14509     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
14510   VIXL_ASSERT(AllowAssembler());
14511   CheckIT(cond);
14512   if (IsUsingT32()) {
14513     // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
14514     if (dt.Is(F32)) {
14515       EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14516                  rm.Encode(5, 0));
14517       AdvanceIT();
14518       return;
14519     }
14520   } else {
14521     // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
14522     if (dt.Is(F32) && cond.IsNotNever()) {
14523       EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14524               rn.Encode(7, 16) | rm.Encode(5, 0));
14525       return;
14526     }
14527   }
14528   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
14529 }
14530 
vaddhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)14531 void Assembler::vaddhn(
14532     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
14533   VIXL_ASSERT(AllowAssembler());
14534   CheckIT(cond);
14535   Dt_size_3 encoded_dt(dt);
14536   if (IsUsingT32()) {
14537     // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
14538     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
14539       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14540         EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) |
14541                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14542         AdvanceIT();
14543         return;
14544       }
14545     }
14546   } else {
14547     // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
14548     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
14549       if (cond.Is(al)) {
14550         EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) |
14551                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14552         return;
14553       }
14554     }
14555   }
14556   Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm);
14557 }
14558 
vaddl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)14559 void Assembler::vaddl(
14560     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
14561   VIXL_ASSERT(AllowAssembler());
14562   CheckIT(cond);
14563   Dt_U_size_1 encoded_dt(dt);
14564   if (IsUsingT32()) {
14565     // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
14566     if (encoded_dt.IsValid()) {
14567       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14568         EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14569                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14570                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14571         AdvanceIT();
14572         return;
14573       }
14574     }
14575   } else {
14576     // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
14577     if (encoded_dt.IsValid()) {
14578       if (cond.Is(al)) {
14579         EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14580                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14581                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14582         return;
14583       }
14584     }
14585   }
14586   Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm);
14587 }
14588 
vaddw(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegister rm)14589 void Assembler::vaddw(
14590     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
14591   VIXL_ASSERT(AllowAssembler());
14592   CheckIT(cond);
14593   Dt_U_size_1 encoded_dt(dt);
14594   if (IsUsingT32()) {
14595     // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
14596     if (encoded_dt.IsValid()) {
14597       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14598         EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14599                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14600                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14601         AdvanceIT();
14602         return;
14603       }
14604     }
14605   } else {
14606     // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
14607     if (encoded_dt.IsValid()) {
14608       if (cond.Is(al)) {
14609         EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14610                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14611                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14612         return;
14613       }
14614     }
14615   }
14616   Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm);
14617 }
14618 
vand(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)14619 void Assembler::vand(Condition cond,
14620                      DataType dt,
14621                      DRegister rd,
14622                      DRegister rn,
14623                      const DOperand& operand) {
14624   VIXL_ASSERT(AllowAssembler());
14625   CheckIT(cond);
14626   if (operand.IsImmediate()) {
14627     ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
14628     if (IsUsingT32()) {
14629       // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
14630       if (encoded_dt.IsValid() && rd.Is(rn)) {
14631         if (cond.Is(al) || AllowStronglyDiscouraged()) {
14632           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
14633                      rd.Encode(22, 12) |
14634                      (encoded_dt.GetEncodedImmediate() & 0xf) |
14635                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14636                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
14637           AdvanceIT();
14638           return;
14639         }
14640       }
14641     } else {
14642       // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
14643       if (encoded_dt.IsValid() && rd.Is(rn)) {
14644         if (cond.Is(al)) {
14645           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
14646                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
14647                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14648                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
14649           return;
14650         }
14651       }
14652     }
14653   }
14654   if (operand.IsRegister()) {
14655     DRegister rm = operand.GetRegister();
14656     USE(dt);
14657     if (IsUsingT32()) {
14658       // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
14659       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14660         EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14661                    rm.Encode(5, 0));
14662         AdvanceIT();
14663         return;
14664       }
14665     } else {
14666       // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
14667       if (cond.Is(al)) {
14668         EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14669                 rm.Encode(5, 0));
14670         return;
14671       }
14672     }
14673   }
14674   Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
14675 }
14676 
vand(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)14677 void Assembler::vand(Condition cond,
14678                      DataType dt,
14679                      QRegister rd,
14680                      QRegister rn,
14681                      const QOperand& operand) {
14682   VIXL_ASSERT(AllowAssembler());
14683   CheckIT(cond);
14684   if (operand.IsImmediate()) {
14685     ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
14686     if (IsUsingT32()) {
14687       // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
14688       if (encoded_dt.IsValid() && rd.Is(rn)) {
14689         if (cond.Is(al) || AllowStronglyDiscouraged()) {
14690           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
14691                      rd.Encode(22, 12) |
14692                      (encoded_dt.GetEncodedImmediate() & 0xf) |
14693                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14694                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
14695           AdvanceIT();
14696           return;
14697         }
14698       }
14699     } else {
14700       // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
14701       if (encoded_dt.IsValid() && rd.Is(rn)) {
14702         if (cond.Is(al)) {
14703           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
14704                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
14705                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14706                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
14707           return;
14708         }
14709       }
14710     }
14711   }
14712   if (operand.IsRegister()) {
14713     QRegister rm = operand.GetRegister();
14714     USE(dt);
14715     if (IsUsingT32()) {
14716       // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
14717       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14718         EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14719                    rm.Encode(5, 0));
14720         AdvanceIT();
14721         return;
14722       }
14723     } else {
14724       // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
14725       if (cond.Is(al)) {
14726         EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14727                 rm.Encode(5, 0));
14728         return;
14729       }
14730     }
14731   }
14732   Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
14733 }
14734 
vbic(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)14735 void Assembler::vbic(Condition cond,
14736                      DataType dt,
14737                      DRegister rd,
14738                      DRegister rn,
14739                      const DOperand& operand) {
14740   VIXL_ASSERT(AllowAssembler());
14741   CheckIT(cond);
14742   if (operand.IsImmediate()) {
14743     ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
14744     if (IsUsingT32()) {
14745       // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
14746       if (encoded_dt.IsValid() && rd.Is(rn)) {
14747         if (cond.Is(al) || AllowStronglyDiscouraged()) {
14748           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
14749                      rd.Encode(22, 12) |
14750                      (encoded_dt.GetEncodedImmediate() & 0xf) |
14751                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14752                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
14753           AdvanceIT();
14754           return;
14755         }
14756       }
14757     } else {
14758       // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
14759       if (encoded_dt.IsValid() && rd.Is(rn)) {
14760         if (cond.Is(al)) {
14761           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
14762                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
14763                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14764                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
14765           return;
14766         }
14767       }
14768     }
14769   }
14770   if (operand.IsRegister()) {
14771     DRegister rm = operand.GetRegister();
14772     USE(dt);
14773     if (IsUsingT32()) {
14774       // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
14775       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14776         EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14777                    rm.Encode(5, 0));
14778         AdvanceIT();
14779         return;
14780       }
14781     } else {
14782       // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
14783       if (cond.Is(al)) {
14784         EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14785                 rm.Encode(5, 0));
14786         return;
14787       }
14788     }
14789   }
14790   Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
14791 }
14792 
vbic(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)14793 void Assembler::vbic(Condition cond,
14794                      DataType dt,
14795                      QRegister rd,
14796                      QRegister rn,
14797                      const QOperand& operand) {
14798   VIXL_ASSERT(AllowAssembler());
14799   CheckIT(cond);
14800   if (operand.IsImmediate()) {
14801     ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
14802     if (IsUsingT32()) {
14803       // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
14804       if (encoded_dt.IsValid() && rd.Is(rn)) {
14805         if (cond.Is(al) || AllowStronglyDiscouraged()) {
14806           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
14807                      rd.Encode(22, 12) |
14808                      (encoded_dt.GetEncodedImmediate() & 0xf) |
14809                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14810                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
14811           AdvanceIT();
14812           return;
14813         }
14814       }
14815     } else {
14816       // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
14817       if (encoded_dt.IsValid() && rd.Is(rn)) {
14818         if (cond.Is(al)) {
14819           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
14820                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
14821                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14822                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
14823           return;
14824         }
14825       }
14826     }
14827   }
14828   if (operand.IsRegister()) {
14829     QRegister rm = operand.GetRegister();
14830     USE(dt);
14831     if (IsUsingT32()) {
14832       // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
14833       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14834         EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14835                    rm.Encode(5, 0));
14836         AdvanceIT();
14837         return;
14838       }
14839     } else {
14840       // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
14841       if (cond.Is(al)) {
14842         EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14843                 rm.Encode(5, 0));
14844         return;
14845       }
14846     }
14847   }
14848   Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
14849 }
14850 
vbif(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14851 void Assembler::vbif(
14852     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14853   VIXL_ASSERT(AllowAssembler());
14854   CheckIT(cond);
14855   USE(dt);
14856   if (IsUsingT32()) {
14857     // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
14858     if (cond.Is(al) || AllowStronglyDiscouraged()) {
14859       EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14860                  rm.Encode(5, 0));
14861       AdvanceIT();
14862       return;
14863     }
14864   } else {
14865     // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
14866     if (cond.Is(al)) {
14867       EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14868               rm.Encode(5, 0));
14869       return;
14870     }
14871   }
14872   Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
14873 }
14874 
vbif(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14875 void Assembler::vbif(
14876     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14877   VIXL_ASSERT(AllowAssembler());
14878   CheckIT(cond);
14879   USE(dt);
14880   if (IsUsingT32()) {
14881     // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
14882     if (cond.Is(al) || AllowStronglyDiscouraged()) {
14883       EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14884                  rm.Encode(5, 0));
14885       AdvanceIT();
14886       return;
14887     }
14888   } else {
14889     // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
14890     if (cond.Is(al)) {
14891       EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14892               rm.Encode(5, 0));
14893       return;
14894     }
14895   }
14896   Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
14897 }
14898 
vbit(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14899 void Assembler::vbit(
14900     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14901   VIXL_ASSERT(AllowAssembler());
14902   CheckIT(cond);
14903   USE(dt);
14904   if (IsUsingT32()) {
14905     // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
14906     if (cond.Is(al) || AllowStronglyDiscouraged()) {
14907       EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14908                  rm.Encode(5, 0));
14909       AdvanceIT();
14910       return;
14911     }
14912   } else {
14913     // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
14914     if (cond.Is(al)) {
14915       EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14916               rm.Encode(5, 0));
14917       return;
14918     }
14919   }
14920   Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
14921 }
14922 
vbit(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14923 void Assembler::vbit(
14924     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14925   VIXL_ASSERT(AllowAssembler());
14926   CheckIT(cond);
14927   USE(dt);
14928   if (IsUsingT32()) {
14929     // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
14930     if (cond.Is(al) || AllowStronglyDiscouraged()) {
14931       EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14932                  rm.Encode(5, 0));
14933       AdvanceIT();
14934       return;
14935     }
14936   } else {
14937     // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
14938     if (cond.Is(al)) {
14939       EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14940               rm.Encode(5, 0));
14941       return;
14942     }
14943   }
14944   Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
14945 }
14946 
vbsl(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14947 void Assembler::vbsl(
14948     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14949   VIXL_ASSERT(AllowAssembler());
14950   CheckIT(cond);
14951   USE(dt);
14952   if (IsUsingT32()) {
14953     // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
14954     if (cond.Is(al) || AllowStronglyDiscouraged()) {
14955       EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14956                  rm.Encode(5, 0));
14957       AdvanceIT();
14958       return;
14959     }
14960   } else {
14961     // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
14962     if (cond.Is(al)) {
14963       EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14964               rm.Encode(5, 0));
14965       return;
14966     }
14967   }
14968   Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
14969 }
14970 
vbsl(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14971 void Assembler::vbsl(
14972     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14973   VIXL_ASSERT(AllowAssembler());
14974   CheckIT(cond);
14975   USE(dt);
14976   if (IsUsingT32()) {
14977     // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
14978     if (cond.Is(al) || AllowStronglyDiscouraged()) {
14979       EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14980                  rm.Encode(5, 0));
14981       AdvanceIT();
14982       return;
14983     }
14984   } else {
14985     // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
14986     if (cond.Is(al)) {
14987       EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14988               rm.Encode(5, 0));
14989       return;
14990     }
14991   }
14992   Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
14993 }
14994 
vceq(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)14995 void Assembler::vceq(Condition cond,
14996                      DataType dt,
14997                      DRegister rd,
14998                      DRegister rm,
14999                      const DOperand& operand) {
15000   VIXL_ASSERT(AllowAssembler());
15001   CheckIT(cond);
15002   if (operand.IsImmediate()) {
15003     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15004       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15005       Dt_F_size_2 encoded_dt(dt);
15006       if (IsUsingT32()) {
15007         // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
15008         if (encoded_dt.IsValid() && (imm == 0)) {
15009           if (cond.Is(al) || AllowStronglyDiscouraged()) {
15010             EmitT32_32(0xffb10100U |
15011                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15012                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15013                        rd.Encode(22, 12) | rm.Encode(5, 0));
15014             AdvanceIT();
15015             return;
15016           }
15017         }
15018       } else {
15019         // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
15020         if (encoded_dt.IsValid() && (imm == 0)) {
15021           if (cond.Is(al)) {
15022             EmitA32(0xf3b10100U |
15023                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15024                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15025                     rd.Encode(22, 12) | rm.Encode(5, 0));
15026             return;
15027           }
15028         }
15029       }
15030     }
15031   }
15032   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
15033 }
15034 
vceq(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)15035 void Assembler::vceq(Condition cond,
15036                      DataType dt,
15037                      QRegister rd,
15038                      QRegister rm,
15039                      const QOperand& operand) {
15040   VIXL_ASSERT(AllowAssembler());
15041   CheckIT(cond);
15042   if (operand.IsImmediate()) {
15043     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15044       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15045       Dt_F_size_2 encoded_dt(dt);
15046       if (IsUsingT32()) {
15047         // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
15048         if (encoded_dt.IsValid() && (imm == 0)) {
15049           if (cond.Is(al) || AllowStronglyDiscouraged()) {
15050             EmitT32_32(0xffb10140U |
15051                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15052                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15053                        rd.Encode(22, 12) | rm.Encode(5, 0));
15054             AdvanceIT();
15055             return;
15056           }
15057         }
15058       } else {
15059         // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
15060         if (encoded_dt.IsValid() && (imm == 0)) {
15061           if (cond.Is(al)) {
15062             EmitA32(0xf3b10140U |
15063                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15064                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15065                     rd.Encode(22, 12) | rm.Encode(5, 0));
15066             return;
15067           }
15068         }
15069       }
15070     }
15071   }
15072   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
15073 }
15074 
vceq(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)15075 void Assembler::vceq(
15076     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15077   VIXL_ASSERT(AllowAssembler());
15078   CheckIT(cond);
15079   Dt_size_4 encoded_dt(dt);
15080   Dt_sz_1 encoded_dt_2(dt);
15081   if (IsUsingT32()) {
15082     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
15083     if (encoded_dt.IsValid()) {
15084       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15085         EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) |
15086                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15087         AdvanceIT();
15088         return;
15089       }
15090     }
15091     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2
15092     if (encoded_dt_2.IsValid()) {
15093       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15094         EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
15095                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15096         AdvanceIT();
15097         return;
15098       }
15099     }
15100   } else {
15101     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
15102     if (encoded_dt.IsValid()) {
15103       if (cond.Is(al)) {
15104         EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) |
15105                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15106         return;
15107       }
15108     }
15109     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2
15110     if (encoded_dt_2.IsValid()) {
15111       if (cond.Is(al)) {
15112         EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
15113                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15114         return;
15115       }
15116     }
15117   }
15118   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
15119 }
15120 
vceq(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)15121 void Assembler::vceq(
15122     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15123   VIXL_ASSERT(AllowAssembler());
15124   CheckIT(cond);
15125   Dt_size_4 encoded_dt(dt);
15126   Dt_sz_1 encoded_dt_2(dt);
15127   if (IsUsingT32()) {
15128     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
15129     if (encoded_dt.IsValid()) {
15130       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15131         EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) |
15132                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15133         AdvanceIT();
15134         return;
15135       }
15136     }
15137     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2
15138     if (encoded_dt_2.IsValid()) {
15139       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15140         EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
15141                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15142         AdvanceIT();
15143         return;
15144       }
15145     }
15146   } else {
15147     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
15148     if (encoded_dt.IsValid()) {
15149       if (cond.Is(al)) {
15150         EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) |
15151                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15152         return;
15153       }
15154     }
15155     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2
15156     if (encoded_dt_2.IsValid()) {
15157       if (cond.Is(al)) {
15158         EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
15159                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15160         return;
15161       }
15162     }
15163   }
15164   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
15165 }
15166 
vcge(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)15167 void Assembler::vcge(Condition cond,
15168                      DataType dt,
15169                      DRegister rd,
15170                      DRegister rm,
15171                      const DOperand& operand) {
15172   VIXL_ASSERT(AllowAssembler());
15173   CheckIT(cond);
15174   if (operand.IsImmediate()) {
15175     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15176       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15177       Dt_F_size_1 encoded_dt(dt);
15178       if (IsUsingT32()) {
15179         // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
15180         if (encoded_dt.IsValid() && (imm == 0)) {
15181           if (cond.Is(al) || AllowStronglyDiscouraged()) {
15182             EmitT32_32(0xffb10080U |
15183                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15184                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15185                        rd.Encode(22, 12) | rm.Encode(5, 0));
15186             AdvanceIT();
15187             return;
15188           }
15189         }
15190       } else {
15191         // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
15192         if (encoded_dt.IsValid() && (imm == 0)) {
15193           if (cond.Is(al)) {
15194             EmitA32(0xf3b10080U |
15195                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15196                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15197                     rd.Encode(22, 12) | rm.Encode(5, 0));
15198             return;
15199           }
15200         }
15201       }
15202     }
15203   }
15204   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
15205 }
15206 
vcge(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)15207 void Assembler::vcge(Condition cond,
15208                      DataType dt,
15209                      QRegister rd,
15210                      QRegister rm,
15211                      const QOperand& operand) {
15212   VIXL_ASSERT(AllowAssembler());
15213   CheckIT(cond);
15214   if (operand.IsImmediate()) {
15215     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15216       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15217       Dt_F_size_1 encoded_dt(dt);
15218       if (IsUsingT32()) {
15219         // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
15220         if (encoded_dt.IsValid() && (imm == 0)) {
15221           if (cond.Is(al) || AllowStronglyDiscouraged()) {
15222             EmitT32_32(0xffb100c0U |
15223                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15224                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15225                        rd.Encode(22, 12) | rm.Encode(5, 0));
15226             AdvanceIT();
15227             return;
15228           }
15229         }
15230       } else {
15231         // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
15232         if (encoded_dt.IsValid() && (imm == 0)) {
15233           if (cond.Is(al)) {
15234             EmitA32(0xf3b100c0U |
15235                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15236                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15237                     rd.Encode(22, 12) | rm.Encode(5, 0));
15238             return;
15239           }
15240         }
15241       }
15242     }
15243   }
15244   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
15245 }
15246 
vcge(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)15247 void Assembler::vcge(
15248     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15249   VIXL_ASSERT(AllowAssembler());
15250   CheckIT(cond);
15251   Dt_U_size_1 encoded_dt(dt);
15252   if (IsUsingT32()) {
15253     // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
15254     if (encoded_dt.IsValid()) {
15255       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15256         EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15257                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15258                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15259         AdvanceIT();
15260         return;
15261       }
15262     }
15263     // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
15264     if (dt.Is(F32)) {
15265       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15266         EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15267                    rm.Encode(5, 0));
15268         AdvanceIT();
15269         return;
15270       }
15271     }
15272   } else {
15273     // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
15274     if (encoded_dt.IsValid()) {
15275       if (cond.Is(al)) {
15276         EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15277                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15278                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15279         return;
15280       }
15281     }
15282     // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
15283     if (dt.Is(F32)) {
15284       if (cond.Is(al)) {
15285         EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15286                 rm.Encode(5, 0));
15287         return;
15288       }
15289     }
15290   }
15291   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
15292 }
15293 
vcge(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)15294 void Assembler::vcge(
15295     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15296   VIXL_ASSERT(AllowAssembler());
15297   CheckIT(cond);
15298   Dt_U_size_1 encoded_dt(dt);
15299   if (IsUsingT32()) {
15300     // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
15301     if (encoded_dt.IsValid()) {
15302       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15303         EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15304                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15305                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15306         AdvanceIT();
15307         return;
15308       }
15309     }
15310     // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
15311     if (dt.Is(F32)) {
15312       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15313         EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15314                    rm.Encode(5, 0));
15315         AdvanceIT();
15316         return;
15317       }
15318     }
15319   } else {
15320     // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
15321     if (encoded_dt.IsValid()) {
15322       if (cond.Is(al)) {
15323         EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15324                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15325                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15326         return;
15327       }
15328     }
15329     // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
15330     if (dt.Is(F32)) {
15331       if (cond.Is(al)) {
15332         EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15333                 rm.Encode(5, 0));
15334         return;
15335       }
15336     }
15337   }
15338   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
15339 }
15340 
vcgt(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)15341 void Assembler::vcgt(Condition cond,
15342                      DataType dt,
15343                      DRegister rd,
15344                      DRegister rm,
15345                      const DOperand& operand) {
15346   VIXL_ASSERT(AllowAssembler());
15347   CheckIT(cond);
15348   if (operand.IsImmediate()) {
15349     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15350       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15351       Dt_F_size_1 encoded_dt(dt);
15352       if (IsUsingT32()) {
15353         // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
15354         if (encoded_dt.IsValid() && (imm == 0)) {
15355           if (cond.Is(al) || AllowStronglyDiscouraged()) {
15356             EmitT32_32(0xffb10000U |
15357                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15358                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15359                        rd.Encode(22, 12) | rm.Encode(5, 0));
15360             AdvanceIT();
15361             return;
15362           }
15363         }
15364       } else {
15365         // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
15366         if (encoded_dt.IsValid() && (imm == 0)) {
15367           if (cond.Is(al)) {
15368             EmitA32(0xf3b10000U |
15369                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15370                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15371                     rd.Encode(22, 12) | rm.Encode(5, 0));
15372             return;
15373           }
15374         }
15375       }
15376     }
15377   }
15378   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
15379 }
15380 
vcgt(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)15381 void Assembler::vcgt(Condition cond,
15382                      DataType dt,
15383                      QRegister rd,
15384                      QRegister rm,
15385                      const QOperand& operand) {
15386   VIXL_ASSERT(AllowAssembler());
15387   CheckIT(cond);
15388   if (operand.IsImmediate()) {
15389     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15390       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15391       Dt_F_size_1 encoded_dt(dt);
15392       if (IsUsingT32()) {
15393         // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
15394         if (encoded_dt.IsValid() && (imm == 0)) {
15395           if (cond.Is(al) || AllowStronglyDiscouraged()) {
15396             EmitT32_32(0xffb10040U |
15397                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15398                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15399                        rd.Encode(22, 12) | rm.Encode(5, 0));
15400             AdvanceIT();
15401             return;
15402           }
15403         }
15404       } else {
15405         // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
15406         if (encoded_dt.IsValid() && (imm == 0)) {
15407           if (cond.Is(al)) {
15408             EmitA32(0xf3b10040U |
15409                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15410                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15411                     rd.Encode(22, 12) | rm.Encode(5, 0));
15412             return;
15413           }
15414         }
15415       }
15416     }
15417   }
15418   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
15419 }
15420 
vcgt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)15421 void Assembler::vcgt(
15422     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15423   VIXL_ASSERT(AllowAssembler());
15424   CheckIT(cond);
15425   Dt_U_size_1 encoded_dt(dt);
15426   if (IsUsingT32()) {
15427     // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
15428     if (encoded_dt.IsValid()) {
15429       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15430         EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15431                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15432                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15433         AdvanceIT();
15434         return;
15435       }
15436     }
15437     // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
15438     if (dt.Is(F32)) {
15439       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15440         EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15441                    rm.Encode(5, 0));
15442         AdvanceIT();
15443         return;
15444       }
15445     }
15446   } else {
15447     // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
15448     if (encoded_dt.IsValid()) {
15449       if (cond.Is(al)) {
15450         EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15451                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15452                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15453         return;
15454       }
15455     }
15456     // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
15457     if (dt.Is(F32)) {
15458       if (cond.Is(al)) {
15459         EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15460                 rm.Encode(5, 0));
15461         return;
15462       }
15463     }
15464   }
15465   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
15466 }
15467 
vcgt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)15468 void Assembler::vcgt(
15469     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15470   VIXL_ASSERT(AllowAssembler());
15471   CheckIT(cond);
15472   Dt_U_size_1 encoded_dt(dt);
15473   if (IsUsingT32()) {
15474     // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
15475     if (encoded_dt.IsValid()) {
15476       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15477         EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15478                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15479                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15480         AdvanceIT();
15481         return;
15482       }
15483     }
15484     // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
15485     if (dt.Is(F32)) {
15486       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15487         EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15488                    rm.Encode(5, 0));
15489         AdvanceIT();
15490         return;
15491       }
15492     }
15493   } else {
15494     // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
15495     if (encoded_dt.IsValid()) {
15496       if (cond.Is(al)) {
15497         EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15498                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15499                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15500         return;
15501       }
15502     }
15503     // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
15504     if (dt.Is(F32)) {
15505       if (cond.Is(al)) {
15506         EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15507                 rm.Encode(5, 0));
15508         return;
15509       }
15510     }
15511   }
15512   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
15513 }
15514 
vcle(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)15515 void Assembler::vcle(Condition cond,
15516                      DataType dt,
15517                      DRegister rd,
15518                      DRegister rm,
15519                      const DOperand& operand) {
15520   VIXL_ASSERT(AllowAssembler());
15521   CheckIT(cond);
15522   if (operand.IsImmediate()) {
15523     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15524       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15525       Dt_F_size_1 encoded_dt(dt);
15526       if (IsUsingT32()) {
15527         // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
15528         if (encoded_dt.IsValid() && (imm == 0)) {
15529           if (cond.Is(al) || AllowStronglyDiscouraged()) {
15530             EmitT32_32(0xffb10180U |
15531                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15532                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15533                        rd.Encode(22, 12) | rm.Encode(5, 0));
15534             AdvanceIT();
15535             return;
15536           }
15537         }
15538       } else {
15539         // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
15540         if (encoded_dt.IsValid() && (imm == 0)) {
15541           if (cond.Is(al)) {
15542             EmitA32(0xf3b10180U |
15543                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15544                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15545                     rd.Encode(22, 12) | rm.Encode(5, 0));
15546             return;
15547           }
15548         }
15549       }
15550     }
15551   }
15552   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
15553 }
15554 
vcle(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)15555 void Assembler::vcle(Condition cond,
15556                      DataType dt,
15557                      QRegister rd,
15558                      QRegister rm,
15559                      const QOperand& operand) {
15560   VIXL_ASSERT(AllowAssembler());
15561   CheckIT(cond);
15562   if (operand.IsImmediate()) {
15563     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15564       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15565       Dt_F_size_1 encoded_dt(dt);
15566       if (IsUsingT32()) {
15567         // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
15568         if (encoded_dt.IsValid() && (imm == 0)) {
15569           if (cond.Is(al) || AllowStronglyDiscouraged()) {
15570             EmitT32_32(0xffb101c0U |
15571                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15572                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15573                        rd.Encode(22, 12) | rm.Encode(5, 0));
15574             AdvanceIT();
15575             return;
15576           }
15577         }
15578       } else {
15579         // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
15580         if (encoded_dt.IsValid() && (imm == 0)) {
15581           if (cond.Is(al)) {
15582             EmitA32(0xf3b101c0U |
15583                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15584                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15585                     rd.Encode(22, 12) | rm.Encode(5, 0));
15586             return;
15587           }
15588         }
15589       }
15590     }
15591   }
15592   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
15593 }
15594 
vcle(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)15595 void Assembler::vcle(
15596     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15597   VIXL_ASSERT(AllowAssembler());
15598   CheckIT(cond);
15599   Dt_U_size_1 encoded_dt(dt);
15600   if (IsUsingT32()) {
15601     // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
15602     if (encoded_dt.IsValid()) {
15603       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15604         EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15605                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15606                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15607         AdvanceIT();
15608         return;
15609       }
15610     }
15611     // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
15612     if (dt.Is(F32)) {
15613       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15614         EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15615                    rm.Encode(7, 16));
15616         AdvanceIT();
15617         return;
15618       }
15619     }
15620   } else {
15621     // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
15622     if (encoded_dt.IsValid()) {
15623       if (cond.Is(al)) {
15624         EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15625                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15626                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15627         return;
15628       }
15629     }
15630     // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
15631     if (dt.Is(F32)) {
15632       if (cond.Is(al)) {
15633         EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15634                 rm.Encode(7, 16));
15635         return;
15636       }
15637     }
15638   }
15639   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
15640 }
15641 
vcle(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)15642 void Assembler::vcle(
15643     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15644   VIXL_ASSERT(AllowAssembler());
15645   CheckIT(cond);
15646   Dt_U_size_1 encoded_dt(dt);
15647   if (IsUsingT32()) {
15648     // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
15649     if (encoded_dt.IsValid()) {
15650       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15651         EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15652                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15653                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15654         AdvanceIT();
15655         return;
15656       }
15657     }
15658     // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
15659     if (dt.Is(F32)) {
15660       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15661         EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15662                    rm.Encode(7, 16));
15663         AdvanceIT();
15664         return;
15665       }
15666     }
15667   } else {
15668     // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
15669     if (encoded_dt.IsValid()) {
15670       if (cond.Is(al)) {
15671         EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15672                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15673                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15674         return;
15675       }
15676     }
15677     // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
15678     if (dt.Is(F32)) {
15679       if (cond.Is(al)) {
15680         EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15681                 rm.Encode(7, 16));
15682         return;
15683       }
15684     }
15685   }
15686   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
15687 }
15688 
vcls(Condition cond,DataType dt,DRegister rd,DRegister rm)15689 void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) {
15690   VIXL_ASSERT(AllowAssembler());
15691   CheckIT(cond);
15692   Dt_size_5 encoded_dt(dt);
15693   if (IsUsingT32()) {
15694     // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
15695     if (encoded_dt.IsValid()) {
15696       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15697         EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) |
15698                    rd.Encode(22, 12) | rm.Encode(5, 0));
15699         AdvanceIT();
15700         return;
15701       }
15702     }
15703   } else {
15704     // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
15705     if (encoded_dt.IsValid()) {
15706       if (cond.Is(al)) {
15707         EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) |
15708                 rd.Encode(22, 12) | rm.Encode(5, 0));
15709         return;
15710       }
15711     }
15712   }
15713   Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
15714 }
15715 
vcls(Condition cond,DataType dt,QRegister rd,QRegister rm)15716 void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) {
15717   VIXL_ASSERT(AllowAssembler());
15718   CheckIT(cond);
15719   Dt_size_5 encoded_dt(dt);
15720   if (IsUsingT32()) {
15721     // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
15722     if (encoded_dt.IsValid()) {
15723       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15724         EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) |
15725                    rd.Encode(22, 12) | rm.Encode(5, 0));
15726         AdvanceIT();
15727         return;
15728       }
15729     }
15730   } else {
15731     // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
15732     if (encoded_dt.IsValid()) {
15733       if (cond.Is(al)) {
15734         EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) |
15735                 rd.Encode(22, 12) | rm.Encode(5, 0));
15736         return;
15737       }
15738     }
15739   }
15740   Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
15741 }
15742 
vclt(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)15743 void Assembler::vclt(Condition cond,
15744                      DataType dt,
15745                      DRegister rd,
15746                      DRegister rm,
15747                      const DOperand& operand) {
15748   VIXL_ASSERT(AllowAssembler());
15749   CheckIT(cond);
15750   if (operand.IsImmediate()) {
15751     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15752       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15753       Dt_F_size_1 encoded_dt(dt);
15754       if (IsUsingT32()) {
15755         // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
15756         if (encoded_dt.IsValid() && (imm == 0)) {
15757           if (cond.Is(al) || AllowStronglyDiscouraged()) {
15758             EmitT32_32(0xffb10200U |
15759                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15760                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15761                        rd.Encode(22, 12) | rm.Encode(5, 0));
15762             AdvanceIT();
15763             return;
15764           }
15765         }
15766       } else {
15767         // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
15768         if (encoded_dt.IsValid() && (imm == 0)) {
15769           if (cond.Is(al)) {
15770             EmitA32(0xf3b10200U |
15771                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15772                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15773                     rd.Encode(22, 12) | rm.Encode(5, 0));
15774             return;
15775           }
15776         }
15777       }
15778     }
15779   }
15780   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
15781 }
15782 
vclt(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)15783 void Assembler::vclt(Condition cond,
15784                      DataType dt,
15785                      QRegister rd,
15786                      QRegister rm,
15787                      const QOperand& operand) {
15788   VIXL_ASSERT(AllowAssembler());
15789   CheckIT(cond);
15790   if (operand.IsImmediate()) {
15791     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15792       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15793       Dt_F_size_1 encoded_dt(dt);
15794       if (IsUsingT32()) {
15795         // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
15796         if (encoded_dt.IsValid() && (imm == 0)) {
15797           if (cond.Is(al) || AllowStronglyDiscouraged()) {
15798             EmitT32_32(0xffb10240U |
15799                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15800                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15801                        rd.Encode(22, 12) | rm.Encode(5, 0));
15802             AdvanceIT();
15803             return;
15804           }
15805         }
15806       } else {
15807         // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
15808         if (encoded_dt.IsValid() && (imm == 0)) {
15809           if (cond.Is(al)) {
15810             EmitA32(0xf3b10240U |
15811                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15812                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15813                     rd.Encode(22, 12) | rm.Encode(5, 0));
15814             return;
15815           }
15816         }
15817       }
15818     }
15819   }
15820   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
15821 }
15822 
vclt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)15823 void Assembler::vclt(
15824     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15825   VIXL_ASSERT(AllowAssembler());
15826   CheckIT(cond);
15827   Dt_U_size_1 encoded_dt(dt);
15828   if (IsUsingT32()) {
15829     // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
15830     if (encoded_dt.IsValid()) {
15831       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15832         EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15833                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15834                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15835         AdvanceIT();
15836         return;
15837       }
15838     }
15839     // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
15840     if (dt.Is(F32)) {
15841       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15842         EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15843                    rm.Encode(7, 16));
15844         AdvanceIT();
15845         return;
15846       }
15847     }
15848   } else {
15849     // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
15850     if (encoded_dt.IsValid()) {
15851       if (cond.Is(al)) {
15852         EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15853                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15854                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15855         return;
15856       }
15857     }
15858     // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
15859     if (dt.Is(F32)) {
15860       if (cond.Is(al)) {
15861         EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15862                 rm.Encode(7, 16));
15863         return;
15864       }
15865     }
15866   }
15867   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
15868 }
15869 
vclt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)15870 void Assembler::vclt(
15871     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15872   VIXL_ASSERT(AllowAssembler());
15873   CheckIT(cond);
15874   Dt_U_size_1 encoded_dt(dt);
15875   if (IsUsingT32()) {
15876     // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
15877     if (encoded_dt.IsValid()) {
15878       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15879         EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15880                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15881                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15882         AdvanceIT();
15883         return;
15884       }
15885     }
15886     // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
15887     if (dt.Is(F32)) {
15888       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15889         EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15890                    rm.Encode(7, 16));
15891         AdvanceIT();
15892         return;
15893       }
15894     }
15895   } else {
15896     // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
15897     if (encoded_dt.IsValid()) {
15898       if (cond.Is(al)) {
15899         EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15900                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15901                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15902         return;
15903       }
15904     }
15905     // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
15906     if (dt.Is(F32)) {
15907       if (cond.Is(al)) {
15908         EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15909                 rm.Encode(7, 16));
15910         return;
15911       }
15912     }
15913   }
15914   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
15915 }
15916 
vclz(Condition cond,DataType dt,DRegister rd,DRegister rm)15917 void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) {
15918   VIXL_ASSERT(AllowAssembler());
15919   CheckIT(cond);
15920   Dt_size_4 encoded_dt(dt);
15921   if (IsUsingT32()) {
15922     // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
15923     if (encoded_dt.IsValid()) {
15924       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15925         EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) |
15926                    rd.Encode(22, 12) | rm.Encode(5, 0));
15927         AdvanceIT();
15928         return;
15929       }
15930     }
15931   } else {
15932     // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
15933     if (encoded_dt.IsValid()) {
15934       if (cond.Is(al)) {
15935         EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) |
15936                 rd.Encode(22, 12) | rm.Encode(5, 0));
15937         return;
15938       }
15939     }
15940   }
15941   Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
15942 }
15943 
vclz(Condition cond,DataType dt,QRegister rd,QRegister rm)15944 void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) {
15945   VIXL_ASSERT(AllowAssembler());
15946   CheckIT(cond);
15947   Dt_size_4 encoded_dt(dt);
15948   if (IsUsingT32()) {
15949     // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
15950     if (encoded_dt.IsValid()) {
15951       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15952         EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) |
15953                    rd.Encode(22, 12) | rm.Encode(5, 0));
15954         AdvanceIT();
15955         return;
15956       }
15957     }
15958   } else {
15959     // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
15960     if (encoded_dt.IsValid()) {
15961       if (cond.Is(al)) {
15962         EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) |
15963                 rd.Encode(22, 12) | rm.Encode(5, 0));
15964         return;
15965       }
15966     }
15967   }
15968   Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
15969 }
15970 
vcmp(Condition cond,DataType dt,SRegister rd,const SOperand & operand)15971 void Assembler::vcmp(Condition cond,
15972                      DataType dt,
15973                      SRegister rd,
15974                      const SOperand& operand) {
15975   VIXL_ASSERT(AllowAssembler());
15976   CheckIT(cond);
15977   if (operand.IsRegister()) {
15978     SRegister rm = operand.GetRegister();
15979     if (IsUsingT32()) {
15980       // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
15981       if (dt.Is(F32)) {
15982         EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15983         AdvanceIT();
15984         return;
15985       }
15986     } else {
15987       // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
15988       if (dt.Is(F32) && cond.IsNotNever()) {
15989         EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15990                 rm.Encode(5, 0));
15991         return;
15992       }
15993     }
15994   }
15995   if (operand.IsImmediate()) {
15996     if (IsUsingT32()) {
15997       // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
15998       if (dt.Is(F32) && (operand.IsFloatZero())) {
15999         EmitT32_32(0xeeb50a40U | rd.Encode(22, 12));
16000         AdvanceIT();
16001         return;
16002       }
16003     } else {
16004       // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
16005       if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) {
16006         EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
16007         return;
16008       }
16009     }
16010   }
16011   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand);
16012 }
16013 
vcmp(Condition cond,DataType dt,DRegister rd,const DOperand & operand)16014 void Assembler::vcmp(Condition cond,
16015                      DataType dt,
16016                      DRegister rd,
16017                      const DOperand& operand) {
16018   VIXL_ASSERT(AllowAssembler());
16019   CheckIT(cond);
16020   if (operand.IsRegister()) {
16021     DRegister rm = operand.GetRegister();
16022     if (IsUsingT32()) {
16023       // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
16024       if (dt.Is(F64)) {
16025         EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
16026         AdvanceIT();
16027         return;
16028       }
16029     } else {
16030       // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
16031       if (dt.Is(F64) && cond.IsNotNever()) {
16032         EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16033                 rm.Encode(5, 0));
16034         return;
16035       }
16036     }
16037   }
16038   if (operand.IsImmediate()) {
16039     if (IsUsingT32()) {
16040       // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
16041       if (dt.Is(F64) && (operand.IsFloatZero())) {
16042         EmitT32_32(0xeeb50b40U | rd.Encode(22, 12));
16043         AdvanceIT();
16044         return;
16045       }
16046     } else {
16047       // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
16048       if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) {
16049         EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
16050         return;
16051       }
16052     }
16053   }
16054   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand);
16055 }
16056 
vcmpe(Condition cond,DataType dt,SRegister rd,const SOperand & operand)16057 void Assembler::vcmpe(Condition cond,
16058                       DataType dt,
16059                       SRegister rd,
16060                       const SOperand& operand) {
16061   VIXL_ASSERT(AllowAssembler());
16062   CheckIT(cond);
16063   if (operand.IsRegister()) {
16064     SRegister rm = operand.GetRegister();
16065     if (IsUsingT32()) {
16066       // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
16067       if (dt.Is(F32)) {
16068         EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16069         AdvanceIT();
16070         return;
16071       }
16072     } else {
16073       // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
16074       if (dt.Is(F32) && cond.IsNotNever()) {
16075         EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16076                 rm.Encode(5, 0));
16077         return;
16078       }
16079     }
16080   }
16081   if (operand.IsImmediate()) {
16082     if (IsUsingT32()) {
16083       // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
16084       if (dt.Is(F32) && (operand.IsFloatZero())) {
16085         EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12));
16086         AdvanceIT();
16087         return;
16088       }
16089     } else {
16090       // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
16091       if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) {
16092         EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
16093         return;
16094       }
16095     }
16096   }
16097   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand);
16098 }
16099 
vcmpe(Condition cond,DataType dt,DRegister rd,const DOperand & operand)16100 void Assembler::vcmpe(Condition cond,
16101                       DataType dt,
16102                       DRegister rd,
16103                       const DOperand& operand) {
16104   VIXL_ASSERT(AllowAssembler());
16105   CheckIT(cond);
16106   if (operand.IsRegister()) {
16107     DRegister rm = operand.GetRegister();
16108     if (IsUsingT32()) {
16109       // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
16110       if (dt.Is(F64)) {
16111         EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16112         AdvanceIT();
16113         return;
16114       }
16115     } else {
16116       // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
16117       if (dt.Is(F64) && cond.IsNotNever()) {
16118         EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16119                 rm.Encode(5, 0));
16120         return;
16121       }
16122     }
16123   }
16124   if (operand.IsImmediate()) {
16125     if (IsUsingT32()) {
16126       // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
16127       if (dt.Is(F64) && (operand.IsFloatZero())) {
16128         EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12));
16129         AdvanceIT();
16130         return;
16131       }
16132     } else {
16133       // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
16134       if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) {
16135         EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
16136         return;
16137       }
16138     }
16139   }
16140   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand);
16141 }
16142 
vcnt(Condition cond,DataType dt,DRegister rd,DRegister rm)16143 void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
16144   VIXL_ASSERT(AllowAssembler());
16145   CheckIT(cond);
16146   if (IsUsingT32()) {
16147     // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1
16148     if (dt.Is(Untyped8)) {
16149       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16150         EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
16151         AdvanceIT();
16152         return;
16153       }
16154     }
16155   } else {
16156     // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1
16157     if (dt.Is(Untyped8)) {
16158       if (cond.Is(al)) {
16159         EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
16160         return;
16161       }
16162     }
16163   }
16164   Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
16165 }
16166 
vcnt(Condition cond,DataType dt,QRegister rd,QRegister rm)16167 void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) {
16168   VIXL_ASSERT(AllowAssembler());
16169   CheckIT(cond);
16170   if (IsUsingT32()) {
16171     // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1
16172     if (dt.Is(Untyped8)) {
16173       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16174         EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
16175         AdvanceIT();
16176         return;
16177       }
16178     }
16179   } else {
16180     // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1
16181     if (dt.Is(Untyped8)) {
16182       if (cond.Is(al)) {
16183         EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
16184         return;
16185       }
16186     }
16187   }
16188   Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
16189 }
16190 
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,SRegister rm)16191 void Assembler::vcvt(
16192     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
16193   VIXL_ASSERT(AllowAssembler());
16194   CheckIT(cond);
16195   Dt_op_2 encoded_dt(dt2);
16196   if (IsUsingT32()) {
16197     // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1
16198     if (dt1.Is(F64) && dt2.Is(F32)) {
16199       EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16200       AdvanceIT();
16201       return;
16202     }
16203     // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1
16204     if (dt1.Is(F64) && encoded_dt.IsValid()) {
16205       EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) |
16206                  rd.Encode(22, 12) | rm.Encode(5, 0));
16207       AdvanceIT();
16208       return;
16209     }
16210   } else {
16211     // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1
16212     if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) {
16213       EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16214               rm.Encode(5, 0));
16215       return;
16216     }
16217     // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1
16218     if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) {
16219       EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) |
16220               (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
16221               rm.Encode(5, 0));
16222       return;
16223     }
16224   }
16225   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16226 }
16227 
vcvt(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)16228 void Assembler::vcvt(
16229     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16230   VIXL_ASSERT(AllowAssembler());
16231   CheckIT(cond);
16232   if (IsUsingT32()) {
16233     // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1
16234     if (dt1.Is(F32) && dt2.Is(F64)) {
16235       EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16236       AdvanceIT();
16237       return;
16238     }
16239     // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
16240     if (dt1.Is(U32) && dt2.Is(F64)) {
16241       EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16242       AdvanceIT();
16243       return;
16244     }
16245     // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
16246     if (dt1.Is(S32) && dt2.Is(F64)) {
16247       EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16248       AdvanceIT();
16249       return;
16250     }
16251   } else {
16252     // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1
16253     if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) {
16254       EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16255               rm.Encode(5, 0));
16256       return;
16257     }
16258     // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
16259     if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
16260       EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16261               rm.Encode(5, 0));
16262       return;
16263     }
16264     // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
16265     if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
16266       EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16267               rm.Encode(5, 0));
16268       return;
16269     }
16270   }
16271   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16272 }
16273 
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,DRegister rm,int32_t fbits)16274 void Assembler::vcvt(Condition cond,
16275                      DataType dt1,
16276                      DataType dt2,
16277                      DRegister rd,
16278                      DRegister rm,
16279                      int32_t fbits) {
16280   VIXL_ASSERT(AllowAssembler());
16281   CheckIT(cond);
16282   Dt_op_U_1 encoded_dt(dt1, dt2);
16283   Dt_U_sx_1 encoded_dt_2(dt2);
16284   Dt_U_sx_1 encoded_dt_3(dt1);
16285   if (IsUsingT32()) {
16286     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1
16287     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
16288       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16289         uint32_t fbits_ = 64 - fbits;
16290         EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
16291                    ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
16292                    rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
16293         AdvanceIT();
16294         return;
16295       }
16296     }
16297     // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1
16298     if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
16299         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
16300          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
16301       unsigned offset = 32;
16302       if (dt2.Is(S16) || dt2.Is(U16)) {
16303         offset = 16;
16304       }
16305       uint32_t fbits_ = offset - fbits;
16306       EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
16307                  ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
16308                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16309                  ((fbits_ & 0x1e) >> 1));
16310       AdvanceIT();
16311       return;
16312     }
16313     // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1
16314     if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
16315         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
16316          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
16317       unsigned offset = 32;
16318       if (dt1.Is(S16) || dt1.Is(U16)) {
16319         offset = 16;
16320       }
16321       uint32_t fbits_ = offset - fbits;
16322       EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
16323                  ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
16324                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16325                  ((fbits_ & 0x1e) >> 1));
16326       AdvanceIT();
16327       return;
16328     }
16329   } else {
16330     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1
16331     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
16332       if (cond.Is(al)) {
16333         uint32_t fbits_ = 64 - fbits;
16334         EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
16335                 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
16336                 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
16337         return;
16338       }
16339     }
16340     // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1
16341     if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
16342         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
16343          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
16344         cond.IsNotNever()) {
16345       unsigned offset = 32;
16346       if (dt2.Is(S16) || dt2.Is(U16)) {
16347         offset = 16;
16348       }
16349       uint32_t fbits_ = offset - fbits;
16350       EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) |
16351               ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
16352               ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
16353               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16354               ((fbits_ & 0x1e) >> 1));
16355       return;
16356     }
16357     // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1
16358     if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
16359         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
16360          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
16361         cond.IsNotNever()) {
16362       unsigned offset = 32;
16363       if (dt1.Is(S16) || dt1.Is(U16)) {
16364         offset = 16;
16365       }
16366       uint32_t fbits_ = offset - fbits;
16367       EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) |
16368               ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
16369               ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
16370               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16371               ((fbits_ & 0x1e) >> 1));
16372       return;
16373     }
16374   }
16375   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
16376 }
16377 
vcvt(Condition cond,DataType dt1,DataType dt2,QRegister rd,QRegister rm,int32_t fbits)16378 void Assembler::vcvt(Condition cond,
16379                      DataType dt1,
16380                      DataType dt2,
16381                      QRegister rd,
16382                      QRegister rm,
16383                      int32_t fbits) {
16384   VIXL_ASSERT(AllowAssembler());
16385   CheckIT(cond);
16386   Dt_op_U_1 encoded_dt(dt1, dt2);
16387   if (IsUsingT32()) {
16388     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1
16389     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
16390       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16391         uint32_t fbits_ = 64 - fbits;
16392         EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
16393                    ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
16394                    rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
16395         AdvanceIT();
16396         return;
16397       }
16398     }
16399   } else {
16400     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1
16401     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
16402       if (cond.Is(al)) {
16403         uint32_t fbits_ = 64 - fbits;
16404         EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
16405                 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
16406                 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
16407         return;
16408       }
16409     }
16410   }
16411   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
16412 }
16413 
vcvt(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm,int32_t fbits)16414 void Assembler::vcvt(Condition cond,
16415                      DataType dt1,
16416                      DataType dt2,
16417                      SRegister rd,
16418                      SRegister rm,
16419                      int32_t fbits) {
16420   VIXL_ASSERT(AllowAssembler());
16421   CheckIT(cond);
16422   Dt_U_sx_1 encoded_dt(dt2);
16423   Dt_U_sx_1 encoded_dt_2(dt1);
16424   if (IsUsingT32()) {
16425     // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1
16426     if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
16427         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
16428          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
16429       unsigned offset = 32;
16430       if (dt2.Is(S16) || dt2.Is(U16)) {
16431         offset = 16;
16432       }
16433       uint32_t fbits_ = offset - fbits;
16434       EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
16435                  ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
16436                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16437                  ((fbits_ & 0x1e) >> 1));
16438       AdvanceIT();
16439       return;
16440     }
16441     // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1
16442     if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
16443         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
16444          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
16445       unsigned offset = 32;
16446       if (dt1.Is(S16) || dt1.Is(U16)) {
16447         offset = 16;
16448       }
16449       uint32_t fbits_ = offset - fbits;
16450       EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
16451                  ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
16452                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16453                  ((fbits_ & 0x1e) >> 1));
16454       AdvanceIT();
16455       return;
16456     }
16457   } else {
16458     // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1
16459     if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
16460         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
16461          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
16462         cond.IsNotNever()) {
16463       unsigned offset = 32;
16464       if (dt2.Is(S16) || dt2.Is(U16)) {
16465         offset = 16;
16466       }
16467       uint32_t fbits_ = offset - fbits;
16468       EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) |
16469               ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
16470               ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
16471               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16472               ((fbits_ & 0x1e) >> 1));
16473       return;
16474     }
16475     // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1
16476     if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
16477         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
16478          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
16479         cond.IsNotNever()) {
16480       unsigned offset = 32;
16481       if (dt1.Is(S16) || dt1.Is(U16)) {
16482         offset = 16;
16483       }
16484       uint32_t fbits_ = offset - fbits;
16485       EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) |
16486               ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
16487               ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
16488               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16489               ((fbits_ & 0x1e) >> 1));
16490       return;
16491     }
16492   }
16493   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
16494 }
16495 
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,DRegister rm)16496 void Assembler::vcvt(
16497     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
16498   VIXL_ASSERT(AllowAssembler());
16499   CheckIT(cond);
16500   Dt_op_1 encoded_dt(dt1, dt2);
16501   if (IsUsingT32()) {
16502     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1
16503     if (encoded_dt.IsValid()) {
16504       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16505         EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) |
16506                    rd.Encode(22, 12) | rm.Encode(5, 0));
16507         AdvanceIT();
16508         return;
16509       }
16510     }
16511   } else {
16512     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1
16513     if (encoded_dt.IsValid()) {
16514       if (cond.Is(al)) {
16515         EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) |
16516                 rd.Encode(22, 12) | rm.Encode(5, 0));
16517         return;
16518       }
16519     }
16520   }
16521   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16522 }
16523 
vcvt(Condition cond,DataType dt1,DataType dt2,QRegister rd,QRegister rm)16524 void Assembler::vcvt(
16525     Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
16526   VIXL_ASSERT(AllowAssembler());
16527   CheckIT(cond);
16528   Dt_op_1 encoded_dt(dt1, dt2);
16529   if (IsUsingT32()) {
16530     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1
16531     if (encoded_dt.IsValid()) {
16532       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16533         EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) |
16534                    rd.Encode(22, 12) | rm.Encode(5, 0));
16535         AdvanceIT();
16536         return;
16537       }
16538     }
16539   } else {
16540     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1
16541     if (encoded_dt.IsValid()) {
16542       if (cond.Is(al)) {
16543         EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) |
16544                 rd.Encode(22, 12) | rm.Encode(5, 0));
16545         return;
16546       }
16547     }
16548   }
16549   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16550 }
16551 
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,QRegister rm)16552 void Assembler::vcvt(
16553     Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) {
16554   VIXL_ASSERT(AllowAssembler());
16555   CheckIT(cond);
16556   if (IsUsingT32()) {
16557     // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1
16558     if (dt1.Is(F16) && dt2.Is(F32)) {
16559       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16560         EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
16561         AdvanceIT();
16562         return;
16563       }
16564     }
16565   } else {
16566     // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1
16567     if (dt1.Is(F16) && dt2.Is(F32)) {
16568       if (cond.Is(al)) {
16569         EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
16570         return;
16571       }
16572     }
16573   }
16574   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16575 }
16576 
vcvt(Condition cond,DataType dt1,DataType dt2,QRegister rd,DRegister rm)16577 void Assembler::vcvt(
16578     Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) {
16579   VIXL_ASSERT(AllowAssembler());
16580   CheckIT(cond);
16581   if (IsUsingT32()) {
16582     // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1
16583     if (dt1.Is(F32) && dt2.Is(F16)) {
16584       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16585         EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
16586         AdvanceIT();
16587         return;
16588       }
16589     }
16590   } else {
16591     // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1
16592     if (dt1.Is(F32) && dt2.Is(F16)) {
16593       if (cond.Is(al)) {
16594         EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
16595         return;
16596       }
16597     }
16598   }
16599   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16600 }
16601 
vcvt(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)16602 void Assembler::vcvt(
16603     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16604   VIXL_ASSERT(AllowAssembler());
16605   CheckIT(cond);
16606   Dt_op_2 encoded_dt(dt2);
16607   if (IsUsingT32()) {
16608     // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
16609     if (dt1.Is(U32) && dt2.Is(F32)) {
16610       EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16611       AdvanceIT();
16612       return;
16613     }
16614     // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
16615     if (dt1.Is(S32) && dt2.Is(F32)) {
16616       EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16617       AdvanceIT();
16618       return;
16619     }
16620     // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1
16621     if (dt1.Is(F32) && encoded_dt.IsValid()) {
16622       EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) |
16623                  rd.Encode(22, 12) | rm.Encode(5, 0));
16624       AdvanceIT();
16625       return;
16626     }
16627   } else {
16628     // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
16629     if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
16630       EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16631               rm.Encode(5, 0));
16632       return;
16633     }
16634     // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
16635     if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
16636       EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16637               rm.Encode(5, 0));
16638       return;
16639     }
16640     // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1
16641     if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) {
16642       EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) |
16643               (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
16644               rm.Encode(5, 0));
16645       return;
16646     }
16647   }
16648   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16649 }
16650 
vcvta(DataType dt1,DataType dt2,DRegister rd,DRegister rm)16651 void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
16652   VIXL_ASSERT(AllowAssembler());
16653   CheckIT(al);
16654   Dt_op_3 encoded_dt(dt1);
16655   if (IsUsingT32()) {
16656     // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
16657     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16658       EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) |
16659                  rd.Encode(22, 12) | rm.Encode(5, 0));
16660       AdvanceIT();
16661       return;
16662     }
16663   } else {
16664     // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
16665     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16666       EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) |
16667               rd.Encode(22, 12) | rm.Encode(5, 0));
16668       return;
16669     }
16670   }
16671   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
16672 }
16673 
vcvta(DataType dt1,DataType dt2,QRegister rd,QRegister rm)16674 void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
16675   VIXL_ASSERT(AllowAssembler());
16676   CheckIT(al);
16677   Dt_op_3 encoded_dt(dt1);
16678   if (IsUsingT32()) {
16679     // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
16680     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16681       EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) |
16682                  rd.Encode(22, 12) | rm.Encode(5, 0));
16683       AdvanceIT();
16684       return;
16685     }
16686   } else {
16687     // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
16688     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16689       EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) |
16690               rd.Encode(22, 12) | rm.Encode(5, 0));
16691       return;
16692     }
16693   }
16694   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
16695 }
16696 
vcvta(DataType dt1,DataType dt2,SRegister rd,SRegister rm)16697 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16698   VIXL_ASSERT(AllowAssembler());
16699   CheckIT(al);
16700   Dt_op_2 encoded_dt(dt1);
16701   if (IsUsingT32()) {
16702     // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
16703     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16704       EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
16705                  rd.Encode(22, 12) | rm.Encode(5, 0));
16706       AdvanceIT();
16707       return;
16708     }
16709   } else {
16710     // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
16711     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16712       EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
16713               rd.Encode(22, 12) | rm.Encode(5, 0));
16714       return;
16715     }
16716   }
16717   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
16718 }
16719 
vcvta(DataType dt1,DataType dt2,SRegister rd,DRegister rm)16720 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16721   VIXL_ASSERT(AllowAssembler());
16722   CheckIT(al);
16723   Dt_op_2 encoded_dt(dt1);
16724   if (IsUsingT32()) {
16725     // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
16726     if (encoded_dt.IsValid() && dt2.Is(F64)) {
16727       EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
16728                  rd.Encode(22, 12) | rm.Encode(5, 0));
16729       AdvanceIT();
16730       return;
16731     }
16732   } else {
16733     // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
16734     if (encoded_dt.IsValid() && dt2.Is(F64)) {
16735       EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
16736               rd.Encode(22, 12) | rm.Encode(5, 0));
16737       return;
16738     }
16739   }
16740   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
16741 }
16742 
vcvtb(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)16743 void Assembler::vcvtb(
16744     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16745   VIXL_ASSERT(AllowAssembler());
16746   CheckIT(cond);
16747   if (IsUsingT32()) {
16748     // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
16749     if (dt1.Is(F32) && dt2.Is(F16)) {
16750       EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
16751       AdvanceIT();
16752       return;
16753     }
16754     // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
16755     if (dt1.Is(F16) && dt2.Is(F32)) {
16756       EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
16757       AdvanceIT();
16758       return;
16759     }
16760   } else {
16761     // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
16762     if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
16763       EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16764               rm.Encode(5, 0));
16765       return;
16766     }
16767     // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
16768     if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
16769       EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16770               rm.Encode(5, 0));
16771       return;
16772     }
16773   }
16774   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
16775 }
16776 
vcvtb(Condition cond,DataType dt1,DataType dt2,DRegister rd,SRegister rm)16777 void Assembler::vcvtb(
16778     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
16779   VIXL_ASSERT(AllowAssembler());
16780   CheckIT(cond);
16781   if (IsUsingT32()) {
16782     // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
16783     if (dt1.Is(F64) && dt2.Is(F16)) {
16784       EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
16785       AdvanceIT();
16786       return;
16787     }
16788   } else {
16789     // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
16790     if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
16791       EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16792               rm.Encode(5, 0));
16793       return;
16794     }
16795   }
16796   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
16797 }
16798 
vcvtb(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)16799 void Assembler::vcvtb(
16800     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16801   VIXL_ASSERT(AllowAssembler());
16802   CheckIT(cond);
16803   if (IsUsingT32()) {
16804     // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
16805     if (dt1.Is(F16) && dt2.Is(F64)) {
16806       EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
16807       AdvanceIT();
16808       return;
16809     }
16810   } else {
16811     // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
16812     if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
16813       EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16814               rm.Encode(5, 0));
16815       return;
16816     }
16817   }
16818   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
16819 }
16820 
vcvtm(DataType dt1,DataType dt2,DRegister rd,DRegister rm)16821 void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
16822   VIXL_ASSERT(AllowAssembler());
16823   CheckIT(al);
16824   Dt_op_3 encoded_dt(dt1);
16825   if (IsUsingT32()) {
16826     // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
16827     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16828       EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) |
16829                  rd.Encode(22, 12) | rm.Encode(5, 0));
16830       AdvanceIT();
16831       return;
16832     }
16833   } else {
16834     // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
16835     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16836       EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) |
16837               rd.Encode(22, 12) | rm.Encode(5, 0));
16838       return;
16839     }
16840   }
16841   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
16842 }
16843 
vcvtm(DataType dt1,DataType dt2,QRegister rd,QRegister rm)16844 void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
16845   VIXL_ASSERT(AllowAssembler());
16846   CheckIT(al);
16847   Dt_op_3 encoded_dt(dt1);
16848   if (IsUsingT32()) {
16849     // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
16850     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16851       EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) |
16852                  rd.Encode(22, 12) | rm.Encode(5, 0));
16853       AdvanceIT();
16854       return;
16855     }
16856   } else {
16857     // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
16858     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16859       EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) |
16860               rd.Encode(22, 12) | rm.Encode(5, 0));
16861       return;
16862     }
16863   }
16864   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
16865 }
16866 
vcvtm(DataType dt1,DataType dt2,SRegister rd,SRegister rm)16867 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16868   VIXL_ASSERT(AllowAssembler());
16869   CheckIT(al);
16870   Dt_op_2 encoded_dt(dt1);
16871   if (IsUsingT32()) {
16872     // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
16873     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16874       EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
16875                  rd.Encode(22, 12) | rm.Encode(5, 0));
16876       AdvanceIT();
16877       return;
16878     }
16879   } else {
16880     // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
16881     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16882       EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
16883               rd.Encode(22, 12) | rm.Encode(5, 0));
16884       return;
16885     }
16886   }
16887   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
16888 }
16889 
vcvtm(DataType dt1,DataType dt2,SRegister rd,DRegister rm)16890 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16891   VIXL_ASSERT(AllowAssembler());
16892   CheckIT(al);
16893   Dt_op_2 encoded_dt(dt1);
16894   if (IsUsingT32()) {
16895     // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
16896     if (encoded_dt.IsValid() && dt2.Is(F64)) {
16897       EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
16898                  rd.Encode(22, 12) | rm.Encode(5, 0));
16899       AdvanceIT();
16900       return;
16901     }
16902   } else {
16903     // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
16904     if (encoded_dt.IsValid() && dt2.Is(F64)) {
16905       EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
16906               rd.Encode(22, 12) | rm.Encode(5, 0));
16907       return;
16908     }
16909   }
16910   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
16911 }
16912 
vcvtn(DataType dt1,DataType dt2,DRegister rd,DRegister rm)16913 void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
16914   VIXL_ASSERT(AllowAssembler());
16915   CheckIT(al);
16916   Dt_op_3 encoded_dt(dt1);
16917   if (IsUsingT32()) {
16918     // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
16919     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16920       EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) |
16921                  rd.Encode(22, 12) | rm.Encode(5, 0));
16922       AdvanceIT();
16923       return;
16924     }
16925   } else {
16926     // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
16927     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16928       EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) |
16929               rd.Encode(22, 12) | rm.Encode(5, 0));
16930       return;
16931     }
16932   }
16933   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
16934 }
16935 
vcvtn(DataType dt1,DataType dt2,QRegister rd,QRegister rm)16936 void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
16937   VIXL_ASSERT(AllowAssembler());
16938   CheckIT(al);
16939   Dt_op_3 encoded_dt(dt1);
16940   if (IsUsingT32()) {
16941     // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
16942     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16943       EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) |
16944                  rd.Encode(22, 12) | rm.Encode(5, 0));
16945       AdvanceIT();
16946       return;
16947     }
16948   } else {
16949     // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
16950     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16951       EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) |
16952               rd.Encode(22, 12) | rm.Encode(5, 0));
16953       return;
16954     }
16955   }
16956   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
16957 }
16958 
vcvtn(DataType dt1,DataType dt2,SRegister rd,SRegister rm)16959 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16960   VIXL_ASSERT(AllowAssembler());
16961   CheckIT(al);
16962   Dt_op_2 encoded_dt(dt1);
16963   if (IsUsingT32()) {
16964     // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
16965     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16966       EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
16967                  rd.Encode(22, 12) | rm.Encode(5, 0));
16968       AdvanceIT();
16969       return;
16970     }
16971   } else {
16972     // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
16973     if (encoded_dt.IsValid() && dt2.Is(F32)) {
16974       EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
16975               rd.Encode(22, 12) | rm.Encode(5, 0));
16976       return;
16977     }
16978   }
16979   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
16980 }
16981 
vcvtn(DataType dt1,DataType dt2,SRegister rd,DRegister rm)16982 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16983   VIXL_ASSERT(AllowAssembler());
16984   CheckIT(al);
16985   Dt_op_2 encoded_dt(dt1);
16986   if (IsUsingT32()) {
16987     // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
16988     if (encoded_dt.IsValid() && dt2.Is(F64)) {
16989       EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
16990                  rd.Encode(22, 12) | rm.Encode(5, 0));
16991       AdvanceIT();
16992       return;
16993     }
16994   } else {
16995     // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
16996     if (encoded_dt.IsValid() && dt2.Is(F64)) {
16997       EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
16998               rd.Encode(22, 12) | rm.Encode(5, 0));
16999       return;
17000     }
17001   }
17002   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
17003 }
17004 
vcvtp(DataType dt1,DataType dt2,DRegister rd,DRegister rm)17005 void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
17006   VIXL_ASSERT(AllowAssembler());
17007   CheckIT(al);
17008   Dt_op_3 encoded_dt(dt1);
17009   if (IsUsingT32()) {
17010     // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
17011     if (encoded_dt.IsValid() && dt2.Is(F32)) {
17012       EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) |
17013                  rd.Encode(22, 12) | rm.Encode(5, 0));
17014       AdvanceIT();
17015       return;
17016     }
17017   } else {
17018     // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
17019     if (encoded_dt.IsValid() && dt2.Is(F32)) {
17020       EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) |
17021               rd.Encode(22, 12) | rm.Encode(5, 0));
17022       return;
17023     }
17024   }
17025   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
17026 }
17027 
vcvtp(DataType dt1,DataType dt2,QRegister rd,QRegister rm)17028 void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
17029   VIXL_ASSERT(AllowAssembler());
17030   CheckIT(al);
17031   Dt_op_3 encoded_dt(dt1);
17032   if (IsUsingT32()) {
17033     // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
17034     if (encoded_dt.IsValid() && dt2.Is(F32)) {
17035       EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) |
17036                  rd.Encode(22, 12) | rm.Encode(5, 0));
17037       AdvanceIT();
17038       return;
17039     }
17040   } else {
17041     // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
17042     if (encoded_dt.IsValid() && dt2.Is(F32)) {
17043       EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) |
17044               rd.Encode(22, 12) | rm.Encode(5, 0));
17045       return;
17046     }
17047   }
17048   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
17049 }
17050 
vcvtp(DataType dt1,DataType dt2,SRegister rd,SRegister rm)17051 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
17052   VIXL_ASSERT(AllowAssembler());
17053   CheckIT(al);
17054   Dt_op_2 encoded_dt(dt1);
17055   if (IsUsingT32()) {
17056     // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
17057     if (encoded_dt.IsValid() && dt2.Is(F32)) {
17058       EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
17059                  rd.Encode(22, 12) | rm.Encode(5, 0));
17060       AdvanceIT();
17061       return;
17062     }
17063   } else {
17064     // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
17065     if (encoded_dt.IsValid() && dt2.Is(F32)) {
17066       EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
17067               rd.Encode(22, 12) | rm.Encode(5, 0));
17068       return;
17069     }
17070   }
17071   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
17072 }
17073 
vcvtp(DataType dt1,DataType dt2,SRegister rd,DRegister rm)17074 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
17075   VIXL_ASSERT(AllowAssembler());
17076   CheckIT(al);
17077   Dt_op_2 encoded_dt(dt1);
17078   if (IsUsingT32()) {
17079     // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
17080     if (encoded_dt.IsValid() && dt2.Is(F64)) {
17081       EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
17082                  rd.Encode(22, 12) | rm.Encode(5, 0));
17083       AdvanceIT();
17084       return;
17085     }
17086   } else {
17087     // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
17088     if (encoded_dt.IsValid() && dt2.Is(F64)) {
17089       EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
17090               rd.Encode(22, 12) | rm.Encode(5, 0));
17091       return;
17092     }
17093   }
17094   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
17095 }
17096 
vcvtr(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)17097 void Assembler::vcvtr(
17098     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
17099   VIXL_ASSERT(AllowAssembler());
17100   CheckIT(cond);
17101   if (IsUsingT32()) {
17102     // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
17103     if (dt1.Is(U32) && dt2.Is(F32)) {
17104       EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
17105       AdvanceIT();
17106       return;
17107     }
17108     // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
17109     if (dt1.Is(S32) && dt2.Is(F32)) {
17110       EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
17111       AdvanceIT();
17112       return;
17113     }
17114   } else {
17115     // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
17116     if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
17117       EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17118               rm.Encode(5, 0));
17119       return;
17120     }
17121     // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
17122     if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
17123       EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17124               rm.Encode(5, 0));
17125       return;
17126     }
17127   }
17128   Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
17129 }
17130 
vcvtr(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)17131 void Assembler::vcvtr(
17132     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
17133   VIXL_ASSERT(AllowAssembler());
17134   CheckIT(cond);
17135   if (IsUsingT32()) {
17136     // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
17137     if (dt1.Is(U32) && dt2.Is(F64)) {
17138       EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
17139       AdvanceIT();
17140       return;
17141     }
17142     // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
17143     if (dt1.Is(S32) && dt2.Is(F64)) {
17144       EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
17145       AdvanceIT();
17146       return;
17147     }
17148   } else {
17149     // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
17150     if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
17151       EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17152               rm.Encode(5, 0));
17153       return;
17154     }
17155     // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
17156     if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
17157       EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17158               rm.Encode(5, 0));
17159       return;
17160     }
17161   }
17162   Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
17163 }
17164 
vcvtt(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)17165 void Assembler::vcvtt(
17166     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
17167   VIXL_ASSERT(AllowAssembler());
17168   CheckIT(cond);
17169   if (IsUsingT32()) {
17170     // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
17171     if (dt1.Is(F32) && dt2.Is(F16)) {
17172       EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
17173       AdvanceIT();
17174       return;
17175     }
17176     // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
17177     if (dt1.Is(F16) && dt2.Is(F32)) {
17178       EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
17179       AdvanceIT();
17180       return;
17181     }
17182   } else {
17183     // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
17184     if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
17185       EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17186               rm.Encode(5, 0));
17187       return;
17188     }
17189     // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
17190     if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
17191       EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17192               rm.Encode(5, 0));
17193       return;
17194     }
17195   }
17196   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
17197 }
17198 
vcvtt(Condition cond,DataType dt1,DataType dt2,DRegister rd,SRegister rm)17199 void Assembler::vcvtt(
17200     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
17201   VIXL_ASSERT(AllowAssembler());
17202   CheckIT(cond);
17203   if (IsUsingT32()) {
17204     // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
17205     if (dt1.Is(F64) && dt2.Is(F16)) {
17206       EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
17207       AdvanceIT();
17208       return;
17209     }
17210   } else {
17211     // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
17212     if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
17213       EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17214               rm.Encode(5, 0));
17215       return;
17216     }
17217   }
17218   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
17219 }
17220 
vcvtt(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)17221 void Assembler::vcvtt(
17222     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
17223   VIXL_ASSERT(AllowAssembler());
17224   CheckIT(cond);
17225   if (IsUsingT32()) {
17226     // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
17227     if (dt1.Is(F16) && dt2.Is(F64)) {
17228       EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
17229       AdvanceIT();
17230       return;
17231     }
17232   } else {
17233     // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
17234     if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
17235       EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17236               rm.Encode(5, 0));
17237       return;
17238     }
17239   }
17240   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
17241 }
17242 
vdiv(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)17243 void Assembler::vdiv(
17244     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
17245   VIXL_ASSERT(AllowAssembler());
17246   CheckIT(cond);
17247   if (IsUsingT32()) {
17248     // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
17249     if (dt.Is(F32)) {
17250       EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17251                  rm.Encode(5, 0));
17252       AdvanceIT();
17253       return;
17254     }
17255   } else {
17256     // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
17257     if (dt.Is(F32) && cond.IsNotNever()) {
17258       EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17259               rn.Encode(7, 16) | rm.Encode(5, 0));
17260       return;
17261     }
17262   }
17263   Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
17264 }
17265 
vdiv(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17266 void Assembler::vdiv(
17267     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17268   VIXL_ASSERT(AllowAssembler());
17269   CheckIT(cond);
17270   if (IsUsingT32()) {
17271     // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
17272     if (dt.Is(F64)) {
17273       EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17274                  rm.Encode(5, 0));
17275       AdvanceIT();
17276       return;
17277     }
17278   } else {
17279     // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
17280     if (dt.Is(F64) && cond.IsNotNever()) {
17281       EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17282               rn.Encode(7, 16) | rm.Encode(5, 0));
17283       return;
17284     }
17285   }
17286   Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
17287 }
17288 
vdup(Condition cond,DataType dt,QRegister rd,Register rt)17289 void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) {
17290   VIXL_ASSERT(AllowAssembler());
17291   CheckIT(cond);
17292   Dt_B_E_1 encoded_dt(dt);
17293   if (IsUsingT32()) {
17294     // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1
17295     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
17296       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17297         EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
17298                    ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
17299                    rd.Encode(7, 16) | (rt.GetCode() << 12));
17300         AdvanceIT();
17301         return;
17302       }
17303     }
17304   } else {
17305     // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1
17306     if (encoded_dt.IsValid() && cond.IsNotNever() &&
17307         (!rt.IsPC() || AllowUnpredictable())) {
17308       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17309         EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) |
17310                 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
17311                 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
17312                 rd.Encode(7, 16) | (rt.GetCode() << 12));
17313         return;
17314       }
17315     }
17316   }
17317   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
17318 }
17319 
vdup(Condition cond,DataType dt,DRegister rd,Register rt)17320 void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) {
17321   VIXL_ASSERT(AllowAssembler());
17322   CheckIT(cond);
17323   Dt_B_E_1 encoded_dt(dt);
17324   if (IsUsingT32()) {
17325     // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1
17326     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
17327       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17328         EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
17329                    ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
17330                    rd.Encode(7, 16) | (rt.GetCode() << 12));
17331         AdvanceIT();
17332         return;
17333       }
17334     }
17335   } else {
17336     // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1
17337     if (encoded_dt.IsValid() && cond.IsNotNever() &&
17338         (!rt.IsPC() || AllowUnpredictable())) {
17339       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17340         EmitA32(0x0e800b10U | (cond.GetCondition() << 28) |
17341                 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
17342                 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
17343                 rd.Encode(7, 16) | (rt.GetCode() << 12));
17344         return;
17345       }
17346     }
17347   }
17348   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
17349 }
17350 
vdup(Condition cond,DataType dt,DRegister rd,DRegisterLane rm)17351 void Assembler::vdup(Condition cond,
17352                      DataType dt,
17353                      DRegister rd,
17354                      DRegisterLane rm) {
17355   VIXL_ASSERT(AllowAssembler());
17356   CheckIT(cond);
17357   Dt_imm4_1 encoded_dt(dt, rm);
17358   if (IsUsingT32()) {
17359     // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1
17360     if (encoded_dt.IsValid()) {
17361       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17362         EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) |
17363                    rd.Encode(22, 12) | rm.Encode(5, 0));
17364         AdvanceIT();
17365         return;
17366       }
17367     }
17368   } else {
17369     // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1
17370     if (encoded_dt.IsValid()) {
17371       if (cond.Is(al)) {
17372         EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) |
17373                 rd.Encode(22, 12) | rm.Encode(5, 0));
17374         return;
17375       }
17376     }
17377   }
17378   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
17379 }
17380 
vdup(Condition cond,DataType dt,QRegister rd,DRegisterLane rm)17381 void Assembler::vdup(Condition cond,
17382                      DataType dt,
17383                      QRegister rd,
17384                      DRegisterLane rm) {
17385   VIXL_ASSERT(AllowAssembler());
17386   CheckIT(cond);
17387   Dt_imm4_1 encoded_dt(dt, rm);
17388   if (IsUsingT32()) {
17389     // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1
17390     if (encoded_dt.IsValid()) {
17391       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17392         EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) |
17393                    rd.Encode(22, 12) | rm.Encode(5, 0));
17394         AdvanceIT();
17395         return;
17396       }
17397     }
17398   } else {
17399     // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1
17400     if (encoded_dt.IsValid()) {
17401       if (cond.Is(al)) {
17402         EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) |
17403                 rd.Encode(22, 12) | rm.Encode(5, 0));
17404         return;
17405       }
17406     }
17407   }
17408   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
17409 }
17410 
veor(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17411 void Assembler::veor(
17412     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17413   VIXL_ASSERT(AllowAssembler());
17414   CheckIT(cond);
17415   USE(dt);
17416   if (IsUsingT32()) {
17417     // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
17418     if (cond.Is(al) || AllowStronglyDiscouraged()) {
17419       EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17420                  rm.Encode(5, 0));
17421       AdvanceIT();
17422       return;
17423     }
17424   } else {
17425     // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
17426     if (cond.Is(al)) {
17427       EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17428               rm.Encode(5, 0));
17429       return;
17430     }
17431   }
17432   Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
17433 }
17434 
veor(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)17435 void Assembler::veor(
17436     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
17437   VIXL_ASSERT(AllowAssembler());
17438   CheckIT(cond);
17439   USE(dt);
17440   if (IsUsingT32()) {
17441     // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
17442     if (cond.Is(al) || AllowStronglyDiscouraged()) {
17443       EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17444                  rm.Encode(5, 0));
17445       AdvanceIT();
17446       return;
17447     }
17448   } else {
17449     // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
17450     if (cond.Is(al)) {
17451       EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17452               rm.Encode(5, 0));
17453       return;
17454     }
17455   }
17456   Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
17457 }
17458 
vext(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm,const DOperand & operand)17459 void Assembler::vext(Condition cond,
17460                      DataType dt,
17461                      DRegister rd,
17462                      DRegister rn,
17463                      DRegister rm,
17464                      const DOperand& operand) {
17465   VIXL_ASSERT(AllowAssembler());
17466   CheckIT(cond);
17467   if (operand.IsImmediate()) {
17468     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
17469       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
17470       if (IsUsingT32()) {
17471         // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
17472         if (dt.Is(Untyped8) && (imm <= 7)) {
17473           if (cond.Is(al) || AllowStronglyDiscouraged()) {
17474             EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17475                        rm.Encode(5, 0) | (imm << 8));
17476             AdvanceIT();
17477             return;
17478           }
17479         }
17480         // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
17481         if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
17482             (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
17483           if (cond.Is(al) || AllowStronglyDiscouraged()) {
17484             uint32_t imm4 = imm / dt.GetSize();
17485             EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17486                        rm.Encode(5, 0) | (imm4 << 8));
17487             AdvanceIT();
17488             return;
17489           }
17490         }
17491       } else {
17492         // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
17493         if (dt.Is(Untyped8) && (imm <= 7)) {
17494           if (cond.Is(al)) {
17495             EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17496                     rm.Encode(5, 0) | (imm << 8));
17497             return;
17498           }
17499         }
17500         // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
17501         if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
17502             (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
17503           if (cond.Is(al)) {
17504             uint32_t imm4 = imm / dt.GetSize();
17505             EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17506                     rm.Encode(5, 0) | (imm4 << 8));
17507             return;
17508           }
17509         }
17510       }
17511     }
17512   }
17513   Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
17514 }
17515 
vext(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm,const QOperand & operand)17516 void Assembler::vext(Condition cond,
17517                      DataType dt,
17518                      QRegister rd,
17519                      QRegister rn,
17520                      QRegister rm,
17521                      const QOperand& operand) {
17522   VIXL_ASSERT(AllowAssembler());
17523   CheckIT(cond);
17524   if (operand.IsImmediate()) {
17525     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
17526       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
17527       if (IsUsingT32()) {
17528         // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
17529         if (dt.Is(Untyped8) && (imm <= 15)) {
17530           if (cond.Is(al) || AllowStronglyDiscouraged()) {
17531             EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17532                        rm.Encode(5, 0) | (imm << 8));
17533             AdvanceIT();
17534             return;
17535           }
17536         }
17537         // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
17538         if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
17539             (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
17540           if (cond.Is(al) || AllowStronglyDiscouraged()) {
17541             uint32_t imm4 = imm / dt.GetSize();
17542             EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17543                        rm.Encode(5, 0) | (imm4 << 8));
17544             AdvanceIT();
17545             return;
17546           }
17547         }
17548       } else {
17549         // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
17550         if (dt.Is(Untyped8) && (imm <= 15)) {
17551           if (cond.Is(al)) {
17552             EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17553                     rm.Encode(5, 0) | (imm << 8));
17554             return;
17555           }
17556         }
17557         // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
17558         if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
17559             (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
17560           if (cond.Is(al)) {
17561             uint32_t imm4 = imm / dt.GetSize();
17562             EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17563                     rm.Encode(5, 0) | (imm4 << 8));
17564             return;
17565           }
17566         }
17567       }
17568     }
17569   }
17570   Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
17571 }
17572 
vfma(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17573 void Assembler::vfma(
17574     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17575   VIXL_ASSERT(AllowAssembler());
17576   CheckIT(cond);
17577   if (IsUsingT32()) {
17578     // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
17579     if (dt.Is(F32)) {
17580       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17581         EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17582                    rm.Encode(5, 0));
17583         AdvanceIT();
17584         return;
17585       }
17586     }
17587     // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
17588     if (dt.Is(F64)) {
17589       EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17590                  rm.Encode(5, 0));
17591       AdvanceIT();
17592       return;
17593     }
17594   } else {
17595     // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
17596     if (dt.Is(F32)) {
17597       if (cond.Is(al)) {
17598         EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17599                 rm.Encode(5, 0));
17600         return;
17601       }
17602     }
17603     // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
17604     if (dt.Is(F64) && cond.IsNotNever()) {
17605       EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17606               rn.Encode(7, 16) | rm.Encode(5, 0));
17607       return;
17608     }
17609   }
17610   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
17611 }
17612 
vfma(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)17613 void Assembler::vfma(
17614     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
17615   VIXL_ASSERT(AllowAssembler());
17616   CheckIT(cond);
17617   if (IsUsingT32()) {
17618     // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
17619     if (dt.Is(F32)) {
17620       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17621         EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17622                    rm.Encode(5, 0));
17623         AdvanceIT();
17624         return;
17625       }
17626     }
17627   } else {
17628     // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
17629     if (dt.Is(F32)) {
17630       if (cond.Is(al)) {
17631         EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17632                 rm.Encode(5, 0));
17633         return;
17634       }
17635     }
17636   }
17637   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
17638 }
17639 
vfma(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)17640 void Assembler::vfma(
17641     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
17642   VIXL_ASSERT(AllowAssembler());
17643   CheckIT(cond);
17644   if (IsUsingT32()) {
17645     // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
17646     if (dt.Is(F32)) {
17647       EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17648                  rm.Encode(5, 0));
17649       AdvanceIT();
17650       return;
17651     }
17652   } else {
17653     // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
17654     if (dt.Is(F32) && cond.IsNotNever()) {
17655       EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17656               rn.Encode(7, 16) | rm.Encode(5, 0));
17657       return;
17658     }
17659   }
17660   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
17661 }
17662 
vfms(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17663 void Assembler::vfms(
17664     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17665   VIXL_ASSERT(AllowAssembler());
17666   CheckIT(cond);
17667   if (IsUsingT32()) {
17668     // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
17669     if (dt.Is(F32)) {
17670       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17671         EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17672                    rm.Encode(5, 0));
17673         AdvanceIT();
17674         return;
17675       }
17676     }
17677     // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
17678     if (dt.Is(F64)) {
17679       EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17680                  rm.Encode(5, 0));
17681       AdvanceIT();
17682       return;
17683     }
17684   } else {
17685     // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
17686     if (dt.Is(F32)) {
17687       if (cond.Is(al)) {
17688         EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17689                 rm.Encode(5, 0));
17690         return;
17691       }
17692     }
17693     // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
17694     if (dt.Is(F64) && cond.IsNotNever()) {
17695       EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17696               rn.Encode(7, 16) | rm.Encode(5, 0));
17697       return;
17698     }
17699   }
17700   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
17701 }
17702 
vfms(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)17703 void Assembler::vfms(
17704     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
17705   VIXL_ASSERT(AllowAssembler());
17706   CheckIT(cond);
17707   if (IsUsingT32()) {
17708     // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
17709     if (dt.Is(F32)) {
17710       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17711         EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17712                    rm.Encode(5, 0));
17713         AdvanceIT();
17714         return;
17715       }
17716     }
17717   } else {
17718     // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
17719     if (dt.Is(F32)) {
17720       if (cond.Is(al)) {
17721         EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17722                 rm.Encode(5, 0));
17723         return;
17724       }
17725     }
17726   }
17727   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
17728 }
17729 
vfms(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)17730 void Assembler::vfms(
17731     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
17732   VIXL_ASSERT(AllowAssembler());
17733   CheckIT(cond);
17734   if (IsUsingT32()) {
17735     // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
17736     if (dt.Is(F32)) {
17737       EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17738                  rm.Encode(5, 0));
17739       AdvanceIT();
17740       return;
17741     }
17742   } else {
17743     // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
17744     if (dt.Is(F32) && cond.IsNotNever()) {
17745       EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17746               rn.Encode(7, 16) | rm.Encode(5, 0));
17747       return;
17748     }
17749   }
17750   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
17751 }
17752 
vfnma(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)17753 void Assembler::vfnma(
17754     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
17755   VIXL_ASSERT(AllowAssembler());
17756   CheckIT(cond);
17757   if (IsUsingT32()) {
17758     // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
17759     if (dt.Is(F32)) {
17760       EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17761                  rm.Encode(5, 0));
17762       AdvanceIT();
17763       return;
17764     }
17765   } else {
17766     // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
17767     if (dt.Is(F32) && cond.IsNotNever()) {
17768       EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17769               rn.Encode(7, 16) | rm.Encode(5, 0));
17770       return;
17771     }
17772   }
17773   Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
17774 }
17775 
vfnma(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17776 void Assembler::vfnma(
17777     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17778   VIXL_ASSERT(AllowAssembler());
17779   CheckIT(cond);
17780   if (IsUsingT32()) {
17781     // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
17782     if (dt.Is(F64)) {
17783       EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17784                  rm.Encode(5, 0));
17785       AdvanceIT();
17786       return;
17787     }
17788   } else {
17789     // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
17790     if (dt.Is(F64) && cond.IsNotNever()) {
17791       EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17792               rn.Encode(7, 16) | rm.Encode(5, 0));
17793       return;
17794     }
17795   }
17796   Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
17797 }
17798 
vfnms(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)17799 void Assembler::vfnms(
17800     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
17801   VIXL_ASSERT(AllowAssembler());
17802   CheckIT(cond);
17803   if (IsUsingT32()) {
17804     // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
17805     if (dt.Is(F32)) {
17806       EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17807                  rm.Encode(5, 0));
17808       AdvanceIT();
17809       return;
17810     }
17811   } else {
17812     // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
17813     if (dt.Is(F32) && cond.IsNotNever()) {
17814       EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17815               rn.Encode(7, 16) | rm.Encode(5, 0));
17816       return;
17817     }
17818   }
17819   Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
17820 }
17821 
vfnms(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17822 void Assembler::vfnms(
17823     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17824   VIXL_ASSERT(AllowAssembler());
17825   CheckIT(cond);
17826   if (IsUsingT32()) {
17827     // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
17828     if (dt.Is(F64)) {
17829       EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17830                  rm.Encode(5, 0));
17831       AdvanceIT();
17832       return;
17833     }
17834   } else {
17835     // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
17836     if (dt.Is(F64) && cond.IsNotNever()) {
17837       EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17838               rn.Encode(7, 16) | rm.Encode(5, 0));
17839       return;
17840     }
17841   }
17842   Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
17843 }
17844 
vhadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17845 void Assembler::vhadd(
17846     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17847   VIXL_ASSERT(AllowAssembler());
17848   CheckIT(cond);
17849   Dt_U_size_1 encoded_dt(dt);
17850   if (IsUsingT32()) {
17851     // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
17852     if (encoded_dt.IsValid()) {
17853       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17854         EmitT32_32(0xef000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17855                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
17856                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17857         AdvanceIT();
17858         return;
17859       }
17860     }
17861   } else {
17862     // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
17863     if (encoded_dt.IsValid()) {
17864       if (cond.Is(al)) {
17865         EmitA32(0xf2000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17866                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
17867                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17868         return;
17869       }
17870     }
17871   }
17872   Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
17873 }
17874 
vhadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)17875 void Assembler::vhadd(
17876     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
17877   VIXL_ASSERT(AllowAssembler());
17878   CheckIT(cond);
17879   Dt_U_size_1 encoded_dt(dt);
17880   if (IsUsingT32()) {
17881     // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
17882     if (encoded_dt.IsValid()) {
17883       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17884         EmitT32_32(0xef000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17885                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
17886                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17887         AdvanceIT();
17888         return;
17889       }
17890     }
17891   } else {
17892     // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
17893     if (encoded_dt.IsValid()) {
17894       if (cond.Is(al)) {
17895         EmitA32(0xf2000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17896                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
17897                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17898         return;
17899       }
17900     }
17901   }
17902   Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
17903 }
17904 
vhsub(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17905 void Assembler::vhsub(
17906     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17907   VIXL_ASSERT(AllowAssembler());
17908   CheckIT(cond);
17909   Dt_U_size_1 encoded_dt(dt);
17910   if (IsUsingT32()) {
17911     // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
17912     if (encoded_dt.IsValid()) {
17913       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17914         EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17915                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
17916                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17917         AdvanceIT();
17918         return;
17919       }
17920     }
17921   } else {
17922     // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
17923     if (encoded_dt.IsValid()) {
17924       if (cond.Is(al)) {
17925         EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17926                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
17927                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17928         return;
17929       }
17930     }
17931   }
17932   Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
17933 }
17934 
vhsub(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)17935 void Assembler::vhsub(
17936     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
17937   VIXL_ASSERT(AllowAssembler());
17938   CheckIT(cond);
17939   Dt_U_size_1 encoded_dt(dt);
17940   if (IsUsingT32()) {
17941     // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
17942     if (encoded_dt.IsValid()) {
17943       if (cond.Is(al) || AllowStronglyDiscouraged()) {
17944         EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17945                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
17946                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17947         AdvanceIT();
17948         return;
17949       }
17950     }
17951   } else {
17952     // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
17953     if (encoded_dt.IsValid()) {
17954       if (cond.Is(al)) {
17955         EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17956                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
17957                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17958         return;
17959       }
17960     }
17961   }
17962   Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
17963 }
17964 
vld1(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)17965 void Assembler::vld1(Condition cond,
17966                      DataType dt,
17967                      const NeonRegisterList& nreglist,
17968                      const AlignedMemOperand& operand) {
17969   VIXL_ASSERT(AllowAssembler());
17970   CheckIT(cond);
17971   if (operand.IsImmediateZero()) {
17972     Register rn = operand.GetBaseRegister();
17973     Alignment align = operand.GetAlignment();
17974     Dt_size_6 encoded_dt(dt);
17975     Dt_size_7 encoded_dt_2(dt);
17976     Align_align_1 encoded_align_1(align, nreglist);
17977     Align_a_1 encoded_align_2(align, dt);
17978     Align_index_align_1 encoded_align_3(align, nreglist, dt);
17979     if (IsUsingT32()) {
17980       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17981       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17982           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
17983           operand.IsOffset() && encoded_align_1.IsValid() &&
17984           (!rn.IsPC() || AllowUnpredictable())) {
17985         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17986           const DRegister& first = nreglist.GetFirstDRegister();
17987           uint32_t len_encoding;
17988           switch (nreglist.GetLength()) {
17989             default:
17990               VIXL_UNREACHABLE_OR_FALLTHROUGH();
17991             case 1:
17992               len_encoding = 0x7;
17993               break;
17994             case 2:
17995               len_encoding = 0xa;
17996               break;
17997             case 3:
17998               len_encoding = 0x6;
17999               break;
18000             case 4:
18001               len_encoding = 0x2;
18002               break;
18003           }
18004           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
18005                      (encoded_align_1.GetEncodingValue() << 4) |
18006                      first.Encode(22, 12) | (len_encoding << 8) |
18007                      (rn.GetCode() << 16));
18008           AdvanceIT();
18009           return;
18010         }
18011       }
18012       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18013       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18014           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
18015           operand.IsPostIndex() && encoded_align_1.IsValid() &&
18016           (!rn.IsPC() || AllowUnpredictable())) {
18017         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18018           const DRegister& first = nreglist.GetFirstDRegister();
18019           uint32_t len_encoding;
18020           switch (nreglist.GetLength()) {
18021             default:
18022               VIXL_UNREACHABLE_OR_FALLTHROUGH();
18023             case 1:
18024               len_encoding = 0x7;
18025               break;
18026             case 2:
18027               len_encoding = 0xa;
18028               break;
18029             case 3:
18030               len_encoding = 0x6;
18031               break;
18032             case 4:
18033               len_encoding = 0x2;
18034               break;
18035           }
18036           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
18037                      (encoded_align_1.GetEncodingValue() << 4) |
18038                      first.Encode(22, 12) | (len_encoding << 8) |
18039                      (rn.GetCode() << 16));
18040           AdvanceIT();
18041           return;
18042         }
18043       }
18044       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18045       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18046           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18047           operand.IsOffset() && encoded_align_2.IsValid() &&
18048           (!rn.IsPC() || AllowUnpredictable())) {
18049         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18050           const DRegister& first = nreglist.GetFirstDRegister();
18051           uint32_t len_encoding = nreglist.GetLength() - 1;
18052           EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
18053                      (encoded_align_2.GetEncodingValue() << 4) |
18054                      first.Encode(22, 12) | (len_encoding << 5) |
18055                      (rn.GetCode() << 16));
18056           AdvanceIT();
18057           return;
18058         }
18059       }
18060       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18061       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18062           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18063           operand.IsPostIndex() && encoded_align_2.IsValid() &&
18064           (!rn.IsPC() || AllowUnpredictable())) {
18065         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18066           const DRegister& first = nreglist.GetFirstDRegister();
18067           uint32_t len_encoding = nreglist.GetLength() - 1;
18068           EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
18069                      (encoded_align_2.GetEncodingValue() << 4) |
18070                      first.Encode(22, 12) | (len_encoding << 5) |
18071                      (rn.GetCode() << 16));
18072           AdvanceIT();
18073           return;
18074         }
18075       }
18076       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18077       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18078           (nreglist.GetLength() == 1) && operand.IsOffset() &&
18079           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
18080         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18081           const DRegister& first = nreglist.GetFirstDRegister();
18082           EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
18083                      (encoded_align_3.GetEncodingValue() << 4) |
18084                      first.Encode(22, 12) | (rn.GetCode() << 16));
18085           AdvanceIT();
18086           return;
18087         }
18088       }
18089       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18090       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18091           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
18092           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
18093         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18094           const DRegister& first = nreglist.GetFirstDRegister();
18095           EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
18096                      (encoded_align_3.GetEncodingValue() << 4) |
18097                      first.Encode(22, 12) | (rn.GetCode() << 16));
18098           AdvanceIT();
18099           return;
18100         }
18101       }
18102     } else {
18103       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18104       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18105           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
18106           operand.IsOffset() && encoded_align_1.IsValid() &&
18107           (!rn.IsPC() || AllowUnpredictable())) {
18108         if (cond.Is(al)) {
18109           const DRegister& first = nreglist.GetFirstDRegister();
18110           uint32_t len_encoding;
18111           switch (nreglist.GetLength()) {
18112             default:
18113               VIXL_UNREACHABLE_OR_FALLTHROUGH();
18114             case 1:
18115               len_encoding = 0x7;
18116               break;
18117             case 2:
18118               len_encoding = 0xa;
18119               break;
18120             case 3:
18121               len_encoding = 0x6;
18122               break;
18123             case 4:
18124               len_encoding = 0x2;
18125               break;
18126           }
18127           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
18128                   (encoded_align_1.GetEncodingValue() << 4) |
18129                   first.Encode(22, 12) | (len_encoding << 8) |
18130                   (rn.GetCode() << 16));
18131           return;
18132         }
18133       }
18134       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18135       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18136           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
18137           operand.IsPostIndex() && encoded_align_1.IsValid() &&
18138           (!rn.IsPC() || AllowUnpredictable())) {
18139         if (cond.Is(al)) {
18140           const DRegister& first = nreglist.GetFirstDRegister();
18141           uint32_t len_encoding;
18142           switch (nreglist.GetLength()) {
18143             default:
18144               VIXL_UNREACHABLE_OR_FALLTHROUGH();
18145             case 1:
18146               len_encoding = 0x7;
18147               break;
18148             case 2:
18149               len_encoding = 0xa;
18150               break;
18151             case 3:
18152               len_encoding = 0x6;
18153               break;
18154             case 4:
18155               len_encoding = 0x2;
18156               break;
18157           }
18158           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
18159                   (encoded_align_1.GetEncodingValue() << 4) |
18160                   first.Encode(22, 12) | (len_encoding << 8) |
18161                   (rn.GetCode() << 16));
18162           return;
18163         }
18164       }
18165       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18166       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18167           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18168           operand.IsOffset() && encoded_align_2.IsValid() &&
18169           (!rn.IsPC() || AllowUnpredictable())) {
18170         if (cond.Is(al)) {
18171           const DRegister& first = nreglist.GetFirstDRegister();
18172           uint32_t len_encoding = nreglist.GetLength() - 1;
18173           EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
18174                   (encoded_align_2.GetEncodingValue() << 4) |
18175                   first.Encode(22, 12) | (len_encoding << 5) |
18176                   (rn.GetCode() << 16));
18177           return;
18178         }
18179       }
18180       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18181       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18182           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18183           operand.IsPostIndex() && encoded_align_2.IsValid() &&
18184           (!rn.IsPC() || AllowUnpredictable())) {
18185         if (cond.Is(al)) {
18186           const DRegister& first = nreglist.GetFirstDRegister();
18187           uint32_t len_encoding = nreglist.GetLength() - 1;
18188           EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
18189                   (encoded_align_2.GetEncodingValue() << 4) |
18190                   first.Encode(22, 12) | (len_encoding << 5) |
18191                   (rn.GetCode() << 16));
18192           return;
18193         }
18194       }
18195       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18196       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18197           (nreglist.GetLength() == 1) && operand.IsOffset() &&
18198           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
18199         if (cond.Is(al)) {
18200           const DRegister& first = nreglist.GetFirstDRegister();
18201           EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
18202                   (encoded_align_3.GetEncodingValue() << 4) |
18203                   first.Encode(22, 12) | (rn.GetCode() << 16));
18204           return;
18205         }
18206       }
18207       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18208       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18209           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
18210           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
18211         if (cond.Is(al)) {
18212           const DRegister& first = nreglist.GetFirstDRegister();
18213           EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
18214                   (encoded_align_3.GetEncodingValue() << 4) |
18215                   first.Encode(22, 12) | (rn.GetCode() << 16));
18216           return;
18217         }
18218       }
18219     }
18220   }
18221   if (operand.IsPlainRegister()) {
18222     Register rn = operand.GetBaseRegister();
18223     Alignment align = operand.GetAlignment();
18224     Register rm = operand.GetOffsetRegister();
18225     Dt_size_6 encoded_dt(dt);
18226     Dt_size_7 encoded_dt_2(dt);
18227     Align_align_1 encoded_align_1(align, nreglist);
18228     Align_a_1 encoded_align_2(align, dt);
18229     Align_index_align_1 encoded_align_3(align, nreglist, dt);
18230     if (IsUsingT32()) {
18231       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18232       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18233           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
18234           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18235         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18236           const DRegister& first = nreglist.GetFirstDRegister();
18237           uint32_t len_encoding;
18238           switch (nreglist.GetLength()) {
18239             default:
18240               VIXL_UNREACHABLE_OR_FALLTHROUGH();
18241             case 1:
18242               len_encoding = 0x7;
18243               break;
18244             case 2:
18245               len_encoding = 0xa;
18246               break;
18247             case 3:
18248               len_encoding = 0x6;
18249               break;
18250             case 4:
18251               len_encoding = 0x2;
18252               break;
18253           }
18254           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
18255                      (encoded_align_1.GetEncodingValue() << 4) |
18256                      first.Encode(22, 12) | (len_encoding << 8) |
18257                      (rn.GetCode() << 16) | rm.GetCode());
18258           AdvanceIT();
18259           return;
18260         }
18261       }
18262       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18263       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18264           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18265           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18266         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18267           const DRegister& first = nreglist.GetFirstDRegister();
18268           uint32_t len_encoding = nreglist.GetLength() - 1;
18269           EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
18270                      (encoded_align_2.GetEncodingValue() << 4) |
18271                      first.Encode(22, 12) | (len_encoding << 5) |
18272                      (rn.GetCode() << 16) | rm.GetCode());
18273           AdvanceIT();
18274           return;
18275         }
18276       }
18277       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18278       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18279           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
18280           (!rn.IsPC() || AllowUnpredictable())) {
18281         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18282           const DRegister& first = nreglist.GetFirstDRegister();
18283           EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
18284                      (encoded_align_3.GetEncodingValue() << 4) |
18285                      first.Encode(22, 12) | (rn.GetCode() << 16) |
18286                      rm.GetCode());
18287           AdvanceIT();
18288           return;
18289         }
18290       }
18291     } else {
18292       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18293       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18294           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
18295           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18296         if (cond.Is(al)) {
18297           const DRegister& first = nreglist.GetFirstDRegister();
18298           uint32_t len_encoding;
18299           switch (nreglist.GetLength()) {
18300             default:
18301               VIXL_UNREACHABLE_OR_FALLTHROUGH();
18302             case 1:
18303               len_encoding = 0x7;
18304               break;
18305             case 2:
18306               len_encoding = 0xa;
18307               break;
18308             case 3:
18309               len_encoding = 0x6;
18310               break;
18311             case 4:
18312               len_encoding = 0x2;
18313               break;
18314           }
18315           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
18316                   (encoded_align_1.GetEncodingValue() << 4) |
18317                   first.Encode(22, 12) | (len_encoding << 8) |
18318                   (rn.GetCode() << 16) | rm.GetCode());
18319           return;
18320         }
18321       }
18322       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18323       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18324           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18325           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18326         if (cond.Is(al)) {
18327           const DRegister& first = nreglist.GetFirstDRegister();
18328           uint32_t len_encoding = nreglist.GetLength() - 1;
18329           EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
18330                   (encoded_align_2.GetEncodingValue() << 4) |
18331                   first.Encode(22, 12) | (len_encoding << 5) |
18332                   (rn.GetCode() << 16) | rm.GetCode());
18333           return;
18334         }
18335       }
18336       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18337       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18338           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
18339           (!rn.IsPC() || AllowUnpredictable())) {
18340         if (cond.Is(al)) {
18341           const DRegister& first = nreglist.GetFirstDRegister();
18342           EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
18343                   (encoded_align_3.GetEncodingValue() << 4) |
18344                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
18345           return;
18346         }
18347       }
18348     }
18349   }
18350   Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand);
18351 }
18352 
vld2(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)18353 void Assembler::vld2(Condition cond,
18354                      DataType dt,
18355                      const NeonRegisterList& nreglist,
18356                      const AlignedMemOperand& operand) {
18357   VIXL_ASSERT(AllowAssembler());
18358   CheckIT(cond);
18359   if (operand.IsImmediateZero()) {
18360     Register rn = operand.GetBaseRegister();
18361     Alignment align = operand.GetAlignment();
18362     Dt_size_7 encoded_dt(dt);
18363     Align_align_2 encoded_align_1(align, nreglist);
18364     Align_a_2 encoded_align_2(align, dt);
18365     Align_index_align_2 encoded_align_3(align, nreglist, dt);
18366     if (IsUsingT32()) {
18367       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18368       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18369           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18370            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18371            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18372           operand.IsOffset() && encoded_align_1.IsValid() &&
18373           (!rn.IsPC() || AllowUnpredictable())) {
18374         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18375           const DRegister& first = nreglist.GetFirstDRegister();
18376           uint32_t len_encoding;
18377           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18378             len_encoding = 0x8;
18379           }
18380           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18381             len_encoding = 0x9;
18382           }
18383           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18384             len_encoding = 0x3;
18385           }
18386           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
18387                      (encoded_align_1.GetEncodingValue() << 4) |
18388                      first.Encode(22, 12) | (len_encoding << 8) |
18389                      (rn.GetCode() << 16));
18390           AdvanceIT();
18391           return;
18392         }
18393       }
18394       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18395       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18396           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18397            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18398            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18399           operand.IsPostIndex() && encoded_align_1.IsValid() &&
18400           (!rn.IsPC() || AllowUnpredictable())) {
18401         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18402           const DRegister& first = nreglist.GetFirstDRegister();
18403           uint32_t len_encoding;
18404           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18405             len_encoding = 0x8;
18406           }
18407           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18408             len_encoding = 0x9;
18409           }
18410           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18411             len_encoding = 0x3;
18412           }
18413           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
18414                      (encoded_align_1.GetEncodingValue() << 4) |
18415                      first.Encode(22, 12) | (len_encoding << 8) |
18416                      (rn.GetCode() << 16));
18417           AdvanceIT();
18418           return;
18419         }
18420       }
18421       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18422       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18423           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18424            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18425           operand.IsOffset() && encoded_align_2.IsValid() &&
18426           (!rn.IsPC() || AllowUnpredictable())) {
18427         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18428           const DRegister& first = nreglist.GetFirstDRegister();
18429           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18430           EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
18431                      (encoded_align_2.GetEncodingValue() << 4) |
18432                      first.Encode(22, 12) | (len_encoding << 5) |
18433                      (rn.GetCode() << 16));
18434           AdvanceIT();
18435           return;
18436         }
18437       }
18438       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18439       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18440           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18441            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18442           operand.IsPostIndex() && encoded_align_2.IsValid() &&
18443           (!rn.IsPC() || AllowUnpredictable())) {
18444         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18445           const DRegister& first = nreglist.GetFirstDRegister();
18446           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18447           EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
18448                      (encoded_align_2.GetEncodingValue() << 4) |
18449                      first.Encode(22, 12) | (len_encoding << 5) |
18450                      (rn.GetCode() << 16));
18451           AdvanceIT();
18452           return;
18453         }
18454       }
18455       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18456       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18457           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18458            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18459           operand.IsOffset() && encoded_align_3.IsValid() &&
18460           (!rn.IsPC() || AllowUnpredictable())) {
18461         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18462           const DRegister& first = nreglist.GetFirstDRegister();
18463           EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) |
18464                      (encoded_align_3.GetEncodingValue() << 4) |
18465                      first.Encode(22, 12) | (rn.GetCode() << 16));
18466           AdvanceIT();
18467           return;
18468         }
18469       }
18470       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18471       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18472           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18473            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18474           operand.IsPostIndex() && encoded_align_3.IsValid() &&
18475           (!rn.IsPC() || AllowUnpredictable())) {
18476         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18477           const DRegister& first = nreglist.GetFirstDRegister();
18478           EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) |
18479                      (encoded_align_3.GetEncodingValue() << 4) |
18480                      first.Encode(22, 12) | (rn.GetCode() << 16));
18481           AdvanceIT();
18482           return;
18483         }
18484       }
18485     } else {
18486       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18487       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18488           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18489            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18490            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18491           operand.IsOffset() && encoded_align_1.IsValid() &&
18492           (!rn.IsPC() || AllowUnpredictable())) {
18493         if (cond.Is(al)) {
18494           const DRegister& first = nreglist.GetFirstDRegister();
18495           uint32_t len_encoding;
18496           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18497             len_encoding = 0x8;
18498           }
18499           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18500             len_encoding = 0x9;
18501           }
18502           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18503             len_encoding = 0x3;
18504           }
18505           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
18506                   (encoded_align_1.GetEncodingValue() << 4) |
18507                   first.Encode(22, 12) | (len_encoding << 8) |
18508                   (rn.GetCode() << 16));
18509           return;
18510         }
18511       }
18512       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18513       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18514           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18515            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18516            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18517           operand.IsPostIndex() && encoded_align_1.IsValid() &&
18518           (!rn.IsPC() || AllowUnpredictable())) {
18519         if (cond.Is(al)) {
18520           const DRegister& first = nreglist.GetFirstDRegister();
18521           uint32_t len_encoding;
18522           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18523             len_encoding = 0x8;
18524           }
18525           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18526             len_encoding = 0x9;
18527           }
18528           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18529             len_encoding = 0x3;
18530           }
18531           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
18532                   (encoded_align_1.GetEncodingValue() << 4) |
18533                   first.Encode(22, 12) | (len_encoding << 8) |
18534                   (rn.GetCode() << 16));
18535           return;
18536         }
18537       }
18538       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18539       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18540           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18541            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18542           operand.IsOffset() && encoded_align_2.IsValid() &&
18543           (!rn.IsPC() || AllowUnpredictable())) {
18544         if (cond.Is(al)) {
18545           const DRegister& first = nreglist.GetFirstDRegister();
18546           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18547           EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
18548                   (encoded_align_2.GetEncodingValue() << 4) |
18549                   first.Encode(22, 12) | (len_encoding << 5) |
18550                   (rn.GetCode() << 16));
18551           return;
18552         }
18553       }
18554       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18555       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18556           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18557            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18558           operand.IsPostIndex() && encoded_align_2.IsValid() &&
18559           (!rn.IsPC() || AllowUnpredictable())) {
18560         if (cond.Is(al)) {
18561           const DRegister& first = nreglist.GetFirstDRegister();
18562           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18563           EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
18564                   (encoded_align_2.GetEncodingValue() << 4) |
18565                   first.Encode(22, 12) | (len_encoding << 5) |
18566                   (rn.GetCode() << 16));
18567           return;
18568         }
18569       }
18570       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18571       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18572           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18573            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18574           operand.IsOffset() && encoded_align_3.IsValid() &&
18575           (!rn.IsPC() || AllowUnpredictable())) {
18576         if (cond.Is(al)) {
18577           const DRegister& first = nreglist.GetFirstDRegister();
18578           EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) |
18579                   (encoded_align_3.GetEncodingValue() << 4) |
18580                   first.Encode(22, 12) | (rn.GetCode() << 16));
18581           return;
18582         }
18583       }
18584       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18585       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18586           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18587            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18588           operand.IsPostIndex() && encoded_align_3.IsValid() &&
18589           (!rn.IsPC() || AllowUnpredictable())) {
18590         if (cond.Is(al)) {
18591           const DRegister& first = nreglist.GetFirstDRegister();
18592           EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) |
18593                   (encoded_align_3.GetEncodingValue() << 4) |
18594                   first.Encode(22, 12) | (rn.GetCode() << 16));
18595           return;
18596         }
18597       }
18598     }
18599   }
18600   if (operand.IsPlainRegister()) {
18601     Register rn = operand.GetBaseRegister();
18602     Alignment align = operand.GetAlignment();
18603     Register rm = operand.GetOffsetRegister();
18604     Dt_size_7 encoded_dt(dt);
18605     Align_align_2 encoded_align_1(align, nreglist);
18606     Align_a_2 encoded_align_2(align, dt);
18607     Align_index_align_2 encoded_align_3(align, nreglist, dt);
18608     if (IsUsingT32()) {
18609       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18610       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18611           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18612            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18613            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18614           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18615         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18616           const DRegister& first = nreglist.GetFirstDRegister();
18617           uint32_t len_encoding;
18618           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18619             len_encoding = 0x8;
18620           }
18621           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18622             len_encoding = 0x9;
18623           }
18624           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18625             len_encoding = 0x3;
18626           }
18627           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
18628                      (encoded_align_1.GetEncodingValue() << 4) |
18629                      first.Encode(22, 12) | (len_encoding << 8) |
18630                      (rn.GetCode() << 16) | rm.GetCode());
18631           AdvanceIT();
18632           return;
18633         }
18634       }
18635       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18636       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18637           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18638            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18639           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18640         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18641           const DRegister& first = nreglist.GetFirstDRegister();
18642           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18643           EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) |
18644                      (encoded_align_2.GetEncodingValue() << 4) |
18645                      first.Encode(22, 12) | (len_encoding << 5) |
18646                      (rn.GetCode() << 16) | rm.GetCode());
18647           AdvanceIT();
18648           return;
18649         }
18650       }
18651       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18652       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18653           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18654            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18655           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18656         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18657           const DRegister& first = nreglist.GetFirstDRegister();
18658           EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) |
18659                      (encoded_align_3.GetEncodingValue() << 4) |
18660                      first.Encode(22, 12) | (rn.GetCode() << 16) |
18661                      rm.GetCode());
18662           AdvanceIT();
18663           return;
18664         }
18665       }
18666     } else {
18667       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18668       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18669           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18670            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18671            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18672           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18673         if (cond.Is(al)) {
18674           const DRegister& first = nreglist.GetFirstDRegister();
18675           uint32_t len_encoding;
18676           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18677             len_encoding = 0x8;
18678           }
18679           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18680             len_encoding = 0x9;
18681           }
18682           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18683             len_encoding = 0x3;
18684           }
18685           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
18686                   (encoded_align_1.GetEncodingValue() << 4) |
18687                   first.Encode(22, 12) | (len_encoding << 8) |
18688                   (rn.GetCode() << 16) | rm.GetCode());
18689           return;
18690         }
18691       }
18692       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18693       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18694           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18695            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18696           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18697         if (cond.Is(al)) {
18698           const DRegister& first = nreglist.GetFirstDRegister();
18699           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18700           EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) |
18701                   (encoded_align_2.GetEncodingValue() << 4) |
18702                   first.Encode(22, 12) | (len_encoding << 5) |
18703                   (rn.GetCode() << 16) | rm.GetCode());
18704           return;
18705         }
18706       }
18707       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18708       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18709           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18710            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18711           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18712         if (cond.Is(al)) {
18713           const DRegister& first = nreglist.GetFirstDRegister();
18714           EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) |
18715                   (encoded_align_3.GetEncodingValue() << 4) |
18716                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
18717           return;
18718         }
18719       }
18720     }
18721   }
18722   Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand);
18723 }
18724 
vld3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)18725 void Assembler::vld3(Condition cond,
18726                      DataType dt,
18727                      const NeonRegisterList& nreglist,
18728                      const AlignedMemOperand& operand) {
18729   VIXL_ASSERT(AllowAssembler());
18730   CheckIT(cond);
18731   if (operand.IsImmediateZero()) {
18732     Register rn = operand.GetBaseRegister();
18733     Alignment align = operand.GetAlignment();
18734     Dt_size_7 encoded_dt(dt);
18735     Align_align_3 encoded_align_1(align);
18736     if (IsUsingT32()) {
18737       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18738       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18739           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18740            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18741           operand.IsOffset() && encoded_align_1.IsValid() &&
18742           (!rn.IsPC() || AllowUnpredictable())) {
18743         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18744           const DRegister& first = nreglist.GetFirstDRegister();
18745           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18746           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
18747                      (encoded_align_1.GetEncodingValue() << 4) |
18748                      first.Encode(22, 12) | (len_encoding << 8) |
18749                      (rn.GetCode() << 16));
18750           AdvanceIT();
18751           return;
18752         }
18753       }
18754       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18755       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18756           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18757            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18758           operand.IsPostIndex() && encoded_align_1.IsValid() &&
18759           (!rn.IsPC() || AllowUnpredictable())) {
18760         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18761           const DRegister& first = nreglist.GetFirstDRegister();
18762           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18763           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
18764                      (encoded_align_1.GetEncodingValue() << 4) |
18765                      first.Encode(22, 12) | (len_encoding << 8) |
18766                      (rn.GetCode() << 16));
18767           AdvanceIT();
18768           return;
18769         }
18770       }
18771     } else {
18772       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18773       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18774           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18775            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18776           operand.IsOffset() && encoded_align_1.IsValid() &&
18777           (!rn.IsPC() || AllowUnpredictable())) {
18778         if (cond.Is(al)) {
18779           const DRegister& first = nreglist.GetFirstDRegister();
18780           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18781           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
18782                   (encoded_align_1.GetEncodingValue() << 4) |
18783                   first.Encode(22, 12) | (len_encoding << 8) |
18784                   (rn.GetCode() << 16));
18785           return;
18786         }
18787       }
18788       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18789       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18790           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18791            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18792           operand.IsPostIndex() && encoded_align_1.IsValid() &&
18793           (!rn.IsPC() || AllowUnpredictable())) {
18794         if (cond.Is(al)) {
18795           const DRegister& first = nreglist.GetFirstDRegister();
18796           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18797           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
18798                   (encoded_align_1.GetEncodingValue() << 4) |
18799                   first.Encode(22, 12) | (len_encoding << 8) |
18800                   (rn.GetCode() << 16));
18801           return;
18802         }
18803       }
18804     }
18805   }
18806   if (operand.IsPlainRegister()) {
18807     Register rn = operand.GetBaseRegister();
18808     Alignment align = operand.GetAlignment();
18809     Register rm = operand.GetOffsetRegister();
18810     Dt_size_7 encoded_dt(dt);
18811     Align_align_3 encoded_align_1(align);
18812     if (IsUsingT32()) {
18813       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18814       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18815           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18816            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18817           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18818         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18819           const DRegister& first = nreglist.GetFirstDRegister();
18820           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18821           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
18822                      (encoded_align_1.GetEncodingValue() << 4) |
18823                      first.Encode(22, 12) | (len_encoding << 8) |
18824                      (rn.GetCode() << 16) | rm.GetCode());
18825           AdvanceIT();
18826           return;
18827         }
18828       }
18829     } else {
18830       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18831       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18832           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18833            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18834           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18835         if (cond.Is(al)) {
18836           const DRegister& first = nreglist.GetFirstDRegister();
18837           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18838           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
18839                   (encoded_align_1.GetEncodingValue() << 4) |
18840                   first.Encode(22, 12) | (len_encoding << 8) |
18841                   (rn.GetCode() << 16) | rm.GetCode());
18842           return;
18843         }
18844       }
18845     }
18846   }
18847   Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
18848 }
18849 
vld3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const MemOperand & operand)18850 void Assembler::vld3(Condition cond,
18851                      DataType dt,
18852                      const NeonRegisterList& nreglist,
18853                      const MemOperand& operand) {
18854   VIXL_ASSERT(AllowAssembler());
18855   CheckIT(cond);
18856   if (operand.IsImmediateZero()) {
18857     Register rn = operand.GetBaseRegister();
18858     Dt_size_7 encoded_dt(dt);
18859     Index_1 encoded_align_1(nreglist, dt);
18860     if (IsUsingT32()) {
18861       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
18862       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18863           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18864            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18865           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
18866         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18867           const DRegister& first = nreglist.GetFirstDRegister();
18868           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18869           EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
18870                      first.Encode(22, 12) | (len_encoding << 5) |
18871                      (rn.GetCode() << 16));
18872           AdvanceIT();
18873           return;
18874         }
18875       }
18876       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
18877       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18878           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18879            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18880           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
18881         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18882           const DRegister& first = nreglist.GetFirstDRegister();
18883           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18884           EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
18885                      first.Encode(22, 12) | (len_encoding << 5) |
18886                      (rn.GetCode() << 16));
18887           AdvanceIT();
18888           return;
18889         }
18890       }
18891       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
18892       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18893           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18894            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18895           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
18896         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18897           const DRegister& first = nreglist.GetFirstDRegister();
18898           EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) |
18899                      (encoded_align_1.GetEncodingValue() << 4) |
18900                      first.Encode(22, 12) | (rn.GetCode() << 16));
18901           AdvanceIT();
18902           return;
18903         }
18904       }
18905       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
18906       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18907           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18908            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18909           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
18910         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18911           const DRegister& first = nreglist.GetFirstDRegister();
18912           EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) |
18913                      (encoded_align_1.GetEncodingValue() << 4) |
18914                      first.Encode(22, 12) | (rn.GetCode() << 16));
18915           AdvanceIT();
18916           return;
18917         }
18918       }
18919     } else {
18920       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
18921       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18922           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18923            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18924           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
18925         if (cond.Is(al)) {
18926           const DRegister& first = nreglist.GetFirstDRegister();
18927           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18928           EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
18929                   first.Encode(22, 12) | (len_encoding << 5) |
18930                   (rn.GetCode() << 16));
18931           return;
18932         }
18933       }
18934       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
18935       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18936           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18937            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18938           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
18939         if (cond.Is(al)) {
18940           const DRegister& first = nreglist.GetFirstDRegister();
18941           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18942           EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
18943                   first.Encode(22, 12) | (len_encoding << 5) |
18944                   (rn.GetCode() << 16));
18945           return;
18946         }
18947       }
18948       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
18949       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18950           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18951            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18952           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
18953         if (cond.Is(al)) {
18954           const DRegister& first = nreglist.GetFirstDRegister();
18955           EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) |
18956                   (encoded_align_1.GetEncodingValue() << 4) |
18957                   first.Encode(22, 12) | (rn.GetCode() << 16));
18958           return;
18959         }
18960       }
18961       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
18962       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18963           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18964            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18965           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
18966         if (cond.Is(al)) {
18967           const DRegister& first = nreglist.GetFirstDRegister();
18968           EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) |
18969                   (encoded_align_1.GetEncodingValue() << 4) |
18970                   first.Encode(22, 12) | (rn.GetCode() << 16));
18971           return;
18972         }
18973       }
18974     }
18975   }
18976   if (operand.IsPlainRegister()) {
18977     Register rn = operand.GetBaseRegister();
18978     Sign sign = operand.GetSign();
18979     Register rm = operand.GetOffsetRegister();
18980     Dt_size_7 encoded_dt(dt);
18981     Index_1 encoded_align_1(nreglist, dt);
18982     if (IsUsingT32()) {
18983       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
18984       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18985           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18986            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18987           sign.IsPlus() && operand.IsPostIndex() &&
18988           (!rn.IsPC() || AllowUnpredictable())) {
18989         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18990           const DRegister& first = nreglist.GetFirstDRegister();
18991           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18992           EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) |
18993                      first.Encode(22, 12) | (len_encoding << 5) |
18994                      (rn.GetCode() << 16) | rm.GetCode());
18995           AdvanceIT();
18996           return;
18997         }
18998       }
18999       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
19000       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19001           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
19002            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
19003           sign.IsPlus() && operand.IsPostIndex() &&
19004           (!rn.IsPC() || AllowUnpredictable())) {
19005         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19006           const DRegister& first = nreglist.GetFirstDRegister();
19007           EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) |
19008                      (encoded_align_1.GetEncodingValue() << 4) |
19009                      first.Encode(22, 12) | (rn.GetCode() << 16) |
19010                      rm.GetCode());
19011           AdvanceIT();
19012           return;
19013         }
19014       }
19015     } else {
19016       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
19017       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
19018           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
19019            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
19020           sign.IsPlus() && operand.IsPostIndex() &&
19021           (!rn.IsPC() || AllowUnpredictable())) {
19022         if (cond.Is(al)) {
19023           const DRegister& first = nreglist.GetFirstDRegister();
19024           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19025           EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) |
19026                   first.Encode(22, 12) | (len_encoding << 5) |
19027                   (rn.GetCode() << 16) | rm.GetCode());
19028           return;
19029         }
19030       }
19031       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
19032       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19033           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
19034            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
19035           sign.IsPlus() && operand.IsPostIndex() &&
19036           (!rn.IsPC() || AllowUnpredictable())) {
19037         if (cond.Is(al)) {
19038           const DRegister& first = nreglist.GetFirstDRegister();
19039           EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) |
19040                   (encoded_align_1.GetEncodingValue() << 4) |
19041                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
19042           return;
19043         }
19044       }
19045     }
19046   }
19047   Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
19048 }
19049 
vld4(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)19050 void Assembler::vld4(Condition cond,
19051                      DataType dt,
19052                      const NeonRegisterList& nreglist,
19053                      const AlignedMemOperand& operand) {
19054   VIXL_ASSERT(AllowAssembler());
19055   CheckIT(cond);
19056   if (operand.IsImmediateZero()) {
19057     Register rn = operand.GetBaseRegister();
19058     Alignment align = operand.GetAlignment();
19059     Dt_size_7 encoded_dt(dt);
19060     Dt_size_8 encoded_dt_2(dt, align);
19061     Align_align_4 encoded_align_1(align);
19062     Align_a_3 encoded_align_2(align, dt);
19063     Align_index_align_3 encoded_align_3(align, nreglist, dt);
19064     if (IsUsingT32()) {
19065       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
19066       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19067           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19068            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19069           operand.IsOffset() && encoded_align_1.IsValid() &&
19070           (!rn.IsPC() || AllowUnpredictable())) {
19071         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19072           const DRegister& first = nreglist.GetFirstDRegister();
19073           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19074           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
19075                      (encoded_align_1.GetEncodingValue() << 4) |
19076                      first.Encode(22, 12) | (len_encoding << 8) |
19077                      (rn.GetCode() << 16));
19078           AdvanceIT();
19079           return;
19080         }
19081       }
19082       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
19083       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19084           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19085            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19086           operand.IsPostIndex() && encoded_align_1.IsValid() &&
19087           (!rn.IsPC() || AllowUnpredictable())) {
19088         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19089           const DRegister& first = nreglist.GetFirstDRegister();
19090           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19091           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
19092                      (encoded_align_1.GetEncodingValue() << 4) |
19093                      first.Encode(22, 12) | (len_encoding << 8) |
19094                      (rn.GetCode() << 16));
19095           AdvanceIT();
19096           return;
19097         }
19098       }
19099       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
19100       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19101           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19102            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19103           operand.IsOffset() && encoded_align_2.IsValid() &&
19104           (!rn.IsPC() || AllowUnpredictable())) {
19105         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19106           const DRegister& first = nreglist.GetFirstDRegister();
19107           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19108           EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
19109                      (encoded_align_2.GetEncodingValue() << 4) |
19110                      first.Encode(22, 12) | (len_encoding << 5) |
19111                      (rn.GetCode() << 16));
19112           AdvanceIT();
19113           return;
19114         }
19115       }
19116       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
19117       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19118           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19119            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19120           operand.IsPostIndex() && encoded_align_2.IsValid() &&
19121           (!rn.IsPC() || AllowUnpredictable())) {
19122         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19123           const DRegister& first = nreglist.GetFirstDRegister();
19124           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19125           EmitT32_32(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
19126                      (encoded_align_2.GetEncodingValue() << 4) |
19127                      first.Encode(22, 12) | (len_encoding << 5) |
19128                      (rn.GetCode() << 16));
19129           AdvanceIT();
19130           return;
19131         }
19132       }
19133       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
19134       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19135           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19136            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19137           operand.IsOffset() && encoded_align_3.IsValid() &&
19138           (!rn.IsPC() || AllowUnpredictable())) {
19139         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19140           const DRegister& first = nreglist.GetFirstDRegister();
19141           EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) |
19142                      (encoded_align_3.GetEncodingValue() << 4) |
19143                      first.Encode(22, 12) | (rn.GetCode() << 16));
19144           AdvanceIT();
19145           return;
19146         }
19147       }
19148       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
19149       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19150           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19151            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19152           operand.IsPostIndex() && encoded_align_3.IsValid() &&
19153           (!rn.IsPC() || AllowUnpredictable())) {
19154         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19155           const DRegister& first = nreglist.GetFirstDRegister();
19156           EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) |
19157                      (encoded_align_3.GetEncodingValue() << 4) |
19158                      first.Encode(22, 12) | (rn.GetCode() << 16));
19159           AdvanceIT();
19160           return;
19161         }
19162       }
19163     } else {
19164       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
19165       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19166           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19167            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19168           operand.IsOffset() && encoded_align_1.IsValid() &&
19169           (!rn.IsPC() || AllowUnpredictable())) {
19170         if (cond.Is(al)) {
19171           const DRegister& first = nreglist.GetFirstDRegister();
19172           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19173           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
19174                   (encoded_align_1.GetEncodingValue() << 4) |
19175                   first.Encode(22, 12) | (len_encoding << 8) |
19176                   (rn.GetCode() << 16));
19177           return;
19178         }
19179       }
19180       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
19181       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19182           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19183            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19184           operand.IsPostIndex() && encoded_align_1.IsValid() &&
19185           (!rn.IsPC() || AllowUnpredictable())) {
19186         if (cond.Is(al)) {
19187           const DRegister& first = nreglist.GetFirstDRegister();
19188           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19189           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
19190                   (encoded_align_1.GetEncodingValue() << 4) |
19191                   first.Encode(22, 12) | (len_encoding << 8) |
19192                   (rn.GetCode() << 16));
19193           return;
19194         }
19195       }
19196       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
19197       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19198           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19199            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19200           operand.IsOffset() && encoded_align_2.IsValid() &&
19201           (!rn.IsPC() || AllowUnpredictable())) {
19202         if (cond.Is(al)) {
19203           const DRegister& first = nreglist.GetFirstDRegister();
19204           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19205           EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
19206                   (encoded_align_2.GetEncodingValue() << 4) |
19207                   first.Encode(22, 12) | (len_encoding << 5) |
19208                   (rn.GetCode() << 16));
19209           return;
19210         }
19211       }
19212       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
19213       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19214           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19215            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19216           operand.IsPostIndex() && encoded_align_2.IsValid() &&
19217           (!rn.IsPC() || AllowUnpredictable())) {
19218         if (cond.Is(al)) {
19219           const DRegister& first = nreglist.GetFirstDRegister();
19220           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19221           EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
19222                   (encoded_align_2.GetEncodingValue() << 4) |
19223                   first.Encode(22, 12) | (len_encoding << 5) |
19224                   (rn.GetCode() << 16));
19225           return;
19226         }
19227       }
19228       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
19229       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19230           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19231            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19232           operand.IsOffset() && encoded_align_3.IsValid() &&
19233           (!rn.IsPC() || AllowUnpredictable())) {
19234         if (cond.Is(al)) {
19235           const DRegister& first = nreglist.GetFirstDRegister();
19236           EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) |
19237                   (encoded_align_3.GetEncodingValue() << 4) |
19238                   first.Encode(22, 12) | (rn.GetCode() << 16));
19239           return;
19240         }
19241       }
19242       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
19243       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19244           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19245            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19246           operand.IsPostIndex() && encoded_align_3.IsValid() &&
19247           (!rn.IsPC() || AllowUnpredictable())) {
19248         if (cond.Is(al)) {
19249           const DRegister& first = nreglist.GetFirstDRegister();
19250           EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) |
19251                   (encoded_align_3.GetEncodingValue() << 4) |
19252                   first.Encode(22, 12) | (rn.GetCode() << 16));
19253           return;
19254         }
19255       }
19256     }
19257   }
19258   if (operand.IsPlainRegister()) {
19259     Register rn = operand.GetBaseRegister();
19260     Alignment align = operand.GetAlignment();
19261     Register rm = operand.GetOffsetRegister();
19262     Dt_size_7 encoded_dt(dt);
19263     Dt_size_8 encoded_dt_2(dt, align);
19264     Align_align_4 encoded_align_1(align);
19265     Align_a_3 encoded_align_2(align, dt);
19266     Align_index_align_3 encoded_align_3(align, nreglist, dt);
19267     if (IsUsingT32()) {
19268       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
19269       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19270           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19271            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19272           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19273         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19274           const DRegister& first = nreglist.GetFirstDRegister();
19275           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19276           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
19277                      (encoded_align_1.GetEncodingValue() << 4) |
19278                      first.Encode(22, 12) | (len_encoding << 8) |
19279                      (rn.GetCode() << 16) | rm.GetCode());
19280           AdvanceIT();
19281           return;
19282         }
19283       }
19284       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
19285       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19286           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19287            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19288           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19289         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19290           const DRegister& first = nreglist.GetFirstDRegister();
19291           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19292           EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
19293                      (encoded_align_2.GetEncodingValue() << 4) |
19294                      first.Encode(22, 12) | (len_encoding << 5) |
19295                      (rn.GetCode() << 16) | rm.GetCode());
19296           AdvanceIT();
19297           return;
19298         }
19299       }
19300       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
19301       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19302           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19303            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19304           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19305         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19306           const DRegister& first = nreglist.GetFirstDRegister();
19307           EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) |
19308                      (encoded_align_3.GetEncodingValue() << 4) |
19309                      first.Encode(22, 12) | (rn.GetCode() << 16) |
19310                      rm.GetCode());
19311           AdvanceIT();
19312           return;
19313         }
19314       }
19315     } else {
19316       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
19317       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19318           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19319            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19320           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19321         if (cond.Is(al)) {
19322           const DRegister& first = nreglist.GetFirstDRegister();
19323           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19324           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
19325                   (encoded_align_1.GetEncodingValue() << 4) |
19326                   first.Encode(22, 12) | (len_encoding << 8) |
19327                   (rn.GetCode() << 16) | rm.GetCode());
19328           return;
19329         }
19330       }
19331       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
19332       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19333           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19334            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19335           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19336         if (cond.Is(al)) {
19337           const DRegister& first = nreglist.GetFirstDRegister();
19338           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19339           EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
19340                   (encoded_align_2.GetEncodingValue() << 4) |
19341                   first.Encode(22, 12) | (len_encoding << 5) |
19342                   (rn.GetCode() << 16) | rm.GetCode());
19343           return;
19344         }
19345       }
19346       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
19347       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19348           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19349            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19350           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19351         if (cond.Is(al)) {
19352           const DRegister& first = nreglist.GetFirstDRegister();
19353           EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) |
19354                   (encoded_align_3.GetEncodingValue() << 4) |
19355                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
19356           return;
19357         }
19358       }
19359     }
19360   }
19361   Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand);
19362 }
19363 
vldm(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)19364 void Assembler::vldm(Condition cond,
19365                      DataType dt,
19366                      Register rn,
19367                      WriteBack write_back,
19368                      DRegisterList dreglist) {
19369   VIXL_ASSERT(AllowAssembler());
19370   CheckIT(cond);
19371   USE(dt);
19372   if (IsUsingT32()) {
19373     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
19374     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
19375          AllowUnpredictable())) {
19376       const DRegister& dreg = dreglist.GetFirstDRegister();
19377       unsigned len = dreglist.GetLength() * 2;
19378       EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
19379                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
19380                  (len & 0xff));
19381       AdvanceIT();
19382       return;
19383     }
19384   } else {
19385     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
19386     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
19387                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
19388                               AllowUnpredictable())) {
19389       const DRegister& dreg = dreglist.GetFirstDRegister();
19390       unsigned len = dreglist.GetLength() * 2;
19391       EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19392               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
19393               (len & 0xff));
19394       return;
19395     }
19396   }
19397   Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist);
19398 }
19399 
vldm(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)19400 void Assembler::vldm(Condition cond,
19401                      DataType dt,
19402                      Register rn,
19403                      WriteBack write_back,
19404                      SRegisterList sreglist) {
19405   VIXL_ASSERT(AllowAssembler());
19406   CheckIT(cond);
19407   USE(dt);
19408   if (IsUsingT32()) {
19409     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
19410     if ((!rn.IsPC() || AllowUnpredictable())) {
19411       const SRegister& sreg = sreglist.GetFirstSRegister();
19412       unsigned len = sreglist.GetLength();
19413       EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
19414                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
19415                  (len & 0xff));
19416       AdvanceIT();
19417       return;
19418     }
19419   } else {
19420     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
19421     if (cond.IsNotNever() &&
19422         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
19423       const SRegister& sreg = sreglist.GetFirstSRegister();
19424       unsigned len = sreglist.GetLength();
19425       EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19426               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
19427               (len & 0xff));
19428       return;
19429     }
19430   }
19431   Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist);
19432 }
19433 
vldmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)19434 void Assembler::vldmdb(Condition cond,
19435                        DataType dt,
19436                        Register rn,
19437                        WriteBack write_back,
19438                        DRegisterList dreglist) {
19439   VIXL_ASSERT(AllowAssembler());
19440   CheckIT(cond);
19441   USE(dt);
19442   if (IsUsingT32()) {
19443     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
19444     if (write_back.DoesWriteBack() &&
19445         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
19446          AllowUnpredictable())) {
19447       const DRegister& dreg = dreglist.GetFirstDRegister();
19448       unsigned len = dreglist.GetLength() * 2;
19449       EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
19450                  (len & 0xff));
19451       AdvanceIT();
19452       return;
19453     }
19454   } else {
19455     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
19456     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
19457         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
19458          AllowUnpredictable())) {
19459       const DRegister& dreg = dreglist.GetFirstDRegister();
19460       unsigned len = dreglist.GetLength() * 2;
19461       EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19462               dreg.Encode(22, 12) | (len & 0xff));
19463       return;
19464     }
19465   }
19466   Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist);
19467 }
19468 
vldmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)19469 void Assembler::vldmdb(Condition cond,
19470                        DataType dt,
19471                        Register rn,
19472                        WriteBack write_back,
19473                        SRegisterList sreglist) {
19474   VIXL_ASSERT(AllowAssembler());
19475   CheckIT(cond);
19476   USE(dt);
19477   if (IsUsingT32()) {
19478     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
19479     if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) {
19480       const SRegister& sreg = sreglist.GetFirstSRegister();
19481       unsigned len = sreglist.GetLength();
19482       EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
19483                  (len & 0xff));
19484       AdvanceIT();
19485       return;
19486     }
19487   } else {
19488     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
19489     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
19490         (!rn.IsPC() || AllowUnpredictable())) {
19491       const SRegister& sreg = sreglist.GetFirstSRegister();
19492       unsigned len = sreglist.GetLength();
19493       EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19494               sreg.Encode(22, 12) | (len & 0xff));
19495       return;
19496     }
19497   }
19498   Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist);
19499 }
19500 
vldmia(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)19501 void Assembler::vldmia(Condition cond,
19502                        DataType dt,
19503                        Register rn,
19504                        WriteBack write_back,
19505                        DRegisterList dreglist) {
19506   VIXL_ASSERT(AllowAssembler());
19507   CheckIT(cond);
19508   USE(dt);
19509   if (IsUsingT32()) {
19510     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
19511     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
19512          AllowUnpredictable())) {
19513       const DRegister& dreg = dreglist.GetFirstDRegister();
19514       unsigned len = dreglist.GetLength() * 2;
19515       EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
19516                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
19517                  (len & 0xff));
19518       AdvanceIT();
19519       return;
19520     }
19521   } else {
19522     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
19523     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
19524                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
19525                               AllowUnpredictable())) {
19526       const DRegister& dreg = dreglist.GetFirstDRegister();
19527       unsigned len = dreglist.GetLength() * 2;
19528       EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19529               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
19530               (len & 0xff));
19531       return;
19532     }
19533   }
19534   Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist);
19535 }
19536 
vldmia(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)19537 void Assembler::vldmia(Condition cond,
19538                        DataType dt,
19539                        Register rn,
19540                        WriteBack write_back,
19541                        SRegisterList sreglist) {
19542   VIXL_ASSERT(AllowAssembler());
19543   CheckIT(cond);
19544   USE(dt);
19545   if (IsUsingT32()) {
19546     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
19547     if ((!rn.IsPC() || AllowUnpredictable())) {
19548       const SRegister& sreg = sreglist.GetFirstSRegister();
19549       unsigned len = sreglist.GetLength();
19550       EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
19551                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
19552                  (len & 0xff));
19553       AdvanceIT();
19554       return;
19555     }
19556   } else {
19557     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
19558     if (cond.IsNotNever() &&
19559         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
19560       const SRegister& sreg = sreglist.GetFirstSRegister();
19561       unsigned len = sreglist.GetLength();
19562       EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19563               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
19564               (len & 0xff));
19565       return;
19566     }
19567   }
19568   Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist);
19569 }
19570 
vldr(Condition cond,DataType dt,DRegister rd,Location * location)19571 void Assembler::vldr(Condition cond,
19572                      DataType dt,
19573                      DRegister rd,
19574                      Location* location) {
19575   VIXL_ASSERT(AllowAssembler());
19576   CheckIT(cond);
19577   Location::Offset offset =
19578       location->IsBound()
19579           ? location->GetLocation() -
19580                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
19581           : 0;
19582   if (IsUsingT32()) {
19583     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
19584     if (dt.IsNoneOr(Untyped64) &&
19585         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
19586           ((offset & 0x3) == 0)) ||
19587          !location->IsBound())) {
19588       static class EmitOp : public Location::EmitOperator {
19589        public:
19590         EmitOp() : Location::EmitOperator(T32) {}
19591         virtual uint32_t Encode(uint32_t instr,
19592                                 Location::Offset pc,
19593                                 const Location* location) const VIXL_OVERRIDE {
19594           pc += kT32PcDelta;
19595           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
19596           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
19597                       ((offset & 0x3) == 0));
19598           int32_t target = offset >> 2;
19599           uint32_t U = (target >= 0);
19600           target = abs(target) | (U << 8);
19601           return instr | (target & 0xff) | ((target & 0x100) << 15);
19602         }
19603       } immop;
19604       EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12),
19605                       location,
19606                       immop,
19607                       &kT32DataInfo));
19608       AdvanceIT();
19609       return;
19610     }
19611   } else {
19612     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
19613     if (dt.IsNoneOr(Untyped64) &&
19614         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
19615           ((offset & 0x3) == 0)) ||
19616          !location->IsBound()) &&
19617         cond.IsNotNever()) {
19618       static class EmitOp : public Location::EmitOperator {
19619        public:
19620         EmitOp() : Location::EmitOperator(A32) {}
19621         virtual uint32_t Encode(uint32_t instr,
19622                                 Location::Offset pc,
19623                                 const Location* location) const VIXL_OVERRIDE {
19624           pc += kA32PcDelta;
19625           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
19626           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
19627                       ((offset & 0x3) == 0));
19628           int32_t target = offset >> 2;
19629           uint32_t U = (target >= 0);
19630           target = abs(target) | (U << 8);
19631           return instr | (target & 0xff) | ((target & 0x100) << 15);
19632         }
19633       } immop;
19634       EmitA32(
19635           Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
19636                location,
19637                immop,
19638                &kA32DataInfo));
19639       return;
19640     }
19641   }
19642   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location);
19643 }
19644 
vldr_info(Condition cond,DataType dt,DRegister rd,Location * location,const struct ReferenceInfo ** info)19645 bool Assembler::vldr_info(Condition cond,
19646                           DataType dt,
19647                           DRegister rd,
19648                           Location* location,
19649                           const struct ReferenceInfo** info) {
19650   VIXL_ASSERT(!location->IsBound());
19651   USE(location);
19652   USE(rd);
19653   if (IsUsingT32()) {
19654     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
19655     if (dt.IsNoneOr(Untyped64)) {
19656       *info = &kT32DataInfo;
19657       return true;
19658     }
19659   } else {
19660     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
19661     if (dt.IsNoneOr(Untyped64) && cond.IsNotNever()) {
19662       *info = &kA32DataInfo;
19663       return true;
19664     }
19665   }
19666   return false;
19667 }
19668 
vldr(Condition cond,DataType dt,DRegister rd,const MemOperand & operand)19669 void Assembler::vldr(Condition cond,
19670                      DataType dt,
19671                      DRegister rd,
19672                      const MemOperand& operand) {
19673   VIXL_ASSERT(AllowAssembler());
19674   CheckIT(cond);
19675   if (operand.IsImmediate()) {
19676     Register rn = operand.GetBaseRegister();
19677     int32_t offset = operand.GetOffsetImmediate();
19678     if (IsUsingT32()) {
19679       // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1
19680       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
19681           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
19682         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19683         uint32_t offset_ = abs(offset) >> 2;
19684         EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23));
19685         AdvanceIT();
19686         return;
19687       }
19688       // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
19689       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
19690           ((offset % 4) == 0) && operand.IsOffset() &&
19691           ((rn.GetCode() & 0xf) != 0xf)) {
19692         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19693         uint32_t offset_ = abs(offset) >> 2;
19694         EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
19695                    offset_ | (sign << 23));
19696         AdvanceIT();
19697         return;
19698       }
19699     } else {
19700       // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1
19701       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
19702           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
19703           cond.IsNotNever()) {
19704         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19705         uint32_t offset_ = abs(offset) >> 2;
19706         EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19707                 offset_ | (sign << 23));
19708         return;
19709       }
19710       // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
19711       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
19712           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
19713           ((rn.GetCode() & 0xf) != 0xf)) {
19714         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19715         uint32_t offset_ = abs(offset) >> 2;
19716         EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19717                 (rn.GetCode() << 16) | offset_ | (sign << 23));
19718         return;
19719       }
19720     }
19721   }
19722   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
19723 }
19724 
vldr(Condition cond,DataType dt,SRegister rd,Location * location)19725 void Assembler::vldr(Condition cond,
19726                      DataType dt,
19727                      SRegister rd,
19728                      Location* location) {
19729   VIXL_ASSERT(AllowAssembler());
19730   CheckIT(cond);
19731   Location::Offset offset =
19732       location->IsBound()
19733           ? location->GetLocation() -
19734                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
19735           : 0;
19736   if (IsUsingT32()) {
19737     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
19738     if (dt.IsNoneOr(Untyped32) &&
19739         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
19740           ((offset & 0x3) == 0)) ||
19741          !location->IsBound())) {
19742       static class EmitOp : public Location::EmitOperator {
19743        public:
19744         EmitOp() : Location::EmitOperator(T32) {}
19745         virtual uint32_t Encode(uint32_t instr,
19746                                 Location::Offset pc,
19747                                 const Location* location) const VIXL_OVERRIDE {
19748           pc += kT32PcDelta;
19749           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
19750           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
19751                       ((offset & 0x3) == 0));
19752           int32_t target = offset >> 2;
19753           uint32_t U = (target >= 0);
19754           target = abs(target) | (U << 8);
19755           return instr | (target & 0xff) | ((target & 0x100) << 15);
19756         }
19757       } immop;
19758       EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12),
19759                       location,
19760                       immop,
19761                       &kT32DataInfo));
19762       AdvanceIT();
19763       return;
19764     }
19765   } else {
19766     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
19767     if (dt.IsNoneOr(Untyped32) &&
19768         ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
19769           ((offset & 0x3) == 0)) ||
19770          !location->IsBound()) &&
19771         cond.IsNotNever()) {
19772       static class EmitOp : public Location::EmitOperator {
19773        public:
19774         EmitOp() : Location::EmitOperator(A32) {}
19775         virtual uint32_t Encode(uint32_t instr,
19776                                 Location::Offset pc,
19777                                 const Location* location) const VIXL_OVERRIDE {
19778           pc += kA32PcDelta;
19779           Location::Offset offset = location->GetLocation() - AlignDown(pc, 4);
19780           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
19781                       ((offset & 0x3) == 0));
19782           int32_t target = offset >> 2;
19783           uint32_t U = (target >= 0);
19784           target = abs(target) | (U << 8);
19785           return instr | (target & 0xff) | ((target & 0x100) << 15);
19786         }
19787       } immop;
19788       EmitA32(
19789           Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
19790                location,
19791                immop,
19792                &kA32DataInfo));
19793       return;
19794     }
19795   }
19796   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location);
19797 }
19798 
vldr_info(Condition cond,DataType dt,SRegister rd,Location * location,const struct ReferenceInfo ** info)19799 bool Assembler::vldr_info(Condition cond,
19800                           DataType dt,
19801                           SRegister rd,
19802                           Location* location,
19803                           const struct ReferenceInfo** info) {
19804   VIXL_ASSERT(!location->IsBound());
19805   USE(location);
19806   USE(rd);
19807   if (IsUsingT32()) {
19808     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
19809     if (dt.IsNoneOr(Untyped32)) {
19810       *info = &kT32DataInfo;
19811       return true;
19812     }
19813   } else {
19814     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
19815     if (dt.IsNoneOr(Untyped32) && cond.IsNotNever()) {
19816       *info = &kA32DataInfo;
19817       return true;
19818     }
19819   }
19820   return false;
19821 }
19822 
vldr(Condition cond,DataType dt,SRegister rd,const MemOperand & operand)19823 void Assembler::vldr(Condition cond,
19824                      DataType dt,
19825                      SRegister rd,
19826                      const MemOperand& operand) {
19827   VIXL_ASSERT(AllowAssembler());
19828   CheckIT(cond);
19829   if (operand.IsImmediate()) {
19830     Register rn = operand.GetBaseRegister();
19831     int32_t offset = operand.GetOffsetImmediate();
19832     if (IsUsingT32()) {
19833       // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2
19834       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
19835           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
19836         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19837         uint32_t offset_ = abs(offset) >> 2;
19838         EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23));
19839         AdvanceIT();
19840         return;
19841       }
19842       // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
19843       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
19844           ((offset % 4) == 0) && operand.IsOffset() &&
19845           ((rn.GetCode() & 0xf) != 0xf)) {
19846         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19847         uint32_t offset_ = abs(offset) >> 2;
19848         EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
19849                    offset_ | (sign << 23));
19850         AdvanceIT();
19851         return;
19852       }
19853     } else {
19854       // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2
19855       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
19856           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
19857           cond.IsNotNever()) {
19858         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19859         uint32_t offset_ = abs(offset) >> 2;
19860         EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19861                 offset_ | (sign << 23));
19862         return;
19863       }
19864       // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
19865       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
19866           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
19867           ((rn.GetCode() & 0xf) != 0xf)) {
19868         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19869         uint32_t offset_ = abs(offset) >> 2;
19870         EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19871                 (rn.GetCode() << 16) | offset_ | (sign << 23));
19872         return;
19873       }
19874     }
19875   }
19876   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
19877 }
19878 
vmax(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)19879 void Assembler::vmax(
19880     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
19881   VIXL_ASSERT(AllowAssembler());
19882   CheckIT(cond);
19883   Dt_U_size_1 encoded_dt(dt);
19884   if (IsUsingT32()) {
19885     // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
19886     if (dt.Is(F32)) {
19887       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19888         EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19889                    rm.Encode(5, 0));
19890         AdvanceIT();
19891         return;
19892       }
19893     }
19894     // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
19895     if (encoded_dt.IsValid()) {
19896       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19897         EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19898                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
19899                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19900         AdvanceIT();
19901         return;
19902       }
19903     }
19904   } else {
19905     // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
19906     if (dt.Is(F32)) {
19907       if (cond.Is(al)) {
19908         EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19909                 rm.Encode(5, 0));
19910         return;
19911       }
19912     }
19913     // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
19914     if (encoded_dt.IsValid()) {
19915       if (cond.Is(al)) {
19916         EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19917                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
19918                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19919         return;
19920       }
19921     }
19922   }
19923   Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
19924 }
19925 
vmax(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)19926 void Assembler::vmax(
19927     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
19928   VIXL_ASSERT(AllowAssembler());
19929   CheckIT(cond);
19930   Dt_U_size_1 encoded_dt(dt);
19931   if (IsUsingT32()) {
19932     // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
19933     if (dt.Is(F32)) {
19934       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19935         EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19936                    rm.Encode(5, 0));
19937         AdvanceIT();
19938         return;
19939       }
19940     }
19941     // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
19942     if (encoded_dt.IsValid()) {
19943       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19944         EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19945                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
19946                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19947         AdvanceIT();
19948         return;
19949       }
19950     }
19951   } else {
19952     // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
19953     if (dt.Is(F32)) {
19954       if (cond.Is(al)) {
19955         EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19956                 rm.Encode(5, 0));
19957         return;
19958       }
19959     }
19960     // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
19961     if (encoded_dt.IsValid()) {
19962       if (cond.Is(al)) {
19963         EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19964                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
19965                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19966         return;
19967       }
19968     }
19969   }
19970   Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
19971 }
19972 
vmaxnm(DataType dt,DRegister rd,DRegister rn,DRegister rm)19973 void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
19974   VIXL_ASSERT(AllowAssembler());
19975   CheckIT(al);
19976   if (IsUsingT32()) {
19977     // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
19978     if (OutsideITBlock() && dt.Is(F32)) {
19979       EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19980                  rm.Encode(5, 0));
19981       AdvanceIT();
19982       return;
19983     }
19984     // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
19985     if (OutsideITBlock() && dt.Is(F64)) {
19986       EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19987                  rm.Encode(5, 0));
19988       AdvanceIT();
19989       return;
19990     }
19991   } else {
19992     // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
19993     if (dt.Is(F32)) {
19994       EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19995               rm.Encode(5, 0));
19996       return;
19997     }
19998     // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
19999     if (dt.Is(F64)) {
20000       EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20001               rm.Encode(5, 0));
20002       return;
20003     }
20004   }
20005   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
20006 }
20007 
vmaxnm(DataType dt,QRegister rd,QRegister rn,QRegister rm)20008 void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20009   VIXL_ASSERT(AllowAssembler());
20010   CheckIT(al);
20011   if (IsUsingT32()) {
20012     // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
20013     if (OutsideITBlock() && dt.Is(F32)) {
20014       EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20015                  rm.Encode(5, 0));
20016       AdvanceIT();
20017       return;
20018     }
20019   } else {
20020     // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
20021     if (dt.Is(F32)) {
20022       EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20023               rm.Encode(5, 0));
20024       return;
20025     }
20026   }
20027   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
20028 }
20029 
vmaxnm(DataType dt,SRegister rd,SRegister rn,SRegister rm)20030 void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20031   VIXL_ASSERT(AllowAssembler());
20032   CheckIT(al);
20033   if (IsUsingT32()) {
20034     // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
20035     if (OutsideITBlock() && dt.Is(F32)) {
20036       EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20037                  rm.Encode(5, 0));
20038       AdvanceIT();
20039       return;
20040     }
20041   } else {
20042     // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
20043     if (dt.Is(F32)) {
20044       EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20045               rm.Encode(5, 0));
20046       return;
20047     }
20048   }
20049   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
20050 }
20051 
vmin(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)20052 void Assembler::vmin(
20053     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20054   VIXL_ASSERT(AllowAssembler());
20055   CheckIT(cond);
20056   Dt_U_size_1 encoded_dt(dt);
20057   if (IsUsingT32()) {
20058     // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20059     if (dt.Is(F32)) {
20060       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20061         EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20062                    rm.Encode(5, 0));
20063         AdvanceIT();
20064         return;
20065       }
20066     }
20067     // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20068     if (encoded_dt.IsValid()) {
20069       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20070         EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20071                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20072                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20073         AdvanceIT();
20074         return;
20075       }
20076     }
20077   } else {
20078     // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
20079     if (dt.Is(F32)) {
20080       if (cond.Is(al)) {
20081         EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20082                 rm.Encode(5, 0));
20083         return;
20084       }
20085     }
20086     // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20087     if (encoded_dt.IsValid()) {
20088       if (cond.Is(al)) {
20089         EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20090                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20091                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20092         return;
20093       }
20094     }
20095   }
20096   Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
20097 }
20098 
vmin(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)20099 void Assembler::vmin(
20100     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20101   VIXL_ASSERT(AllowAssembler());
20102   CheckIT(cond);
20103   Dt_U_size_1 encoded_dt(dt);
20104   if (IsUsingT32()) {
20105     // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
20106     if (dt.Is(F32)) {
20107       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20108         EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20109                    rm.Encode(5, 0));
20110         AdvanceIT();
20111         return;
20112       }
20113     }
20114     // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
20115     if (encoded_dt.IsValid()) {
20116       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20117         EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20118                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20119                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20120         AdvanceIT();
20121         return;
20122       }
20123     }
20124   } else {
20125     // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
20126     if (dt.Is(F32)) {
20127       if (cond.Is(al)) {
20128         EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20129                 rm.Encode(5, 0));
20130         return;
20131       }
20132     }
20133     // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
20134     if (encoded_dt.IsValid()) {
20135       if (cond.Is(al)) {
20136         EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20137                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20138                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20139         return;
20140       }
20141     }
20142   }
20143   Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
20144 }
20145 
vminnm(DataType dt,DRegister rd,DRegister rn,DRegister rm)20146 void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20147   VIXL_ASSERT(AllowAssembler());
20148   CheckIT(al);
20149   if (IsUsingT32()) {
20150     // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
20151     if (OutsideITBlock() && dt.Is(F32)) {
20152       EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20153                  rm.Encode(5, 0));
20154       AdvanceIT();
20155       return;
20156     }
20157     // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
20158     if (OutsideITBlock() && dt.Is(F64)) {
20159       EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20160                  rm.Encode(5, 0));
20161       AdvanceIT();
20162       return;
20163     }
20164   } else {
20165     // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
20166     if (dt.Is(F32)) {
20167       EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20168               rm.Encode(5, 0));
20169       return;
20170     }
20171     // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
20172     if (dt.Is(F64)) {
20173       EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20174               rm.Encode(5, 0));
20175       return;
20176     }
20177   }
20178   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
20179 }
20180 
vminnm(DataType dt,QRegister rd,QRegister rn,QRegister rm)20181 void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20182   VIXL_ASSERT(AllowAssembler());
20183   CheckIT(al);
20184   if (IsUsingT32()) {
20185     // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
20186     if (OutsideITBlock() && dt.Is(F32)) {
20187       EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20188                  rm.Encode(5, 0));
20189       AdvanceIT();
20190       return;
20191     }
20192   } else {
20193     // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
20194     if (dt.Is(F32)) {
20195       EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20196               rm.Encode(5, 0));
20197       return;
20198     }
20199   }
20200   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
20201 }
20202 
vminnm(DataType dt,SRegister rd,SRegister rn,SRegister rm)20203 void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20204   VIXL_ASSERT(AllowAssembler());
20205   CheckIT(al);
20206   if (IsUsingT32()) {
20207     // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
20208     if (OutsideITBlock() && dt.Is(F32)) {
20209       EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20210                  rm.Encode(5, 0));
20211       AdvanceIT();
20212       return;
20213     }
20214   } else {
20215     // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
20216     if (dt.Is(F32)) {
20217       EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20218               rm.Encode(5, 0));
20219       return;
20220     }
20221   }
20222   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
20223 }
20224 
vmla(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)20225 void Assembler::vmla(
20226     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
20227   VIXL_ASSERT(AllowAssembler());
20228   CheckIT(cond);
20229   Dt_size_9 encoded_dt(dt);
20230   if (IsUsingT32()) {
20231     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
20232     if (encoded_dt.IsValid() &&
20233         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20234          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20235           (rm.GetLane() <= 1)))) {
20236       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20237         EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
20238                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20239                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20240         AdvanceIT();
20241         return;
20242       }
20243     }
20244   } else {
20245     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
20246     if (encoded_dt.IsValid() &&
20247         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20248          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20249           (rm.GetLane() <= 1)))) {
20250       if (cond.Is(al)) {
20251         EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
20252                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20253                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20254         return;
20255       }
20256     }
20257   }
20258   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
20259 }
20260 
vmla(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)20261 void Assembler::vmla(
20262     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
20263   VIXL_ASSERT(AllowAssembler());
20264   CheckIT(cond);
20265   Dt_size_9 encoded_dt(dt);
20266   if (IsUsingT32()) {
20267     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
20268     if (encoded_dt.IsValid() &&
20269         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20270          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20271           (rm.GetLane() <= 1)))) {
20272       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20273         EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
20274                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20275                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20276         AdvanceIT();
20277         return;
20278       }
20279     }
20280   } else {
20281     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
20282     if (encoded_dt.IsValid() &&
20283         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20284          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20285           (rm.GetLane() <= 1)))) {
20286       if (cond.Is(al)) {
20287         EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
20288                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20289                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20290         return;
20291       }
20292     }
20293   }
20294   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
20295 }
20296 
vmla(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)20297 void Assembler::vmla(
20298     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20299   VIXL_ASSERT(AllowAssembler());
20300   CheckIT(cond);
20301   Dt_size_10 encoded_dt(dt);
20302   if (IsUsingT32()) {
20303     // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
20304     if (dt.Is(F32)) {
20305       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20306         EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20307                    rm.Encode(5, 0));
20308         AdvanceIT();
20309         return;
20310       }
20311     }
20312     // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
20313     if (dt.Is(F64)) {
20314       EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20315                  rm.Encode(5, 0));
20316       AdvanceIT();
20317       return;
20318     }
20319     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
20320     if (encoded_dt.IsValid()) {
20321       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20322         EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) |
20323                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20324         AdvanceIT();
20325         return;
20326       }
20327     }
20328   } else {
20329     // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
20330     if (dt.Is(F32)) {
20331       if (cond.Is(al)) {
20332         EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20333                 rm.Encode(5, 0));
20334         return;
20335       }
20336     }
20337     // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
20338     if (dt.Is(F64) && cond.IsNotNever()) {
20339       EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20340               rn.Encode(7, 16) | rm.Encode(5, 0));
20341       return;
20342     }
20343     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
20344     if (encoded_dt.IsValid()) {
20345       if (cond.Is(al)) {
20346         EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) |
20347                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20348         return;
20349       }
20350     }
20351   }
20352   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
20353 }
20354 
vmla(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)20355 void Assembler::vmla(
20356     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20357   VIXL_ASSERT(AllowAssembler());
20358   CheckIT(cond);
20359   Dt_size_10 encoded_dt(dt);
20360   if (IsUsingT32()) {
20361     // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
20362     if (dt.Is(F32)) {
20363       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20364         EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20365                    rm.Encode(5, 0));
20366         AdvanceIT();
20367         return;
20368       }
20369     }
20370     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
20371     if (encoded_dt.IsValid()) {
20372       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20373         EmitT32_32(0xef000940U | (encoded_dt.GetEncodingValue() << 20) |
20374                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20375         AdvanceIT();
20376         return;
20377       }
20378     }
20379   } else {
20380     // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
20381     if (dt.Is(F32)) {
20382       if (cond.Is(al)) {
20383         EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20384                 rm.Encode(5, 0));
20385         return;
20386       }
20387     }
20388     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
20389     if (encoded_dt.IsValid()) {
20390       if (cond.Is(al)) {
20391         EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) |
20392                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20393         return;
20394       }
20395     }
20396   }
20397   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
20398 }
20399 
vmla(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)20400 void Assembler::vmla(
20401     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20402   VIXL_ASSERT(AllowAssembler());
20403   CheckIT(cond);
20404   if (IsUsingT32()) {
20405     // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
20406     if (dt.Is(F32)) {
20407       EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20408                  rm.Encode(5, 0));
20409       AdvanceIT();
20410       return;
20411     }
20412   } else {
20413     // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
20414     if (dt.Is(F32) && cond.IsNotNever()) {
20415       EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20416               rn.Encode(7, 16) | rm.Encode(5, 0));
20417       return;
20418     }
20419   }
20420   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
20421 }
20422 
vmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegisterLane rm)20423 void Assembler::vmlal(
20424     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
20425   VIXL_ASSERT(AllowAssembler());
20426   CheckIT(cond);
20427   Dt_size_11 encoded_dt(dt);
20428   if (IsUsingT32()) {
20429     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
20430     if (encoded_dt.IsValid() &&
20431         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20432          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20433           (rm.GetLane() <= 1)))) {
20434       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20435         EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) |
20436                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20437                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20438         AdvanceIT();
20439         return;
20440       }
20441     }
20442   } else {
20443     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
20444     if (encoded_dt.IsValid() &&
20445         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20446          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20447           (rm.GetLane() <= 1)))) {
20448       if (cond.Is(al)) {
20449         EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) |
20450                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20451                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20452         return;
20453       }
20454     }
20455   }
20456   Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
20457 }
20458 
vmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)20459 void Assembler::vmlal(
20460     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
20461   VIXL_ASSERT(AllowAssembler());
20462   CheckIT(cond);
20463   Dt_size_12 encoded_dt(dt);
20464   if (IsUsingT32()) {
20465     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
20466     if (encoded_dt.IsValid()) {
20467       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20468         EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) |
20469                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20470                    rn.Encode(7, 16) | rm.Encode(5, 0));
20471         AdvanceIT();
20472         return;
20473       }
20474     }
20475   } else {
20476     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
20477     if (encoded_dt.IsValid()) {
20478       if (cond.Is(al)) {
20479         EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) |
20480                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20481                 rn.Encode(7, 16) | rm.Encode(5, 0));
20482         return;
20483       }
20484     }
20485   }
20486   Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
20487 }
20488 
vmls(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)20489 void Assembler::vmls(
20490     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
20491   VIXL_ASSERT(AllowAssembler());
20492   CheckIT(cond);
20493   Dt_size_9 encoded_dt(dt);
20494   if (IsUsingT32()) {
20495     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
20496     if (encoded_dt.IsValid() &&
20497         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20498          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20499           (rm.GetLane() <= 1)))) {
20500       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20501         EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
20502                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20503                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20504         AdvanceIT();
20505         return;
20506       }
20507     }
20508   } else {
20509     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
20510     if (encoded_dt.IsValid() &&
20511         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20512          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20513           (rm.GetLane() <= 1)))) {
20514       if (cond.Is(al)) {
20515         EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
20516                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20517                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20518         return;
20519       }
20520     }
20521   }
20522   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
20523 }
20524 
vmls(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)20525 void Assembler::vmls(
20526     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
20527   VIXL_ASSERT(AllowAssembler());
20528   CheckIT(cond);
20529   Dt_size_9 encoded_dt(dt);
20530   if (IsUsingT32()) {
20531     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
20532     if (encoded_dt.IsValid() &&
20533         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20534          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20535           (rm.GetLane() <= 1)))) {
20536       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20537         EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
20538                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20539                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20540         AdvanceIT();
20541         return;
20542       }
20543     }
20544   } else {
20545     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
20546     if (encoded_dt.IsValid() &&
20547         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20548          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20549           (rm.GetLane() <= 1)))) {
20550       if (cond.Is(al)) {
20551         EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
20552                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20553                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20554         return;
20555       }
20556     }
20557   }
20558   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
20559 }
20560 
vmls(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)20561 void Assembler::vmls(
20562     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20563   VIXL_ASSERT(AllowAssembler());
20564   CheckIT(cond);
20565   Dt_size_10 encoded_dt(dt);
20566   if (IsUsingT32()) {
20567     // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
20568     if (dt.Is(F32)) {
20569       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20570         EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20571                    rm.Encode(5, 0));
20572         AdvanceIT();
20573         return;
20574       }
20575     }
20576     // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
20577     if (dt.Is(F64)) {
20578       EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20579                  rm.Encode(5, 0));
20580       AdvanceIT();
20581       return;
20582     }
20583     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
20584     if (encoded_dt.IsValid()) {
20585       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20586         EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) |
20587                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20588         AdvanceIT();
20589         return;
20590       }
20591     }
20592   } else {
20593     // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
20594     if (dt.Is(F32)) {
20595       if (cond.Is(al)) {
20596         EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20597                 rm.Encode(5, 0));
20598         return;
20599       }
20600     }
20601     // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
20602     if (dt.Is(F64) && cond.IsNotNever()) {
20603       EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20604               rn.Encode(7, 16) | rm.Encode(5, 0));
20605       return;
20606     }
20607     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
20608     if (encoded_dt.IsValid()) {
20609       if (cond.Is(al)) {
20610         EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) |
20611                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20612         return;
20613       }
20614     }
20615   }
20616   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
20617 }
20618 
vmls(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)20619 void Assembler::vmls(
20620     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20621   VIXL_ASSERT(AllowAssembler());
20622   CheckIT(cond);
20623   Dt_size_10 encoded_dt(dt);
20624   if (IsUsingT32()) {
20625     // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
20626     if (dt.Is(F32)) {
20627       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20628         EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20629                    rm.Encode(5, 0));
20630         AdvanceIT();
20631         return;
20632       }
20633     }
20634     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
20635     if (encoded_dt.IsValid()) {
20636       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20637         EmitT32_32(0xff000940U | (encoded_dt.GetEncodingValue() << 20) |
20638                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20639         AdvanceIT();
20640         return;
20641       }
20642     }
20643   } else {
20644     // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
20645     if (dt.Is(F32)) {
20646       if (cond.Is(al)) {
20647         EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20648                 rm.Encode(5, 0));
20649         return;
20650       }
20651     }
20652     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
20653     if (encoded_dt.IsValid()) {
20654       if (cond.Is(al)) {
20655         EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) |
20656                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20657         return;
20658       }
20659     }
20660   }
20661   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
20662 }
20663 
vmls(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)20664 void Assembler::vmls(
20665     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20666   VIXL_ASSERT(AllowAssembler());
20667   CheckIT(cond);
20668   if (IsUsingT32()) {
20669     // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
20670     if (dt.Is(F32)) {
20671       EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20672                  rm.Encode(5, 0));
20673       AdvanceIT();
20674       return;
20675     }
20676   } else {
20677     // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
20678     if (dt.Is(F32) && cond.IsNotNever()) {
20679       EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20680               rn.Encode(7, 16) | rm.Encode(5, 0));
20681       return;
20682     }
20683   }
20684   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
20685 }
20686 
vmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegisterLane rm)20687 void Assembler::vmlsl(
20688     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
20689   VIXL_ASSERT(AllowAssembler());
20690   CheckIT(cond);
20691   Dt_size_11 encoded_dt(dt);
20692   if (IsUsingT32()) {
20693     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
20694     if (encoded_dt.IsValid() &&
20695         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20696          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20697           (rm.GetLane() <= 1)))) {
20698       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20699         EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) |
20700                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20701                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20702         AdvanceIT();
20703         return;
20704       }
20705     }
20706   } else {
20707     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
20708     if (encoded_dt.IsValid() &&
20709         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20710          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20711           (rm.GetLane() <= 1)))) {
20712       if (cond.Is(al)) {
20713         EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) |
20714                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20715                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20716         return;
20717       }
20718     }
20719   }
20720   Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
20721 }
20722 
vmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)20723 void Assembler::vmlsl(
20724     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
20725   VIXL_ASSERT(AllowAssembler());
20726   CheckIT(cond);
20727   Dt_size_12 encoded_dt(dt);
20728   if (IsUsingT32()) {
20729     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
20730     if (encoded_dt.IsValid()) {
20731       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20732         EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) |
20733                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20734                    rn.Encode(7, 16) | rm.Encode(5, 0));
20735         AdvanceIT();
20736         return;
20737       }
20738     }
20739   } else {
20740     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
20741     if (encoded_dt.IsValid()) {
20742       if (cond.Is(al)) {
20743         EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) |
20744                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20745                 rn.Encode(7, 16) | rm.Encode(5, 0));
20746         return;
20747       }
20748     }
20749   }
20750   Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
20751 }
20752 
vmov(Condition cond,Register rt,SRegister rn)20753 void Assembler::vmov(Condition cond, Register rt, SRegister rn) {
20754   VIXL_ASSERT(AllowAssembler());
20755   CheckIT(cond);
20756   if (IsUsingT32()) {
20757     // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1
20758     if ((!rt.IsPC() || AllowUnpredictable())) {
20759       EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16));
20760       AdvanceIT();
20761       return;
20762     }
20763   } else {
20764     // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1
20765     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
20766       EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
20767               rn.Encode(7, 16));
20768       return;
20769     }
20770   }
20771   Delegate(kVmov, &Assembler::vmov, cond, rt, rn);
20772 }
20773 
vmov(Condition cond,SRegister rn,Register rt)20774 void Assembler::vmov(Condition cond, SRegister rn, Register rt) {
20775   VIXL_ASSERT(AllowAssembler());
20776   CheckIT(cond);
20777   if (IsUsingT32()) {
20778     // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1
20779     if ((!rt.IsPC() || AllowUnpredictable())) {
20780       EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12));
20781       AdvanceIT();
20782       return;
20783     }
20784   } else {
20785     // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1
20786     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
20787       EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) |
20788               (rt.GetCode() << 12));
20789       return;
20790     }
20791   }
20792   Delegate(kVmov, &Assembler::vmov, cond, rn, rt);
20793 }
20794 
vmov(Condition cond,Register rt,Register rt2,DRegister rm)20795 void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) {
20796   VIXL_ASSERT(AllowAssembler());
20797   CheckIT(cond);
20798   if (IsUsingT32()) {
20799     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1
20800     if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20801       EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
20802                  rm.Encode(5, 0));
20803       AdvanceIT();
20804       return;
20805     }
20806   } else {
20807     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1
20808     if (cond.IsNotNever() &&
20809         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20810       EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
20811               (rt2.GetCode() << 16) | rm.Encode(5, 0));
20812       return;
20813     }
20814   }
20815   Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm);
20816 }
20817 
vmov(Condition cond,DRegister rm,Register rt,Register rt2)20818 void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) {
20819   VIXL_ASSERT(AllowAssembler());
20820   CheckIT(cond);
20821   if (IsUsingT32()) {
20822     // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1
20823     if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20824       EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
20825                  (rt2.GetCode() << 16));
20826       AdvanceIT();
20827       return;
20828     }
20829   } else {
20830     // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1
20831     if (cond.IsNotNever() &&
20832         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20833       EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
20834               (rt.GetCode() << 12) | (rt2.GetCode() << 16));
20835       return;
20836     }
20837   }
20838   Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2);
20839 }
20840 
vmov(Condition cond,Register rt,Register rt2,SRegister rm,SRegister rm1)20841 void Assembler::vmov(
20842     Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) {
20843   VIXL_ASSERT(AllowAssembler());
20844   CheckIT(cond);
20845   if (IsUsingT32()) {
20846     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1
20847     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
20848         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20849       EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
20850                  rm.Encode(5, 0));
20851       AdvanceIT();
20852       return;
20853     }
20854   } else {
20855     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1
20856     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
20857         cond.IsNotNever() &&
20858         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20859       EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
20860               (rt2.GetCode() << 16) | rm.Encode(5, 0));
20861       return;
20862     }
20863   }
20864   Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1);
20865 }
20866 
vmov(Condition cond,SRegister rm,SRegister rm1,Register rt,Register rt2)20867 void Assembler::vmov(
20868     Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) {
20869   VIXL_ASSERT(AllowAssembler());
20870   CheckIT(cond);
20871   if (IsUsingT32()) {
20872     // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1
20873     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
20874         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20875       EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
20876                  (rt2.GetCode() << 16));
20877       AdvanceIT();
20878       return;
20879     }
20880   } else {
20881     // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1
20882     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
20883         cond.IsNotNever() &&
20884         ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20885       EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
20886               (rt.GetCode() << 12) | (rt2.GetCode() << 16));
20887       return;
20888     }
20889   }
20890   Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2);
20891 }
20892 
vmov(Condition cond,DataType dt,DRegisterLane rd,Register rt)20893 void Assembler::vmov(Condition cond,
20894                      DataType dt,
20895                      DRegisterLane rd,
20896                      Register rt) {
20897   VIXL_ASSERT(AllowAssembler());
20898   CheckIT(cond);
20899   Dt_opc1_opc2_1 encoded_dt(dt, rd);
20900   if (IsUsingT32()) {
20901     // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1
20902     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
20903       EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
20904                  ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
20905                  rd.Encode(7, 16) | (rt.GetCode() << 12));
20906       AdvanceIT();
20907       return;
20908     }
20909   } else {
20910     // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1
20911     if (encoded_dt.IsValid() && cond.IsNotNever() &&
20912         (!rt.IsPC() || AllowUnpredictable())) {
20913       EmitA32(0x0e000b10U | (cond.GetCondition() << 28) |
20914               ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
20915               ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) |
20916               (rt.GetCode() << 12));
20917       return;
20918     }
20919   }
20920   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt);
20921 }
20922 
vmov(Condition cond,DataType dt,DRegister rd,const DOperand & operand)20923 void Assembler::vmov(Condition cond,
20924                      DataType dt,
20925                      DRegister rd,
20926                      const DOperand& operand) {
20927   VIXL_ASSERT(AllowAssembler());
20928   CheckIT(cond);
20929   if (operand.IsImmediate()) {
20930     ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
20931     if (IsUsingT32()) {
20932       // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
20933       if (encoded_dt.IsValid()) {
20934         if (cond.Is(al) || AllowStronglyDiscouraged()) {
20935           EmitT32_32(
20936               0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
20937               ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
20938               rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20939               ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20940               ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20941           AdvanceIT();
20942           return;
20943         }
20944       }
20945     } else {
20946       // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
20947       if (encoded_dt.IsValid()) {
20948         if (cond.Is(al)) {
20949           EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
20950                   ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
20951                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20952                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20953                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20954           return;
20955         }
20956       }
20957     }
20958   }
20959   if (operand.IsImmediate()) {
20960     ImmediateVFP vfp(operand.GetNeonImmediate());
20961     if (IsUsingT32()) {
20962       // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2
20963       if (dt.Is(F64) && vfp.IsValid()) {
20964         EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) |
20965                    (vfp.GetEncodingValue() & 0xf) |
20966                    ((vfp.GetEncodingValue() & 0xf0) << 12));
20967         AdvanceIT();
20968         return;
20969       }
20970     } else {
20971       // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2
20972       if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) {
20973         EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20974                 (vfp.GetEncodingValue() & 0xf) |
20975                 ((vfp.GetEncodingValue() & 0xf0) << 12));
20976         return;
20977       }
20978     }
20979   }
20980   if (operand.IsRegister()) {
20981     DRegister rm = operand.GetRegister();
20982     if (IsUsingT32()) {
20983       // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
20984       if (dt.Is(F64)) {
20985         EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
20986         AdvanceIT();
20987         return;
20988       }
20989       // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
20990       if (!dt.Is(F64)) {
20991         if (cond.Is(al) || AllowStronglyDiscouraged()) {
20992           EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
20993                      rm.Encode(5, 0));
20994           AdvanceIT();
20995           return;
20996         }
20997       }
20998     } else {
20999       // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
21000       if (dt.Is(F64) && cond.IsNotNever()) {
21001         EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21002                 rm.Encode(5, 0));
21003         return;
21004       }
21005       // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
21006       if (!dt.Is(F64)) {
21007         if (cond.Is(al)) {
21008           EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
21009                   rm.Encode(5, 0));
21010           return;
21011         }
21012       }
21013     }
21014   }
21015   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
21016 }
21017 
vmov(Condition cond,DataType dt,QRegister rd,const QOperand & operand)21018 void Assembler::vmov(Condition cond,
21019                      DataType dt,
21020                      QRegister rd,
21021                      const QOperand& operand) {
21022   VIXL_ASSERT(AllowAssembler());
21023   CheckIT(cond);
21024   if (operand.IsImmediate()) {
21025     ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
21026     if (IsUsingT32()) {
21027       // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
21028       if (encoded_dt.IsValid()) {
21029         if (cond.Is(al) || AllowStronglyDiscouraged()) {
21030           EmitT32_32(
21031               0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
21032               ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
21033               rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
21034               ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21035               ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
21036           AdvanceIT();
21037           return;
21038         }
21039       }
21040     } else {
21041       // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
21042       if (encoded_dt.IsValid()) {
21043         if (cond.Is(al)) {
21044           EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
21045                   ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
21046                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
21047                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21048                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
21049           return;
21050         }
21051       }
21052     }
21053   }
21054   if (operand.IsRegister()) {
21055     QRegister rm = operand.GetRegister();
21056     if (IsUsingT32()) {
21057       // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
21058       if (!dt.Is(F64)) {
21059         if (cond.Is(al) || AllowStronglyDiscouraged()) {
21060           EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
21061                      rm.Encode(5, 0));
21062           AdvanceIT();
21063           return;
21064         }
21065       }
21066     } else {
21067       // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
21068       if (!dt.Is(F64)) {
21069         if (cond.Is(al)) {
21070           EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
21071                   rm.Encode(5, 0));
21072           return;
21073         }
21074       }
21075     }
21076   }
21077   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
21078 }
21079 
vmov(Condition cond,DataType dt,SRegister rd,const SOperand & operand)21080 void Assembler::vmov(Condition cond,
21081                      DataType dt,
21082                      SRegister rd,
21083                      const SOperand& operand) {
21084   VIXL_ASSERT(AllowAssembler());
21085   CheckIT(cond);
21086   if (operand.IsImmediate()) {
21087     ImmediateVFP vfp(operand.GetNeonImmediate());
21088     if (IsUsingT32()) {
21089       // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2
21090       if (dt.Is(F32) && vfp.IsValid()) {
21091         EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) |
21092                    (vfp.GetEncodingValue() & 0xf) |
21093                    ((vfp.GetEncodingValue() & 0xf0) << 12));
21094         AdvanceIT();
21095         return;
21096       }
21097     } else {
21098       // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2
21099       if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) {
21100         EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21101                 (vfp.GetEncodingValue() & 0xf) |
21102                 ((vfp.GetEncodingValue() & 0xf0) << 12));
21103         return;
21104       }
21105     }
21106   }
21107   if (operand.IsRegister()) {
21108     SRegister rm = operand.GetRegister();
21109     if (IsUsingT32()) {
21110       // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
21111       if (dt.Is(F32)) {
21112         EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
21113         AdvanceIT();
21114         return;
21115       }
21116     } else {
21117       // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
21118       if (dt.Is(F32) && cond.IsNotNever()) {
21119         EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21120                 rm.Encode(5, 0));
21121         return;
21122       }
21123     }
21124   }
21125   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
21126 }
21127 
vmov(Condition cond,DataType dt,Register rt,DRegisterLane rn)21128 void Assembler::vmov(Condition cond,
21129                      DataType dt,
21130                      Register rt,
21131                      DRegisterLane rn) {
21132   VIXL_ASSERT(AllowAssembler());
21133   CheckIT(cond);
21134   Dt_U_opc1_opc2_1 encoded_dt(dt, rn);
21135   if (IsUsingT32()) {
21136     // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1
21137     if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
21138       EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
21139                  ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
21140                  ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
21141                  (rt.GetCode() << 12) | rn.Encode(7, 16));
21142       AdvanceIT();
21143       return;
21144     }
21145   } else {
21146     // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1
21147     if (encoded_dt.IsValid() && cond.IsNotNever() &&
21148         (!rt.IsPC() || AllowUnpredictable())) {
21149       EmitA32(0x0e100b10U | (cond.GetCondition() << 28) |
21150               ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
21151               ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
21152               ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
21153               (rt.GetCode() << 12) | rn.Encode(7, 16));
21154       return;
21155     }
21156   }
21157   Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn);
21158 }
21159 
vmovl(Condition cond,DataType dt,QRegister rd,DRegister rm)21160 void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) {
21161   VIXL_ASSERT(AllowAssembler());
21162   CheckIT(cond);
21163   Dt_U_imm3H_1 encoded_dt(dt);
21164   if (IsUsingT32()) {
21165     // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1
21166     if (encoded_dt.IsValid()) {
21167       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21168         EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21169                    ((encoded_dt.GetEncodingValue() & 0x8) << 25) |
21170                    rd.Encode(22, 12) | rm.Encode(5, 0));
21171         AdvanceIT();
21172         return;
21173       }
21174     }
21175   } else {
21176     // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
21177     if (encoded_dt.IsValid()) {
21178       if (cond.Is(al)) {
21179         EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21180                 ((encoded_dt.GetEncodingValue() & 0x8) << 21) |
21181                 rd.Encode(22, 12) | rm.Encode(5, 0));
21182         return;
21183       }
21184     }
21185   }
21186   Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm);
21187 }
21188 
vmovn(Condition cond,DataType dt,DRegister rd,QRegister rm)21189 void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) {
21190   VIXL_ASSERT(AllowAssembler());
21191   CheckIT(cond);
21192   Dt_size_3 encoded_dt(dt);
21193   if (IsUsingT32()) {
21194     // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
21195     if (encoded_dt.IsValid()) {
21196       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21197         EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) |
21198                    rd.Encode(22, 12) | rm.Encode(5, 0));
21199         AdvanceIT();
21200         return;
21201       }
21202     }
21203   } else {
21204     // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
21205     if (encoded_dt.IsValid()) {
21206       if (cond.Is(al)) {
21207         EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) |
21208                 rd.Encode(22, 12) | rm.Encode(5, 0));
21209         return;
21210       }
21211     }
21212   }
21213   Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm);
21214 }
21215 
vmrs(Condition cond,RegisterOrAPSR_nzcv rt,SpecialFPRegister spec_reg)21216 void Assembler::vmrs(Condition cond,
21217                      RegisterOrAPSR_nzcv rt,
21218                      SpecialFPRegister spec_reg) {
21219   VIXL_ASSERT(AllowAssembler());
21220   CheckIT(cond);
21221   if (IsUsingT32()) {
21222     // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1
21223     EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16));
21224     AdvanceIT();
21225     return;
21226   } else {
21227     // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1
21228     if (cond.IsNotNever()) {
21229       EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
21230               (spec_reg.GetReg() << 16));
21231       return;
21232     }
21233   }
21234   Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg);
21235 }
21236 
vmsr(Condition cond,SpecialFPRegister spec_reg,Register rt)21237 void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) {
21238   VIXL_ASSERT(AllowAssembler());
21239   CheckIT(cond);
21240   if (IsUsingT32()) {
21241     // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1
21242     if ((!rt.IsPC() || AllowUnpredictable())) {
21243       EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) |
21244                  (rt.GetCode() << 12));
21245       AdvanceIT();
21246       return;
21247     }
21248   } else {
21249     // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1
21250     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
21251       EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) |
21252               (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
21253       return;
21254     }
21255   }
21256   Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt);
21257 }
21258 
vmul(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister dm,unsigned index)21259 void Assembler::vmul(Condition cond,
21260                      DataType dt,
21261                      DRegister rd,
21262                      DRegister rn,
21263                      DRegister dm,
21264                      unsigned index) {
21265   VIXL_ASSERT(AllowAssembler());
21266   CheckIT(cond);
21267   Dt_F_size_3 encoded_dt(dt);
21268   if (IsUsingT32()) {
21269     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1
21270     if (encoded_dt.IsValid() &&
21271         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21272          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
21273       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21274         uint32_t shift = 4;
21275         if (dt.Is(I16)) {
21276           shift = 3;
21277         }
21278         uint32_t mvm = dm.GetCode() | index << shift;
21279         EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21280                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
21281                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21282                    ((mvm & 0x10) << 1));
21283         AdvanceIT();
21284         return;
21285       }
21286     }
21287   } else {
21288     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1
21289     if (encoded_dt.IsValid() &&
21290         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21291          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
21292       if (cond.Is(al)) {
21293         uint32_t shift = 4;
21294         if (dt.Is(I16)) {
21295           shift = 3;
21296         }
21297         uint32_t mvm = dm.GetCode() | index << shift;
21298         EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21299                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
21300                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21301                 ((mvm & 0x10) << 1));
21302         return;
21303       }
21304     }
21305   }
21306   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
21307 }
21308 
vmul(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegister dm,unsigned index)21309 void Assembler::vmul(Condition cond,
21310                      DataType dt,
21311                      QRegister rd,
21312                      QRegister rn,
21313                      DRegister dm,
21314                      unsigned index) {
21315   VIXL_ASSERT(AllowAssembler());
21316   CheckIT(cond);
21317   Dt_F_size_3 encoded_dt(dt);
21318   if (IsUsingT32()) {
21319     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1
21320     if (encoded_dt.IsValid() &&
21321         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21322          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
21323       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21324         uint32_t shift = 4;
21325         if (dt.Is(I16)) {
21326           shift = 3;
21327         }
21328         uint32_t mvm = dm.GetCode() | index << shift;
21329         EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21330                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
21331                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21332                    ((mvm & 0x10) << 1));
21333         AdvanceIT();
21334         return;
21335       }
21336     }
21337   } else {
21338     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1
21339     if (encoded_dt.IsValid() &&
21340         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21341          (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
21342       if (cond.Is(al)) {
21343         uint32_t shift = 4;
21344         if (dt.Is(I16)) {
21345           shift = 3;
21346         }
21347         uint32_t mvm = dm.GetCode() | index << shift;
21348         EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21349                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
21350                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21351                 ((mvm & 0x10) << 1));
21352         return;
21353       }
21354     }
21355   }
21356   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
21357 }
21358 
vmul(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21359 void Assembler::vmul(
21360     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21361   VIXL_ASSERT(AllowAssembler());
21362   CheckIT(cond);
21363   Dt_op_size_1 encoded_dt(dt);
21364   if (IsUsingT32()) {
21365     // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
21366     if (dt.Is(F32)) {
21367       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21368         EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21369                    rm.Encode(5, 0));
21370         AdvanceIT();
21371         return;
21372       }
21373     }
21374     // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
21375     if (dt.Is(F64)) {
21376       EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21377                  rm.Encode(5, 0));
21378       AdvanceIT();
21379       return;
21380     }
21381     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21382     if (encoded_dt.IsValid()) {
21383       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21384         EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21385                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21386                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21387         AdvanceIT();
21388         return;
21389       }
21390     }
21391   } else {
21392     // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
21393     if (dt.Is(F32)) {
21394       if (cond.Is(al)) {
21395         EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21396                 rm.Encode(5, 0));
21397         return;
21398       }
21399     }
21400     // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
21401     if (dt.Is(F64) && cond.IsNotNever()) {
21402       EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21403               rn.Encode(7, 16) | rm.Encode(5, 0));
21404       return;
21405     }
21406     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21407     if (encoded_dt.IsValid()) {
21408       if (cond.Is(al)) {
21409         EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21410                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21411                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21412         return;
21413       }
21414     }
21415   }
21416   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
21417 }
21418 
vmul(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)21419 void Assembler::vmul(
21420     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21421   VIXL_ASSERT(AllowAssembler());
21422   CheckIT(cond);
21423   Dt_op_size_1 encoded_dt(dt);
21424   if (IsUsingT32()) {
21425     // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
21426     if (dt.Is(F32)) {
21427       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21428         EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21429                    rm.Encode(5, 0));
21430         AdvanceIT();
21431         return;
21432       }
21433     }
21434     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21435     if (encoded_dt.IsValid()) {
21436       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21437         EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21438                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21439                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21440         AdvanceIT();
21441         return;
21442       }
21443     }
21444   } else {
21445     // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
21446     if (dt.Is(F32)) {
21447       if (cond.Is(al)) {
21448         EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21449                 rm.Encode(5, 0));
21450         return;
21451       }
21452     }
21453     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21454     if (encoded_dt.IsValid()) {
21455       if (cond.Is(al)) {
21456         EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21457                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21458                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21459         return;
21460       }
21461     }
21462   }
21463   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
21464 }
21465 
vmul(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)21466 void Assembler::vmul(
21467     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
21468   VIXL_ASSERT(AllowAssembler());
21469   CheckIT(cond);
21470   if (IsUsingT32()) {
21471     // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
21472     if (dt.Is(F32)) {
21473       EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21474                  rm.Encode(5, 0));
21475       AdvanceIT();
21476       return;
21477     }
21478   } else {
21479     // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
21480     if (dt.Is(F32) && cond.IsNotNever()) {
21481       EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21482               rn.Encode(7, 16) | rm.Encode(5, 0));
21483       return;
21484     }
21485   }
21486   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
21487 }
21488 
vmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister dm,unsigned index)21489 void Assembler::vmull(Condition cond,
21490                       DataType dt,
21491                       QRegister rd,
21492                       DRegister rn,
21493                       DRegister dm,
21494                       unsigned index) {
21495   VIXL_ASSERT(AllowAssembler());
21496   CheckIT(cond);
21497   Dt_U_size_2 encoded_dt(dt);
21498   if (IsUsingT32()) {
21499     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1
21500     if (encoded_dt.IsValid() &&
21501         (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
21502          (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) &&
21503           (dm.GetCode() <= 15)))) {
21504       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21505         uint32_t shift = 4;
21506         if (dt.Is(S16) || dt.Is(U16)) {
21507           shift = 3;
21508         }
21509         uint32_t mvm = dm.GetCode() | index << shift;
21510         EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21511                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21512                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21513                    ((mvm & 0x10) << 1));
21514         AdvanceIT();
21515         return;
21516       }
21517     }
21518   } else {
21519     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1
21520     if (encoded_dt.IsValid() &&
21521         (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
21522          (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) &&
21523           (dm.GetCode() <= 15)))) {
21524       if (cond.Is(al)) {
21525         uint32_t shift = 4;
21526         if (dt.Is(S16) || dt.Is(U16)) {
21527           shift = 3;
21528         }
21529         uint32_t mvm = dm.GetCode() | index << shift;
21530         EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21531                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21532                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21533                 ((mvm & 0x10) << 1));
21534         return;
21535       }
21536     }
21537   }
21538   Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index);
21539 }
21540 
vmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)21541 void Assembler::vmull(
21542     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21543   VIXL_ASSERT(AllowAssembler());
21544   CheckIT(cond);
21545   Dt_op_U_size_1 encoded_dt(dt);
21546   if (IsUsingT32()) {
21547     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21548     if (encoded_dt.IsValid()) {
21549       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21550         EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21551                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21552                    ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
21553                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21554         AdvanceIT();
21555         return;
21556       }
21557     }
21558   } else {
21559     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21560     if (encoded_dt.IsValid()) {
21561       if (cond.Is(al)) {
21562         EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21563                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21564                 ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
21565                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21566         return;
21567       }
21568     }
21569   }
21570   Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm);
21571 }
21572 
vmvn(Condition cond,DataType dt,DRegister rd,const DOperand & operand)21573 void Assembler::vmvn(Condition cond,
21574                      DataType dt,
21575                      DRegister rd,
21576                      const DOperand& operand) {
21577   VIXL_ASSERT(AllowAssembler());
21578   CheckIT(cond);
21579   if (operand.IsImmediate()) {
21580     ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
21581     if (IsUsingT32()) {
21582       // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
21583       if (encoded_dt.IsValid()) {
21584         if (cond.Is(al) || AllowStronglyDiscouraged()) {
21585           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
21586                      rd.Encode(22, 12) |
21587                      (encoded_dt.GetEncodedImmediate() & 0xf) |
21588                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21589                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
21590           AdvanceIT();
21591           return;
21592         }
21593       }
21594     } else {
21595       // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
21596       if (encoded_dt.IsValid()) {
21597         if (cond.Is(al)) {
21598           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
21599                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
21600                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21601                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
21602           return;
21603         }
21604       }
21605     }
21606   }
21607   if (operand.IsRegister()) {
21608     DRegister rm = operand.GetRegister();
21609     USE(dt);
21610     if (IsUsingT32()) {
21611       // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
21612       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21613         EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
21614         AdvanceIT();
21615         return;
21616       }
21617     } else {
21618       // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
21619       if (cond.Is(al)) {
21620         EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
21621         return;
21622       }
21623     }
21624   }
21625   Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
21626 }
21627 
vmvn(Condition cond,DataType dt,QRegister rd,const QOperand & operand)21628 void Assembler::vmvn(Condition cond,
21629                      DataType dt,
21630                      QRegister rd,
21631                      const QOperand& operand) {
21632   VIXL_ASSERT(AllowAssembler());
21633   CheckIT(cond);
21634   if (operand.IsImmediate()) {
21635     ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
21636     if (IsUsingT32()) {
21637       // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
21638       if (encoded_dt.IsValid()) {
21639         if (cond.Is(al) || AllowStronglyDiscouraged()) {
21640           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
21641                      rd.Encode(22, 12) |
21642                      (encoded_dt.GetEncodedImmediate() & 0xf) |
21643                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21644                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
21645           AdvanceIT();
21646           return;
21647         }
21648       }
21649     } else {
21650       // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
21651       if (encoded_dt.IsValid()) {
21652         if (cond.Is(al)) {
21653           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
21654                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
21655                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21656                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
21657           return;
21658         }
21659       }
21660     }
21661   }
21662   if (operand.IsRegister()) {
21663     QRegister rm = operand.GetRegister();
21664     USE(dt);
21665     if (IsUsingT32()) {
21666       // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
21667       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21668         EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
21669         AdvanceIT();
21670         return;
21671       }
21672     } else {
21673       // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
21674       if (cond.Is(al)) {
21675         EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
21676         return;
21677       }
21678     }
21679   }
21680   Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
21681 }
21682 
vneg(Condition cond,DataType dt,DRegister rd,DRegister rm)21683 void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
21684   VIXL_ASSERT(AllowAssembler());
21685   CheckIT(cond);
21686   Dt_F_size_1 encoded_dt(dt);
21687   if (IsUsingT32()) {
21688     // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
21689     if (encoded_dt.IsValid()) {
21690       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21691         EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21692                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
21693                    rd.Encode(22, 12) | rm.Encode(5, 0));
21694         AdvanceIT();
21695         return;
21696       }
21697     }
21698     // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
21699     if (dt.Is(F64)) {
21700       EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
21701       AdvanceIT();
21702       return;
21703     }
21704   } else {
21705     // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
21706     if (encoded_dt.IsValid()) {
21707       if (cond.Is(al)) {
21708         EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21709                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
21710                 rd.Encode(22, 12) | rm.Encode(5, 0));
21711         return;
21712       }
21713     }
21714     // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
21715     if (dt.Is(F64) && cond.IsNotNever()) {
21716       EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21717               rm.Encode(5, 0));
21718       return;
21719     }
21720   }
21721   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
21722 }
21723 
vneg(Condition cond,DataType dt,QRegister rd,QRegister rm)21724 void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
21725   VIXL_ASSERT(AllowAssembler());
21726   CheckIT(cond);
21727   Dt_F_size_1 encoded_dt(dt);
21728   if (IsUsingT32()) {
21729     // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
21730     if (encoded_dt.IsValid()) {
21731       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21732         EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21733                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
21734                    rd.Encode(22, 12) | rm.Encode(5, 0));
21735         AdvanceIT();
21736         return;
21737       }
21738     }
21739   } else {
21740     // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
21741     if (encoded_dt.IsValid()) {
21742       if (cond.Is(al)) {
21743         EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21744                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
21745                 rd.Encode(22, 12) | rm.Encode(5, 0));
21746         return;
21747       }
21748     }
21749   }
21750   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
21751 }
21752 
vneg(Condition cond,DataType dt,SRegister rd,SRegister rm)21753 void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) {
21754   VIXL_ASSERT(AllowAssembler());
21755   CheckIT(cond);
21756   if (IsUsingT32()) {
21757     // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
21758     if (dt.Is(F32)) {
21759       EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
21760       AdvanceIT();
21761       return;
21762     }
21763   } else {
21764     // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
21765     if (dt.Is(F32) && cond.IsNotNever()) {
21766       EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21767               rm.Encode(5, 0));
21768       return;
21769     }
21770   }
21771   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
21772 }
21773 
vnmla(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)21774 void Assembler::vnmla(
21775     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
21776   VIXL_ASSERT(AllowAssembler());
21777   CheckIT(cond);
21778   if (IsUsingT32()) {
21779     // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
21780     if (dt.Is(F32)) {
21781       EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21782                  rm.Encode(5, 0));
21783       AdvanceIT();
21784       return;
21785     }
21786   } else {
21787     // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
21788     if (dt.Is(F32) && cond.IsNotNever()) {
21789       EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21790               rn.Encode(7, 16) | rm.Encode(5, 0));
21791       return;
21792     }
21793   }
21794   Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
21795 }
21796 
vnmla(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21797 void Assembler::vnmla(
21798     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21799   VIXL_ASSERT(AllowAssembler());
21800   CheckIT(cond);
21801   if (IsUsingT32()) {
21802     // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
21803     if (dt.Is(F64)) {
21804       EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21805                  rm.Encode(5, 0));
21806       AdvanceIT();
21807       return;
21808     }
21809   } else {
21810     // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
21811     if (dt.Is(F64) && cond.IsNotNever()) {
21812       EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21813               rn.Encode(7, 16) | rm.Encode(5, 0));
21814       return;
21815     }
21816   }
21817   Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
21818 }
21819 
vnmls(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)21820 void Assembler::vnmls(
21821     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
21822   VIXL_ASSERT(AllowAssembler());
21823   CheckIT(cond);
21824   if (IsUsingT32()) {
21825     // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
21826     if (dt.Is(F32)) {
21827       EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21828                  rm.Encode(5, 0));
21829       AdvanceIT();
21830       return;
21831     }
21832   } else {
21833     // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
21834     if (dt.Is(F32) && cond.IsNotNever()) {
21835       EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21836               rn.Encode(7, 16) | rm.Encode(5, 0));
21837       return;
21838     }
21839   }
21840   Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
21841 }
21842 
vnmls(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21843 void Assembler::vnmls(
21844     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21845   VIXL_ASSERT(AllowAssembler());
21846   CheckIT(cond);
21847   if (IsUsingT32()) {
21848     // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
21849     if (dt.Is(F64)) {
21850       EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21851                  rm.Encode(5, 0));
21852       AdvanceIT();
21853       return;
21854     }
21855   } else {
21856     // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
21857     if (dt.Is(F64) && cond.IsNotNever()) {
21858       EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21859               rn.Encode(7, 16) | rm.Encode(5, 0));
21860       return;
21861     }
21862   }
21863   Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
21864 }
21865 
vnmul(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)21866 void Assembler::vnmul(
21867     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
21868   VIXL_ASSERT(AllowAssembler());
21869   CheckIT(cond);
21870   if (IsUsingT32()) {
21871     // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
21872     if (dt.Is(F32)) {
21873       EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21874                  rm.Encode(5, 0));
21875       AdvanceIT();
21876       return;
21877     }
21878   } else {
21879     // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
21880     if (dt.Is(F32) && cond.IsNotNever()) {
21881       EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21882               rn.Encode(7, 16) | rm.Encode(5, 0));
21883       return;
21884     }
21885   }
21886   Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
21887 }
21888 
vnmul(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21889 void Assembler::vnmul(
21890     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21891   VIXL_ASSERT(AllowAssembler());
21892   CheckIT(cond);
21893   if (IsUsingT32()) {
21894     // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
21895     if (dt.Is(F64)) {
21896       EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21897                  rm.Encode(5, 0));
21898       AdvanceIT();
21899       return;
21900     }
21901   } else {
21902     // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
21903     if (dt.Is(F64) && cond.IsNotNever()) {
21904       EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21905               rn.Encode(7, 16) | rm.Encode(5, 0));
21906       return;
21907     }
21908   }
21909   Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
21910 }
21911 
vorn(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)21912 void Assembler::vorn(Condition cond,
21913                      DataType dt,
21914                      DRegister rd,
21915                      DRegister rn,
21916                      const DOperand& operand) {
21917   VIXL_ASSERT(AllowAssembler());
21918   CheckIT(cond);
21919   if (operand.IsImmediate()) {
21920     ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
21921     if (IsUsingT32()) {
21922       // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
21923       if (encoded_dt.IsValid() && rd.Is(rn)) {
21924         if (cond.Is(al) || AllowStronglyDiscouraged()) {
21925           EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
21926                      rd.Encode(22, 12) |
21927                      (encoded_dt.GetEncodedImmediate() & 0xf) |
21928                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21929                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
21930           AdvanceIT();
21931           return;
21932         }
21933       }
21934     } else {
21935       // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
21936       if (encoded_dt.IsValid() && rd.Is(rn)) {
21937         if (cond.Is(al)) {
21938           EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
21939                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
21940                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21941                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
21942           return;
21943         }
21944       }
21945     }
21946   }
21947   if (operand.IsRegister()) {
21948     DRegister rm = operand.GetRegister();
21949     USE(dt);
21950     if (IsUsingT32()) {
21951       // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
21952       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21953         EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21954                    rm.Encode(5, 0));
21955         AdvanceIT();
21956         return;
21957       }
21958     } else {
21959       // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
21960       if (cond.Is(al)) {
21961         EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21962                 rm.Encode(5, 0));
21963         return;
21964       }
21965     }
21966   }
21967   Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
21968 }
21969 
vorn(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)21970 void Assembler::vorn(Condition cond,
21971                      DataType dt,
21972                      QRegister rd,
21973                      QRegister rn,
21974                      const QOperand& operand) {
21975   VIXL_ASSERT(AllowAssembler());
21976   CheckIT(cond);
21977   if (operand.IsImmediate()) {
21978     ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
21979     if (IsUsingT32()) {
21980       // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
21981       if (encoded_dt.IsValid() && rd.Is(rn)) {
21982         if (cond.Is(al) || AllowStronglyDiscouraged()) {
21983           EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
21984                      rd.Encode(22, 12) |
21985                      (encoded_dt.GetEncodedImmediate() & 0xf) |
21986                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21987                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
21988           AdvanceIT();
21989           return;
21990         }
21991       }
21992     } else {
21993       // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
21994       if (encoded_dt.IsValid() && rd.Is(rn)) {
21995         if (cond.Is(al)) {
21996           EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
21997                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
21998                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21999                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
22000           return;
22001         }
22002       }
22003     }
22004   }
22005   if (operand.IsRegister()) {
22006     QRegister rm = operand.GetRegister();
22007     USE(dt);
22008     if (IsUsingT32()) {
22009       // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
22010       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22011         EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22012                    rm.Encode(5, 0));
22013         AdvanceIT();
22014         return;
22015       }
22016     } else {
22017       // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
22018       if (cond.Is(al)) {
22019         EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22020                 rm.Encode(5, 0));
22021         return;
22022       }
22023     }
22024   }
22025   Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
22026 }
22027 
vorr(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)22028 void Assembler::vorr(Condition cond,
22029                      DataType dt,
22030                      DRegister rd,
22031                      DRegister rn,
22032                      const DOperand& operand) {
22033   VIXL_ASSERT(AllowAssembler());
22034   CheckIT(cond);
22035   if (operand.IsRegister()) {
22036     DRegister rm = operand.GetRegister();
22037     USE(dt);
22038     if (IsUsingT32()) {
22039       // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
22040       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22041         EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22042                    rm.Encode(5, 0));
22043         AdvanceIT();
22044         return;
22045       }
22046     } else {
22047       // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
22048       if (cond.Is(al)) {
22049         EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22050                 rm.Encode(5, 0));
22051         return;
22052       }
22053     }
22054   }
22055   if (operand.IsImmediate()) {
22056     ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
22057     if (IsUsingT32()) {
22058       // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
22059       if (encoded_dt.IsValid() && rd.Is(rn)) {
22060         if (cond.Is(al) || AllowStronglyDiscouraged()) {
22061           EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
22062                      rd.Encode(22, 12) |
22063                      (encoded_dt.GetEncodedImmediate() & 0xf) |
22064                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
22065                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
22066           AdvanceIT();
22067           return;
22068         }
22069       }
22070     } else {
22071       // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
22072       if (encoded_dt.IsValid() && rd.Is(rn)) {
22073         if (cond.Is(al)) {
22074           EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
22075                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
22076                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
22077                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
22078           return;
22079         }
22080       }
22081     }
22082   }
22083   Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
22084 }
22085 
vorr(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)22086 void Assembler::vorr(Condition cond,
22087                      DataType dt,
22088                      QRegister rd,
22089                      QRegister rn,
22090                      const QOperand& operand) {
22091   VIXL_ASSERT(AllowAssembler());
22092   CheckIT(cond);
22093   if (operand.IsRegister()) {
22094     QRegister rm = operand.GetRegister();
22095     USE(dt);
22096     if (IsUsingT32()) {
22097       // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
22098       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22099         EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22100                    rm.Encode(5, 0));
22101         AdvanceIT();
22102         return;
22103       }
22104     } else {
22105       // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
22106       if (cond.Is(al)) {
22107         EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22108                 rm.Encode(5, 0));
22109         return;
22110       }
22111     }
22112   }
22113   if (operand.IsImmediate()) {
22114     ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
22115     if (IsUsingT32()) {
22116       // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
22117       if (encoded_dt.IsValid() && rd.Is(rn)) {
22118         if (cond.Is(al) || AllowStronglyDiscouraged()) {
22119           EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
22120                      rd.Encode(22, 12) |
22121                      (encoded_dt.GetEncodedImmediate() & 0xf) |
22122                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
22123                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
22124           AdvanceIT();
22125           return;
22126         }
22127       }
22128     } else {
22129       // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
22130       if (encoded_dt.IsValid() && rd.Is(rn)) {
22131         if (cond.Is(al)) {
22132           EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
22133                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
22134                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
22135                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
22136           return;
22137         }
22138       }
22139     }
22140   }
22141   Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
22142 }
22143 
vpadal(Condition cond,DataType dt,DRegister rd,DRegister rm)22144 void Assembler::vpadal(Condition cond,
22145                        DataType dt,
22146                        DRegister rd,
22147                        DRegister rm) {
22148   VIXL_ASSERT(AllowAssembler());
22149   CheckIT(cond);
22150   Dt_op_size_2 encoded_dt(dt);
22151   if (IsUsingT32()) {
22152     // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22153     if (encoded_dt.IsValid()) {
22154       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22155         EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22156                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22157                    rd.Encode(22, 12) | rm.Encode(5, 0));
22158         AdvanceIT();
22159         return;
22160       }
22161     }
22162   } else {
22163     // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22164     if (encoded_dt.IsValid()) {
22165       if (cond.Is(al)) {
22166         EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22167                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22168                 rd.Encode(22, 12) | rm.Encode(5, 0));
22169         return;
22170       }
22171     }
22172   }
22173   Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
22174 }
22175 
vpadal(Condition cond,DataType dt,QRegister rd,QRegister rm)22176 void Assembler::vpadal(Condition cond,
22177                        DataType dt,
22178                        QRegister rd,
22179                        QRegister rm) {
22180   VIXL_ASSERT(AllowAssembler());
22181   CheckIT(cond);
22182   Dt_op_size_2 encoded_dt(dt);
22183   if (IsUsingT32()) {
22184     // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22185     if (encoded_dt.IsValid()) {
22186       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22187         EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22188                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22189                    rd.Encode(22, 12) | rm.Encode(5, 0));
22190         AdvanceIT();
22191         return;
22192       }
22193     }
22194   } else {
22195     // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22196     if (encoded_dt.IsValid()) {
22197       if (cond.Is(al)) {
22198         EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22199                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22200                 rd.Encode(22, 12) | rm.Encode(5, 0));
22201         return;
22202       }
22203     }
22204   }
22205   Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
22206 }
22207 
vpadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22208 void Assembler::vpadd(
22209     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22210   VIXL_ASSERT(AllowAssembler());
22211   CheckIT(cond);
22212   Dt_size_4 encoded_dt(dt);
22213   if (IsUsingT32()) {
22214     // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
22215     if (dt.Is(F32)) {
22216       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22217         EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22218                    rm.Encode(5, 0));
22219         AdvanceIT();
22220         return;
22221       }
22222     }
22223     // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22224     if (encoded_dt.IsValid()) {
22225       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22226         EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) |
22227                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22228         AdvanceIT();
22229         return;
22230       }
22231     }
22232   } else {
22233     // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
22234     if (dt.Is(F32)) {
22235       if (cond.Is(al)) {
22236         EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22237                 rm.Encode(5, 0));
22238         return;
22239       }
22240     }
22241     // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22242     if (encoded_dt.IsValid()) {
22243       if (cond.Is(al)) {
22244         EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) |
22245                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22246         return;
22247       }
22248     }
22249   }
22250   Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm);
22251 }
22252 
vpaddl(Condition cond,DataType dt,DRegister rd,DRegister rm)22253 void Assembler::vpaddl(Condition cond,
22254                        DataType dt,
22255                        DRegister rd,
22256                        DRegister rm) {
22257   VIXL_ASSERT(AllowAssembler());
22258   CheckIT(cond);
22259   Dt_op_size_2 encoded_dt(dt);
22260   if (IsUsingT32()) {
22261     // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22262     if (encoded_dt.IsValid()) {
22263       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22264         EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22265                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22266                    rd.Encode(22, 12) | rm.Encode(5, 0));
22267         AdvanceIT();
22268         return;
22269       }
22270     }
22271   } else {
22272     // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22273     if (encoded_dt.IsValid()) {
22274       if (cond.Is(al)) {
22275         EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22276                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22277                 rd.Encode(22, 12) | rm.Encode(5, 0));
22278         return;
22279       }
22280     }
22281   }
22282   Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
22283 }
22284 
vpaddl(Condition cond,DataType dt,QRegister rd,QRegister rm)22285 void Assembler::vpaddl(Condition cond,
22286                        DataType dt,
22287                        QRegister rd,
22288                        QRegister rm) {
22289   VIXL_ASSERT(AllowAssembler());
22290   CheckIT(cond);
22291   Dt_op_size_2 encoded_dt(dt);
22292   if (IsUsingT32()) {
22293     // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22294     if (encoded_dt.IsValid()) {
22295       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22296         EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22297                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22298                    rd.Encode(22, 12) | rm.Encode(5, 0));
22299         AdvanceIT();
22300         return;
22301       }
22302     }
22303   } else {
22304     // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22305     if (encoded_dt.IsValid()) {
22306       if (cond.Is(al)) {
22307         EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22308                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22309                 rd.Encode(22, 12) | rm.Encode(5, 0));
22310         return;
22311       }
22312     }
22313   }
22314   Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
22315 }
22316 
vpmax(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22317 void Assembler::vpmax(
22318     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22319   VIXL_ASSERT(AllowAssembler());
22320   CheckIT(cond);
22321   Dt_U_size_1 encoded_dt(dt);
22322   if (IsUsingT32()) {
22323     // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
22324     if (dt.Is(F32)) {
22325       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22326         EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22327                    rm.Encode(5, 0));
22328         AdvanceIT();
22329         return;
22330       }
22331     }
22332     // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22333     if (encoded_dt.IsValid()) {
22334       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22335         EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22336                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22337                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22338         AdvanceIT();
22339         return;
22340       }
22341     }
22342   } else {
22343     // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
22344     if (dt.Is(F32)) {
22345       if (cond.Is(al)) {
22346         EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22347                 rm.Encode(5, 0));
22348         return;
22349       }
22350     }
22351     // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22352     if (encoded_dt.IsValid()) {
22353       if (cond.Is(al)) {
22354         EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22355                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22356                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22357         return;
22358       }
22359     }
22360   }
22361   Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm);
22362 }
22363 
vpmin(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22364 void Assembler::vpmin(
22365     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22366   VIXL_ASSERT(AllowAssembler());
22367   CheckIT(cond);
22368   Dt_U_size_1 encoded_dt(dt);
22369   if (IsUsingT32()) {
22370     // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
22371     if (dt.Is(F32)) {
22372       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22373         EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22374                    rm.Encode(5, 0));
22375         AdvanceIT();
22376         return;
22377       }
22378     }
22379     // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22380     if (encoded_dt.IsValid()) {
22381       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22382         EmitT32_32(0xef000a10U | ((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     // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
22391     if (dt.Is(F32)) {
22392       if (cond.Is(al)) {
22393         EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22394                 rm.Encode(5, 0));
22395         return;
22396       }
22397     }
22398     // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22399     if (encoded_dt.IsValid()) {
22400       if (cond.Is(al)) {
22401         EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22402                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22403                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22404         return;
22405       }
22406     }
22407   }
22408   Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm);
22409 }
22410 
vpop(Condition cond,DataType dt,DRegisterList dreglist)22411 void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) {
22412   VIXL_ASSERT(AllowAssembler());
22413   CheckIT(cond);
22414   USE(dt);
22415   if (IsUsingT32()) {
22416     // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1
22417     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
22418       const DRegister& dreg = dreglist.GetFirstDRegister();
22419       unsigned len = dreglist.GetLength() * 2;
22420       EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff));
22421       AdvanceIT();
22422       return;
22423     }
22424   } else {
22425     // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1
22426     if (cond.IsNotNever() &&
22427         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
22428       const DRegister& dreg = dreglist.GetFirstDRegister();
22429       unsigned len = dreglist.GetLength() * 2;
22430       EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
22431               (len & 0xff));
22432       return;
22433     }
22434   }
22435   Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist);
22436 }
22437 
vpop(Condition cond,DataType dt,SRegisterList sreglist)22438 void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) {
22439   VIXL_ASSERT(AllowAssembler());
22440   CheckIT(cond);
22441   USE(dt);
22442   if (IsUsingT32()) {
22443     // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2
22444     const SRegister& sreg = sreglist.GetFirstSRegister();
22445     unsigned len = sreglist.GetLength();
22446     EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff));
22447     AdvanceIT();
22448     return;
22449   } else {
22450     // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2
22451     if (cond.IsNotNever()) {
22452       const SRegister& sreg = sreglist.GetFirstSRegister();
22453       unsigned len = sreglist.GetLength();
22454       EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
22455               (len & 0xff));
22456       return;
22457     }
22458   }
22459   Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist);
22460 }
22461 
vpush(Condition cond,DataType dt,DRegisterList dreglist)22462 void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) {
22463   VIXL_ASSERT(AllowAssembler());
22464   CheckIT(cond);
22465   USE(dt);
22466   if (IsUsingT32()) {
22467     // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1
22468     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
22469       const DRegister& dreg = dreglist.GetFirstDRegister();
22470       unsigned len = dreglist.GetLength() * 2;
22471       EmitT32_32(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff));
22472       AdvanceIT();
22473       return;
22474     }
22475   } else {
22476     // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1
22477     if (cond.IsNotNever() &&
22478         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
22479       const DRegister& dreg = dreglist.GetFirstDRegister();
22480       unsigned len = dreglist.GetLength() * 2;
22481       EmitA32(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
22482               (len & 0xff));
22483       return;
22484     }
22485   }
22486   Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist);
22487 }
22488 
vpush(Condition cond,DataType dt,SRegisterList sreglist)22489 void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) {
22490   VIXL_ASSERT(AllowAssembler());
22491   CheckIT(cond);
22492   USE(dt);
22493   if (IsUsingT32()) {
22494     // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2
22495     const SRegister& sreg = sreglist.GetFirstSRegister();
22496     unsigned len = sreglist.GetLength();
22497     EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff));
22498     AdvanceIT();
22499     return;
22500   } else {
22501     // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2
22502     if (cond.IsNotNever()) {
22503       const SRegister& sreg = sreglist.GetFirstSRegister();
22504       unsigned len = sreglist.GetLength();
22505       EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
22506               (len & 0xff));
22507       return;
22508     }
22509   }
22510   Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist);
22511 }
22512 
vqabs(Condition cond,DataType dt,DRegister rd,DRegister rm)22513 void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
22514   VIXL_ASSERT(AllowAssembler());
22515   CheckIT(cond);
22516   Dt_size_5 encoded_dt(dt);
22517   if (IsUsingT32()) {
22518     // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22519     if (encoded_dt.IsValid()) {
22520       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22521         EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) |
22522                    rd.Encode(22, 12) | rm.Encode(5, 0));
22523         AdvanceIT();
22524         return;
22525       }
22526     }
22527   } else {
22528     // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22529     if (encoded_dt.IsValid()) {
22530       if (cond.Is(al)) {
22531         EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) |
22532                 rd.Encode(22, 12) | rm.Encode(5, 0));
22533         return;
22534       }
22535     }
22536   }
22537   Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
22538 }
22539 
vqabs(Condition cond,DataType dt,QRegister rd,QRegister rm)22540 void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
22541   VIXL_ASSERT(AllowAssembler());
22542   CheckIT(cond);
22543   Dt_size_5 encoded_dt(dt);
22544   if (IsUsingT32()) {
22545     // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22546     if (encoded_dt.IsValid()) {
22547       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22548         EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) |
22549                    rd.Encode(22, 12) | rm.Encode(5, 0));
22550         AdvanceIT();
22551         return;
22552       }
22553     }
22554   } else {
22555     // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22556     if (encoded_dt.IsValid()) {
22557       if (cond.Is(al)) {
22558         EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) |
22559                 rd.Encode(22, 12) | rm.Encode(5, 0));
22560         return;
22561       }
22562     }
22563   }
22564   Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
22565 }
22566 
vqadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22567 void Assembler::vqadd(
22568     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22569   VIXL_ASSERT(AllowAssembler());
22570   CheckIT(cond);
22571   Dt_U_size_3 encoded_dt(dt);
22572   if (IsUsingT32()) {
22573     // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22574     if (encoded_dt.IsValid()) {
22575       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22576         EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22577                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22578                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22579         AdvanceIT();
22580         return;
22581       }
22582     }
22583   } else {
22584     // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22585     if (encoded_dt.IsValid()) {
22586       if (cond.Is(al)) {
22587         EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22588                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22589                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22590         return;
22591       }
22592     }
22593   }
22594   Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
22595 }
22596 
vqadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)22597 void Assembler::vqadd(
22598     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22599   VIXL_ASSERT(AllowAssembler());
22600   CheckIT(cond);
22601   Dt_U_size_3 encoded_dt(dt);
22602   if (IsUsingT32()) {
22603     // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22604     if (encoded_dt.IsValid()) {
22605       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22606         EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22607                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22608                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22609         AdvanceIT();
22610         return;
22611       }
22612     }
22613   } else {
22614     // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22615     if (encoded_dt.IsValid()) {
22616       if (cond.Is(al)) {
22617         EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22618                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22619                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22620         return;
22621       }
22622     }
22623   }
22624   Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
22625 }
22626 
vqdmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)22627 void Assembler::vqdmlal(
22628     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
22629   VIXL_ASSERT(AllowAssembler());
22630   CheckIT(cond);
22631   Dt_size_13 encoded_dt(dt);
22632   if (IsUsingT32()) {
22633     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
22634     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22635       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22636         EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) |
22637                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22638         AdvanceIT();
22639         return;
22640       }
22641     }
22642   } else {
22643     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
22644     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22645       if (cond.Is(al)) {
22646         EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) |
22647                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22648         return;
22649       }
22650     }
22651   }
22652   Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm);
22653 }
22654 
vqdmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister dm,unsigned index)22655 void Assembler::vqdmlal(Condition cond,
22656                         DataType dt,
22657                         QRegister rd,
22658                         DRegister rn,
22659                         DRegister dm,
22660                         unsigned index) {
22661   VIXL_ASSERT(AllowAssembler());
22662   CheckIT(cond);
22663   Dt_size_13 encoded_dt(dt);
22664   if (IsUsingT32()) {
22665     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
22666     if (encoded_dt.IsValid() &&
22667         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
22668          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
22669         (dt.Is(S16) || dt.Is(S32))) {
22670       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22671         uint32_t shift = 4;
22672         if (dt.Is(S16)) {
22673           shift = 3;
22674         }
22675         uint32_t mvm = dm.GetCode() | index << shift;
22676         EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) |
22677                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
22678                    ((mvm & 0x10) << 1));
22679         AdvanceIT();
22680         return;
22681       }
22682     }
22683   } else {
22684     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
22685     if (encoded_dt.IsValid() &&
22686         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
22687          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
22688         (dt.Is(S16) || dt.Is(S32))) {
22689       if (cond.Is(al)) {
22690         uint32_t shift = 4;
22691         if (dt.Is(S16)) {
22692           shift = 3;
22693         }
22694         uint32_t mvm = dm.GetCode() | index << shift;
22695         EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) |
22696                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
22697                 ((mvm & 0x10) << 1));
22698         return;
22699       }
22700     }
22701   }
22702   Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index);
22703 }
22704 
vqdmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)22705 void Assembler::vqdmlsl(
22706     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
22707   VIXL_ASSERT(AllowAssembler());
22708   CheckIT(cond);
22709   Dt_size_13 encoded_dt(dt);
22710   if (IsUsingT32()) {
22711     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
22712     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22713       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22714         EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) |
22715                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22716         AdvanceIT();
22717         return;
22718       }
22719     }
22720   } else {
22721     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
22722     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22723       if (cond.Is(al)) {
22724         EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) |
22725                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22726         return;
22727       }
22728     }
22729   }
22730   Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm);
22731 }
22732 
vqdmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister dm,unsigned index)22733 void Assembler::vqdmlsl(Condition cond,
22734                         DataType dt,
22735                         QRegister rd,
22736                         DRegister rn,
22737                         DRegister dm,
22738                         unsigned index) {
22739   VIXL_ASSERT(AllowAssembler());
22740   CheckIT(cond);
22741   Dt_size_13 encoded_dt(dt);
22742   if (IsUsingT32()) {
22743     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
22744     if (encoded_dt.IsValid() &&
22745         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
22746          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
22747         (dt.Is(S16) || dt.Is(S32))) {
22748       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22749         uint32_t shift = 4;
22750         if (dt.Is(S16)) {
22751           shift = 3;
22752         }
22753         uint32_t mvm = dm.GetCode() | index << shift;
22754         EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) |
22755                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
22756                    ((mvm & 0x10) << 1));
22757         AdvanceIT();
22758         return;
22759       }
22760     }
22761   } else {
22762     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
22763     if (encoded_dt.IsValid() &&
22764         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
22765          (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
22766         (dt.Is(S16) || dt.Is(S32))) {
22767       if (cond.Is(al)) {
22768         uint32_t shift = 4;
22769         if (dt.Is(S16)) {
22770           shift = 3;
22771         }
22772         uint32_t mvm = dm.GetCode() | index << shift;
22773         EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) |
22774                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
22775                 ((mvm & 0x10) << 1));
22776         return;
22777       }
22778     }
22779   }
22780   Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index);
22781 }
22782 
vqdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22783 void Assembler::vqdmulh(
22784     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22785   VIXL_ASSERT(AllowAssembler());
22786   CheckIT(cond);
22787   Dt_size_13 encoded_dt(dt);
22788   if (IsUsingT32()) {
22789     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22790     if (encoded_dt.IsValid()) {
22791       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22792         EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) |
22793                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22794         AdvanceIT();
22795         return;
22796       }
22797     }
22798   } else {
22799     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22800     if (encoded_dt.IsValid()) {
22801       if (cond.Is(al)) {
22802         EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) |
22803                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22804         return;
22805       }
22806     }
22807   }
22808   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
22809 }
22810 
vqdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)22811 void Assembler::vqdmulh(
22812     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22813   VIXL_ASSERT(AllowAssembler());
22814   CheckIT(cond);
22815   Dt_size_13 encoded_dt(dt);
22816   if (IsUsingT32()) {
22817     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22818     if (encoded_dt.IsValid()) {
22819       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22820         EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) |
22821                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22822         AdvanceIT();
22823         return;
22824       }
22825     }
22826   } else {
22827     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22828     if (encoded_dt.IsValid()) {
22829       if (cond.Is(al)) {
22830         EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) |
22831                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22832         return;
22833       }
22834     }
22835   }
22836   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
22837 }
22838 
vqdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)22839 void Assembler::vqdmulh(
22840     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
22841   VIXL_ASSERT(AllowAssembler());
22842   CheckIT(cond);
22843   Dt_size_13 encoded_dt(dt);
22844   if (IsUsingT32()) {
22845     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
22846     if (encoded_dt.IsValid() &&
22847         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22848          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22849           (rm.GetLane() <= 1))) &&
22850         (dt.Is(S16) || dt.Is(S32))) {
22851       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22852         EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) |
22853                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
22854         AdvanceIT();
22855         return;
22856       }
22857     }
22858   } else {
22859     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
22860     if (encoded_dt.IsValid() &&
22861         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22862          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22863           (rm.GetLane() <= 1))) &&
22864         (dt.Is(S16) || dt.Is(S32))) {
22865       if (cond.Is(al)) {
22866         EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) |
22867                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
22868         return;
22869       }
22870     }
22871   }
22872   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
22873 }
22874 
vqdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)22875 void Assembler::vqdmulh(
22876     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
22877   VIXL_ASSERT(AllowAssembler());
22878   CheckIT(cond);
22879   Dt_size_13 encoded_dt(dt);
22880   if (IsUsingT32()) {
22881     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
22882     if (encoded_dt.IsValid() &&
22883         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22884          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22885           (rm.GetLane() <= 1))) &&
22886         (dt.Is(S16) || dt.Is(S32))) {
22887       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22888         EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) |
22889                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
22890         AdvanceIT();
22891         return;
22892       }
22893     }
22894   } else {
22895     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
22896     if (encoded_dt.IsValid() &&
22897         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22898          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22899           (rm.GetLane() <= 1))) &&
22900         (dt.Is(S16) || dt.Is(S32))) {
22901       if (cond.Is(al)) {
22902         EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) |
22903                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
22904         return;
22905       }
22906     }
22907   }
22908   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
22909 }
22910 
vqdmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)22911 void Assembler::vqdmull(
22912     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
22913   VIXL_ASSERT(AllowAssembler());
22914   CheckIT(cond);
22915   Dt_size_13 encoded_dt(dt);
22916   if (IsUsingT32()) {
22917     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
22918     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22919       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22920         EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) |
22921                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22922         AdvanceIT();
22923         return;
22924       }
22925     }
22926   } else {
22927     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
22928     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22929       if (cond.Is(al)) {
22930         EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) |
22931                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22932         return;
22933       }
22934     }
22935   }
22936   Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
22937 }
22938 
vqdmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegisterLane rm)22939 void Assembler::vqdmull(
22940     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
22941   VIXL_ASSERT(AllowAssembler());
22942   CheckIT(cond);
22943   Dt_size_13 encoded_dt(dt);
22944   if (IsUsingT32()) {
22945     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2
22946     if (encoded_dt.IsValid() &&
22947         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22948          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22949           (rm.GetLane() <= 1))) &&
22950         (dt.Is(S16) || dt.Is(S32))) {
22951       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22952         EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) |
22953                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
22954         AdvanceIT();
22955         return;
22956       }
22957     }
22958   } else {
22959     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2
22960     if (encoded_dt.IsValid() &&
22961         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22962          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22963           (rm.GetLane() <= 1))) &&
22964         (dt.Is(S16) || dt.Is(S32))) {
22965       if (cond.Is(al)) {
22966         EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) |
22967                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
22968         return;
22969       }
22970     }
22971   }
22972   Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
22973 }
22974 
vqmovn(Condition cond,DataType dt,DRegister rd,QRegister rm)22975 void Assembler::vqmovn(Condition cond,
22976                        DataType dt,
22977                        DRegister rd,
22978                        QRegister rm) {
22979   VIXL_ASSERT(AllowAssembler());
22980   CheckIT(cond);
22981   Dt_op_size_3 encoded_dt(dt);
22982   if (IsUsingT32()) {
22983     // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
22984     if (encoded_dt.IsValid()) {
22985       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22986         EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22987                    ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22988                    rd.Encode(22, 12) | rm.Encode(5, 0));
22989         AdvanceIT();
22990         return;
22991       }
22992     }
22993   } else {
22994     // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
22995     if (encoded_dt.IsValid()) {
22996       if (cond.Is(al)) {
22997         EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22998                 ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22999                 rd.Encode(22, 12) | rm.Encode(5, 0));
23000         return;
23001       }
23002     }
23003   }
23004   Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm);
23005 }
23006 
vqmovun(Condition cond,DataType dt,DRegister rd,QRegister rm)23007 void Assembler::vqmovun(Condition cond,
23008                         DataType dt,
23009                         DRegister rd,
23010                         QRegister rm) {
23011   VIXL_ASSERT(AllowAssembler());
23012   CheckIT(cond);
23013   Dt_size_14 encoded_dt(dt);
23014   if (IsUsingT32()) {
23015     // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
23016     if (encoded_dt.IsValid()) {
23017       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23018         EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) |
23019                    rd.Encode(22, 12) | rm.Encode(5, 0));
23020         AdvanceIT();
23021         return;
23022       }
23023     }
23024   } else {
23025     // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
23026     if (encoded_dt.IsValid()) {
23027       if (cond.Is(al)) {
23028         EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) |
23029                 rd.Encode(22, 12) | rm.Encode(5, 0));
23030         return;
23031       }
23032     }
23033   }
23034   Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm);
23035 }
23036 
vqneg(Condition cond,DataType dt,DRegister rd,DRegister rm)23037 void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
23038   VIXL_ASSERT(AllowAssembler());
23039   CheckIT(cond);
23040   Dt_size_5 encoded_dt(dt);
23041   if (IsUsingT32()) {
23042     // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
23043     if (encoded_dt.IsValid()) {
23044       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23045         EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) |
23046                    rd.Encode(22, 12) | rm.Encode(5, 0));
23047         AdvanceIT();
23048         return;
23049       }
23050     }
23051   } else {
23052     // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
23053     if (encoded_dt.IsValid()) {
23054       if (cond.Is(al)) {
23055         EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) |
23056                 rd.Encode(22, 12) | rm.Encode(5, 0));
23057         return;
23058       }
23059     }
23060   }
23061   Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
23062 }
23063 
vqneg(Condition cond,DataType dt,QRegister rd,QRegister rm)23064 void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
23065   VIXL_ASSERT(AllowAssembler());
23066   CheckIT(cond);
23067   Dt_size_5 encoded_dt(dt);
23068   if (IsUsingT32()) {
23069     // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
23070     if (encoded_dt.IsValid()) {
23071       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23072         EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) |
23073                    rd.Encode(22, 12) | rm.Encode(5, 0));
23074         AdvanceIT();
23075         return;
23076       }
23077     }
23078   } else {
23079     // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
23080     if (encoded_dt.IsValid()) {
23081       if (cond.Is(al)) {
23082         EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) |
23083                 rd.Encode(22, 12) | rm.Encode(5, 0));
23084         return;
23085       }
23086     }
23087   }
23088   Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
23089 }
23090 
vqrdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)23091 void Assembler::vqrdmulh(
23092     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23093   VIXL_ASSERT(AllowAssembler());
23094   CheckIT(cond);
23095   Dt_size_13 encoded_dt(dt);
23096   if (IsUsingT32()) {
23097     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
23098     if (encoded_dt.IsValid()) {
23099       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23100         EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) |
23101                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23102         AdvanceIT();
23103         return;
23104       }
23105     }
23106   } else {
23107     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
23108     if (encoded_dt.IsValid()) {
23109       if (cond.Is(al)) {
23110         EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) |
23111                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23112         return;
23113       }
23114     }
23115   }
23116   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
23117 }
23118 
vqrdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)23119 void Assembler::vqrdmulh(
23120     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
23121   VIXL_ASSERT(AllowAssembler());
23122   CheckIT(cond);
23123   Dt_size_13 encoded_dt(dt);
23124   if (IsUsingT32()) {
23125     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
23126     if (encoded_dt.IsValid()) {
23127       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23128         EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) |
23129                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23130         AdvanceIT();
23131         return;
23132       }
23133     }
23134   } else {
23135     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
23136     if (encoded_dt.IsValid()) {
23137       if (cond.Is(al)) {
23138         EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) |
23139                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23140         return;
23141       }
23142     }
23143   }
23144   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
23145 }
23146 
vqrdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)23147 void Assembler::vqrdmulh(
23148     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
23149   VIXL_ASSERT(AllowAssembler());
23150   CheckIT(cond);
23151   Dt_size_13 encoded_dt(dt);
23152   if (IsUsingT32()) {
23153     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
23154     if (encoded_dt.IsValid() &&
23155         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
23156          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
23157           (rm.GetLane() <= 1))) &&
23158         (dt.Is(S16) || dt.Is(S32))) {
23159       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23160         EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) |
23161                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
23162         AdvanceIT();
23163         return;
23164       }
23165     }
23166   } else {
23167     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
23168     if (encoded_dt.IsValid() &&
23169         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
23170          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
23171           (rm.GetLane() <= 1))) &&
23172         (dt.Is(S16) || dt.Is(S32))) {
23173       if (cond.Is(al)) {
23174         EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) |
23175                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
23176         return;
23177       }
23178     }
23179   }
23180   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
23181 }
23182 
vqrdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)23183 void Assembler::vqrdmulh(
23184     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
23185   VIXL_ASSERT(AllowAssembler());
23186   CheckIT(cond);
23187   Dt_size_13 encoded_dt(dt);
23188   if (IsUsingT32()) {
23189     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
23190     if (encoded_dt.IsValid() &&
23191         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
23192          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
23193           (rm.GetLane() <= 1))) &&
23194         (dt.Is(S16) || dt.Is(S32))) {
23195       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23196         EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) |
23197                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
23198         AdvanceIT();
23199         return;
23200       }
23201     }
23202   } else {
23203     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
23204     if (encoded_dt.IsValid() &&
23205         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
23206          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
23207           (rm.GetLane() <= 1))) &&
23208         (dt.Is(S16) || dt.Is(S32))) {
23209       if (cond.Is(al)) {
23210         EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) |
23211                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
23212         return;
23213       }
23214     }
23215   }
23216   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
23217 }
23218 
vqrshl(Condition cond,DataType dt,DRegister rd,DRegister rm,DRegister rn)23219 void Assembler::vqrshl(
23220     Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
23221   VIXL_ASSERT(AllowAssembler());
23222   CheckIT(cond);
23223   Dt_U_size_3 encoded_dt(dt);
23224   if (IsUsingT32()) {
23225     // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
23226     if (encoded_dt.IsValid()) {
23227       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23228         EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23229                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23230                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23231         AdvanceIT();
23232         return;
23233       }
23234     }
23235   } else {
23236     // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
23237     if (encoded_dt.IsValid()) {
23238       if (cond.Is(al)) {
23239         EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23240                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23241                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23242         return;
23243       }
23244     }
23245   }
23246   Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
23247 }
23248 
vqrshl(Condition cond,DataType dt,QRegister rd,QRegister rm,QRegister rn)23249 void Assembler::vqrshl(
23250     Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
23251   VIXL_ASSERT(AllowAssembler());
23252   CheckIT(cond);
23253   Dt_U_size_3 encoded_dt(dt);
23254   if (IsUsingT32()) {
23255     // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
23256     if (encoded_dt.IsValid()) {
23257       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23258         EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23259                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23260                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23261         AdvanceIT();
23262         return;
23263       }
23264     }
23265   } else {
23266     // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
23267     if (encoded_dt.IsValid()) {
23268       if (cond.Is(al)) {
23269         EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23270                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23271                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23272         return;
23273       }
23274     }
23275   }
23276   Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
23277 }
23278 
vqrshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)23279 void Assembler::vqrshrn(Condition cond,
23280                         DataType dt,
23281                         DRegister rd,
23282                         QRegister rm,
23283                         const QOperand& operand) {
23284   VIXL_ASSERT(AllowAssembler());
23285   CheckIT(cond);
23286   if (operand.IsImmediate()) {
23287     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23288       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23289       Dt_op_size_3 encoded_dt(dt);
23290       Dt_imm6_1 encoded_dt_2(dt);
23291       if (IsUsingT32()) {
23292         // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23293         if (encoded_dt.IsValid() && (imm == 0)) {
23294           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23295             EmitT32_32(0xffb20280U |
23296                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23297                        ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
23298                        rd.Encode(22, 12) | rm.Encode(5, 0));
23299             AdvanceIT();
23300             return;
23301           }
23302         }
23303         // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
23304         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23305           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23306             uint32_t imm6 = dt.GetSize() / 2 - imm;
23307             EmitT32_32(0xef800950U |
23308                        (encoded_dt_2.GetTypeEncodingValue() << 28) |
23309                        ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
23310                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23311             AdvanceIT();
23312             return;
23313           }
23314         }
23315       } else {
23316         // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23317         if (encoded_dt.IsValid() && (imm == 0)) {
23318           if (cond.Is(al)) {
23319             EmitA32(0xf3b20280U |
23320                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23321                     ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
23322                     rd.Encode(22, 12) | rm.Encode(5, 0));
23323             return;
23324           }
23325         }
23326         // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
23327         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23328           if (cond.Is(al)) {
23329             uint32_t imm6 = dt.GetSize() / 2 - imm;
23330             EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
23331                     ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
23332                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23333             return;
23334           }
23335         }
23336       }
23337     }
23338   }
23339   Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand);
23340 }
23341 
vqrshrun(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)23342 void Assembler::vqrshrun(Condition cond,
23343                          DataType dt,
23344                          DRegister rd,
23345                          QRegister rm,
23346                          const QOperand& operand) {
23347   VIXL_ASSERT(AllowAssembler());
23348   CheckIT(cond);
23349   if (operand.IsImmediate()) {
23350     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23351       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23352       Dt_imm6_2 encoded_dt(dt);
23353       Dt_size_14 encoded_dt_2(dt);
23354       if (IsUsingT32()) {
23355         // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
23356         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23357           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23358             uint32_t imm6 = dt.GetSize() / 2 - imm;
23359             EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) |
23360                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23361                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23362             AdvanceIT();
23363             return;
23364           }
23365         }
23366         // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23367         if (encoded_dt_2.IsValid() && (imm == 0)) {
23368           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23369             EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
23370                        rd.Encode(22, 12) | rm.Encode(5, 0));
23371             AdvanceIT();
23372             return;
23373           }
23374         }
23375       } else {
23376         // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
23377         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23378           if (cond.Is(al)) {
23379             uint32_t imm6 = dt.GetSize() / 2 - imm;
23380             EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) |
23381                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23382                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23383             return;
23384           }
23385         }
23386         // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23387         if (encoded_dt_2.IsValid() && (imm == 0)) {
23388           if (cond.Is(al)) {
23389             EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
23390                     rd.Encode(22, 12) | rm.Encode(5, 0));
23391             return;
23392           }
23393         }
23394       }
23395     }
23396   }
23397   Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand);
23398 }
23399 
vqshl(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)23400 void Assembler::vqshl(Condition cond,
23401                       DataType dt,
23402                       DRegister rd,
23403                       DRegister rm,
23404                       const DOperand& operand) {
23405   VIXL_ASSERT(AllowAssembler());
23406   CheckIT(cond);
23407   if (operand.IsRegister()) {
23408     DRegister rn = operand.GetRegister();
23409     Dt_U_size_3 encoded_dt(dt);
23410     if (IsUsingT32()) {
23411       // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
23412       if (encoded_dt.IsValid()) {
23413         if (cond.Is(al) || AllowStronglyDiscouraged()) {
23414           EmitT32_32(0xef000410U |
23415                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23416                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23417                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23418           AdvanceIT();
23419           return;
23420         }
23421       }
23422     } else {
23423       // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
23424       if (encoded_dt.IsValid()) {
23425         if (cond.Is(al)) {
23426           EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23427                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23428                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23429           return;
23430         }
23431       }
23432     }
23433   }
23434   if (operand.IsImmediate()) {
23435     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23436       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23437       Dt_L_imm6_1 encoded_dt(dt);
23438       if (IsUsingT32()) {
23439         // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23440         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23441           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23442             uint32_t imm6 = imm;
23443             EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) |
23444                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23445                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23446                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23447             AdvanceIT();
23448             return;
23449           }
23450         }
23451       } else {
23452         // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23453         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23454           if (cond.Is(al)) {
23455             uint32_t imm6 = imm;
23456             EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) |
23457                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23458                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23459                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23460             return;
23461           }
23462         }
23463       }
23464     }
23465   }
23466   Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
23467 }
23468 
vqshl(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)23469 void Assembler::vqshl(Condition cond,
23470                       DataType dt,
23471                       QRegister rd,
23472                       QRegister rm,
23473                       const QOperand& operand) {
23474   VIXL_ASSERT(AllowAssembler());
23475   CheckIT(cond);
23476   if (operand.IsRegister()) {
23477     QRegister rn = operand.GetRegister();
23478     Dt_U_size_3 encoded_dt(dt);
23479     if (IsUsingT32()) {
23480       // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
23481       if (encoded_dt.IsValid()) {
23482         if (cond.Is(al) || AllowStronglyDiscouraged()) {
23483           EmitT32_32(0xef000450U |
23484                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23485                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23486                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23487           AdvanceIT();
23488           return;
23489         }
23490       }
23491     } else {
23492       // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
23493       if (encoded_dt.IsValid()) {
23494         if (cond.Is(al)) {
23495           EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23496                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23497                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23498           return;
23499         }
23500       }
23501     }
23502   }
23503   if (operand.IsImmediate()) {
23504     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23505       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23506       Dt_L_imm6_1 encoded_dt(dt);
23507       if (IsUsingT32()) {
23508         // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23509         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23510           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23511             uint32_t imm6 = imm;
23512             EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) |
23513                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23514                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23515                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23516             AdvanceIT();
23517             return;
23518           }
23519         }
23520       } else {
23521         // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23522         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23523           if (cond.Is(al)) {
23524             uint32_t imm6 = imm;
23525             EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) |
23526                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23527                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23528                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23529             return;
23530           }
23531         }
23532       }
23533     }
23534   }
23535   Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
23536 }
23537 
vqshlu(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)23538 void Assembler::vqshlu(Condition cond,
23539                        DataType dt,
23540                        DRegister rd,
23541                        DRegister rm,
23542                        const DOperand& operand) {
23543   VIXL_ASSERT(AllowAssembler());
23544   CheckIT(cond);
23545   if (operand.IsImmediate()) {
23546     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23547       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23548       Dt_L_imm6_2 encoded_dt(dt);
23549       if (IsUsingT32()) {
23550         // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23551         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23552           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23553             uint32_t imm6 = imm;
23554             EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) |
23555                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23556                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23557                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23558             AdvanceIT();
23559             return;
23560           }
23561         }
23562       } else {
23563         // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23564         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23565           if (cond.Is(al)) {
23566             uint32_t imm6 = imm;
23567             EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) |
23568                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23569                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23570                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23571             return;
23572           }
23573         }
23574       }
23575     }
23576   }
23577   Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
23578 }
23579 
vqshlu(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)23580 void Assembler::vqshlu(Condition cond,
23581                        DataType dt,
23582                        QRegister rd,
23583                        QRegister rm,
23584                        const QOperand& operand) {
23585   VIXL_ASSERT(AllowAssembler());
23586   CheckIT(cond);
23587   if (operand.IsImmediate()) {
23588     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23589       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23590       Dt_L_imm6_2 encoded_dt(dt);
23591       if (IsUsingT32()) {
23592         // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23593         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23594           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23595             uint32_t imm6 = imm;
23596             EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) |
23597                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23598                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23599                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23600             AdvanceIT();
23601             return;
23602           }
23603         }
23604       } else {
23605         // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23606         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23607           if (cond.Is(al)) {
23608             uint32_t imm6 = imm;
23609             EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) |
23610                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23611                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23612                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23613             return;
23614           }
23615         }
23616       }
23617     }
23618   }
23619   Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
23620 }
23621 
vqshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)23622 void Assembler::vqshrn(Condition cond,
23623                        DataType dt,
23624                        DRegister rd,
23625                        QRegister rm,
23626                        const QOperand& operand) {
23627   VIXL_ASSERT(AllowAssembler());
23628   CheckIT(cond);
23629   if (operand.IsImmediate()) {
23630     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23631       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23632       Dt_op_size_3 encoded_dt(dt);
23633       Dt_imm6_1 encoded_dt_2(dt);
23634       if (IsUsingT32()) {
23635         // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23636         if (encoded_dt.IsValid() && (imm == 0)) {
23637           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23638             EmitT32_32(0xffb20280U |
23639                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23640                        ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
23641                        rd.Encode(22, 12) | rm.Encode(5, 0));
23642             AdvanceIT();
23643             return;
23644           }
23645         }
23646         // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
23647         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23648           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23649             uint32_t imm6 = dt.GetSize() / 2 - imm;
23650             EmitT32_32(0xef800910U |
23651                        (encoded_dt_2.GetTypeEncodingValue() << 28) |
23652                        ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
23653                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23654             AdvanceIT();
23655             return;
23656           }
23657         }
23658       } else {
23659         // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23660         if (encoded_dt.IsValid() && (imm == 0)) {
23661           if (cond.Is(al)) {
23662             EmitA32(0xf3b20280U |
23663                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23664                     ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
23665                     rd.Encode(22, 12) | rm.Encode(5, 0));
23666             return;
23667           }
23668         }
23669         // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
23670         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23671           if (cond.Is(al)) {
23672             uint32_t imm6 = dt.GetSize() / 2 - imm;
23673             EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
23674                     ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
23675                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23676             return;
23677           }
23678         }
23679       }
23680     }
23681   }
23682   Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand);
23683 }
23684 
vqshrun(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)23685 void Assembler::vqshrun(Condition cond,
23686                         DataType dt,
23687                         DRegister rd,
23688                         QRegister rm,
23689                         const QOperand& operand) {
23690   VIXL_ASSERT(AllowAssembler());
23691   CheckIT(cond);
23692   if (operand.IsImmediate()) {
23693     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23694       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23695       Dt_imm6_2 encoded_dt(dt);
23696       Dt_size_14 encoded_dt_2(dt);
23697       if (IsUsingT32()) {
23698         // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
23699         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23700           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23701             uint32_t imm6 = dt.GetSize() / 2 - imm;
23702             EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) |
23703                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23704                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23705             AdvanceIT();
23706             return;
23707           }
23708         }
23709         // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23710         if (encoded_dt_2.IsValid() && (imm == 0)) {
23711           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23712             EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
23713                        rd.Encode(22, 12) | rm.Encode(5, 0));
23714             AdvanceIT();
23715             return;
23716           }
23717         }
23718       } else {
23719         // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
23720         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23721           if (cond.Is(al)) {
23722             uint32_t imm6 = dt.GetSize() / 2 - imm;
23723             EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) |
23724                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23725                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23726             return;
23727           }
23728         }
23729         // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23730         if (encoded_dt_2.IsValid() && (imm == 0)) {
23731           if (cond.Is(al)) {
23732             EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
23733                     rd.Encode(22, 12) | rm.Encode(5, 0));
23734             return;
23735           }
23736         }
23737       }
23738     }
23739   }
23740   Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand);
23741 }
23742 
vqsub(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)23743 void Assembler::vqsub(
23744     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23745   VIXL_ASSERT(AllowAssembler());
23746   CheckIT(cond);
23747   Dt_U_size_3 encoded_dt(dt);
23748   if (IsUsingT32()) {
23749     // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
23750     if (encoded_dt.IsValid()) {
23751       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23752         EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23753                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23754                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23755         AdvanceIT();
23756         return;
23757       }
23758     }
23759   } else {
23760     // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
23761     if (encoded_dt.IsValid()) {
23762       if (cond.Is(al)) {
23763         EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23764                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23765                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23766         return;
23767       }
23768     }
23769   }
23770   Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
23771 }
23772 
vqsub(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)23773 void Assembler::vqsub(
23774     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
23775   VIXL_ASSERT(AllowAssembler());
23776   CheckIT(cond);
23777   Dt_U_size_3 encoded_dt(dt);
23778   if (IsUsingT32()) {
23779     // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
23780     if (encoded_dt.IsValid()) {
23781       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23782         EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23783                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23784                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23785         AdvanceIT();
23786         return;
23787       }
23788     }
23789   } else {
23790     // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
23791     if (encoded_dt.IsValid()) {
23792       if (cond.Is(al)) {
23793         EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23794                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23795                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23796         return;
23797       }
23798     }
23799   }
23800   Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
23801 }
23802 
vraddhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)23803 void Assembler::vraddhn(
23804     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
23805   VIXL_ASSERT(AllowAssembler());
23806   CheckIT(cond);
23807   Dt_size_3 encoded_dt(dt);
23808   if (IsUsingT32()) {
23809     // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
23810     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
23811       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23812         EmitT32_32(0xff800400U | (encoded_dt.GetEncodingValue() << 20) |
23813                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23814         AdvanceIT();
23815         return;
23816       }
23817     }
23818   } else {
23819     // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
23820     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
23821       if (cond.Is(al)) {
23822         EmitA32(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) |
23823                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23824         return;
23825       }
23826     }
23827   }
23828   Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm);
23829 }
23830 
vrecpe(Condition cond,DataType dt,DRegister rd,DRegister rm)23831 void Assembler::vrecpe(Condition cond,
23832                        DataType dt,
23833                        DRegister rd,
23834                        DRegister rm) {
23835   VIXL_ASSERT(AllowAssembler());
23836   CheckIT(cond);
23837   Dt_F_size_4 encoded_dt(dt);
23838   if (IsUsingT32()) {
23839     // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
23840     if (encoded_dt.IsValid()) {
23841       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23842         EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23843                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23844                    rd.Encode(22, 12) | rm.Encode(5, 0));
23845         AdvanceIT();
23846         return;
23847       }
23848     }
23849   } else {
23850     // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
23851     if (encoded_dt.IsValid()) {
23852       if (cond.Is(al)) {
23853         EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23854                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23855                 rd.Encode(22, 12) | rm.Encode(5, 0));
23856         return;
23857       }
23858     }
23859   }
23860   Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
23861 }
23862 
vrecpe(Condition cond,DataType dt,QRegister rd,QRegister rm)23863 void Assembler::vrecpe(Condition cond,
23864                        DataType dt,
23865                        QRegister rd,
23866                        QRegister rm) {
23867   VIXL_ASSERT(AllowAssembler());
23868   CheckIT(cond);
23869   Dt_F_size_4 encoded_dt(dt);
23870   if (IsUsingT32()) {
23871     // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
23872     if (encoded_dt.IsValid()) {
23873       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23874         EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23875                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23876                    rd.Encode(22, 12) | rm.Encode(5, 0));
23877         AdvanceIT();
23878         return;
23879       }
23880     }
23881   } else {
23882     // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
23883     if (encoded_dt.IsValid()) {
23884       if (cond.Is(al)) {
23885         EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23886                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23887                 rd.Encode(22, 12) | rm.Encode(5, 0));
23888         return;
23889       }
23890     }
23891   }
23892   Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
23893 }
23894 
vrecps(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)23895 void Assembler::vrecps(
23896     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23897   VIXL_ASSERT(AllowAssembler());
23898   CheckIT(cond);
23899   if (IsUsingT32()) {
23900     // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
23901     if (dt.Is(F32)) {
23902       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23903         EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23904                    rm.Encode(5, 0));
23905         AdvanceIT();
23906         return;
23907       }
23908     }
23909   } else {
23910     // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
23911     if (dt.Is(F32)) {
23912       if (cond.Is(al)) {
23913         EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23914                 rm.Encode(5, 0));
23915         return;
23916       }
23917     }
23918   }
23919   Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
23920 }
23921 
vrecps(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)23922 void Assembler::vrecps(
23923     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
23924   VIXL_ASSERT(AllowAssembler());
23925   CheckIT(cond);
23926   if (IsUsingT32()) {
23927     // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
23928     if (dt.Is(F32)) {
23929       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23930         EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23931                    rm.Encode(5, 0));
23932         AdvanceIT();
23933         return;
23934       }
23935     }
23936   } else {
23937     // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
23938     if (dt.Is(F32)) {
23939       if (cond.Is(al)) {
23940         EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23941                 rm.Encode(5, 0));
23942         return;
23943       }
23944     }
23945   }
23946   Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
23947 }
23948 
vrev16(Condition cond,DataType dt,DRegister rd,DRegister rm)23949 void Assembler::vrev16(Condition cond,
23950                        DataType dt,
23951                        DRegister rd,
23952                        DRegister rm) {
23953   VIXL_ASSERT(AllowAssembler());
23954   CheckIT(cond);
23955   Dt_size_1 encoded_dt(dt);
23956   if (IsUsingT32()) {
23957     // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
23958     if (encoded_dt.IsValid()) {
23959       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23960         EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) |
23961                    rd.Encode(22, 12) | rm.Encode(5, 0));
23962         AdvanceIT();
23963         return;
23964       }
23965     }
23966   } else {
23967     // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
23968     if (encoded_dt.IsValid()) {
23969       if (cond.Is(al)) {
23970         EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) |
23971                 rd.Encode(22, 12) | rm.Encode(5, 0));
23972         return;
23973       }
23974     }
23975   }
23976   Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
23977 }
23978 
vrev16(Condition cond,DataType dt,QRegister rd,QRegister rm)23979 void Assembler::vrev16(Condition cond,
23980                        DataType dt,
23981                        QRegister rd,
23982                        QRegister rm) {
23983   VIXL_ASSERT(AllowAssembler());
23984   CheckIT(cond);
23985   Dt_size_1 encoded_dt(dt);
23986   if (IsUsingT32()) {
23987     // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
23988     if (encoded_dt.IsValid()) {
23989       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23990         EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) |
23991                    rd.Encode(22, 12) | rm.Encode(5, 0));
23992         AdvanceIT();
23993         return;
23994       }
23995     }
23996   } else {
23997     // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
23998     if (encoded_dt.IsValid()) {
23999       if (cond.Is(al)) {
24000         EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) |
24001                 rd.Encode(22, 12) | rm.Encode(5, 0));
24002         return;
24003       }
24004     }
24005   }
24006   Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
24007 }
24008 
vrev32(Condition cond,DataType dt,DRegister rd,DRegister rm)24009 void Assembler::vrev32(Condition cond,
24010                        DataType dt,
24011                        DRegister rd,
24012                        DRegister rm) {
24013   VIXL_ASSERT(AllowAssembler());
24014   CheckIT(cond);
24015   Dt_size_15 encoded_dt(dt);
24016   if (IsUsingT32()) {
24017     // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
24018     if (encoded_dt.IsValid()) {
24019       if (cond.Is(al) || AllowStronglyDiscouraged()) {
24020         EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) |
24021                    rd.Encode(22, 12) | rm.Encode(5, 0));
24022         AdvanceIT();
24023         return;
24024       }
24025     }
24026   } else {
24027     // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
24028     if (encoded_dt.IsValid()) {
24029       if (cond.Is(al)) {
24030         EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) |
24031                 rd.Encode(22, 12) | rm.Encode(5, 0));
24032         return;
24033       }
24034     }
24035   }
24036   Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
24037 }
24038 
vrev32(Condition cond,DataType dt,QRegister rd,QRegister rm)24039 void Assembler::vrev32(Condition cond,
24040                        DataType dt,
24041                        QRegister rd,
24042                        QRegister rm) {
24043   VIXL_ASSERT(AllowAssembler());
24044   CheckIT(cond);
24045   Dt_size_15 encoded_dt(dt);
24046   if (IsUsingT32()) {
24047     // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
24048     if (encoded_dt.IsValid()) {
24049       if (cond.Is(al) || AllowStronglyDiscouraged()) {
24050         EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) |
24051                    rd.Encode(22, 12) | rm.Encode(5, 0));
24052         AdvanceIT();
24053         return;
24054       }
24055     }
24056   } else {
24057     // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
24058     if (encoded_dt.IsValid()) {
24059       if (cond.Is(al)) {
24060         EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) |
24061                 rd.Encode(22, 12) | rm.Encode(5, 0));
24062         return;
24063       }
24064     }
24065   }
24066   Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
24067 }
24068 
vrev64(Condition cond,DataType dt,DRegister rd,DRegister rm)24069 void Assembler::vrev64(Condition cond,
24070                        DataType dt,
24071                        DRegister rd,
24072                        DRegister rm) {
24073   VIXL_ASSERT(AllowAssembler());
24074   CheckIT(cond);
24075   Dt_size_7 encoded_dt(dt);
24076   if (IsUsingT32()) {
24077     // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
24078     if (encoded_dt.IsValid()) {
24079       if (cond.Is(al) || AllowStronglyDiscouraged()) {
24080         EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) |
24081                    rd.Encode(22, 12) | rm.Encode(5, 0));
24082         AdvanceIT();
24083         return;
24084       }
24085     }
24086   } else {
24087     // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
24088     if (encoded_dt.IsValid()) {
24089       if (cond.Is(al)) {
24090         EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) |
24091                 rd.Encode(22, 12) | rm.Encode(5, 0));
24092         return;
24093       }
24094     }
24095   }
24096   Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
24097 }
24098 
vrev64(Condition cond,DataType dt,QRegister rd,QRegister rm)24099 void Assembler::vrev64(Condition cond,
24100                        DataType dt,
24101                        QRegister rd,
24102                        QRegister rm) {
24103   VIXL_ASSERT(AllowAssembler());
24104   CheckIT(cond);
24105   Dt_size_7 encoded_dt(dt);
24106   if (IsUsingT32()) {
24107     // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
24108     if (encoded_dt.IsValid()) {
24109       if (cond.Is(al) || AllowStronglyDiscouraged()) {
24110         EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) |
24111                    rd.Encode(22, 12) | rm.Encode(5, 0));
24112         AdvanceIT();
24113         return;
24114       }
24115     }
24116   } else {
24117     // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
24118     if (encoded_dt.IsValid()) {
24119       if (cond.Is(al)) {
24120         EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) |
24121                 rd.Encode(22, 12) | rm.Encode(5, 0));
24122         return;
24123       }
24124     }
24125   }
24126   Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
24127 }
24128 
vrhadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)24129 void Assembler::vrhadd(
24130     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
24131   VIXL_ASSERT(AllowAssembler());
24132   CheckIT(cond);
24133   Dt_U_size_1 encoded_dt(dt);
24134   if (IsUsingT32()) {
24135     // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
24136     if (encoded_dt.IsValid()) {
24137       if (cond.Is(al) || AllowStronglyDiscouraged()) {
24138         EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24139                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24140                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
24141         AdvanceIT();
24142         return;
24143       }
24144     }
24145   } else {
24146     // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
24147     if (encoded_dt.IsValid()) {
24148       if (cond.Is(al)) {
24149         EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24150                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24151                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
24152         return;
24153       }
24154     }
24155   }
24156   Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
24157 }
24158 
vrhadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)24159 void Assembler::vrhadd(
24160     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
24161   VIXL_ASSERT(AllowAssembler());
24162   CheckIT(cond);
24163   Dt_U_size_1 encoded_dt(dt);
24164   if (IsUsingT32()) {
24165     // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
24166     if (encoded_dt.IsValid()) {
24167       if (cond.Is(al) || AllowStronglyDiscouraged()) {
24168         EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24169                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24170                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
24171         AdvanceIT();
24172         return;
24173       }
24174     }
24175   } else {
24176     // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
24177     if (encoded_dt.IsValid()) {
24178       if (cond.Is(al)) {
24179         EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24180                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24181                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
24182         return;
24183       }
24184     }
24185   }
24186   Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
24187 }
24188 
vrinta(DataType dt,DRegister rd,DRegister rm)24189 void Assembler::vrinta(DataType dt, DRegister rd, DRegister rm) {
24190   VIXL_ASSERT(AllowAssembler());
24191   CheckIT(al);
24192   Dt_size_16 encoded_dt(dt);
24193   if (IsUsingT32()) {
24194     // VRINTA{<q>}.<dt> <Dd>, <Dm> ; T1
24195     if (encoded_dt.IsValid()) {
24196       EmitT32_32(0xffb20500U | (encoded_dt.GetEncodingValue() << 18) |
24197                  rd.Encode(22, 12) | rm.Encode(5, 0));
24198       AdvanceIT();
24199       return;
24200     }
24201     // VRINTA{<q>}.F64 <Dd>, <Dm> ; T1
24202     if (dt.Is(F64)) {
24203       EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24204       AdvanceIT();
24205       return;
24206     }
24207   } else {
24208     // VRINTA{<q>}.<dt> <Dd>, <Dm> ; A1
24209     if (encoded_dt.IsValid()) {
24210       EmitA32(0xf3b20500U | (encoded_dt.GetEncodingValue() << 18) |
24211               rd.Encode(22, 12) | rm.Encode(5, 0));
24212       return;
24213     }
24214     // VRINTA{<q>}.F64 <Dd>, <Dm> ; A1
24215     if (dt.Is(F64)) {
24216       EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24217       return;
24218     }
24219   }
24220   Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm);
24221 }
24222 
vrinta(DataType dt,QRegister rd,QRegister rm)24223 void Assembler::vrinta(DataType dt, QRegister rd, QRegister rm) {
24224   VIXL_ASSERT(AllowAssembler());
24225   CheckIT(al);
24226   Dt_size_16 encoded_dt(dt);
24227   if (IsUsingT32()) {
24228     // VRINTA{<q>}.<dt> <Qd>, <Qm> ; T1
24229     if (encoded_dt.IsValid()) {
24230       EmitT32_32(0xffb20540U | (encoded_dt.GetEncodingValue() << 18) |
24231                  rd.Encode(22, 12) | rm.Encode(5, 0));
24232       AdvanceIT();
24233       return;
24234     }
24235   } else {
24236     // VRINTA{<q>}.<dt> <Qd>, <Qm> ; A1
24237     if (encoded_dt.IsValid()) {
24238       EmitA32(0xf3b20540U | (encoded_dt.GetEncodingValue() << 18) |
24239               rd.Encode(22, 12) | rm.Encode(5, 0));
24240       return;
24241     }
24242   }
24243   Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm);
24244 }
24245 
vrinta(DataType dt,SRegister rd,SRegister rm)24246 void Assembler::vrinta(DataType dt, SRegister rd, SRegister rm) {
24247   VIXL_ASSERT(AllowAssembler());
24248   CheckIT(al);
24249   if (IsUsingT32()) {
24250     // VRINTA{<q>}.F32 <Sd>, <Sm> ; T1
24251     if (dt.Is(F32)) {
24252       EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24253       AdvanceIT();
24254       return;
24255     }
24256   } else {
24257     // VRINTA{<q>}.F32 <Sd>, <Sm> ; A1
24258     if (dt.Is(F32)) {
24259       EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24260       return;
24261     }
24262   }
24263   Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm);
24264 }
24265 
vrintm(DataType dt,DRegister rd,DRegister rm)24266 void Assembler::vrintm(DataType dt, DRegister rd, DRegister rm) {
24267   VIXL_ASSERT(AllowAssembler());
24268   CheckIT(al);
24269   Dt_size_16 encoded_dt(dt);
24270   if (IsUsingT32()) {
24271     // VRINTM{<q>}.<dt> <Dd>, <Dm> ; T1
24272     if (encoded_dt.IsValid()) {
24273       EmitT32_32(0xffb20680U | (encoded_dt.GetEncodingValue() << 18) |
24274                  rd.Encode(22, 12) | rm.Encode(5, 0));
24275       AdvanceIT();
24276       return;
24277     }
24278     // VRINTM{<q>}.F64 <Dd>, <Dm> ; T1
24279     if (dt.Is(F64)) {
24280       EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24281       AdvanceIT();
24282       return;
24283     }
24284   } else {
24285     // VRINTM{<q>}.<dt> <Dd>, <Dm> ; A1
24286     if (encoded_dt.IsValid()) {
24287       EmitA32(0xf3b20680U | (encoded_dt.GetEncodingValue() << 18) |
24288               rd.Encode(22, 12) | rm.Encode(5, 0));
24289       return;
24290     }
24291     // VRINTM{<q>}.F64 <Dd>, <Dm> ; A1
24292     if (dt.Is(F64)) {
24293       EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24294       return;
24295     }
24296   }
24297   Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm);
24298 }
24299 
vrintm(DataType dt,QRegister rd,QRegister rm)24300 void Assembler::vrintm(DataType dt, QRegister rd, QRegister rm) {
24301   VIXL_ASSERT(AllowAssembler());
24302   CheckIT(al);
24303   Dt_size_16 encoded_dt(dt);
24304   if (IsUsingT32()) {
24305     // VRINTM{<q>}.<dt> <Qd>, <Qm> ; T1
24306     if (encoded_dt.IsValid()) {
24307       EmitT32_32(0xffb206c0U | (encoded_dt.GetEncodingValue() << 18) |
24308                  rd.Encode(22, 12) | rm.Encode(5, 0));
24309       AdvanceIT();
24310       return;
24311     }
24312   } else {
24313     // VRINTM{<q>}.<dt> <Qd>, <Qm> ; A1
24314     if (encoded_dt.IsValid()) {
24315       EmitA32(0xf3b206c0U | (encoded_dt.GetEncodingValue() << 18) |
24316               rd.Encode(22, 12) | rm.Encode(5, 0));
24317       return;
24318     }
24319   }
24320   Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm);
24321 }
24322 
vrintm(DataType dt,SRegister rd,SRegister rm)24323 void Assembler::vrintm(DataType dt, SRegister rd, SRegister rm) {
24324   VIXL_ASSERT(AllowAssembler());
24325   CheckIT(al);
24326   if (IsUsingT32()) {
24327     // VRINTM{<q>}.F32 <Sd>, <Sm> ; T1
24328     if (dt.Is(F32)) {
24329       EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24330       AdvanceIT();
24331       return;
24332     }
24333   } else {
24334     // VRINTM{<q>}.F32 <Sd>, <Sm> ; A1
24335     if (dt.Is(F32)) {
24336       EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24337       return;
24338     }
24339   }
24340   Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm);
24341 }
24342 
vrintn(DataType dt,DRegister rd,DRegister rm)24343 void Assembler::vrintn(DataType dt, DRegister rd, DRegister rm) {
24344   VIXL_ASSERT(AllowAssembler());
24345   CheckIT(al);
24346   Dt_size_16 encoded_dt(dt);
24347   if (IsUsingT32()) {
24348     // VRINTN{<q>}.<dt> <Dd>, <Dm> ; T1
24349     if (encoded_dt.IsValid()) {
24350       EmitT32_32(0xffb20400U | (encoded_dt.GetEncodingValue() << 18) |
24351                  rd.Encode(22, 12) | rm.Encode(5, 0));
24352       AdvanceIT();
24353       return;
24354     }
24355     // VRINTN{<q>}.F64 <Dd>, <Dm> ; T1
24356     if (dt.Is(F64)) {
24357       EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24358       AdvanceIT();
24359       return;
24360     }
24361   } else {
24362     // VRINTN{<q>}.<dt> <Dd>, <Dm> ; A1
24363     if (encoded_dt.IsValid()) {
24364       EmitA32(0xf3b20400U | (encoded_dt.GetEncodingValue() << 18) |
24365               rd.Encode(22, 12) | rm.Encode(5, 0));
24366       return;
24367     }
24368     // VRINTN{<q>}.F64 <Dd>, <Dm> ; A1
24369     if (dt.Is(F64)) {
24370       EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24371       return;
24372     }
24373   }
24374   Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm);
24375 }
24376 
vrintn(DataType dt,QRegister rd,QRegister rm)24377 void Assembler::vrintn(DataType dt, QRegister rd, QRegister rm) {
24378   VIXL_ASSERT(AllowAssembler());
24379   CheckIT(al);
24380   Dt_size_16 encoded_dt(dt);
24381   if (IsUsingT32()) {
24382     // VRINTN{<q>}.<dt> <Qd>, <Qm> ; T1
24383     if (encoded_dt.IsValid()) {
24384       EmitT32_32(0xffb20440U | (encoded_dt.GetEncodingValue() << 18) |
24385                  rd.Encode(22, 12) | rm.Encode(5, 0));
24386       AdvanceIT();
24387       return;
24388     }
24389   } else {
24390     // VRINTN{<q>}.<dt> <Qd>, <Qm> ; A1
24391     if (encoded_dt.IsValid()) {
24392       EmitA32(0xf3b20440U | (encoded_dt.GetEncodingValue() << 18) |
24393               rd.Encode(22, 12) | rm.Encode(5, 0));
24394       return;
24395     }
24396   }
24397   Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm);
24398 }
24399 
vrintn(DataType dt,SRegister rd,SRegister rm)24400 void Assembler::vrintn(DataType dt, SRegister rd, SRegister rm) {
24401   VIXL_ASSERT(AllowAssembler());
24402   CheckIT(al);
24403   if (IsUsingT32()) {
24404     // VRINTN{<q>}.F32 <Sd>, <Sm> ; T1
24405     if (dt.Is(F32)) {
24406       EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24407       AdvanceIT();
24408       return;
24409     }
24410   } else {
24411     // VRINTN{<q>}.F32 <Sd>, <Sm> ; A1
24412     if (dt.Is(F32)) {
24413       EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24414       return;
24415     }
24416   }
24417   Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm);
24418 }
24419 
vrintp(DataType dt,DRegister rd,DRegister rm)24420 void Assembler::vrintp(DataType dt, DRegister rd, DRegister rm) {
24421   VIXL_ASSERT(AllowAssembler());
24422   CheckIT(al);
24423   Dt_size_16 encoded_dt(dt);
24424   if (IsUsingT32()) {
24425     // VRINTP{<q>}.<dt> <Dd>, <Dm> ; T1
24426     if (encoded_dt.IsValid()) {
24427       EmitT32_32(0xffb20780U | (encoded_dt.GetEncodingValue() << 18) |
24428                  rd.Encode(22, 12) | rm.Encode(5, 0));
24429       AdvanceIT();
24430       return;
24431     }
24432     // VRINTP{<q>}.F64 <Dd>, <Dm> ; T1
24433     if (dt.Is(F64)) {
24434       EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24435       AdvanceIT();
24436       return;
24437     }
24438   } else {
24439     // VRINTP{<q>}.<dt> <Dd>, <Dm> ; A1
24440     if (encoded_dt.IsValid()) {
24441       EmitA32(0xf3b20780U | (encoded_dt.GetEncodingValue() << 18) |
24442               rd.Encode(22, 12) | rm.Encode(5, 0));
24443       return;
24444     }
24445     // VRINTP{<q>}.F64 <Dd>, <Dm> ; A1
24446     if (dt.Is(F64)) {
24447       EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24448       return;
24449     }
24450   }
24451   Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm);
24452 }
24453 
vrintp(DataType dt,QRegister rd,QRegister rm)24454 void Assembler::vrintp(DataType dt, QRegister rd, QRegister rm) {
24455   VIXL_ASSERT(AllowAssembler());
24456   CheckIT(al);
24457   Dt_size_16 encoded_dt(dt);
24458   if (IsUsingT32()) {
24459     // VRINTP{<q>}.<dt> <Qd>, <Qm> ; T1
24460     if (encoded_dt.IsValid()) {
24461       EmitT32_32(0xffb207c0U | (encoded_dt.GetEncodingValue() << 18) |
24462                  rd.Encode(22, 12) | rm.Encode(5, 0));
24463       AdvanceIT();
24464       return;
24465     }
24466   } else {
24467     // VRINTP{<q>}.<dt> <Qd>, <Qm> ; A1
24468     if (encoded_dt.IsValid()) {
24469       EmitA32(0xf3b207c0U | (encoded_dt.GetEncodingValue() << 18) |
24470               rd.Encode(22, 12) | rm.Encode(5, 0));
24471       return;
24472     }
24473   }
24474   Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm);
24475 }
24476 
vrintp(DataType dt,SRegister rd,SRegister rm)24477 void Assembler::vrintp(DataType dt, SRegister rd, SRegister rm) {
24478   VIXL_ASSERT(AllowAssembler());
24479   CheckIT(al);
24480   if (IsUsingT32()) {
24481     // VRINTP{<q>}.F32 <Sd>, <Sm> ; T1
24482     if (dt.Is(F32)) {
24483       EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24484       AdvanceIT();
24485       return;
24486     }
24487   } else {
24488     // VRINTP{<q>}.F32 <Sd>, <Sm> ; A1
24489     if (dt.Is(F32)) {
24490       EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24491       return;
24492     }
24493   }
24494   Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm);
24495 }
24496 
vrintr(Condition cond,DataType dt,SRegister rd,SRegister rm)24497 void Assembler::vrintr(Condition cond,
24498                        DataType dt,
24499                        SRegister rd,
24500                        SRegister rm) {
24501   VIXL_ASSERT(AllowAssembler());
24502   CheckIT(cond);
24503   if (IsUsingT32()) {
24504     // VRINTR{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
24505     if (dt.Is(F32)) {
24506       EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24507       AdvanceIT();
24508       return;
24509     }
24510   } else {
24511     // VRINTR{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
24512     if (dt.Is(F32) && cond.IsNotNever()) {
24513       EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24514               rm.Encode(5, 0));
24515       return;
24516     }
24517   }
24518   Delegate(kVrintr, &Assembler::vrintr, cond, dt, rd, rm);
24519 }
24520 
vrintr(Condition cond,DataType dt,DRegister rd,DRegister rm)24521 void Assembler::vrintr(Condition cond,
24522                        DataType dt,
24523                        DRegister rd,
24524                        DRegister rm) {
24525   VIXL_ASSERT(AllowAssembler());
24526   CheckIT(cond);
24527   if (IsUsingT32()) {
24528     // VRINTR{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
24529     if (dt.Is(F64)) {
24530       EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24531       AdvanceIT();
24532       return;
24533     }
24534   } else {
24535     // VRINTR{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
24536     if (dt.Is(F64) && cond.IsNotNever()) {
24537       EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24538               rm.Encode(5, 0));
24539       return;
24540     }
24541   }
24542   Delegate(kVrintr, &Assembler::vrintr, cond, dt, rd, rm);
24543 }
24544 
vrintx(Condition cond,DataType dt,DRegister rd,DRegister rm)24545 void Assembler::vrintx(Condition cond,
24546                        DataType dt,
24547                        DRegister rd,
24548                        DRegister rm) {
24549   VIXL_ASSERT(AllowAssembler());
24550   CheckIT(cond);
24551   Dt_size_16 encoded_dt(dt);
24552   if (IsUsingT32()) {
24553     // VRINTX{<q>}.<dt> <Dd>, <Dm> ; T1
24554     if (encoded_dt.IsValid()) {
24555       EmitT32_32(0xffb20480U | (encoded_dt.GetEncodingValue() << 18) |
24556                  rd.Encode(22, 12) | rm.Encode(5, 0));
24557       AdvanceIT();
24558       return;
24559     }
24560     // VRINTX{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
24561     if (dt.Is(F64)) {
24562       EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24563       AdvanceIT();
24564       return;
24565     }
24566   } else {
24567     // VRINTX{<q>}.<dt> <Dd>, <Dm> ; A1
24568     if (encoded_dt.IsValid()) {
24569       EmitA32(0xf3b20480U | (encoded_dt.GetEncodingValue() << 18) |
24570               rd.Encode(22, 12) | rm.Encode(5, 0));
24571       return;
24572     }
24573     // VRINTX{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
24574     if (dt.Is(F64) && cond.IsNotNever()) {
24575       EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24576               rm.Encode(5, 0));
24577       return;
24578     }
24579   }
24580   Delegate(kVrintx, &Assembler::vrintx, cond, dt, rd, rm);
24581 }
24582 
vrintx(DataType dt,QRegister rd,QRegister rm)24583 void Assembler::vrintx(DataType dt, QRegister rd, QRegister rm) {
24584   VIXL_ASSERT(AllowAssembler());
24585   CheckIT(al);
24586   Dt_size_16 encoded_dt(dt);
24587   if (IsUsingT32()) {
24588     // VRINTX{<q>}.<dt> <Qd>, <Qm> ; T1
24589     if (encoded_dt.IsValid()) {
24590       EmitT32_32(0xffb204c0U | (encoded_dt.GetEncodingValue() << 18) |
24591                  rd.Encode(22, 12) | rm.Encode(5, 0));
24592       AdvanceIT();
24593       return;
24594     }
24595   } else {
24596     // VRINTX{<q>}.<dt> <Qd>, <Qm> ; A1
24597     if (encoded_dt.IsValid()) {
24598       EmitA32(0xf3b204c0U | (encoded_dt.GetEncodingValue() << 18) |
24599               rd.Encode(22, 12) | rm.Encode(5, 0));
24600       return;
24601     }
24602   }
24603   Delegate(kVrintx, &Assembler::vrintx, dt, rd, rm);
24604 }
24605 
vrintx(Condition cond,DataType dt,SRegister rd,SRegister rm)24606 void Assembler::vrintx(Condition cond,
24607                        DataType dt,
24608                        SRegister rd,
24609                        SRegister rm) {
24610   VIXL_ASSERT(AllowAssembler());
24611   CheckIT(cond);
24612   if (IsUsingT32()) {
24613     // VRINTX{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
24614     if (dt.Is(F32)) {
24615       EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24616       AdvanceIT();
24617       return;
24618     }
24619   } else {
24620     // VRINTX{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
24621     if (dt.Is(F32) && cond.IsNotNever()) {
24622       EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24623               rm.Encode(5, 0));
24624       return;
24625     }
24626   }
24627   Delegate(kVrintx, &Assembler::vrintx, cond, dt, rd, rm);
24628 }
24629 
vrintz(Condition cond,DataType dt,DRegister rd,DRegister rm)24630 void Assembler::vrintz(Condition cond,
24631                        DataType dt,
24632                        DRegister rd,
24633                        DRegister rm) {
24634   VIXL_ASSERT(AllowAssembler());
24635   CheckIT(cond);
24636   Dt_size_16 encoded_dt(dt);
24637   if (IsUsingT32()) {
24638     // VRINTZ{<q>}.<dt> <Dd>, <Dm> ; T1
24639     if (encoded_dt.IsValid()) {
24640       EmitT32_32(0xffb20580U | (encoded_dt.GetEncodingValue() << 18) |
24641                  rd.Encode(22, 12) | rm.Encode(5, 0));
24642       AdvanceIT();
24643       return;
24644     }
24645     // VRINTZ{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
24646     if (dt.Is(F64)) {
24647       EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
24648       AdvanceIT();
24649       return;
24650     }
24651   } else {
24652     // VRINTZ{<q>}.<dt> <Dd>, <Dm> ; A1
24653     if (encoded_dt.IsValid()) {
24654       EmitA32(0xf3b20580U | (encoded_dt.GetEncodingValue() << 18) |
24655               rd.Encode(22, 12) | rm.Encode(5, 0));
24656       return;
24657     }
24658     // VRINTZ{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
24659     if (dt.Is(F64) && cond.IsNotNever()) {
24660       EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24661               rm.Encode(5, 0));
24662       return;
24663     }
24664   }
24665   Delegate(kVrintz, &Assembler::vrintz, cond, dt, rd, rm);
24666 }
24667 
vrintz(DataType dt,QRegister rd,QRegister rm)24668 void Assembler::vrintz(DataType dt, QRegister rd, QRegister rm) {
24669   VIXL_ASSERT(AllowAssembler());
24670   CheckIT(al);
24671   Dt_size_16 encoded_dt(dt);
24672   if (IsUsingT32()) {
24673     // VRINTZ{<q>}.<dt> <Qd>, <Qm> ; T1
24674     if (encoded_dt.IsValid()) {
24675       EmitT32_32(0xffb205c0U | (encoded_dt.GetEncodingValue() << 18) |
24676                  rd.Encode(22, 12) | rm.Encode(5, 0));
24677       AdvanceIT();
24678       return;
24679     }
24680   } else {
24681     // VRINTZ{<q>}.<dt> <Qd>, <Qm> ; A1
24682     if (encoded_dt.IsValid()) {
24683       EmitA32(0xf3b205c0U | (encoded_dt.GetEncodingValue() << 18) |
24684               rd.Encode(22, 12) | rm.Encode(5, 0));
24685       return;
24686     }
24687   }
24688   Delegate(kVrintz, &Assembler::vrintz, dt, rd, rm);
24689 }
24690 
vrintz(Condition cond,DataType dt,SRegister rd,SRegister rm)24691 void Assembler::vrintz(Condition cond,
24692                        DataType dt,
24693                        SRegister rd,
24694                        SRegister rm) {
24695   VIXL_ASSERT(AllowAssembler());
24696   CheckIT(cond);
24697   if (IsUsingT32()) {
24698     // VRINTZ{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
24699     if (dt.Is(F32)) {
24700       EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
24701       AdvanceIT();
24702       return;
24703     }
24704   } else {
24705     // VRINTZ{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
24706     if (dt.Is(F32) && cond.IsNotNever()) {
24707       EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24708               rm.Encode(5, 0));
24709       return;
24710     }
24711   }
24712   Delegate(kVrintz, &Assembler::vrintz, cond, dt, rd, rm);
24713 }
24714 
vrshl(Condition cond,DataType dt,DRegister rd,DRegister rm,DRegister rn)24715 void Assembler::vrshl(
24716     Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
24717   VIXL_ASSERT(AllowAssembler());
24718   CheckIT(cond);
24719   Dt_U_size_3 encoded_dt(dt);
24720   if (IsUsingT32()) {
24721     // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
24722     if (encoded_dt.IsValid()) {
24723       if (cond.Is(al) || AllowStronglyDiscouraged()) {
24724         EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24725                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24726                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24727         AdvanceIT();
24728         return;
24729       }
24730     }
24731   } else {
24732     // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
24733     if (encoded_dt.IsValid()) {
24734       if (cond.Is(al)) {
24735         EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24736                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24737                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24738         return;
24739       }
24740     }
24741   }
24742   Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
24743 }
24744 
vrshl(Condition cond,DataType dt,QRegister rd,QRegister rm,QRegister rn)24745 void Assembler::vrshl(
24746     Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
24747   VIXL_ASSERT(AllowAssembler());
24748   CheckIT(cond);
24749   Dt_U_size_3 encoded_dt(dt);
24750   if (IsUsingT32()) {
24751     // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
24752     if (encoded_dt.IsValid()) {
24753       if (cond.Is(al) || AllowStronglyDiscouraged()) {
24754         EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24755                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24756                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24757         AdvanceIT();
24758         return;
24759       }
24760     }
24761   } else {
24762     // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
24763     if (encoded_dt.IsValid()) {
24764       if (cond.Is(al)) {
24765         EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24766                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24767                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24768         return;
24769       }
24770     }
24771   }
24772   Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
24773 }
24774 
vrshr(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)24775 void Assembler::vrshr(Condition cond,
24776                       DataType dt,
24777                       DRegister rd,
24778                       DRegister rm,
24779                       const DOperand& operand) {
24780   VIXL_ASSERT(AllowAssembler());
24781   CheckIT(cond);
24782   if (operand.IsImmediate()) {
24783     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24784       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24785       Dt_L_imm6_1 encoded_dt(dt);
24786       if (IsUsingT32()) {
24787         // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
24788         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24789           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24790             uint32_t imm6 = dt.GetSize() - imm;
24791             EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) |
24792                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24793                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24794                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24795             AdvanceIT();
24796             return;
24797           }
24798         }
24799         // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
24800         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24801           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24802             EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24803                        rm.Encode(5, 0));
24804             AdvanceIT();
24805             return;
24806           }
24807         }
24808       } else {
24809         // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
24810         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24811           if (cond.Is(al)) {
24812             uint32_t imm6 = dt.GetSize() - imm;
24813             EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) |
24814                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24815                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24816                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24817             return;
24818           }
24819         }
24820         // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
24821         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24822           if (cond.Is(al)) {
24823             EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24824                     rm.Encode(5, 0));
24825             return;
24826           }
24827         }
24828       }
24829     }
24830   }
24831   Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
24832 }
24833 
vrshr(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)24834 void Assembler::vrshr(Condition cond,
24835                       DataType dt,
24836                       QRegister rd,
24837                       QRegister rm,
24838                       const QOperand& operand) {
24839   VIXL_ASSERT(AllowAssembler());
24840   CheckIT(cond);
24841   if (operand.IsImmediate()) {
24842     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24843       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24844       Dt_L_imm6_1 encoded_dt(dt);
24845       if (IsUsingT32()) {
24846         // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
24847         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24848           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24849             uint32_t imm6 = dt.GetSize() - imm;
24850             EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) |
24851                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24852                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24853                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24854             AdvanceIT();
24855             return;
24856           }
24857         }
24858         // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
24859         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24860           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24861             EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24862                        rm.Encode(5, 0));
24863             AdvanceIT();
24864             return;
24865           }
24866         }
24867       } else {
24868         // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
24869         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24870           if (cond.Is(al)) {
24871             uint32_t imm6 = dt.GetSize() - imm;
24872             EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) |
24873                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24874                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24875                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24876             return;
24877           }
24878         }
24879         // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
24880         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24881           if (cond.Is(al)) {
24882             EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24883                     rm.Encode(5, 0));
24884             return;
24885           }
24886         }
24887       }
24888     }
24889   }
24890   Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
24891 }
24892 
vrshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)24893 void Assembler::vrshrn(Condition cond,
24894                        DataType dt,
24895                        DRegister rd,
24896                        QRegister rm,
24897                        const QOperand& operand) {
24898   VIXL_ASSERT(AllowAssembler());
24899   CheckIT(cond);
24900   if (operand.IsImmediate()) {
24901     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24902       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24903       Dt_imm6_3 encoded_dt(dt);
24904       Dt_size_3 encoded_dt_2(dt);
24905       if (IsUsingT32()) {
24906         // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
24907         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
24908           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24909             uint32_t imm6 = dt.GetSize() / 2 - imm;
24910             EmitT32_32(0xef800850U |
24911                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24912                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24913             AdvanceIT();
24914             return;
24915           }
24916         }
24917         // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
24918         if (encoded_dt_2.IsValid() && (imm == 0)) {
24919           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24920             EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
24921                        rd.Encode(22, 12) | rm.Encode(5, 0));
24922             AdvanceIT();
24923             return;
24924           }
24925         }
24926       } else {
24927         // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
24928         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
24929           if (cond.Is(al)) {
24930             uint32_t imm6 = dt.GetSize() / 2 - imm;
24931             EmitA32(0xf2800850U |
24932                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24933                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24934             return;
24935           }
24936         }
24937         // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
24938         if (encoded_dt_2.IsValid() && (imm == 0)) {
24939           if (cond.Is(al)) {
24940             EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
24941                     rd.Encode(22, 12) | rm.Encode(5, 0));
24942             return;
24943           }
24944         }
24945       }
24946     }
24947   }
24948   Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand);
24949 }
24950 
vrsqrte(Condition cond,DataType dt,DRegister rd,DRegister rm)24951 void Assembler::vrsqrte(Condition cond,
24952                         DataType dt,
24953                         DRegister rd,
24954                         DRegister rm) {
24955   VIXL_ASSERT(AllowAssembler());
24956   CheckIT(cond);
24957   Dt_F_size_4 encoded_dt(dt);
24958   if (IsUsingT32()) {
24959     // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
24960     if (encoded_dt.IsValid()) {
24961       if (cond.Is(al) || AllowStronglyDiscouraged()) {
24962         EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
24963                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
24964                    rd.Encode(22, 12) | rm.Encode(5, 0));
24965         AdvanceIT();
24966         return;
24967       }
24968     }
24969   } else {
24970     // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
24971     if (encoded_dt.IsValid()) {
24972       if (cond.Is(al)) {
24973         EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
24974                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
24975                 rd.Encode(22, 12) | rm.Encode(5, 0));
24976         return;
24977       }
24978     }
24979   }
24980   Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
24981 }
24982 
vrsqrte(Condition cond,DataType dt,QRegister rd,QRegister rm)24983 void Assembler::vrsqrte(Condition cond,
24984                         DataType dt,
24985                         QRegister rd,
24986                         QRegister rm) {
24987   VIXL_ASSERT(AllowAssembler());
24988   CheckIT(cond);
24989   Dt_F_size_4 encoded_dt(dt);
24990   if (IsUsingT32()) {
24991     // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
24992     if (encoded_dt.IsValid()) {
24993       if (cond.Is(al) || AllowStronglyDiscouraged()) {
24994         EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
24995                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
24996                    rd.Encode(22, 12) | rm.Encode(5, 0));
24997         AdvanceIT();
24998         return;
24999       }
25000     }
25001   } else {
25002     // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
25003     if (encoded_dt.IsValid()) {
25004       if (cond.Is(al)) {
25005         EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
25006                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
25007                 rd.Encode(22, 12) | rm.Encode(5, 0));
25008         return;
25009       }
25010     }
25011   }
25012   Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
25013 }
25014 
vrsqrts(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)25015 void Assembler::vrsqrts(
25016     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25017   VIXL_ASSERT(AllowAssembler());
25018   CheckIT(cond);
25019   if (IsUsingT32()) {
25020     // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
25021     if (dt.Is(F32)) {
25022       if (cond.Is(al) || AllowStronglyDiscouraged()) {
25023         EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25024                    rm.Encode(5, 0));
25025         AdvanceIT();
25026         return;
25027       }
25028     }
25029   } else {
25030     // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
25031     if (dt.Is(F32)) {
25032       if (cond.Is(al)) {
25033         EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25034                 rm.Encode(5, 0));
25035         return;
25036       }
25037     }
25038   }
25039   Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
25040 }
25041 
vrsqrts(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)25042 void Assembler::vrsqrts(
25043     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
25044   VIXL_ASSERT(AllowAssembler());
25045   CheckIT(cond);
25046   if (IsUsingT32()) {
25047     // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
25048     if (dt.Is(F32)) {
25049       if (cond.Is(al) || AllowStronglyDiscouraged()) {
25050         EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25051                    rm.Encode(5, 0));
25052         AdvanceIT();
25053         return;
25054       }
25055     }
25056   } else {
25057     // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
25058     if (dt.Is(F32)) {
25059       if (cond.Is(al)) {
25060         EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25061                 rm.Encode(5, 0));
25062         return;
25063       }
25064     }
25065   }
25066   Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
25067 }
25068 
vrsra(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25069 void Assembler::vrsra(Condition cond,
25070                       DataType dt,
25071                       DRegister rd,
25072                       DRegister rm,
25073                       const DOperand& operand) {
25074   VIXL_ASSERT(AllowAssembler());
25075   CheckIT(cond);
25076   if (operand.IsImmediate()) {
25077     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25078       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25079       Dt_L_imm6_1 encoded_dt(dt);
25080       if (IsUsingT32()) {
25081         // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
25082         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25083           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25084             uint32_t imm6 = dt.GetSize() - imm;
25085             EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) |
25086                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25087                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25088                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25089             AdvanceIT();
25090             return;
25091           }
25092         }
25093       } else {
25094         // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
25095         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25096           if (cond.Is(al)) {
25097             uint32_t imm6 = dt.GetSize() - imm;
25098             EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) |
25099                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25100                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25101                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25102             return;
25103           }
25104         }
25105       }
25106     }
25107   }
25108   Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
25109 }
25110 
vrsra(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)25111 void Assembler::vrsra(Condition cond,
25112                       DataType dt,
25113                       QRegister rd,
25114                       QRegister rm,
25115                       const QOperand& operand) {
25116   VIXL_ASSERT(AllowAssembler());
25117   CheckIT(cond);
25118   if (operand.IsImmediate()) {
25119     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25120       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25121       Dt_L_imm6_1 encoded_dt(dt);
25122       if (IsUsingT32()) {
25123         // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
25124         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25125           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25126             uint32_t imm6 = dt.GetSize() - imm;
25127             EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) |
25128                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25129                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25130                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25131             AdvanceIT();
25132             return;
25133           }
25134         }
25135       } else {
25136         // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
25137         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25138           if (cond.Is(al)) {
25139             uint32_t imm6 = dt.GetSize() - imm;
25140             EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) |
25141                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25142                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25143                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25144             return;
25145           }
25146         }
25147       }
25148     }
25149   }
25150   Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
25151 }
25152 
vrsubhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)25153 void Assembler::vrsubhn(
25154     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
25155   VIXL_ASSERT(AllowAssembler());
25156   CheckIT(cond);
25157   Dt_size_3 encoded_dt(dt);
25158   if (IsUsingT32()) {
25159     // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
25160     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
25161       if (cond.Is(al) || AllowStronglyDiscouraged()) {
25162         EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) |
25163                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25164         AdvanceIT();
25165         return;
25166       }
25167     }
25168   } else {
25169     // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
25170     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
25171       if (cond.Is(al)) {
25172         EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) |
25173                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25174         return;
25175       }
25176     }
25177   }
25178   Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm);
25179 }
25180 
vseleq(DataType dt,DRegister rd,DRegister rn,DRegister rm)25181 void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25182   VIXL_ASSERT(AllowAssembler());
25183   CheckIT(al);
25184   if (IsUsingT32()) {
25185     // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1
25186     if (OutsideITBlock() && dt.Is(F64)) {
25187       EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25188                  rm.Encode(5, 0));
25189       AdvanceIT();
25190       return;
25191     }
25192   } else {
25193     // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1
25194     if (dt.Is(F64)) {
25195       EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25196               rm.Encode(5, 0));
25197       return;
25198     }
25199   }
25200   Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
25201 }
25202 
vseleq(DataType dt,SRegister rd,SRegister rn,SRegister rm)25203 void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
25204   VIXL_ASSERT(AllowAssembler());
25205   CheckIT(al);
25206   if (IsUsingT32()) {
25207     // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1
25208     if (OutsideITBlock() && dt.Is(F32)) {
25209       EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25210                  rm.Encode(5, 0));
25211       AdvanceIT();
25212       return;
25213     }
25214   } else {
25215     // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1
25216     if (dt.Is(F32)) {
25217       EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25218               rm.Encode(5, 0));
25219       return;
25220     }
25221   }
25222   Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
25223 }
25224 
vselge(DataType dt,DRegister rd,DRegister rn,DRegister rm)25225 void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25226   VIXL_ASSERT(AllowAssembler());
25227   CheckIT(al);
25228   if (IsUsingT32()) {
25229     // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1
25230     if (OutsideITBlock() && dt.Is(F64)) {
25231       EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25232                  rm.Encode(5, 0));
25233       AdvanceIT();
25234       return;
25235     }
25236   } else {
25237     // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1
25238     if (dt.Is(F64)) {
25239       EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25240               rm.Encode(5, 0));
25241       return;
25242     }
25243   }
25244   Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
25245 }
25246 
vselge(DataType dt,SRegister rd,SRegister rn,SRegister rm)25247 void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
25248   VIXL_ASSERT(AllowAssembler());
25249   CheckIT(al);
25250   if (IsUsingT32()) {
25251     // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1
25252     if (OutsideITBlock() && dt.Is(F32)) {
25253       EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25254                  rm.Encode(5, 0));
25255       AdvanceIT();
25256       return;
25257     }
25258   } else {
25259     // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1
25260     if (dt.Is(F32)) {
25261       EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25262               rm.Encode(5, 0));
25263       return;
25264     }
25265   }
25266   Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
25267 }
25268 
vselgt(DataType dt,DRegister rd,DRegister rn,DRegister rm)25269 void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25270   VIXL_ASSERT(AllowAssembler());
25271   CheckIT(al);
25272   if (IsUsingT32()) {
25273     // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1
25274     if (OutsideITBlock() && dt.Is(F64)) {
25275       EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25276                  rm.Encode(5, 0));
25277       AdvanceIT();
25278       return;
25279     }
25280   } else {
25281     // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1
25282     if (dt.Is(F64)) {
25283       EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25284               rm.Encode(5, 0));
25285       return;
25286     }
25287   }
25288   Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
25289 }
25290 
vselgt(DataType dt,SRegister rd,SRegister rn,SRegister rm)25291 void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
25292   VIXL_ASSERT(AllowAssembler());
25293   CheckIT(al);
25294   if (IsUsingT32()) {
25295     // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1
25296     if (OutsideITBlock() && dt.Is(F32)) {
25297       EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25298                  rm.Encode(5, 0));
25299       AdvanceIT();
25300       return;
25301     }
25302   } else {
25303     // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1
25304     if (dt.Is(F32)) {
25305       EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25306               rm.Encode(5, 0));
25307       return;
25308     }
25309   }
25310   Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
25311 }
25312 
vselvs(DataType dt,DRegister rd,DRegister rn,DRegister rm)25313 void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25314   VIXL_ASSERT(AllowAssembler());
25315   CheckIT(al);
25316   if (IsUsingT32()) {
25317     // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1
25318     if (OutsideITBlock() && dt.Is(F64)) {
25319       EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25320                  rm.Encode(5, 0));
25321       AdvanceIT();
25322       return;
25323     }
25324   } else {
25325     // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1
25326     if (dt.Is(F64)) {
25327       EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25328               rm.Encode(5, 0));
25329       return;
25330     }
25331   }
25332   Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
25333 }
25334 
vselvs(DataType dt,SRegister rd,SRegister rn,SRegister rm)25335 void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
25336   VIXL_ASSERT(AllowAssembler());
25337   CheckIT(al);
25338   if (IsUsingT32()) {
25339     // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1
25340     if (OutsideITBlock() && dt.Is(F32)) {
25341       EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25342                  rm.Encode(5, 0));
25343       AdvanceIT();
25344       return;
25345     }
25346   } else {
25347     // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1
25348     if (dt.Is(F32)) {
25349       EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25350               rm.Encode(5, 0));
25351       return;
25352     }
25353   }
25354   Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
25355 }
25356 
vshl(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25357 void Assembler::vshl(Condition cond,
25358                      DataType dt,
25359                      DRegister rd,
25360                      DRegister rm,
25361                      const DOperand& operand) {
25362   VIXL_ASSERT(AllowAssembler());
25363   CheckIT(cond);
25364   if (operand.IsImmediate()) {
25365     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25366       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25367       Dt_L_imm6_3 encoded_dt(dt);
25368       if (IsUsingT32()) {
25369         // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1
25370         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25371           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25372             uint32_t imm6 = imm;
25373             EmitT32_32(0xef800510U |
25374                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25375                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25376                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25377             AdvanceIT();
25378             return;
25379           }
25380         }
25381       } else {
25382         // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1
25383         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25384           if (cond.Is(al)) {
25385             uint32_t imm6 = imm;
25386             EmitA32(0xf2800510U |
25387                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25388                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25389                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25390             return;
25391           }
25392         }
25393       }
25394     }
25395   }
25396   if (operand.IsRegister()) {
25397     DRegister rn = operand.GetRegister();
25398     Dt_U_size_3 encoded_dt(dt);
25399     if (IsUsingT32()) {
25400       // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
25401       if (encoded_dt.IsValid()) {
25402         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25403           EmitT32_32(0xef000400U |
25404                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25405                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
25406                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
25407           AdvanceIT();
25408           return;
25409         }
25410       }
25411     } else {
25412       // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
25413       if (encoded_dt.IsValid()) {
25414         if (cond.Is(al)) {
25415           EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25416                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
25417                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
25418           return;
25419         }
25420       }
25421     }
25422   }
25423   Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
25424 }
25425 
vshl(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)25426 void Assembler::vshl(Condition cond,
25427                      DataType dt,
25428                      QRegister rd,
25429                      QRegister rm,
25430                      const QOperand& operand) {
25431   VIXL_ASSERT(AllowAssembler());
25432   CheckIT(cond);
25433   if (operand.IsImmediate()) {
25434     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25435       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25436       Dt_L_imm6_3 encoded_dt(dt);
25437       if (IsUsingT32()) {
25438         // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1
25439         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25440           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25441             uint32_t imm6 = imm;
25442             EmitT32_32(0xef800550U |
25443                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25444                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25445                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25446             AdvanceIT();
25447             return;
25448           }
25449         }
25450       } else {
25451         // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1
25452         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25453           if (cond.Is(al)) {
25454             uint32_t imm6 = imm;
25455             EmitA32(0xf2800550U |
25456                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25457                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25458                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25459             return;
25460           }
25461         }
25462       }
25463     }
25464   }
25465   if (operand.IsRegister()) {
25466     QRegister rn = operand.GetRegister();
25467     Dt_U_size_3 encoded_dt(dt);
25468     if (IsUsingT32()) {
25469       // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
25470       if (encoded_dt.IsValid()) {
25471         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25472           EmitT32_32(0xef000440U |
25473                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25474                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
25475                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
25476           AdvanceIT();
25477           return;
25478         }
25479       }
25480     } else {
25481       // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
25482       if (encoded_dt.IsValid()) {
25483         if (cond.Is(al)) {
25484           EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25485                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
25486                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
25487           return;
25488         }
25489       }
25490     }
25491   }
25492   Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
25493 }
25494 
vshll(Condition cond,DataType dt,QRegister rd,DRegister rm,const DOperand & operand)25495 void Assembler::vshll(Condition cond,
25496                       DataType dt,
25497                       QRegister rd,
25498                       DRegister rm,
25499                       const DOperand& operand) {
25500   VIXL_ASSERT(AllowAssembler());
25501   CheckIT(cond);
25502   if (operand.IsImmediate()) {
25503     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25504       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25505       Dt_imm6_4 encoded_dt(dt);
25506       Dt_size_17 encoded_dt_2(dt);
25507       if (IsUsingT32()) {
25508         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1
25509         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
25510           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25511             uint32_t imm6 = dt.GetSize() + imm;
25512             EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) |
25513                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25514                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25515             AdvanceIT();
25516             return;
25517           }
25518         }
25519         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2
25520         if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
25521           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25522             EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) |
25523                        rd.Encode(22, 12) | rm.Encode(5, 0));
25524             AdvanceIT();
25525             return;
25526           }
25527         }
25528       } else {
25529         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1
25530         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
25531           if (cond.Is(al)) {
25532             uint32_t imm6 = dt.GetSize() + imm;
25533             EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) |
25534                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25535                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25536             return;
25537           }
25538         }
25539         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2
25540         if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
25541           if (cond.Is(al)) {
25542             EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) |
25543                     rd.Encode(22, 12) | rm.Encode(5, 0));
25544             return;
25545           }
25546         }
25547       }
25548     }
25549   }
25550   Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand);
25551 }
25552 
vshr(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25553 void Assembler::vshr(Condition cond,
25554                      DataType dt,
25555                      DRegister rd,
25556                      DRegister rm,
25557                      const DOperand& operand) {
25558   VIXL_ASSERT(AllowAssembler());
25559   CheckIT(cond);
25560   if (operand.IsImmediate()) {
25561     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25562       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25563       Dt_L_imm6_1 encoded_dt(dt);
25564       if (IsUsingT32()) {
25565         // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
25566         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25567           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25568             uint32_t imm6 = dt.GetSize() - imm;
25569             EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) |
25570                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25571                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25572                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25573             AdvanceIT();
25574             return;
25575           }
25576         }
25577         // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
25578         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
25579           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25580             EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
25581                        rm.Encode(5, 0));
25582             AdvanceIT();
25583             return;
25584           }
25585         }
25586       } else {
25587         // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
25588         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25589           if (cond.Is(al)) {
25590             uint32_t imm6 = dt.GetSize() - imm;
25591             EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) |
25592                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25593                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25594                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25595             return;
25596           }
25597         }
25598         // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
25599         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
25600           if (cond.Is(al)) {
25601             EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
25602                     rm.Encode(5, 0));
25603             return;
25604           }
25605         }
25606       }
25607     }
25608   }
25609   Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
25610 }
25611 
vshr(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)25612 void Assembler::vshr(Condition cond,
25613                      DataType dt,
25614                      QRegister rd,
25615                      QRegister rm,
25616                      const QOperand& operand) {
25617   VIXL_ASSERT(AllowAssembler());
25618   CheckIT(cond);
25619   if (operand.IsImmediate()) {
25620     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25621       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25622       Dt_L_imm6_1 encoded_dt(dt);
25623       if (IsUsingT32()) {
25624         // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
25625         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25626           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25627             uint32_t imm6 = dt.GetSize() - imm;
25628             EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) |
25629                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25630                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25631                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25632             AdvanceIT();
25633             return;
25634           }
25635         }
25636         // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
25637         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
25638           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25639             EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
25640                        rm.Encode(5, 0));
25641             AdvanceIT();
25642             return;
25643           }
25644         }
25645       } else {
25646         // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
25647         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25648           if (cond.Is(al)) {
25649             uint32_t imm6 = dt.GetSize() - imm;
25650             EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) |
25651                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25652                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25653                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25654             return;
25655           }
25656         }
25657         // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
25658         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
25659           if (cond.Is(al)) {
25660             EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
25661                     rm.Encode(5, 0));
25662             return;
25663           }
25664         }
25665       }
25666     }
25667   }
25668   Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
25669 }
25670 
vshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)25671 void Assembler::vshrn(Condition cond,
25672                       DataType dt,
25673                       DRegister rd,
25674                       QRegister rm,
25675                       const QOperand& operand) {
25676   VIXL_ASSERT(AllowAssembler());
25677   CheckIT(cond);
25678   if (operand.IsImmediate()) {
25679     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25680       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25681       Dt_imm6_3 encoded_dt(dt);
25682       Dt_size_3 encoded_dt_2(dt);
25683       if (IsUsingT32()) {
25684         // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
25685         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
25686           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25687             uint32_t imm6 = dt.GetSize() / 2 - imm;
25688             EmitT32_32(0xef800810U |
25689                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25690                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25691             AdvanceIT();
25692             return;
25693           }
25694         }
25695         // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
25696         if (encoded_dt_2.IsValid() && (imm == 0)) {
25697           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25698             EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
25699                        rd.Encode(22, 12) | rm.Encode(5, 0));
25700             AdvanceIT();
25701             return;
25702           }
25703         }
25704       } else {
25705         // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
25706         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
25707           if (cond.Is(al)) {
25708             uint32_t imm6 = dt.GetSize() / 2 - imm;
25709             EmitA32(0xf2800810U |
25710                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25711                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25712             return;
25713           }
25714         }
25715         // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
25716         if (encoded_dt_2.IsValid() && (imm == 0)) {
25717           if (cond.Is(al)) {
25718             EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
25719                     rd.Encode(22, 12) | rm.Encode(5, 0));
25720             return;
25721           }
25722         }
25723       }
25724     }
25725   }
25726   Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand);
25727 }
25728 
vsli(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25729 void Assembler::vsli(Condition cond,
25730                      DataType dt,
25731                      DRegister rd,
25732                      DRegister rm,
25733                      const DOperand& operand) {
25734   VIXL_ASSERT(AllowAssembler());
25735   CheckIT(cond);
25736   if (operand.IsImmediate()) {
25737     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25738       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25739       Dt_L_imm6_4 encoded_dt(dt);
25740       if (IsUsingT32()) {
25741         // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
25742         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25743           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25744             uint32_t imm6 = imm;
25745             EmitT32_32(0xff800510U |
25746                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25747                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25748                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25749             AdvanceIT();
25750             return;
25751           }
25752         }
25753       } else {
25754         // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
25755         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25756           if (cond.Is(al)) {
25757             uint32_t imm6 = imm;
25758             EmitA32(0xf3800510U |
25759                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25760                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25761                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25762             return;
25763           }
25764         }
25765       }
25766     }
25767   }
25768   Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
25769 }
25770 
vsli(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)25771 void Assembler::vsli(Condition cond,
25772                      DataType dt,
25773                      QRegister rd,
25774                      QRegister rm,
25775                      const QOperand& operand) {
25776   VIXL_ASSERT(AllowAssembler());
25777   CheckIT(cond);
25778   if (operand.IsImmediate()) {
25779     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25780       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25781       Dt_L_imm6_4 encoded_dt(dt);
25782       if (IsUsingT32()) {
25783         // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
25784         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25785           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25786             uint32_t imm6 = imm;
25787             EmitT32_32(0xff800550U |
25788                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25789                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25790                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25791             AdvanceIT();
25792             return;
25793           }
25794         }
25795       } else {
25796         // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
25797         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25798           if (cond.Is(al)) {
25799             uint32_t imm6 = imm;
25800             EmitA32(0xf3800550U |
25801                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25802                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25803                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25804             return;
25805           }
25806         }
25807       }
25808     }
25809   }
25810   Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
25811 }
25812 
vsqrt(Condition cond,DataType dt,SRegister rd,SRegister rm)25813 void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) {
25814   VIXL_ASSERT(AllowAssembler());
25815   CheckIT(cond);
25816   if (IsUsingT32()) {
25817     // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
25818     if (dt.Is(F32)) {
25819       EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
25820       AdvanceIT();
25821       return;
25822     }
25823   } else {
25824     // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
25825     if (dt.Is(F32) && cond.IsNotNever()) {
25826       EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25827               rm.Encode(5, 0));
25828       return;
25829     }
25830   }
25831   Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
25832 }
25833 
vsqrt(Condition cond,DataType dt,DRegister rd,DRegister rm)25834 void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
25835   VIXL_ASSERT(AllowAssembler());
25836   CheckIT(cond);
25837   if (IsUsingT32()) {
25838     // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
25839     if (dt.Is(F64)) {
25840       EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
25841       AdvanceIT();
25842       return;
25843     }
25844   } else {
25845     // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
25846     if (dt.Is(F64) && cond.IsNotNever()) {
25847       EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25848               rm.Encode(5, 0));
25849       return;
25850     }
25851   }
25852   Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
25853 }
25854 
vsra(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25855 void Assembler::vsra(Condition cond,
25856                      DataType dt,
25857                      DRegister rd,
25858                      DRegister rm,
25859                      const DOperand& operand) {
25860   VIXL_ASSERT(AllowAssembler());
25861   CheckIT(cond);
25862   if (operand.IsImmediate()) {
25863     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25864       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25865       Dt_L_imm6_1 encoded_dt(dt);
25866       if (IsUsingT32()) {
25867         // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
25868         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25869           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25870             uint32_t imm6 = dt.GetSize() - imm;
25871             EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) |
25872                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25873                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25874                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25875             AdvanceIT();
25876             return;
25877           }
25878         }
25879       } else {
25880         // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
25881         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25882           if (cond.Is(al)) {
25883             uint32_t imm6 = dt.GetSize() - imm;
25884             EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) |
25885                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25886                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25887                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25888             return;
25889           }
25890         }
25891       }
25892     }
25893   }
25894   Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
25895 }
25896 
vsra(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)25897 void Assembler::vsra(Condition cond,
25898                      DataType dt,
25899                      QRegister rd,
25900                      QRegister rm,
25901                      const QOperand& operand) {
25902   VIXL_ASSERT(AllowAssembler());
25903   CheckIT(cond);
25904   if (operand.IsImmediate()) {
25905     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25906       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25907       Dt_L_imm6_1 encoded_dt(dt);
25908       if (IsUsingT32()) {
25909         // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
25910         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25911           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25912             uint32_t imm6 = dt.GetSize() - imm;
25913             EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) |
25914                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25915                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25916                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25917             AdvanceIT();
25918             return;
25919           }
25920         }
25921       } else {
25922         // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
25923         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25924           if (cond.Is(al)) {
25925             uint32_t imm6 = dt.GetSize() - imm;
25926             EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) |
25927                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25928                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25929                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25930             return;
25931           }
25932         }
25933       }
25934     }
25935   }
25936   Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
25937 }
25938 
vsri(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25939 void Assembler::vsri(Condition cond,
25940                      DataType dt,
25941                      DRegister rd,
25942                      DRegister rm,
25943                      const DOperand& operand) {
25944   VIXL_ASSERT(AllowAssembler());
25945   CheckIT(cond);
25946   if (operand.IsImmediate()) {
25947     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25948       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25949       Dt_L_imm6_4 encoded_dt(dt);
25950       if (IsUsingT32()) {
25951         // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
25952         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25953           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25954             uint32_t imm6 = dt.GetSize() - imm;
25955             EmitT32_32(0xff800410U |
25956                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25957                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25958                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25959             AdvanceIT();
25960             return;
25961           }
25962         }
25963       } else {
25964         // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
25965         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25966           if (cond.Is(al)) {
25967             uint32_t imm6 = dt.GetSize() - imm;
25968             EmitA32(0xf3800410U |
25969                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25970                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25971                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25972             return;
25973           }
25974         }
25975       }
25976     }
25977   }
25978   Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
25979 }
25980 
vsri(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)25981 void Assembler::vsri(Condition cond,
25982                      DataType dt,
25983                      QRegister rd,
25984                      QRegister rm,
25985                      const QOperand& operand) {
25986   VIXL_ASSERT(AllowAssembler());
25987   CheckIT(cond);
25988   if (operand.IsImmediate()) {
25989     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25990       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25991       Dt_L_imm6_4 encoded_dt(dt);
25992       if (IsUsingT32()) {
25993         // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
25994         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25995           if (cond.Is(al) || AllowStronglyDiscouraged()) {
25996             uint32_t imm6 = dt.GetSize() - imm;
25997             EmitT32_32(0xff800450U |
25998                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25999                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
26000                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
26001             AdvanceIT();
26002             return;
26003           }
26004         }
26005       } else {
26006         // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
26007         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
26008           if (cond.Is(al)) {
26009             uint32_t imm6 = dt.GetSize() - imm;
26010             EmitA32(0xf3800450U |
26011                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
26012                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
26013                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
26014             return;
26015           }
26016         }
26017       }
26018     }
26019   }
26020   Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
26021 }
26022 
vst1(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)26023 void Assembler::vst1(Condition cond,
26024                      DataType dt,
26025                      const NeonRegisterList& nreglist,
26026                      const AlignedMemOperand& operand) {
26027   VIXL_ASSERT(AllowAssembler());
26028   CheckIT(cond);
26029   if (operand.IsImmediateZero()) {
26030     Register rn = operand.GetBaseRegister();
26031     Alignment align = operand.GetAlignment();
26032     Dt_size_6 encoded_dt(dt);
26033     Dt_size_7 encoded_dt_2(dt);
26034     Align_align_5 encoded_align_1(align, nreglist);
26035     Align_index_align_1 encoded_align_2(align, nreglist, dt);
26036     if (IsUsingT32()) {
26037       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26038       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26039           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26040           operand.IsOffset() && encoded_align_1.IsValid() &&
26041           (!rn.IsPC() || AllowUnpredictable())) {
26042         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26043           const DRegister& first = nreglist.GetFirstDRegister();
26044           uint32_t len_encoding;
26045           switch (nreglist.GetLength()) {
26046             default:
26047               VIXL_UNREACHABLE_OR_FALLTHROUGH();
26048             case 1:
26049               len_encoding = 0x7;
26050               break;
26051             case 2:
26052               len_encoding = 0xa;
26053               break;
26054             case 3:
26055               len_encoding = 0x6;
26056               break;
26057             case 4:
26058               len_encoding = 0x2;
26059               break;
26060           }
26061           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
26062                      (encoded_align_1.GetEncodingValue() << 4) |
26063                      first.Encode(22, 12) | (len_encoding << 8) |
26064                      (rn.GetCode() << 16));
26065           AdvanceIT();
26066           return;
26067         }
26068       }
26069       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26070       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26071           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26072           operand.IsPostIndex() && encoded_align_1.IsValid() &&
26073           (!rn.IsPC() || AllowUnpredictable())) {
26074         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26075           const DRegister& first = nreglist.GetFirstDRegister();
26076           uint32_t len_encoding;
26077           switch (nreglist.GetLength()) {
26078             default:
26079               VIXL_UNREACHABLE_OR_FALLTHROUGH();
26080             case 1:
26081               len_encoding = 0x7;
26082               break;
26083             case 2:
26084               len_encoding = 0xa;
26085               break;
26086             case 3:
26087               len_encoding = 0x6;
26088               break;
26089             case 4:
26090               len_encoding = 0x2;
26091               break;
26092           }
26093           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
26094                      (encoded_align_1.GetEncodingValue() << 4) |
26095                      first.Encode(22, 12) | (len_encoding << 8) |
26096                      (rn.GetCode() << 16));
26097           AdvanceIT();
26098           return;
26099         }
26100       }
26101       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26102       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26103           (nreglist.GetLength() == 1) && operand.IsOffset() &&
26104           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
26105         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26106           const DRegister& first = nreglist.GetFirstDRegister();
26107           EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) |
26108                      (encoded_align_2.GetEncodingValue() << 4) |
26109                      first.Encode(22, 12) | (rn.GetCode() << 16));
26110           AdvanceIT();
26111           return;
26112         }
26113       }
26114       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26115       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26116           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
26117           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
26118         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26119           const DRegister& first = nreglist.GetFirstDRegister();
26120           EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) |
26121                      (encoded_align_2.GetEncodingValue() << 4) |
26122                      first.Encode(22, 12) | (rn.GetCode() << 16));
26123           AdvanceIT();
26124           return;
26125         }
26126       }
26127     } else {
26128       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26129       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26130           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26131           operand.IsOffset() && encoded_align_1.IsValid() &&
26132           (!rn.IsPC() || AllowUnpredictable())) {
26133         if (cond.Is(al)) {
26134           const DRegister& first = nreglist.GetFirstDRegister();
26135           uint32_t len_encoding;
26136           switch (nreglist.GetLength()) {
26137             default:
26138               VIXL_UNREACHABLE_OR_FALLTHROUGH();
26139             case 1:
26140               len_encoding = 0x7;
26141               break;
26142             case 2:
26143               len_encoding = 0xa;
26144               break;
26145             case 3:
26146               len_encoding = 0x6;
26147               break;
26148             case 4:
26149               len_encoding = 0x2;
26150               break;
26151           }
26152           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
26153                   (encoded_align_1.GetEncodingValue() << 4) |
26154                   first.Encode(22, 12) | (len_encoding << 8) |
26155                   (rn.GetCode() << 16));
26156           return;
26157         }
26158       }
26159       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26160       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26161           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26162           operand.IsPostIndex() && encoded_align_1.IsValid() &&
26163           (!rn.IsPC() || AllowUnpredictable())) {
26164         if (cond.Is(al)) {
26165           const DRegister& first = nreglist.GetFirstDRegister();
26166           uint32_t len_encoding;
26167           switch (nreglist.GetLength()) {
26168             default:
26169               VIXL_UNREACHABLE_OR_FALLTHROUGH();
26170             case 1:
26171               len_encoding = 0x7;
26172               break;
26173             case 2:
26174               len_encoding = 0xa;
26175               break;
26176             case 3:
26177               len_encoding = 0x6;
26178               break;
26179             case 4:
26180               len_encoding = 0x2;
26181               break;
26182           }
26183           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
26184                   (encoded_align_1.GetEncodingValue() << 4) |
26185                   first.Encode(22, 12) | (len_encoding << 8) |
26186                   (rn.GetCode() << 16));
26187           return;
26188         }
26189       }
26190       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26191       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26192           (nreglist.GetLength() == 1) && operand.IsOffset() &&
26193           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
26194         if (cond.Is(al)) {
26195           const DRegister& first = nreglist.GetFirstDRegister();
26196           EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) |
26197                   (encoded_align_2.GetEncodingValue() << 4) |
26198                   first.Encode(22, 12) | (rn.GetCode() << 16));
26199           return;
26200         }
26201       }
26202       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26203       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26204           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
26205           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
26206         if (cond.Is(al)) {
26207           const DRegister& first = nreglist.GetFirstDRegister();
26208           EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) |
26209                   (encoded_align_2.GetEncodingValue() << 4) |
26210                   first.Encode(22, 12) | (rn.GetCode() << 16));
26211           return;
26212         }
26213       }
26214     }
26215   }
26216   if (operand.IsPlainRegister()) {
26217     Register rn = operand.GetBaseRegister();
26218     Alignment align = operand.GetAlignment();
26219     Register rm = operand.GetOffsetRegister();
26220     Dt_size_6 encoded_dt(dt);
26221     Dt_size_7 encoded_dt_2(dt);
26222     Align_align_5 encoded_align_1(align, nreglist);
26223     Align_index_align_1 encoded_align_2(align, nreglist, dt);
26224     if (IsUsingT32()) {
26225       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26226       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26227           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26228           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26229         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26230           const DRegister& first = nreglist.GetFirstDRegister();
26231           uint32_t len_encoding;
26232           switch (nreglist.GetLength()) {
26233             default:
26234               VIXL_UNREACHABLE_OR_FALLTHROUGH();
26235             case 1:
26236               len_encoding = 0x7;
26237               break;
26238             case 2:
26239               len_encoding = 0xa;
26240               break;
26241             case 3:
26242               len_encoding = 0x6;
26243               break;
26244             case 4:
26245               len_encoding = 0x2;
26246               break;
26247           }
26248           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
26249                      (encoded_align_1.GetEncodingValue() << 4) |
26250                      first.Encode(22, 12) | (len_encoding << 8) |
26251                      (rn.GetCode() << 16) | rm.GetCode());
26252           AdvanceIT();
26253           return;
26254         }
26255       }
26256       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26257       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26258           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
26259           (!rn.IsPC() || AllowUnpredictable())) {
26260         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26261           const DRegister& first = nreglist.GetFirstDRegister();
26262           EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) |
26263                      (encoded_align_2.GetEncodingValue() << 4) |
26264                      first.Encode(22, 12) | (rn.GetCode() << 16) |
26265                      rm.GetCode());
26266           AdvanceIT();
26267           return;
26268         }
26269       }
26270     } else {
26271       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
26272       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26273           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26274           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26275         if (cond.Is(al)) {
26276           const DRegister& first = nreglist.GetFirstDRegister();
26277           uint32_t len_encoding;
26278           switch (nreglist.GetLength()) {
26279             default:
26280               VIXL_UNREACHABLE_OR_FALLTHROUGH();
26281             case 1:
26282               len_encoding = 0x7;
26283               break;
26284             case 2:
26285               len_encoding = 0xa;
26286               break;
26287             case 3:
26288               len_encoding = 0x6;
26289               break;
26290             case 4:
26291               len_encoding = 0x2;
26292               break;
26293           }
26294           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
26295                   (encoded_align_1.GetEncodingValue() << 4) |
26296                   first.Encode(22, 12) | (len_encoding << 8) |
26297                   (rn.GetCode() << 16) | rm.GetCode());
26298           return;
26299         }
26300       }
26301       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
26302       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26303           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
26304           (!rn.IsPC() || AllowUnpredictable())) {
26305         if (cond.Is(al)) {
26306           const DRegister& first = nreglist.GetFirstDRegister();
26307           EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) |
26308                   (encoded_align_2.GetEncodingValue() << 4) |
26309                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
26310           return;
26311         }
26312       }
26313     }
26314   }
26315   Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand);
26316 }
26317 
vst2(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)26318 void Assembler::vst2(Condition cond,
26319                      DataType dt,
26320                      const NeonRegisterList& nreglist,
26321                      const AlignedMemOperand& operand) {
26322   VIXL_ASSERT(AllowAssembler());
26323   CheckIT(cond);
26324   if (operand.IsImmediateZero()) {
26325     Register rn = operand.GetBaseRegister();
26326     Alignment align = operand.GetAlignment();
26327     Dt_size_7 encoded_dt(dt);
26328     Align_align_2 encoded_align_1(align, nreglist);
26329     Align_index_align_2 encoded_align_2(align, nreglist, dt);
26330     if (IsUsingT32()) {
26331       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26332       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26333           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26334            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26335            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26336           operand.IsOffset() && encoded_align_1.IsValid() &&
26337           (!rn.IsPC() || AllowUnpredictable())) {
26338         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26339           const DRegister& first = nreglist.GetFirstDRegister();
26340           uint32_t len_encoding;
26341           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26342             len_encoding = 0x8;
26343           }
26344           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26345             len_encoding = 0x9;
26346           }
26347           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26348             len_encoding = 0x3;
26349           }
26350           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
26351                      (encoded_align_1.GetEncodingValue() << 4) |
26352                      first.Encode(22, 12) | (len_encoding << 8) |
26353                      (rn.GetCode() << 16));
26354           AdvanceIT();
26355           return;
26356         }
26357       }
26358       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26359       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26360           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26361            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26362            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26363           operand.IsPostIndex() && encoded_align_1.IsValid() &&
26364           (!rn.IsPC() || AllowUnpredictable())) {
26365         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26366           const DRegister& first = nreglist.GetFirstDRegister();
26367           uint32_t len_encoding;
26368           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26369             len_encoding = 0x8;
26370           }
26371           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26372             len_encoding = 0x9;
26373           }
26374           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26375             len_encoding = 0x3;
26376           }
26377           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
26378                      (encoded_align_1.GetEncodingValue() << 4) |
26379                      first.Encode(22, 12) | (len_encoding << 8) |
26380                      (rn.GetCode() << 16));
26381           AdvanceIT();
26382           return;
26383         }
26384       }
26385       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26386       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26387           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26388            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26389           operand.IsOffset() && encoded_align_2.IsValid() &&
26390           (!rn.IsPC() || AllowUnpredictable())) {
26391         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26392           const DRegister& first = nreglist.GetFirstDRegister();
26393           EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) |
26394                      (encoded_align_2.GetEncodingValue() << 4) |
26395                      first.Encode(22, 12) | (rn.GetCode() << 16));
26396           AdvanceIT();
26397           return;
26398         }
26399       }
26400       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26401       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26402           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26403            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26404           operand.IsPostIndex() && encoded_align_2.IsValid() &&
26405           (!rn.IsPC() || AllowUnpredictable())) {
26406         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26407           const DRegister& first = nreglist.GetFirstDRegister();
26408           EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) |
26409                      (encoded_align_2.GetEncodingValue() << 4) |
26410                      first.Encode(22, 12) | (rn.GetCode() << 16));
26411           AdvanceIT();
26412           return;
26413         }
26414       }
26415     } else {
26416       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26417       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26418           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26419            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26420            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26421           operand.IsOffset() && encoded_align_1.IsValid() &&
26422           (!rn.IsPC() || AllowUnpredictable())) {
26423         if (cond.Is(al)) {
26424           const DRegister& first = nreglist.GetFirstDRegister();
26425           uint32_t len_encoding;
26426           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26427             len_encoding = 0x8;
26428           }
26429           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26430             len_encoding = 0x9;
26431           }
26432           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26433             len_encoding = 0x3;
26434           }
26435           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
26436                   (encoded_align_1.GetEncodingValue() << 4) |
26437                   first.Encode(22, 12) | (len_encoding << 8) |
26438                   (rn.GetCode() << 16));
26439           return;
26440         }
26441       }
26442       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26443       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26444           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26445            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26446            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26447           operand.IsPostIndex() && encoded_align_1.IsValid() &&
26448           (!rn.IsPC() || AllowUnpredictable())) {
26449         if (cond.Is(al)) {
26450           const DRegister& first = nreglist.GetFirstDRegister();
26451           uint32_t len_encoding;
26452           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26453             len_encoding = 0x8;
26454           }
26455           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26456             len_encoding = 0x9;
26457           }
26458           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26459             len_encoding = 0x3;
26460           }
26461           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
26462                   (encoded_align_1.GetEncodingValue() << 4) |
26463                   first.Encode(22, 12) | (len_encoding << 8) |
26464                   (rn.GetCode() << 16));
26465           return;
26466         }
26467       }
26468       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26469       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26470           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26471            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26472           operand.IsOffset() && encoded_align_2.IsValid() &&
26473           (!rn.IsPC() || AllowUnpredictable())) {
26474         if (cond.Is(al)) {
26475           const DRegister& first = nreglist.GetFirstDRegister();
26476           EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) |
26477                   (encoded_align_2.GetEncodingValue() << 4) |
26478                   first.Encode(22, 12) | (rn.GetCode() << 16));
26479           return;
26480         }
26481       }
26482       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26483       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26484           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26485            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26486           operand.IsPostIndex() && encoded_align_2.IsValid() &&
26487           (!rn.IsPC() || AllowUnpredictable())) {
26488         if (cond.Is(al)) {
26489           const DRegister& first = nreglist.GetFirstDRegister();
26490           EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) |
26491                   (encoded_align_2.GetEncodingValue() << 4) |
26492                   first.Encode(22, 12) | (rn.GetCode() << 16));
26493           return;
26494         }
26495       }
26496     }
26497   }
26498   if (operand.IsPlainRegister()) {
26499     Register rn = operand.GetBaseRegister();
26500     Alignment align = operand.GetAlignment();
26501     Register rm = operand.GetOffsetRegister();
26502     Dt_size_7 encoded_dt(dt);
26503     Align_align_2 encoded_align_1(align, nreglist);
26504     Align_index_align_2 encoded_align_2(align, nreglist, dt);
26505     if (IsUsingT32()) {
26506       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26507       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26508           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26509            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26510            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26511           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26512         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26513           const DRegister& first = nreglist.GetFirstDRegister();
26514           uint32_t len_encoding;
26515           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26516             len_encoding = 0x8;
26517           }
26518           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26519             len_encoding = 0x9;
26520           }
26521           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26522             len_encoding = 0x3;
26523           }
26524           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
26525                      (encoded_align_1.GetEncodingValue() << 4) |
26526                      first.Encode(22, 12) | (len_encoding << 8) |
26527                      (rn.GetCode() << 16) | rm.GetCode());
26528           AdvanceIT();
26529           return;
26530         }
26531       }
26532       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26533       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26534           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26535            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26536           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26537         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26538           const DRegister& first = nreglist.GetFirstDRegister();
26539           EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) |
26540                      (encoded_align_2.GetEncodingValue() << 4) |
26541                      first.Encode(22, 12) | (rn.GetCode() << 16) |
26542                      rm.GetCode());
26543           AdvanceIT();
26544           return;
26545         }
26546       }
26547     } else {
26548       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
26549       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26550           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26551            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26552            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26553           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26554         if (cond.Is(al)) {
26555           const DRegister& first = nreglist.GetFirstDRegister();
26556           uint32_t len_encoding;
26557           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26558             len_encoding = 0x8;
26559           }
26560           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26561             len_encoding = 0x9;
26562           }
26563           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26564             len_encoding = 0x3;
26565           }
26566           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
26567                   (encoded_align_1.GetEncodingValue() << 4) |
26568                   first.Encode(22, 12) | (len_encoding << 8) |
26569                   (rn.GetCode() << 16) | rm.GetCode());
26570           return;
26571         }
26572       }
26573       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
26574       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26575           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26576            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26577           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26578         if (cond.Is(al)) {
26579           const DRegister& first = nreglist.GetFirstDRegister();
26580           EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) |
26581                   (encoded_align_2.GetEncodingValue() << 4) |
26582                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
26583           return;
26584         }
26585       }
26586     }
26587   }
26588   Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand);
26589 }
26590 
vst3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)26591 void Assembler::vst3(Condition cond,
26592                      DataType dt,
26593                      const NeonRegisterList& nreglist,
26594                      const AlignedMemOperand& operand) {
26595   VIXL_ASSERT(AllowAssembler());
26596   CheckIT(cond);
26597   if (operand.IsImmediateZero()) {
26598     Register rn = operand.GetBaseRegister();
26599     Alignment align = operand.GetAlignment();
26600     Dt_size_7 encoded_dt(dt);
26601     Align_align_3 encoded_align_1(align);
26602     if (IsUsingT32()) {
26603       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26604       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26605           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26606            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26607           operand.IsOffset() && encoded_align_1.IsValid() &&
26608           (!rn.IsPC() || AllowUnpredictable())) {
26609         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26610           const DRegister& first = nreglist.GetFirstDRegister();
26611           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26612           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
26613                      (encoded_align_1.GetEncodingValue() << 4) |
26614                      first.Encode(22, 12) | (len_encoding << 8) |
26615                      (rn.GetCode() << 16));
26616           AdvanceIT();
26617           return;
26618         }
26619       }
26620       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26621       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26622           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26623            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26624           operand.IsPostIndex() && encoded_align_1.IsValid() &&
26625           (!rn.IsPC() || AllowUnpredictable())) {
26626         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26627           const DRegister& first = nreglist.GetFirstDRegister();
26628           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26629           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
26630                      (encoded_align_1.GetEncodingValue() << 4) |
26631                      first.Encode(22, 12) | (len_encoding << 8) |
26632                      (rn.GetCode() << 16));
26633           AdvanceIT();
26634           return;
26635         }
26636       }
26637     } else {
26638       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26639       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26640           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26641            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26642           operand.IsOffset() && encoded_align_1.IsValid() &&
26643           (!rn.IsPC() || AllowUnpredictable())) {
26644         if (cond.Is(al)) {
26645           const DRegister& first = nreglist.GetFirstDRegister();
26646           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26647           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
26648                   (encoded_align_1.GetEncodingValue() << 4) |
26649                   first.Encode(22, 12) | (len_encoding << 8) |
26650                   (rn.GetCode() << 16));
26651           return;
26652         }
26653       }
26654       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26655       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26656           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26657            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26658           operand.IsPostIndex() && encoded_align_1.IsValid() &&
26659           (!rn.IsPC() || AllowUnpredictable())) {
26660         if (cond.Is(al)) {
26661           const DRegister& first = nreglist.GetFirstDRegister();
26662           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26663           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
26664                   (encoded_align_1.GetEncodingValue() << 4) |
26665                   first.Encode(22, 12) | (len_encoding << 8) |
26666                   (rn.GetCode() << 16));
26667           return;
26668         }
26669       }
26670     }
26671   }
26672   if (operand.IsPlainRegister()) {
26673     Register rn = operand.GetBaseRegister();
26674     Alignment align = operand.GetAlignment();
26675     Register rm = operand.GetOffsetRegister();
26676     Dt_size_7 encoded_dt(dt);
26677     Align_align_3 encoded_align_1(align);
26678     if (IsUsingT32()) {
26679       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26680       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26681           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26682            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26683           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26684         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26685           const DRegister& first = nreglist.GetFirstDRegister();
26686           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26687           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
26688                      (encoded_align_1.GetEncodingValue() << 4) |
26689                      first.Encode(22, 12) | (len_encoding << 8) |
26690                      (rn.GetCode() << 16) | rm.GetCode());
26691           AdvanceIT();
26692           return;
26693         }
26694       }
26695     } else {
26696       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
26697       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26698           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26699            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26700           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26701         if (cond.Is(al)) {
26702           const DRegister& first = nreglist.GetFirstDRegister();
26703           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26704           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
26705                   (encoded_align_1.GetEncodingValue() << 4) |
26706                   first.Encode(22, 12) | (len_encoding << 8) |
26707                   (rn.GetCode() << 16) | rm.GetCode());
26708           return;
26709         }
26710       }
26711     }
26712   }
26713   Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
26714 }
26715 
vst3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const MemOperand & operand)26716 void Assembler::vst3(Condition cond,
26717                      DataType dt,
26718                      const NeonRegisterList& nreglist,
26719                      const MemOperand& operand) {
26720   VIXL_ASSERT(AllowAssembler());
26721   CheckIT(cond);
26722   if (operand.IsImmediateZero()) {
26723     Register rn = operand.GetBaseRegister();
26724     Dt_size_7 encoded_dt(dt);
26725     Index_1 encoded_align_1(nreglist, dt);
26726     if (IsUsingT32()) {
26727       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
26728       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26729           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26730            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26731           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
26732         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26733           const DRegister& first = nreglist.GetFirstDRegister();
26734           EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) |
26735                      (encoded_align_1.GetEncodingValue() << 4) |
26736                      first.Encode(22, 12) | (rn.GetCode() << 16));
26737           AdvanceIT();
26738           return;
26739         }
26740       }
26741       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
26742       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26743           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26744            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26745           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
26746         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26747           const DRegister& first = nreglist.GetFirstDRegister();
26748           EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) |
26749                      (encoded_align_1.GetEncodingValue() << 4) |
26750                      first.Encode(22, 12) | (rn.GetCode() << 16));
26751           AdvanceIT();
26752           return;
26753         }
26754       }
26755     } else {
26756       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
26757       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26758           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26759            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26760           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
26761         if (cond.Is(al)) {
26762           const DRegister& first = nreglist.GetFirstDRegister();
26763           EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) |
26764                   (encoded_align_1.GetEncodingValue() << 4) |
26765                   first.Encode(22, 12) | (rn.GetCode() << 16));
26766           return;
26767         }
26768       }
26769       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
26770       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26771           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26772            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26773           operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
26774         if (cond.Is(al)) {
26775           const DRegister& first = nreglist.GetFirstDRegister();
26776           EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) |
26777                   (encoded_align_1.GetEncodingValue() << 4) |
26778                   first.Encode(22, 12) | (rn.GetCode() << 16));
26779           return;
26780         }
26781       }
26782     }
26783   }
26784   if (operand.IsPlainRegister()) {
26785     Register rn = operand.GetBaseRegister();
26786     Sign sign = operand.GetSign();
26787     Register rm = operand.GetOffsetRegister();
26788     Dt_size_7 encoded_dt(dt);
26789     Index_1 encoded_align_1(nreglist, dt);
26790     if (IsUsingT32()) {
26791       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
26792       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26793           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26794            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26795           sign.IsPlus() && operand.IsPostIndex() &&
26796           (!rn.IsPC() || AllowUnpredictable())) {
26797         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26798           const DRegister& first = nreglist.GetFirstDRegister();
26799           EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) |
26800                      (encoded_align_1.GetEncodingValue() << 4) |
26801                      first.Encode(22, 12) | (rn.GetCode() << 16) |
26802                      rm.GetCode());
26803           AdvanceIT();
26804           return;
26805         }
26806       }
26807     } else {
26808       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
26809       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26810           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26811            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26812           sign.IsPlus() && operand.IsPostIndex() &&
26813           (!rn.IsPC() || AllowUnpredictable())) {
26814         if (cond.Is(al)) {
26815           const DRegister& first = nreglist.GetFirstDRegister();
26816           EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) |
26817                   (encoded_align_1.GetEncodingValue() << 4) |
26818                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
26819           return;
26820         }
26821       }
26822     }
26823   }
26824   Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
26825 }
26826 
vst4(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)26827 void Assembler::vst4(Condition cond,
26828                      DataType dt,
26829                      const NeonRegisterList& nreglist,
26830                      const AlignedMemOperand& operand) {
26831   VIXL_ASSERT(AllowAssembler());
26832   CheckIT(cond);
26833   if (operand.IsImmediateZero()) {
26834     Register rn = operand.GetBaseRegister();
26835     Alignment align = operand.GetAlignment();
26836     Dt_size_7 encoded_dt(dt);
26837     Align_align_4 encoded_align_1(align);
26838     Align_index_align_3 encoded_align_2(align, nreglist, dt);
26839     if (IsUsingT32()) {
26840       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26841       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26842           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26843            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26844           operand.IsOffset() && encoded_align_1.IsValid() &&
26845           (!rn.IsPC() || AllowUnpredictable())) {
26846         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26847           const DRegister& first = nreglist.GetFirstDRegister();
26848           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
26849           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
26850                      (encoded_align_1.GetEncodingValue() << 4) |
26851                      first.Encode(22, 12) | (len_encoding << 8) |
26852                      (rn.GetCode() << 16));
26853           AdvanceIT();
26854           return;
26855         }
26856       }
26857       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26858       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26859           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26860            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26861           operand.IsPostIndex() && encoded_align_1.IsValid() &&
26862           (!rn.IsPC() || AllowUnpredictable())) {
26863         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26864           const DRegister& first = nreglist.GetFirstDRegister();
26865           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
26866           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
26867                      (encoded_align_1.GetEncodingValue() << 4) |
26868                      first.Encode(22, 12) | (len_encoding << 8) |
26869                      (rn.GetCode() << 16));
26870           AdvanceIT();
26871           return;
26872         }
26873       }
26874       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26875       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26876           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26877            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26878           operand.IsOffset() && encoded_align_2.IsValid() &&
26879           (!rn.IsPC() || AllowUnpredictable())) {
26880         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26881           const DRegister& first = nreglist.GetFirstDRegister();
26882           EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) |
26883                      (encoded_align_2.GetEncodingValue() << 4) |
26884                      first.Encode(22, 12) | (rn.GetCode() << 16));
26885           AdvanceIT();
26886           return;
26887         }
26888       }
26889       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26890       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26891           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26892            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26893           operand.IsPostIndex() && encoded_align_2.IsValid() &&
26894           (!rn.IsPC() || AllowUnpredictable())) {
26895         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26896           const DRegister& first = nreglist.GetFirstDRegister();
26897           EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) |
26898                      (encoded_align_2.GetEncodingValue() << 4) |
26899                      first.Encode(22, 12) | (rn.GetCode() << 16));
26900           AdvanceIT();
26901           return;
26902         }
26903       }
26904     } else {
26905       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26906       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26907           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26908            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26909           operand.IsOffset() && encoded_align_1.IsValid() &&
26910           (!rn.IsPC() || AllowUnpredictable())) {
26911         if (cond.Is(al)) {
26912           const DRegister& first = nreglist.GetFirstDRegister();
26913           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
26914           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
26915                   (encoded_align_1.GetEncodingValue() << 4) |
26916                   first.Encode(22, 12) | (len_encoding << 8) |
26917                   (rn.GetCode() << 16));
26918           return;
26919         }
26920       }
26921       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26922       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26923           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26924            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26925           operand.IsPostIndex() && encoded_align_1.IsValid() &&
26926           (!rn.IsPC() || AllowUnpredictable())) {
26927         if (cond.Is(al)) {
26928           const DRegister& first = nreglist.GetFirstDRegister();
26929           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
26930           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
26931                   (encoded_align_1.GetEncodingValue() << 4) |
26932                   first.Encode(22, 12) | (len_encoding << 8) |
26933                   (rn.GetCode() << 16));
26934           return;
26935         }
26936       }
26937       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26938       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26939           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26940            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26941           operand.IsOffset() && encoded_align_2.IsValid() &&
26942           (!rn.IsPC() || AllowUnpredictable())) {
26943         if (cond.Is(al)) {
26944           const DRegister& first = nreglist.GetFirstDRegister();
26945           EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) |
26946                   (encoded_align_2.GetEncodingValue() << 4) |
26947                   first.Encode(22, 12) | (rn.GetCode() << 16));
26948           return;
26949         }
26950       }
26951       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26952       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26953           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26954            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26955           operand.IsPostIndex() && encoded_align_2.IsValid() &&
26956           (!rn.IsPC() || AllowUnpredictable())) {
26957         if (cond.Is(al)) {
26958           const DRegister& first = nreglist.GetFirstDRegister();
26959           EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) |
26960                   (encoded_align_2.GetEncodingValue() << 4) |
26961                   first.Encode(22, 12) | (rn.GetCode() << 16));
26962           return;
26963         }
26964       }
26965     }
26966   }
26967   if (operand.IsPlainRegister()) {
26968     Register rn = operand.GetBaseRegister();
26969     Alignment align = operand.GetAlignment();
26970     Register rm = operand.GetOffsetRegister();
26971     Dt_size_7 encoded_dt(dt);
26972     Align_align_4 encoded_align_1(align);
26973     Align_index_align_3 encoded_align_2(align, nreglist, dt);
26974     if (IsUsingT32()) {
26975       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26976       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26977           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26978            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26979           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26980         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26981           const DRegister& first = nreglist.GetFirstDRegister();
26982           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
26983           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
26984                      (encoded_align_1.GetEncodingValue() << 4) |
26985                      first.Encode(22, 12) | (len_encoding << 8) |
26986                      (rn.GetCode() << 16) | rm.GetCode());
26987           AdvanceIT();
26988           return;
26989         }
26990       }
26991       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26992       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26993           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26994            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26995           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26996         if (cond.Is(al) || AllowStronglyDiscouraged()) {
26997           const DRegister& first = nreglist.GetFirstDRegister();
26998           EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) |
26999                      (encoded_align_2.GetEncodingValue() << 4) |
27000                      first.Encode(22, 12) | (rn.GetCode() << 16) |
27001                      rm.GetCode());
27002           AdvanceIT();
27003           return;
27004         }
27005       }
27006     } else {
27007       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
27008       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
27009           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
27010            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
27011           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
27012         if (cond.Is(al)) {
27013           const DRegister& first = nreglist.GetFirstDRegister();
27014           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
27015           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
27016                   (encoded_align_1.GetEncodingValue() << 4) |
27017                   first.Encode(22, 12) | (len_encoding << 8) |
27018                   (rn.GetCode() << 16) | rm.GetCode());
27019           return;
27020         }
27021       }
27022       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
27023       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
27024           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
27025            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
27026           !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
27027         if (cond.Is(al)) {
27028           const DRegister& first = nreglist.GetFirstDRegister();
27029           EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) |
27030                   (encoded_align_2.GetEncodingValue() << 4) |
27031                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
27032           return;
27033         }
27034       }
27035     }
27036   }
27037   Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand);
27038 }
27039 
vstm(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)27040 void Assembler::vstm(Condition cond,
27041                      DataType dt,
27042                      Register rn,
27043                      WriteBack write_back,
27044                      DRegisterList dreglist) {
27045   VIXL_ASSERT(AllowAssembler());
27046   CheckIT(cond);
27047   USE(dt);
27048   if (IsUsingT32()) {
27049     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
27050     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
27051          AllowUnpredictable())) {
27052       const DRegister& dreg = dreglist.GetFirstDRegister();
27053       unsigned len = dreglist.GetLength() * 2;
27054       EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
27055                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
27056                  (len & 0xff));
27057       AdvanceIT();
27058       return;
27059     }
27060   } else {
27061     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
27062     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
27063                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
27064                               AllowUnpredictable())) {
27065       const DRegister& dreg = dreglist.GetFirstDRegister();
27066       unsigned len = dreglist.GetLength() * 2;
27067       EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27068               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
27069               (len & 0xff));
27070       return;
27071     }
27072   }
27073   Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist);
27074 }
27075 
vstm(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)27076 void Assembler::vstm(Condition cond,
27077                      DataType dt,
27078                      Register rn,
27079                      WriteBack write_back,
27080                      SRegisterList sreglist) {
27081   VIXL_ASSERT(AllowAssembler());
27082   CheckIT(cond);
27083   USE(dt);
27084   if (IsUsingT32()) {
27085     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
27086     if ((!rn.IsPC() || AllowUnpredictable())) {
27087       const SRegister& sreg = sreglist.GetFirstSRegister();
27088       unsigned len = sreglist.GetLength();
27089       EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
27090                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
27091                  (len & 0xff));
27092       AdvanceIT();
27093       return;
27094     }
27095   } else {
27096     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
27097     if (cond.IsNotNever() &&
27098         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
27099       const SRegister& sreg = sreglist.GetFirstSRegister();
27100       unsigned len = sreglist.GetLength();
27101       EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27102               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
27103               (len & 0xff));
27104       return;
27105     }
27106   }
27107   Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist);
27108 }
27109 
vstmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)27110 void Assembler::vstmdb(Condition cond,
27111                        DataType dt,
27112                        Register rn,
27113                        WriteBack write_back,
27114                        DRegisterList dreglist) {
27115   VIXL_ASSERT(AllowAssembler());
27116   CheckIT(cond);
27117   USE(dt);
27118   if (IsUsingT32()) {
27119     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
27120     if (write_back.DoesWriteBack() &&
27121         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
27122          AllowUnpredictable())) {
27123       const DRegister& dreg = dreglist.GetFirstDRegister();
27124       unsigned len = dreglist.GetLength() * 2;
27125       EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
27126                  (len & 0xff));
27127       AdvanceIT();
27128       return;
27129     }
27130   } else {
27131     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
27132     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
27133         (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
27134          AllowUnpredictable())) {
27135       const DRegister& dreg = dreglist.GetFirstDRegister();
27136       unsigned len = dreglist.GetLength() * 2;
27137       EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27138               dreg.Encode(22, 12) | (len & 0xff));
27139       return;
27140     }
27141   }
27142   Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist);
27143 }
27144 
vstmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)27145 void Assembler::vstmdb(Condition cond,
27146                        DataType dt,
27147                        Register rn,
27148                        WriteBack write_back,
27149                        SRegisterList sreglist) {
27150   VIXL_ASSERT(AllowAssembler());
27151   CheckIT(cond);
27152   USE(dt);
27153   if (IsUsingT32()) {
27154     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
27155     if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) {
27156       const SRegister& sreg = sreglist.GetFirstSRegister();
27157       unsigned len = sreglist.GetLength();
27158       EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
27159                  (len & 0xff));
27160       AdvanceIT();
27161       return;
27162     }
27163   } else {
27164     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
27165     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
27166         (!rn.IsPC() || AllowUnpredictable())) {
27167       const SRegister& sreg = sreglist.GetFirstSRegister();
27168       unsigned len = sreglist.GetLength();
27169       EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27170               sreg.Encode(22, 12) | (len & 0xff));
27171       return;
27172     }
27173   }
27174   Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist);
27175 }
27176 
vstmia(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)27177 void Assembler::vstmia(Condition cond,
27178                        DataType dt,
27179                        Register rn,
27180                        WriteBack write_back,
27181                        DRegisterList dreglist) {
27182   VIXL_ASSERT(AllowAssembler());
27183   CheckIT(cond);
27184   USE(dt);
27185   if (IsUsingT32()) {
27186     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
27187     if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
27188          AllowUnpredictable())) {
27189       const DRegister& dreg = dreglist.GetFirstDRegister();
27190       unsigned len = dreglist.GetLength() * 2;
27191       EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
27192                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
27193                  (len & 0xff));
27194       AdvanceIT();
27195       return;
27196     }
27197   } else {
27198     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
27199     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
27200                                (!rn.IsPC() || !write_back.DoesWriteBack())) ||
27201                               AllowUnpredictable())) {
27202       const DRegister& dreg = dreglist.GetFirstDRegister();
27203       unsigned len = dreglist.GetLength() * 2;
27204       EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27205               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
27206               (len & 0xff));
27207       return;
27208     }
27209   }
27210   Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist);
27211 }
27212 
vstmia(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)27213 void Assembler::vstmia(Condition cond,
27214                        DataType dt,
27215                        Register rn,
27216                        WriteBack write_back,
27217                        SRegisterList sreglist) {
27218   VIXL_ASSERT(AllowAssembler());
27219   CheckIT(cond);
27220   USE(dt);
27221   if (IsUsingT32()) {
27222     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
27223     if ((!rn.IsPC() || AllowUnpredictable())) {
27224       const SRegister& sreg = sreglist.GetFirstSRegister();
27225       unsigned len = sreglist.GetLength();
27226       EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
27227                  (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
27228                  (len & 0xff));
27229       AdvanceIT();
27230       return;
27231     }
27232   } else {
27233     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
27234     if (cond.IsNotNever() &&
27235         ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
27236       const SRegister& sreg = sreglist.GetFirstSRegister();
27237       unsigned len = sreglist.GetLength();
27238       EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27239               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
27240               (len & 0xff));
27241       return;
27242     }
27243   }
27244   Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist);
27245 }
27246 
vstr(Condition cond,DataType dt,DRegister rd,const MemOperand & operand)27247 void Assembler::vstr(Condition cond,
27248                      DataType dt,
27249                      DRegister rd,
27250                      const MemOperand& operand) {
27251   VIXL_ASSERT(AllowAssembler());
27252   CheckIT(cond);
27253   if (operand.IsImmediate()) {
27254     Register rn = operand.GetBaseRegister();
27255     int32_t offset = operand.GetOffsetImmediate();
27256     if (IsUsingT32()) {
27257       // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
27258       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
27259           ((offset % 4) == 0) && operand.IsOffset() &&
27260           (!rn.IsPC() || AllowUnpredictable())) {
27261         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
27262         uint32_t offset_ = abs(offset) >> 2;
27263         EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
27264                    offset_ | (sign << 23));
27265         AdvanceIT();
27266         return;
27267       }
27268     } else {
27269       // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
27270       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
27271           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
27272         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
27273         uint32_t offset_ = abs(offset) >> 2;
27274         EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
27275                 (rn.GetCode() << 16) | offset_ | (sign << 23));
27276         return;
27277       }
27278     }
27279   }
27280   Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
27281 }
27282 
vstr(Condition cond,DataType dt,SRegister rd,const MemOperand & operand)27283 void Assembler::vstr(Condition cond,
27284                      DataType dt,
27285                      SRegister rd,
27286                      const MemOperand& operand) {
27287   VIXL_ASSERT(AllowAssembler());
27288   CheckIT(cond);
27289   if (operand.IsImmediate()) {
27290     Register rn = operand.GetBaseRegister();
27291     int32_t offset = operand.GetOffsetImmediate();
27292     if (IsUsingT32()) {
27293       // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
27294       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
27295           ((offset % 4) == 0) && operand.IsOffset() &&
27296           (!rn.IsPC() || AllowUnpredictable())) {
27297         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
27298         uint32_t offset_ = abs(offset) >> 2;
27299         EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
27300                    offset_ | (sign << 23));
27301         AdvanceIT();
27302         return;
27303       }
27304     } else {
27305       // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
27306       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
27307           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
27308         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
27309         uint32_t offset_ = abs(offset) >> 2;
27310         EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
27311                 (rn.GetCode() << 16) | offset_ | (sign << 23));
27312         return;
27313       }
27314     }
27315   }
27316   Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
27317 }
27318 
vsub(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)27319 void Assembler::vsub(
27320     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
27321   VIXL_ASSERT(AllowAssembler());
27322   CheckIT(cond);
27323   Dt_size_2 encoded_dt(dt);
27324   if (IsUsingT32()) {
27325     // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
27326     if (dt.Is(F32)) {
27327       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27328         EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27329                    rm.Encode(5, 0));
27330         AdvanceIT();
27331         return;
27332       }
27333     }
27334     // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
27335     if (dt.Is(F64)) {
27336       EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27337                  rm.Encode(5, 0));
27338       AdvanceIT();
27339       return;
27340     }
27341     // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
27342     if (encoded_dt.IsValid()) {
27343       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27344         EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) |
27345                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27346         AdvanceIT();
27347         return;
27348       }
27349     }
27350   } else {
27351     // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
27352     if (dt.Is(F32)) {
27353       if (cond.Is(al)) {
27354         EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27355                 rm.Encode(5, 0));
27356         return;
27357       }
27358     }
27359     // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
27360     if (dt.Is(F64) && cond.IsNotNever()) {
27361       EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
27362               rn.Encode(7, 16) | rm.Encode(5, 0));
27363       return;
27364     }
27365     // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
27366     if (encoded_dt.IsValid()) {
27367       if (cond.Is(al)) {
27368         EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) |
27369                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27370         return;
27371       }
27372     }
27373   }
27374   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
27375 }
27376 
vsub(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)27377 void Assembler::vsub(
27378     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
27379   VIXL_ASSERT(AllowAssembler());
27380   CheckIT(cond);
27381   Dt_size_2 encoded_dt(dt);
27382   if (IsUsingT32()) {
27383     // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
27384     if (dt.Is(F32)) {
27385       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27386         EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27387                    rm.Encode(5, 0));
27388         AdvanceIT();
27389         return;
27390       }
27391     }
27392     // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
27393     if (encoded_dt.IsValid()) {
27394       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27395         EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) |
27396                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27397         AdvanceIT();
27398         return;
27399       }
27400     }
27401   } else {
27402     // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
27403     if (dt.Is(F32)) {
27404       if (cond.Is(al)) {
27405         EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27406                 rm.Encode(5, 0));
27407         return;
27408       }
27409     }
27410     // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
27411     if (encoded_dt.IsValid()) {
27412       if (cond.Is(al)) {
27413         EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) |
27414                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27415         return;
27416       }
27417     }
27418   }
27419   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
27420 }
27421 
vsub(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)27422 void Assembler::vsub(
27423     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
27424   VIXL_ASSERT(AllowAssembler());
27425   CheckIT(cond);
27426   if (IsUsingT32()) {
27427     // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
27428     if (dt.Is(F32)) {
27429       EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27430                  rm.Encode(5, 0));
27431       AdvanceIT();
27432       return;
27433     }
27434   } else {
27435     // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
27436     if (dt.Is(F32) && cond.IsNotNever()) {
27437       EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
27438               rn.Encode(7, 16) | rm.Encode(5, 0));
27439       return;
27440     }
27441   }
27442   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
27443 }
27444 
vsubhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)27445 void Assembler::vsubhn(
27446     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
27447   VIXL_ASSERT(AllowAssembler());
27448   CheckIT(cond);
27449   Dt_size_3 encoded_dt(dt);
27450   if (IsUsingT32()) {
27451     // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
27452     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
27453       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27454         EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) |
27455                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27456         AdvanceIT();
27457         return;
27458       }
27459     }
27460   } else {
27461     // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
27462     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
27463       if (cond.Is(al)) {
27464         EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) |
27465                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27466         return;
27467       }
27468     }
27469   }
27470   Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm);
27471 }
27472 
vsubl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)27473 void Assembler::vsubl(
27474     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
27475   VIXL_ASSERT(AllowAssembler());
27476   CheckIT(cond);
27477   Dt_U_size_1 encoded_dt(dt);
27478   if (IsUsingT32()) {
27479     // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
27480     if (encoded_dt.IsValid()) {
27481       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27482         EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
27483                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
27484                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27485         AdvanceIT();
27486         return;
27487       }
27488     }
27489   } else {
27490     // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
27491     if (encoded_dt.IsValid()) {
27492       if (cond.Is(al)) {
27493         EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
27494                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
27495                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27496         return;
27497       }
27498     }
27499   }
27500   Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm);
27501 }
27502 
vsubw(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegister rm)27503 void Assembler::vsubw(
27504     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
27505   VIXL_ASSERT(AllowAssembler());
27506   CheckIT(cond);
27507   Dt_U_size_1 encoded_dt(dt);
27508   if (IsUsingT32()) {
27509     // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
27510     if (encoded_dt.IsValid()) {
27511       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27512         EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
27513                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
27514                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27515         AdvanceIT();
27516         return;
27517       }
27518     }
27519   } else {
27520     // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
27521     if (encoded_dt.IsValid()) {
27522       if (cond.Is(al)) {
27523         EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
27524                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
27525                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27526         return;
27527       }
27528     }
27529   }
27530   Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm);
27531 }
27532 
vswp(Condition cond,DataType dt,DRegister rd,DRegister rm)27533 void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
27534   VIXL_ASSERT(AllowAssembler());
27535   CheckIT(cond);
27536   USE(dt);
27537   if (IsUsingT32()) {
27538     // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
27539     if (cond.Is(al) || AllowStronglyDiscouraged()) {
27540       EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
27541       AdvanceIT();
27542       return;
27543     }
27544   } else {
27545     // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
27546     if (cond.Is(al)) {
27547       EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
27548       return;
27549     }
27550   }
27551   Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
27552 }
27553 
vswp(Condition cond,DataType dt,QRegister rd,QRegister rm)27554 void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
27555   VIXL_ASSERT(AllowAssembler());
27556   CheckIT(cond);
27557   USE(dt);
27558   if (IsUsingT32()) {
27559     // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
27560     if (cond.Is(al) || AllowStronglyDiscouraged()) {
27561       EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
27562       AdvanceIT();
27563       return;
27564     }
27565   } else {
27566     // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
27567     if (cond.Is(al)) {
27568       EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
27569       return;
27570     }
27571   }
27572   Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
27573 }
27574 
vtbl(Condition cond,DataType dt,DRegister rd,const NeonRegisterList & nreglist,DRegister rm)27575 void Assembler::vtbl(Condition cond,
27576                      DataType dt,
27577                      DRegister rd,
27578                      const NeonRegisterList& nreglist,
27579                      DRegister rm) {
27580   VIXL_ASSERT(AllowAssembler());
27581   CheckIT(cond);
27582   if (IsUsingT32()) {
27583     // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
27584     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
27585         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
27586       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27587         const DRegister& first = nreglist.GetFirstDRegister();
27588         uint32_t len_encoding = nreglist.GetLength() - 1;
27589         EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
27590                    (len_encoding << 8) | rm.Encode(5, 0));
27591         AdvanceIT();
27592         return;
27593       }
27594     }
27595   } else {
27596     // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
27597     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
27598         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
27599       if (cond.Is(al)) {
27600         const DRegister& first = nreglist.GetFirstDRegister();
27601         uint32_t len_encoding = nreglist.GetLength() - 1;
27602         EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
27603                 (len_encoding << 8) | rm.Encode(5, 0));
27604         return;
27605       }
27606     }
27607   }
27608   Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm);
27609 }
27610 
vtbx(Condition cond,DataType dt,DRegister rd,const NeonRegisterList & nreglist,DRegister rm)27611 void Assembler::vtbx(Condition cond,
27612                      DataType dt,
27613                      DRegister rd,
27614                      const NeonRegisterList& nreglist,
27615                      DRegister rm) {
27616   VIXL_ASSERT(AllowAssembler());
27617   CheckIT(cond);
27618   if (IsUsingT32()) {
27619     // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
27620     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
27621         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
27622       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27623         const DRegister& first = nreglist.GetFirstDRegister();
27624         uint32_t len_encoding = nreglist.GetLength() - 1;
27625         EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
27626                    (len_encoding << 8) | rm.Encode(5, 0));
27627         AdvanceIT();
27628         return;
27629       }
27630     }
27631   } else {
27632     // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
27633     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
27634         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
27635       if (cond.Is(al)) {
27636         const DRegister& first = nreglist.GetFirstDRegister();
27637         uint32_t len_encoding = nreglist.GetLength() - 1;
27638         EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
27639                 (len_encoding << 8) | rm.Encode(5, 0));
27640         return;
27641       }
27642     }
27643   }
27644   Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm);
27645 }
27646 
vtrn(Condition cond,DataType dt,DRegister rd,DRegister rm)27647 void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) {
27648   VIXL_ASSERT(AllowAssembler());
27649   CheckIT(cond);
27650   Dt_size_7 encoded_dt(dt);
27651   if (IsUsingT32()) {
27652     // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
27653     if (encoded_dt.IsValid()) {
27654       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27655         EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) |
27656                    rd.Encode(22, 12) | rm.Encode(5, 0));
27657         AdvanceIT();
27658         return;
27659       }
27660     }
27661   } else {
27662     // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
27663     if (encoded_dt.IsValid()) {
27664       if (cond.Is(al)) {
27665         EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) |
27666                 rd.Encode(22, 12) | rm.Encode(5, 0));
27667         return;
27668       }
27669     }
27670   }
27671   Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
27672 }
27673 
vtrn(Condition cond,DataType dt,QRegister rd,QRegister rm)27674 void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) {
27675   VIXL_ASSERT(AllowAssembler());
27676   CheckIT(cond);
27677   Dt_size_7 encoded_dt(dt);
27678   if (IsUsingT32()) {
27679     // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
27680     if (encoded_dt.IsValid()) {
27681       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27682         EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) |
27683                    rd.Encode(22, 12) | rm.Encode(5, 0));
27684         AdvanceIT();
27685         return;
27686       }
27687     }
27688   } else {
27689     // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
27690     if (encoded_dt.IsValid()) {
27691       if (cond.Is(al)) {
27692         EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) |
27693                 rd.Encode(22, 12) | rm.Encode(5, 0));
27694         return;
27695       }
27696     }
27697   }
27698   Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
27699 }
27700 
vtst(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)27701 void Assembler::vtst(
27702     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
27703   VIXL_ASSERT(AllowAssembler());
27704   CheckIT(cond);
27705   Dt_size_7 encoded_dt(dt);
27706   if (IsUsingT32()) {
27707     // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
27708     if (encoded_dt.IsValid()) {
27709       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27710         EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) |
27711                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27712         AdvanceIT();
27713         return;
27714       }
27715     }
27716   } else {
27717     // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
27718     if (encoded_dt.IsValid()) {
27719       if (cond.Is(al)) {
27720         EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) |
27721                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27722         return;
27723       }
27724     }
27725   }
27726   Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
27727 }
27728 
vtst(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)27729 void Assembler::vtst(
27730     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
27731   VIXL_ASSERT(AllowAssembler());
27732   CheckIT(cond);
27733   Dt_size_7 encoded_dt(dt);
27734   if (IsUsingT32()) {
27735     // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
27736     if (encoded_dt.IsValid()) {
27737       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27738         EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) |
27739                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27740         AdvanceIT();
27741         return;
27742       }
27743     }
27744   } else {
27745     // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
27746     if (encoded_dt.IsValid()) {
27747       if (cond.Is(al)) {
27748         EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) |
27749                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27750         return;
27751       }
27752     }
27753   }
27754   Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
27755 }
27756 
vuzp(Condition cond,DataType dt,DRegister rd,DRegister rm)27757 void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
27758   VIXL_ASSERT(AllowAssembler());
27759   CheckIT(cond);
27760   Dt_size_15 encoded_dt(dt);
27761   if (IsUsingT32()) {
27762     // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
27763     if (encoded_dt.IsValid()) {
27764       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27765         EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) |
27766                    rd.Encode(22, 12) | rm.Encode(5, 0));
27767         AdvanceIT();
27768         return;
27769       }
27770     }
27771     // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
27772     if (dt.Is(Untyped32)) {
27773       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27774         EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
27775         AdvanceIT();
27776         return;
27777       }
27778     }
27779   } else {
27780     // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
27781     if (encoded_dt.IsValid()) {
27782       if (cond.Is(al)) {
27783         EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) |
27784                 rd.Encode(22, 12) | rm.Encode(5, 0));
27785         return;
27786       }
27787     }
27788     // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
27789     if (dt.Is(Untyped32)) {
27790       if (cond.Is(al)) {
27791         EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
27792         return;
27793       }
27794     }
27795   }
27796   Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
27797 }
27798 
vuzp(Condition cond,DataType dt,QRegister rd,QRegister rm)27799 void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
27800   VIXL_ASSERT(AllowAssembler());
27801   CheckIT(cond);
27802   Dt_size_7 encoded_dt(dt);
27803   if (IsUsingT32()) {
27804     // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
27805     if (encoded_dt.IsValid()) {
27806       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27807         EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) |
27808                    rd.Encode(22, 12) | rm.Encode(5, 0));
27809         AdvanceIT();
27810         return;
27811       }
27812     }
27813   } else {
27814     // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
27815     if (encoded_dt.IsValid()) {
27816       if (cond.Is(al)) {
27817         EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) |
27818                 rd.Encode(22, 12) | rm.Encode(5, 0));
27819         return;
27820       }
27821     }
27822   }
27823   Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
27824 }
27825 
vzip(Condition cond,DataType dt,DRegister rd,DRegister rm)27826 void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) {
27827   VIXL_ASSERT(AllowAssembler());
27828   CheckIT(cond);
27829   Dt_size_15 encoded_dt(dt);
27830   if (IsUsingT32()) {
27831     // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
27832     if (encoded_dt.IsValid()) {
27833       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27834         EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) |
27835                    rd.Encode(22, 12) | rm.Encode(5, 0));
27836         AdvanceIT();
27837         return;
27838       }
27839     }
27840     // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
27841     if (dt.Is(Untyped32)) {
27842       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27843         EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
27844         AdvanceIT();
27845         return;
27846       }
27847     }
27848   } else {
27849     // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
27850     if (encoded_dt.IsValid()) {
27851       if (cond.Is(al)) {
27852         EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) |
27853                 rd.Encode(22, 12) | rm.Encode(5, 0));
27854         return;
27855       }
27856     }
27857     // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
27858     if (dt.Is(Untyped32)) {
27859       if (cond.Is(al)) {
27860         EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
27861         return;
27862       }
27863     }
27864   }
27865   Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
27866 }
27867 
vzip(Condition cond,DataType dt,QRegister rd,QRegister rm)27868 void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) {
27869   VIXL_ASSERT(AllowAssembler());
27870   CheckIT(cond);
27871   Dt_size_7 encoded_dt(dt);
27872   if (IsUsingT32()) {
27873     // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
27874     if (encoded_dt.IsValid()) {
27875       if (cond.Is(al) || AllowStronglyDiscouraged()) {
27876         EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) |
27877                    rd.Encode(22, 12) | rm.Encode(5, 0));
27878         AdvanceIT();
27879         return;
27880       }
27881     }
27882   } else {
27883     // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
27884     if (encoded_dt.IsValid()) {
27885       if (cond.Is(al)) {
27886         EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) |
27887                 rd.Encode(22, 12) | rm.Encode(5, 0));
27888         return;
27889       }
27890     }
27891   }
27892   Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
27893 }
27894 
yield(Condition cond,EncodingSize size)27895 void Assembler::yield(Condition cond, EncodingSize size) {
27896   VIXL_ASSERT(AllowAssembler());
27897   CheckIT(cond);
27898   if (IsUsingT32()) {
27899     // YIELD{<c>}{<q>} ; T1
27900     if (!size.IsWide()) {
27901       EmitT32_16(0xbf10);
27902       AdvanceIT();
27903       return;
27904     }
27905     // YIELD{<c>}.W ; T2
27906     if (!size.IsNarrow()) {
27907       EmitT32_32(0xf3af8001U);
27908       AdvanceIT();
27909       return;
27910     }
27911   } else {
27912     // YIELD{<c>}{<q>} ; A1
27913     if (cond.IsNotNever()) {
27914       EmitA32(0x0320f001U | (cond.GetCondition() << 28));
27915       return;
27916     }
27917   }
27918   Delegate(kYield, &Assembler::yield, cond, size);
27919 }
27920 // End of generated code.
27921 
27922 }  // namespace aarch32
27923 }  // namespace vixl
27924