• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015, VIXL authors
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
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/constants-aarch32.h"
39 #include "aarch32/instructions-aarch32.h"
40 #include "aarch32/operands-aarch32.h"
41 #include "aarch32/assembler-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     first_condition_ =
72         Condition((first_condition_.GetCondition() & 0xe) | (it_mask_ >> 3));
73     // For A32, AdavanceIT() is not called by the assembler. We must call it
74     // in order to check that IT instructions are used consistently with
75     // the following conditional instructions.
76     if (IsUsingA32()) AdvanceIT();
77   }
78 }
79 #endif
80 
81 
BindHelper(Label * label)82 void Assembler::BindHelper(Label* label) {
83   VIXL_ASSERT(!label->IsBound());
84   label->Bind(GetCursorOffset(), GetInstructionSetInUse());
85 
86   for (Label::ForwardRefList::iterator ref = label->GetFirstForwardRef();
87        ref != label->GetEndForwardRef();
88        ref++) {
89     EncodeLabelFor(*ref, label);
90   }
91   if (label->IsInVeneerPool()) {
92     label->GetVeneerPoolManager()->RemoveLabel(label);
93   }
94 }
95 
96 
Link(uint32_t instr,Label * label,const Label::LabelEmitOperator & op)97 uint32_t Assembler::Link(uint32_t instr,
98                          Label* label,
99                          const Label::LabelEmitOperator& op) {
100   label->SetReferenced();
101   if (label->IsBound()) {
102     return op.Encode(instr,
103                      GetCursorOffset() + GetArchitectureStatePCOffset(),
104                      label);
105   }
106   label->AddForwardRef(GetCursorOffset(), GetInstructionSetInUse(), op);
107   return instr;
108 }
109 
110 
EncodeLabelFor(const Label::ForwardReference & forward,Label * label)111 void Assembler::EncodeLabelFor(const Label::ForwardReference& forward,
112                                Label* label) {
113   const uint32_t location = forward.GetLocation();
114   const uint32_t from = location + forward.GetStatePCOffset();
115   const Label::LabelEmitOperator& encoder = forward.GetEmitOperator();
116   if (forward.IsUsingT32()) {
117     uint16_t* instr_ptr = buffer_.GetOffsetAddress<uint16_t*>(location);
118     if (Is16BitEncoding(instr_ptr[0])) {
119       // The Encode methods always deals with uint32_t types so we need
120       // to explicitely cast it.
121       uint32_t instr = static_cast<uint32_t>(instr_ptr[0]);
122       instr = encoder.Encode(instr, from, label);
123       // The Encode method should not ever set the top 16 bits.
124       VIXL_ASSERT((instr & ~0xffff) == 0);
125       instr_ptr[0] = static_cast<uint16_t>(instr);
126     } else {
127       uint32_t instr =
128           instr_ptr[1] | (static_cast<uint32_t>(instr_ptr[0]) << 16);
129       instr = encoder.Encode(instr, from, label);
130       instr_ptr[0] = static_cast<uint16_t>(instr >> 16);
131       instr_ptr[1] = static_cast<uint16_t>(instr);
132     }
133   } else {
134     uint32_t* instr_ptr = buffer_.GetOffsetAddress<uint32_t*>(location);
135     instr_ptr[0] = encoder.Encode(instr_ptr[0], from, label);
136   }
137 }
138 
139 
140 // Start of generated code.
141 class Dt_L_imm6_1 : public EncodingValue {
142   uint32_t type_;
143 
144  public:
145   explicit Dt_L_imm6_1(DataType dt);
GetTypeEncodingValue() const146   uint32_t GetTypeEncodingValue() const { return type_; }
147 };
148 
Dt_L_imm6_1(DataType dt)149 Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) {
150   switch (dt.GetValue()) {
151     case S8:
152       type_ = 0x0;
153       SetEncodingValue(0x1);
154       break;
155     case U8:
156       type_ = 0x1;
157       SetEncodingValue(0x1);
158       break;
159     case S16:
160       type_ = 0x0;
161       SetEncodingValue(0x2);
162       break;
163     case U16:
164       type_ = 0x1;
165       SetEncodingValue(0x2);
166       break;
167     case S32:
168       type_ = 0x0;
169       SetEncodingValue(0x4);
170       break;
171     case U32:
172       type_ = 0x1;
173       SetEncodingValue(0x4);
174       break;
175     case S64:
176       type_ = 0x0;
177       SetEncodingValue(0x8);
178       break;
179     case U64:
180       type_ = 0x1;
181       SetEncodingValue(0x8);
182       break;
183     default:
184       VIXL_UNREACHABLE();
185       type_ = 0x0;
186       break;
187   }
188 }
189 
190 class Dt_L_imm6_2 : public EncodingValue {
191   uint32_t type_;
192 
193  public:
194   explicit Dt_L_imm6_2(DataType dt);
GetTypeEncodingValue() const195   uint32_t GetTypeEncodingValue() const { return type_; }
196 };
197 
Dt_L_imm6_2(DataType dt)198 Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) {
199   switch (dt.GetValue()) {
200     case S8:
201       type_ = 0x1;
202       SetEncodingValue(0x1);
203       break;
204     case S16:
205       type_ = 0x1;
206       SetEncodingValue(0x2);
207       break;
208     case S32:
209       type_ = 0x1;
210       SetEncodingValue(0x4);
211       break;
212     case S64:
213       type_ = 0x1;
214       SetEncodingValue(0x8);
215       break;
216     default:
217       VIXL_UNREACHABLE();
218       type_ = 0x0;
219       break;
220   }
221 }
222 
223 class Dt_L_imm6_3 : public EncodingValue {
224  public:
225   explicit Dt_L_imm6_3(DataType dt);
226 };
227 
Dt_L_imm6_3(DataType dt)228 Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) {
229   switch (dt.GetValue()) {
230     case I8:
231       SetEncodingValue(0x1);
232       break;
233     case I16:
234       SetEncodingValue(0x2);
235       break;
236     case I32:
237       SetEncodingValue(0x4);
238       break;
239     case I64:
240       SetEncodingValue(0x8);
241       break;
242     default:
243       break;
244   }
245 }
246 
247 class Dt_L_imm6_4 : public EncodingValue {
248  public:
249   explicit Dt_L_imm6_4(DataType dt);
250 };
251 
Dt_L_imm6_4(DataType dt)252 Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) {
253   switch (dt.GetValue()) {
254     case Untyped8:
255       SetEncodingValue(0x1);
256       break;
257     case Untyped16:
258       SetEncodingValue(0x2);
259       break;
260     case Untyped32:
261       SetEncodingValue(0x4);
262       break;
263     case Untyped64:
264       SetEncodingValue(0x8);
265       break;
266     default:
267       break;
268   }
269 }
270 
271 class Dt_imm6_1 : public EncodingValue {
272   uint32_t type_;
273 
274  public:
275   explicit Dt_imm6_1(DataType dt);
GetTypeEncodingValue() const276   uint32_t GetTypeEncodingValue() const { return type_; }
277 };
278 
Dt_imm6_1(DataType dt)279 Dt_imm6_1::Dt_imm6_1(DataType dt) {
280   switch (dt.GetValue()) {
281     case S16:
282       type_ = 0x0;
283       SetEncodingValue(0x1);
284       break;
285     case U16:
286       type_ = 0x1;
287       SetEncodingValue(0x1);
288       break;
289     case S32:
290       type_ = 0x0;
291       SetEncodingValue(0x2);
292       break;
293     case U32:
294       type_ = 0x1;
295       SetEncodingValue(0x2);
296       break;
297     case S64:
298       type_ = 0x0;
299       SetEncodingValue(0x4);
300       break;
301     case U64:
302       type_ = 0x1;
303       SetEncodingValue(0x4);
304       break;
305     default:
306       VIXL_UNREACHABLE();
307       type_ = 0x0;
308       break;
309   }
310 }
311 
312 class Dt_imm6_2 : public EncodingValue {
313   uint32_t type_;
314 
315  public:
316   explicit Dt_imm6_2(DataType dt);
GetTypeEncodingValue() const317   uint32_t GetTypeEncodingValue() const { return type_; }
318 };
319 
Dt_imm6_2(DataType dt)320 Dt_imm6_2::Dt_imm6_2(DataType dt) {
321   switch (dt.GetValue()) {
322     case S16:
323       type_ = 0x1;
324       SetEncodingValue(0x1);
325       break;
326     case S32:
327       type_ = 0x1;
328       SetEncodingValue(0x2);
329       break;
330     case S64:
331       type_ = 0x1;
332       SetEncodingValue(0x4);
333       break;
334     default:
335       VIXL_UNREACHABLE();
336       type_ = 0x0;
337       break;
338   }
339 }
340 
341 class Dt_imm6_3 : public EncodingValue {
342  public:
343   explicit Dt_imm6_3(DataType dt);
344 };
345 
Dt_imm6_3(DataType dt)346 Dt_imm6_3::Dt_imm6_3(DataType dt) {
347   switch (dt.GetValue()) {
348     case I16:
349       SetEncodingValue(0x1);
350       break;
351     case I32:
352       SetEncodingValue(0x2);
353       break;
354     case I64:
355       SetEncodingValue(0x4);
356       break;
357     default:
358       break;
359   }
360 }
361 
362 class Dt_imm6_4 : public EncodingValue {
363   uint32_t type_;
364 
365  public:
366   explicit Dt_imm6_4(DataType dt);
GetTypeEncodingValue() const367   uint32_t GetTypeEncodingValue() const { return type_; }
368 };
369 
Dt_imm6_4(DataType dt)370 Dt_imm6_4::Dt_imm6_4(DataType dt) {
371   switch (dt.GetValue()) {
372     case S8:
373       type_ = 0x0;
374       SetEncodingValue(0x1);
375       break;
376     case U8:
377       type_ = 0x1;
378       SetEncodingValue(0x1);
379       break;
380     case S16:
381       type_ = 0x0;
382       SetEncodingValue(0x2);
383       break;
384     case U16:
385       type_ = 0x1;
386       SetEncodingValue(0x2);
387       break;
388     case S32:
389       type_ = 0x0;
390       SetEncodingValue(0x4);
391       break;
392     case U32:
393       type_ = 0x1;
394       SetEncodingValue(0x4);
395       break;
396     default:
397       VIXL_UNREACHABLE();
398       type_ = 0x0;
399       break;
400   }
401 }
402 
403 class Dt_op_U_size_1 : public EncodingValue {
404  public:
405   explicit Dt_op_U_size_1(DataType dt);
406 };
407 
Dt_op_U_size_1(DataType dt)408 Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) {
409   switch (dt.GetValue()) {
410     case S8:
411       SetEncodingValue(0x0);
412       break;
413     case S16:
414       SetEncodingValue(0x1);
415       break;
416     case S32:
417       SetEncodingValue(0x2);
418       break;
419     case U8:
420       SetEncodingValue(0x4);
421       break;
422     case U16:
423       SetEncodingValue(0x5);
424       break;
425     case U32:
426       SetEncodingValue(0x6);
427       break;
428     case P8:
429       SetEncodingValue(0x8);
430       break;
431     case P64:
432       SetEncodingValue(0xa);
433       break;
434     default:
435       break;
436   }
437 }
438 
439 class Dt_op_size_1 : public EncodingValue {
440  public:
441   explicit Dt_op_size_1(DataType dt);
442 };
443 
Dt_op_size_1(DataType dt)444 Dt_op_size_1::Dt_op_size_1(DataType dt) {
445   switch (dt.GetValue()) {
446     case I8:
447       SetEncodingValue(0x0);
448       break;
449     case I16:
450       SetEncodingValue(0x1);
451       break;
452     case I32:
453       SetEncodingValue(0x2);
454       break;
455     case P8:
456       SetEncodingValue(0x4);
457       break;
458     default:
459       break;
460   }
461 }
462 
463 class Dt_op_size_2 : public EncodingValue {
464  public:
465   explicit Dt_op_size_2(DataType dt);
466 };
467 
Dt_op_size_2(DataType dt)468 Dt_op_size_2::Dt_op_size_2(DataType dt) {
469   switch (dt.GetValue()) {
470     case S8:
471       SetEncodingValue(0x0);
472       break;
473     case S16:
474       SetEncodingValue(0x1);
475       break;
476     case S32:
477       SetEncodingValue(0x2);
478       break;
479     case U8:
480       SetEncodingValue(0x4);
481       break;
482     case U16:
483       SetEncodingValue(0x5);
484       break;
485     case U32:
486       SetEncodingValue(0x6);
487       break;
488     default:
489       break;
490   }
491 }
492 
493 class Dt_op_size_3 : public EncodingValue {
494  public:
495   explicit Dt_op_size_3(DataType dt);
496 };
497 
Dt_op_size_3(DataType dt)498 Dt_op_size_3::Dt_op_size_3(DataType dt) {
499   switch (dt.GetValue()) {
500     case S16:
501       SetEncodingValue(0x0);
502       break;
503     case S32:
504       SetEncodingValue(0x1);
505       break;
506     case S64:
507       SetEncodingValue(0x2);
508       break;
509     case U16:
510       SetEncodingValue(0x4);
511       break;
512     case U32:
513       SetEncodingValue(0x5);
514       break;
515     case U64:
516       SetEncodingValue(0x6);
517       break;
518     default:
519       break;
520   }
521 }
522 
523 class Dt_U_imm3H_1 : public EncodingValue {
524  public:
525   explicit Dt_U_imm3H_1(DataType dt);
526 };
527 
Dt_U_imm3H_1(DataType dt)528 Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) {
529   switch (dt.GetValue()) {
530     case S8:
531       SetEncodingValue(0x1);
532       break;
533     case S16:
534       SetEncodingValue(0x2);
535       break;
536     case S32:
537       SetEncodingValue(0x4);
538       break;
539     case U8:
540       SetEncodingValue(0x9);
541       break;
542     case U16:
543       SetEncodingValue(0xa);
544       break;
545     case U32:
546       SetEncodingValue(0xc);
547       break;
548     default:
549       break;
550   }
551 }
552 
553 class Dt_U_opc1_opc2_1 : public EncodingValue {
554  public:
555   explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
556 };
557 
Dt_U_opc1_opc2_1(DataType dt,const DRegisterLane & lane)558 Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
559   switch (dt.GetValue()) {
560     case S8:
561       if ((lane.GetLane() & 7) != lane.GetLane()) {
562         return;
563       }
564       SetEncodingValue(0x8 | lane.GetLane());
565       break;
566     case S16:
567       if ((lane.GetLane() & 3) != lane.GetLane()) {
568         return;
569       }
570       SetEncodingValue(0x1 | (lane.GetLane() << 1));
571       break;
572     case U8:
573       if ((lane.GetLane() & 7) != lane.GetLane()) {
574         return;
575       }
576       SetEncodingValue(0x18 | lane.GetLane());
577       break;
578     case U16:
579       if ((lane.GetLane() & 3) != lane.GetLane()) {
580         return;
581       }
582       SetEncodingValue(0x11 | (lane.GetLane() << 1));
583       break;
584     case Untyped32:
585       if ((lane.GetLane() & 1) != lane.GetLane()) {
586         return;
587       }
588       SetEncodingValue(0x0 | (lane.GetLane() << 2));
589       break;
590     case kDataTypeValueNone:
591       if ((lane.GetLane() & 1) != lane.GetLane()) {
592         return;
593       }
594       SetEncodingValue(0x0 | (lane.GetLane() << 2));
595       break;
596     default:
597       break;
598   }
599 }
600 
601 class Dt_opc1_opc2_1 : public EncodingValue {
602  public:
603   explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
604 };
605 
Dt_opc1_opc2_1(DataType dt,const DRegisterLane & lane)606 Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
607   switch (dt.GetValue()) {
608     case Untyped8:
609       if ((lane.GetLane() & 7) != lane.GetLane()) {
610         return;
611       }
612       SetEncodingValue(0x8 | lane.GetLane());
613       break;
614     case Untyped16:
615       if ((lane.GetLane() & 3) != lane.GetLane()) {
616         return;
617       }
618       SetEncodingValue(0x1 | (lane.GetLane() << 1));
619       break;
620     case Untyped32:
621       if ((lane.GetLane() & 1) != lane.GetLane()) {
622         return;
623       }
624       SetEncodingValue(0x0 | (lane.GetLane() << 2));
625       break;
626     case kDataTypeValueNone:
627       if ((lane.GetLane() & 1) != lane.GetLane()) {
628         return;
629       }
630       SetEncodingValue(0x0 | (lane.GetLane() << 2));
631       break;
632     default:
633       break;
634   }
635 }
636 
637 class Dt_imm4_1 : public EncodingValue {
638  public:
639   explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane);
640 };
641 
Dt_imm4_1(DataType dt,const DRegisterLane & lane)642 Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) {
643   switch (dt.GetValue()) {
644     case Untyped8:
645       if ((lane.GetLane() & 7) != lane.GetLane()) {
646         return;
647       }
648       SetEncodingValue(0x1 | (lane.GetLane() << 1));
649       break;
650     case Untyped16:
651       if ((lane.GetLane() & 3) != lane.GetLane()) {
652         return;
653       }
654       SetEncodingValue(0x2 | (lane.GetLane() << 2));
655       break;
656     case Untyped32:
657       if ((lane.GetLane() & 1) != lane.GetLane()) {
658         return;
659       }
660       SetEncodingValue(0x4 | (lane.GetLane() << 3));
661       break;
662     default:
663       break;
664   }
665 }
666 
667 class Dt_B_E_1 : public EncodingValue {
668  public:
669   explicit Dt_B_E_1(DataType dt);
670 };
671 
Dt_B_E_1(DataType dt)672 Dt_B_E_1::Dt_B_E_1(DataType dt) {
673   switch (dt.GetValue()) {
674     case Untyped8:
675       SetEncodingValue(0x2);
676       break;
677     case Untyped16:
678       SetEncodingValue(0x1);
679       break;
680     case Untyped32:
681       SetEncodingValue(0x0);
682       break;
683     default:
684       break;
685   }
686 }
687 
688 class Dt_op_1 : public EncodingValue {
689  public:
690   Dt_op_1(DataType dt1, DataType dt2);
691 };
692 
Dt_op_1(DataType dt1,DataType dt2)693 Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) {
694   if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
695     SetEncodingValue(0x0);
696     return;
697   }
698   if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
699     SetEncodingValue(0x1);
700     return;
701   }
702   if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
703     SetEncodingValue(0x2);
704     return;
705   }
706   if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
707     SetEncodingValue(0x3);
708     return;
709   }
710 }
711 
712 class Dt_op_2 : public EncodingValue {
713  public:
714   explicit Dt_op_2(DataType dt);
715 };
716 
Dt_op_2(DataType dt)717 Dt_op_2::Dt_op_2(DataType dt) {
718   switch (dt.GetValue()) {
719     case U32:
720       SetEncodingValue(0x0);
721       break;
722     case S32:
723       SetEncodingValue(0x1);
724       break;
725     default:
726       break;
727   }
728 }
729 
730 class Dt_op_3 : public EncodingValue {
731  public:
732   explicit Dt_op_3(DataType dt);
733 };
734 
Dt_op_3(DataType dt)735 Dt_op_3::Dt_op_3(DataType dt) {
736   switch (dt.GetValue()) {
737     case S32:
738       SetEncodingValue(0x0);
739       break;
740     case U32:
741       SetEncodingValue(0x1);
742       break;
743     default:
744       break;
745   }
746 }
747 
748 class Dt_U_sx_1 : public EncodingValue {
749  public:
750   explicit Dt_U_sx_1(DataType dt);
751 };
752 
Dt_U_sx_1(DataType dt)753 Dt_U_sx_1::Dt_U_sx_1(DataType dt) {
754   switch (dt.GetValue()) {
755     case S16:
756       SetEncodingValue(0x0);
757       break;
758     case S32:
759       SetEncodingValue(0x1);
760       break;
761     case U16:
762       SetEncodingValue(0x2);
763       break;
764     case U32:
765       SetEncodingValue(0x3);
766       break;
767     default:
768       break;
769   }
770 }
771 
772 class Dt_op_U_1 : public EncodingValue {
773  public:
774   Dt_op_U_1(DataType dt1, DataType dt2);
775 };
776 
Dt_op_U_1(DataType dt1,DataType dt2)777 Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) {
778   if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
779     SetEncodingValue(0x0);
780     return;
781   }
782   if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
783     SetEncodingValue(0x1);
784     return;
785   }
786   if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
787     SetEncodingValue(0x2);
788     return;
789   }
790   if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
791     SetEncodingValue(0x3);
792     return;
793   }
794 }
795 
796 class Dt_sz_1 : public EncodingValue {
797  public:
798   explicit Dt_sz_1(DataType dt);
799 };
800 
Dt_sz_1(DataType dt)801 Dt_sz_1::Dt_sz_1(DataType dt) {
802   switch (dt.GetValue()) {
803     case F32:
804       SetEncodingValue(0x0);
805       break;
806     default:
807       break;
808   }
809 }
810 
811 class Dt_F_size_1 : public EncodingValue {
812  public:
813   explicit Dt_F_size_1(DataType dt);
814 };
815 
Dt_F_size_1(DataType dt)816 Dt_F_size_1::Dt_F_size_1(DataType dt) {
817   switch (dt.GetValue()) {
818     case S8:
819       SetEncodingValue(0x0);
820       break;
821     case S16:
822       SetEncodingValue(0x1);
823       break;
824     case S32:
825       SetEncodingValue(0x2);
826       break;
827     case F32:
828       SetEncodingValue(0x6);
829       break;
830     default:
831       break;
832   }
833 }
834 
835 class Dt_F_size_2 : public EncodingValue {
836  public:
837   explicit Dt_F_size_2(DataType dt);
838 };
839 
Dt_F_size_2(DataType dt)840 Dt_F_size_2::Dt_F_size_2(DataType dt) {
841   switch (dt.GetValue()) {
842     case I8:
843       SetEncodingValue(0x0);
844       break;
845     case I16:
846       SetEncodingValue(0x1);
847       break;
848     case I32:
849       SetEncodingValue(0x2);
850       break;
851     case F32:
852       SetEncodingValue(0x6);
853       break;
854     default:
855       break;
856   }
857 }
858 
859 class Dt_F_size_3 : public EncodingValue {
860  public:
861   explicit Dt_F_size_3(DataType dt);
862 };
863 
Dt_F_size_3(DataType dt)864 Dt_F_size_3::Dt_F_size_3(DataType dt) {
865   switch (dt.GetValue()) {
866     case I16:
867       SetEncodingValue(0x1);
868       break;
869     case I32:
870       SetEncodingValue(0x2);
871       break;
872     case F32:
873       SetEncodingValue(0x6);
874       break;
875     default:
876       break;
877   }
878 }
879 
880 class Dt_F_size_4 : public EncodingValue {
881  public:
882   explicit Dt_F_size_4(DataType dt);
883 };
884 
Dt_F_size_4(DataType dt)885 Dt_F_size_4::Dt_F_size_4(DataType dt) {
886   switch (dt.GetValue()) {
887     case U32:
888       SetEncodingValue(0x2);
889       break;
890     case F32:
891       SetEncodingValue(0x6);
892       break;
893     default:
894       break;
895   }
896 }
897 
898 class Dt_U_size_1 : public EncodingValue {
899  public:
900   explicit Dt_U_size_1(DataType dt);
901 };
902 
Dt_U_size_1(DataType dt)903 Dt_U_size_1::Dt_U_size_1(DataType dt) {
904   switch (dt.GetValue()) {
905     case S8:
906       SetEncodingValue(0x0);
907       break;
908     case S16:
909       SetEncodingValue(0x1);
910       break;
911     case S32:
912       SetEncodingValue(0x2);
913       break;
914     case U8:
915       SetEncodingValue(0x4);
916       break;
917     case U16:
918       SetEncodingValue(0x5);
919       break;
920     case U32:
921       SetEncodingValue(0x6);
922       break;
923     default:
924       break;
925   }
926 }
927 
928 class Dt_U_size_2 : public EncodingValue {
929  public:
930   explicit Dt_U_size_2(DataType dt);
931 };
932 
Dt_U_size_2(DataType dt)933 Dt_U_size_2::Dt_U_size_2(DataType dt) {
934   switch (dt.GetValue()) {
935     case S16:
936       SetEncodingValue(0x1);
937       break;
938     case S32:
939       SetEncodingValue(0x2);
940       break;
941     case U16:
942       SetEncodingValue(0x5);
943       break;
944     case U32:
945       SetEncodingValue(0x6);
946       break;
947     default:
948       break;
949   }
950 }
951 
952 class Dt_U_size_3 : public EncodingValue {
953  public:
954   explicit Dt_U_size_3(DataType dt);
955 };
956 
Dt_U_size_3(DataType dt)957 Dt_U_size_3::Dt_U_size_3(DataType dt) {
958   switch (dt.GetValue()) {
959     case S8:
960       SetEncodingValue(0x0);
961       break;
962     case S16:
963       SetEncodingValue(0x1);
964       break;
965     case S32:
966       SetEncodingValue(0x2);
967       break;
968     case S64:
969       SetEncodingValue(0x3);
970       break;
971     case U8:
972       SetEncodingValue(0x4);
973       break;
974     case U16:
975       SetEncodingValue(0x5);
976       break;
977     case U32:
978       SetEncodingValue(0x6);
979       break;
980     case U64:
981       SetEncodingValue(0x7);
982       break;
983     default:
984       break;
985   }
986 }
987 
988 class Dt_size_1 : public EncodingValue {
989  public:
990   explicit Dt_size_1(DataType dt);
991 };
992 
Dt_size_1(DataType dt)993 Dt_size_1::Dt_size_1(DataType dt) {
994   switch (dt.GetValue()) {
995     case Untyped8:
996       SetEncodingValue(0x0);
997       break;
998     default:
999       break;
1000   }
1001 }
1002 
1003 class Dt_size_2 : public EncodingValue {
1004  public:
1005   explicit Dt_size_2(DataType dt);
1006 };
1007 
Dt_size_2(DataType dt)1008 Dt_size_2::Dt_size_2(DataType dt) {
1009   switch (dt.GetValue()) {
1010     case I8:
1011       SetEncodingValue(0x0);
1012       break;
1013     case I16:
1014       SetEncodingValue(0x1);
1015       break;
1016     case I32:
1017       SetEncodingValue(0x2);
1018       break;
1019     case I64:
1020       SetEncodingValue(0x3);
1021       break;
1022     default:
1023       break;
1024   }
1025 }
1026 
1027 class Dt_size_3 : public EncodingValue {
1028  public:
1029   explicit Dt_size_3(DataType dt);
1030 };
1031 
Dt_size_3(DataType dt)1032 Dt_size_3::Dt_size_3(DataType dt) {
1033   switch (dt.GetValue()) {
1034     case I16:
1035       SetEncodingValue(0x0);
1036       break;
1037     case I32:
1038       SetEncodingValue(0x1);
1039       break;
1040     case I64:
1041       SetEncodingValue(0x2);
1042       break;
1043     default:
1044       break;
1045   }
1046 }
1047 
1048 class Dt_size_4 : public EncodingValue {
1049  public:
1050   explicit Dt_size_4(DataType dt);
1051 };
1052 
Dt_size_4(DataType dt)1053 Dt_size_4::Dt_size_4(DataType dt) {
1054   switch (dt.GetValue()) {
1055     case I8:
1056       SetEncodingValue(0x0);
1057       break;
1058     case I16:
1059       SetEncodingValue(0x1);
1060       break;
1061     case I32:
1062       SetEncodingValue(0x2);
1063       break;
1064     default:
1065       break;
1066   }
1067 }
1068 
1069 class Dt_size_5 : public EncodingValue {
1070  public:
1071   explicit Dt_size_5(DataType dt);
1072 };
1073 
Dt_size_5(DataType dt)1074 Dt_size_5::Dt_size_5(DataType dt) {
1075   switch (dt.GetValue()) {
1076     case S8:
1077       SetEncodingValue(0x0);
1078       break;
1079     case S16:
1080       SetEncodingValue(0x1);
1081       break;
1082     case S32:
1083       SetEncodingValue(0x2);
1084       break;
1085     default:
1086       break;
1087   }
1088 }
1089 
1090 class Dt_size_6 : public EncodingValue {
1091  public:
1092   explicit Dt_size_6(DataType dt);
1093 };
1094 
Dt_size_6(DataType dt)1095 Dt_size_6::Dt_size_6(DataType dt) {
1096   switch (dt.GetValue()) {
1097     case Untyped8:
1098       SetEncodingValue(0x0);
1099       break;
1100     case Untyped16:
1101       SetEncodingValue(0x1);
1102       break;
1103     case Untyped32:
1104       SetEncodingValue(0x2);
1105       break;
1106     case Untyped64:
1107       SetEncodingValue(0x3);
1108       break;
1109     default:
1110       break;
1111   }
1112 }
1113 
1114 class Dt_size_7 : public EncodingValue {
1115  public:
1116   explicit Dt_size_7(DataType dt);
1117 };
1118 
Dt_size_7(DataType dt)1119 Dt_size_7::Dt_size_7(DataType dt) {
1120   switch (dt.GetValue()) {
1121     case Untyped8:
1122       SetEncodingValue(0x0);
1123       break;
1124     case Untyped16:
1125       SetEncodingValue(0x1);
1126       break;
1127     case Untyped32:
1128       SetEncodingValue(0x2);
1129       break;
1130     default:
1131       break;
1132   }
1133 }
1134 
1135 class Dt_size_8 : public EncodingValue {
1136  public:
1137   Dt_size_8(DataType dt, Alignment align);
1138 };
1139 
Dt_size_8(DataType dt,Alignment align)1140 Dt_size_8::Dt_size_8(DataType dt, Alignment align) {
1141   switch (dt.GetValue()) {
1142     case Untyped8:
1143       SetEncodingValue(0x0);
1144       break;
1145     case Untyped16:
1146       SetEncodingValue(0x1);
1147       break;
1148     case Untyped32:
1149       if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) {
1150         SetEncodingValue(0x2);
1151       } else if (align.Is(k128BitAlign)) {
1152         SetEncodingValue(0x3);
1153       }
1154       break;
1155     default:
1156       break;
1157   }
1158 }
1159 
1160 class Dt_size_9 : public EncodingValue {
1161   uint32_t type_;
1162 
1163  public:
1164   explicit Dt_size_9(DataType dt);
GetTypeEncodingValue() const1165   uint32_t GetTypeEncodingValue() const { return type_; }
1166 };
1167 
Dt_size_9(DataType dt)1168 Dt_size_9::Dt_size_9(DataType dt) {
1169   switch (dt.GetValue()) {
1170     case I16:
1171       type_ = 0x0;
1172       SetEncodingValue(0x1);
1173       break;
1174     case I32:
1175       type_ = 0x0;
1176       SetEncodingValue(0x2);
1177       break;
1178     case F32:
1179       type_ = 0x1;
1180       SetEncodingValue(0x2);
1181       break;
1182     default:
1183       VIXL_UNREACHABLE();
1184       type_ = 0x0;
1185       break;
1186   }
1187 }
1188 
1189 class Dt_size_10 : public EncodingValue {
1190  public:
1191   explicit Dt_size_10(DataType dt);
1192 };
1193 
Dt_size_10(DataType dt)1194 Dt_size_10::Dt_size_10(DataType dt) {
1195   switch (dt.GetValue()) {
1196     case S8:
1197     case U8:
1198     case I8:
1199       SetEncodingValue(0x0);
1200       break;
1201     case S16:
1202     case U16:
1203     case I16:
1204       SetEncodingValue(0x1);
1205       break;
1206     case S32:
1207     case U32:
1208     case I32:
1209       SetEncodingValue(0x2);
1210       break;
1211     default:
1212       break;
1213   }
1214 }
1215 
1216 class Dt_size_11 : public EncodingValue {
1217   uint32_t type_;
1218 
1219  public:
1220   explicit Dt_size_11(DataType dt);
GetTypeEncodingValue() const1221   uint32_t GetTypeEncodingValue() const { return type_; }
1222 };
1223 
Dt_size_11(DataType dt)1224 Dt_size_11::Dt_size_11(DataType dt) {
1225   switch (dt.GetValue()) {
1226     case S16:
1227       type_ = 0x0;
1228       SetEncodingValue(0x1);
1229       break;
1230     case U16:
1231       type_ = 0x1;
1232       SetEncodingValue(0x1);
1233       break;
1234     case S32:
1235       type_ = 0x0;
1236       SetEncodingValue(0x2);
1237       break;
1238     case U32:
1239       type_ = 0x1;
1240       SetEncodingValue(0x2);
1241       break;
1242     default:
1243       VIXL_UNREACHABLE();
1244       type_ = 0x0;
1245       break;
1246   }
1247 }
1248 
1249 class Dt_size_12 : public EncodingValue {
1250   uint32_t type_;
1251 
1252  public:
1253   explicit Dt_size_12(DataType dt);
GetTypeEncodingValue() const1254   uint32_t GetTypeEncodingValue() const { return type_; }
1255 };
1256 
Dt_size_12(DataType dt)1257 Dt_size_12::Dt_size_12(DataType dt) {
1258   switch (dt.GetValue()) {
1259     case S8:
1260       type_ = 0x0;
1261       SetEncodingValue(0x0);
1262       break;
1263     case U8:
1264       type_ = 0x1;
1265       SetEncodingValue(0x0);
1266       break;
1267     case S16:
1268       type_ = 0x0;
1269       SetEncodingValue(0x1);
1270       break;
1271     case U16:
1272       type_ = 0x1;
1273       SetEncodingValue(0x1);
1274       break;
1275     case S32:
1276       type_ = 0x0;
1277       SetEncodingValue(0x2);
1278       break;
1279     case U32:
1280       type_ = 0x1;
1281       SetEncodingValue(0x2);
1282       break;
1283     default:
1284       VIXL_UNREACHABLE();
1285       type_ = 0x0;
1286       break;
1287   }
1288 }
1289 
1290 class Dt_size_13 : public EncodingValue {
1291  public:
1292   explicit Dt_size_13(DataType dt);
1293 };
1294 
Dt_size_13(DataType dt)1295 Dt_size_13::Dt_size_13(DataType dt) {
1296   switch (dt.GetValue()) {
1297     case S16:
1298       SetEncodingValue(0x1);
1299       break;
1300     case S32:
1301       SetEncodingValue(0x2);
1302       break;
1303     default:
1304       break;
1305   }
1306 }
1307 
1308 class Dt_size_14 : public EncodingValue {
1309  public:
1310   explicit Dt_size_14(DataType dt);
1311 };
1312 
Dt_size_14(DataType dt)1313 Dt_size_14::Dt_size_14(DataType dt) {
1314   switch (dt.GetValue()) {
1315     case S16:
1316       SetEncodingValue(0x0);
1317       break;
1318     case S32:
1319       SetEncodingValue(0x1);
1320       break;
1321     case S64:
1322       SetEncodingValue(0x2);
1323       break;
1324     default:
1325       break;
1326   }
1327 }
1328 
1329 class Dt_size_15 : public EncodingValue {
1330  public:
1331   explicit Dt_size_15(DataType dt);
1332 };
1333 
Dt_size_15(DataType dt)1334 Dt_size_15::Dt_size_15(DataType dt) {
1335   switch (dt.GetValue()) {
1336     case Untyped8:
1337       SetEncodingValue(0x0);
1338       break;
1339     case Untyped16:
1340       SetEncodingValue(0x1);
1341       break;
1342     default:
1343       break;
1344   }
1345 }
1346 
1347 class Dt_size_16 : public EncodingValue {
1348  public:
1349   explicit Dt_size_16(DataType dt);
1350 };
1351 
Dt_size_16(DataType dt)1352 Dt_size_16::Dt_size_16(DataType dt) {
1353   switch (dt.GetValue()) {
1354     case I8:
1355       SetEncodingValue(0x0);
1356       break;
1357     case I16:
1358       SetEncodingValue(0x1);
1359       break;
1360     case I32:
1361       SetEncodingValue(0x2);
1362       break;
1363     default:
1364       break;
1365   }
1366 }
1367 
1368 class Index_1 : public EncodingValue {
1369  public:
1370   Index_1(const NeonRegisterList& nreglist, DataType dt);
1371 };
1372 
Index_1(const NeonRegisterList & nreglist,DataType dt)1373 Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) {
1374   switch (dt.GetValue()) {
1375     case Untyped8: {
1376       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1377         return;
1378       }
1379       uint32_t value = nreglist.GetTransferLane() << 1;
1380       if (!nreglist.IsSingleSpaced()) return;
1381       SetEncodingValue(value);
1382       break;
1383     }
1384     case Untyped16: {
1385       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1386         return;
1387       }
1388       uint32_t value = nreglist.GetTransferLane() << 2;
1389       if (nreglist.IsDoubleSpaced()) value |= 2;
1390       SetEncodingValue(value);
1391       break;
1392     }
1393     case Untyped32: {
1394       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1395         return;
1396       }
1397       uint32_t value = nreglist.GetTransferLane() << 3;
1398       if (nreglist.IsDoubleSpaced()) value |= 4;
1399       SetEncodingValue(value);
1400       break;
1401     }
1402     default:
1403       break;
1404   }
1405 }
1406 
1407 class Align_index_align_1 : public EncodingValue {
1408  public:
1409   Align_index_align_1(Alignment align,
1410                       const NeonRegisterList& nreglist,
1411                       DataType dt);
1412 };
1413 
Align_index_align_1(Alignment align,const NeonRegisterList & nreglist,DataType dt)1414 Align_index_align_1::Align_index_align_1(Alignment align,
1415                                          const NeonRegisterList& nreglist,
1416                                          DataType dt) {
1417   switch (dt.GetValue()) {
1418     case Untyped8: {
1419       uint32_t value;
1420       if (align.GetType() == kNoAlignment) {
1421         value = 0;
1422       } else {
1423         return;
1424       }
1425       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1426         return;
1427       }
1428       value |= nreglist.GetTransferLane() << 1;
1429       SetEncodingValue(value);
1430       break;
1431     }
1432     case Untyped16: {
1433       uint32_t value;
1434       if (align.GetType() == k16BitAlign) {
1435         value = 1;
1436       } else if (align.GetType() == kNoAlignment) {
1437         value = 0;
1438       } else {
1439         return;
1440       }
1441       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1442         return;
1443       }
1444       value |= nreglist.GetTransferLane() << 2;
1445       SetEncodingValue(value);
1446       break;
1447     }
1448     case Untyped32: {
1449       uint32_t value;
1450       if (align.GetType() == k32BitAlign) {
1451         value = 3;
1452       } else if (align.GetType() == kNoAlignment) {
1453         value = 0;
1454       } else {
1455         return;
1456       }
1457       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1458         return;
1459       }
1460       value |= nreglist.GetTransferLane() << 3;
1461       SetEncodingValue(value);
1462       break;
1463     }
1464     default:
1465       break;
1466   }
1467 }
1468 
1469 class Align_index_align_2 : public EncodingValue {
1470  public:
1471   Align_index_align_2(Alignment align,
1472                       const NeonRegisterList& nreglist,
1473                       DataType dt);
1474 };
1475 
Align_index_align_2(Alignment align,const NeonRegisterList & nreglist,DataType dt)1476 Align_index_align_2::Align_index_align_2(Alignment align,
1477                                          const NeonRegisterList& nreglist,
1478                                          DataType dt) {
1479   switch (dt.GetValue()) {
1480     case Untyped8: {
1481       uint32_t value;
1482       if (align.GetType() == k16BitAlign) {
1483         value = 1;
1484       } else if (align.GetType() == kNoAlignment) {
1485         value = 0;
1486       } else {
1487         return;
1488       }
1489       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1490         return;
1491       }
1492       value |= nreglist.GetTransferLane() << 1;
1493       if (!nreglist.IsSingleSpaced()) return;
1494       SetEncodingValue(value);
1495       break;
1496     }
1497     case Untyped16: {
1498       uint32_t value;
1499       if (align.GetType() == k32BitAlign) {
1500         value = 1;
1501       } else if (align.GetType() == kNoAlignment) {
1502         value = 0;
1503       } else {
1504         return;
1505       }
1506       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1507         return;
1508       }
1509       value |= nreglist.GetTransferLane() << 2;
1510       if (nreglist.IsDoubleSpaced()) value |= 2;
1511       SetEncodingValue(value);
1512       break;
1513     }
1514     case Untyped32: {
1515       uint32_t value;
1516       if (align.GetType() == k64BitAlign) {
1517         value = 1;
1518       } else if (align.GetType() == kNoAlignment) {
1519         value = 0;
1520       } else {
1521         return;
1522       }
1523       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1524         return;
1525       }
1526       value |= nreglist.GetTransferLane() << 3;
1527       if (nreglist.IsDoubleSpaced()) value |= 4;
1528       SetEncodingValue(value);
1529       break;
1530     }
1531     default:
1532       break;
1533   }
1534 }
1535 
1536 class Align_index_align_3 : public EncodingValue {
1537  public:
1538   Align_index_align_3(Alignment align,
1539                       const NeonRegisterList& nreglist,
1540                       DataType dt);
1541 };
1542 
Align_index_align_3(Alignment align,const NeonRegisterList & nreglist,DataType dt)1543 Align_index_align_3::Align_index_align_3(Alignment align,
1544                                          const NeonRegisterList& nreglist,
1545                                          DataType dt) {
1546   switch (dt.GetValue()) {
1547     case Untyped8: {
1548       uint32_t value;
1549       if (align.GetType() == k32BitAlign) {
1550         value = 1;
1551       } else if (align.GetType() == kNoAlignment) {
1552         value = 0;
1553       } else {
1554         return;
1555       }
1556       if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1557         return;
1558       }
1559       value |= nreglist.GetTransferLane() << 1;
1560       if (!nreglist.IsSingleSpaced()) return;
1561       SetEncodingValue(value);
1562       break;
1563     }
1564     case Untyped16: {
1565       uint32_t value;
1566       if (align.GetType() == k64BitAlign) {
1567         value = 1;
1568       } else if (align.GetType() == kNoAlignment) {
1569         value = 0;
1570       } else {
1571         return;
1572       }
1573       if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1574         return;
1575       }
1576       value |= nreglist.GetTransferLane() << 2;
1577       if (nreglist.IsDoubleSpaced()) value |= 2;
1578       SetEncodingValue(value);
1579       break;
1580     }
1581     case Untyped32: {
1582       uint32_t value;
1583       if (align.GetType() == k64BitAlign) {
1584         value = 1;
1585       } else if (align.GetType() == k128BitAlign) {
1586         value = 2;
1587       } else if (align.GetType() == kNoAlignment) {
1588         value = 0;
1589       } else {
1590         return;
1591       }
1592       if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1593         return;
1594       }
1595       value |= nreglist.GetTransferLane() << 3;
1596       if (nreglist.IsDoubleSpaced()) value |= 4;
1597       SetEncodingValue(value);
1598       break;
1599     }
1600     default:
1601       break;
1602   }
1603 }
1604 
1605 class Align_a_1 : public EncodingValue {
1606  public:
1607   Align_a_1(Alignment align, DataType dt);
1608 };
1609 
Align_a_1(Alignment align,DataType dt)1610 Align_a_1::Align_a_1(Alignment align, DataType dt) {
1611   switch (align.GetType()) {
1612     case k16BitAlign:
1613       if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1614       break;
1615     case k32BitAlign:
1616       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1617       break;
1618     case kNoAlignment:
1619       SetEncodingValue(0x0);
1620       break;
1621     default:
1622       break;
1623   }
1624 }
1625 
1626 class Align_a_2 : public EncodingValue {
1627  public:
1628   Align_a_2(Alignment align, DataType dt);
1629 };
1630 
Align_a_2(Alignment align,DataType dt)1631 Align_a_2::Align_a_2(Alignment align, DataType dt) {
1632   switch (align.GetType()) {
1633     case k16BitAlign:
1634       if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1635       break;
1636     case k32BitAlign:
1637       if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1638       break;
1639     case k64BitAlign:
1640       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1641       break;
1642     case kNoAlignment:
1643       SetEncodingValue(0x0);
1644       break;
1645     default:
1646       break;
1647   }
1648 }
1649 
1650 class Align_a_3 : public EncodingValue {
1651  public:
1652   Align_a_3(Alignment align, DataType dt);
1653 };
1654 
Align_a_3(Alignment align,DataType dt)1655 Align_a_3::Align_a_3(Alignment align, DataType dt) {
1656   switch (align.GetType()) {
1657     case k32BitAlign:
1658       if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1659       break;
1660     case k64BitAlign:
1661       if (dt.Is(Untyped16))
1662         SetEncodingValue(0x1);
1663       else if (dt.Is(Untyped32))
1664         SetEncodingValue(0x1);
1665       break;
1666     case k128BitAlign:
1667       if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1668       break;
1669     case kNoAlignment:
1670       SetEncodingValue(0x0);
1671       break;
1672     default:
1673       break;
1674   }
1675 }
1676 
1677 class Align_align_1 : public EncodingValue {
1678  public:
1679   Align_align_1(Alignment align, const NeonRegisterList& nreglist);
1680 };
1681 
Align_align_1(Alignment align,const NeonRegisterList & nreglist)1682 Align_align_1::Align_align_1(Alignment align,
1683                              const NeonRegisterList& nreglist) {
1684   switch (align.GetType()) {
1685     case k64BitAlign:
1686       SetEncodingValue(0x1);
1687       break;
1688     case k128BitAlign:
1689       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1690         SetEncodingValue(0x2);
1691       break;
1692     case k256BitAlign:
1693       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1694         SetEncodingValue(0x3);
1695       break;
1696     case kNoAlignment:
1697       SetEncodingValue(0x0);
1698       break;
1699     default:
1700       break;
1701   }
1702 }
1703 
1704 class Align_align_2 : public EncodingValue {
1705  public:
1706   Align_align_2(Alignment align, const NeonRegisterList& nreglist);
1707 };
1708 
Align_align_2(Alignment align,const NeonRegisterList & nreglist)1709 Align_align_2::Align_align_2(Alignment align,
1710                              const NeonRegisterList& nreglist) {
1711   switch (align.GetType()) {
1712     case k64BitAlign:
1713       SetEncodingValue(0x1);
1714       break;
1715     case k128BitAlign:
1716       SetEncodingValue(0x2);
1717       break;
1718     case k256BitAlign:
1719       if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1720       break;
1721     case kNoAlignment:
1722       SetEncodingValue(0x0);
1723       break;
1724     default:
1725       break;
1726   }
1727 }
1728 
1729 class Align_align_3 : public EncodingValue {
1730  public:
1731   explicit Align_align_3(Alignment align);
1732 };
1733 
Align_align_3(Alignment align)1734 Align_align_3::Align_align_3(Alignment align) {
1735   switch (align.GetType()) {
1736     case k64BitAlign:
1737       SetEncodingValue(0x1);
1738       break;
1739     case kNoAlignment:
1740       SetEncodingValue(0x0);
1741       break;
1742     default:
1743       break;
1744   }
1745 }
1746 
1747 class Align_align_4 : public EncodingValue {
1748  public:
1749   explicit Align_align_4(Alignment align);
1750 };
1751 
Align_align_4(Alignment align)1752 Align_align_4::Align_align_4(Alignment align) {
1753   switch (align.GetType()) {
1754     case k64BitAlign:
1755       SetEncodingValue(0x1);
1756       break;
1757     case k128BitAlign:
1758       SetEncodingValue(0x2);
1759       break;
1760     case k256BitAlign:
1761       SetEncodingValue(0x3);
1762       break;
1763     case kNoAlignment:
1764       SetEncodingValue(0x0);
1765       break;
1766     default:
1767       break;
1768   }
1769 }
1770 
1771 class Align_align_5 : public EncodingValue {
1772  public:
1773   Align_align_5(Alignment align, const NeonRegisterList& nreglist);
1774 };
1775 
Align_align_5(Alignment align,const NeonRegisterList & nreglist)1776 Align_align_5::Align_align_5(Alignment align,
1777                              const NeonRegisterList& nreglist) {
1778   switch (align.GetType()) {
1779     case k64BitAlign:
1780       SetEncodingValue(0x1);
1781       break;
1782     case k128BitAlign:
1783       if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1784         SetEncodingValue(0x2);
1785       break;
1786     case k256BitAlign:
1787       if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1788       break;
1789     case kNoAlignment:
1790       SetEncodingValue(0x0);
1791       break;
1792     default:
1793       break;
1794   }
1795 }
1796 
1797 
adc(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)1798 void Assembler::adc(Condition cond,
1799                     EncodingSize size,
1800                     Register rd,
1801                     Register rn,
1802                     const Operand& operand) {
1803   VIXL_ASSERT(AllowAssembler());
1804   CheckIT(cond);
1805   if (operand.IsImmediate()) {
1806     uint32_t imm = operand.GetImmediate();
1807     if (IsUsingT32()) {
1808       ImmediateT32 immediate_t32(imm);
1809       // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
1810       if (!size.IsNarrow() && immediate_t32.IsValid() &&
1811           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
1812         EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1813                    (immediate_t32.GetEncodingValue() & 0xff) |
1814                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
1815                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
1816         AdvanceIT();
1817         return;
1818       }
1819     } else {
1820       ImmediateA32 immediate_a32(imm);
1821       // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
1822       if (immediate_a32.IsValid() && cond.IsNotNever()) {
1823         EmitA32(0x02a00000U | (cond.GetCondition() << 28) |
1824                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
1825                 immediate_a32.GetEncodingValue());
1826         return;
1827       }
1828     }
1829   }
1830   if (operand.IsImmediateShiftedRegister()) {
1831     Register rm = operand.GetBaseRegister();
1832     if (operand.IsPlainRegister()) {
1833       if (IsUsingT32()) {
1834         // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
1835         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1836             rm.IsLow()) {
1837           EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
1838           AdvanceIT();
1839           return;
1840         }
1841       }
1842     }
1843     Shift shift = operand.GetShift();
1844     uint32_t amount = operand.GetShiftAmount();
1845     if (IsUsingT32()) {
1846       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
1847       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
1848           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
1849         uint32_t amount_ = amount % 32;
1850         EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1851                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
1852                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
1853         AdvanceIT();
1854         return;
1855       }
1856     } else {
1857       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
1858       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
1859         uint32_t amount_ = amount % 32;
1860         EmitA32(0x00a00000U | (cond.GetCondition() << 28) |
1861                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1862                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
1863         return;
1864       }
1865     }
1866   }
1867   if (operand.IsRegisterShiftedRegister()) {
1868     Register rm = operand.GetBaseRegister();
1869     Shift shift = operand.GetShift();
1870     if (IsUsingA32()) {
1871       // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
1872       if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
1873                                  !operand.GetShiftRegister().IsPC()) ||
1874                                 AllowUnpredictable())) {
1875         EmitA32(0x00a00010U | (cond.GetCondition() << 28) |
1876                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1877                 (shift.GetType() << 5) |
1878                 (operand.GetShiftRegister().GetCode() << 8));
1879         return;
1880       }
1881     }
1882   }
1883   Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand);
1884 }
1885 
adcs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)1886 void Assembler::adcs(Condition cond,
1887                      EncodingSize size,
1888                      Register rd,
1889                      Register rn,
1890                      const Operand& operand) {
1891   VIXL_ASSERT(AllowAssembler());
1892   CheckIT(cond);
1893   if (operand.IsImmediate()) {
1894     uint32_t imm = operand.GetImmediate();
1895     if (IsUsingT32()) {
1896       ImmediateT32 immediate_t32(imm);
1897       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
1898       if (!size.IsNarrow() && immediate_t32.IsValid() &&
1899           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
1900         EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1901                    (immediate_t32.GetEncodingValue() & 0xff) |
1902                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
1903                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
1904         AdvanceIT();
1905         return;
1906       }
1907     } else {
1908       ImmediateA32 immediate_a32(imm);
1909       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
1910       if (immediate_a32.IsValid() && cond.IsNotNever()) {
1911         EmitA32(0x02b00000U | (cond.GetCondition() << 28) |
1912                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
1913                 immediate_a32.GetEncodingValue());
1914         return;
1915       }
1916     }
1917   }
1918   if (operand.IsImmediateShiftedRegister()) {
1919     Register rm = operand.GetBaseRegister();
1920     if (operand.IsPlainRegister()) {
1921       if (IsUsingT32()) {
1922         // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
1923         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1924             rm.IsLow()) {
1925           EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
1926           AdvanceIT();
1927           return;
1928         }
1929       }
1930     }
1931     Shift shift = operand.GetShift();
1932     uint32_t amount = operand.GetShiftAmount();
1933     if (IsUsingT32()) {
1934       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
1935       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
1936           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
1937         uint32_t amount_ = amount % 32;
1938         EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1939                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
1940                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
1941         AdvanceIT();
1942         return;
1943       }
1944     } else {
1945       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
1946       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
1947         uint32_t amount_ = amount % 32;
1948         EmitA32(0x00b00000U | (cond.GetCondition() << 28) |
1949                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1950                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
1951         return;
1952       }
1953     }
1954   }
1955   if (operand.IsRegisterShiftedRegister()) {
1956     Register rm = operand.GetBaseRegister();
1957     Shift shift = operand.GetShift();
1958     if (IsUsingA32()) {
1959       // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
1960       if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
1961                                  !operand.GetShiftRegister().IsPC()) ||
1962                                 AllowUnpredictable())) {
1963         EmitA32(0x00b00010U | (cond.GetCondition() << 28) |
1964                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1965                 (shift.GetType() << 5) |
1966                 (operand.GetShiftRegister().GetCode() << 8));
1967         return;
1968       }
1969     }
1970   }
1971   Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand);
1972 }
1973 
add(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)1974 void Assembler::add(Condition cond,
1975                     EncodingSize size,
1976                     Register rd,
1977                     Register rn,
1978                     const Operand& operand) {
1979   VIXL_ASSERT(AllowAssembler());
1980   CheckIT(cond);
1981   if (operand.IsImmediate()) {
1982     uint32_t imm = operand.GetImmediate();
1983     if (IsUsingT32()) {
1984       ImmediateT32 immediate_t32(imm);
1985       // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1
1986       if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) &&
1987           ((imm % 4) == 0)) {
1988         uint32_t imm_ = imm >> 2;
1989         EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_);
1990         AdvanceIT();
1991         return;
1992       }
1993       // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
1994       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
1995           (imm <= 7)) {
1996         EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
1997         AdvanceIT();
1998         return;
1999       }
2000       // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
2001       if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2002           (imm <= 255)) {
2003         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2004         AdvanceIT();
2005         return;
2006       }
2007       // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1
2008       if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) &&
2009           ((imm % 4) == 0)) {
2010         uint32_t imm_ = imm >> 2;
2011         EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_);
2012         AdvanceIT();
2013         return;
2014       }
2015       // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2
2016       if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
2017           ((imm % 4) == 0)) {
2018         uint32_t imm_ = imm >> 2;
2019         EmitT32_16(0xb000 | imm_);
2020         AdvanceIT();
2021         return;
2022       }
2023       // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2024       if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
2025           (!rd.IsPC() || AllowUnpredictable())) {
2026         EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2027                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2028         AdvanceIT();
2029         return;
2030       }
2031       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2032       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
2033           ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
2034         EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2035                    (immediate_t32.GetEncodingValue() & 0xff) |
2036                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2037                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2038         AdvanceIT();
2039         return;
2040       }
2041       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2042       if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
2043           (!rd.IsPC() || AllowUnpredictable())) {
2044         EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2045                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2046         AdvanceIT();
2047         return;
2048       }
2049       // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2050       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
2051           (!rd.IsPC() || AllowUnpredictable())) {
2052         EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) |
2053                    (immediate_t32.GetEncodingValue() & 0xff) |
2054                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2055                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2056         AdvanceIT();
2057         return;
2058       }
2059       // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2060       if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
2061           (!rd.IsPC() || AllowUnpredictable())) {
2062         EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2063                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2064         AdvanceIT();
2065         return;
2066       }
2067     } else {
2068       ImmediateA32 immediate_a32(imm);
2069       // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1
2070       if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
2071         EmitA32(0x028f0000U | (cond.GetCondition() << 28) |
2072                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2073         return;
2074       }
2075       // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2076       if (immediate_a32.IsValid() && cond.IsNotNever() &&
2077           ((rn.GetCode() & 0xd) != 0xd)) {
2078         EmitA32(0x02800000U | (cond.GetCondition() << 28) |
2079                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2080                 immediate_a32.GetEncodingValue());
2081         return;
2082       }
2083       // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2084       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2085         EmitA32(0x028d0000U | (cond.GetCondition() << 28) |
2086                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2087         return;
2088       }
2089     }
2090   }
2091   if (operand.IsImmediateShiftedRegister()) {
2092     Register rm = operand.GetBaseRegister();
2093     if (operand.IsPlainRegister()) {
2094       if (IsUsingT32()) {
2095         // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
2096         if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2097             rm.IsLow()) {
2098           EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2099                      (rm.GetCode() << 6));
2100           AdvanceIT();
2101           return;
2102         }
2103         // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2
2104         if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) &&
2105             (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
2106               (!rd.IsPC() || !rm.IsPC())) ||
2107              AllowUnpredictable())) {
2108           EmitT32_16(0x4400 | (rd.GetCode() & 0x7) |
2109                      ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
2110           AdvanceIT();
2111           return;
2112         }
2113         // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1
2114         if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) &&
2115             ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
2116              AllowUnpredictable())) {
2117           EmitT32_16(0x4468 | (rd.GetCode() & 0x7) |
2118                      ((rd.GetCode() & 0x8) << 4));
2119           AdvanceIT();
2120           return;
2121         }
2122         // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2
2123         if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) {
2124           EmitT32_16(0x4485 | (rm.GetCode() << 3));
2125           AdvanceIT();
2126           return;
2127         }
2128       }
2129     }
2130     Shift shift = operand.GetShift();
2131     uint32_t amount = operand.GetShiftAmount();
2132     if (IsUsingT32()) {
2133       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2134       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
2135           ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2136         uint32_t amount_ = amount % 32;
2137         EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2138                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2139                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2140         AdvanceIT();
2141         return;
2142       }
2143       // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2144       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
2145           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2146         uint32_t amount_ = amount % 32;
2147         EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2148                    (operand.GetTypeEncodingValue() << 4) |
2149                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2150         AdvanceIT();
2151         return;
2152       }
2153     } else {
2154       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2155       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2156         uint32_t amount_ = amount % 32;
2157         EmitA32(0x00800000U | (cond.GetCondition() << 28) |
2158                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2159                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2160         return;
2161       }
2162       // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2163       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2164         uint32_t amount_ = amount % 32;
2165         EmitA32(0x008d0000U | (cond.GetCondition() << 28) |
2166                 (rd.GetCode() << 12) | rm.GetCode() |
2167                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2168         return;
2169       }
2170     }
2171   }
2172   if (operand.IsRegisterShiftedRegister()) {
2173     Register rm = operand.GetBaseRegister();
2174     Shift shift = operand.GetShift();
2175     if (IsUsingA32()) {
2176       // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2177       if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
2178                                  !operand.GetShiftRegister().IsPC()) ||
2179                                 AllowUnpredictable())) {
2180         EmitA32(0x00800010U | (cond.GetCondition() << 28) |
2181                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2182                 (shift.GetType() << 5) |
2183                 (operand.GetShiftRegister().GetCode() << 8));
2184         return;
2185       }
2186     }
2187   }
2188   Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand);
2189 }
2190 
add(Condition cond,Register rd,const Operand & operand)2191 void Assembler::add(Condition cond, Register rd, const Operand& operand) {
2192   VIXL_ASSERT(AllowAssembler());
2193   CheckIT(cond);
2194   if (operand.IsImmediate()) {
2195     uint32_t imm = operand.GetImmediate();
2196     if (IsUsingT32()) {
2197       // ADD<c>{<q>} <Rdn>, #<imm8> ; T2
2198       if (InITBlock() && rd.IsLow() && (imm <= 255)) {
2199         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2200         AdvanceIT();
2201         return;
2202       }
2203     }
2204   }
2205   if (operand.IsPlainRegister()) {
2206     Register rm = operand.GetBaseRegister();
2207     if (IsUsingT32()) {
2208       // ADD<c>{<q>} <Rdn>, <Rm> ; T2
2209       if (InITBlock() && !rm.Is(sp) &&
2210           (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
2211             (!rd.IsPC() || !rm.IsPC())) ||
2212            AllowUnpredictable())) {
2213         EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) |
2214                    (rm.GetCode() << 3));
2215         AdvanceIT();
2216         return;
2217       }
2218     }
2219   }
2220   Delegate(kAdd, &Assembler::add, cond, rd, operand);
2221 }
2222 
adds(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2223 void Assembler::adds(Condition cond,
2224                      EncodingSize size,
2225                      Register rd,
2226                      Register rn,
2227                      const Operand& operand) {
2228   VIXL_ASSERT(AllowAssembler());
2229   CheckIT(cond);
2230   if (operand.IsImmediate()) {
2231     uint32_t imm = operand.GetImmediate();
2232     if (IsUsingT32()) {
2233       ImmediateT32 immediate_t32(imm);
2234       // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1
2235       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2236           (imm <= 7)) {
2237         EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
2238         AdvanceIT();
2239         return;
2240       }
2241       // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
2242       if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2243           (imm <= 255)) {
2244         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2245         AdvanceIT();
2246         return;
2247       }
2248       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2249       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
2250           !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) {
2251         EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2252                    (immediate_t32.GetEncodingValue() & 0xff) |
2253                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2254                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2255         AdvanceIT();
2256         return;
2257       }
2258       // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2259       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
2260           !rd.Is(pc)) {
2261         EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) |
2262                    (immediate_t32.GetEncodingValue() & 0xff) |
2263                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2264                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2265         AdvanceIT();
2266         return;
2267       }
2268     } else {
2269       ImmediateA32 immediate_a32(imm);
2270       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2271       if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
2272         EmitA32(0x02900000U | (cond.GetCondition() << 28) |
2273                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2274                 immediate_a32.GetEncodingValue());
2275         return;
2276       }
2277       // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2278       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2279         EmitA32(0x029d0000U | (cond.GetCondition() << 28) |
2280                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2281         return;
2282       }
2283     }
2284   }
2285   if (operand.IsImmediateShiftedRegister()) {
2286     Register rm = operand.GetBaseRegister();
2287     if (operand.IsPlainRegister()) {
2288       if (IsUsingT32()) {
2289         // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
2290         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2291             rm.IsLow()) {
2292           EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2293                      (rm.GetCode() << 6));
2294           AdvanceIT();
2295           return;
2296         }
2297       }
2298     }
2299     Shift shift = operand.GetShift();
2300     uint32_t amount = operand.GetShiftAmount();
2301     if (IsUsingT32()) {
2302       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2303       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
2304           !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2305         uint32_t amount_ = amount % 32;
2306         EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2307                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2308                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2309         AdvanceIT();
2310         return;
2311       }
2312       // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2313       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
2314           !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) {
2315         uint32_t amount_ = amount % 32;
2316         EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2317                    (operand.GetTypeEncodingValue() << 4) |
2318                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2319         AdvanceIT();
2320         return;
2321       }
2322     } else {
2323       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2324       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2325         uint32_t amount_ = amount % 32;
2326         EmitA32(0x00900000U | (cond.GetCondition() << 28) |
2327                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2328                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2329         return;
2330       }
2331       // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2332       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2333         uint32_t amount_ = amount % 32;
2334         EmitA32(0x009d0000U | (cond.GetCondition() << 28) |
2335                 (rd.GetCode() << 12) | rm.GetCode() |
2336                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2337         return;
2338       }
2339     }
2340   }
2341   if (operand.IsRegisterShiftedRegister()) {
2342     Register rm = operand.GetBaseRegister();
2343     Shift shift = operand.GetShift();
2344     if (IsUsingA32()) {
2345       // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2346       if (cond.IsNotNever() && ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() &&
2347                                  !operand.GetShiftRegister().IsPC()) ||
2348                                 AllowUnpredictable())) {
2349         EmitA32(0x00900010U | (cond.GetCondition() << 28) |
2350                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2351                 (shift.GetType() << 5) |
2352                 (operand.GetShiftRegister().GetCode() << 8));
2353         return;
2354       }
2355     }
2356   }
2357   Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand);
2358 }
2359 
adds(Register rd,const Operand & operand)2360 void Assembler::adds(Register rd, const Operand& operand) {
2361   VIXL_ASSERT(AllowAssembler());
2362   CheckIT(al);
2363   if (operand.IsImmediate()) {
2364     uint32_t imm = operand.GetImmediate();
2365     if (IsUsingT32()) {
2366       // ADDS{<q>} <Rdn>, #<imm8> ; T2
2367       if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
2368         EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2369         AdvanceIT();
2370         return;
2371       }
2372     }
2373   }
2374   Delegate(kAdds, &Assembler::adds, rd, operand);
2375 }
2376 
addw(Condition cond,Register rd,Register rn,const Operand & operand)2377 void Assembler::addw(Condition cond,
2378                      Register rd,
2379                      Register rn,
2380                      const Operand& operand) {
2381   VIXL_ASSERT(AllowAssembler());
2382   CheckIT(cond);
2383   if (operand.IsImmediate()) {
2384     uint32_t imm = operand.GetImmediate();
2385     if (IsUsingT32()) {
2386       // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2387       if (rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2388         EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2389                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2390         AdvanceIT();
2391         return;
2392       }
2393       // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2394       if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
2395           (!rd.IsPC() || AllowUnpredictable())) {
2396         EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2397                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2398         AdvanceIT();
2399         return;
2400       }
2401       // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2402       if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2403         EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2404                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2405         AdvanceIT();
2406         return;
2407       }
2408     }
2409   }
2410   Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand);
2411 }
2412 
adr(Condition cond,EncodingSize size,Register rd,Label * label)2413 void Assembler::adr(Condition cond,
2414                     EncodingSize size,
2415                     Register rd,
2416                     Label* label) {
2417   VIXL_ASSERT(AllowAssembler());
2418   CheckIT(cond);
2419   Label::Offset offset =
2420       label->IsBound()
2421           ? label->GetLocation() -
2422                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
2423           : 0;
2424   if (IsUsingT32()) {
2425     int32_t neg_offset = -offset;
2426     // ADR{<c>}{<q>} <Rd>, <label> ; T1
2427     if (!size.IsWide() && rd.IsLow() &&
2428         ((label->IsBound() && (offset >= 0) && (offset <= 1020) &&
2429           ((offset & 0x3) == 0)) ||
2430          (!label->IsBound() && size.IsNarrow()))) {
2431       static class EmitOp : public Label::LabelEmitOperator {
2432        public:
2433         EmitOp() : Label::LabelEmitOperator(0, 1020) {}
2434         virtual uint32_t Encode(uint32_t instr,
2435                                 Label::Offset pc,
2436                                 const Label* label) const VIXL_OVERRIDE {
2437           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2438           VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
2439                       ((offset & 0x3) == 0));
2440           const int32_t target = offset >> 2;
2441           return instr | (target & 0xff);
2442         }
2443       } immop;
2444       EmitT32_16(Link(0xa000 | (rd.GetCode() << 8), label, immop));
2445       AdvanceIT();
2446       return;
2447     }
2448     // ADR{<c>}{<q>} <Rd>, <label> ; T2
2449     if (!size.IsNarrow() && label->IsBound() && (neg_offset > 0) &&
2450         (neg_offset <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2451       EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) |
2452                  ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15));
2453       AdvanceIT();
2454       return;
2455     }
2456     // ADR{<c>}{<q>} <Rd>, <label> ; T3
2457     if (!size.IsNarrow() &&
2458         (!label->IsBound() || ((offset >= 0) && (offset <= 4095))) &&
2459         (!rd.IsPC() || AllowUnpredictable())) {
2460       static class EmitOp : public Label::LabelEmitOperator {
2461        public:
2462         EmitOp() : Label::LabelEmitOperator(0, 4095) {}
2463         virtual uint32_t Encode(uint32_t instr,
2464                                 Label::Offset pc,
2465                                 const Label* label) const VIXL_OVERRIDE {
2466           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2467           int32_t target;
2468           if ((offset >= 0) && (offset <= 4095) && !label->IsMinusZero()) {
2469             target = offset;
2470           } else {
2471             target = -offset;
2472             VIXL_ASSERT((target >= 0) && (target <= 4095));
2473             // Emit the T2 encoding.
2474             instr |= 0x00a00000;
2475           }
2476           return instr | (target & 0xff) | ((target & 0x700) << 4) |
2477                  ((target & 0x800) << 15);
2478         }
2479       } immop;
2480       EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8), label, immop));
2481       AdvanceIT();
2482       return;
2483     }
2484   } else {
2485     ImmediateA32 positive_immediate_a32(offset);
2486     ImmediateA32 negative_immediate_a32(-offset);
2487     // ADR{<c>}{<q>} <Rd>, <label> ; A1
2488     if ((!label->IsBound() || positive_immediate_a32.IsValid()) &&
2489         cond.IsNotNever()) {
2490       static class EmitOp : public Label::LabelEmitOperator {
2491        public:
2492         EmitOp() : Label::LabelEmitOperator(0, 255) {}
2493         virtual uint32_t Encode(uint32_t instr,
2494                                 Label::Offset pc,
2495                                 const Label* label) const VIXL_OVERRIDE {
2496           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
2497           int32_t target;
2498           ImmediateA32 positive_immediate_a32(offset);
2499           if (positive_immediate_a32.IsValid()) {
2500             target = positive_immediate_a32.GetEncodingValue();
2501           } else {
2502             ImmediateA32 negative_immediate_a32(-offset);
2503             VIXL_ASSERT(negative_immediate_a32.IsValid());
2504             // Emit the A2 encoding.
2505             target = negative_immediate_a32.GetEncodingValue();
2506             instr = (instr & ~0x00f00000) | 0x00400000;
2507           }
2508           return instr | (target & 0xfff);
2509         }
2510       } immop;
2511       EmitA32(
2512           Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12),
2513                label,
2514                immop));
2515       return;
2516     }
2517     // ADR{<c>}{<q>} <Rd>, <label> ; A2
2518     if (label->IsBound() && negative_immediate_a32.IsValid() &&
2519         cond.IsNotNever()) {
2520       EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
2521               negative_immediate_a32.GetEncodingValue());
2522       return;
2523     }
2524   }
2525   Delegate(kAdr, &Assembler::adr, cond, size, rd, label);
2526 }
2527 
and_(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2528 void Assembler::and_(Condition cond,
2529                      EncodingSize size,
2530                      Register rd,
2531                      Register rn,
2532                      const Operand& operand) {
2533   VIXL_ASSERT(AllowAssembler());
2534   CheckIT(cond);
2535   if (operand.IsImmediate()) {
2536     uint32_t imm = operand.GetImmediate();
2537     if (IsUsingT32()) {
2538       ImmediateT32 immediate_t32(imm);
2539       // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2540       if (!size.IsNarrow() && immediate_t32.IsValid()) {
2541         EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2542                    (immediate_t32.GetEncodingValue() & 0xff) |
2543                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2544                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2545         AdvanceIT();
2546         return;
2547       }
2548     } else {
2549       ImmediateA32 immediate_a32(imm);
2550       // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2551       if (immediate_a32.IsValid() && cond.IsNotNever()) {
2552         EmitA32(0x02000000U | (cond.GetCondition() << 28) |
2553                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2554                 immediate_a32.GetEncodingValue());
2555         return;
2556       }
2557     }
2558   }
2559   if (operand.IsImmediateShiftedRegister()) {
2560     Register rm = operand.GetBaseRegister();
2561     if (operand.IsPlainRegister()) {
2562       if (IsUsingT32()) {
2563         // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2564         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2565             rm.IsLow()) {
2566           EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2567           AdvanceIT();
2568           return;
2569         }
2570       }
2571     }
2572     Shift shift = operand.GetShift();
2573     uint32_t amount = operand.GetShiftAmount();
2574     if (IsUsingT32()) {
2575       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2576       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
2577         uint32_t amount_ = amount % 32;
2578         EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2579                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2580                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2581         AdvanceIT();
2582         return;
2583       }
2584     } else {
2585       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2586       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2587         uint32_t amount_ = amount % 32;
2588         EmitA32(0x00000000U | (cond.GetCondition() << 28) |
2589                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2590                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2591         return;
2592       }
2593     }
2594   }
2595   if (operand.IsRegisterShiftedRegister()) {
2596     Register rm = operand.GetBaseRegister();
2597     Shift shift = operand.GetShift();
2598     if (IsUsingA32()) {
2599       // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2600       if (cond.IsNotNever()) {
2601         EmitA32(0x00000010U | (cond.GetCondition() << 28) |
2602                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2603                 (shift.GetType() << 5) |
2604                 (operand.GetShiftRegister().GetCode() << 8));
2605         return;
2606       }
2607     }
2608   }
2609   Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand);
2610 }
2611 
ands(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2612 void Assembler::ands(Condition cond,
2613                      EncodingSize size,
2614                      Register rd,
2615                      Register rn,
2616                      const Operand& operand) {
2617   VIXL_ASSERT(AllowAssembler());
2618   CheckIT(cond);
2619   if (operand.IsImmediate()) {
2620     uint32_t imm = operand.GetImmediate();
2621     if (IsUsingT32()) {
2622       ImmediateT32 immediate_t32(imm);
2623       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2624       if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) {
2625         EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2626                    (immediate_t32.GetEncodingValue() & 0xff) |
2627                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2628                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2629         AdvanceIT();
2630         return;
2631       }
2632     } else {
2633       ImmediateA32 immediate_a32(imm);
2634       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2635       if (immediate_a32.IsValid() && cond.IsNotNever()) {
2636         EmitA32(0x02100000U | (cond.GetCondition() << 28) |
2637                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2638                 immediate_a32.GetEncodingValue());
2639         return;
2640       }
2641     }
2642   }
2643   if (operand.IsImmediateShiftedRegister()) {
2644     Register rm = operand.GetBaseRegister();
2645     if (operand.IsPlainRegister()) {
2646       if (IsUsingT32()) {
2647         // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2648         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2649             rm.IsLow()) {
2650           EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2651           AdvanceIT();
2652           return;
2653         }
2654       }
2655     }
2656     Shift shift = operand.GetShift();
2657     uint32_t amount = operand.GetShiftAmount();
2658     if (IsUsingT32()) {
2659       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2660       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) {
2661         uint32_t amount_ = amount % 32;
2662         EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2663                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2664                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2665         AdvanceIT();
2666         return;
2667       }
2668     } else {
2669       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2670       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2671         uint32_t amount_ = amount % 32;
2672         EmitA32(0x00100000U | (cond.GetCondition() << 28) |
2673                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2674                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2675         return;
2676       }
2677     }
2678   }
2679   if (operand.IsRegisterShiftedRegister()) {
2680     Register rm = operand.GetBaseRegister();
2681     Shift shift = operand.GetShift();
2682     if (IsUsingA32()) {
2683       // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2684       if (cond.IsNotNever()) {
2685         EmitA32(0x00100010U | (cond.GetCondition() << 28) |
2686                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2687                 (shift.GetType() << 5) |
2688                 (operand.GetShiftRegister().GetCode() << 8));
2689         return;
2690       }
2691     }
2692   }
2693   Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand);
2694 }
2695 
asr(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)2696 void Assembler::asr(Condition cond,
2697                     EncodingSize size,
2698                     Register rd,
2699                     Register rm,
2700                     const Operand& operand) {
2701   VIXL_ASSERT(AllowAssembler());
2702   CheckIT(cond);
2703   if (operand.IsImmediate()) {
2704     uint32_t imm = operand.GetImmediate();
2705     if (IsUsingT32()) {
2706       // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2707       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2708           (imm >= 1) && (imm <= 32)) {
2709         uint32_t amount_ = imm % 32;
2710         EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2711                    (amount_ << 6));
2712         AdvanceIT();
2713         return;
2714       }
2715       // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2716       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
2717         uint32_t amount_ = imm % 32;
2718         EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2719                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2720         AdvanceIT();
2721         return;
2722       }
2723     } else {
2724       // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2725       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2726         uint32_t amount_ = imm % 32;
2727         EmitA32(0x01a00040U | (cond.GetCondition() << 28) |
2728                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2729         return;
2730       }
2731     }
2732   }
2733   if (operand.IsPlainRegister()) {
2734     Register rs = operand.GetBaseRegister();
2735     if (IsUsingT32()) {
2736       // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2737       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2738           rs.IsLow()) {
2739         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2740         AdvanceIT();
2741         return;
2742       }
2743       // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2744       if (!size.IsNarrow()) {
2745         EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2746                    rs.GetCode());
2747         AdvanceIT();
2748         return;
2749       }
2750     } else {
2751       // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
2752       if (cond.IsNotNever()) {
2753         EmitA32(0x01a00050U | (cond.GetCondition() << 28) |
2754                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
2755         return;
2756       }
2757     }
2758   }
2759   Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand);
2760 }
2761 
asrs(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)2762 void Assembler::asrs(Condition cond,
2763                      EncodingSize size,
2764                      Register rd,
2765                      Register rm,
2766                      const Operand& operand) {
2767   VIXL_ASSERT(AllowAssembler());
2768   CheckIT(cond);
2769   if (operand.IsImmediate()) {
2770     uint32_t imm = operand.GetImmediate();
2771     if (IsUsingT32()) {
2772       // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2773       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2774           (imm >= 1) && (imm <= 32)) {
2775         uint32_t amount_ = imm % 32;
2776         EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2777                    (amount_ << 6));
2778         AdvanceIT();
2779         return;
2780       }
2781       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2782       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
2783         uint32_t amount_ = imm % 32;
2784         EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2785                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2786         AdvanceIT();
2787         return;
2788       }
2789     } else {
2790       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2791       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2792         uint32_t amount_ = imm % 32;
2793         EmitA32(0x01b00040U | (cond.GetCondition() << 28) |
2794                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2795         return;
2796       }
2797     }
2798   }
2799   if (operand.IsPlainRegister()) {
2800     Register rs = operand.GetBaseRegister();
2801     if (IsUsingT32()) {
2802       // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2803       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2804           rs.IsLow()) {
2805         EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2806         AdvanceIT();
2807         return;
2808       }
2809       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2810       if (!size.IsNarrow()) {
2811         EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2812                    rs.GetCode());
2813         AdvanceIT();
2814         return;
2815       }
2816     } else {
2817       // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
2818       if (cond.IsNotNever()) {
2819         EmitA32(0x01b00050U | (cond.GetCondition() << 28) |
2820                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
2821         return;
2822       }
2823     }
2824   }
2825   Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand);
2826 }
2827 
b(Condition cond,EncodingSize size,Label * label)2828 void Assembler::b(Condition cond, EncodingSize size, Label* label) {
2829   VIXL_ASSERT(AllowAssembler());
2830   Label::Offset offset =
2831       label->IsBound()
2832           ? label->GetLocation() -
2833                 (GetCursorOffset() + GetArchitectureStatePCOffset())
2834           : 0;
2835   if (IsUsingT32()) {
2836     // B<c>{<q>} <label> ; T1
2837     if (OutsideITBlock() && !size.IsWide() &&
2838         ((label->IsBound() && (offset >= -256) && (offset <= 254) &&
2839           ((offset & 0x1) == 0)) ||
2840          (!label->IsBound() && size.IsNarrow())) &&
2841         !cond.Is(al) && cond.IsNotNever()) {
2842       static class EmitOp : public Label::LabelEmitOperator {
2843        public:
2844         EmitOp() : Label::LabelEmitOperator(-256, 254) {}
2845         virtual uint32_t Encode(uint32_t instr,
2846                                 Label::Offset pc,
2847                                 const Label* label) const VIXL_OVERRIDE {
2848           Label::Offset offset = label->GetLocation() - pc;
2849           VIXL_ASSERT((offset >= -256) && (offset <= 254) &&
2850                       ((offset & 0x1) == 0));
2851           const int32_t target = offset >> 1;
2852           return instr | (target & 0xff);
2853         }
2854       } immop;
2855       EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8), label, immop));
2856       AdvanceIT();
2857       return;
2858     }
2859     // B{<c>}{<q>} <label> ; T2
2860     if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() &&
2861         ((label->IsBound() && (offset >= -2048) && (offset <= 2046) &&
2862           ((offset & 0x1) == 0)) ||
2863          (!label->IsBound() && size.IsNarrow()))) {
2864       CheckIT(cond);
2865       static class EmitOp : public Label::LabelEmitOperator {
2866        public:
2867         EmitOp() : Label::LabelEmitOperator(-2048, 2046) {}
2868         virtual uint32_t Encode(uint32_t instr,
2869                                 Label::Offset pc,
2870                                 const Label* label) const VIXL_OVERRIDE {
2871           Label::Offset offset = label->GetLocation() - pc;
2872           VIXL_ASSERT((offset >= -2048) && (offset <= 2046) &&
2873                       ((offset & 0x1) == 0));
2874           const int32_t target = offset >> 1;
2875           return instr | (target & 0x7ff);
2876         }
2877       } immop;
2878       EmitT32_16(Link(0xe000, label, immop));
2879       AdvanceIT();
2880       return;
2881     }
2882     // B<c>{<q>} <label> ; T3
2883     if (OutsideITBlock() && !size.IsNarrow() &&
2884         ((label->IsBound() && (offset >= -1048576) && (offset <= 1048574) &&
2885           ((offset & 0x1) == 0)) ||
2886          !label->IsBound()) &&
2887         !cond.Is(al) && cond.IsNotNever()) {
2888       static class EmitOp : public Label::LabelEmitOperator {
2889        public:
2890         EmitOp() : Label::LabelEmitOperator(-1048576, 1048574) {}
2891         virtual uint32_t Encode(uint32_t instr,
2892                                 Label::Offset pc,
2893                                 const Label* label) const VIXL_OVERRIDE {
2894           Label::Offset offset = label->GetLocation() - pc;
2895           VIXL_ASSERT((offset >= -1048576) && (offset <= 1048574) &&
2896                       ((offset & 0x1) == 0));
2897           const int32_t target = offset >> 1;
2898           return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) |
2899                  ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) |
2900                  ((target & 0x80000) << 7);
2901         }
2902       } immop;
2903       EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22), label, immop));
2904       AdvanceIT();
2905       return;
2906     }
2907     // B{<c>}{<q>} <label> ; T4
2908     if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() &&
2909         ((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) &&
2910           ((offset & 0x1) == 0)) ||
2911          !label->IsBound())) {
2912       CheckIT(cond);
2913       static class EmitOp : public Label::LabelEmitOperator {
2914        public:
2915         EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {}
2916         virtual uint32_t Encode(uint32_t instr,
2917                                 Label::Offset pc,
2918                                 const Label* label) const VIXL_OVERRIDE {
2919           Label::Offset offset = label->GetLocation() - pc;
2920           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
2921                       ((offset & 0x1) == 0));
2922           int32_t target = offset >> 1;
2923           uint32_t S = target & (1 << 23);
2924           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
2925           return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
2926                  ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
2927                  ((target & 0x800000) << 3);
2928         }
2929       } immop;
2930       EmitT32_32(Link(0xf0009000U, label, immop));
2931       AdvanceIT();
2932       return;
2933     }
2934   } else {
2935     // B{<c>}{<q>} <label> ; A1
2936     if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) &&
2937           ((offset & 0x3) == 0)) ||
2938          !label->IsBound()) &&
2939         cond.IsNotNever()) {
2940       static class EmitOp : public Label::LabelEmitOperator {
2941        public:
2942         EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {}
2943         virtual uint32_t Encode(uint32_t instr,
2944                                 Label::Offset pc,
2945                                 const Label* label) const VIXL_OVERRIDE {
2946           Label::Offset offset = label->GetLocation() - pc;
2947           VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
2948                       ((offset & 0x3) == 0));
2949           const int32_t target = offset >> 2;
2950           return instr | (target & 0xffffff);
2951         }
2952       } immop;
2953       EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28), label, immop));
2954       return;
2955     }
2956   }
2957   Delegate(kB, &Assembler::b, cond, size, label);
2958 }
2959 
bfc(Condition cond,Register rd,uint32_t lsb,const Operand & operand)2960 void Assembler::bfc(Condition cond,
2961                     Register rd,
2962                     uint32_t lsb,
2963                     const Operand& operand) {
2964   VIXL_ASSERT(AllowAssembler());
2965   CheckIT(cond);
2966   if (operand.IsImmediate()) {
2967     uint32_t width = operand.GetImmediate();
2968     if (IsUsingT32()) {
2969       // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1
2970       if ((lsb <= 31) &&
2971           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2972         uint32_t msb = lsb + width - 1;
2973         EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) |
2974                    ((lsb & 0x1c) << 10) | msb);
2975         AdvanceIT();
2976         return;
2977       }
2978     } else {
2979       // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1
2980       if ((lsb <= 31) && cond.IsNotNever() &&
2981           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
2982         uint32_t msb = lsb + width - 1;
2983         EmitA32(0x07c0001fU | (cond.GetCondition() << 28) |
2984                 (rd.GetCode() << 12) | (lsb << 7) | (msb << 16));
2985         return;
2986       }
2987     }
2988   }
2989   Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, operand);
2990 }
2991 
bfi(Condition cond,Register rd,Register rn,uint32_t lsb,const Operand & operand)2992 void Assembler::bfi(Condition cond,
2993                     Register rd,
2994                     Register rn,
2995                     uint32_t lsb,
2996                     const Operand& operand) {
2997   VIXL_ASSERT(AllowAssembler());
2998   CheckIT(cond);
2999   if (operand.IsImmediate()) {
3000     uint32_t width = operand.GetImmediate();
3001     if (IsUsingT32()) {
3002       // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
3003       if ((lsb <= 31) && !rn.Is(pc) &&
3004           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
3005         uint32_t msb = lsb + width - 1;
3006         EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3007                    ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb);
3008         AdvanceIT();
3009         return;
3010       }
3011     } else {
3012       // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
3013       if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) &&
3014           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
3015         uint32_t msb = lsb + width - 1;
3016         EmitA32(0x07c00010U | (cond.GetCondition() << 28) |
3017                 (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) | (msb << 16));
3018         return;
3019       }
3020     }
3021   }
3022   Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, operand);
3023 }
3024 
bic(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)3025 void Assembler::bic(Condition cond,
3026                     EncodingSize size,
3027                     Register rd,
3028                     Register rn,
3029                     const Operand& operand) {
3030   VIXL_ASSERT(AllowAssembler());
3031   CheckIT(cond);
3032   if (operand.IsImmediate()) {
3033     uint32_t imm = operand.GetImmediate();
3034     if (IsUsingT32()) {
3035       ImmediateT32 immediate_t32(imm);
3036       // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3037       if (!size.IsNarrow() && immediate_t32.IsValid()) {
3038         EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3039                    (immediate_t32.GetEncodingValue() & 0xff) |
3040                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3041                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3042         AdvanceIT();
3043         return;
3044       }
3045     } else {
3046       ImmediateA32 immediate_a32(imm);
3047       // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3048       if (immediate_a32.IsValid() && cond.IsNotNever()) {
3049         EmitA32(0x03c00000U | (cond.GetCondition() << 28) |
3050                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3051                 immediate_a32.GetEncodingValue());
3052         return;
3053       }
3054     }
3055   }
3056   if (operand.IsImmediateShiftedRegister()) {
3057     Register rm = operand.GetBaseRegister();
3058     if (operand.IsPlainRegister()) {
3059       if (IsUsingT32()) {
3060         // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3061         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3062             rm.IsLow()) {
3063           EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3064           AdvanceIT();
3065           return;
3066         }
3067       }
3068     }
3069     Shift shift = operand.GetShift();
3070     uint32_t amount = operand.GetShiftAmount();
3071     if (IsUsingT32()) {
3072       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3073       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3074         uint32_t amount_ = amount % 32;
3075         EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3076                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3077                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3078         AdvanceIT();
3079         return;
3080       }
3081     } else {
3082       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3083       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3084         uint32_t amount_ = amount % 32;
3085         EmitA32(0x01c00000U | (cond.GetCondition() << 28) |
3086                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3087                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3088         return;
3089       }
3090     }
3091   }
3092   if (operand.IsRegisterShiftedRegister()) {
3093     Register rm = operand.GetBaseRegister();
3094     Shift shift = operand.GetShift();
3095     if (IsUsingA32()) {
3096       // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3097       if (cond.IsNotNever()) {
3098         EmitA32(0x01c00010U | (cond.GetCondition() << 28) |
3099                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3100                 (shift.GetType() << 5) |
3101                 (operand.GetShiftRegister().GetCode() << 8));
3102         return;
3103       }
3104     }
3105   }
3106   Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand);
3107 }
3108 
bics(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)3109 void Assembler::bics(Condition cond,
3110                      EncodingSize size,
3111                      Register rd,
3112                      Register rn,
3113                      const Operand& operand) {
3114   VIXL_ASSERT(AllowAssembler());
3115   CheckIT(cond);
3116   if (operand.IsImmediate()) {
3117     uint32_t imm = operand.GetImmediate();
3118     if (IsUsingT32()) {
3119       ImmediateT32 immediate_t32(imm);
3120       // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3121       if (!size.IsNarrow() && immediate_t32.IsValid()) {
3122         EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3123                    (immediate_t32.GetEncodingValue() & 0xff) |
3124                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3125                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3126         AdvanceIT();
3127         return;
3128       }
3129     } else {
3130       ImmediateA32 immediate_a32(imm);
3131       // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3132       if (immediate_a32.IsValid() && cond.IsNotNever()) {
3133         EmitA32(0x03d00000U | (cond.GetCondition() << 28) |
3134                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3135                 immediate_a32.GetEncodingValue());
3136         return;
3137       }
3138     }
3139   }
3140   if (operand.IsImmediateShiftedRegister()) {
3141     Register rm = operand.GetBaseRegister();
3142     if (operand.IsPlainRegister()) {
3143       if (IsUsingT32()) {
3144         // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3145         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3146             rm.IsLow()) {
3147           EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3148           AdvanceIT();
3149           return;
3150         }
3151       }
3152     }
3153     Shift shift = operand.GetShift();
3154     uint32_t amount = operand.GetShiftAmount();
3155     if (IsUsingT32()) {
3156       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3157       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3158         uint32_t amount_ = amount % 32;
3159         EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3160                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3161                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3162         AdvanceIT();
3163         return;
3164       }
3165     } else {
3166       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3167       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3168         uint32_t amount_ = amount % 32;
3169         EmitA32(0x01d00000U | (cond.GetCondition() << 28) |
3170                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3171                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3172         return;
3173       }
3174     }
3175   }
3176   if (operand.IsRegisterShiftedRegister()) {
3177     Register rm = operand.GetBaseRegister();
3178     Shift shift = operand.GetShift();
3179     if (IsUsingA32()) {
3180       // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3181       if (cond.IsNotNever()) {
3182         EmitA32(0x01d00010U | (cond.GetCondition() << 28) |
3183                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3184                 (shift.GetType() << 5) |
3185                 (operand.GetShiftRegister().GetCode() << 8));
3186         return;
3187       }
3188     }
3189   }
3190   Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand);
3191 }
3192 
bkpt(Condition cond,uint32_t imm)3193 void Assembler::bkpt(Condition cond, uint32_t imm) {
3194   VIXL_ASSERT(AllowAssembler());
3195   CheckIT(cond);
3196   if (IsUsingT32()) {
3197     // BKPT{<q>} {#}<imm> ; T1
3198     if ((imm <= 255)) {
3199       EmitT32_16(0xbe00 | imm);
3200       AdvanceIT();
3201       return;
3202     }
3203   } else {
3204     // BKPT{<q>} {#}<imm> ; A1
3205     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
3206       EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) |
3207               ((imm & 0xfff0) << 4));
3208       return;
3209     }
3210   }
3211   Delegate(kBkpt, &Assembler::bkpt, cond, imm);
3212 }
3213 
bl(Condition cond,Label * label)3214 void Assembler::bl(Condition cond, Label* label) {
3215   VIXL_ASSERT(AllowAssembler());
3216   CheckIT(cond);
3217   Label::Offset offset =
3218       label->IsBound()
3219           ? label->GetLocation() -
3220                 (GetCursorOffset() + GetArchitectureStatePCOffset())
3221           : 0;
3222   if (IsUsingT32()) {
3223     // BL{<c>}{<q>} <label> ; T1
3224     if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777214) &&
3225           ((offset & 0x1) == 0)) ||
3226          !label->IsBound())) {
3227       static class EmitOp : public Label::LabelEmitOperator {
3228        public:
3229         EmitOp() : Label::LabelEmitOperator(-16777216, 16777214) {}
3230         virtual uint32_t Encode(uint32_t instr,
3231                                 Label::Offset pc,
3232                                 const Label* label) const VIXL_OVERRIDE {
3233           Label::Offset offset = label->GetLocation() - pc;
3234           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777214) &&
3235                       ((offset & 0x1) == 0));
3236           int32_t target = offset >> 1;
3237           uint32_t S = target & (1 << 23);
3238           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
3239           return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
3240                  ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
3241                  ((target & 0x800000) << 3);
3242         }
3243       } immop;
3244       EmitT32_32(Link(0xf000d000U, label, immop));
3245       AdvanceIT();
3246       return;
3247     }
3248   } else {
3249     // BL{<c>}{<q>} <label> ; A1
3250     if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554428) &&
3251           ((offset & 0x3) == 0)) ||
3252          !label->IsBound()) &&
3253         cond.IsNotNever()) {
3254       static class EmitOp : public Label::LabelEmitOperator {
3255        public:
3256         EmitOp() : Label::LabelEmitOperator(-33554432, 33554428) {}
3257         virtual uint32_t Encode(uint32_t instr,
3258                                 Label::Offset pc,
3259                                 const Label* label) const VIXL_OVERRIDE {
3260           Label::Offset offset = label->GetLocation() - pc;
3261           VIXL_ASSERT((offset >= -33554432) && (offset <= 33554428) &&
3262                       ((offset & 0x3) == 0));
3263           const int32_t target = offset >> 2;
3264           return instr | (target & 0xffffff);
3265         }
3266       } immop;
3267       EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28), label, immop));
3268       return;
3269     }
3270   }
3271   Delegate(kBl, &Assembler::bl, cond, label);
3272 }
3273 
blx(Condition cond,Label * label)3274 void Assembler::blx(Condition cond, Label* label) {
3275   VIXL_ASSERT(AllowAssembler());
3276   CheckIT(cond);
3277   Label::Offset offset =
3278       label->IsBound()
3279           ? label->GetLocation() -
3280                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
3281           : 0;
3282   if (IsUsingT32()) {
3283     // BLX{<c>}{<q>} <label> ; T2
3284     if (((label->IsBound() && (offset >= -16777216) && (offset <= 16777212) &&
3285           ((offset & 0x3) == 0)) ||
3286          !label->IsBound())) {
3287       static class EmitOp : public Label::LabelEmitOperator {
3288        public:
3289         EmitOp() : Label::LabelEmitOperator(-16777216, 16777212) {}
3290         virtual uint32_t Encode(uint32_t instr,
3291                                 Label::Offset pc,
3292                                 const Label* label) const VIXL_OVERRIDE {
3293           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
3294           VIXL_ASSERT((offset >= -16777216) && (offset <= 16777212) &&
3295                       ((offset & 0x3) == 0));
3296           int32_t target = offset >> 2;
3297           uint32_t S = target & (1 << 22);
3298           target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20);
3299           return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) |
3300                  ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) |
3301                  ((target & 0x400000) << 4);
3302         }
3303       } immop;
3304       EmitT32_32(Link(0xf000c000U, label, immop));
3305       AdvanceIT();
3306       return;
3307     }
3308   } else {
3309     // BLX{<c>}{<q>} <label> ; A2
3310     if (((label->IsBound() && (offset >= -33554432) && (offset <= 33554430) &&
3311           ((offset & 0x1) == 0)) ||
3312          !label->IsBound())) {
3313       if (cond.Is(al) || AllowStronglyDiscouraged()) {
3314         static class EmitOp : public Label::LabelEmitOperator {
3315          public:
3316           EmitOp() : Label::LabelEmitOperator(-33554432, 33554430) {}
3317           virtual uint32_t Encode(uint32_t instr,
3318                                   Label::Offset pc,
3319                                   const Label* label) const VIXL_OVERRIDE {
3320             Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
3321             VIXL_ASSERT((offset >= -33554432) && (offset <= 33554430) &&
3322                         ((offset & 0x1) == 0));
3323             const int32_t target = offset >> 1;
3324             return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1);
3325           }
3326         } immop;
3327         EmitA32(Link(0xfa000000U, label, immop));
3328         return;
3329       }
3330     }
3331   }
3332   Delegate(kBlx, &Assembler::blx, cond, label);
3333 }
3334 
blx(Condition cond,Register rm)3335 void Assembler::blx(Condition cond, Register rm) {
3336   VIXL_ASSERT(AllowAssembler());
3337   CheckIT(cond);
3338   if (IsUsingT32()) {
3339     // BLX{<c>}{<q>} <Rm> ; T1
3340     EmitT32_16(0x4780 | (rm.GetCode() << 3));
3341     AdvanceIT();
3342     return;
3343   } else {
3344     // BLX{<c>}{<q>} <Rm> ; A1
3345     if (cond.IsNotNever()) {
3346       EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode());
3347       return;
3348     }
3349   }
3350   Delegate(kBlx, &Assembler::blx, cond, rm);
3351 }
3352 
bx(Condition cond,Register rm)3353 void Assembler::bx(Condition cond, Register rm) {
3354   VIXL_ASSERT(AllowAssembler());
3355   CheckIT(cond);
3356   if (IsUsingT32()) {
3357     // BX{<c>}{<q>} <Rm> ; T1
3358     EmitT32_16(0x4700 | (rm.GetCode() << 3));
3359     AdvanceIT();
3360     return;
3361   } else {
3362     // BX{<c>}{<q>} <Rm> ; A1
3363     if (cond.IsNotNever()) {
3364       EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode());
3365       return;
3366     }
3367   }
3368   Delegate(kBx, &Assembler::bx, cond, rm);
3369 }
3370 
bxj(Condition cond,Register rm)3371 void Assembler::bxj(Condition cond, Register rm) {
3372   VIXL_ASSERT(AllowAssembler());
3373   CheckIT(cond);
3374   if (IsUsingT32()) {
3375     // BXJ{<c>}{<q>} <Rm> ; T1
3376     EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16));
3377     AdvanceIT();
3378     return;
3379   } else {
3380     // BXJ{<c>}{<q>} <Rm> ; A1
3381     if (cond.IsNotNever()) {
3382       EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode());
3383       return;
3384     }
3385   }
3386   Delegate(kBxj, &Assembler::bxj, cond, rm);
3387 }
3388 
cbnz(Register rn,Label * label)3389 void Assembler::cbnz(Register rn, Label* label) {
3390   VIXL_ASSERT(AllowAssembler());
3391   CheckIT(al);
3392   Label::Offset offset =
3393       label->IsBound()
3394           ? label->GetLocation() -
3395                 (GetCursorOffset() + GetArchitectureStatePCOffset())
3396           : 0;
3397   if (IsUsingT32()) {
3398     // CBNZ{<q>} <Rn>, <label> ; T1
3399     if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) &&
3400                         ((offset & 0x1) == 0)) ||
3401                        !label->IsBound())) {
3402       static class EmitOp : public Label::LabelEmitOperator {
3403        public:
3404         EmitOp() : Label::LabelEmitOperator(0, 126) {}
3405         virtual uint32_t Encode(uint32_t instr,
3406                                 Label::Offset pc,
3407                                 const Label* label) const VIXL_OVERRIDE {
3408           Label::Offset offset = label->GetLocation() - pc;
3409           VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
3410                       ((offset & 0x1) == 0));
3411           const int32_t target = offset >> 1;
3412           return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3413         }
3414       } immop;
3415       EmitT32_16(Link(0xb900 | rn.GetCode(), label, immop));
3416       AdvanceIT();
3417       return;
3418     }
3419   }
3420   Delegate(kCbnz, &Assembler::cbnz, rn, label);
3421 }
3422 
cbz(Register rn,Label * label)3423 void Assembler::cbz(Register rn, Label* label) {
3424   VIXL_ASSERT(AllowAssembler());
3425   CheckIT(al);
3426   Label::Offset offset =
3427       label->IsBound()
3428           ? label->GetLocation() -
3429                 (GetCursorOffset() + GetArchitectureStatePCOffset())
3430           : 0;
3431   if (IsUsingT32()) {
3432     // CBZ{<q>} <Rn>, <label> ; T1
3433     if (rn.IsLow() && ((label->IsBound() && (offset >= 0) && (offset <= 126) &&
3434                         ((offset & 0x1) == 0)) ||
3435                        !label->IsBound())) {
3436       static class EmitOp : public Label::LabelEmitOperator {
3437        public:
3438         EmitOp() : Label::LabelEmitOperator(0, 126) {}
3439         virtual uint32_t Encode(uint32_t instr,
3440                                 Label::Offset pc,
3441                                 const Label* label) const VIXL_OVERRIDE {
3442           Label::Offset offset = label->GetLocation() - pc;
3443           VIXL_ASSERT((offset >= 0) && (offset <= 126) &&
3444                       ((offset & 0x1) == 0));
3445           const int32_t target = offset >> 1;
3446           return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3447         }
3448       } immop;
3449       EmitT32_16(Link(0xb100 | rn.GetCode(), label, immop));
3450       AdvanceIT();
3451       return;
3452     }
3453   }
3454   Delegate(kCbz, &Assembler::cbz, rn, label);
3455 }
3456 
clrex(Condition cond)3457 void Assembler::clrex(Condition cond) {
3458   VIXL_ASSERT(AllowAssembler());
3459   CheckIT(cond);
3460   if (IsUsingT32()) {
3461     // CLREX{<c>}{<q>} ; T1
3462     EmitT32_32(0xf3bf8f2fU);
3463     AdvanceIT();
3464     return;
3465   } else {
3466     // CLREX{<c>}{<q>} ; A1
3467     if (cond.Is(al)) {
3468       EmitA32(0xf57ff01fU);
3469       return;
3470     }
3471   }
3472   Delegate(kClrex, &Assembler::clrex, cond);
3473 }
3474 
clz(Condition cond,Register rd,Register rm)3475 void Assembler::clz(Condition cond, Register rd, Register rm) {
3476   VIXL_ASSERT(AllowAssembler());
3477   CheckIT(cond);
3478   if (IsUsingT32()) {
3479     // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1
3480     if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3481       EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() |
3482                  (rm.GetCode() << 16));
3483       AdvanceIT();
3484       return;
3485     }
3486   } else {
3487     // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1
3488     if (cond.IsNotNever() &&
3489         ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3490       EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3491               rm.GetCode());
3492       return;
3493     }
3494   }
3495   Delegate(kClz, &Assembler::clz, cond, rd, rm);
3496 }
3497 
cmn(Condition cond,EncodingSize size,Register rn,const Operand & operand)3498 void Assembler::cmn(Condition cond,
3499                     EncodingSize size,
3500                     Register rn,
3501                     const Operand& operand) {
3502   VIXL_ASSERT(AllowAssembler());
3503   CheckIT(cond);
3504   if (operand.IsImmediate()) {
3505     uint32_t imm = operand.GetImmediate();
3506     if (IsUsingT32()) {
3507       ImmediateT32 immediate_t32(imm);
3508       // CMN{<c>}{<q>} <Rn>, #<const> ; T1
3509       if (!size.IsNarrow() && immediate_t32.IsValid()) {
3510         EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) |
3511                    (immediate_t32.GetEncodingValue() & 0xff) |
3512                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3513                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3514         AdvanceIT();
3515         return;
3516       }
3517     } else {
3518       ImmediateA32 immediate_a32(imm);
3519       // CMN{<c>}{<q>} <Rn>, #<const> ; A1
3520       if (immediate_a32.IsValid() && cond.IsNotNever()) {
3521         EmitA32(0x03700000U | (cond.GetCondition() << 28) |
3522                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3523         return;
3524       }
3525     }
3526   }
3527   if (operand.IsImmediateShiftedRegister()) {
3528     Register rm = operand.GetBaseRegister();
3529     if (operand.IsPlainRegister()) {
3530       if (IsUsingT32()) {
3531         // CMN{<c>}{<q>} <Rn>, <Rm> ; T1
3532         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3533           EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3));
3534           AdvanceIT();
3535           return;
3536         }
3537       }
3538     }
3539     Shift shift = operand.GetShift();
3540     uint32_t amount = operand.GetShiftAmount();
3541     if (IsUsingT32()) {
3542       // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
3543       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3544         uint32_t amount_ = amount % 32;
3545         EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() |
3546                    (operand.GetTypeEncodingValue() << 4) |
3547                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3548         AdvanceIT();
3549         return;
3550       }
3551     } else {
3552       // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3553       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3554         uint32_t amount_ = amount % 32;
3555         EmitA32(0x01700000U | (cond.GetCondition() << 28) |
3556                 (rn.GetCode() << 16) | rm.GetCode() |
3557                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3558         return;
3559       }
3560     }
3561   }
3562   if (operand.IsRegisterShiftedRegister()) {
3563     Register rm = operand.GetBaseRegister();
3564     Shift shift = operand.GetShift();
3565     if (IsUsingA32()) {
3566       // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3567       if (cond.IsNotNever()) {
3568         EmitA32(0x01700010U | (cond.GetCondition() << 28) |
3569                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3570                 (operand.GetShiftRegister().GetCode() << 8));
3571         return;
3572       }
3573     }
3574   }
3575   Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand);
3576 }
3577 
cmp(Condition cond,EncodingSize size,Register rn,const Operand & operand)3578 void Assembler::cmp(Condition cond,
3579                     EncodingSize size,
3580                     Register rn,
3581                     const Operand& operand) {
3582   VIXL_ASSERT(AllowAssembler());
3583   CheckIT(cond);
3584   if (operand.IsImmediate()) {
3585     uint32_t imm = operand.GetImmediate();
3586     if (IsUsingT32()) {
3587       ImmediateT32 immediate_t32(imm);
3588       // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1
3589       if (!size.IsWide() && rn.IsLow() && (imm <= 255)) {
3590         EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm);
3591         AdvanceIT();
3592         return;
3593       }
3594       // CMP{<c>}{<q>} <Rn>, #<const> ; T2
3595       if (!size.IsNarrow() && immediate_t32.IsValid()) {
3596         EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) |
3597                    (immediate_t32.GetEncodingValue() & 0xff) |
3598                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3599                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3600         AdvanceIT();
3601         return;
3602       }
3603     } else {
3604       ImmediateA32 immediate_a32(imm);
3605       // CMP{<c>}{<q>} <Rn>, #<const> ; A1
3606       if (immediate_a32.IsValid() && cond.IsNotNever()) {
3607         EmitA32(0x03500000U | (cond.GetCondition() << 28) |
3608                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3609         return;
3610       }
3611     }
3612   }
3613   if (operand.IsImmediateShiftedRegister()) {
3614     Register rm = operand.GetBaseRegister();
3615     if (operand.IsPlainRegister()) {
3616       if (IsUsingT32()) {
3617         // CMP{<c>}{<q>} <Rn>, <Rm> ; T1
3618         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3619           EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3));
3620           AdvanceIT();
3621           return;
3622         }
3623         // CMP{<c>}{<q>} <Rn>, <Rm> ; T2
3624         if (!size.IsWide()) {
3625           EmitT32_16(0x4500 | (rn.GetCode() & 0x7) |
3626                      ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
3627           AdvanceIT();
3628           return;
3629         }
3630       }
3631     }
3632     Shift shift = operand.GetShift();
3633     uint32_t amount = operand.GetShiftAmount();
3634     if (IsUsingT32()) {
3635       // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3
3636       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3637         uint32_t amount_ = amount % 32;
3638         EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() |
3639                    (operand.GetTypeEncodingValue() << 4) |
3640                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3641         AdvanceIT();
3642         return;
3643       }
3644     } else {
3645       // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3646       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3647         uint32_t amount_ = amount % 32;
3648         EmitA32(0x01500000U | (cond.GetCondition() << 28) |
3649                 (rn.GetCode() << 16) | rm.GetCode() |
3650                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3651         return;
3652       }
3653     }
3654   }
3655   if (operand.IsRegisterShiftedRegister()) {
3656     Register rm = operand.GetBaseRegister();
3657     Shift shift = operand.GetShift();
3658     if (IsUsingA32()) {
3659       // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3660       if (cond.IsNotNever()) {
3661         EmitA32(0x01500010U | (cond.GetCondition() << 28) |
3662                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3663                 (operand.GetShiftRegister().GetCode() << 8));
3664         return;
3665       }
3666     }
3667   }
3668   Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand);
3669 }
3670 
crc32b(Condition cond,Register rd,Register rn,Register rm)3671 void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) {
3672   VIXL_ASSERT(AllowAssembler());
3673   CheckIT(cond);
3674   if (IsUsingT32()) {
3675     // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1
3676     EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3677                rm.GetCode());
3678     AdvanceIT();
3679     return;
3680   } else {
3681     // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1
3682     if ((cond.Is(al) || AllowUnpredictable())) {
3683       EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3684               (rn.GetCode() << 16) | rm.GetCode());
3685       return;
3686     }
3687   }
3688   Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm);
3689 }
3690 
crc32cb(Condition cond,Register rd,Register rn,Register rm)3691 void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) {
3692   VIXL_ASSERT(AllowAssembler());
3693   CheckIT(cond);
3694   if (IsUsingT32()) {
3695     // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1
3696     EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3697                rm.GetCode());
3698     AdvanceIT();
3699     return;
3700   } else {
3701     // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1
3702     if ((cond.Is(al) || AllowUnpredictable())) {
3703       EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3704               (rn.GetCode() << 16) | rm.GetCode());
3705       return;
3706     }
3707   }
3708   Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm);
3709 }
3710 
crc32ch(Condition cond,Register rd,Register rn,Register rm)3711 void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) {
3712   VIXL_ASSERT(AllowAssembler());
3713   CheckIT(cond);
3714   if (IsUsingT32()) {
3715     // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1
3716     EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3717                rm.GetCode());
3718     AdvanceIT();
3719     return;
3720   } else {
3721     // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1
3722     if ((cond.Is(al) || AllowUnpredictable())) {
3723       EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3724               (rn.GetCode() << 16) | rm.GetCode());
3725       return;
3726     }
3727   }
3728   Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm);
3729 }
3730 
crc32cw(Condition cond,Register rd,Register rn,Register rm)3731 void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) {
3732   VIXL_ASSERT(AllowAssembler());
3733   CheckIT(cond);
3734   if (IsUsingT32()) {
3735     // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1
3736     EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3737                rm.GetCode());
3738     AdvanceIT();
3739     return;
3740   } else {
3741     // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1
3742     if ((cond.Is(al) || AllowUnpredictable())) {
3743       EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3744               (rn.GetCode() << 16) | rm.GetCode());
3745       return;
3746     }
3747   }
3748   Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm);
3749 }
3750 
crc32h(Condition cond,Register rd,Register rn,Register rm)3751 void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) {
3752   VIXL_ASSERT(AllowAssembler());
3753   CheckIT(cond);
3754   if (IsUsingT32()) {
3755     // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1
3756     EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3757                rm.GetCode());
3758     AdvanceIT();
3759     return;
3760   } else {
3761     // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1
3762     if ((cond.Is(al) || AllowUnpredictable())) {
3763       EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3764               (rn.GetCode() << 16) | rm.GetCode());
3765       return;
3766     }
3767   }
3768   Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm);
3769 }
3770 
crc32w(Condition cond,Register rd,Register rn,Register rm)3771 void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) {
3772   VIXL_ASSERT(AllowAssembler());
3773   CheckIT(cond);
3774   if (IsUsingT32()) {
3775     // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1
3776     EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3777                rm.GetCode());
3778     AdvanceIT();
3779     return;
3780   } else {
3781     // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1
3782     if ((cond.Is(al) || AllowUnpredictable())) {
3783       EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3784               (rn.GetCode() << 16) | rm.GetCode());
3785       return;
3786     }
3787   }
3788   Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm);
3789 }
3790 
dmb(Condition cond,MemoryBarrier option)3791 void Assembler::dmb(Condition cond, MemoryBarrier option) {
3792   VIXL_ASSERT(AllowAssembler());
3793   CheckIT(cond);
3794   if (IsUsingT32()) {
3795     // DMB{<c>}{<q>} {<option>} ; T1
3796     EmitT32_32(0xf3bf8f50U | option.GetType());
3797     AdvanceIT();
3798     return;
3799   } else {
3800     // DMB{<c>}{<q>} {<option>} ; A1
3801     if (cond.Is(al)) {
3802       EmitA32(0xf57ff050U | option.GetType());
3803       return;
3804     }
3805   }
3806   Delegate(kDmb, &Assembler::dmb, cond, option);
3807 }
3808 
dsb(Condition cond,MemoryBarrier option)3809 void Assembler::dsb(Condition cond, MemoryBarrier option) {
3810   VIXL_ASSERT(AllowAssembler());
3811   CheckIT(cond);
3812   if (IsUsingT32()) {
3813     // DSB{<c>}{<q>} {<option>} ; T1
3814     EmitT32_32(0xf3bf8f40U | option.GetType());
3815     AdvanceIT();
3816     return;
3817   } else {
3818     // DSB{<c>}{<q>} {<option>} ; A1
3819     if (cond.Is(al)) {
3820       EmitA32(0xf57ff040U | option.GetType());
3821       return;
3822     }
3823   }
3824   Delegate(kDsb, &Assembler::dsb, cond, option);
3825 }
3826 
eor(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)3827 void Assembler::eor(Condition cond,
3828                     EncodingSize size,
3829                     Register rd,
3830                     Register rn,
3831                     const Operand& operand) {
3832   VIXL_ASSERT(AllowAssembler());
3833   CheckIT(cond);
3834   if (operand.IsImmediate()) {
3835     uint32_t imm = operand.GetImmediate();
3836     if (IsUsingT32()) {
3837       ImmediateT32 immediate_t32(imm);
3838       // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3839       if (!size.IsNarrow() && immediate_t32.IsValid()) {
3840         EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3841                    (immediate_t32.GetEncodingValue() & 0xff) |
3842                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3843                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3844         AdvanceIT();
3845         return;
3846       }
3847     } else {
3848       ImmediateA32 immediate_a32(imm);
3849       // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3850       if (immediate_a32.IsValid() && cond.IsNotNever()) {
3851         EmitA32(0x02200000U | (cond.GetCondition() << 28) |
3852                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3853                 immediate_a32.GetEncodingValue());
3854         return;
3855       }
3856     }
3857   }
3858   if (operand.IsImmediateShiftedRegister()) {
3859     Register rm = operand.GetBaseRegister();
3860     if (operand.IsPlainRegister()) {
3861       if (IsUsingT32()) {
3862         // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3863         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3864             rm.IsLow()) {
3865           EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
3866           AdvanceIT();
3867           return;
3868         }
3869       }
3870     }
3871     Shift shift = operand.GetShift();
3872     uint32_t amount = operand.GetShiftAmount();
3873     if (IsUsingT32()) {
3874       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3875       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
3876         uint32_t amount_ = amount % 32;
3877         EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3878                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3879                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3880         AdvanceIT();
3881         return;
3882       }
3883     } else {
3884       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3885       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3886         uint32_t amount_ = amount % 32;
3887         EmitA32(0x00200000U | (cond.GetCondition() << 28) |
3888                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3889                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3890         return;
3891       }
3892     }
3893   }
3894   if (operand.IsRegisterShiftedRegister()) {
3895     Register rm = operand.GetBaseRegister();
3896     Shift shift = operand.GetShift();
3897     if (IsUsingA32()) {
3898       // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3899       if (cond.IsNotNever()) {
3900         EmitA32(0x00200010U | (cond.GetCondition() << 28) |
3901                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3902                 (shift.GetType() << 5) |
3903                 (operand.GetShiftRegister().GetCode() << 8));
3904         return;
3905       }
3906     }
3907   }
3908   Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand);
3909 }
3910 
eors(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)3911 void Assembler::eors(Condition cond,
3912                      EncodingSize size,
3913                      Register rd,
3914                      Register rn,
3915                      const Operand& operand) {
3916   VIXL_ASSERT(AllowAssembler());
3917   CheckIT(cond);
3918   if (operand.IsImmediate()) {
3919     uint32_t imm = operand.GetImmediate();
3920     if (IsUsingT32()) {
3921       ImmediateT32 immediate_t32(imm);
3922       // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3923       if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc)) {
3924         EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3925                    (immediate_t32.GetEncodingValue() & 0xff) |
3926                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3927                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3928         AdvanceIT();
3929         return;
3930       }
3931     } else {
3932       ImmediateA32 immediate_a32(imm);
3933       // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3934       if (immediate_a32.IsValid() && cond.IsNotNever()) {
3935         EmitA32(0x02300000U | (cond.GetCondition() << 28) |
3936                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3937                 immediate_a32.GetEncodingValue());
3938         return;
3939       }
3940     }
3941   }
3942   if (operand.IsImmediateShiftedRegister()) {
3943     Register rm = operand.GetBaseRegister();
3944     if (operand.IsPlainRegister()) {
3945       if (IsUsingT32()) {
3946         // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3947         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3948             rm.IsLow()) {
3949           EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
3950           AdvanceIT();
3951           return;
3952         }
3953       }
3954     }
3955     Shift shift = operand.GetShift();
3956     uint32_t amount = operand.GetShiftAmount();
3957     if (IsUsingT32()) {
3958       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3959       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc)) {
3960         uint32_t amount_ = amount % 32;
3961         EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3962                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3963                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3964         AdvanceIT();
3965         return;
3966       }
3967     } else {
3968       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3969       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3970         uint32_t amount_ = amount % 32;
3971         EmitA32(0x00300000U | (cond.GetCondition() << 28) |
3972                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3973                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3974         return;
3975       }
3976     }
3977   }
3978   if (operand.IsRegisterShiftedRegister()) {
3979     Register rm = operand.GetBaseRegister();
3980     Shift shift = operand.GetShift();
3981     if (IsUsingA32()) {
3982       // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3983       if (cond.IsNotNever()) {
3984         EmitA32(0x00300010U | (cond.GetCondition() << 28) |
3985                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3986                 (shift.GetType() << 5) |
3987                 (operand.GetShiftRegister().GetCode() << 8));
3988         return;
3989       }
3990     }
3991   }
3992   Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand);
3993 }
3994 
fldmdbx(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)3995 void Assembler::fldmdbx(Condition cond,
3996                         Register rn,
3997                         WriteBack write_back,
3998                         DRegisterList dreglist) {
3999   VIXL_ASSERT(AllowAssembler());
4000   CheckIT(cond);
4001   if (IsUsingT32()) {
4002     // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
4003     if (write_back.DoesWriteBack() &&
4004         (((dreglist.GetLength() <= 16) &&
4005           (dreglist.GetLastDRegister().GetCode() < 16)) ||
4006          AllowUnpredictable())) {
4007       const DRegister& dreg = dreglist.GetFirstDRegister();
4008       unsigned len = dreglist.GetLength() * 2;
4009       EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
4010                  (len & 0xff));
4011       AdvanceIT();
4012       return;
4013     }
4014   } else {
4015     // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
4016     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
4017         (((dreglist.GetLength() <= 16) &&
4018           (dreglist.GetLastDRegister().GetCode() < 16)) ||
4019          AllowUnpredictable())) {
4020       const DRegister& dreg = dreglist.GetFirstDRegister();
4021       unsigned len = dreglist.GetLength() * 2;
4022       EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4023               dreg.Encode(22, 12) | (len & 0xff));
4024       return;
4025     }
4026   }
4027   Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist);
4028 }
4029 
fldmiax(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)4030 void Assembler::fldmiax(Condition cond,
4031                         Register rn,
4032                         WriteBack write_back,
4033                         DRegisterList dreglist) {
4034   VIXL_ASSERT(AllowAssembler());
4035   CheckIT(cond);
4036   if (IsUsingT32()) {
4037     // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
4038     if ((((dreglist.GetLength() <= 16) &&
4039           (dreglist.GetLastDRegister().GetCode() < 16)) ||
4040          AllowUnpredictable())) {
4041       const DRegister& dreg = dreglist.GetFirstDRegister();
4042       unsigned len = dreglist.GetLength() * 2;
4043       EmitT32_32(0xec900b01U | (rn.GetCode() << 16) |
4044                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4045                  (len & 0xff));
4046       AdvanceIT();
4047       return;
4048     }
4049   } else {
4050     // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
4051     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
4052                                (dreglist.GetLastDRegister().GetCode() < 16)) ||
4053                               AllowUnpredictable())) {
4054       const DRegister& dreg = dreglist.GetFirstDRegister();
4055       unsigned len = dreglist.GetLength() * 2;
4056       EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4057               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4058               (len & 0xff));
4059       return;
4060     }
4061   }
4062   Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist);
4063 }
4064 
fstmdbx(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)4065 void Assembler::fstmdbx(Condition cond,
4066                         Register rn,
4067                         WriteBack write_back,
4068                         DRegisterList dreglist) {
4069   VIXL_ASSERT(AllowAssembler());
4070   CheckIT(cond);
4071   if (IsUsingT32()) {
4072     // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
4073     if (write_back.DoesWriteBack() &&
4074         (((dreglist.GetLength() <= 16) &&
4075           (dreglist.GetLastDRegister().GetCode() < 16)) ||
4076          AllowUnpredictable())) {
4077       const DRegister& dreg = dreglist.GetFirstDRegister();
4078       unsigned len = dreglist.GetLength() * 2;
4079       EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
4080                  (len & 0xff));
4081       AdvanceIT();
4082       return;
4083     }
4084   } else {
4085     // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
4086     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
4087         (((dreglist.GetLength() <= 16) &&
4088           (dreglist.GetLastDRegister().GetCode() < 16)) ||
4089          AllowUnpredictable())) {
4090       const DRegister& dreg = dreglist.GetFirstDRegister();
4091       unsigned len = dreglist.GetLength() * 2;
4092       EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4093               dreg.Encode(22, 12) | (len & 0xff));
4094       return;
4095     }
4096   }
4097   Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist);
4098 }
4099 
fstmiax(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)4100 void Assembler::fstmiax(Condition cond,
4101                         Register rn,
4102                         WriteBack write_back,
4103                         DRegisterList dreglist) {
4104   VIXL_ASSERT(AllowAssembler());
4105   CheckIT(cond);
4106   if (IsUsingT32()) {
4107     // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
4108     if ((((dreglist.GetLength() <= 16) &&
4109           (dreglist.GetLastDRegister().GetCode() < 16)) ||
4110          AllowUnpredictable())) {
4111       const DRegister& dreg = dreglist.GetFirstDRegister();
4112       unsigned len = dreglist.GetLength() * 2;
4113       EmitT32_32(0xec800b01U | (rn.GetCode() << 16) |
4114                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4115                  (len & 0xff));
4116       AdvanceIT();
4117       return;
4118     }
4119   } else {
4120     // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
4121     if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
4122                                (dreglist.GetLastDRegister().GetCode() < 16)) ||
4123                               AllowUnpredictable())) {
4124       const DRegister& dreg = dreglist.GetFirstDRegister();
4125       unsigned len = dreglist.GetLength() * 2;
4126       EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4127               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4128               (len & 0xff));
4129       return;
4130     }
4131   }
4132   Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist);
4133 }
4134 
hlt(Condition cond,uint32_t imm)4135 void Assembler::hlt(Condition cond, uint32_t imm) {
4136   VIXL_ASSERT(AllowAssembler());
4137   CheckIT(cond);
4138   if (IsUsingT32()) {
4139     // HLT{<q>} {#}<imm> ; T1
4140     if ((imm <= 63)) {
4141       EmitT32_16(0xba80 | imm);
4142       AdvanceIT();
4143       return;
4144     }
4145   } else {
4146     // HLT{<q>} {#}<imm> ; A1
4147     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4148       EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4149               ((imm & 0xfff0) << 4));
4150       return;
4151     }
4152   }
4153   Delegate(kHlt, &Assembler::hlt, cond, imm);
4154 }
4155 
hvc(Condition cond,uint32_t imm)4156 void Assembler::hvc(Condition cond, uint32_t imm) {
4157   VIXL_ASSERT(AllowAssembler());
4158   CheckIT(cond);
4159   if (IsUsingT32()) {
4160     // HVC{<q>} {#}<imm16> ; T1
4161     if ((imm <= 65535)) {
4162       EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
4163       AdvanceIT();
4164       return;
4165     }
4166   } else {
4167     // HVC{<q>} {#}<imm16> ; A1
4168     if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4169       EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4170               ((imm & 0xfff0) << 4));
4171       return;
4172     }
4173   }
4174   Delegate(kHvc, &Assembler::hvc, cond, imm);
4175 }
4176 
isb(Condition cond,MemoryBarrier option)4177 void Assembler::isb(Condition cond, MemoryBarrier option) {
4178   VIXL_ASSERT(AllowAssembler());
4179   CheckIT(cond);
4180   if (IsUsingT32()) {
4181     // ISB{<c>}{<q>} {<option>} ; T1
4182     EmitT32_32(0xf3bf8f60U | option.GetType());
4183     AdvanceIT();
4184     return;
4185   } else {
4186     // ISB{<c>}{<q>} {<option>} ; A1
4187     if (cond.Is(al)) {
4188       EmitA32(0xf57ff060U | option.GetType());
4189       return;
4190     }
4191   }
4192   Delegate(kIsb, &Assembler::isb, cond, option);
4193 }
4194 
it(Condition cond,uint16_t mask)4195 void Assembler::it(Condition cond, uint16_t mask) {
4196   VIXL_ASSERT(AllowAssembler());
4197   CheckNotIT();
4198   if (mask != 0) {
4199     if ((cond.GetCondition() & 0x1) != 0) {
4200       if ((mask & 0x1) != 0) {
4201         mask ^= 0xE;
4202       } else if ((mask & 0x2) != 0) {
4203         mask ^= 0xC;
4204       } else if ((mask & 0x4) != 0) {
4205         mask ^= 0x8;
4206       }
4207     }
4208     if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask);
4209     SetIT(cond, mask);
4210     return;
4211   }
4212   DelegateIt(cond, mask);
4213 }
4214 
lda(Condition cond,Register rt,const MemOperand & operand)4215 void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) {
4216   VIXL_ASSERT(AllowAssembler());
4217   CheckIT(cond);
4218   if (operand.IsImmediateZero()) {
4219     Register rn = operand.GetBaseRegister();
4220     if (IsUsingT32()) {
4221       // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1
4222       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4223         EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4224         AdvanceIT();
4225         return;
4226       }
4227     } else {
4228       // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1
4229       if (operand.IsOffset() && cond.IsNotNever() &&
4230           (!rn.IsPC() || AllowUnpredictable())) {
4231         EmitA32(0x01900c9fU | (cond.GetCondition() << 28) |
4232                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4233         return;
4234       }
4235     }
4236   }
4237   Delegate(kLda, &Assembler::lda, cond, rt, operand);
4238 }
4239 
ldab(Condition cond,Register rt,const MemOperand & operand)4240 void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) {
4241   VIXL_ASSERT(AllowAssembler());
4242   CheckIT(cond);
4243   if (operand.IsImmediateZero()) {
4244     Register rn = operand.GetBaseRegister();
4245     if (IsUsingT32()) {
4246       // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4247       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4248         EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4249         AdvanceIT();
4250         return;
4251       }
4252     } else {
4253       // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4254       if (operand.IsOffset() && cond.IsNotNever() &&
4255           (!rn.IsPC() || AllowUnpredictable())) {
4256         EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) |
4257                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4258         return;
4259       }
4260     }
4261   }
4262   Delegate(kLdab, &Assembler::ldab, cond, rt, operand);
4263 }
4264 
ldaex(Condition cond,Register rt,const MemOperand & operand)4265 void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) {
4266   VIXL_ASSERT(AllowAssembler());
4267   CheckIT(cond);
4268   if (operand.IsImmediateZero()) {
4269     Register rn = operand.GetBaseRegister();
4270     if (IsUsingT32()) {
4271       // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1
4272       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4273         EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4274         AdvanceIT();
4275         return;
4276       }
4277     } else {
4278       // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1
4279       if (operand.IsOffset() && cond.IsNotNever() &&
4280           (!rn.IsPC() || AllowUnpredictable())) {
4281         EmitA32(0x01900e9fU | (cond.GetCondition() << 28) |
4282                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4283         return;
4284       }
4285     }
4286   }
4287   Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand);
4288 }
4289 
ldaexb(Condition cond,Register rt,const MemOperand & operand)4290 void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) {
4291   VIXL_ASSERT(AllowAssembler());
4292   CheckIT(cond);
4293   if (operand.IsImmediateZero()) {
4294     Register rn = operand.GetBaseRegister();
4295     if (IsUsingT32()) {
4296       // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4297       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4298         EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4299         AdvanceIT();
4300         return;
4301       }
4302     } else {
4303       // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4304       if (operand.IsOffset() && cond.IsNotNever() &&
4305           (!rn.IsPC() || AllowUnpredictable())) {
4306         EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) |
4307                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4308         return;
4309       }
4310     }
4311   }
4312   Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand);
4313 }
4314 
ldaexd(Condition cond,Register rt,Register rt2,const MemOperand & operand)4315 void Assembler::ldaexd(Condition cond,
4316                        Register rt,
4317                        Register rt2,
4318                        const MemOperand& operand) {
4319   VIXL_ASSERT(AllowAssembler());
4320   CheckIT(cond);
4321   if (operand.IsImmediateZero()) {
4322     Register rn = operand.GetBaseRegister();
4323     if (IsUsingT32()) {
4324       // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
4325       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4326         EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
4327                    (rn.GetCode() << 16));
4328         AdvanceIT();
4329         return;
4330       }
4331     } else {
4332       // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
4333       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
4334           operand.IsOffset() && cond.IsNotNever() &&
4335           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
4336            AllowUnpredictable())) {
4337         EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) |
4338                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4339         return;
4340       }
4341     }
4342   }
4343   Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand);
4344 }
4345 
ldaexh(Condition cond,Register rt,const MemOperand & operand)4346 void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) {
4347   VIXL_ASSERT(AllowAssembler());
4348   CheckIT(cond);
4349   if (operand.IsImmediateZero()) {
4350     Register rn = operand.GetBaseRegister();
4351     if (IsUsingT32()) {
4352       // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4353       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4354         EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4355         AdvanceIT();
4356         return;
4357       }
4358     } else {
4359       // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4360       if (operand.IsOffset() && cond.IsNotNever() &&
4361           (!rn.IsPC() || AllowUnpredictable())) {
4362         EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) |
4363                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4364         return;
4365       }
4366     }
4367   }
4368   Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand);
4369 }
4370 
ldah(Condition cond,Register rt,const MemOperand & operand)4371 void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) {
4372   VIXL_ASSERT(AllowAssembler());
4373   CheckIT(cond);
4374   if (operand.IsImmediateZero()) {
4375     Register rn = operand.GetBaseRegister();
4376     if (IsUsingT32()) {
4377       // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4378       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
4379         EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4380         AdvanceIT();
4381         return;
4382       }
4383     } else {
4384       // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4385       if (operand.IsOffset() && cond.IsNotNever() &&
4386           (!rn.IsPC() || AllowUnpredictable())) {
4387         EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) |
4388                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4389         return;
4390       }
4391     }
4392   }
4393   Delegate(kLdah, &Assembler::ldah, cond, rt, operand);
4394 }
4395 
ldm(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)4396 void Assembler::ldm(Condition cond,
4397                     EncodingSize size,
4398                     Register rn,
4399                     WriteBack write_back,
4400                     RegisterList registers) {
4401   VIXL_ASSERT(AllowAssembler());
4402   CheckIT(cond);
4403   if (IsUsingT32()) {
4404     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1
4405     if (!size.IsWide() && rn.IsLow() &&
4406         (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4407          write_back.DoesWriteBack()) &&
4408         ((registers.GetList() & ~0xff) == 0)) {
4409       EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4410                  GetRegisterListEncoding(registers, 0, 8));
4411       AdvanceIT();
4412       return;
4413     }
4414     // LDM{<c>}{<q>} SP!, <registers> ; T1
4415     if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
4416         ((registers.GetList() & ~0x80ff) == 0)) {
4417       EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
4418                  GetRegisterListEncoding(registers, 0, 8));
4419       AdvanceIT();
4420       return;
4421     }
4422     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2
4423     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
4424       EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4425                  (write_back.GetWriteBackUint32() << 21) |
4426                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
4427                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
4428                  GetRegisterListEncoding(registers, 0, 13));
4429       AdvanceIT();
4430       return;
4431     }
4432   } else {
4433     // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1
4434     if (cond.IsNotNever()) {
4435       EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4436               (write_back.GetWriteBackUint32() << 21) |
4437               GetRegisterListEncoding(registers, 0, 16));
4438       return;
4439     }
4440   }
4441   Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers);
4442 }
4443 
ldmda(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4444 void Assembler::ldmda(Condition cond,
4445                       Register rn,
4446                       WriteBack write_back,
4447                       RegisterList registers) {
4448   VIXL_ASSERT(AllowAssembler());
4449   CheckIT(cond);
4450   if (IsUsingA32()) {
4451     // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4452     if (cond.IsNotNever()) {
4453       EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4454               (write_back.GetWriteBackUint32() << 21) |
4455               GetRegisterListEncoding(registers, 0, 16));
4456       return;
4457     }
4458   }
4459   Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers);
4460 }
4461 
ldmdb(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4462 void Assembler::ldmdb(Condition cond,
4463                       Register rn,
4464                       WriteBack write_back,
4465                       RegisterList registers) {
4466   VIXL_ASSERT(AllowAssembler());
4467   CheckIT(cond);
4468   if (IsUsingT32()) {
4469     // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
4470     if (((registers.GetList() & ~0xdfff) == 0)) {
4471       EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4472                  (write_back.GetWriteBackUint32() << 21) |
4473                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
4474                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
4475                  GetRegisterListEncoding(registers, 0, 13));
4476       AdvanceIT();
4477       return;
4478     }
4479   } else {
4480     // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4481     if (cond.IsNotNever()) {
4482       EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4483               (write_back.GetWriteBackUint32() << 21) |
4484               GetRegisterListEncoding(registers, 0, 16));
4485       return;
4486     }
4487   }
4488   Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers);
4489 }
4490 
ldmea(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4491 void Assembler::ldmea(Condition cond,
4492                       Register rn,
4493                       WriteBack write_back,
4494                       RegisterList registers) {
4495   VIXL_ASSERT(AllowAssembler());
4496   CheckIT(cond);
4497   if (IsUsingT32()) {
4498     // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1
4499     if (((registers.GetList() & ~0xdfff) == 0)) {
4500       EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4501                  (write_back.GetWriteBackUint32() << 21) |
4502                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
4503                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
4504                  GetRegisterListEncoding(registers, 0, 13));
4505       AdvanceIT();
4506       return;
4507     }
4508   } else {
4509     // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4510     if (cond.IsNotNever()) {
4511       EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4512               (write_back.GetWriteBackUint32() << 21) |
4513               GetRegisterListEncoding(registers, 0, 16));
4514       return;
4515     }
4516   }
4517   Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers);
4518 }
4519 
ldmed(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4520 void Assembler::ldmed(Condition cond,
4521                       Register rn,
4522                       WriteBack write_back,
4523                       RegisterList registers) {
4524   VIXL_ASSERT(AllowAssembler());
4525   CheckIT(cond);
4526   if (IsUsingA32()) {
4527     // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
4528     if (cond.IsNotNever()) {
4529       EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4530               (write_back.GetWriteBackUint32() << 21) |
4531               GetRegisterListEncoding(registers, 0, 16));
4532       return;
4533     }
4534   }
4535   Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers);
4536 }
4537 
ldmfa(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4538 void Assembler::ldmfa(Condition cond,
4539                       Register rn,
4540                       WriteBack write_back,
4541                       RegisterList registers) {
4542   VIXL_ASSERT(AllowAssembler());
4543   CheckIT(cond);
4544   if (IsUsingA32()) {
4545     // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4546     if (cond.IsNotNever()) {
4547       EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4548               (write_back.GetWriteBackUint32() << 21) |
4549               GetRegisterListEncoding(registers, 0, 16));
4550       return;
4551     }
4552   }
4553   Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers);
4554 }
4555 
ldmfd(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)4556 void Assembler::ldmfd(Condition cond,
4557                       EncodingSize size,
4558                       Register rn,
4559                       WriteBack write_back,
4560                       RegisterList registers) {
4561   VIXL_ASSERT(AllowAssembler());
4562   CheckIT(cond);
4563   if (IsUsingT32()) {
4564     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
4565     if (!size.IsWide() && rn.IsLow() &&
4566         (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4567          write_back.DoesWriteBack()) &&
4568         ((registers.GetList() & ~0xff) == 0)) {
4569       EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4570                  GetRegisterListEncoding(registers, 0, 8));
4571       AdvanceIT();
4572       return;
4573     }
4574     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2
4575     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
4576       EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4577                  (write_back.GetWriteBackUint32() << 21) |
4578                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
4579                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
4580                  GetRegisterListEncoding(registers, 0, 13));
4581       AdvanceIT();
4582       return;
4583     }
4584   } else {
4585     // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
4586     if (cond.IsNotNever()) {
4587       EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4588               (write_back.GetWriteBackUint32() << 21) |
4589               GetRegisterListEncoding(registers, 0, 16));
4590       return;
4591     }
4592   }
4593   Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers);
4594 }
4595 
ldmib(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4596 void Assembler::ldmib(Condition cond,
4597                       Register rn,
4598                       WriteBack write_back,
4599                       RegisterList registers) {
4600   VIXL_ASSERT(AllowAssembler());
4601   CheckIT(cond);
4602   if (IsUsingA32()) {
4603     // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4604     if (cond.IsNotNever()) {
4605       EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4606               (write_back.GetWriteBackUint32() << 21) |
4607               GetRegisterListEncoding(registers, 0, 16));
4608       return;
4609     }
4610   }
4611   Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers);
4612 }
4613 
ldr(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)4614 void Assembler::ldr(Condition cond,
4615                     EncodingSize size,
4616                     Register rt,
4617                     const MemOperand& operand) {
4618   VIXL_ASSERT(AllowAssembler());
4619   CheckIT(cond);
4620   if (operand.IsImmediate()) {
4621     Register rn = operand.GetBaseRegister();
4622     int32_t offset = operand.GetOffsetImmediate();
4623     if (IsUsingT32()) {
4624       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
4625       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
4626           (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
4627         int32_t offset_ = offset >> 2;
4628         EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) |
4629                    ((offset_ & 0x1f) << 6));
4630         AdvanceIT();
4631         return;
4632       }
4633       // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
4634       if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
4635           ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
4636         int32_t offset_ = offset >> 2;
4637         EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff));
4638         AdvanceIT();
4639         return;
4640       }
4641       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
4642       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
4643           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
4644         EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4645                    (offset & 0xfff));
4646         AdvanceIT();
4647         return;
4648       }
4649       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
4650       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
4651           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
4652         EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4653                    (-offset & 0xff));
4654         AdvanceIT();
4655         return;
4656       }
4657       // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
4658       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4659           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4660         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4661         uint32_t offset_ = abs(offset);
4662         EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4663                    offset_ | (sign << 9));
4664         AdvanceIT();
4665         return;
4666       }
4667       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
4668       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4669           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4670         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4671         uint32_t offset_ = abs(offset);
4672         EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4673                    offset_ | (sign << 9));
4674         AdvanceIT();
4675         return;
4676       }
4677       // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2
4678       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
4679           rn.Is(pc) && operand.IsOffset()) {
4680         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4681         uint32_t offset_ = abs(offset);
4682         EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
4683         AdvanceIT();
4684         return;
4685       }
4686     } else {
4687       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
4688       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
4689           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4690         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4691         uint32_t offset_ = abs(offset);
4692         EmitA32(0x05100000U | (cond.GetCondition() << 28) |
4693                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4694                 (sign << 23));
4695         return;
4696       }
4697       // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
4698       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
4699           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4700         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4701         uint32_t offset_ = abs(offset);
4702         EmitA32(0x04100000U | (cond.GetCondition() << 28) |
4703                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4704                 (sign << 23));
4705         return;
4706       }
4707       // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
4708       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
4709           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4710         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4711         uint32_t offset_ = abs(offset);
4712         EmitA32(0x05300000U | (cond.GetCondition() << 28) |
4713                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4714                 (sign << 23));
4715         return;
4716       }
4717       // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
4718       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
4719           operand.IsOffset() && cond.IsNotNever()) {
4720         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4721         uint32_t offset_ = abs(offset);
4722         EmitA32(0x051f0000U | (cond.GetCondition() << 28) |
4723                 (rt.GetCode() << 12) | offset_ | (sign << 23));
4724         return;
4725       }
4726     }
4727   }
4728   if (operand.IsPlainRegister()) {
4729     Register rn = operand.GetBaseRegister();
4730     Sign sign = operand.GetSign();
4731     Register rm = operand.GetOffsetRegister();
4732     if (IsUsingT32()) {
4733       // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
4734       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
4735           sign.IsPlus() && operand.IsOffset()) {
4736         EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) |
4737                    (rm.GetCode() << 6));
4738         AdvanceIT();
4739         return;
4740       }
4741     }
4742   }
4743   if (operand.IsShiftedRegister()) {
4744     Register rn = operand.GetBaseRegister();
4745     Sign sign = operand.GetSign();
4746     Register rm = operand.GetOffsetRegister();
4747     Shift shift = operand.GetShift();
4748     uint32_t amount = operand.GetShiftAmount();
4749     if (IsUsingT32()) {
4750       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
4751       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
4752           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
4753         EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4754                    rm.GetCode() | (amount << 4));
4755         AdvanceIT();
4756         return;
4757       }
4758     } else {
4759       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
4760       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
4761         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4762         uint32_t shift_ = TypeEncodingValue(shift);
4763         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4764         EmitA32(0x07100000U | (cond.GetCondition() << 28) |
4765                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4766                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4767         return;
4768       }
4769       // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
4770       if (operand.IsShiftValid() && operand.IsPostIndex() &&
4771           cond.IsNotNever()) {
4772         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4773         uint32_t shift_ = TypeEncodingValue(shift);
4774         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4775         EmitA32(0x06100000U | (cond.GetCondition() << 28) |
4776                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4777                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4778         return;
4779       }
4780       // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
4781       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
4782         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
4783         uint32_t shift_ = TypeEncodingValue(shift);
4784         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
4785         EmitA32(0x07300000U | (cond.GetCondition() << 28) |
4786                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4787                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
4788         return;
4789       }
4790     }
4791   }
4792   Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand);
4793 }
4794 
ldr(Condition cond,EncodingSize size,Register rt,Label * label)4795 void Assembler::ldr(Condition cond,
4796                     EncodingSize size,
4797                     Register rt,
4798                     Label* label) {
4799   VIXL_ASSERT(AllowAssembler());
4800   CheckIT(cond);
4801   Label::Offset offset =
4802       label->IsBound()
4803           ? label->GetLocation() -
4804                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
4805           : 0;
4806   if (IsUsingT32()) {
4807     // LDR{<c>}{<q>} <Rt>, <label> ; T1
4808     if (!size.IsWide() && rt.IsLow() &&
4809         ((label->IsBound() && (offset >= 0) && (offset <= 1020) &&
4810           ((offset & 0x3) == 0)) ||
4811          (!label->IsBound() && size.IsNarrow()))) {
4812       static class EmitOp : public Label::LabelEmitOperator {
4813        public:
4814         EmitOp() : Label::LabelEmitOperator(0, 1020) {}
4815         virtual uint32_t Encode(uint32_t instr,
4816                                 Label::Offset pc,
4817                                 const Label* label) const VIXL_OVERRIDE {
4818           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4819           VIXL_ASSERT((offset >= 0) && (offset <= 1020) &&
4820                       ((offset & 0x3) == 0));
4821           const int32_t target = offset >> 2;
4822           return instr | (target & 0xff);
4823         }
4824       } immop;
4825       EmitT32_16(Link(0x4800 | (rt.GetCode() << 8), label, immop));
4826       AdvanceIT();
4827       return;
4828     }
4829     // LDR{<c>}{<q>} <Rt>, <label> ; T2
4830     if (!size.IsNarrow() &&
4831         ((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
4832          !label->IsBound())) {
4833       static class EmitOp : public Label::LabelEmitOperator {
4834        public:
4835         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
4836         virtual uint32_t Encode(uint32_t instr,
4837                                 Label::Offset pc,
4838                                 const Label* label) const VIXL_OVERRIDE {
4839           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4840           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
4841           uint32_t U = (offset >= 0) && !label->IsMinusZero();
4842           int32_t target = abs(offset) | (U << 12);
4843           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
4844         }
4845       } immop;
4846       EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12), label, immop));
4847       AdvanceIT();
4848       return;
4849     }
4850   } else {
4851     // LDR{<c>}{<q>} <Rt>, <label> ; A1
4852     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
4853          !label->IsBound()) &&
4854         cond.IsNotNever()) {
4855       static class EmitOp : public Label::LabelEmitOperator {
4856        public:
4857         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
4858         virtual uint32_t Encode(uint32_t instr,
4859                                 Label::Offset pc,
4860                                 const Label* label) const VIXL_OVERRIDE {
4861           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
4862           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
4863           uint32_t U = (offset >= 0) && !label->IsMinusZero();
4864           int32_t target = abs(offset) | (U << 12);
4865           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
4866         }
4867       } immop;
4868       EmitA32(
4869           Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
4870                label,
4871                immop));
4872       return;
4873     }
4874   }
4875   Delegate(kLdr, &Assembler::ldr, cond, size, rt, label);
4876 }
4877 
ldrb(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)4878 void Assembler::ldrb(Condition cond,
4879                      EncodingSize size,
4880                      Register rt,
4881                      const MemOperand& operand) {
4882   VIXL_ASSERT(AllowAssembler());
4883   CheckIT(cond);
4884   if (operand.IsImmediate()) {
4885     Register rn = operand.GetBaseRegister();
4886     int32_t offset = operand.GetOffsetImmediate();
4887     if (IsUsingT32()) {
4888       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
4889       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
4890           (offset <= 31) && operand.IsOffset()) {
4891         EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) |
4892                    ((offset & 0x1f) << 6));
4893         AdvanceIT();
4894         return;
4895       }
4896       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
4897       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
4898           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
4899         EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4900                    (offset & 0xfff));
4901         AdvanceIT();
4902         return;
4903       }
4904       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
4905       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
4906           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
4907         EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4908                    (-offset & 0xff));
4909         AdvanceIT();
4910         return;
4911       }
4912       // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
4913       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4914           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4915         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4916         uint32_t offset_ = abs(offset);
4917         EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4918                    offset_ | (sign << 9));
4919         AdvanceIT();
4920         return;
4921       }
4922       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
4923       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
4924           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
4925         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4926         uint32_t offset_ = abs(offset);
4927         EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
4928                    offset_ | (sign << 9));
4929         AdvanceIT();
4930         return;
4931       }
4932       // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
4933       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
4934           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
4935         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4936         uint32_t offset_ = abs(offset);
4937         EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
4938         AdvanceIT();
4939         return;
4940       }
4941     } else {
4942       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
4943       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
4944           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4945         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4946         uint32_t offset_ = abs(offset);
4947         EmitA32(0x05500000U | (cond.GetCondition() << 28) |
4948                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4949                 (sign << 23));
4950         return;
4951       }
4952       // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
4953       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
4954           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4955         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4956         uint32_t offset_ = abs(offset);
4957         EmitA32(0x04500000U | (cond.GetCondition() << 28) |
4958                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4959                 (sign << 23));
4960         return;
4961       }
4962       // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
4963       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
4964           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
4965         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4966         uint32_t offset_ = abs(offset);
4967         EmitA32(0x05700000U | (cond.GetCondition() << 28) |
4968                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
4969                 (sign << 23));
4970         return;
4971       }
4972       // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
4973       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
4974           operand.IsOffset() && cond.IsNotNever()) {
4975         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
4976         uint32_t offset_ = abs(offset);
4977         EmitA32(0x055f0000U | (cond.GetCondition() << 28) |
4978                 (rt.GetCode() << 12) | offset_ | (sign << 23));
4979         return;
4980       }
4981     }
4982   }
4983   if (operand.IsPlainRegister()) {
4984     Register rn = operand.GetBaseRegister();
4985     Sign sign = operand.GetSign();
4986     Register rm = operand.GetOffsetRegister();
4987     if (IsUsingT32()) {
4988       // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
4989       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
4990           sign.IsPlus() && operand.IsOffset()) {
4991         EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) |
4992                    (rm.GetCode() << 6));
4993         AdvanceIT();
4994         return;
4995       }
4996     }
4997   }
4998   if (operand.IsShiftedRegister()) {
4999     Register rn = operand.GetBaseRegister();
5000     Sign sign = operand.GetSign();
5001     Register rm = operand.GetOffsetRegister();
5002     Shift shift = operand.GetShift();
5003     uint32_t amount = operand.GetShiftAmount();
5004     if (IsUsingT32()) {
5005       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5006       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5007           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5008         EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5009                    rm.GetCode() | (amount << 4));
5010         AdvanceIT();
5011         return;
5012       }
5013     } else {
5014       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
5015       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
5016         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5017         uint32_t shift_ = TypeEncodingValue(shift);
5018         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5019         EmitA32(0x07500000U | (cond.GetCondition() << 28) |
5020                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5021                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5022         return;
5023       }
5024       // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
5025       if (operand.IsShiftValid() && operand.IsPostIndex() &&
5026           cond.IsNotNever()) {
5027         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5028         uint32_t shift_ = TypeEncodingValue(shift);
5029         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5030         EmitA32(0x06500000U | (cond.GetCondition() << 28) |
5031                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5032                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5033         return;
5034       }
5035       // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
5036       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
5037         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5038         uint32_t shift_ = TypeEncodingValue(shift);
5039         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5040         EmitA32(0x07700000U | (cond.GetCondition() << 28) |
5041                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5042                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5043         return;
5044       }
5045     }
5046   }
5047   Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand);
5048 }
5049 
ldrb(Condition cond,Register rt,Label * label)5050 void Assembler::ldrb(Condition cond, Register rt, Label* label) {
5051   VIXL_ASSERT(AllowAssembler());
5052   CheckIT(cond);
5053   Label::Offset offset =
5054       label->IsBound()
5055           ? label->GetLocation() -
5056                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5057           : 0;
5058   if (IsUsingT32()) {
5059     // LDRB{<c>}{<q>} <Rt>, <label> ; T1
5060     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5061          !label->IsBound()) &&
5062         !rt.Is(pc)) {
5063       static class EmitOp : public Label::LabelEmitOperator {
5064        public:
5065         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5066         virtual uint32_t Encode(uint32_t instr,
5067                                 Label::Offset pc,
5068                                 const Label* label) const VIXL_OVERRIDE {
5069           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5070           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5071           uint32_t U = (offset >= 0) && !label->IsMinusZero();
5072           int32_t target = abs(offset) | (U << 12);
5073           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5074         }
5075       } immop;
5076       EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12), label, immop));
5077       AdvanceIT();
5078       return;
5079     }
5080   } else {
5081     // LDRB{<c>}{<q>} <Rt>, <label> ; A1
5082     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5083          !label->IsBound()) &&
5084         cond.IsNotNever()) {
5085       static class EmitOp : public Label::LabelEmitOperator {
5086        public:
5087         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5088         virtual uint32_t Encode(uint32_t instr,
5089                                 Label::Offset pc,
5090                                 const Label* label) const VIXL_OVERRIDE {
5091           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5092           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5093           uint32_t U = (offset >= 0) && !label->IsMinusZero();
5094           int32_t target = abs(offset) | (U << 12);
5095           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5096         }
5097       } immop;
5098       EmitA32(
5099           Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5100                label,
5101                immop));
5102       return;
5103     }
5104   }
5105   Delegate(kLdrb, &Assembler::ldrb, cond, rt, label);
5106 }
5107 
ldrd(Condition cond,Register rt,Register rt2,const MemOperand & operand)5108 void Assembler::ldrd(Condition cond,
5109                      Register rt,
5110                      Register rt2,
5111                      const MemOperand& operand) {
5112   VIXL_ASSERT(AllowAssembler());
5113   CheckIT(cond);
5114   if (operand.IsImmediate()) {
5115     Register rn = operand.GetBaseRegister();
5116     int32_t offset = operand.GetOffsetImmediate();
5117     if (IsUsingT32()) {
5118       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
5119       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5120           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
5121         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5122         uint32_t offset_ = abs(offset) >> 2;
5123         EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5124                    (rn.GetCode() << 16) | offset_ | (sign << 23));
5125         AdvanceIT();
5126         return;
5127       }
5128       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
5129       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5130           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5131         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5132         uint32_t offset_ = abs(offset) >> 2;
5133         EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5134                    (rn.GetCode() << 16) | offset_ | (sign << 23));
5135         AdvanceIT();
5136         return;
5137       }
5138       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
5139       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5140           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5141         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5142         uint32_t offset_ = abs(offset) >> 2;
5143         EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5144                    (rn.GetCode() << 16) | offset_ | (sign << 23));
5145         AdvanceIT();
5146         return;
5147       }
5148       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1
5149       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5150           operand.IsOffset()) {
5151         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5152         uint32_t offset_ = abs(offset);
5153         EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5154                    offset_ | (sign << 23));
5155         AdvanceIT();
5156         return;
5157       }
5158     } else {
5159       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
5160       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5161           (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5162           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5163           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5164         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5165         uint32_t offset_ = abs(offset);
5166         EmitA32(0x014000d0U | (cond.GetCondition() << 28) |
5167                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5168                 ((offset_ & 0xf0) << 4) | (sign << 23));
5169         return;
5170       }
5171       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
5172       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5173           (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5174           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5175           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5176         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5177         uint32_t offset_ = abs(offset);
5178         EmitA32(0x004000d0U | (cond.GetCondition() << 28) |
5179                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5180                 ((offset_ & 0xf0) << 4) | (sign << 23));
5181         return;
5182       }
5183       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
5184       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5185           (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5186           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5187           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5188         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5189         uint32_t offset_ = abs(offset);
5190         EmitA32(0x016000d0U | (cond.GetCondition() << 28) |
5191                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5192                 ((offset_ & 0xf0) << 4) | (sign << 23));
5193         return;
5194       }
5195       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1
5196       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5197           (offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5198           operand.IsOffset() && cond.IsNotNever() &&
5199           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5200         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5201         uint32_t offset_ = abs(offset);
5202         EmitA32(0x014f00d0U | (cond.GetCondition() << 28) |
5203                 (rt.GetCode() << 12) | (offset_ & 0xf) |
5204                 ((offset_ & 0xf0) << 4) | (sign << 23));
5205         return;
5206       }
5207     }
5208   }
5209   if (operand.IsPlainRegister()) {
5210     Register rn = operand.GetBaseRegister();
5211     Sign sign = operand.GetSign();
5212     Register rm = operand.GetOffsetRegister();
5213     if (IsUsingA32()) {
5214       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
5215       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5216           operand.IsOffset() && cond.IsNotNever() &&
5217           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5218         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5219         EmitA32(0x010000d0U | (cond.GetCondition() << 28) |
5220                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5221                 (sign_ << 23));
5222         return;
5223       }
5224       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
5225       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5226           operand.IsPostIndex() && cond.IsNotNever() &&
5227           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5228         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5229         EmitA32(0x000000d0U | (cond.GetCondition() << 28) |
5230                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5231                 (sign_ << 23));
5232         return;
5233       }
5234       // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
5235       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5236           operand.IsPreIndex() && cond.IsNotNever() &&
5237           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5238         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5239         EmitA32(0x012000d0U | (cond.GetCondition() << 28) |
5240                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5241                 (sign_ << 23));
5242         return;
5243       }
5244     }
5245   }
5246   Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand);
5247 }
5248 
ldrd(Condition cond,Register rt,Register rt2,Label * label)5249 void Assembler::ldrd(Condition cond, Register rt, Register rt2, Label* label) {
5250   VIXL_ASSERT(AllowAssembler());
5251   CheckIT(cond);
5252   Label::Offset offset =
5253       label->IsBound()
5254           ? label->GetLocation() -
5255                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5256           : 0;
5257   if (IsUsingT32()) {
5258     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
5259     if (((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
5260           ((offset & 0x3) == 0)) ||
5261          !label->IsBound())) {
5262       static class EmitOp : public Label::LabelEmitOperator {
5263        public:
5264         EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
5265         virtual uint32_t Encode(uint32_t instr,
5266                                 Label::Offset pc,
5267                                 const Label* label) const VIXL_OVERRIDE {
5268           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5269           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
5270                       ((offset & 0x3) == 0));
5271           int32_t target = offset >> 2;
5272           uint32_t U = (target >= 0) && !label->IsMinusZero();
5273           target = abs(target) | (U << 8);
5274           return instr | (target & 0xff) | ((target & 0x100) << 15);
5275         }
5276       } immop;
5277       EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8),
5278                       label,
5279                       immop));
5280       AdvanceIT();
5281       return;
5282     }
5283   } else {
5284     // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
5285     if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5286         ((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5287          !label->IsBound()) &&
5288         cond.IsNotNever() &&
5289         ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
5290       static class EmitOp : public Label::LabelEmitOperator {
5291        public:
5292         EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5293         virtual uint32_t Encode(uint32_t instr,
5294                                 Label::Offset pc,
5295                                 const Label* label) const VIXL_OVERRIDE {
5296           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5297           VIXL_ASSERT((offset >= -255) && (offset <= 255));
5298           uint32_t U = (offset >= 0) && !label->IsMinusZero();
5299           int32_t target = abs(offset) | (U << 8);
5300           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5301                  ((target & 0x100) << 15);
5302         }
5303       } immop;
5304       EmitA32(
5305           Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5306                label,
5307                immop));
5308       return;
5309     }
5310   }
5311   Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, label);
5312 }
5313 
ldrex(Condition cond,Register rt,const MemOperand & operand)5314 void Assembler::ldrex(Condition cond, Register rt, 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       // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1
5322       if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
5323           operand.IsOffset()) {
5324         int32_t offset_ = offset >> 2;
5325         EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5326                    (offset_ & 0xff));
5327         AdvanceIT();
5328         return;
5329       }
5330     } else {
5331       // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1
5332       if ((offset == 0) && operand.IsOffset() && cond.IsNotNever()) {
5333         EmitA32(0x01900f9fU | (cond.GetCondition() << 28) |
5334                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5335         return;
5336       }
5337     }
5338   }
5339   Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand);
5340 }
5341 
ldrexb(Condition cond,Register rt,const MemOperand & operand)5342 void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) {
5343   VIXL_ASSERT(AllowAssembler());
5344   CheckIT(cond);
5345   if (operand.IsImmediateZero()) {
5346     Register rn = operand.GetBaseRegister();
5347     if (IsUsingT32()) {
5348       // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
5349       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
5350         EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5351         AdvanceIT();
5352         return;
5353       }
5354     } else {
5355       // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
5356       if (operand.IsOffset() && cond.IsNotNever() &&
5357           (!rn.IsPC() || AllowUnpredictable())) {
5358         EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) |
5359                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5360         return;
5361       }
5362     }
5363   }
5364   Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand);
5365 }
5366 
ldrexd(Condition cond,Register rt,Register rt2,const MemOperand & operand)5367 void Assembler::ldrexd(Condition cond,
5368                        Register rt,
5369                        Register rt2,
5370                        const MemOperand& operand) {
5371   VIXL_ASSERT(AllowAssembler());
5372   CheckIT(cond);
5373   if (operand.IsImmediateZero()) {
5374     Register rn = operand.GetBaseRegister();
5375     if (IsUsingT32()) {
5376       // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
5377       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
5378         EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5379                    (rn.GetCode() << 16));
5380         AdvanceIT();
5381         return;
5382       }
5383     } else {
5384       // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
5385       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5386           operand.IsOffset() && cond.IsNotNever() &&
5387           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
5388            AllowUnpredictable())) {
5389         EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) |
5390                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5391         return;
5392       }
5393     }
5394   }
5395   Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand);
5396 }
5397 
ldrexh(Condition cond,Register rt,const MemOperand & operand)5398 void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) {
5399   VIXL_ASSERT(AllowAssembler());
5400   CheckIT(cond);
5401   if (operand.IsImmediateZero()) {
5402     Register rn = operand.GetBaseRegister();
5403     if (IsUsingT32()) {
5404       // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
5405       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
5406         EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5407         AdvanceIT();
5408         return;
5409       }
5410     } else {
5411       // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
5412       if (operand.IsOffset() && cond.IsNotNever() &&
5413           (!rn.IsPC() || AllowUnpredictable())) {
5414         EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) |
5415                 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5416         return;
5417       }
5418     }
5419   }
5420   Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand);
5421 }
5422 
ldrh(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)5423 void Assembler::ldrh(Condition cond,
5424                      EncodingSize size,
5425                      Register rt,
5426                      const MemOperand& operand) {
5427   VIXL_ASSERT(AllowAssembler());
5428   CheckIT(cond);
5429   if (operand.IsImmediate()) {
5430     Register rn = operand.GetBaseRegister();
5431     int32_t offset = operand.GetOffsetImmediate();
5432     if (IsUsingT32()) {
5433       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5434       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
5435           (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
5436         int32_t offset_ = offset >> 1;
5437         EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) |
5438                    ((offset_ & 0x1f) << 6));
5439         AdvanceIT();
5440         return;
5441       }
5442       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
5443       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5444           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5445         EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5446                    (offset & 0xfff));
5447         AdvanceIT();
5448         return;
5449       }
5450       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
5451       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5452           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5453         EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5454                    (-offset & 0xff));
5455         AdvanceIT();
5456         return;
5457       }
5458       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
5459       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5460           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5461         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5462         uint32_t offset_ = abs(offset);
5463         EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5464                    offset_ | (sign << 9));
5465         AdvanceIT();
5466         return;
5467       }
5468       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
5469       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5470           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5471         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5472         uint32_t offset_ = abs(offset);
5473         EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5474                    offset_ | (sign << 9));
5475         AdvanceIT();
5476         return;
5477       }
5478       // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5479       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5480           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5481         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5482         uint32_t offset_ = abs(offset);
5483         EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5484         AdvanceIT();
5485         return;
5486       }
5487     } else {
5488       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
5489       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5490           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5491         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5492         uint32_t offset_ = abs(offset);
5493         EmitA32(0x015000b0U | (cond.GetCondition() << 28) |
5494                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5495                 ((offset_ & 0xf0) << 4) | (sign << 23));
5496         return;
5497       }
5498       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
5499       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5500           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5501         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5502         uint32_t offset_ = abs(offset);
5503         EmitA32(0x005000b0U | (cond.GetCondition() << 28) |
5504                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5505                 ((offset_ & 0xf0) << 4) | (sign << 23));
5506         return;
5507       }
5508       // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
5509       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5510           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5511         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5512         uint32_t offset_ = abs(offset);
5513         EmitA32(0x017000b0U | (cond.GetCondition() << 28) |
5514                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5515                 ((offset_ & 0xf0) << 4) | (sign << 23));
5516         return;
5517       }
5518       // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5519       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5520           operand.IsOffset() && cond.IsNotNever()) {
5521         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5522         uint32_t offset_ = abs(offset);
5523         EmitA32(0x015f00b0U | (cond.GetCondition() << 28) |
5524                 (rt.GetCode() << 12) | (offset_ & 0xf) |
5525                 ((offset_ & 0xf0) << 4) | (sign << 23));
5526         return;
5527       }
5528     }
5529   }
5530   if (operand.IsPlainRegister()) {
5531     Register rn = operand.GetBaseRegister();
5532     Sign sign = operand.GetSign();
5533     Register rm = operand.GetOffsetRegister();
5534     if (IsUsingT32()) {
5535       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5536       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5537           sign.IsPlus() && operand.IsOffset()) {
5538         EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) |
5539                    (rm.GetCode() << 6));
5540         AdvanceIT();
5541         return;
5542       }
5543     } else {
5544       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5545       if (operand.IsOffset() && cond.IsNotNever()) {
5546         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5547         EmitA32(0x011000b0U | (cond.GetCondition() << 28) |
5548                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5549                 (sign_ << 23));
5550         return;
5551       }
5552       // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5553       if (operand.IsPostIndex() && cond.IsNotNever()) {
5554         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5555         EmitA32(0x001000b0U | (cond.GetCondition() << 28) |
5556                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5557                 (sign_ << 23));
5558         return;
5559       }
5560       // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5561       if (operand.IsPreIndex() && cond.IsNotNever()) {
5562         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5563         EmitA32(0x013000b0U | (cond.GetCondition() << 28) |
5564                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5565                 (sign_ << 23));
5566         return;
5567       }
5568     }
5569   }
5570   if (operand.IsShiftedRegister()) {
5571     Register rn = operand.GetBaseRegister();
5572     Sign sign = operand.GetSign();
5573     Register rm = operand.GetOffsetRegister();
5574     Shift shift = operand.GetShift();
5575     uint32_t amount = operand.GetShiftAmount();
5576     if (IsUsingT32()) {
5577       // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5578       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5579           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5580         EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5581                    rm.GetCode() | (amount << 4));
5582         AdvanceIT();
5583         return;
5584       }
5585     }
5586   }
5587   Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand);
5588 }
5589 
ldrh(Condition cond,Register rt,Label * label)5590 void Assembler::ldrh(Condition cond, Register rt, Label* label) {
5591   VIXL_ASSERT(AllowAssembler());
5592   CheckIT(cond);
5593   Label::Offset offset =
5594       label->IsBound()
5595           ? label->GetLocation() -
5596                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5597           : 0;
5598   if (IsUsingT32()) {
5599     // LDRH{<c>}{<q>} <Rt>, <label> ; T1
5600     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5601          !label->IsBound()) &&
5602         !rt.Is(pc)) {
5603       static class EmitOp : public Label::LabelEmitOperator {
5604        public:
5605         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5606         virtual uint32_t Encode(uint32_t instr,
5607                                 Label::Offset pc,
5608                                 const Label* label) const VIXL_OVERRIDE {
5609           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5610           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5611           uint32_t U = (offset >= 0) && !label->IsMinusZero();
5612           int32_t target = abs(offset) | (U << 12);
5613           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5614         }
5615       } immop;
5616       EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12), label, immop));
5617       AdvanceIT();
5618       return;
5619     }
5620   } else {
5621     // LDRH{<c>}{<q>} <Rt>, <label> ; A1
5622     if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5623          !label->IsBound()) &&
5624         cond.IsNotNever()) {
5625       static class EmitOp : public Label::LabelEmitOperator {
5626        public:
5627         EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5628         virtual uint32_t Encode(uint32_t instr,
5629                                 Label::Offset pc,
5630                                 const Label* label) const VIXL_OVERRIDE {
5631           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5632           VIXL_ASSERT((offset >= -255) && (offset <= 255));
5633           uint32_t U = (offset >= 0) && !label->IsMinusZero();
5634           int32_t target = abs(offset) | (U << 8);
5635           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5636                  ((target & 0x100) << 15);
5637         }
5638       } immop;
5639       EmitA32(
5640           Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5641                label,
5642                immop));
5643       return;
5644     }
5645   }
5646   Delegate(kLdrh, &Assembler::ldrh, cond, rt, label);
5647 }
5648 
ldrsb(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)5649 void Assembler::ldrsb(Condition cond,
5650                       EncodingSize size,
5651                       Register rt,
5652                       const MemOperand& operand) {
5653   VIXL_ASSERT(AllowAssembler());
5654   CheckIT(cond);
5655   if (operand.IsImmediate()) {
5656     Register rn = operand.GetBaseRegister();
5657     int32_t offset = operand.GetOffsetImmediate();
5658     if (IsUsingT32()) {
5659       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5660       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5661           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5662         EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5663                    (offset & 0xfff));
5664         AdvanceIT();
5665         return;
5666       }
5667       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
5668       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5669           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5670         EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5671                    (-offset & 0xff));
5672         AdvanceIT();
5673         return;
5674       }
5675       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
5676       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5677           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5678         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5679         uint32_t offset_ = abs(offset);
5680         EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5681                    offset_ | (sign << 9));
5682         AdvanceIT();
5683         return;
5684       }
5685       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
5686       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5687           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5688         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5689         uint32_t offset_ = abs(offset);
5690         EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5691                    offset_ | (sign << 9));
5692         AdvanceIT();
5693         return;
5694       }
5695       // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5696       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5697           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5698         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5699         uint32_t offset_ = abs(offset);
5700         EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5701         AdvanceIT();
5702         return;
5703       }
5704     } else {
5705       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
5706       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5707           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5708         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5709         uint32_t offset_ = abs(offset);
5710         EmitA32(0x015000d0U | (cond.GetCondition() << 28) |
5711                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5712                 ((offset_ & 0xf0) << 4) | (sign << 23));
5713         return;
5714       }
5715       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
5716       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5717           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5718         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5719         uint32_t offset_ = abs(offset);
5720         EmitA32(0x005000d0U | (cond.GetCondition() << 28) |
5721                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5722                 ((offset_ & 0xf0) << 4) | (sign << 23));
5723         return;
5724       }
5725       // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
5726       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5727           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5728         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5729         uint32_t offset_ = abs(offset);
5730         EmitA32(0x017000d0U | (cond.GetCondition() << 28) |
5731                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5732                 ((offset_ & 0xf0) << 4) | (sign << 23));
5733         return;
5734       }
5735       // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5736       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5737           operand.IsOffset() && cond.IsNotNever()) {
5738         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5739         uint32_t offset_ = abs(offset);
5740         EmitA32(0x015f00d0U | (cond.GetCondition() << 28) |
5741                 (rt.GetCode() << 12) | (offset_ & 0xf) |
5742                 ((offset_ & 0xf0) << 4) | (sign << 23));
5743         return;
5744       }
5745     }
5746   }
5747   if (operand.IsPlainRegister()) {
5748     Register rn = operand.GetBaseRegister();
5749     Sign sign = operand.GetSign();
5750     Register rm = operand.GetOffsetRegister();
5751     if (IsUsingT32()) {
5752       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5753       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5754           sign.IsPlus() && operand.IsOffset()) {
5755         EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) |
5756                    (rm.GetCode() << 6));
5757         AdvanceIT();
5758         return;
5759       }
5760     } else {
5761       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5762       if (operand.IsOffset() && cond.IsNotNever()) {
5763         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5764         EmitA32(0x011000d0U | (cond.GetCondition() << 28) |
5765                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5766                 (sign_ << 23));
5767         return;
5768       }
5769       // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5770       if (operand.IsPostIndex() && cond.IsNotNever()) {
5771         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5772         EmitA32(0x001000d0U | (cond.GetCondition() << 28) |
5773                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5774                 (sign_ << 23));
5775         return;
5776       }
5777       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5778       if (operand.IsPreIndex() && cond.IsNotNever()) {
5779         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5780         EmitA32(0x013000d0U | (cond.GetCondition() << 28) |
5781                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5782                 (sign_ << 23));
5783         return;
5784       }
5785     }
5786   }
5787   if (operand.IsShiftedRegister()) {
5788     Register rn = operand.GetBaseRegister();
5789     Sign sign = operand.GetSign();
5790     Register rm = operand.GetOffsetRegister();
5791     Shift shift = operand.GetShift();
5792     uint32_t amount = operand.GetShiftAmount();
5793     if (IsUsingT32()) {
5794       // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5795       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5796           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5797         EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5798                    rm.GetCode() | (amount << 4));
5799         AdvanceIT();
5800         return;
5801       }
5802     }
5803   }
5804   Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand);
5805 }
5806 
ldrsb(Condition cond,Register rt,Label * label)5807 void Assembler::ldrsb(Condition cond, Register rt, Label* label) {
5808   VIXL_ASSERT(AllowAssembler());
5809   CheckIT(cond);
5810   Label::Offset offset =
5811       label->IsBound()
5812           ? label->GetLocation() -
5813                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5814           : 0;
5815   if (IsUsingT32()) {
5816     // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
5817     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5818          !label->IsBound()) &&
5819         !rt.Is(pc)) {
5820       static class EmitOp : public Label::LabelEmitOperator {
5821        public:
5822         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
5823         virtual uint32_t Encode(uint32_t instr,
5824                                 Label::Offset pc,
5825                                 const Label* label) const VIXL_OVERRIDE {
5826           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5827           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
5828           uint32_t U = (offset >= 0) && !label->IsMinusZero();
5829           int32_t target = abs(offset) | (U << 12);
5830           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5831         }
5832       } immop;
5833       EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12), label, immop));
5834       AdvanceIT();
5835       return;
5836     }
5837   } else {
5838     // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
5839     if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
5840          !label->IsBound()) &&
5841         cond.IsNotNever()) {
5842       static class EmitOp : public Label::LabelEmitOperator {
5843        public:
5844         EmitOp() : Label::LabelEmitOperator(-255, 255) {}
5845         virtual uint32_t Encode(uint32_t instr,
5846                                 Label::Offset pc,
5847                                 const Label* label) const VIXL_OVERRIDE {
5848           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
5849           VIXL_ASSERT((offset >= -255) && (offset <= 255));
5850           uint32_t U = (offset >= 0) && !label->IsMinusZero();
5851           int32_t target = abs(offset) | (U << 8);
5852           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5853                  ((target & 0x100) << 15);
5854         }
5855       } immop;
5856       EmitA32(
5857           Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5858                label,
5859                immop));
5860       return;
5861     }
5862   }
5863   Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, label);
5864 }
5865 
ldrsh(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)5866 void Assembler::ldrsh(Condition cond,
5867                       EncodingSize size,
5868                       Register rt,
5869                       const MemOperand& operand) {
5870   VIXL_ASSERT(AllowAssembler());
5871   CheckIT(cond);
5872   if (operand.IsImmediate()) {
5873     Register rn = operand.GetBaseRegister();
5874     int32_t offset = operand.GetOffsetImmediate();
5875     if (IsUsingT32()) {
5876       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5877       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5878           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5879         EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5880                    (offset & 0xfff));
5881         AdvanceIT();
5882         return;
5883       }
5884       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
5885       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5886           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5887         EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5888                    (-offset & 0xff));
5889         AdvanceIT();
5890         return;
5891       }
5892       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
5893       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5894           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5895         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5896         uint32_t offset_ = abs(offset);
5897         EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5898                    offset_ | (sign << 9));
5899         AdvanceIT();
5900         return;
5901       }
5902       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
5903       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5904           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5905         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5906         uint32_t offset_ = abs(offset);
5907         EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5908                    offset_ | (sign << 9));
5909         AdvanceIT();
5910         return;
5911       }
5912       // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5913       if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5914           rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5915         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5916         uint32_t offset_ = abs(offset);
5917         EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5918         AdvanceIT();
5919         return;
5920       }
5921     } else {
5922       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
5923       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5924           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5925         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5926         uint32_t offset_ = abs(offset);
5927         EmitA32(0x015000f0U | (cond.GetCondition() << 28) |
5928                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5929                 ((offset_ & 0xf0) << 4) | (sign << 23));
5930         return;
5931       }
5932       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
5933       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5934           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5935         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5936         uint32_t offset_ = abs(offset);
5937         EmitA32(0x005000f0U | (cond.GetCondition() << 28) |
5938                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5939                 ((offset_ & 0xf0) << 4) | (sign << 23));
5940         return;
5941       }
5942       // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
5943       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5944           cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5945         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5946         uint32_t offset_ = abs(offset);
5947         EmitA32(0x017000f0U | (cond.GetCondition() << 28) |
5948                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5949                 ((offset_ & 0xf0) << 4) | (sign << 23));
5950         return;
5951       }
5952       // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5953       if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5954           operand.IsOffset() && cond.IsNotNever()) {
5955         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5956         uint32_t offset_ = abs(offset);
5957         EmitA32(0x015f00f0U | (cond.GetCondition() << 28) |
5958                 (rt.GetCode() << 12) | (offset_ & 0xf) |
5959                 ((offset_ & 0xf0) << 4) | (sign << 23));
5960         return;
5961       }
5962     }
5963   }
5964   if (operand.IsPlainRegister()) {
5965     Register rn = operand.GetBaseRegister();
5966     Sign sign = operand.GetSign();
5967     Register rm = operand.GetOffsetRegister();
5968     if (IsUsingT32()) {
5969       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5970       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5971           sign.IsPlus() && operand.IsOffset()) {
5972         EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) |
5973                    (rm.GetCode() << 6));
5974         AdvanceIT();
5975         return;
5976       }
5977     } else {
5978       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
5979       if (operand.IsOffset() && cond.IsNotNever()) {
5980         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5981         EmitA32(0x011000f0U | (cond.GetCondition() << 28) |
5982                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5983                 (sign_ << 23));
5984         return;
5985       }
5986       // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
5987       if (operand.IsPostIndex() && cond.IsNotNever()) {
5988         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5989         EmitA32(0x001000f0U | (cond.GetCondition() << 28) |
5990                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5991                 (sign_ << 23));
5992         return;
5993       }
5994       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
5995       if (operand.IsPreIndex() && cond.IsNotNever()) {
5996         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5997         EmitA32(0x013000f0U | (cond.GetCondition() << 28) |
5998                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5999                 (sign_ << 23));
6000         return;
6001       }
6002     }
6003   }
6004   if (operand.IsShiftedRegister()) {
6005     Register rn = operand.GetBaseRegister();
6006     Sign sign = operand.GetSign();
6007     Register rm = operand.GetOffsetRegister();
6008     Shift shift = operand.GetShift();
6009     uint32_t amount = operand.GetShiftAmount();
6010     if (IsUsingT32()) {
6011       // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
6012       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
6013           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
6014         EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6015                    rm.GetCode() | (amount << 4));
6016         AdvanceIT();
6017         return;
6018       }
6019     }
6020   }
6021   Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand);
6022 }
6023 
ldrsh(Condition cond,Register rt,Label * label)6024 void Assembler::ldrsh(Condition cond, Register rt, Label* label) {
6025   VIXL_ASSERT(AllowAssembler());
6026   CheckIT(cond);
6027   Label::Offset offset =
6028       label->IsBound()
6029           ? label->GetLocation() -
6030                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
6031           : 0;
6032   if (IsUsingT32()) {
6033     // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
6034     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
6035          !label->IsBound()) &&
6036         !rt.Is(pc)) {
6037       static class EmitOp : public Label::LabelEmitOperator {
6038        public:
6039         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
6040         virtual uint32_t Encode(uint32_t instr,
6041                                 Label::Offset pc,
6042                                 const Label* label) const VIXL_OVERRIDE {
6043           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
6044           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
6045           uint32_t U = (offset >= 0) && !label->IsMinusZero();
6046           int32_t target = abs(offset) | (U << 12);
6047           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
6048         }
6049       } immop;
6050       EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12), label, immop));
6051       AdvanceIT();
6052       return;
6053     }
6054   } else {
6055     // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
6056     if (((label->IsBound() && (offset >= -255) && (offset <= 255)) ||
6057          !label->IsBound()) &&
6058         cond.IsNotNever()) {
6059       static class EmitOp : public Label::LabelEmitOperator {
6060        public:
6061         EmitOp() : Label::LabelEmitOperator(-255, 255) {}
6062         virtual uint32_t Encode(uint32_t instr,
6063                                 Label::Offset pc,
6064                                 const Label* label) const VIXL_OVERRIDE {
6065           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
6066           VIXL_ASSERT((offset >= -255) && (offset <= 255));
6067           uint32_t U = (offset >= 0) && !label->IsMinusZero();
6068           int32_t target = abs(offset) | (U << 8);
6069           return instr | (target & 0xf) | ((target & 0xf0) << 4) |
6070                  ((target & 0x100) << 15);
6071         }
6072       } immop;
6073       EmitA32(
6074           Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
6075                label,
6076                immop));
6077       return;
6078     }
6079   }
6080   Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, label);
6081 }
6082 
lsl(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6083 void Assembler::lsl(Condition cond,
6084                     EncodingSize size,
6085                     Register rd,
6086                     Register rm,
6087                     const Operand& operand) {
6088   VIXL_ASSERT(AllowAssembler());
6089   CheckIT(cond);
6090   if (operand.IsImmediate()) {
6091     uint32_t imm = operand.GetImmediate();
6092     if (IsUsingT32()) {
6093       // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6094       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6095           (imm >= 1) && (imm <= 31)) {
6096         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6097         AdvanceIT();
6098         return;
6099       }
6100       // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6101       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
6102         EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6103                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6104         AdvanceIT();
6105         return;
6106       }
6107     } else {
6108       // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6109       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6110         EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
6111                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6112         return;
6113       }
6114     }
6115   }
6116   if (operand.IsPlainRegister()) {
6117     Register rs = operand.GetBaseRegister();
6118     if (IsUsingT32()) {
6119       // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6120       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6121           rs.IsLow()) {
6122         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6123         AdvanceIT();
6124         return;
6125       }
6126       // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6127       if (!size.IsNarrow()) {
6128         EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6129                    rs.GetCode());
6130         AdvanceIT();
6131         return;
6132       }
6133     } else {
6134       // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6135       if (cond.IsNotNever()) {
6136         EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
6137                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6138         return;
6139       }
6140     }
6141   }
6142   Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand);
6143 }
6144 
lsls(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6145 void Assembler::lsls(Condition cond,
6146                      EncodingSize size,
6147                      Register rd,
6148                      Register rm,
6149                      const Operand& operand) {
6150   VIXL_ASSERT(AllowAssembler());
6151   CheckIT(cond);
6152   if (operand.IsImmediate()) {
6153     uint32_t imm = operand.GetImmediate();
6154     if (IsUsingT32()) {
6155       // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6156       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6157           (imm >= 1) && (imm <= 31)) {
6158         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6159         AdvanceIT();
6160         return;
6161       }
6162       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6163       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
6164         EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6165                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6166         AdvanceIT();
6167         return;
6168       }
6169     } else {
6170       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6171       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6172         EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
6173                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6174         return;
6175       }
6176     }
6177   }
6178   if (operand.IsPlainRegister()) {
6179     Register rs = operand.GetBaseRegister();
6180     if (IsUsingT32()) {
6181       // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6182       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6183           rs.IsLow()) {
6184         EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6185         AdvanceIT();
6186         return;
6187       }
6188       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6189       if (!size.IsNarrow()) {
6190         EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6191                    rs.GetCode());
6192         AdvanceIT();
6193         return;
6194       }
6195     } else {
6196       // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6197       if (cond.IsNotNever()) {
6198         EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
6199                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6200         return;
6201       }
6202     }
6203   }
6204   Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand);
6205 }
6206 
lsr(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6207 void Assembler::lsr(Condition cond,
6208                     EncodingSize size,
6209                     Register rd,
6210                     Register rm,
6211                     const Operand& operand) {
6212   VIXL_ASSERT(AllowAssembler());
6213   CheckIT(cond);
6214   if (operand.IsImmediate()) {
6215     uint32_t imm = operand.GetImmediate();
6216     if (IsUsingT32()) {
6217       // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6218       if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6219           (imm >= 1) && (imm <= 32)) {
6220         uint32_t amount_ = imm % 32;
6221         EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6222                    (amount_ << 6));
6223         AdvanceIT();
6224         return;
6225       }
6226       // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6227       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
6228         uint32_t amount_ = imm % 32;
6229         EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6230                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6231         AdvanceIT();
6232         return;
6233       }
6234     } else {
6235       // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6236       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6237         uint32_t amount_ = imm % 32;
6238         EmitA32(0x01a00020U | (cond.GetCondition() << 28) |
6239                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6240         return;
6241       }
6242     }
6243   }
6244   if (operand.IsPlainRegister()) {
6245     Register rs = operand.GetBaseRegister();
6246     if (IsUsingT32()) {
6247       // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6248       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6249           rs.IsLow()) {
6250         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6251         AdvanceIT();
6252         return;
6253       }
6254       // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6255       if (!size.IsNarrow()) {
6256         EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6257                    rs.GetCode());
6258         AdvanceIT();
6259         return;
6260       }
6261     } else {
6262       // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6263       if (cond.IsNotNever()) {
6264         EmitA32(0x01a00030U | (cond.GetCondition() << 28) |
6265                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6266         return;
6267       }
6268     }
6269   }
6270   Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand);
6271 }
6272 
lsrs(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6273 void Assembler::lsrs(Condition cond,
6274                      EncodingSize size,
6275                      Register rd,
6276                      Register rm,
6277                      const Operand& operand) {
6278   VIXL_ASSERT(AllowAssembler());
6279   CheckIT(cond);
6280   if (operand.IsImmediate()) {
6281     uint32_t imm = operand.GetImmediate();
6282     if (IsUsingT32()) {
6283       // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6284       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6285           (imm >= 1) && (imm <= 32)) {
6286         uint32_t amount_ = imm % 32;
6287         EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6288                    (amount_ << 6));
6289         AdvanceIT();
6290         return;
6291       }
6292       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6293       if (!size.IsNarrow() && (imm >= 1) && (imm <= 32)) {
6294         uint32_t amount_ = imm % 32;
6295         EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6296                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6297         AdvanceIT();
6298         return;
6299       }
6300     } else {
6301       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6302       if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6303         uint32_t amount_ = imm % 32;
6304         EmitA32(0x01b00020U | (cond.GetCondition() << 28) |
6305                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6306         return;
6307       }
6308     }
6309   }
6310   if (operand.IsPlainRegister()) {
6311     Register rs = operand.GetBaseRegister();
6312     if (IsUsingT32()) {
6313       // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6314       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6315           rs.IsLow()) {
6316         EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6317         AdvanceIT();
6318         return;
6319       }
6320       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6321       if (!size.IsNarrow()) {
6322         EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6323                    rs.GetCode());
6324         AdvanceIT();
6325         return;
6326       }
6327     } else {
6328       // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6329       if (cond.IsNotNever()) {
6330         EmitA32(0x01b00030U | (cond.GetCondition() << 28) |
6331                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6332         return;
6333       }
6334     }
6335   }
6336   Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand);
6337 }
6338 
mla(Condition cond,Register rd,Register rn,Register rm,Register ra)6339 void Assembler::mla(
6340     Condition cond, Register rd, Register rn, Register rm, Register ra) {
6341   VIXL_ASSERT(AllowAssembler());
6342   CheckIT(cond);
6343   if (IsUsingT32()) {
6344     // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
6345     if (!ra.Is(pc)) {
6346       EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6347                  rm.GetCode() | (ra.GetCode() << 12));
6348       AdvanceIT();
6349       return;
6350     }
6351   } else {
6352     // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6353     if (cond.IsNotNever()) {
6354       EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6355               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6356       return;
6357     }
6358   }
6359   Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra);
6360 }
6361 
mlas(Condition cond,Register rd,Register rn,Register rm,Register ra)6362 void Assembler::mlas(
6363     Condition cond, Register rd, Register rn, Register rm, Register ra) {
6364   VIXL_ASSERT(AllowAssembler());
6365   CheckIT(cond);
6366   if (IsUsingA32()) {
6367     // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6368     if (cond.IsNotNever()) {
6369       EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6370               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6371       return;
6372     }
6373   }
6374   Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra);
6375 }
6376 
mls(Condition cond,Register rd,Register rn,Register rm,Register ra)6377 void Assembler::mls(
6378     Condition cond, Register rd, Register rn, Register rm, Register ra) {
6379   VIXL_ASSERT(AllowAssembler());
6380   CheckIT(cond);
6381   if (IsUsingT32()) {
6382     // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
6383     EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6384                rm.GetCode() | (ra.GetCode() << 12));
6385     AdvanceIT();
6386     return;
6387   } else {
6388     // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
6389     if (cond.IsNotNever()) {
6390       EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6391               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
6392       return;
6393     }
6394   }
6395   Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra);
6396 }
6397 
mov(Condition cond,EncodingSize size,Register rd,const Operand & operand)6398 void Assembler::mov(Condition cond,
6399                     EncodingSize size,
6400                     Register rd,
6401                     const Operand& operand) {
6402   VIXL_ASSERT(AllowAssembler());
6403   CheckIT(cond);
6404   if (operand.IsImmediateShiftedRegister()) {
6405     Register rm = operand.GetBaseRegister();
6406     if (operand.IsPlainRegister()) {
6407       if (IsUsingT32()) {
6408         // MOV{<c>}{<q>} <Rd>, <Rm> ; T1
6409         if (!size.IsWide() &&
6410             ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
6411              AllowUnpredictable())) {
6412           EmitT32_16(0x4600 | (rd.GetCode() & 0x7) |
6413                      ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
6414           AdvanceIT();
6415           return;
6416         }
6417       }
6418     }
6419     Shift shift = operand.GetShift();
6420     uint32_t amount = operand.GetShiftAmount();
6421     if (IsUsingT32()) {
6422       // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6423       if (InITBlock() && !size.IsWide() && rd.IsLow() &&
6424           shift.IsValidAmount(amount) && rm.IsLow() &&
6425           (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR)) &&
6426           ((!shift.Is(LSL) || (amount != 0)) || AllowUnpredictable())) {
6427         uint32_t amount_ = amount % 32;
6428         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
6429                    (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
6430         AdvanceIT();
6431         return;
6432       }
6433       // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
6434       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
6435           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6436         uint32_t amount_ = amount % 32;
6437         EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6438                    (operand.GetTypeEncodingValue() << 4) |
6439                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6440         AdvanceIT();
6441         return;
6442       }
6443     } else {
6444       // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6445       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6446         uint32_t amount_ = amount % 32;
6447         EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
6448                 (rd.GetCode() << 12) | rm.GetCode() |
6449                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6450         return;
6451       }
6452     }
6453   }
6454   if (operand.IsRegisterShiftedRegister()) {
6455     Register rm = operand.GetBaseRegister();
6456     Shift shift = operand.GetShift();
6457     if (IsUsingT32()) {
6458       // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
6459       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6460           shift.IsASR() && operand.GetShiftRegister().IsLow()) {
6461         EmitT32_16(0x4100 | rd.GetCode() |
6462                    (operand.GetShiftRegister().GetCode() << 3));
6463         AdvanceIT();
6464         return;
6465       }
6466       // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
6467       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6468           shift.IsLSL() && operand.GetShiftRegister().IsLow()) {
6469         EmitT32_16(0x4080 | rd.GetCode() |
6470                    (operand.GetShiftRegister().GetCode() << 3));
6471         AdvanceIT();
6472         return;
6473       }
6474       // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
6475       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6476           shift.IsLSR() && operand.GetShiftRegister().IsLow()) {
6477         EmitT32_16(0x40c0 | rd.GetCode() |
6478                    (operand.GetShiftRegister().GetCode() << 3));
6479         AdvanceIT();
6480         return;
6481       }
6482       // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
6483       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6484           shift.IsROR() && operand.GetShiftRegister().IsLow()) {
6485         EmitT32_16(0x41c0 | rd.GetCode() |
6486                    (operand.GetShiftRegister().GetCode() << 3));
6487         AdvanceIT();
6488         return;
6489       }
6490       // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
6491       if (!size.IsNarrow() &&
6492           ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
6493            AllowUnpredictable())) {
6494         EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6495                    (shift.GetType() << 21) |
6496                    operand.GetShiftRegister().GetCode());
6497         AdvanceIT();
6498         return;
6499       }
6500     } else {
6501       // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6502       if (cond.IsNotNever() &&
6503           ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
6504            AllowUnpredictable())) {
6505         EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
6506                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6507                 (operand.GetShiftRegister().GetCode() << 8));
6508         return;
6509       }
6510     }
6511   }
6512   if (operand.IsImmediate()) {
6513     uint32_t imm = operand.GetImmediate();
6514     if (IsUsingT32()) {
6515       ImmediateT32 immediate_t32(imm);
6516       // MOV<c>{<q>} <Rd>, #<imm8> ; T1
6517       if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
6518         EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
6519         AdvanceIT();
6520         return;
6521       }
6522       // MOV{<c>}{<q>} <Rd>, #<const> ; T2
6523       if (!size.IsNarrow() && immediate_t32.IsValid() &&
6524           (!rd.IsPC() || AllowUnpredictable())) {
6525         EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) |
6526                    (immediate_t32.GetEncodingValue() & 0xff) |
6527                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6528                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6529         AdvanceIT();
6530         return;
6531       }
6532       // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3
6533       if (!size.IsNarrow() && (imm <= 65535) &&
6534           (!rd.IsPC() || AllowUnpredictable())) {
6535         EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
6536                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6537                    ((imm & 0xf000) << 4));
6538         AdvanceIT();
6539         return;
6540       }
6541     } else {
6542       ImmediateA32 immediate_a32(imm);
6543       // MOV{<c>}{<q>} <Rd>, #<const> ; A1
6544       if (immediate_a32.IsValid() && cond.IsNotNever()) {
6545         EmitA32(0x03a00000U | (cond.GetCondition() << 28) |
6546                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6547         return;
6548       }
6549       // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2
6550       if ((imm <= 65535) && cond.IsNotNever() &&
6551           (!rd.IsPC() || AllowUnpredictable())) {
6552         EmitA32(0x03000000U | (cond.GetCondition() << 28) |
6553                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6554         return;
6555       }
6556     }
6557   }
6558   Delegate(kMov, &Assembler::mov, cond, size, rd, operand);
6559 }
6560 
movs(Condition cond,EncodingSize size,Register rd,const Operand & operand)6561 void Assembler::movs(Condition cond,
6562                      EncodingSize size,
6563                      Register rd,
6564                      const Operand& operand) {
6565   VIXL_ASSERT(AllowAssembler());
6566   CheckIT(cond);
6567   if (operand.IsImmediateShiftedRegister()) {
6568     Register rm = operand.GetBaseRegister();
6569     Shift shift = operand.GetShift();
6570     uint32_t amount = operand.GetShiftAmount();
6571     if (IsUsingT32()) {
6572       // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6573       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() &&
6574           shift.IsValidAmount(amount) && rm.IsLow() &&
6575           (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) {
6576         uint32_t amount_ = amount % 32;
6577         EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
6578                    (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
6579         AdvanceIT();
6580         return;
6581       }
6582       // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
6583       if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
6584           ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6585         uint32_t amount_ = amount % 32;
6586         EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6587                    (operand.GetTypeEncodingValue() << 4) |
6588                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6589         AdvanceIT();
6590         return;
6591       }
6592     } else {
6593       // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6594       if (shift.IsValidAmount(amount) && cond.IsNotNever() &&
6595           (!rd.IsPC() || AllowUnpredictable())) {
6596         uint32_t amount_ = amount % 32;
6597         EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
6598                 (rd.GetCode() << 12) | rm.GetCode() |
6599                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6600         return;
6601       }
6602     }
6603   }
6604   if (operand.IsRegisterShiftedRegister()) {
6605     Register rm = operand.GetBaseRegister();
6606     Shift shift = operand.GetShift();
6607     if (IsUsingT32()) {
6608       // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
6609       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6610           shift.IsASR() && operand.GetShiftRegister().IsLow()) {
6611         EmitT32_16(0x4100 | rd.GetCode() |
6612                    (operand.GetShiftRegister().GetCode() << 3));
6613         AdvanceIT();
6614         return;
6615       }
6616       // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
6617       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6618           shift.IsLSL() && operand.GetShiftRegister().IsLow()) {
6619         EmitT32_16(0x4080 | rd.GetCode() |
6620                    (operand.GetShiftRegister().GetCode() << 3));
6621         AdvanceIT();
6622         return;
6623       }
6624       // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
6625       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6626           shift.IsLSR() && operand.GetShiftRegister().IsLow()) {
6627         EmitT32_16(0x40c0 | rd.GetCode() |
6628                    (operand.GetShiftRegister().GetCode() << 3));
6629         AdvanceIT();
6630         return;
6631       }
6632       // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
6633       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6634           shift.IsROR() && operand.GetShiftRegister().IsLow()) {
6635         EmitT32_16(0x41c0 | rd.GetCode() |
6636                    (operand.GetShiftRegister().GetCode() << 3));
6637         AdvanceIT();
6638         return;
6639       }
6640       // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
6641       if (!size.IsNarrow() &&
6642           ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
6643            AllowUnpredictable())) {
6644         EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6645                    (shift.GetType() << 21) |
6646                    operand.GetShiftRegister().GetCode());
6647         AdvanceIT();
6648         return;
6649       }
6650     } else {
6651       // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6652       if (cond.IsNotNever() &&
6653           ((!rd.IsPC() && !rm.IsPC() && !operand.GetShiftRegister().IsPC()) ||
6654            AllowUnpredictable())) {
6655         EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
6656                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6657                 (operand.GetShiftRegister().GetCode() << 8));
6658         return;
6659       }
6660     }
6661   }
6662   if (operand.IsImmediate()) {
6663     uint32_t imm = operand.GetImmediate();
6664     if (IsUsingT32()) {
6665       ImmediateT32 immediate_t32(imm);
6666       // MOVS{<q>} <Rd>, #<imm8> ; T1
6667       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
6668         EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
6669         AdvanceIT();
6670         return;
6671       }
6672       // MOVS{<c>}{<q>} <Rd>, #<const> ; T2
6673       if (!size.IsNarrow() && immediate_t32.IsValid() &&
6674           (!rd.IsPC() || AllowUnpredictable())) {
6675         EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) |
6676                    (immediate_t32.GetEncodingValue() & 0xff) |
6677                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6678                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6679         AdvanceIT();
6680         return;
6681       }
6682     } else {
6683       ImmediateA32 immediate_a32(imm);
6684       // MOVS{<c>}{<q>} <Rd>, #<const> ; A1
6685       if (immediate_a32.IsValid() && cond.IsNotNever()) {
6686         EmitA32(0x03b00000U | (cond.GetCondition() << 28) |
6687                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6688         return;
6689       }
6690     }
6691   }
6692   Delegate(kMovs, &Assembler::movs, cond, size, rd, operand);
6693 }
6694 
movt(Condition cond,Register rd,const Operand & operand)6695 void Assembler::movt(Condition cond, Register rd, const Operand& operand) {
6696   VIXL_ASSERT(AllowAssembler());
6697   CheckIT(cond);
6698   if (operand.IsImmediate()) {
6699     uint32_t imm = operand.GetImmediate();
6700     if (IsUsingT32()) {
6701       // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1
6702       if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
6703         EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) |
6704                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6705                    ((imm & 0xf000) << 4));
6706         AdvanceIT();
6707         return;
6708       }
6709     } else {
6710       // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1
6711       if ((imm <= 65535) && cond.IsNotNever() &&
6712           (!rd.IsPC() || AllowUnpredictable())) {
6713         EmitA32(0x03400000U | (cond.GetCondition() << 28) |
6714                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6715         return;
6716       }
6717     }
6718   }
6719   Delegate(kMovt, &Assembler::movt, cond, rd, operand);
6720 }
6721 
movw(Condition cond,Register rd,const Operand & operand)6722 void Assembler::movw(Condition cond, Register rd, const Operand& operand) {
6723   VIXL_ASSERT(AllowAssembler());
6724   CheckIT(cond);
6725   if (operand.IsImmediate()) {
6726     uint32_t imm = operand.GetImmediate();
6727     if (IsUsingT32()) {
6728       // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3
6729       if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
6730         EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
6731                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
6732                    ((imm & 0xf000) << 4));
6733         AdvanceIT();
6734         return;
6735       }
6736     } else {
6737       // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2
6738       if ((imm <= 65535) && cond.IsNotNever() &&
6739           (!rd.IsPC() || AllowUnpredictable())) {
6740         EmitA32(0x03000000U | (cond.GetCondition() << 28) |
6741                 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
6742         return;
6743       }
6744     }
6745   }
6746   Delegate(kMovw, &Assembler::movw, cond, rd, operand);
6747 }
6748 
mrs(Condition cond,Register rd,SpecialRegister spec_reg)6749 void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) {
6750   VIXL_ASSERT(AllowAssembler());
6751   CheckIT(cond);
6752   if (IsUsingT32()) {
6753     // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1
6754     EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20));
6755     AdvanceIT();
6756     return;
6757   } else {
6758     // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1
6759     if (cond.IsNotNever()) {
6760       EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
6761               (spec_reg.GetReg() << 22));
6762       return;
6763     }
6764   }
6765   Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg);
6766 }
6767 
msr(Condition cond,MaskedSpecialRegister spec_reg,const Operand & operand)6768 void Assembler::msr(Condition cond,
6769                     MaskedSpecialRegister spec_reg,
6770                     const Operand& operand) {
6771   VIXL_ASSERT(AllowAssembler());
6772   CheckIT(cond);
6773   if (operand.IsImmediate()) {
6774     uint32_t imm = operand.GetImmediate();
6775     if (IsUsingA32()) {
6776       ImmediateA32 immediate_a32(imm);
6777       // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1
6778       if (immediate_a32.IsValid() && cond.IsNotNever()) {
6779         EmitA32(0x0320f000U | (cond.GetCondition() << 28) |
6780                 ((spec_reg.GetReg() & 0xf) << 16) |
6781                 ((spec_reg.GetReg() & 0x10) << 18) |
6782                 immediate_a32.GetEncodingValue());
6783         return;
6784       }
6785     }
6786   }
6787   if (operand.IsPlainRegister()) {
6788     Register rn = operand.GetBaseRegister();
6789     if (IsUsingT32()) {
6790       // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1
6791       EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) |
6792                  ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16));
6793       AdvanceIT();
6794       return;
6795     } else {
6796       // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1
6797       if (cond.IsNotNever()) {
6798         EmitA32(0x0120f000U | (cond.GetCondition() << 28) |
6799                 ((spec_reg.GetReg() & 0xf) << 16) |
6800                 ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode());
6801         return;
6802       }
6803     }
6804   }
6805   Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand);
6806 }
6807 
mul(Condition cond,EncodingSize size,Register rd,Register rn,Register rm)6808 void Assembler::mul(
6809     Condition cond, EncodingSize size, Register rd, Register rn, Register rm) {
6810   VIXL_ASSERT(AllowAssembler());
6811   CheckIT(cond);
6812   if (IsUsingT32()) {
6813     // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
6814     if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() &&
6815         rm.IsLow()) {
6816       EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
6817       AdvanceIT();
6818       return;
6819     }
6820     // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2
6821     if (!size.IsNarrow()) {
6822       EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6823                  rm.GetCode());
6824       AdvanceIT();
6825       return;
6826     }
6827   } else {
6828     // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
6829     if (cond.IsNotNever()) {
6830       EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6831               rn.GetCode() | (rm.GetCode() << 8));
6832       return;
6833     }
6834   }
6835   Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm);
6836 }
6837 
muls(Condition cond,Register rd,Register rn,Register rm)6838 void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) {
6839   VIXL_ASSERT(AllowAssembler());
6840   CheckIT(cond);
6841   if (IsUsingT32()) {
6842     // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
6843     if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) {
6844       EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
6845       AdvanceIT();
6846       return;
6847     }
6848   } else {
6849     // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
6850     if (cond.IsNotNever()) {
6851       EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
6852               rn.GetCode() | (rm.GetCode() << 8));
6853       return;
6854     }
6855   }
6856   Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm);
6857 }
6858 
mvn(Condition cond,EncodingSize size,Register rd,const Operand & operand)6859 void Assembler::mvn(Condition cond,
6860                     EncodingSize size,
6861                     Register rd,
6862                     const Operand& operand) {
6863   VIXL_ASSERT(AllowAssembler());
6864   CheckIT(cond);
6865   if (operand.IsImmediate()) {
6866     uint32_t imm = operand.GetImmediate();
6867     if (IsUsingT32()) {
6868       ImmediateT32 immediate_t32(imm);
6869       // MVN{<c>}{<q>} <Rd>, #<const> ; T1
6870       if (!size.IsNarrow() && immediate_t32.IsValid()) {
6871         EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) |
6872                    (immediate_t32.GetEncodingValue() & 0xff) |
6873                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6874                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6875         AdvanceIT();
6876         return;
6877       }
6878     } else {
6879       ImmediateA32 immediate_a32(imm);
6880       // MVN{<c>}{<q>} <Rd>, #<const> ; A1
6881       if (immediate_a32.IsValid() && cond.IsNotNever()) {
6882         EmitA32(0x03e00000U | (cond.GetCondition() << 28) |
6883                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6884         return;
6885       }
6886     }
6887   }
6888   if (operand.IsImmediateShiftedRegister()) {
6889     Register rm = operand.GetBaseRegister();
6890     if (operand.IsPlainRegister()) {
6891       if (IsUsingT32()) {
6892         // MVN<c>{<q>} <Rd>, <Rm> ; T1
6893         if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
6894           EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
6895           AdvanceIT();
6896           return;
6897         }
6898       }
6899     }
6900     Shift shift = operand.GetShift();
6901     uint32_t amount = operand.GetShiftAmount();
6902     if (IsUsingT32()) {
6903       // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6904       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6905         uint32_t amount_ = amount % 32;
6906         EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6907                    (operand.GetTypeEncodingValue() << 4) |
6908                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6909         AdvanceIT();
6910         return;
6911       }
6912     } else {
6913       // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6914       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6915         uint32_t amount_ = amount % 32;
6916         EmitA32(0x01e00000U | (cond.GetCondition() << 28) |
6917                 (rd.GetCode() << 12) | rm.GetCode() |
6918                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6919         return;
6920       }
6921     }
6922   }
6923   if (operand.IsRegisterShiftedRegister()) {
6924     Register rm = operand.GetBaseRegister();
6925     Shift shift = operand.GetShift();
6926     if (IsUsingA32()) {
6927       // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
6928       if (cond.IsNotNever()) {
6929         EmitA32(0x01e00010U | (cond.GetCondition() << 28) |
6930                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
6931                 (operand.GetShiftRegister().GetCode() << 8));
6932         return;
6933       }
6934     }
6935   }
6936   Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand);
6937 }
6938 
mvns(Condition cond,EncodingSize size,Register rd,const Operand & operand)6939 void Assembler::mvns(Condition cond,
6940                      EncodingSize size,
6941                      Register rd,
6942                      const Operand& operand) {
6943   VIXL_ASSERT(AllowAssembler());
6944   CheckIT(cond);
6945   if (operand.IsImmediate()) {
6946     uint32_t imm = operand.GetImmediate();
6947     if (IsUsingT32()) {
6948       ImmediateT32 immediate_t32(imm);
6949       // MVNS{<c>}{<q>} <Rd>, #<const> ; T1
6950       if (!size.IsNarrow() && immediate_t32.IsValid()) {
6951         EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) |
6952                    (immediate_t32.GetEncodingValue() & 0xff) |
6953                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
6954                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
6955         AdvanceIT();
6956         return;
6957       }
6958     } else {
6959       ImmediateA32 immediate_a32(imm);
6960       // MVNS{<c>}{<q>} <Rd>, #<const> ; A1
6961       if (immediate_a32.IsValid() && cond.IsNotNever()) {
6962         EmitA32(0x03f00000U | (cond.GetCondition() << 28) |
6963                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
6964         return;
6965       }
6966     }
6967   }
6968   if (operand.IsImmediateShiftedRegister()) {
6969     Register rm = operand.GetBaseRegister();
6970     if (operand.IsPlainRegister()) {
6971       if (IsUsingT32()) {
6972         // MVNS{<q>} <Rd>, <Rm> ; T1
6973         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
6974           EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
6975           AdvanceIT();
6976           return;
6977         }
6978       }
6979     }
6980     Shift shift = operand.GetShift();
6981     uint32_t amount = operand.GetShiftAmount();
6982     if (IsUsingT32()) {
6983       // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
6984       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
6985         uint32_t amount_ = amount % 32;
6986         EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6987                    (operand.GetTypeEncodingValue() << 4) |
6988                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6989         AdvanceIT();
6990         return;
6991       }
6992     } else {
6993       // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
6994       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
6995         uint32_t amount_ = amount % 32;
6996         EmitA32(0x01f00000U | (cond.GetCondition() << 28) |
6997                 (rd.GetCode() << 12) | rm.GetCode() |
6998                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
6999         return;
7000       }
7001     }
7002   }
7003   if (operand.IsRegisterShiftedRegister()) {
7004     Register rm = operand.GetBaseRegister();
7005     Shift shift = operand.GetShift();
7006     if (IsUsingA32()) {
7007       // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
7008       if (cond.IsNotNever()) {
7009         EmitA32(0x01f00010U | (cond.GetCondition() << 28) |
7010                 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
7011                 (operand.GetShiftRegister().GetCode() << 8));
7012         return;
7013       }
7014     }
7015   }
7016   Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand);
7017 }
7018 
nop(Condition cond,EncodingSize size)7019 void Assembler::nop(Condition cond, EncodingSize size) {
7020   VIXL_ASSERT(AllowAssembler());
7021   CheckIT(cond);
7022   if (IsUsingT32()) {
7023     // NOP{<c>}{<q>} ; T1
7024     if (!size.IsWide()) {
7025       EmitT32_16(0xbf00);
7026       AdvanceIT();
7027       return;
7028     }
7029     // NOP{<c>}.W ; T2
7030     if (!size.IsNarrow()) {
7031       EmitT32_32(0xf3af8000U);
7032       AdvanceIT();
7033       return;
7034     }
7035   } else {
7036     // NOP{<c>}{<q>} ; A1
7037     if (cond.IsNotNever()) {
7038       EmitA32(0x0320f000U | (cond.GetCondition() << 28));
7039       return;
7040     }
7041   }
7042   Delegate(kNop, &Assembler::nop, cond, size);
7043 }
7044 
orn(Condition cond,Register rd,Register rn,const Operand & operand)7045 void Assembler::orn(Condition cond,
7046                     Register rd,
7047                     Register rn,
7048                     const Operand& operand) {
7049   VIXL_ASSERT(AllowAssembler());
7050   CheckIT(cond);
7051   if (operand.IsImmediate()) {
7052     uint32_t imm = operand.GetImmediate();
7053     if (IsUsingT32()) {
7054       ImmediateT32 immediate_t32(imm);
7055       // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7056       if (immediate_t32.IsValid() && !rn.Is(pc)) {
7057         EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7058                    (immediate_t32.GetEncodingValue() & 0xff) |
7059                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7060                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7061         AdvanceIT();
7062         return;
7063       }
7064     }
7065   }
7066   if (operand.IsImmediateShiftedRegister()) {
7067     Register rm = operand.GetBaseRegister();
7068     Shift shift = operand.GetShift();
7069     uint32_t amount = operand.GetShiftAmount();
7070     if (IsUsingT32()) {
7071       // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
7072       if (shift.IsValidAmount(amount) && !rn.Is(pc)) {
7073         uint32_t amount_ = amount % 32;
7074         EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7075                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7076                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7077         AdvanceIT();
7078         return;
7079       }
7080     }
7081   }
7082   Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand);
7083 }
7084 
orns(Condition cond,Register rd,Register rn,const Operand & operand)7085 void Assembler::orns(Condition cond,
7086                      Register rd,
7087                      Register rn,
7088                      const Operand& operand) {
7089   VIXL_ASSERT(AllowAssembler());
7090   CheckIT(cond);
7091   if (operand.IsImmediate()) {
7092     uint32_t imm = operand.GetImmediate();
7093     if (IsUsingT32()) {
7094       ImmediateT32 immediate_t32(imm);
7095       // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7096       if (immediate_t32.IsValid() && !rn.Is(pc)) {
7097         EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7098                    (immediate_t32.GetEncodingValue() & 0xff) |
7099                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7100                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7101         AdvanceIT();
7102         return;
7103       }
7104     }
7105   }
7106   if (operand.IsImmediateShiftedRegister()) {
7107     Register rm = operand.GetBaseRegister();
7108     Shift shift = operand.GetShift();
7109     uint32_t amount = operand.GetShiftAmount();
7110     if (IsUsingT32()) {
7111       // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
7112       if (shift.IsValidAmount(amount) && !rn.Is(pc)) {
7113         uint32_t amount_ = amount % 32;
7114         EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7115                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7116                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7117         AdvanceIT();
7118         return;
7119       }
7120     }
7121   }
7122   Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand);
7123 }
7124 
orr(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)7125 void Assembler::orr(Condition cond,
7126                     EncodingSize size,
7127                     Register rd,
7128                     Register rn,
7129                     const Operand& operand) {
7130   VIXL_ASSERT(AllowAssembler());
7131   CheckIT(cond);
7132   if (operand.IsImmediate()) {
7133     uint32_t imm = operand.GetImmediate();
7134     if (IsUsingT32()) {
7135       ImmediateT32 immediate_t32(imm);
7136       // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7137       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) {
7138         EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7139                    (immediate_t32.GetEncodingValue() & 0xff) |
7140                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7141                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7142         AdvanceIT();
7143         return;
7144       }
7145     } else {
7146       ImmediateA32 immediate_a32(imm);
7147       // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7148       if (immediate_a32.IsValid() && cond.IsNotNever()) {
7149         EmitA32(0x03800000U | (cond.GetCondition() << 28) |
7150                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7151                 immediate_a32.GetEncodingValue());
7152         return;
7153       }
7154     }
7155   }
7156   if (operand.IsImmediateShiftedRegister()) {
7157     Register rm = operand.GetBaseRegister();
7158     if (operand.IsPlainRegister()) {
7159       if (IsUsingT32()) {
7160         // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7161         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7162             rm.IsLow()) {
7163           EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7164           AdvanceIT();
7165           return;
7166         }
7167       }
7168     }
7169     Shift shift = operand.GetShift();
7170     uint32_t amount = operand.GetShiftAmount();
7171     if (IsUsingT32()) {
7172       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7173       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) {
7174         uint32_t amount_ = amount % 32;
7175         EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7176                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7177                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7178         AdvanceIT();
7179         return;
7180       }
7181     } else {
7182       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7183       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7184         uint32_t amount_ = amount % 32;
7185         EmitA32(0x01800000U | (cond.GetCondition() << 28) |
7186                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7187                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7188         return;
7189       }
7190     }
7191   }
7192   if (operand.IsRegisterShiftedRegister()) {
7193     Register rm = operand.GetBaseRegister();
7194     Shift shift = operand.GetShift();
7195     if (IsUsingA32()) {
7196       // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7197       if (cond.IsNotNever()) {
7198         EmitA32(0x01800010U | (cond.GetCondition() << 28) |
7199                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7200                 (shift.GetType() << 5) |
7201                 (operand.GetShiftRegister().GetCode() << 8));
7202         return;
7203       }
7204     }
7205   }
7206   Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand);
7207 }
7208 
orrs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)7209 void Assembler::orrs(Condition cond,
7210                      EncodingSize size,
7211                      Register rd,
7212                      Register rn,
7213                      const Operand& operand) {
7214   VIXL_ASSERT(AllowAssembler());
7215   CheckIT(cond);
7216   if (operand.IsImmediate()) {
7217     uint32_t imm = operand.GetImmediate();
7218     if (IsUsingT32()) {
7219       ImmediateT32 immediate_t32(imm);
7220       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7221       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc)) {
7222         EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7223                    (immediate_t32.GetEncodingValue() & 0xff) |
7224                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7225                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7226         AdvanceIT();
7227         return;
7228       }
7229     } else {
7230       ImmediateA32 immediate_a32(imm);
7231       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7232       if (immediate_a32.IsValid() && cond.IsNotNever()) {
7233         EmitA32(0x03900000U | (cond.GetCondition() << 28) |
7234                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7235                 immediate_a32.GetEncodingValue());
7236         return;
7237       }
7238     }
7239   }
7240   if (operand.IsImmediateShiftedRegister()) {
7241     Register rm = operand.GetBaseRegister();
7242     if (operand.IsPlainRegister()) {
7243       if (IsUsingT32()) {
7244         // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7245         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7246             rm.IsLow()) {
7247           EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7248           AdvanceIT();
7249           return;
7250         }
7251       }
7252     }
7253     Shift shift = operand.GetShift();
7254     uint32_t amount = operand.GetShiftAmount();
7255     if (IsUsingT32()) {
7256       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7257       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc)) {
7258         uint32_t amount_ = amount % 32;
7259         EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7260                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7261                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7262         AdvanceIT();
7263         return;
7264       }
7265     } else {
7266       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7267       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7268         uint32_t amount_ = amount % 32;
7269         EmitA32(0x01900000U | (cond.GetCondition() << 28) |
7270                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7271                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7272         return;
7273       }
7274     }
7275   }
7276   if (operand.IsRegisterShiftedRegister()) {
7277     Register rm = operand.GetBaseRegister();
7278     Shift shift = operand.GetShift();
7279     if (IsUsingA32()) {
7280       // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7281       if (cond.IsNotNever()) {
7282         EmitA32(0x01900010U | (cond.GetCondition() << 28) |
7283                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7284                 (shift.GetType() << 5) |
7285                 (operand.GetShiftRegister().GetCode() << 8));
7286         return;
7287       }
7288     }
7289   }
7290   Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand);
7291 }
7292 
pkhbt(Condition cond,Register rd,Register rn,const Operand & operand)7293 void Assembler::pkhbt(Condition cond,
7294                       Register rd,
7295                       Register rn,
7296                       const Operand& operand) {
7297   VIXL_ASSERT(AllowAssembler());
7298   CheckIT(cond);
7299   if (operand.IsImmediateShiftedRegister()) {
7300     Register rm = operand.GetBaseRegister();
7301     Shift shift = operand.GetShift();
7302     uint32_t amount = operand.GetShiftAmount();
7303     if (IsUsingT32()) {
7304       // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1
7305       if (shift.IsLSL() && shift.IsValidAmount(amount)) {
7306         EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7307                    rm.GetCode() | ((amount & 0x3) << 6) |
7308                    ((amount & 0x1c) << 10));
7309         AdvanceIT();
7310         return;
7311       }
7312     } else {
7313       // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1
7314       if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever()) {
7315         EmitA32(0x06800010U | (cond.GetCondition() << 28) |
7316                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7317                 (amount << 7));
7318         return;
7319       }
7320     }
7321   }
7322   Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand);
7323 }
7324 
pkhtb(Condition cond,Register rd,Register rn,const Operand & operand)7325 void Assembler::pkhtb(Condition cond,
7326                       Register rd,
7327                       Register rn,
7328                       const Operand& operand) {
7329   VIXL_ASSERT(AllowAssembler());
7330   CheckIT(cond);
7331   if (operand.IsImmediateShiftedRegister()) {
7332     Register rm = operand.GetBaseRegister();
7333     Shift shift = operand.GetShift();
7334     uint32_t amount = operand.GetShiftAmount();
7335     if (IsUsingT32()) {
7336       // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1
7337       if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount)) {
7338         uint32_t amount_ = amount % 32;
7339         EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7340                    rm.GetCode() | ((amount_ & 0x3) << 6) |
7341                    ((amount_ & 0x1c) << 10));
7342         AdvanceIT();
7343         return;
7344       }
7345     } else {
7346       // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1
7347       if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
7348           cond.IsNotNever()) {
7349         uint32_t amount_ = amount % 32;
7350         EmitA32(0x06800050U | (cond.GetCondition() << 28) |
7351                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7352                 (amount_ << 7));
7353         return;
7354       }
7355     }
7356   }
7357   Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand);
7358 }
7359 
pld(Condition cond,Label * label)7360 void Assembler::pld(Condition cond, Label* label) {
7361   VIXL_ASSERT(AllowAssembler());
7362   CheckIT(cond);
7363   Label::Offset offset =
7364       label->IsBound()
7365           ? label->GetLocation() -
7366                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
7367           : 0;
7368   if (IsUsingT32()) {
7369     // PLD{<c>}{<q>} <label> ; T1
7370     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7371          !label->IsBound())) {
7372       static class EmitOp : public Label::LabelEmitOperator {
7373        public:
7374         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7375         virtual uint32_t Encode(uint32_t instr,
7376                                 Label::Offset pc,
7377                                 const Label* label) const VIXL_OVERRIDE {
7378           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7379           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7380           uint32_t U = (offset >= 0) && !label->IsMinusZero();
7381           int32_t target = abs(offset) | (U << 12);
7382           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7383         }
7384       } immop;
7385       EmitT32_32(Link(0xf81ff000U, label, immop));
7386       AdvanceIT();
7387       return;
7388     }
7389   } else {
7390     // PLD{<c>}{<q>} <label> ; A1
7391     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7392          !label->IsBound())) {
7393       if (cond.Is(al)) {
7394         static class EmitOp : public Label::LabelEmitOperator {
7395          public:
7396           EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7397           virtual uint32_t Encode(uint32_t instr,
7398                                   Label::Offset pc,
7399                                   const Label* label) const VIXL_OVERRIDE {
7400             Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7401             VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7402             uint32_t U = (offset >= 0) && !label->IsMinusZero();
7403             int32_t target = abs(offset) | (U << 12);
7404             return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7405           }
7406         } immop;
7407         EmitA32(Link(0xf55ff000U, label, immop));
7408         return;
7409       }
7410     }
7411   }
7412   Delegate(kPld, &Assembler::pld, cond, label);
7413 }
7414 
pld(Condition cond,const MemOperand & operand)7415 void Assembler::pld(Condition cond, const MemOperand& operand) {
7416   VIXL_ASSERT(AllowAssembler());
7417   CheckIT(cond);
7418   if (operand.IsImmediate()) {
7419     Register rn = operand.GetBaseRegister();
7420     int32_t offset = operand.GetOffsetImmediate();
7421     if (IsUsingT32()) {
7422       // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1
7423       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
7424           operand.IsOffset()) {
7425         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7426         uint32_t offset_ = abs(offset);
7427         EmitT32_32(0xf81ff000U | offset_ | (sign << 23));
7428         AdvanceIT();
7429         return;
7430       }
7431     } else {
7432       // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1
7433       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
7434           operand.IsOffset()) {
7435         if (cond.Is(al)) {
7436           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7437           uint32_t offset_ = abs(offset);
7438           EmitA32(0xf55ff000U | offset_ | (sign << 23));
7439           return;
7440         }
7441       }
7442     }
7443   }
7444   if (operand.IsImmediate()) {
7445     Register rn = operand.GetBaseRegister();
7446     int32_t offset = operand.GetOffsetImmediate();
7447     if (IsUsingT32()) {
7448       // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7449       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
7450           ((rn.GetCode() & 0xf) != 0xf)) {
7451         EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7452         AdvanceIT();
7453         return;
7454       }
7455       // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7456       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
7457           ((rn.GetCode() & 0xf) != 0xf)) {
7458         EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7459         AdvanceIT();
7460         return;
7461       }
7462     } else {
7463       // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
7464       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
7465           ((rn.GetCode() & 0xf) != 0xf)) {
7466         if (cond.Is(al)) {
7467           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7468           uint32_t offset_ = abs(offset);
7469           EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7470           return;
7471         }
7472       }
7473     }
7474   }
7475   if (operand.IsShiftedRegister()) {
7476     Register rn = operand.GetBaseRegister();
7477     Sign sign = operand.GetSign();
7478     Register rm = operand.GetOffsetRegister();
7479     Shift shift = operand.GetShift();
7480     uint32_t amount = operand.GetShiftAmount();
7481     if (IsUsingT32()) {
7482       // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7483       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
7484           ((rn.GetCode() & 0xf) != 0xf)) {
7485         EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() |
7486                    (amount << 4));
7487         AdvanceIT();
7488         return;
7489       }
7490     } else {
7491       // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7492       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
7493         if (cond.Is(al)) {
7494           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7495           uint32_t amount_ = amount % 32;
7496           EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() |
7497                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7498           return;
7499         }
7500       }
7501       // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7502       if (shift.IsRRX() && operand.IsOffset()) {
7503         if (cond.Is(al)) {
7504           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7505           EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() |
7506                   (sign_ << 23));
7507           return;
7508         }
7509       }
7510     }
7511   }
7512   Delegate(kPld, &Assembler::pld, cond, operand);
7513 }
7514 
pldw(Condition cond,const MemOperand & operand)7515 void Assembler::pldw(Condition cond, const MemOperand& operand) {
7516   VIXL_ASSERT(AllowAssembler());
7517   CheckIT(cond);
7518   if (operand.IsImmediate()) {
7519     Register rn = operand.GetBaseRegister();
7520     int32_t offset = operand.GetOffsetImmediate();
7521     if (IsUsingT32()) {
7522       // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7523       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
7524           ((rn.GetCode() & 0xf) != 0xf)) {
7525         EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7526         AdvanceIT();
7527         return;
7528       }
7529       // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7530       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
7531           ((rn.GetCode() & 0xf) != 0xf)) {
7532         EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7533         AdvanceIT();
7534         return;
7535       }
7536     } else {
7537       // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
7538       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
7539           ((rn.GetCode() & 0xf) != 0xf)) {
7540         if (cond.Is(al)) {
7541           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7542           uint32_t offset_ = abs(offset);
7543           EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7544           return;
7545         }
7546       }
7547     }
7548   }
7549   if (operand.IsShiftedRegister()) {
7550     Register rn = operand.GetBaseRegister();
7551     Sign sign = operand.GetSign();
7552     Register rm = operand.GetOffsetRegister();
7553     Shift shift = operand.GetShift();
7554     uint32_t amount = operand.GetShiftAmount();
7555     if (IsUsingT32()) {
7556       // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7557       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
7558           ((rn.GetCode() & 0xf) != 0xf)) {
7559         EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() |
7560                    (amount << 4));
7561         AdvanceIT();
7562         return;
7563       }
7564     } else {
7565       // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7566       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
7567         if (cond.Is(al)) {
7568           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7569           uint32_t amount_ = amount % 32;
7570           EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() |
7571                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7572           return;
7573         }
7574       }
7575       // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7576       if (shift.IsRRX() && operand.IsOffset()) {
7577         if (cond.Is(al)) {
7578           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7579           EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() |
7580                   (sign_ << 23));
7581           return;
7582         }
7583       }
7584     }
7585   }
7586   Delegate(kPldw, &Assembler::pldw, cond, operand);
7587 }
7588 
pli(Condition cond,const MemOperand & operand)7589 void Assembler::pli(Condition cond, const MemOperand& operand) {
7590   VIXL_ASSERT(AllowAssembler());
7591   CheckIT(cond);
7592   if (operand.IsImmediate()) {
7593     Register rn = operand.GetBaseRegister();
7594     int32_t offset = operand.GetOffsetImmediate();
7595     if (IsUsingT32()) {
7596       // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
7597       if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
7598           ((rn.GetCode() & 0xf) != 0xf)) {
7599         EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff));
7600         AdvanceIT();
7601         return;
7602       }
7603       // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
7604       if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
7605           ((rn.GetCode() & 0xf) != 0xf)) {
7606         EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
7607         AdvanceIT();
7608         return;
7609       }
7610     } else {
7611       // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1
7612       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
7613           ((rn.GetCode() & 0xf) != 0xf)) {
7614         if (cond.Is(al)) {
7615           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7616           uint32_t offset_ = abs(offset);
7617           EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
7618           return;
7619         }
7620       }
7621     }
7622   }
7623   if (operand.IsImmediate()) {
7624     Register rn = operand.GetBaseRegister();
7625     int32_t offset = operand.GetOffsetImmediate();
7626     if (IsUsingT32()) {
7627       // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3
7628       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
7629           operand.IsOffset()) {
7630         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7631         uint32_t offset_ = abs(offset);
7632         EmitT32_32(0xf91ff000U | offset_ | (sign << 23));
7633         AdvanceIT();
7634         return;
7635       }
7636     } else {
7637       // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1
7638       if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
7639           operand.IsOffset()) {
7640         if (cond.Is(al)) {
7641           uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
7642           uint32_t offset_ = abs(offset);
7643           EmitA32(0xf45ff000U | offset_ | (sign << 23));
7644           return;
7645         }
7646       }
7647     }
7648   }
7649   if (operand.IsShiftedRegister()) {
7650     Register rn = operand.GetBaseRegister();
7651     Sign sign = operand.GetSign();
7652     Register rm = operand.GetOffsetRegister();
7653     Shift shift = operand.GetShift();
7654     uint32_t amount = operand.GetShiftAmount();
7655     if (IsUsingT32()) {
7656       // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
7657       if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
7658           ((rn.GetCode() & 0xf) != 0xf)) {
7659         EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() |
7660                    (amount << 4));
7661         AdvanceIT();
7662         return;
7663       }
7664     } else {
7665       // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
7666       if (shift.IsRRX() && operand.IsOffset()) {
7667         if (cond.Is(al)) {
7668           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7669           EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() |
7670                   (sign_ << 23));
7671           return;
7672         }
7673       }
7674       // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
7675       if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset()) {
7676         if (cond.Is(al)) {
7677           uint32_t sign_ = sign.IsPlus() ? 1 : 0;
7678           uint32_t amount_ = amount % 32;
7679           EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() |
7680                   (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
7681           return;
7682         }
7683       }
7684     }
7685   }
7686   Delegate(kPli, &Assembler::pli, cond, operand);
7687 }
7688 
pli(Condition cond,Label * label)7689 void Assembler::pli(Condition cond, Label* label) {
7690   VIXL_ASSERT(AllowAssembler());
7691   CheckIT(cond);
7692   Label::Offset offset =
7693       label->IsBound()
7694           ? label->GetLocation() -
7695                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
7696           : 0;
7697   if (IsUsingT32()) {
7698     // PLI{<c>}{<q>} <label> ; T3
7699     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7700          !label->IsBound())) {
7701       static class EmitOp : public Label::LabelEmitOperator {
7702        public:
7703         EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7704         virtual uint32_t Encode(uint32_t instr,
7705                                 Label::Offset pc,
7706                                 const Label* label) const VIXL_OVERRIDE {
7707           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7708           VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7709           uint32_t U = (offset >= 0) && !label->IsMinusZero();
7710           int32_t target = abs(offset) | (U << 12);
7711           return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7712         }
7713       } immop;
7714       EmitT32_32(Link(0xf91ff000U, label, immop));
7715       AdvanceIT();
7716       return;
7717     }
7718   } else {
7719     // PLI{<c>}{<q>} <label> ; A1
7720     if (((label->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
7721          !label->IsBound())) {
7722       if (cond.Is(al)) {
7723         static class EmitOp : public Label::LabelEmitOperator {
7724          public:
7725           EmitOp() : Label::LabelEmitOperator(-4095, 4095) {}
7726           virtual uint32_t Encode(uint32_t instr,
7727                                   Label::Offset pc,
7728                                   const Label* label) const VIXL_OVERRIDE {
7729             Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
7730             VIXL_ASSERT((offset >= -4095) && (offset <= 4095));
7731             uint32_t U = (offset >= 0) && !label->IsMinusZero();
7732             int32_t target = abs(offset) | (U << 12);
7733             return instr | (target & 0xfff) | ((target & 0x1000) << 11);
7734           }
7735         } immop;
7736         EmitA32(Link(0xf45ff000U, label, immop));
7737         return;
7738       }
7739     }
7740   }
7741   Delegate(kPli, &Assembler::pli, cond, label);
7742 }
7743 
pop(Condition cond,EncodingSize size,RegisterList registers)7744 void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) {
7745   VIXL_ASSERT(AllowAssembler());
7746   CheckIT(cond);
7747   if (IsUsingT32()) {
7748     // POP{<c>}{<q>} <registers> ; T1
7749     if (!size.IsWide() && ((registers.GetList() & ~0x80ff) == 0)) {
7750       EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
7751                  GetRegisterListEncoding(registers, 0, 8));
7752       AdvanceIT();
7753       return;
7754     }
7755     // POP{<c>}{<q>} <registers> ; T2
7756     if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0)) {
7757       EmitT32_32(0xe8bd0000U |
7758                  (GetRegisterListEncoding(registers, 15, 1) << 15) |
7759                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
7760                  GetRegisterListEncoding(registers, 0, 13));
7761       AdvanceIT();
7762       return;
7763     }
7764   } else {
7765     // POP{<c>}{<q>} <registers> ; A1
7766     if (cond.IsNotNever()) {
7767       EmitA32(0x08bd0000U | (cond.GetCondition() << 28) |
7768               GetRegisterListEncoding(registers, 0, 16));
7769       return;
7770     }
7771   }
7772   Delegate(kPop, &Assembler::pop, cond, size, registers);
7773 }
7774 
pop(Condition cond,EncodingSize size,Register rt)7775 void Assembler::pop(Condition cond, EncodingSize size, Register rt) {
7776   VIXL_ASSERT(AllowAssembler());
7777   CheckIT(cond);
7778   if (IsUsingT32()) {
7779     // POP{<c>}{<q>} <single_register_list> ; T4
7780     if (!size.IsNarrow() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) {
7781       EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12));
7782       AdvanceIT();
7783       return;
7784     }
7785   } else {
7786     // POP{<c>}{<q>} <single_register_list> ; A1
7787     if (cond.IsNotNever()) {
7788       EmitA32(0x049d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
7789       return;
7790     }
7791   }
7792   Delegate(kPop, &Assembler::pop, cond, size, rt);
7793 }
7794 
push(Condition cond,EncodingSize size,RegisterList registers)7795 void Assembler::push(Condition cond,
7796                      EncodingSize size,
7797                      RegisterList registers) {
7798   VIXL_ASSERT(AllowAssembler());
7799   CheckIT(cond);
7800   if (IsUsingT32()) {
7801     // PUSH{<c>}{<q>} <registers> ; T1
7802     if (!size.IsWide() && ((registers.GetList() & ~0x40ff) == 0)) {
7803       EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
7804                  GetRegisterListEncoding(registers, 0, 8));
7805       AdvanceIT();
7806       return;
7807     }
7808     // PUSH{<c>}{<q>} <registers> ; T1
7809     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
7810       EmitT32_32(0xe92d0000U |
7811                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
7812                  GetRegisterListEncoding(registers, 0, 13));
7813       AdvanceIT();
7814       return;
7815     }
7816   } else {
7817     // PUSH{<c>}{<q>} <registers> ; A1
7818     if (cond.IsNotNever()) {
7819       EmitA32(0x092d0000U | (cond.GetCondition() << 28) |
7820               GetRegisterListEncoding(registers, 0, 16));
7821       return;
7822     }
7823   }
7824   Delegate(kPush, &Assembler::push, cond, size, registers);
7825 }
7826 
push(Condition cond,EncodingSize size,Register rt)7827 void Assembler::push(Condition cond, EncodingSize size, Register rt) {
7828   VIXL_ASSERT(AllowAssembler());
7829   CheckIT(cond);
7830   if (IsUsingT32()) {
7831     // PUSH{<c>}{<q>} <single_register_list> ; T4
7832     if (!size.IsNarrow()) {
7833       EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12));
7834       AdvanceIT();
7835       return;
7836     }
7837   } else {
7838     // PUSH{<c>}{<q>} <single_register_list> ; A1
7839     if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
7840       EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
7841       return;
7842     }
7843   }
7844   Delegate(kPush, &Assembler::push, cond, size, rt);
7845 }
7846 
qadd(Condition cond,Register rd,Register rm,Register rn)7847 void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) {
7848   VIXL_ASSERT(AllowAssembler());
7849   CheckIT(cond);
7850   if (IsUsingT32()) {
7851     // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7852     EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() |
7853                (rn.GetCode() << 16));
7854     AdvanceIT();
7855     return;
7856   } else {
7857     // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7858     if (cond.IsNotNever()) {
7859       EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7860               rm.GetCode() | (rn.GetCode() << 16));
7861       return;
7862     }
7863   }
7864   Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn);
7865 }
7866 
qadd16(Condition cond,Register rd,Register rn,Register rm)7867 void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) {
7868   VIXL_ASSERT(AllowAssembler());
7869   CheckIT(cond);
7870   if (IsUsingT32()) {
7871     // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7872     EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7873                rm.GetCode());
7874     AdvanceIT();
7875     return;
7876   } else {
7877     // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7878     if (cond.IsNotNever()) {
7879       EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7880               (rn.GetCode() << 16) | rm.GetCode());
7881       return;
7882     }
7883   }
7884   Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm);
7885 }
7886 
qadd8(Condition cond,Register rd,Register rn,Register rm)7887 void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) {
7888   VIXL_ASSERT(AllowAssembler());
7889   CheckIT(cond);
7890   if (IsUsingT32()) {
7891     // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7892     EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7893                rm.GetCode());
7894     AdvanceIT();
7895     return;
7896   } else {
7897     // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7898     if (cond.IsNotNever()) {
7899       EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7900               (rn.GetCode() << 16) | rm.GetCode());
7901       return;
7902     }
7903   }
7904   Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm);
7905 }
7906 
qasx(Condition cond,Register rd,Register rn,Register rm)7907 void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) {
7908   VIXL_ASSERT(AllowAssembler());
7909   CheckIT(cond);
7910   if (IsUsingT32()) {
7911     // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7912     EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7913                rm.GetCode());
7914     AdvanceIT();
7915     return;
7916   } else {
7917     // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7918     if (cond.IsNotNever()) {
7919       EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7920               (rn.GetCode() << 16) | rm.GetCode());
7921       return;
7922     }
7923   }
7924   Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm);
7925 }
7926 
qdadd(Condition cond,Register rd,Register rm,Register rn)7927 void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) {
7928   VIXL_ASSERT(AllowAssembler());
7929   CheckIT(cond);
7930   if (IsUsingT32()) {
7931     // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7932     EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() |
7933                (rn.GetCode() << 16));
7934     AdvanceIT();
7935     return;
7936   } else {
7937     // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7938     if (cond.IsNotNever()) {
7939       EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7940               rm.GetCode() | (rn.GetCode() << 16));
7941       return;
7942     }
7943   }
7944   Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn);
7945 }
7946 
qdsub(Condition cond,Register rd,Register rm,Register rn)7947 void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) {
7948   VIXL_ASSERT(AllowAssembler());
7949   CheckIT(cond);
7950   if (IsUsingT32()) {
7951     // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7952     EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
7953                (rn.GetCode() << 16));
7954     AdvanceIT();
7955     return;
7956   } else {
7957     // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7958     if (cond.IsNotNever()) {
7959       EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7960               rm.GetCode() | (rn.GetCode() << 16));
7961       return;
7962     }
7963   }
7964   Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn);
7965 }
7966 
qsax(Condition cond,Register rd,Register rn,Register rm)7967 void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) {
7968   VIXL_ASSERT(AllowAssembler());
7969   CheckIT(cond);
7970   if (IsUsingT32()) {
7971     // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
7972     EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7973                rm.GetCode());
7974     AdvanceIT();
7975     return;
7976   } else {
7977     // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
7978     if (cond.IsNotNever()) {
7979       EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7980               (rn.GetCode() << 16) | rm.GetCode());
7981       return;
7982     }
7983   }
7984   Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm);
7985 }
7986 
qsub(Condition cond,Register rd,Register rm,Register rn)7987 void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) {
7988   VIXL_ASSERT(AllowAssembler());
7989   CheckIT(cond);
7990   if (IsUsingT32()) {
7991     // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
7992     EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
7993                (rn.GetCode() << 16));
7994     AdvanceIT();
7995     return;
7996   } else {
7997     // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
7998     if (cond.IsNotNever()) {
7999       EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8000               rm.GetCode() | (rn.GetCode() << 16));
8001       return;
8002     }
8003   }
8004   Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn);
8005 }
8006 
qsub16(Condition cond,Register rd,Register rn,Register rm)8007 void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) {
8008   VIXL_ASSERT(AllowAssembler());
8009   CheckIT(cond);
8010   if (IsUsingT32()) {
8011     // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8012     EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8013                rm.GetCode());
8014     AdvanceIT();
8015     return;
8016   } else {
8017     // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8018     if (cond.IsNotNever()) {
8019       EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8020               (rn.GetCode() << 16) | rm.GetCode());
8021       return;
8022     }
8023   }
8024   Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm);
8025 }
8026 
qsub8(Condition cond,Register rd,Register rn,Register rm)8027 void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) {
8028   VIXL_ASSERT(AllowAssembler());
8029   CheckIT(cond);
8030   if (IsUsingT32()) {
8031     // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8032     EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8033                rm.GetCode());
8034     AdvanceIT();
8035     return;
8036   } else {
8037     // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8038     if (cond.IsNotNever()) {
8039       EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8040               (rn.GetCode() << 16) | rm.GetCode());
8041       return;
8042     }
8043   }
8044   Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm);
8045 }
8046 
rbit(Condition cond,Register rd,Register rm)8047 void Assembler::rbit(Condition cond, Register rd, Register rm) {
8048   VIXL_ASSERT(AllowAssembler());
8049   CheckIT(cond);
8050   if (IsUsingT32()) {
8051     // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1
8052     EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
8053                (rm.GetCode() << 16));
8054     AdvanceIT();
8055     return;
8056   } else {
8057     // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1
8058     if (cond.IsNotNever()) {
8059       EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8060               rm.GetCode());
8061       return;
8062     }
8063   }
8064   Delegate(kRbit, &Assembler::rbit, cond, rd, rm);
8065 }
8066 
rev(Condition cond,EncodingSize size,Register rd,Register rm)8067 void Assembler::rev(Condition cond,
8068                     EncodingSize size,
8069                     Register rd,
8070                     Register rm) {
8071   VIXL_ASSERT(AllowAssembler());
8072   CheckIT(cond);
8073   if (IsUsingT32()) {
8074     // REV{<c>}{<q>} <Rd>, <Rm> ; T1
8075     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8076       EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3));
8077       AdvanceIT();
8078       return;
8079     }
8080     // REV{<c>}{<q>} <Rd>, <Rm> ; T2
8081     if (!size.IsNarrow()) {
8082       EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() |
8083                  (rm.GetCode() << 16));
8084       AdvanceIT();
8085       return;
8086     }
8087   } else {
8088     // REV{<c>}{<q>} <Rd>, <Rm> ; A1
8089     if (cond.IsNotNever()) {
8090       EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8091               rm.GetCode());
8092       return;
8093     }
8094   }
8095   Delegate(kRev, &Assembler::rev, cond, size, rd, rm);
8096 }
8097 
rev16(Condition cond,EncodingSize size,Register rd,Register rm)8098 void Assembler::rev16(Condition cond,
8099                       EncodingSize size,
8100                       Register rd,
8101                       Register rm) {
8102   VIXL_ASSERT(AllowAssembler());
8103   CheckIT(cond);
8104   if (IsUsingT32()) {
8105     // REV16{<c>}{<q>} <Rd>, <Rm> ; T1
8106     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8107       EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3));
8108       AdvanceIT();
8109       return;
8110     }
8111     // REV16{<c>}{<q>} <Rd>, <Rm> ; T2
8112     if (!size.IsNarrow()) {
8113       EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() |
8114                  (rm.GetCode() << 16));
8115       AdvanceIT();
8116       return;
8117     }
8118   } else {
8119     // REV16{<c>}{<q>} <Rd>, <Rm> ; A1
8120     if (cond.IsNotNever()) {
8121       EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8122               rm.GetCode());
8123       return;
8124     }
8125   }
8126   Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm);
8127 }
8128 
revsh(Condition cond,EncodingSize size,Register rd,Register rm)8129 void Assembler::revsh(Condition cond,
8130                       EncodingSize size,
8131                       Register rd,
8132                       Register rm) {
8133   VIXL_ASSERT(AllowAssembler());
8134   CheckIT(cond);
8135   if (IsUsingT32()) {
8136     // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1
8137     if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8138       EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3));
8139       AdvanceIT();
8140       return;
8141     }
8142     // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2
8143     if (!size.IsNarrow()) {
8144       EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
8145                  (rm.GetCode() << 16));
8146       AdvanceIT();
8147       return;
8148     }
8149   } else {
8150     // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1
8151     if (cond.IsNotNever()) {
8152       EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8153               rm.GetCode());
8154       return;
8155     }
8156   }
8157   Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm);
8158 }
8159 
ror(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)8160 void Assembler::ror(Condition cond,
8161                     EncodingSize size,
8162                     Register rd,
8163                     Register rm,
8164                     const Operand& operand) {
8165   VIXL_ASSERT(AllowAssembler());
8166   CheckIT(cond);
8167   if (operand.IsImmediate()) {
8168     uint32_t imm = operand.GetImmediate();
8169     if (IsUsingT32()) {
8170       // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
8171       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
8172         EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() |
8173                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
8174         AdvanceIT();
8175         return;
8176       }
8177     } else {
8178       // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
8179       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
8180         EmitA32(0x01a00060U | (cond.GetCondition() << 28) |
8181                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
8182         return;
8183       }
8184     }
8185   }
8186   if (operand.IsPlainRegister()) {
8187     Register rs = operand.GetBaseRegister();
8188     if (IsUsingT32()) {
8189       // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
8190       if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
8191           rs.IsLow()) {
8192         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
8193         AdvanceIT();
8194         return;
8195       }
8196       // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
8197       if (!size.IsNarrow()) {
8198         EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
8199                    rs.GetCode());
8200         AdvanceIT();
8201         return;
8202       }
8203     } else {
8204       // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
8205       if (cond.IsNotNever()) {
8206         EmitA32(0x01a00070U | (cond.GetCondition() << 28) |
8207                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
8208         return;
8209       }
8210     }
8211   }
8212   Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand);
8213 }
8214 
rors(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)8215 void Assembler::rors(Condition cond,
8216                      EncodingSize size,
8217                      Register rd,
8218                      Register rm,
8219                      const Operand& operand) {
8220   VIXL_ASSERT(AllowAssembler());
8221   CheckIT(cond);
8222   if (operand.IsImmediate()) {
8223     uint32_t imm = operand.GetImmediate();
8224     if (IsUsingT32()) {
8225       // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
8226       if (!size.IsNarrow() && (imm >= 1) && (imm <= 31)) {
8227         EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() |
8228                    ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
8229         AdvanceIT();
8230         return;
8231       }
8232     } else {
8233       // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
8234       if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
8235         EmitA32(0x01b00060U | (cond.GetCondition() << 28) |
8236                 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
8237         return;
8238       }
8239     }
8240   }
8241   if (operand.IsPlainRegister()) {
8242     Register rs = operand.GetBaseRegister();
8243     if (IsUsingT32()) {
8244       // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
8245       if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
8246           rs.IsLow()) {
8247         EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
8248         AdvanceIT();
8249         return;
8250       }
8251       // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
8252       if (!size.IsNarrow()) {
8253         EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
8254                    rs.GetCode());
8255         AdvanceIT();
8256         return;
8257       }
8258     } else {
8259       // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
8260       if (cond.IsNotNever()) {
8261         EmitA32(0x01b00070U | (cond.GetCondition() << 28) |
8262                 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
8263         return;
8264       }
8265     }
8266   }
8267   Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand);
8268 }
8269 
rrx(Condition cond,Register rd,Register rm)8270 void Assembler::rrx(Condition cond, Register rd, Register rm) {
8271   VIXL_ASSERT(AllowAssembler());
8272   CheckIT(cond);
8273   if (IsUsingT32()) {
8274     // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3
8275     EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode());
8276     AdvanceIT();
8277     return;
8278   } else {
8279     // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1
8280     if (cond.IsNotNever()) {
8281       EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8282               rm.GetCode());
8283       return;
8284     }
8285   }
8286   Delegate(kRrx, &Assembler::rrx, cond, rd, rm);
8287 }
8288 
rrxs(Condition cond,Register rd,Register rm)8289 void Assembler::rrxs(Condition cond, Register rd, Register rm) {
8290   VIXL_ASSERT(AllowAssembler());
8291   CheckIT(cond);
8292   if (IsUsingT32()) {
8293     // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3
8294     EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode());
8295     AdvanceIT();
8296     return;
8297   } else {
8298     // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1
8299     if (cond.IsNotNever()) {
8300       EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8301               rm.GetCode());
8302       return;
8303     }
8304   }
8305   Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm);
8306 }
8307 
rsb(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)8308 void Assembler::rsb(Condition cond,
8309                     EncodingSize size,
8310                     Register rd,
8311                     Register rn,
8312                     const Operand& operand) {
8313   VIXL_ASSERT(AllowAssembler());
8314   CheckIT(cond);
8315   if (operand.IsImmediate()) {
8316     uint32_t imm = operand.GetImmediate();
8317     if (IsUsingT32()) {
8318       ImmediateT32 immediate_t32(imm);
8319       // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1
8320       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
8321           (imm == 0)) {
8322         EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
8323         AdvanceIT();
8324         return;
8325       }
8326       // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
8327       if (!size.IsNarrow() && immediate_t32.IsValid()) {
8328         EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8329                    (immediate_t32.GetEncodingValue() & 0xff) |
8330                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8331                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8332         AdvanceIT();
8333         return;
8334       }
8335     } else {
8336       ImmediateA32 immediate_a32(imm);
8337       // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8338       if (immediate_a32.IsValid() && cond.IsNotNever()) {
8339         EmitA32(0x02600000U | (cond.GetCondition() << 28) |
8340                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8341                 immediate_a32.GetEncodingValue());
8342         return;
8343       }
8344     }
8345   }
8346   if (operand.IsImmediateShiftedRegister()) {
8347     Register rm = operand.GetBaseRegister();
8348     Shift shift = operand.GetShift();
8349     uint32_t amount = operand.GetShiftAmount();
8350     if (IsUsingT32()) {
8351       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
8352       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8353         uint32_t amount_ = amount % 32;
8354         EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8355                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8356                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8357         AdvanceIT();
8358         return;
8359       }
8360     } else {
8361       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8362       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8363         uint32_t amount_ = amount % 32;
8364         EmitA32(0x00600000U | (cond.GetCondition() << 28) |
8365                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8366                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8367         return;
8368       }
8369     }
8370   }
8371   if (operand.IsRegisterShiftedRegister()) {
8372     Register rm = operand.GetBaseRegister();
8373     Shift shift = operand.GetShift();
8374     if (IsUsingA32()) {
8375       // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8376       if (cond.IsNotNever()) {
8377         EmitA32(0x00600010U | (cond.GetCondition() << 28) |
8378                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8379                 (shift.GetType() << 5) |
8380                 (operand.GetShiftRegister().GetCode() << 8));
8381         return;
8382       }
8383     }
8384   }
8385   Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand);
8386 }
8387 
rsbs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)8388 void Assembler::rsbs(Condition cond,
8389                      EncodingSize size,
8390                      Register rd,
8391                      Register rn,
8392                      const Operand& operand) {
8393   VIXL_ASSERT(AllowAssembler());
8394   CheckIT(cond);
8395   if (operand.IsImmediate()) {
8396     uint32_t imm = operand.GetImmediate();
8397     if (IsUsingT32()) {
8398       ImmediateT32 immediate_t32(imm);
8399       // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1
8400       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
8401           (imm == 0)) {
8402         EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
8403         AdvanceIT();
8404         return;
8405       }
8406       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
8407       if (!size.IsNarrow() && immediate_t32.IsValid()) {
8408         EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8409                    (immediate_t32.GetEncodingValue() & 0xff) |
8410                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8411                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8412         AdvanceIT();
8413         return;
8414       }
8415     } else {
8416       ImmediateA32 immediate_a32(imm);
8417       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8418       if (immediate_a32.IsValid() && cond.IsNotNever()) {
8419         EmitA32(0x02700000U | (cond.GetCondition() << 28) |
8420                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8421                 immediate_a32.GetEncodingValue());
8422         return;
8423       }
8424     }
8425   }
8426   if (operand.IsImmediateShiftedRegister()) {
8427     Register rm = operand.GetBaseRegister();
8428     Shift shift = operand.GetShift();
8429     uint32_t amount = operand.GetShiftAmount();
8430     if (IsUsingT32()) {
8431       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
8432       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8433         uint32_t amount_ = amount % 32;
8434         EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8435                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8436                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8437         AdvanceIT();
8438         return;
8439       }
8440     } else {
8441       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8442       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8443         uint32_t amount_ = amount % 32;
8444         EmitA32(0x00700000U | (cond.GetCondition() << 28) |
8445                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8446                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8447         return;
8448       }
8449     }
8450   }
8451   if (operand.IsRegisterShiftedRegister()) {
8452     Register rm = operand.GetBaseRegister();
8453     Shift shift = operand.GetShift();
8454     if (IsUsingA32()) {
8455       // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8456       if (cond.IsNotNever()) {
8457         EmitA32(0x00700010U | (cond.GetCondition() << 28) |
8458                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8459                 (shift.GetType() << 5) |
8460                 (operand.GetShiftRegister().GetCode() << 8));
8461         return;
8462       }
8463     }
8464   }
8465   Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand);
8466 }
8467 
rsc(Condition cond,Register rd,Register rn,const Operand & operand)8468 void Assembler::rsc(Condition cond,
8469                     Register rd,
8470                     Register rn,
8471                     const Operand& operand) {
8472   VIXL_ASSERT(AllowAssembler());
8473   CheckIT(cond);
8474   if (operand.IsImmediate()) {
8475     uint32_t imm = operand.GetImmediate();
8476     if (IsUsingA32()) {
8477       ImmediateA32 immediate_a32(imm);
8478       // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8479       if (immediate_a32.IsValid() && cond.IsNotNever()) {
8480         EmitA32(0x02e00000U | (cond.GetCondition() << 28) |
8481                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8482                 immediate_a32.GetEncodingValue());
8483         return;
8484       }
8485     }
8486   }
8487   if (operand.IsImmediateShiftedRegister()) {
8488     Register rm = operand.GetBaseRegister();
8489     Shift shift = operand.GetShift();
8490     uint32_t amount = operand.GetShiftAmount();
8491     if (IsUsingA32()) {
8492       // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8493       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8494         uint32_t amount_ = amount % 32;
8495         EmitA32(0x00e00000U | (cond.GetCondition() << 28) |
8496                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8497                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8498         return;
8499       }
8500     }
8501   }
8502   if (operand.IsRegisterShiftedRegister()) {
8503     Register rm = operand.GetBaseRegister();
8504     Shift shift = operand.GetShift();
8505     if (IsUsingA32()) {
8506       // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8507       if (cond.IsNotNever()) {
8508         EmitA32(0x00e00010U | (cond.GetCondition() << 28) |
8509                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8510                 (shift.GetType() << 5) |
8511                 (operand.GetShiftRegister().GetCode() << 8));
8512         return;
8513       }
8514     }
8515   }
8516   Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand);
8517 }
8518 
rscs(Condition cond,Register rd,Register rn,const Operand & operand)8519 void Assembler::rscs(Condition cond,
8520                      Register rd,
8521                      Register rn,
8522                      const Operand& operand) {
8523   VIXL_ASSERT(AllowAssembler());
8524   CheckIT(cond);
8525   if (operand.IsImmediate()) {
8526     uint32_t imm = operand.GetImmediate();
8527     if (IsUsingA32()) {
8528       ImmediateA32 immediate_a32(imm);
8529       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8530       if (immediate_a32.IsValid() && cond.IsNotNever()) {
8531         EmitA32(0x02f00000U | (cond.GetCondition() << 28) |
8532                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8533                 immediate_a32.GetEncodingValue());
8534         return;
8535       }
8536     }
8537   }
8538   if (operand.IsImmediateShiftedRegister()) {
8539     Register rm = operand.GetBaseRegister();
8540     Shift shift = operand.GetShift();
8541     uint32_t amount = operand.GetShiftAmount();
8542     if (IsUsingA32()) {
8543       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8544       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8545         uint32_t amount_ = amount % 32;
8546         EmitA32(0x00f00000U | (cond.GetCondition() << 28) |
8547                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8548                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8549         return;
8550       }
8551     }
8552   }
8553   if (operand.IsRegisterShiftedRegister()) {
8554     Register rm = operand.GetBaseRegister();
8555     Shift shift = operand.GetShift();
8556     if (IsUsingA32()) {
8557       // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8558       if (cond.IsNotNever()) {
8559         EmitA32(0x00f00010U | (cond.GetCondition() << 28) |
8560                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8561                 (shift.GetType() << 5) |
8562                 (operand.GetShiftRegister().GetCode() << 8));
8563         return;
8564       }
8565     }
8566   }
8567   Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand);
8568 }
8569 
sadd16(Condition cond,Register rd,Register rn,Register rm)8570 void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) {
8571   VIXL_ASSERT(AllowAssembler());
8572   CheckIT(cond);
8573   if (IsUsingT32()) {
8574     // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8575     EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8576                rm.GetCode());
8577     AdvanceIT();
8578     return;
8579   } else {
8580     // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8581     if (cond.IsNotNever()) {
8582       EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8583               (rn.GetCode() << 16) | rm.GetCode());
8584       return;
8585     }
8586   }
8587   Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm);
8588 }
8589 
sadd8(Condition cond,Register rd,Register rn,Register rm)8590 void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) {
8591   VIXL_ASSERT(AllowAssembler());
8592   CheckIT(cond);
8593   if (IsUsingT32()) {
8594     // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8595     EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8596                rm.GetCode());
8597     AdvanceIT();
8598     return;
8599   } else {
8600     // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8601     if (cond.IsNotNever()) {
8602       EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8603               (rn.GetCode() << 16) | rm.GetCode());
8604       return;
8605     }
8606   }
8607   Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm);
8608 }
8609 
sasx(Condition cond,Register rd,Register rn,Register rm)8610 void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) {
8611   VIXL_ASSERT(AllowAssembler());
8612   CheckIT(cond);
8613   if (IsUsingT32()) {
8614     // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8615     EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8616                rm.GetCode());
8617     AdvanceIT();
8618     return;
8619   } else {
8620     // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8621     if (cond.IsNotNever()) {
8622       EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8623               (rn.GetCode() << 16) | rm.GetCode());
8624       return;
8625     }
8626   }
8627   Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm);
8628 }
8629 
sbc(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)8630 void Assembler::sbc(Condition cond,
8631                     EncodingSize size,
8632                     Register rd,
8633                     Register rn,
8634                     const Operand& operand) {
8635   VIXL_ASSERT(AllowAssembler());
8636   CheckIT(cond);
8637   if (operand.IsImmediate()) {
8638     uint32_t imm = operand.GetImmediate();
8639     if (IsUsingT32()) {
8640       ImmediateT32 immediate_t32(imm);
8641       // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
8642       if (!size.IsNarrow() && immediate_t32.IsValid()) {
8643         EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8644                    (immediate_t32.GetEncodingValue() & 0xff) |
8645                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8646                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8647         AdvanceIT();
8648         return;
8649       }
8650     } else {
8651       ImmediateA32 immediate_a32(imm);
8652       // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8653       if (immediate_a32.IsValid() && cond.IsNotNever()) {
8654         EmitA32(0x02c00000U | (cond.GetCondition() << 28) |
8655                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8656                 immediate_a32.GetEncodingValue());
8657         return;
8658       }
8659     }
8660   }
8661   if (operand.IsImmediateShiftedRegister()) {
8662     Register rm = operand.GetBaseRegister();
8663     if (operand.IsPlainRegister()) {
8664       if (IsUsingT32()) {
8665         // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
8666         if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
8667             rm.IsLow()) {
8668           EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
8669           AdvanceIT();
8670           return;
8671         }
8672       }
8673     }
8674     Shift shift = operand.GetShift();
8675     uint32_t amount = operand.GetShiftAmount();
8676     if (IsUsingT32()) {
8677       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
8678       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8679         uint32_t amount_ = amount % 32;
8680         EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8681                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8682                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8683         AdvanceIT();
8684         return;
8685       }
8686     } else {
8687       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8688       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8689         uint32_t amount_ = amount % 32;
8690         EmitA32(0x00c00000U | (cond.GetCondition() << 28) |
8691                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8692                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8693         return;
8694       }
8695     }
8696   }
8697   if (operand.IsRegisterShiftedRegister()) {
8698     Register rm = operand.GetBaseRegister();
8699     Shift shift = operand.GetShift();
8700     if (IsUsingA32()) {
8701       // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8702       if (cond.IsNotNever()) {
8703         EmitA32(0x00c00010U | (cond.GetCondition() << 28) |
8704                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8705                 (shift.GetType() << 5) |
8706                 (operand.GetShiftRegister().GetCode() << 8));
8707         return;
8708       }
8709     }
8710   }
8711   Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand);
8712 }
8713 
sbcs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)8714 void Assembler::sbcs(Condition cond,
8715                      EncodingSize size,
8716                      Register rd,
8717                      Register rn,
8718                      const Operand& operand) {
8719   VIXL_ASSERT(AllowAssembler());
8720   CheckIT(cond);
8721   if (operand.IsImmediate()) {
8722     uint32_t imm = operand.GetImmediate();
8723     if (IsUsingT32()) {
8724       ImmediateT32 immediate_t32(imm);
8725       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
8726       if (!size.IsNarrow() && immediate_t32.IsValid()) {
8727         EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8728                    (immediate_t32.GetEncodingValue() & 0xff) |
8729                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
8730                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
8731         AdvanceIT();
8732         return;
8733       }
8734     } else {
8735       ImmediateA32 immediate_a32(imm);
8736       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
8737       if (immediate_a32.IsValid() && cond.IsNotNever()) {
8738         EmitA32(0x02d00000U | (cond.GetCondition() << 28) |
8739                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
8740                 immediate_a32.GetEncodingValue());
8741         return;
8742       }
8743     }
8744   }
8745   if (operand.IsImmediateShiftedRegister()) {
8746     Register rm = operand.GetBaseRegister();
8747     if (operand.IsPlainRegister()) {
8748       if (IsUsingT32()) {
8749         // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
8750         if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
8751             rm.IsLow()) {
8752           EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
8753           AdvanceIT();
8754           return;
8755         }
8756       }
8757     }
8758     Shift shift = operand.GetShift();
8759     uint32_t amount = operand.GetShiftAmount();
8760     if (IsUsingT32()) {
8761       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
8762       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
8763         uint32_t amount_ = amount % 32;
8764         EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8765                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
8766                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
8767         AdvanceIT();
8768         return;
8769       }
8770     } else {
8771       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
8772       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
8773         uint32_t amount_ = amount % 32;
8774         EmitA32(0x00d00000U | (cond.GetCondition() << 28) |
8775                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8776                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
8777         return;
8778       }
8779     }
8780   }
8781   if (operand.IsRegisterShiftedRegister()) {
8782     Register rm = operand.GetBaseRegister();
8783     Shift shift = operand.GetShift();
8784     if (IsUsingA32()) {
8785       // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
8786       if (cond.IsNotNever()) {
8787         EmitA32(0x00d00010U | (cond.GetCondition() << 28) |
8788                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8789                 (shift.GetType() << 5) |
8790                 (operand.GetShiftRegister().GetCode() << 8));
8791         return;
8792       }
8793     }
8794   }
8795   Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand);
8796 }
8797 
sbfx(Condition cond,Register rd,Register rn,uint32_t lsb,const Operand & operand)8798 void Assembler::sbfx(Condition cond,
8799                      Register rd,
8800                      Register rn,
8801                      uint32_t lsb,
8802                      const Operand& operand) {
8803   VIXL_ASSERT(AllowAssembler());
8804   CheckIT(cond);
8805   if (operand.IsImmediate()) {
8806     uint32_t width = operand.GetImmediate();
8807     if (IsUsingT32()) {
8808       // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
8809       if ((lsb <= 31) &&
8810           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
8811         uint32_t widthm1 = width - 1;
8812         EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8813                    ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
8814         AdvanceIT();
8815         return;
8816       }
8817     } else {
8818       // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
8819       if ((lsb <= 31) && cond.IsNotNever() &&
8820           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
8821         uint32_t widthm1 = width - 1;
8822         EmitA32(0x07a00050U | (cond.GetCondition() << 28) |
8823                 (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) |
8824                 (widthm1 << 16));
8825         return;
8826       }
8827     }
8828   }
8829   Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, operand);
8830 }
8831 
sdiv(Condition cond,Register rd,Register rn,Register rm)8832 void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) {
8833   VIXL_ASSERT(AllowAssembler());
8834   CheckIT(cond);
8835   if (IsUsingT32()) {
8836     // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8837     EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8838                rm.GetCode());
8839     AdvanceIT();
8840     return;
8841   } else {
8842     // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8843     if (cond.IsNotNever()) {
8844       EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
8845               rn.GetCode() | (rm.GetCode() << 8));
8846       return;
8847     }
8848   }
8849   Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm);
8850 }
8851 
sel(Condition cond,Register rd,Register rn,Register rm)8852 void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) {
8853   VIXL_ASSERT(AllowAssembler());
8854   CheckIT(cond);
8855   if (IsUsingT32()) {
8856     // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8857     EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8858                rm.GetCode());
8859     AdvanceIT();
8860     return;
8861   } else {
8862     // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8863     if (cond.IsNotNever()) {
8864       EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8865               (rn.GetCode() << 16) | rm.GetCode());
8866       return;
8867     }
8868   }
8869   Delegate(kSel, &Assembler::sel, cond, rd, rn, rm);
8870 }
8871 
shadd16(Condition cond,Register rd,Register rn,Register rm)8872 void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) {
8873   VIXL_ASSERT(AllowAssembler());
8874   CheckIT(cond);
8875   if (IsUsingT32()) {
8876     // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8877     EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8878                rm.GetCode());
8879     AdvanceIT();
8880     return;
8881   } else {
8882     // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8883     if (cond.IsNotNever()) {
8884       EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8885               (rn.GetCode() << 16) | rm.GetCode());
8886       return;
8887     }
8888   }
8889   Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm);
8890 }
8891 
shadd8(Condition cond,Register rd,Register rn,Register rm)8892 void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) {
8893   VIXL_ASSERT(AllowAssembler());
8894   CheckIT(cond);
8895   if (IsUsingT32()) {
8896     // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8897     EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8898                rm.GetCode());
8899     AdvanceIT();
8900     return;
8901   } else {
8902     // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8903     if (cond.IsNotNever()) {
8904       EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8905               (rn.GetCode() << 16) | rm.GetCode());
8906       return;
8907     }
8908   }
8909   Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm);
8910 }
8911 
shasx(Condition cond,Register rd,Register rn,Register rm)8912 void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) {
8913   VIXL_ASSERT(AllowAssembler());
8914   CheckIT(cond);
8915   if (IsUsingT32()) {
8916     // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8917     EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8918                rm.GetCode());
8919     AdvanceIT();
8920     return;
8921   } else {
8922     // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8923     if (cond.IsNotNever()) {
8924       EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8925               (rn.GetCode() << 16) | rm.GetCode());
8926       return;
8927     }
8928   }
8929   Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm);
8930 }
8931 
shsax(Condition cond,Register rd,Register rn,Register rm)8932 void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) {
8933   VIXL_ASSERT(AllowAssembler());
8934   CheckIT(cond);
8935   if (IsUsingT32()) {
8936     // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8937     EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8938                rm.GetCode());
8939     AdvanceIT();
8940     return;
8941   } else {
8942     // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8943     if (cond.IsNotNever()) {
8944       EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8945               (rn.GetCode() << 16) | rm.GetCode());
8946       return;
8947     }
8948   }
8949   Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm);
8950 }
8951 
shsub16(Condition cond,Register rd,Register rn,Register rm)8952 void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) {
8953   VIXL_ASSERT(AllowAssembler());
8954   CheckIT(cond);
8955   if (IsUsingT32()) {
8956     // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8957     EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8958                rm.GetCode());
8959     AdvanceIT();
8960     return;
8961   } else {
8962     // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8963     if (cond.IsNotNever()) {
8964       EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8965               (rn.GetCode() << 16) | rm.GetCode());
8966       return;
8967     }
8968   }
8969   Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm);
8970 }
8971 
shsub8(Condition cond,Register rd,Register rn,Register rm)8972 void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) {
8973   VIXL_ASSERT(AllowAssembler());
8974   CheckIT(cond);
8975   if (IsUsingT32()) {
8976     // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8977     EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8978                rm.GetCode());
8979     AdvanceIT();
8980     return;
8981   } else {
8982     // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8983     if (cond.IsNotNever()) {
8984       EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8985               (rn.GetCode() << 16) | rm.GetCode());
8986       return;
8987     }
8988   }
8989   Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm);
8990 }
8991 
smlabb(Condition cond,Register rd,Register rn,Register rm,Register ra)8992 void Assembler::smlabb(
8993     Condition cond, Register rd, Register rn, Register rm, Register ra) {
8994   VIXL_ASSERT(AllowAssembler());
8995   CheckIT(cond);
8996   if (IsUsingT32()) {
8997     // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
8998     if (!ra.Is(pc)) {
8999       EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9000                  rm.GetCode() | (ra.GetCode() << 12));
9001       AdvanceIT();
9002       return;
9003     }
9004   } else {
9005     // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9006     if (cond.IsNotNever()) {
9007       EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9008               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9009       return;
9010     }
9011   }
9012   Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra);
9013 }
9014 
smlabt(Condition cond,Register rd,Register rn,Register rm,Register ra)9015 void Assembler::smlabt(
9016     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9017   VIXL_ASSERT(AllowAssembler());
9018   CheckIT(cond);
9019   if (IsUsingT32()) {
9020     // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9021     if (!ra.Is(pc)) {
9022       EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9023                  rm.GetCode() | (ra.GetCode() << 12));
9024       AdvanceIT();
9025       return;
9026     }
9027   } else {
9028     // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9029     if (cond.IsNotNever()) {
9030       EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9031               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9032       return;
9033     }
9034   }
9035   Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra);
9036 }
9037 
smlad(Condition cond,Register rd,Register rn,Register rm,Register ra)9038 void Assembler::smlad(
9039     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9040   VIXL_ASSERT(AllowAssembler());
9041   CheckIT(cond);
9042   if (IsUsingT32()) {
9043     // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9044     if (!ra.Is(pc)) {
9045       EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9046                  rm.GetCode() | (ra.GetCode() << 12));
9047       AdvanceIT();
9048       return;
9049     }
9050   } else {
9051     // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9052     if (cond.IsNotNever() && !ra.Is(pc)) {
9053       EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9054               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9055       return;
9056     }
9057   }
9058   Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra);
9059 }
9060 
smladx(Condition cond,Register rd,Register rn,Register rm,Register ra)9061 void Assembler::smladx(
9062     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9063   VIXL_ASSERT(AllowAssembler());
9064   CheckIT(cond);
9065   if (IsUsingT32()) {
9066     // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9067     if (!ra.Is(pc)) {
9068       EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9069                  rm.GetCode() | (ra.GetCode() << 12));
9070       AdvanceIT();
9071       return;
9072     }
9073   } else {
9074     // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9075     if (cond.IsNotNever() && !ra.Is(pc)) {
9076       EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9077               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9078       return;
9079     }
9080   }
9081   Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra);
9082 }
9083 
smlal(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9084 void Assembler::smlal(
9085     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9086   VIXL_ASSERT(AllowAssembler());
9087   CheckIT(cond);
9088   if (IsUsingT32()) {
9089     // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9090     EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9091                (rn.GetCode() << 16) | rm.GetCode());
9092     AdvanceIT();
9093     return;
9094   } else {
9095     // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9096     if (cond.IsNotNever()) {
9097       EmitA32(0x00e00090U | (cond.GetCondition() << 28) |
9098               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9099               (rm.GetCode() << 8));
9100       return;
9101     }
9102   }
9103   Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm);
9104 }
9105 
smlalbb(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9106 void Assembler::smlalbb(
9107     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9108   VIXL_ASSERT(AllowAssembler());
9109   CheckIT(cond);
9110   if (IsUsingT32()) {
9111     // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9112     EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9113                (rn.GetCode() << 16) | rm.GetCode());
9114     AdvanceIT();
9115     return;
9116   } else {
9117     // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9118     if (cond.IsNotNever()) {
9119       EmitA32(0x01400080U | (cond.GetCondition() << 28) |
9120               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9121               (rm.GetCode() << 8));
9122       return;
9123     }
9124   }
9125   Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm);
9126 }
9127 
smlalbt(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9128 void Assembler::smlalbt(
9129     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9130   VIXL_ASSERT(AllowAssembler());
9131   CheckIT(cond);
9132   if (IsUsingT32()) {
9133     // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9134     EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9135                (rn.GetCode() << 16) | rm.GetCode());
9136     AdvanceIT();
9137     return;
9138   } else {
9139     // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9140     if (cond.IsNotNever()) {
9141       EmitA32(0x014000c0U | (cond.GetCondition() << 28) |
9142               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9143               (rm.GetCode() << 8));
9144       return;
9145     }
9146   }
9147   Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm);
9148 }
9149 
smlald(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9150 void Assembler::smlald(
9151     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9152   VIXL_ASSERT(AllowAssembler());
9153   CheckIT(cond);
9154   if (IsUsingT32()) {
9155     // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9156     EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9157                (rn.GetCode() << 16) | rm.GetCode());
9158     AdvanceIT();
9159     return;
9160   } else {
9161     // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9162     if (cond.IsNotNever()) {
9163       EmitA32(0x07400010U | (cond.GetCondition() << 28) |
9164               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9165               (rm.GetCode() << 8));
9166       return;
9167     }
9168   }
9169   Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm);
9170 }
9171 
smlaldx(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9172 void Assembler::smlaldx(
9173     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9174   VIXL_ASSERT(AllowAssembler());
9175   CheckIT(cond);
9176   if (IsUsingT32()) {
9177     // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9178     EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9179                (rn.GetCode() << 16) | rm.GetCode());
9180     AdvanceIT();
9181     return;
9182   } else {
9183     // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9184     if (cond.IsNotNever()) {
9185       EmitA32(0x07400030U | (cond.GetCondition() << 28) |
9186               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9187               (rm.GetCode() << 8));
9188       return;
9189     }
9190   }
9191   Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm);
9192 }
9193 
smlals(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9194 void Assembler::smlals(
9195     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9196   VIXL_ASSERT(AllowAssembler());
9197   CheckIT(cond);
9198   if (IsUsingA32()) {
9199     // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9200     if (cond.IsNotNever()) {
9201       EmitA32(0x00f00090U | (cond.GetCondition() << 28) |
9202               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9203               (rm.GetCode() << 8));
9204       return;
9205     }
9206   }
9207   Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm);
9208 }
9209 
smlaltb(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9210 void Assembler::smlaltb(
9211     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9212   VIXL_ASSERT(AllowAssembler());
9213   CheckIT(cond);
9214   if (IsUsingT32()) {
9215     // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9216     EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9217                (rn.GetCode() << 16) | rm.GetCode());
9218     AdvanceIT();
9219     return;
9220   } else {
9221     // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9222     if (cond.IsNotNever()) {
9223       EmitA32(0x014000a0U | (cond.GetCondition() << 28) |
9224               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9225               (rm.GetCode() << 8));
9226       return;
9227     }
9228   }
9229   Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm);
9230 }
9231 
smlaltt(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9232 void Assembler::smlaltt(
9233     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9234   VIXL_ASSERT(AllowAssembler());
9235   CheckIT(cond);
9236   if (IsUsingT32()) {
9237     // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9238     EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9239                (rn.GetCode() << 16) | rm.GetCode());
9240     AdvanceIT();
9241     return;
9242   } else {
9243     // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9244     if (cond.IsNotNever()) {
9245       EmitA32(0x014000e0U | (cond.GetCondition() << 28) |
9246               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9247               (rm.GetCode() << 8));
9248       return;
9249     }
9250   }
9251   Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm);
9252 }
9253 
smlatb(Condition cond,Register rd,Register rn,Register rm,Register ra)9254 void Assembler::smlatb(
9255     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9256   VIXL_ASSERT(AllowAssembler());
9257   CheckIT(cond);
9258   if (IsUsingT32()) {
9259     // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9260     if (!ra.Is(pc)) {
9261       EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9262                  rm.GetCode() | (ra.GetCode() << 12));
9263       AdvanceIT();
9264       return;
9265     }
9266   } else {
9267     // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9268     if (cond.IsNotNever()) {
9269       EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9270               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9271       return;
9272     }
9273   }
9274   Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra);
9275 }
9276 
smlatt(Condition cond,Register rd,Register rn,Register rm,Register ra)9277 void Assembler::smlatt(
9278     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9279   VIXL_ASSERT(AllowAssembler());
9280   CheckIT(cond);
9281   if (IsUsingT32()) {
9282     // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9283     if (!ra.Is(pc)) {
9284       EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9285                  rm.GetCode() | (ra.GetCode() << 12));
9286       AdvanceIT();
9287       return;
9288     }
9289   } else {
9290     // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9291     if (cond.IsNotNever()) {
9292       EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9293               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9294       return;
9295     }
9296   }
9297   Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra);
9298 }
9299 
smlawb(Condition cond,Register rd,Register rn,Register rm,Register ra)9300 void Assembler::smlawb(
9301     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9302   VIXL_ASSERT(AllowAssembler());
9303   CheckIT(cond);
9304   if (IsUsingT32()) {
9305     // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9306     if (!ra.Is(pc)) {
9307       EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9308                  rm.GetCode() | (ra.GetCode() << 12));
9309       AdvanceIT();
9310       return;
9311     }
9312   } else {
9313     // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9314     if (cond.IsNotNever()) {
9315       EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9316               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9317       return;
9318     }
9319   }
9320   Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra);
9321 }
9322 
smlawt(Condition cond,Register rd,Register rn,Register rm,Register ra)9323 void Assembler::smlawt(
9324     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9325   VIXL_ASSERT(AllowAssembler());
9326   CheckIT(cond);
9327   if (IsUsingT32()) {
9328     // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9329     if (!ra.Is(pc)) {
9330       EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9331                  rm.GetCode() | (ra.GetCode() << 12));
9332       AdvanceIT();
9333       return;
9334     }
9335   } else {
9336     // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9337     if (cond.IsNotNever()) {
9338       EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9339               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9340       return;
9341     }
9342   }
9343   Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra);
9344 }
9345 
smlsd(Condition cond,Register rd,Register rn,Register rm,Register ra)9346 void Assembler::smlsd(
9347     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9348   VIXL_ASSERT(AllowAssembler());
9349   CheckIT(cond);
9350   if (IsUsingT32()) {
9351     // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9352     if (!ra.Is(pc)) {
9353       EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9354                  rm.GetCode() | (ra.GetCode() << 12));
9355       AdvanceIT();
9356       return;
9357     }
9358   } else {
9359     // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9360     if (cond.IsNotNever() && !ra.Is(pc)) {
9361       EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9362               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9363       return;
9364     }
9365   }
9366   Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra);
9367 }
9368 
smlsdx(Condition cond,Register rd,Register rn,Register rm,Register ra)9369 void Assembler::smlsdx(
9370     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9371   VIXL_ASSERT(AllowAssembler());
9372   CheckIT(cond);
9373   if (IsUsingT32()) {
9374     // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9375     if (!ra.Is(pc)) {
9376       EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9377                  rm.GetCode() | (ra.GetCode() << 12));
9378       AdvanceIT();
9379       return;
9380     }
9381   } else {
9382     // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9383     if (cond.IsNotNever() && !ra.Is(pc)) {
9384       EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9385               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9386       return;
9387     }
9388   }
9389   Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra);
9390 }
9391 
smlsld(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9392 void Assembler::smlsld(
9393     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9394   VIXL_ASSERT(AllowAssembler());
9395   CheckIT(cond);
9396   if (IsUsingT32()) {
9397     // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9398     EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9399                (rn.GetCode() << 16) | rm.GetCode());
9400     AdvanceIT();
9401     return;
9402   } else {
9403     // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9404     if (cond.IsNotNever()) {
9405       EmitA32(0x07400050U | (cond.GetCondition() << 28) |
9406               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9407               (rm.GetCode() << 8));
9408       return;
9409     }
9410   }
9411   Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm);
9412 }
9413 
smlsldx(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9414 void Assembler::smlsldx(
9415     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9416   VIXL_ASSERT(AllowAssembler());
9417   CheckIT(cond);
9418   if (IsUsingT32()) {
9419     // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9420     EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9421                (rn.GetCode() << 16) | rm.GetCode());
9422     AdvanceIT();
9423     return;
9424   } else {
9425     // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9426     if (cond.IsNotNever()) {
9427       EmitA32(0x07400070U | (cond.GetCondition() << 28) |
9428               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9429               (rm.GetCode() << 8));
9430       return;
9431     }
9432   }
9433   Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm);
9434 }
9435 
smmla(Condition cond,Register rd,Register rn,Register rm,Register ra)9436 void Assembler::smmla(
9437     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9438   VIXL_ASSERT(AllowAssembler());
9439   CheckIT(cond);
9440   if (IsUsingT32()) {
9441     // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9442     if (!ra.Is(pc)) {
9443       EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9444                  rm.GetCode() | (ra.GetCode() << 12));
9445       AdvanceIT();
9446       return;
9447     }
9448   } else {
9449     // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9450     if (cond.IsNotNever() && !ra.Is(pc)) {
9451       EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9452               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9453       return;
9454     }
9455   }
9456   Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra);
9457 }
9458 
smmlar(Condition cond,Register rd,Register rn,Register rm,Register ra)9459 void Assembler::smmlar(
9460     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9461   VIXL_ASSERT(AllowAssembler());
9462   CheckIT(cond);
9463   if (IsUsingT32()) {
9464     // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9465     if (!ra.Is(pc)) {
9466       EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9467                  rm.GetCode() | (ra.GetCode() << 12));
9468       AdvanceIT();
9469       return;
9470     }
9471   } else {
9472     // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9473     if (cond.IsNotNever() && !ra.Is(pc)) {
9474       EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9475               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9476       return;
9477     }
9478   }
9479   Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra);
9480 }
9481 
smmls(Condition cond,Register rd,Register rn,Register rm,Register ra)9482 void Assembler::smmls(
9483     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9484   VIXL_ASSERT(AllowAssembler());
9485   CheckIT(cond);
9486   if (IsUsingT32()) {
9487     // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9488     EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9489                rm.GetCode() | (ra.GetCode() << 12));
9490     AdvanceIT();
9491     return;
9492   } else {
9493     // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9494     if (cond.IsNotNever()) {
9495       EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9496               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9497       return;
9498     }
9499   }
9500   Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra);
9501 }
9502 
smmlsr(Condition cond,Register rd,Register rn,Register rm,Register ra)9503 void Assembler::smmlsr(
9504     Condition cond, Register rd, Register rn, Register rm, Register ra) {
9505   VIXL_ASSERT(AllowAssembler());
9506   CheckIT(cond);
9507   if (IsUsingT32()) {
9508     // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9509     EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9510                rm.GetCode() | (ra.GetCode() << 12));
9511     AdvanceIT();
9512     return;
9513   } else {
9514     // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9515     if (cond.IsNotNever()) {
9516       EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9517               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9518       return;
9519     }
9520   }
9521   Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra);
9522 }
9523 
smmul(Condition cond,Register rd,Register rn,Register rm)9524 void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) {
9525   VIXL_ASSERT(AllowAssembler());
9526   CheckIT(cond);
9527   if (IsUsingT32()) {
9528     // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9529     EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9530                rm.GetCode());
9531     AdvanceIT();
9532     return;
9533   } else {
9534     // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9535     if (cond.IsNotNever()) {
9536       EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9537               rn.GetCode() | (rm.GetCode() << 8));
9538       return;
9539     }
9540   }
9541   Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm);
9542 }
9543 
smmulr(Condition cond,Register rd,Register rn,Register rm)9544 void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) {
9545   VIXL_ASSERT(AllowAssembler());
9546   CheckIT(cond);
9547   if (IsUsingT32()) {
9548     // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9549     EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9550                rm.GetCode());
9551     AdvanceIT();
9552     return;
9553   } else {
9554     // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9555     if (cond.IsNotNever()) {
9556       EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9557               rn.GetCode() | (rm.GetCode() << 8));
9558       return;
9559     }
9560   }
9561   Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm);
9562 }
9563 
smuad(Condition cond,Register rd,Register rn,Register rm)9564 void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) {
9565   VIXL_ASSERT(AllowAssembler());
9566   CheckIT(cond);
9567   if (IsUsingT32()) {
9568     // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9569     EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9570                rm.GetCode());
9571     AdvanceIT();
9572     return;
9573   } else {
9574     // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9575     if (cond.IsNotNever()) {
9576       EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9577               rn.GetCode() | (rm.GetCode() << 8));
9578       return;
9579     }
9580   }
9581   Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm);
9582 }
9583 
smuadx(Condition cond,Register rd,Register rn,Register rm)9584 void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) {
9585   VIXL_ASSERT(AllowAssembler());
9586   CheckIT(cond);
9587   if (IsUsingT32()) {
9588     // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9589     EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9590                rm.GetCode());
9591     AdvanceIT();
9592     return;
9593   } else {
9594     // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9595     if (cond.IsNotNever()) {
9596       EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9597               rn.GetCode() | (rm.GetCode() << 8));
9598       return;
9599     }
9600   }
9601   Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm);
9602 }
9603 
smulbb(Condition cond,Register rd,Register rn,Register rm)9604 void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) {
9605   VIXL_ASSERT(AllowAssembler());
9606   CheckIT(cond);
9607   if (IsUsingT32()) {
9608     // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9609     EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9610                rm.GetCode());
9611     AdvanceIT();
9612     return;
9613   } else {
9614     // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9615     if (cond.IsNotNever()) {
9616       EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9617               rn.GetCode() | (rm.GetCode() << 8));
9618       return;
9619     }
9620   }
9621   Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm);
9622 }
9623 
smulbt(Condition cond,Register rd,Register rn,Register rm)9624 void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) {
9625   VIXL_ASSERT(AllowAssembler());
9626   CheckIT(cond);
9627   if (IsUsingT32()) {
9628     // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9629     EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9630                rm.GetCode());
9631     AdvanceIT();
9632     return;
9633   } else {
9634     // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9635     if (cond.IsNotNever()) {
9636       EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9637               rn.GetCode() | (rm.GetCode() << 8));
9638       return;
9639     }
9640   }
9641   Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm);
9642 }
9643 
smull(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9644 void Assembler::smull(
9645     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9646   VIXL_ASSERT(AllowAssembler());
9647   CheckIT(cond);
9648   if (IsUsingT32()) {
9649     // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9650     EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9651                (rn.GetCode() << 16) | rm.GetCode());
9652     AdvanceIT();
9653     return;
9654   } else {
9655     // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9656     if (cond.IsNotNever()) {
9657       EmitA32(0x00c00090U | (cond.GetCondition() << 28) |
9658               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9659               (rm.GetCode() << 8));
9660       return;
9661     }
9662   }
9663   Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm);
9664 }
9665 
smulls(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9666 void Assembler::smulls(
9667     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9668   VIXL_ASSERT(AllowAssembler());
9669   CheckIT(cond);
9670   if (IsUsingA32()) {
9671     // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9672     if (cond.IsNotNever()) {
9673       EmitA32(0x00d00090U | (cond.GetCondition() << 28) |
9674               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9675               (rm.GetCode() << 8));
9676       return;
9677     }
9678   }
9679   Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm);
9680 }
9681 
smultb(Condition cond,Register rd,Register rn,Register rm)9682 void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) {
9683   VIXL_ASSERT(AllowAssembler());
9684   CheckIT(cond);
9685   if (IsUsingT32()) {
9686     // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9687     EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9688                rm.GetCode());
9689     AdvanceIT();
9690     return;
9691   } else {
9692     // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9693     if (cond.IsNotNever()) {
9694       EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9695               rn.GetCode() | (rm.GetCode() << 8));
9696       return;
9697     }
9698   }
9699   Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm);
9700 }
9701 
smultt(Condition cond,Register rd,Register rn,Register rm)9702 void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) {
9703   VIXL_ASSERT(AllowAssembler());
9704   CheckIT(cond);
9705   if (IsUsingT32()) {
9706     // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9707     EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9708                rm.GetCode());
9709     AdvanceIT();
9710     return;
9711   } else {
9712     // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9713     if (cond.IsNotNever()) {
9714       EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9715               rn.GetCode() | (rm.GetCode() << 8));
9716       return;
9717     }
9718   }
9719   Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm);
9720 }
9721 
smulwb(Condition cond,Register rd,Register rn,Register rm)9722 void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) {
9723   VIXL_ASSERT(AllowAssembler());
9724   CheckIT(cond);
9725   if (IsUsingT32()) {
9726     // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9727     EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9728                rm.GetCode());
9729     AdvanceIT();
9730     return;
9731   } else {
9732     // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9733     if (cond.IsNotNever()) {
9734       EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9735               rn.GetCode() | (rm.GetCode() << 8));
9736       return;
9737     }
9738   }
9739   Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm);
9740 }
9741 
smulwt(Condition cond,Register rd,Register rn,Register rm)9742 void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) {
9743   VIXL_ASSERT(AllowAssembler());
9744   CheckIT(cond);
9745   if (IsUsingT32()) {
9746     // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9747     EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9748                rm.GetCode());
9749     AdvanceIT();
9750     return;
9751   } else {
9752     // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9753     if (cond.IsNotNever()) {
9754       EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9755               rn.GetCode() | (rm.GetCode() << 8));
9756       return;
9757     }
9758   }
9759   Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm);
9760 }
9761 
smusd(Condition cond,Register rd,Register rn,Register rm)9762 void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) {
9763   VIXL_ASSERT(AllowAssembler());
9764   CheckIT(cond);
9765   if (IsUsingT32()) {
9766     // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9767     EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9768                rm.GetCode());
9769     AdvanceIT();
9770     return;
9771   } else {
9772     // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9773     if (cond.IsNotNever()) {
9774       EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9775               rn.GetCode() | (rm.GetCode() << 8));
9776       return;
9777     }
9778   }
9779   Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm);
9780 }
9781 
smusdx(Condition cond,Register rd,Register rn,Register rm)9782 void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) {
9783   VIXL_ASSERT(AllowAssembler());
9784   CheckIT(cond);
9785   if (IsUsingT32()) {
9786     // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9787     EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9788                rm.GetCode());
9789     AdvanceIT();
9790     return;
9791   } else {
9792     // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9793     if (cond.IsNotNever()) {
9794       EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9795               rn.GetCode() | (rm.GetCode() << 8));
9796       return;
9797     }
9798   }
9799   Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm);
9800 }
9801 
ssat(Condition cond,Register rd,uint32_t imm,const Operand & operand)9802 void Assembler::ssat(Condition cond,
9803                      Register rd,
9804                      uint32_t imm,
9805                      const Operand& operand) {
9806   VIXL_ASSERT(AllowAssembler());
9807   CheckIT(cond);
9808   if (operand.IsImmediateShiftedRegister()) {
9809     Register rn = operand.GetBaseRegister();
9810     Shift shift = operand.GetShift();
9811     uint32_t amount = operand.GetShiftAmount();
9812     if (IsUsingT32()) {
9813       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
9814       if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
9815           (amount <= 31)) {
9816         uint32_t imm_ = imm - 1;
9817         EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
9818                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
9819                    ((amount & 0x1c) << 10));
9820         AdvanceIT();
9821         return;
9822       }
9823       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
9824       if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31)) {
9825         uint32_t imm_ = imm - 1;
9826         EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ |
9827                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
9828                    ((amount & 0x1c) << 10));
9829         AdvanceIT();
9830         return;
9831       }
9832     } else {
9833       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
9834       if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
9835           (amount <= 32) && cond.IsNotNever()) {
9836         uint32_t imm_ = imm - 1;
9837         uint32_t amount_ = amount % 32;
9838         EmitA32(0x06a00050U | (cond.GetCondition() << 28) |
9839                 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
9840                 (amount_ << 7));
9841         return;
9842       }
9843       // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
9844       if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
9845           cond.IsNotNever()) {
9846         uint32_t imm_ = imm - 1;
9847         EmitA32(0x06a00010U | (cond.GetCondition() << 28) |
9848                 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
9849                 (amount << 7));
9850         return;
9851       }
9852     }
9853   }
9854   Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand);
9855 }
9856 
ssat16(Condition cond,Register rd,uint32_t imm,Register rn)9857 void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) {
9858   VIXL_ASSERT(AllowAssembler());
9859   CheckIT(cond);
9860   if (IsUsingT32()) {
9861     // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
9862     if ((imm >= 1) && (imm <= 16)) {
9863       uint32_t imm_ = imm - 1;
9864       EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
9865                  (rn.GetCode() << 16));
9866       AdvanceIT();
9867       return;
9868     }
9869   } else {
9870     // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
9871     if ((imm >= 1) && (imm <= 16) && cond.IsNotNever()) {
9872       uint32_t imm_ = imm - 1;
9873       EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9874               (imm_ << 16) | rn.GetCode());
9875       return;
9876     }
9877   }
9878   Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn);
9879 }
9880 
ssax(Condition cond,Register rd,Register rn,Register rm)9881 void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) {
9882   VIXL_ASSERT(AllowAssembler());
9883   CheckIT(cond);
9884   if (IsUsingT32()) {
9885     // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9886     EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9887                rm.GetCode());
9888     AdvanceIT();
9889     return;
9890   } else {
9891     // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9892     if (cond.IsNotNever()) {
9893       EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9894               (rn.GetCode() << 16) | rm.GetCode());
9895       return;
9896     }
9897   }
9898   Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm);
9899 }
9900 
ssub16(Condition cond,Register rd,Register rn,Register rm)9901 void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) {
9902   VIXL_ASSERT(AllowAssembler());
9903   CheckIT(cond);
9904   if (IsUsingT32()) {
9905     // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9906     EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9907                rm.GetCode());
9908     AdvanceIT();
9909     return;
9910   } else {
9911     // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9912     if (cond.IsNotNever()) {
9913       EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9914               (rn.GetCode() << 16) | rm.GetCode());
9915       return;
9916     }
9917   }
9918   Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm);
9919 }
9920 
ssub8(Condition cond,Register rd,Register rn,Register rm)9921 void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) {
9922   VIXL_ASSERT(AllowAssembler());
9923   CheckIT(cond);
9924   if (IsUsingT32()) {
9925     // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9926     EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9927                rm.GetCode());
9928     AdvanceIT();
9929     return;
9930   } else {
9931     // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9932     if (cond.IsNotNever()) {
9933       EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9934               (rn.GetCode() << 16) | rm.GetCode());
9935       return;
9936     }
9937   }
9938   Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm);
9939 }
9940 
stl(Condition cond,Register rt,const MemOperand & operand)9941 void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) {
9942   VIXL_ASSERT(AllowAssembler());
9943   CheckIT(cond);
9944   if (operand.IsImmediateZero()) {
9945     Register rn = operand.GetBaseRegister();
9946     if (IsUsingT32()) {
9947       // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1
9948       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
9949         EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
9950         AdvanceIT();
9951         return;
9952       }
9953     } else {
9954       // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1
9955       if (operand.IsOffset() && cond.IsNotNever() &&
9956           (!rn.IsPC() || AllowUnpredictable())) {
9957         EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
9958                 (rn.GetCode() << 16));
9959         return;
9960       }
9961     }
9962   }
9963   Delegate(kStl, &Assembler::stl, cond, rt, operand);
9964 }
9965 
stlb(Condition cond,Register rt,const MemOperand & operand)9966 void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) {
9967   VIXL_ASSERT(AllowAssembler());
9968   CheckIT(cond);
9969   if (operand.IsImmediateZero()) {
9970     Register rn = operand.GetBaseRegister();
9971     if (IsUsingT32()) {
9972       // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1
9973       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
9974         EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
9975         AdvanceIT();
9976         return;
9977       }
9978     } else {
9979       // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1
9980       if (operand.IsOffset() && cond.IsNotNever() &&
9981           (!rn.IsPC() || AllowUnpredictable())) {
9982         EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
9983                 (rn.GetCode() << 16));
9984         return;
9985       }
9986     }
9987   }
9988   Delegate(kStlb, &Assembler::stlb, cond, rt, operand);
9989 }
9990 
stlex(Condition cond,Register rd,Register rt,const MemOperand & operand)9991 void Assembler::stlex(Condition cond,
9992                       Register rd,
9993                       Register rt,
9994                       const MemOperand& operand) {
9995   VIXL_ASSERT(AllowAssembler());
9996   CheckIT(cond);
9997   if (operand.IsImmediateZero()) {
9998     Register rn = operand.GetBaseRegister();
9999     if (IsUsingT32()) {
10000       // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10001       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10002         EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) |
10003                    (rn.GetCode() << 16));
10004         AdvanceIT();
10005         return;
10006       }
10007     } else {
10008       // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10009       if (operand.IsOffset() && cond.IsNotNever() &&
10010           (!rn.IsPC() || AllowUnpredictable())) {
10011         EmitA32(0x01800e90U | (cond.GetCondition() << 28) |
10012                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10013         return;
10014       }
10015     }
10016   }
10017   Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand);
10018 }
10019 
stlexb(Condition cond,Register rd,Register rt,const MemOperand & operand)10020 void Assembler::stlexb(Condition cond,
10021                        Register rd,
10022                        Register rt,
10023                        const MemOperand& operand) {
10024   VIXL_ASSERT(AllowAssembler());
10025   CheckIT(cond);
10026   if (operand.IsImmediateZero()) {
10027     Register rn = operand.GetBaseRegister();
10028     if (IsUsingT32()) {
10029       // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10030       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10031         EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) |
10032                    (rn.GetCode() << 16));
10033         AdvanceIT();
10034         return;
10035       }
10036     } else {
10037       // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10038       if (operand.IsOffset() && cond.IsNotNever() &&
10039           (!rn.IsPC() || AllowUnpredictable())) {
10040         EmitA32(0x01c00e90U | (cond.GetCondition() << 28) |
10041                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10042         return;
10043       }
10044     }
10045   }
10046   Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand);
10047 }
10048 
stlexd(Condition cond,Register rd,Register rt,Register rt2,const MemOperand & operand)10049 void Assembler::stlexd(Condition cond,
10050                        Register rd,
10051                        Register rt,
10052                        Register rt2,
10053                        const MemOperand& operand) {
10054   VIXL_ASSERT(AllowAssembler());
10055   CheckIT(cond);
10056   if (operand.IsImmediateZero()) {
10057     Register rn = operand.GetBaseRegister();
10058     if (IsUsingT32()) {
10059       // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
10060       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10061         EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) |
10062                    (rt2.GetCode() << 8) | (rn.GetCode() << 16));
10063         AdvanceIT();
10064         return;
10065       }
10066     } else {
10067       // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
10068       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10069           operand.IsOffset() && cond.IsNotNever() &&
10070           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
10071            AllowUnpredictable())) {
10072         EmitA32(0x01a00e90U | (cond.GetCondition() << 28) |
10073                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10074         return;
10075       }
10076     }
10077   }
10078   Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand);
10079 }
10080 
stlexh(Condition cond,Register rd,Register rt,const MemOperand & operand)10081 void Assembler::stlexh(Condition cond,
10082                        Register rd,
10083                        Register rt,
10084                        const MemOperand& operand) {
10085   VIXL_ASSERT(AllowAssembler());
10086   CheckIT(cond);
10087   if (operand.IsImmediateZero()) {
10088     Register rn = operand.GetBaseRegister();
10089     if (IsUsingT32()) {
10090       // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10091       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10092         EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) |
10093                    (rn.GetCode() << 16));
10094         AdvanceIT();
10095         return;
10096       }
10097     } else {
10098       // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10099       if (operand.IsOffset() && cond.IsNotNever() &&
10100           (!rn.IsPC() || AllowUnpredictable())) {
10101         EmitA32(0x01e00e90U | (cond.GetCondition() << 28) |
10102                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10103         return;
10104       }
10105     }
10106   }
10107   Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand);
10108 }
10109 
stlh(Condition cond,Register rt,const MemOperand & operand)10110 void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) {
10111   VIXL_ASSERT(AllowAssembler());
10112   CheckIT(cond);
10113   if (operand.IsImmediateZero()) {
10114     Register rn = operand.GetBaseRegister();
10115     if (IsUsingT32()) {
10116       // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1
10117       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10118         EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
10119         AdvanceIT();
10120         return;
10121       }
10122     } else {
10123       // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1
10124       if (operand.IsOffset() && cond.IsNotNever() &&
10125           (!rn.IsPC() || AllowUnpredictable())) {
10126         EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
10127                 (rn.GetCode() << 16));
10128         return;
10129       }
10130     }
10131   }
10132   Delegate(kStlh, &Assembler::stlh, cond, rt, operand);
10133 }
10134 
stm(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)10135 void Assembler::stm(Condition cond,
10136                     EncodingSize size,
10137                     Register rn,
10138                     WriteBack write_back,
10139                     RegisterList registers) {
10140   VIXL_ASSERT(AllowAssembler());
10141   CheckIT(cond);
10142   if (IsUsingT32()) {
10143     // STM{<c>}{<q>} <Rn>!, <registers> ; T1
10144     if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
10145         ((registers.GetList() & ~0xff) == 0)) {
10146       EmitT32_16(0xc000 | (rn.GetCode() << 8) |
10147                  GetRegisterListEncoding(registers, 0, 8));
10148       AdvanceIT();
10149       return;
10150     }
10151     // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2
10152     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10153       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
10154                  (write_back.GetWriteBackUint32() << 21) |
10155                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
10156                  GetRegisterListEncoding(registers, 0, 13));
10157       AdvanceIT();
10158       return;
10159     }
10160   } else {
10161     // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1
10162     if (cond.IsNotNever()) {
10163       EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10164               (write_back.GetWriteBackUint32() << 21) |
10165               GetRegisterListEncoding(registers, 0, 16));
10166       return;
10167     }
10168   }
10169   Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers);
10170 }
10171 
stmda(Condition cond,Register rn,WriteBack write_back,RegisterList registers)10172 void Assembler::stmda(Condition cond,
10173                       Register rn,
10174                       WriteBack write_back,
10175                       RegisterList registers) {
10176   VIXL_ASSERT(AllowAssembler());
10177   CheckIT(cond);
10178   if (IsUsingA32()) {
10179     // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
10180     if (cond.IsNotNever()) {
10181       EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10182               (write_back.GetWriteBackUint32() << 21) |
10183               GetRegisterListEncoding(registers, 0, 16));
10184       return;
10185     }
10186   }
10187   Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers);
10188 }
10189 
stmdb(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)10190 void Assembler::stmdb(Condition cond,
10191                       EncodingSize size,
10192                       Register rn,
10193                       WriteBack write_back,
10194                       RegisterList registers) {
10195   VIXL_ASSERT(AllowAssembler());
10196   CheckIT(cond);
10197   if (IsUsingT32()) {
10198     // STMDB{<c>}{<q>} SP!, <registers> ; T1
10199     if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
10200         ((registers.GetList() & ~0x40ff) == 0)) {
10201       EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
10202                  GetRegisterListEncoding(registers, 0, 8));
10203       AdvanceIT();
10204       return;
10205     }
10206     // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
10207     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10208       EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
10209                  (write_back.GetWriteBackUint32() << 21) |
10210                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
10211                  GetRegisterListEncoding(registers, 0, 13));
10212       AdvanceIT();
10213       return;
10214     }
10215   } else {
10216     // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
10217     if (cond.IsNotNever()) {
10218       EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10219               (write_back.GetWriteBackUint32() << 21) |
10220               GetRegisterListEncoding(registers, 0, 16));
10221       return;
10222     }
10223   }
10224   Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers);
10225 }
10226 
stmea(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)10227 void Assembler::stmea(Condition cond,
10228                       EncodingSize size,
10229                       Register rn,
10230                       WriteBack write_back,
10231                       RegisterList registers) {
10232   VIXL_ASSERT(AllowAssembler());
10233   CheckIT(cond);
10234   if (IsUsingT32()) {
10235     // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1
10236     if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
10237         ((registers.GetList() & ~0xff) == 0)) {
10238       EmitT32_16(0xc000 | (rn.GetCode() << 8) |
10239                  GetRegisterListEncoding(registers, 0, 8));
10240       AdvanceIT();
10241       return;
10242     }
10243     // STMEA{<c>}.W <Rn>{!}, <registers> ; T2
10244     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10245       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
10246                  (write_back.GetWriteBackUint32() << 21) |
10247                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
10248                  GetRegisterListEncoding(registers, 0, 13));
10249       AdvanceIT();
10250       return;
10251     }
10252     // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2
10253     if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0)) {
10254       EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
10255                  (write_back.GetWriteBackUint32() << 21) |
10256                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
10257                  GetRegisterListEncoding(registers, 0, 13));
10258       AdvanceIT();
10259       return;
10260     }
10261   } else {
10262     // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
10263     if (cond.IsNotNever()) {
10264       EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10265               (write_back.GetWriteBackUint32() << 21) |
10266               GetRegisterListEncoding(registers, 0, 16));
10267       return;
10268     }
10269   }
10270   Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers);
10271 }
10272 
stmed(Condition cond,Register rn,WriteBack write_back,RegisterList registers)10273 void Assembler::stmed(Condition cond,
10274                       Register rn,
10275                       WriteBack write_back,
10276                       RegisterList registers) {
10277   VIXL_ASSERT(AllowAssembler());
10278   CheckIT(cond);
10279   if (IsUsingA32()) {
10280     // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
10281     if (cond.IsNotNever()) {
10282       EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10283               (write_back.GetWriteBackUint32() << 21) |
10284               GetRegisterListEncoding(registers, 0, 16));
10285       return;
10286     }
10287   }
10288   Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers);
10289 }
10290 
stmfa(Condition cond,Register rn,WriteBack write_back,RegisterList registers)10291 void Assembler::stmfa(Condition cond,
10292                       Register rn,
10293                       WriteBack write_back,
10294                       RegisterList registers) {
10295   VIXL_ASSERT(AllowAssembler());
10296   CheckIT(cond);
10297   if (IsUsingA32()) {
10298     // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
10299     if (cond.IsNotNever()) {
10300       EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10301               (write_back.GetWriteBackUint32() << 21) |
10302               GetRegisterListEncoding(registers, 0, 16));
10303       return;
10304     }
10305   }
10306   Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers);
10307 }
10308 
stmfd(Condition cond,Register rn,WriteBack write_back,RegisterList registers)10309 void Assembler::stmfd(Condition cond,
10310                       Register rn,
10311                       WriteBack write_back,
10312                       RegisterList registers) {
10313   VIXL_ASSERT(AllowAssembler());
10314   CheckIT(cond);
10315   if (IsUsingT32()) {
10316     // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
10317     if (((registers.GetList() & ~0x5fff) == 0)) {
10318       EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
10319                  (write_back.GetWriteBackUint32() << 21) |
10320                  (GetRegisterListEncoding(registers, 14, 1) << 14) |
10321                  GetRegisterListEncoding(registers, 0, 13));
10322       AdvanceIT();
10323       return;
10324     }
10325   } else {
10326     // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
10327     if (cond.IsNotNever()) {
10328       EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10329               (write_back.GetWriteBackUint32() << 21) |
10330               GetRegisterListEncoding(registers, 0, 16));
10331       return;
10332     }
10333   }
10334   Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers);
10335 }
10336 
stmib(Condition cond,Register rn,WriteBack write_back,RegisterList registers)10337 void Assembler::stmib(Condition cond,
10338                       Register rn,
10339                       WriteBack write_back,
10340                       RegisterList registers) {
10341   VIXL_ASSERT(AllowAssembler());
10342   CheckIT(cond);
10343   if (IsUsingA32()) {
10344     // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
10345     if (cond.IsNotNever()) {
10346       EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
10347               (write_back.GetWriteBackUint32() << 21) |
10348               GetRegisterListEncoding(registers, 0, 16));
10349       return;
10350     }
10351   }
10352   Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers);
10353 }
10354 
str(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)10355 void Assembler::str(Condition cond,
10356                     EncodingSize size,
10357                     Register rt,
10358                     const MemOperand& operand) {
10359   VIXL_ASSERT(AllowAssembler());
10360   CheckIT(cond);
10361   if (operand.IsImmediate()) {
10362     Register rn = operand.GetBaseRegister();
10363     int32_t offset = operand.GetOffsetImmediate();
10364     if (IsUsingT32()) {
10365       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10366       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10367           (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
10368         int32_t offset_ = offset >> 2;
10369         EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) |
10370                    ((offset_ & 0x1f) << 6));
10371         AdvanceIT();
10372         return;
10373       }
10374       // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
10375       if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
10376           ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
10377         int32_t offset_ = offset >> 2;
10378         EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff));
10379         AdvanceIT();
10380         return;
10381       }
10382       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
10383       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10384           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10385         EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10386                    (offset & 0xfff));
10387         AdvanceIT();
10388         return;
10389       }
10390       // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
10391       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10392           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10393         EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10394                    (-offset & 0xff));
10395         AdvanceIT();
10396         return;
10397       }
10398       // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
10399       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10400           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10401         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10402         uint32_t offset_ = abs(offset);
10403         EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10404                    offset_ | (sign << 9));
10405         AdvanceIT();
10406         return;
10407       }
10408       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
10409       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10410           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10411         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10412         uint32_t offset_ = abs(offset);
10413         EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10414                    offset_ | (sign << 9));
10415         AdvanceIT();
10416         return;
10417       }
10418     } else {
10419       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10420       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
10421           cond.IsNotNever()) {
10422         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10423         uint32_t offset_ = abs(offset);
10424         EmitA32(0x05000000U | (cond.GetCondition() << 28) |
10425                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10426                 (sign << 23));
10427         return;
10428       }
10429       // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10430       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
10431           cond.IsNotNever()) {
10432         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10433         uint32_t offset_ = abs(offset);
10434         EmitA32(0x04000000U | (cond.GetCondition() << 28) |
10435                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10436                 (sign << 23));
10437         return;
10438       }
10439       // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10440       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
10441           cond.IsNotNever()) {
10442         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10443         uint32_t offset_ = abs(offset);
10444         EmitA32(0x05200000U | (cond.GetCondition() << 28) |
10445                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10446                 (sign << 23));
10447         return;
10448       }
10449     }
10450   }
10451   if (operand.IsPlainRegister()) {
10452     Register rn = operand.GetBaseRegister();
10453     Sign sign = operand.GetSign();
10454     Register rm = operand.GetOffsetRegister();
10455     if (IsUsingT32()) {
10456       // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
10457       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
10458           sign.IsPlus() && operand.IsOffset()) {
10459         EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) |
10460                    (rm.GetCode() << 6));
10461         AdvanceIT();
10462         return;
10463       }
10464     }
10465   }
10466   if (operand.IsShiftedRegister()) {
10467     Register rn = operand.GetBaseRegister();
10468     Sign sign = operand.GetSign();
10469     Register rm = operand.GetOffsetRegister();
10470     Shift shift = operand.GetShift();
10471     uint32_t amount = operand.GetShiftAmount();
10472     if (IsUsingT32()) {
10473       // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
10474       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
10475           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10476         EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10477                    rm.GetCode() | (amount << 4));
10478         AdvanceIT();
10479         return;
10480       }
10481     } else {
10482       // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
10483       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
10484         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10485         uint32_t shift_ = TypeEncodingValue(shift);
10486         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10487         EmitA32(0x07000000U | (cond.GetCondition() << 28) |
10488                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10489                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10490         return;
10491       }
10492       // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
10493       if (operand.IsShiftValid() && operand.IsPostIndex() &&
10494           cond.IsNotNever()) {
10495         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10496         uint32_t shift_ = TypeEncodingValue(shift);
10497         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10498         EmitA32(0x06000000U | (cond.GetCondition() << 28) |
10499                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10500                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10501         return;
10502       }
10503       // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
10504       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
10505         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10506         uint32_t shift_ = TypeEncodingValue(shift);
10507         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10508         EmitA32(0x07200000U | (cond.GetCondition() << 28) |
10509                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10510                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10511         return;
10512       }
10513     }
10514   }
10515   Delegate(kStr, &Assembler::str, cond, size, rt, operand);
10516 }
10517 
strb(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)10518 void Assembler::strb(Condition cond,
10519                      EncodingSize size,
10520                      Register rt,
10521                      const MemOperand& operand) {
10522   VIXL_ASSERT(AllowAssembler());
10523   CheckIT(cond);
10524   if (operand.IsImmediate()) {
10525     Register rn = operand.GetBaseRegister();
10526     int32_t offset = operand.GetOffsetImmediate();
10527     if (IsUsingT32()) {
10528       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10529       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10530           (offset <= 31) && operand.IsOffset()) {
10531         EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) |
10532                    ((offset & 0x1f) << 6));
10533         AdvanceIT();
10534         return;
10535       }
10536       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
10537       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10538           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10539         EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10540                    (offset & 0xfff));
10541         AdvanceIT();
10542         return;
10543       }
10544       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
10545       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10546           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10547         EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10548                    (-offset & 0xff));
10549         AdvanceIT();
10550         return;
10551       }
10552       // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
10553       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10554           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10555         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10556         uint32_t offset_ = abs(offset);
10557         EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10558                    offset_ | (sign << 9));
10559         AdvanceIT();
10560         return;
10561       }
10562       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
10563       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10564           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10565         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10566         uint32_t offset_ = abs(offset);
10567         EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10568                    offset_ | (sign << 9));
10569         AdvanceIT();
10570         return;
10571       }
10572     } else {
10573       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10574       if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
10575           cond.IsNotNever()) {
10576         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10577         uint32_t offset_ = abs(offset);
10578         EmitA32(0x05400000U | (cond.GetCondition() << 28) |
10579                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10580                 (sign << 23));
10581         return;
10582       }
10583       // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10584       if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
10585           cond.IsNotNever()) {
10586         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10587         uint32_t offset_ = abs(offset);
10588         EmitA32(0x04400000U | (cond.GetCondition() << 28) |
10589                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10590                 (sign << 23));
10591         return;
10592       }
10593       // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10594       if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
10595           cond.IsNotNever()) {
10596         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10597         uint32_t offset_ = abs(offset);
10598         EmitA32(0x05600000U | (cond.GetCondition() << 28) |
10599                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
10600                 (sign << 23));
10601         return;
10602       }
10603     }
10604   }
10605   if (operand.IsPlainRegister()) {
10606     Register rn = operand.GetBaseRegister();
10607     Sign sign = operand.GetSign();
10608     Register rm = operand.GetOffsetRegister();
10609     if (IsUsingT32()) {
10610       // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
10611       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
10612           sign.IsPlus() && operand.IsOffset()) {
10613         EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) |
10614                    (rm.GetCode() << 6));
10615         AdvanceIT();
10616         return;
10617       }
10618     }
10619   }
10620   if (operand.IsShiftedRegister()) {
10621     Register rn = operand.GetBaseRegister();
10622     Sign sign = operand.GetSign();
10623     Register rm = operand.GetOffsetRegister();
10624     Shift shift = operand.GetShift();
10625     uint32_t amount = operand.GetShiftAmount();
10626     if (IsUsingT32()) {
10627       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
10628       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
10629           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10630         EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10631                    rm.GetCode() | (amount << 4));
10632         AdvanceIT();
10633         return;
10634       }
10635     } else {
10636       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
10637       if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever()) {
10638         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10639         uint32_t shift_ = TypeEncodingValue(shift);
10640         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10641         EmitA32(0x07400000U | (cond.GetCondition() << 28) |
10642                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10643                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10644         return;
10645       }
10646       // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
10647       if (operand.IsShiftValid() && operand.IsPostIndex() &&
10648           cond.IsNotNever()) {
10649         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10650         uint32_t shift_ = TypeEncodingValue(shift);
10651         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10652         EmitA32(0x06400000U | (cond.GetCondition() << 28) |
10653                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10654                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10655         return;
10656       }
10657       // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
10658       if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever()) {
10659         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10660         uint32_t shift_ = TypeEncodingValue(shift);
10661         uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
10662         EmitA32(0x07600000U | (cond.GetCondition() << 28) |
10663                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10664                 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
10665         return;
10666       }
10667     }
10668   }
10669   Delegate(kStrb, &Assembler::strb, cond, size, rt, operand);
10670 }
10671 
strd(Condition cond,Register rt,Register rt2,const MemOperand & operand)10672 void Assembler::strd(Condition cond,
10673                      Register rt,
10674                      Register rt2,
10675                      const MemOperand& operand) {
10676   VIXL_ASSERT(AllowAssembler());
10677   CheckIT(cond);
10678   if (operand.IsImmediate()) {
10679     Register rn = operand.GetBaseRegister();
10680     int32_t offset = operand.GetOffsetImmediate();
10681     if (IsUsingT32()) {
10682       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
10683       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10684           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10685         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10686         uint32_t offset_ = abs(offset) >> 2;
10687         EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10688                    (rn.GetCode() << 16) | offset_ | (sign << 23));
10689         AdvanceIT();
10690         return;
10691       }
10692       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
10693       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10694           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10695         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10696         uint32_t offset_ = abs(offset) >> 2;
10697         EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10698                    (rn.GetCode() << 16) | offset_ | (sign << 23));
10699         AdvanceIT();
10700         return;
10701       }
10702       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
10703       if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
10704           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10705         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10706         uint32_t offset_ = abs(offset) >> 2;
10707         EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
10708                    (rn.GetCode() << 16) | offset_ | (sign << 23));
10709         AdvanceIT();
10710         return;
10711       }
10712     } else {
10713       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
10714       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10715           (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
10716           cond.IsNotNever() &&
10717           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10718         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10719         uint32_t offset_ = abs(offset);
10720         EmitA32(0x014000f0U | (cond.GetCondition() << 28) |
10721                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10722                 ((offset_ & 0xf0) << 4) | (sign << 23));
10723         return;
10724       }
10725       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
10726       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10727           (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
10728           cond.IsNotNever() &&
10729           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10730         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10731         uint32_t offset_ = abs(offset);
10732         EmitA32(0x004000f0U | (cond.GetCondition() << 28) |
10733                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10734                 ((offset_ & 0xf0) << 4) | (sign << 23));
10735         return;
10736       }
10737       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
10738       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10739           (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
10740           cond.IsNotNever() &&
10741           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10742         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10743         uint32_t offset_ = abs(offset);
10744         EmitA32(0x016000f0U | (cond.GetCondition() << 28) |
10745                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10746                 ((offset_ & 0xf0) << 4) | (sign << 23));
10747         return;
10748       }
10749     }
10750   }
10751   if (operand.IsPlainRegister()) {
10752     Register rn = operand.GetBaseRegister();
10753     Sign sign = operand.GetSign();
10754     Register rm = operand.GetOffsetRegister();
10755     if (IsUsingA32()) {
10756       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
10757       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10758           operand.IsOffset() && cond.IsNotNever() &&
10759           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10760         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10761         EmitA32(0x010000f0U | (cond.GetCondition() << 28) |
10762                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10763                 (sign_ << 23));
10764         return;
10765       }
10766       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
10767       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10768           operand.IsPostIndex() && cond.IsNotNever() &&
10769           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10770         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10771         EmitA32(0x000000f0U | (cond.GetCondition() << 28) |
10772                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10773                 (sign_ << 23));
10774         return;
10775       }
10776       // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
10777       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10778           operand.IsPreIndex() && cond.IsNotNever() &&
10779           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0)) || AllowUnpredictable())) {
10780         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
10781         EmitA32(0x012000f0U | (cond.GetCondition() << 28) |
10782                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
10783                 (sign_ << 23));
10784         return;
10785       }
10786     }
10787   }
10788   Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand);
10789 }
10790 
strex(Condition cond,Register rd,Register rt,const MemOperand & operand)10791 void Assembler::strex(Condition cond,
10792                       Register rd,
10793                       Register rt,
10794                       const MemOperand& operand) {
10795   VIXL_ASSERT(AllowAssembler());
10796   CheckIT(cond);
10797   if (operand.IsImmediate()) {
10798     Register rn = operand.GetBaseRegister();
10799     int32_t offset = operand.GetOffsetImmediate();
10800     if (IsUsingT32()) {
10801       // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1
10802       if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
10803           operand.IsOffset()) {
10804         int32_t offset_ = offset >> 2;
10805         EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) |
10806                    (rn.GetCode() << 16) | (offset_ & 0xff));
10807         AdvanceIT();
10808         return;
10809       }
10810     } else {
10811       // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1
10812       if ((offset == 0) && operand.IsOffset() && cond.IsNotNever()) {
10813         EmitA32(0x01800f90U | (cond.GetCondition() << 28) |
10814                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10815         return;
10816       }
10817     }
10818   }
10819   Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand);
10820 }
10821 
strexb(Condition cond,Register rd,Register rt,const MemOperand & operand)10822 void Assembler::strexb(Condition cond,
10823                        Register rd,
10824                        Register rt,
10825                        const MemOperand& operand) {
10826   VIXL_ASSERT(AllowAssembler());
10827   CheckIT(cond);
10828   if (operand.IsImmediateZero()) {
10829     Register rn = operand.GetBaseRegister();
10830     if (IsUsingT32()) {
10831       // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10832       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10833         EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) |
10834                    (rn.GetCode() << 16));
10835         AdvanceIT();
10836         return;
10837       }
10838     } else {
10839       // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10840       if (operand.IsOffset() && cond.IsNotNever() &&
10841           (!rn.IsPC() || AllowUnpredictable())) {
10842         EmitA32(0x01c00f90U | (cond.GetCondition() << 28) |
10843                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10844         return;
10845       }
10846     }
10847   }
10848   Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand);
10849 }
10850 
strexd(Condition cond,Register rd,Register rt,Register rt2,const MemOperand & operand)10851 void Assembler::strexd(Condition cond,
10852                        Register rd,
10853                        Register rt,
10854                        Register rt2,
10855                        const MemOperand& operand) {
10856   VIXL_ASSERT(AllowAssembler());
10857   CheckIT(cond);
10858   if (operand.IsImmediateZero()) {
10859     Register rn = operand.GetBaseRegister();
10860     if (IsUsingT32()) {
10861       // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
10862       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10863         EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) |
10864                    (rt2.GetCode() << 8) | (rn.GetCode() << 16));
10865         AdvanceIT();
10866         return;
10867       }
10868     } else {
10869       // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
10870       if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
10871           operand.IsOffset() && cond.IsNotNever() &&
10872           ((!rt.IsLR() && ((rt.GetCode() & 1) == 0) && !rn.IsPC()) ||
10873            AllowUnpredictable())) {
10874         EmitA32(0x01a00f90U | (cond.GetCondition() << 28) |
10875                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10876         return;
10877       }
10878     }
10879   }
10880   Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand);
10881 }
10882 
strexh(Condition cond,Register rd,Register rt,const MemOperand & operand)10883 void Assembler::strexh(Condition cond,
10884                        Register rd,
10885                        Register rt,
10886                        const MemOperand& operand) {
10887   VIXL_ASSERT(AllowAssembler());
10888   CheckIT(cond);
10889   if (operand.IsImmediateZero()) {
10890     Register rn = operand.GetBaseRegister();
10891     if (IsUsingT32()) {
10892       // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
10893       if (operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
10894         EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) |
10895                    (rn.GetCode() << 16));
10896         AdvanceIT();
10897         return;
10898       }
10899     } else {
10900       // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
10901       if (operand.IsOffset() && cond.IsNotNever() &&
10902           (!rn.IsPC() || AllowUnpredictable())) {
10903         EmitA32(0x01e00f90U | (cond.GetCondition() << 28) |
10904                 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
10905         return;
10906       }
10907     }
10908   }
10909   Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand);
10910 }
10911 
strh(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)10912 void Assembler::strh(Condition cond,
10913                      EncodingSize size,
10914                      Register rt,
10915                      const MemOperand& operand) {
10916   VIXL_ASSERT(AllowAssembler());
10917   CheckIT(cond);
10918   if (operand.IsImmediate()) {
10919     Register rn = operand.GetBaseRegister();
10920     int32_t offset = operand.GetOffsetImmediate();
10921     if (IsUsingT32()) {
10922       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
10923       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
10924           (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
10925         int32_t offset_ = offset >> 1;
10926         EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) |
10927                    ((offset_ & 0x1f) << 6));
10928         AdvanceIT();
10929         return;
10930       }
10931       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
10932       if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
10933           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10934         EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10935                    (offset & 0xfff));
10936         AdvanceIT();
10937         return;
10938       }
10939       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
10940       if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
10941           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
10942         EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10943                    (-offset & 0xff));
10944         AdvanceIT();
10945         return;
10946       }
10947       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
10948       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10949           operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10950         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10951         uint32_t offset_ = abs(offset);
10952         EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10953                    offset_ | (sign << 9));
10954         AdvanceIT();
10955         return;
10956       }
10957       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
10958       if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
10959           operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
10960         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10961         uint32_t offset_ = abs(offset);
10962         EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
10963                    offset_ | (sign << 9));
10964         AdvanceIT();
10965         return;
10966       }
10967     } else {
10968       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
10969       if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
10970           cond.IsNotNever()) {
10971         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10972         uint32_t offset_ = abs(offset);
10973         EmitA32(0x014000b0U | (cond.GetCondition() << 28) |
10974                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10975                 ((offset_ & 0xf0) << 4) | (sign << 23));
10976         return;
10977       }
10978       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
10979       if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
10980           cond.IsNotNever()) {
10981         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10982         uint32_t offset_ = abs(offset);
10983         EmitA32(0x004000b0U | (cond.GetCondition() << 28) |
10984                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10985                 ((offset_ & 0xf0) << 4) | (sign << 23));
10986         return;
10987       }
10988       // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
10989       if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
10990           cond.IsNotNever()) {
10991         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
10992         uint32_t offset_ = abs(offset);
10993         EmitA32(0x016000b0U | (cond.GetCondition() << 28) |
10994                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
10995                 ((offset_ & 0xf0) << 4) | (sign << 23));
10996         return;
10997       }
10998     }
10999   }
11000   if (operand.IsPlainRegister()) {
11001     Register rn = operand.GetBaseRegister();
11002     Sign sign = operand.GetSign();
11003     Register rm = operand.GetOffsetRegister();
11004     if (IsUsingT32()) {
11005       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
11006       if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
11007           sign.IsPlus() && operand.IsOffset()) {
11008         EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) |
11009                    (rm.GetCode() << 6));
11010         AdvanceIT();
11011         return;
11012       }
11013     } else {
11014       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
11015       if (operand.IsOffset() && cond.IsNotNever()) {
11016         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11017         EmitA32(0x010000b0U | (cond.GetCondition() << 28) |
11018                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11019                 (sign_ << 23));
11020         return;
11021       }
11022       // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
11023       if (operand.IsPostIndex() && cond.IsNotNever()) {
11024         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11025         EmitA32(0x000000b0U | (cond.GetCondition() << 28) |
11026                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11027                 (sign_ << 23));
11028         return;
11029       }
11030       // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
11031       if (operand.IsPreIndex() && cond.IsNotNever()) {
11032         uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11033         EmitA32(0x012000b0U | (cond.GetCondition() << 28) |
11034                 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11035                 (sign_ << 23));
11036         return;
11037       }
11038     }
11039   }
11040   if (operand.IsShiftedRegister()) {
11041     Register rn = operand.GetBaseRegister();
11042     Sign sign = operand.GetSign();
11043     Register rm = operand.GetOffsetRegister();
11044     Shift shift = operand.GetShift();
11045     uint32_t amount = operand.GetShiftAmount();
11046     if (IsUsingT32()) {
11047       // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
11048       if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
11049           operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf)) {
11050         EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11051                    rm.GetCode() | (amount << 4));
11052         AdvanceIT();
11053         return;
11054       }
11055     }
11056   }
11057   Delegate(kStrh, &Assembler::strh, cond, size, rt, operand);
11058 }
11059 
sub(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)11060 void Assembler::sub(Condition cond,
11061                     EncodingSize size,
11062                     Register rd,
11063                     Register rn,
11064                     const Operand& operand) {
11065   VIXL_ASSERT(AllowAssembler());
11066   CheckIT(cond);
11067   if (operand.IsImmediate()) {
11068     uint32_t imm = operand.GetImmediate();
11069     if (IsUsingT32()) {
11070       ImmediateT32 immediate_t32(imm);
11071       // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
11072       if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11073           (imm <= 7)) {
11074         EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
11075         AdvanceIT();
11076         return;
11077       }
11078       // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
11079       if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
11080           (imm <= 255)) {
11081         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11082         AdvanceIT();
11083         return;
11084       }
11085       // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1
11086       if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
11087           ((imm % 4) == 0)) {
11088         uint32_t imm_ = imm >> 2;
11089         EmitT32_16(0xb080 | imm_);
11090         AdvanceIT();
11091         return;
11092       }
11093       // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2
11094       if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095)) {
11095         EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) |
11096                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11097         AdvanceIT();
11098         return;
11099       }
11100       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
11101       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp)) {
11102         EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11103                    (immediate_t32.GetEncodingValue() & 0xff) |
11104                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11105                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11106         AdvanceIT();
11107         return;
11108       }
11109       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
11110       if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
11111         EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11112                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11113         AdvanceIT();
11114         return;
11115       }
11116       // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
11117       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid()) {
11118         EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) |
11119                    (immediate_t32.GetEncodingValue() & 0xff) |
11120                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11121                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11122         AdvanceIT();
11123         return;
11124       }
11125       // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
11126       if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095)) {
11127         EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
11128                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11129         AdvanceIT();
11130         return;
11131       }
11132     } else {
11133       ImmediateA32 immediate_a32(imm);
11134       // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2
11135       if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
11136         EmitA32(0x024f0000U | (cond.GetCondition() << 28) |
11137                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
11138         return;
11139       }
11140       // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
11141       if (immediate_a32.IsValid() && cond.IsNotNever() &&
11142           ((rn.GetCode() & 0xd) != 0xd)) {
11143         EmitA32(0x02400000U | (cond.GetCondition() << 28) |
11144                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
11145                 immediate_a32.GetEncodingValue());
11146         return;
11147       }
11148       // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
11149       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
11150         EmitA32(0x024d0000U | (cond.GetCondition() << 28) |
11151                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
11152         return;
11153       }
11154     }
11155   }
11156   if (operand.IsImmediateShiftedRegister()) {
11157     Register rm = operand.GetBaseRegister();
11158     if (operand.IsPlainRegister()) {
11159       if (IsUsingT32()) {
11160         // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
11161         if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11162             rm.IsLow()) {
11163           EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
11164                      (rm.GetCode() << 6));
11165           AdvanceIT();
11166           return;
11167         }
11168         // SUB{<c>} {<Rd>}, SP, <Rm> ; T1
11169         if (rn.Is(sp)) {
11170           EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode());
11171           AdvanceIT();
11172           return;
11173         }
11174       }
11175     }
11176     Shift shift = operand.GetShift();
11177     uint32_t amount = operand.GetShiftAmount();
11178     if (IsUsingT32()) {
11179       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
11180       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp)) {
11181         uint32_t amount_ = amount % 32;
11182         EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11183                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
11184                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11185         AdvanceIT();
11186         return;
11187       }
11188       // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
11189       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount)) {
11190         uint32_t amount_ = amount % 32;
11191         EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() |
11192                    (operand.GetTypeEncodingValue() << 4) |
11193                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11194         AdvanceIT();
11195         return;
11196       }
11197     } else {
11198       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
11199       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
11200         uint32_t amount_ = amount % 32;
11201         EmitA32(0x00400000U | (cond.GetCondition() << 28) |
11202                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11203                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11204         return;
11205       }
11206       // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
11207       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
11208         uint32_t amount_ = amount % 32;
11209         EmitA32(0x004d0000U | (cond.GetCondition() << 28) |
11210                 (rd.GetCode() << 12) | rm.GetCode() |
11211                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11212         return;
11213       }
11214     }
11215   }
11216   if (operand.IsRegisterShiftedRegister()) {
11217     Register rm = operand.GetBaseRegister();
11218     Shift shift = operand.GetShift();
11219     if (IsUsingA32()) {
11220       // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
11221       if (cond.IsNotNever()) {
11222         EmitA32(0x00400010U | (cond.GetCondition() << 28) |
11223                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11224                 (shift.GetType() << 5) |
11225                 (operand.GetShiftRegister().GetCode() << 8));
11226         return;
11227       }
11228     }
11229   }
11230   Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand);
11231 }
11232 
sub(Condition cond,Register rd,const Operand & operand)11233 void Assembler::sub(Condition cond, Register rd, const Operand& operand) {
11234   VIXL_ASSERT(AllowAssembler());
11235   CheckIT(cond);
11236   if (operand.IsImmediate()) {
11237     uint32_t imm = operand.GetImmediate();
11238     if (IsUsingT32()) {
11239       // SUB<c>{<q>} <Rdn>, #<imm8> ; T2
11240       if (InITBlock() && rd.IsLow() && (imm <= 255)) {
11241         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11242         AdvanceIT();
11243         return;
11244       }
11245     }
11246   }
11247   Delegate(kSub, &Assembler::sub, cond, rd, operand);
11248 }
11249 
subs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)11250 void Assembler::subs(Condition cond,
11251                      EncodingSize size,
11252                      Register rd,
11253                      Register rn,
11254                      const Operand& operand) {
11255   VIXL_ASSERT(AllowAssembler());
11256   CheckIT(cond);
11257   if (operand.IsImmediate()) {
11258     uint32_t imm = operand.GetImmediate();
11259     if (IsUsingT32()) {
11260       ImmediateT32 immediate_t32(imm);
11261       // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1
11262       if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11263           (imm <= 7)) {
11264         EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
11265         AdvanceIT();
11266         return;
11267       }
11268       // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
11269       if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
11270           (imm <= 255)) {
11271         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11272         AdvanceIT();
11273         return;
11274       }
11275       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
11276       if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
11277           !rd.Is(pc)) {
11278         EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11279                    (immediate_t32.GetEncodingValue() & 0xff) |
11280                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11281                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11282         AdvanceIT();
11283         return;
11284       }
11285       // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5
11286       if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255)) {
11287         EmitT32_32(0xf3de8f00U | imm);
11288         AdvanceIT();
11289         return;
11290       }
11291       // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
11292       if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
11293           !rd.Is(pc)) {
11294         EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) |
11295                    (immediate_t32.GetEncodingValue() & 0xff) |
11296                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11297                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11298         AdvanceIT();
11299         return;
11300       }
11301     } else {
11302       ImmediateA32 immediate_a32(imm);
11303       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
11304       if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
11305         EmitA32(0x02500000U | (cond.GetCondition() << 28) |
11306                 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
11307                 immediate_a32.GetEncodingValue());
11308         return;
11309       }
11310       // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
11311       if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
11312         EmitA32(0x025d0000U | (cond.GetCondition() << 28) |
11313                 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
11314         return;
11315       }
11316     }
11317   }
11318   if (operand.IsImmediateShiftedRegister()) {
11319     Register rm = operand.GetBaseRegister();
11320     if (operand.IsPlainRegister()) {
11321       if (IsUsingT32()) {
11322         // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11323         if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
11324             rm.IsLow()) {
11325           EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
11326                      (rm.GetCode() << 6));
11327           AdvanceIT();
11328           return;
11329         }
11330       }
11331     }
11332     Shift shift = operand.GetShift();
11333     uint32_t amount = operand.GetShiftAmount();
11334     if (IsUsingT32()) {
11335       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
11336       if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
11337           !rd.Is(pc)) {
11338         uint32_t amount_ = amount % 32;
11339         EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11340                    rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
11341                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11342         AdvanceIT();
11343         return;
11344       }
11345       // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
11346       if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
11347           !rd.Is(pc)) {
11348         uint32_t amount_ = amount % 32;
11349         EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() |
11350                    (operand.GetTypeEncodingValue() << 4) |
11351                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11352         AdvanceIT();
11353         return;
11354       }
11355     } else {
11356       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
11357       if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
11358         uint32_t amount_ = amount % 32;
11359         EmitA32(0x00500000U | (cond.GetCondition() << 28) |
11360                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11361                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11362         return;
11363       }
11364       // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
11365       if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
11366         uint32_t amount_ = amount % 32;
11367         EmitA32(0x005d0000U | (cond.GetCondition() << 28) |
11368                 (rd.GetCode() << 12) | rm.GetCode() |
11369                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11370         return;
11371       }
11372     }
11373   }
11374   if (operand.IsRegisterShiftedRegister()) {
11375     Register rm = operand.GetBaseRegister();
11376     Shift shift = operand.GetShift();
11377     if (IsUsingA32()) {
11378       // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
11379       if (cond.IsNotNever()) {
11380         EmitA32(0x00500010U | (cond.GetCondition() << 28) |
11381                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11382                 (shift.GetType() << 5) |
11383                 (operand.GetShiftRegister().GetCode() << 8));
11384         return;
11385       }
11386     }
11387   }
11388   Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand);
11389 }
11390 
subs(Register rd,const Operand & operand)11391 void Assembler::subs(Register rd, const Operand& operand) {
11392   VIXL_ASSERT(AllowAssembler());
11393   CheckIT(al);
11394   if (operand.IsImmediate()) {
11395     uint32_t imm = operand.GetImmediate();
11396     if (IsUsingT32()) {
11397       // SUBS{<q>} <Rdn>, #<imm8> ; T2
11398       if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
11399         EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
11400         AdvanceIT();
11401         return;
11402       }
11403     }
11404   }
11405   Delegate(kSubs, &Assembler::subs, rd, operand);
11406 }
11407 
subw(Condition cond,Register rd,Register rn,const Operand & operand)11408 void Assembler::subw(Condition cond,
11409                      Register rd,
11410                      Register rn,
11411                      const Operand& operand) {
11412   VIXL_ASSERT(AllowAssembler());
11413   CheckIT(cond);
11414   if (operand.IsImmediate()) {
11415     uint32_t imm = operand.GetImmediate();
11416     if (IsUsingT32()) {
11417       // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
11418       if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd)) {
11419         EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11420                    (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11421         AdvanceIT();
11422         return;
11423       }
11424       // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
11425       if (rn.Is(sp) && (imm <= 4095)) {
11426         EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
11427                    ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
11428         AdvanceIT();
11429         return;
11430       }
11431     }
11432   }
11433   Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand);
11434 }
11435 
svc(Condition cond,uint32_t imm)11436 void Assembler::svc(Condition cond, uint32_t imm) {
11437   VIXL_ASSERT(AllowAssembler());
11438   CheckIT(cond);
11439   if (IsUsingT32()) {
11440     // SVC{<c>}{<q>} {#}<imm> ; T1
11441     if ((imm <= 255)) {
11442       EmitT32_16(0xdf00 | imm);
11443       AdvanceIT();
11444       return;
11445     }
11446   } else {
11447     // SVC{<c>}{<q>} {#}<imm> ; A1
11448     if ((imm <= 16777215) && cond.IsNotNever()) {
11449       EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm);
11450       return;
11451     }
11452   }
11453   Delegate(kSvc, &Assembler::svc, cond, imm);
11454 }
11455 
sxtab(Condition cond,Register rd,Register rn,const Operand & operand)11456 void Assembler::sxtab(Condition cond,
11457                       Register rd,
11458                       Register rn,
11459                       const Operand& operand) {
11460   VIXL_ASSERT(AllowAssembler());
11461   CheckIT(cond);
11462   if (operand.IsImmediateShiftedRegister()) {
11463     Register rm = operand.GetBaseRegister();
11464     Shift shift = operand.GetShift();
11465     uint32_t amount = operand.GetShiftAmount();
11466     if (IsUsingT32()) {
11467       // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11468       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11469           ((amount % 8) == 0) && !rn.Is(pc)) {
11470         uint32_t amount_ = amount / 8;
11471         EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11472                    rm.GetCode() | (amount_ << 4));
11473         AdvanceIT();
11474         return;
11475       }
11476     } else {
11477       // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11478       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11479           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11480         uint32_t amount_ = amount / 8;
11481         EmitA32(0x06a00070U | (cond.GetCondition() << 28) |
11482                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11483                 (amount_ << 10));
11484         return;
11485       }
11486     }
11487   }
11488   Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand);
11489 }
11490 
sxtab16(Condition cond,Register rd,Register rn,const Operand & operand)11491 void Assembler::sxtab16(Condition cond,
11492                         Register rd,
11493                         Register rn,
11494                         const Operand& operand) {
11495   VIXL_ASSERT(AllowAssembler());
11496   CheckIT(cond);
11497   if (operand.IsImmediateShiftedRegister()) {
11498     Register rm = operand.GetBaseRegister();
11499     Shift shift = operand.GetShift();
11500     uint32_t amount = operand.GetShiftAmount();
11501     if (IsUsingT32()) {
11502       // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11503       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11504           ((amount % 8) == 0) && !rn.Is(pc)) {
11505         uint32_t amount_ = amount / 8;
11506         EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11507                    rm.GetCode() | (amount_ << 4));
11508         AdvanceIT();
11509         return;
11510       }
11511     } else {
11512       // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11513       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11514           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11515         uint32_t amount_ = amount / 8;
11516         EmitA32(0x06800070U | (cond.GetCondition() << 28) |
11517                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11518                 (amount_ << 10));
11519         return;
11520       }
11521     }
11522   }
11523   Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand);
11524 }
11525 
sxtah(Condition cond,Register rd,Register rn,const Operand & operand)11526 void Assembler::sxtah(Condition cond,
11527                       Register rd,
11528                       Register rn,
11529                       const Operand& operand) {
11530   VIXL_ASSERT(AllowAssembler());
11531   CheckIT(cond);
11532   if (operand.IsImmediateShiftedRegister()) {
11533     Register rm = operand.GetBaseRegister();
11534     Shift shift = operand.GetShift();
11535     uint32_t amount = operand.GetShiftAmount();
11536     if (IsUsingT32()) {
11537       // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
11538       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11539           ((amount % 8) == 0) && !rn.Is(pc)) {
11540         uint32_t amount_ = amount / 8;
11541         EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11542                    rm.GetCode() | (amount_ << 4));
11543         AdvanceIT();
11544         return;
11545       }
11546     } else {
11547       // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
11548       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11549           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
11550         uint32_t amount_ = amount / 8;
11551         EmitA32(0x06b00070U | (cond.GetCondition() << 28) |
11552                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11553                 (amount_ << 10));
11554         return;
11555       }
11556     }
11557   }
11558   Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand);
11559 }
11560 
sxtb(Condition cond,EncodingSize size,Register rd,const Operand & operand)11561 void Assembler::sxtb(Condition cond,
11562                      EncodingSize size,
11563                      Register rd,
11564                      const Operand& operand) {
11565   VIXL_ASSERT(AllowAssembler());
11566   CheckIT(cond);
11567   if (operand.IsImmediateShiftedRegister()) {
11568     Register rm = operand.GetBaseRegister();
11569     if (operand.IsPlainRegister()) {
11570       if (IsUsingT32()) {
11571         // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
11572         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
11573           EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3));
11574           AdvanceIT();
11575           return;
11576         }
11577       }
11578     }
11579     Shift shift = operand.GetShift();
11580     uint32_t amount = operand.GetShiftAmount();
11581     if (IsUsingT32()) {
11582       // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
11583       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
11584           (amount <= 24) && ((amount % 8) == 0)) {
11585         uint32_t amount_ = amount / 8;
11586         EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11587                    (amount_ << 4));
11588         AdvanceIT();
11589         return;
11590       }
11591     } else {
11592       // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11593       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11594           ((amount % 8) == 0) && cond.IsNotNever()) {
11595         uint32_t amount_ = amount / 8;
11596         EmitA32(0x06af0070U | (cond.GetCondition() << 28) |
11597                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11598         return;
11599       }
11600     }
11601   }
11602   Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand);
11603 }
11604 
sxtb16(Condition cond,Register rd,const Operand & operand)11605 void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) {
11606   VIXL_ASSERT(AllowAssembler());
11607   CheckIT(cond);
11608   if (operand.IsImmediateShiftedRegister()) {
11609     Register rm = operand.GetBaseRegister();
11610     Shift shift = operand.GetShift();
11611     uint32_t amount = operand.GetShiftAmount();
11612     if (IsUsingT32()) {
11613       // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
11614       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11615           ((amount % 8) == 0)) {
11616         uint32_t amount_ = amount / 8;
11617         EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11618                    (amount_ << 4));
11619         AdvanceIT();
11620         return;
11621       }
11622     } else {
11623       // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11624       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11625           ((amount % 8) == 0) && cond.IsNotNever()) {
11626         uint32_t amount_ = amount / 8;
11627         EmitA32(0x068f0070U | (cond.GetCondition() << 28) |
11628                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11629         return;
11630       }
11631     }
11632   }
11633   Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand);
11634 }
11635 
sxth(Condition cond,EncodingSize size,Register rd,const Operand & operand)11636 void Assembler::sxth(Condition cond,
11637                      EncodingSize size,
11638                      Register rd,
11639                      const Operand& operand) {
11640   VIXL_ASSERT(AllowAssembler());
11641   CheckIT(cond);
11642   if (operand.IsImmediateShiftedRegister()) {
11643     Register rm = operand.GetBaseRegister();
11644     if (operand.IsPlainRegister()) {
11645       if (IsUsingT32()) {
11646         // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
11647         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
11648           EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3));
11649           AdvanceIT();
11650           return;
11651         }
11652       }
11653     }
11654     Shift shift = operand.GetShift();
11655     uint32_t amount = operand.GetShiftAmount();
11656     if (IsUsingT32()) {
11657       // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
11658       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
11659           (amount <= 24) && ((amount % 8) == 0)) {
11660         uint32_t amount_ = amount / 8;
11661         EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() |
11662                    (amount_ << 4));
11663         AdvanceIT();
11664         return;
11665       }
11666     } else {
11667       // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
11668       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
11669           ((amount % 8) == 0) && cond.IsNotNever()) {
11670         uint32_t amount_ = amount / 8;
11671         EmitA32(0x06bf0070U | (cond.GetCondition() << 28) |
11672                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
11673         return;
11674       }
11675     }
11676   }
11677   Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand);
11678 }
11679 
tbb(Condition cond,Register rn,Register rm)11680 void Assembler::tbb(Condition cond, Register rn, Register rm) {
11681   VIXL_ASSERT(AllowAssembler());
11682   CheckIT(cond);
11683   if (IsUsingT32()) {
11684     // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1
11685     if (OutsideITBlockAndAlOrLast(cond) &&
11686         (!rm.IsPC() || AllowUnpredictable())) {
11687       EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode());
11688       AdvanceIT();
11689       return;
11690     }
11691   }
11692   Delegate(kTbb, &Assembler::tbb, cond, rn, rm);
11693 }
11694 
tbh(Condition cond,Register rn,Register rm)11695 void Assembler::tbh(Condition cond, Register rn, Register rm) {
11696   VIXL_ASSERT(AllowAssembler());
11697   CheckIT(cond);
11698   if (IsUsingT32()) {
11699     // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1
11700     if (OutsideITBlockAndAlOrLast(cond) &&
11701         (!rm.IsPC() || AllowUnpredictable())) {
11702       EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode());
11703       AdvanceIT();
11704       return;
11705     }
11706   }
11707   Delegate(kTbh, &Assembler::tbh, cond, rn, rm);
11708 }
11709 
teq(Condition cond,Register rn,const Operand & operand)11710 void Assembler::teq(Condition cond, Register rn, const Operand& operand) {
11711   VIXL_ASSERT(AllowAssembler());
11712   CheckIT(cond);
11713   if (operand.IsImmediate()) {
11714     uint32_t imm = operand.GetImmediate();
11715     if (IsUsingT32()) {
11716       ImmediateT32 immediate_t32(imm);
11717       // TEQ{<c>}{<q>} <Rn>, #<const> ; T1
11718       if (immediate_t32.IsValid()) {
11719         EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) |
11720                    (immediate_t32.GetEncodingValue() & 0xff) |
11721                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11722                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11723         AdvanceIT();
11724         return;
11725       }
11726     } else {
11727       ImmediateA32 immediate_a32(imm);
11728       // TEQ{<c>}{<q>} <Rn>, #<const> ; A1
11729       if (immediate_a32.IsValid() && cond.IsNotNever()) {
11730         EmitA32(0x03300000U | (cond.GetCondition() << 28) |
11731                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
11732         return;
11733       }
11734     }
11735   }
11736   if (operand.IsImmediateShiftedRegister()) {
11737     Register rm = operand.GetBaseRegister();
11738     Shift shift = operand.GetShift();
11739     uint32_t amount = operand.GetShiftAmount();
11740     if (IsUsingT32()) {
11741       // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1
11742       if (shift.IsValidAmount(amount)) {
11743         uint32_t amount_ = amount % 32;
11744         EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() |
11745                    (operand.GetTypeEncodingValue() << 4) |
11746                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11747         AdvanceIT();
11748         return;
11749       }
11750     } else {
11751       // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
11752       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
11753         uint32_t amount_ = amount % 32;
11754         EmitA32(0x01300000U | (cond.GetCondition() << 28) |
11755                 (rn.GetCode() << 16) | rm.GetCode() |
11756                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11757         return;
11758       }
11759     }
11760   }
11761   if (operand.IsRegisterShiftedRegister()) {
11762     Register rm = operand.GetBaseRegister();
11763     Shift shift = operand.GetShift();
11764     if (IsUsingA32()) {
11765       // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
11766       if (cond.IsNotNever()) {
11767         EmitA32(0x01300010U | (cond.GetCondition() << 28) |
11768                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
11769                 (operand.GetShiftRegister().GetCode() << 8));
11770         return;
11771       }
11772     }
11773   }
11774   Delegate(kTeq, &Assembler::teq, cond, rn, operand);
11775 }
11776 
tst(Condition cond,EncodingSize size,Register rn,const Operand & operand)11777 void Assembler::tst(Condition cond,
11778                     EncodingSize size,
11779                     Register rn,
11780                     const Operand& operand) {
11781   VIXL_ASSERT(AllowAssembler());
11782   CheckIT(cond);
11783   if (operand.IsImmediate()) {
11784     uint32_t imm = operand.GetImmediate();
11785     if (IsUsingT32()) {
11786       ImmediateT32 immediate_t32(imm);
11787       // TST{<c>}{<q>} <Rn>, #<const> ; T1
11788       if (!size.IsNarrow() && immediate_t32.IsValid()) {
11789         EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) |
11790                    (immediate_t32.GetEncodingValue() & 0xff) |
11791                    ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
11792                    ((immediate_t32.GetEncodingValue() & 0x800) << 15));
11793         AdvanceIT();
11794         return;
11795       }
11796     } else {
11797       ImmediateA32 immediate_a32(imm);
11798       // TST{<c>}{<q>} <Rn>, #<const> ; A1
11799       if (immediate_a32.IsValid() && cond.IsNotNever()) {
11800         EmitA32(0x03100000U | (cond.GetCondition() << 28) |
11801                 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
11802         return;
11803       }
11804     }
11805   }
11806   if (operand.IsImmediateShiftedRegister()) {
11807     Register rm = operand.GetBaseRegister();
11808     if (operand.IsPlainRegister()) {
11809       if (IsUsingT32()) {
11810         // TST{<c>}{<q>} <Rn>, <Rm> ; T1
11811         if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
11812           EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3));
11813           AdvanceIT();
11814           return;
11815         }
11816       }
11817     }
11818     Shift shift = operand.GetShift();
11819     uint32_t amount = operand.GetShiftAmount();
11820     if (IsUsingT32()) {
11821       // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
11822       if (!size.IsNarrow() && shift.IsValidAmount(amount)) {
11823         uint32_t amount_ = amount % 32;
11824         EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() |
11825                    (operand.GetTypeEncodingValue() << 4) |
11826                    ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
11827         AdvanceIT();
11828         return;
11829       }
11830     } else {
11831       // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
11832       if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
11833         uint32_t amount_ = amount % 32;
11834         EmitA32(0x01100000U | (cond.GetCondition() << 28) |
11835                 (rn.GetCode() << 16) | rm.GetCode() |
11836                 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
11837         return;
11838       }
11839     }
11840   }
11841   if (operand.IsRegisterShiftedRegister()) {
11842     Register rm = operand.GetBaseRegister();
11843     Shift shift = operand.GetShift();
11844     if (IsUsingA32()) {
11845       // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
11846       if (cond.IsNotNever()) {
11847         EmitA32(0x01100010U | (cond.GetCondition() << 28) |
11848                 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
11849                 (operand.GetShiftRegister().GetCode() << 8));
11850         return;
11851       }
11852     }
11853   }
11854   Delegate(kTst, &Assembler::tst, cond, size, rn, operand);
11855 }
11856 
uadd16(Condition cond,Register rd,Register rn,Register rm)11857 void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) {
11858   VIXL_ASSERT(AllowAssembler());
11859   CheckIT(cond);
11860   if (IsUsingT32()) {
11861     // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11862     EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11863                rm.GetCode());
11864     AdvanceIT();
11865     return;
11866   } else {
11867     // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11868     if (cond.IsNotNever()) {
11869       EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11870               (rn.GetCode() << 16) | rm.GetCode());
11871       return;
11872     }
11873   }
11874   Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm);
11875 }
11876 
uadd8(Condition cond,Register rd,Register rn,Register rm)11877 void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) {
11878   VIXL_ASSERT(AllowAssembler());
11879   CheckIT(cond);
11880   if (IsUsingT32()) {
11881     // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11882     EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11883                rm.GetCode());
11884     AdvanceIT();
11885     return;
11886   } else {
11887     // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11888     if (cond.IsNotNever()) {
11889       EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11890               (rn.GetCode() << 16) | rm.GetCode());
11891       return;
11892     }
11893   }
11894   Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm);
11895 }
11896 
uasx(Condition cond,Register rd,Register rn,Register rm)11897 void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) {
11898   VIXL_ASSERT(AllowAssembler());
11899   CheckIT(cond);
11900   if (IsUsingT32()) {
11901     // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11902     EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11903                rm.GetCode());
11904     AdvanceIT();
11905     return;
11906   } else {
11907     // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11908     if (cond.IsNotNever()) {
11909       EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
11910               (rn.GetCode() << 16) | rm.GetCode());
11911       return;
11912     }
11913   }
11914   Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm);
11915 }
11916 
ubfx(Condition cond,Register rd,Register rn,uint32_t lsb,const Operand & operand)11917 void Assembler::ubfx(Condition cond,
11918                      Register rd,
11919                      Register rn,
11920                      uint32_t lsb,
11921                      const Operand& operand) {
11922   VIXL_ASSERT(AllowAssembler());
11923   CheckIT(cond);
11924   if (operand.IsImmediate()) {
11925     uint32_t width = operand.GetImmediate();
11926     if (IsUsingT32()) {
11927       // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
11928       if ((lsb <= 31) &&
11929           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
11930         uint32_t widthm1 = width - 1;
11931         EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11932                    ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
11933         AdvanceIT();
11934         return;
11935       }
11936     } else {
11937       // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
11938       if ((lsb <= 31) && cond.IsNotNever() &&
11939           (((width >= 1) && (width <= 32 - lsb)) || AllowUnpredictable())) {
11940         uint32_t widthm1 = width - 1;
11941         EmitA32(0x07e00050U | (cond.GetCondition() << 28) |
11942                 (rd.GetCode() << 12) | rn.GetCode() | (lsb << 7) |
11943                 (widthm1 << 16));
11944         return;
11945       }
11946     }
11947   }
11948   Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, operand);
11949 }
11950 
udf(Condition cond,EncodingSize size,uint32_t imm)11951 void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) {
11952   VIXL_ASSERT(AllowAssembler());
11953   CheckIT(cond);
11954   if (IsUsingT32()) {
11955     // UDF{<c>}{<q>} {#}<imm> ; T1
11956     if (!size.IsWide() && (imm <= 255)) {
11957       if (cond.Is(al) || AllowStronglyDiscouraged()) {
11958         EmitT32_16(0xde00 | imm);
11959         AdvanceIT();
11960         return;
11961       }
11962     }
11963     // UDF{<c>}{<q>} {#}<imm> ; T2
11964     if (!size.IsNarrow() && (imm <= 65535)) {
11965       if (cond.Is(al) || AllowStronglyDiscouraged()) {
11966         EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
11967         AdvanceIT();
11968         return;
11969       }
11970     }
11971   } else {
11972     // UDF{<c>}{<q>} {#}<imm> ; A1
11973     if ((imm <= 65535)) {
11974       if (cond.Is(al) || AllowStronglyDiscouraged()) {
11975         EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4));
11976         return;
11977       }
11978     }
11979   }
11980   Delegate(kUdf, &Assembler::udf, cond, size, imm);
11981 }
11982 
udiv(Condition cond,Register rd,Register rn,Register rm)11983 void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) {
11984   VIXL_ASSERT(AllowAssembler());
11985   CheckIT(cond);
11986   if (IsUsingT32()) {
11987     // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
11988     EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
11989                rm.GetCode());
11990     AdvanceIT();
11991     return;
11992   } else {
11993     // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
11994     if (cond.IsNotNever()) {
11995       EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
11996               rn.GetCode() | (rm.GetCode() << 8));
11997       return;
11998     }
11999   }
12000   Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm);
12001 }
12002 
uhadd16(Condition cond,Register rd,Register rn,Register rm)12003 void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) {
12004   VIXL_ASSERT(AllowAssembler());
12005   CheckIT(cond);
12006   if (IsUsingT32()) {
12007     // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12008     EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12009                rm.GetCode());
12010     AdvanceIT();
12011     return;
12012   } else {
12013     // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12014     if (cond.IsNotNever()) {
12015       EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12016               (rn.GetCode() << 16) | rm.GetCode());
12017       return;
12018     }
12019   }
12020   Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm);
12021 }
12022 
uhadd8(Condition cond,Register rd,Register rn,Register rm)12023 void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) {
12024   VIXL_ASSERT(AllowAssembler());
12025   CheckIT(cond);
12026   if (IsUsingT32()) {
12027     // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12028     EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12029                rm.GetCode());
12030     AdvanceIT();
12031     return;
12032   } else {
12033     // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12034     if (cond.IsNotNever()) {
12035       EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12036               (rn.GetCode() << 16) | rm.GetCode());
12037       return;
12038     }
12039   }
12040   Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm);
12041 }
12042 
uhasx(Condition cond,Register rd,Register rn,Register rm)12043 void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) {
12044   VIXL_ASSERT(AllowAssembler());
12045   CheckIT(cond);
12046   if (IsUsingT32()) {
12047     // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12048     EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12049                rm.GetCode());
12050     AdvanceIT();
12051     return;
12052   } else {
12053     // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12054     if (cond.IsNotNever()) {
12055       EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12056               (rn.GetCode() << 16) | rm.GetCode());
12057       return;
12058     }
12059   }
12060   Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm);
12061 }
12062 
uhsax(Condition cond,Register rd,Register rn,Register rm)12063 void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) {
12064   VIXL_ASSERT(AllowAssembler());
12065   CheckIT(cond);
12066   if (IsUsingT32()) {
12067     // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12068     EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12069                rm.GetCode());
12070     AdvanceIT();
12071     return;
12072   } else {
12073     // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12074     if (cond.IsNotNever()) {
12075       EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12076               (rn.GetCode() << 16) | rm.GetCode());
12077       return;
12078     }
12079   }
12080   Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm);
12081 }
12082 
uhsub16(Condition cond,Register rd,Register rn,Register rm)12083 void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) {
12084   VIXL_ASSERT(AllowAssembler());
12085   CheckIT(cond);
12086   if (IsUsingT32()) {
12087     // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12088     EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12089                rm.GetCode());
12090     AdvanceIT();
12091     return;
12092   } else {
12093     // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12094     if (cond.IsNotNever()) {
12095       EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12096               (rn.GetCode() << 16) | rm.GetCode());
12097       return;
12098     }
12099   }
12100   Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm);
12101 }
12102 
uhsub8(Condition cond,Register rd,Register rn,Register rm)12103 void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) {
12104   VIXL_ASSERT(AllowAssembler());
12105   CheckIT(cond);
12106   if (IsUsingT32()) {
12107     // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12108     EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12109                rm.GetCode());
12110     AdvanceIT();
12111     return;
12112   } else {
12113     // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12114     if (cond.IsNotNever()) {
12115       EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12116               (rn.GetCode() << 16) | rm.GetCode());
12117       return;
12118     }
12119   }
12120   Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm);
12121 }
12122 
umaal(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)12123 void Assembler::umaal(
12124     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12125   VIXL_ASSERT(AllowAssembler());
12126   CheckIT(cond);
12127   if (IsUsingT32()) {
12128     // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
12129     EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
12130                (rn.GetCode() << 16) | rm.GetCode());
12131     AdvanceIT();
12132     return;
12133   } else {
12134     // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12135     if (cond.IsNotNever()) {
12136       EmitA32(0x00400090U | (cond.GetCondition() << 28) |
12137               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12138               (rm.GetCode() << 8));
12139       return;
12140     }
12141   }
12142   Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm);
12143 }
12144 
umlal(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)12145 void Assembler::umlal(
12146     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12147   VIXL_ASSERT(AllowAssembler());
12148   CheckIT(cond);
12149   if (IsUsingT32()) {
12150     // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
12151     EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
12152                (rn.GetCode() << 16) | rm.GetCode());
12153     AdvanceIT();
12154     return;
12155   } else {
12156     // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12157     if (cond.IsNotNever()) {
12158       EmitA32(0x00a00090U | (cond.GetCondition() << 28) |
12159               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12160               (rm.GetCode() << 8));
12161       return;
12162     }
12163   }
12164   Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm);
12165 }
12166 
umlals(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)12167 void Assembler::umlals(
12168     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12169   VIXL_ASSERT(AllowAssembler());
12170   CheckIT(cond);
12171   if (IsUsingA32()) {
12172     // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12173     if (cond.IsNotNever()) {
12174       EmitA32(0x00b00090U | (cond.GetCondition() << 28) |
12175               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12176               (rm.GetCode() << 8));
12177       return;
12178     }
12179   }
12180   Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm);
12181 }
12182 
umull(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)12183 void Assembler::umull(
12184     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12185   VIXL_ASSERT(AllowAssembler());
12186   CheckIT(cond);
12187   if (IsUsingT32()) {
12188     // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
12189     EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
12190                (rn.GetCode() << 16) | rm.GetCode());
12191     AdvanceIT();
12192     return;
12193   } else {
12194     // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12195     if (cond.IsNotNever()) {
12196       EmitA32(0x00800090U | (cond.GetCondition() << 28) |
12197               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12198               (rm.GetCode() << 8));
12199       return;
12200     }
12201   }
12202   Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm);
12203 }
12204 
umulls(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)12205 void Assembler::umulls(
12206     Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
12207   VIXL_ASSERT(AllowAssembler());
12208   CheckIT(cond);
12209   if (IsUsingA32()) {
12210     // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
12211     if (cond.IsNotNever()) {
12212       EmitA32(0x00900090U | (cond.GetCondition() << 28) |
12213               (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
12214               (rm.GetCode() << 8));
12215       return;
12216     }
12217   }
12218   Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm);
12219 }
12220 
uqadd16(Condition cond,Register rd,Register rn,Register rm)12221 void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) {
12222   VIXL_ASSERT(AllowAssembler());
12223   CheckIT(cond);
12224   if (IsUsingT32()) {
12225     // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12226     EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12227                rm.GetCode());
12228     AdvanceIT();
12229     return;
12230   } else {
12231     // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12232     if (cond.IsNotNever()) {
12233       EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12234               (rn.GetCode() << 16) | rm.GetCode());
12235       return;
12236     }
12237   }
12238   Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm);
12239 }
12240 
uqadd8(Condition cond,Register rd,Register rn,Register rm)12241 void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) {
12242   VIXL_ASSERT(AllowAssembler());
12243   CheckIT(cond);
12244   if (IsUsingT32()) {
12245     // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12246     EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12247                rm.GetCode());
12248     AdvanceIT();
12249     return;
12250   } else {
12251     // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12252     if (cond.IsNotNever()) {
12253       EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12254               (rn.GetCode() << 16) | rm.GetCode());
12255       return;
12256     }
12257   }
12258   Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm);
12259 }
12260 
uqasx(Condition cond,Register rd,Register rn,Register rm)12261 void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) {
12262   VIXL_ASSERT(AllowAssembler());
12263   CheckIT(cond);
12264   if (IsUsingT32()) {
12265     // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12266     EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12267                rm.GetCode());
12268     AdvanceIT();
12269     return;
12270   } else {
12271     // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12272     if (cond.IsNotNever()) {
12273       EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12274               (rn.GetCode() << 16) | rm.GetCode());
12275       return;
12276     }
12277   }
12278   Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm);
12279 }
12280 
uqsax(Condition cond,Register rd,Register rn,Register rm)12281 void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) {
12282   VIXL_ASSERT(AllowAssembler());
12283   CheckIT(cond);
12284   if (IsUsingT32()) {
12285     // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12286     EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12287                rm.GetCode());
12288     AdvanceIT();
12289     return;
12290   } else {
12291     // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12292     if (cond.IsNotNever()) {
12293       EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12294               (rn.GetCode() << 16) | rm.GetCode());
12295       return;
12296     }
12297   }
12298   Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm);
12299 }
12300 
uqsub16(Condition cond,Register rd,Register rn,Register rm)12301 void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) {
12302   VIXL_ASSERT(AllowAssembler());
12303   CheckIT(cond);
12304   if (IsUsingT32()) {
12305     // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12306     EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12307                rm.GetCode());
12308     AdvanceIT();
12309     return;
12310   } else {
12311     // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12312     if (cond.IsNotNever()) {
12313       EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12314               (rn.GetCode() << 16) | rm.GetCode());
12315       return;
12316     }
12317   }
12318   Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm);
12319 }
12320 
uqsub8(Condition cond,Register rd,Register rn,Register rm)12321 void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) {
12322   VIXL_ASSERT(AllowAssembler());
12323   CheckIT(cond);
12324   if (IsUsingT32()) {
12325     // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12326     EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12327                rm.GetCode());
12328     AdvanceIT();
12329     return;
12330   } else {
12331     // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12332     if (cond.IsNotNever()) {
12333       EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12334               (rn.GetCode() << 16) | rm.GetCode());
12335       return;
12336     }
12337   }
12338   Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm);
12339 }
12340 
usad8(Condition cond,Register rd,Register rn,Register rm)12341 void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) {
12342   VIXL_ASSERT(AllowAssembler());
12343   CheckIT(cond);
12344   if (IsUsingT32()) {
12345     // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12346     EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12347                rm.GetCode());
12348     AdvanceIT();
12349     return;
12350   } else {
12351     // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12352     if (cond.IsNotNever()) {
12353       EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
12354               rn.GetCode() | (rm.GetCode() << 8));
12355       return;
12356     }
12357   }
12358   Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm);
12359 }
12360 
usada8(Condition cond,Register rd,Register rn,Register rm,Register ra)12361 void Assembler::usada8(
12362     Condition cond, Register rd, Register rn, Register rm, Register ra) {
12363   VIXL_ASSERT(AllowAssembler());
12364   CheckIT(cond);
12365   if (IsUsingT32()) {
12366     // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
12367     if (!ra.Is(pc)) {
12368       EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12369                  rm.GetCode() | (ra.GetCode() << 12));
12370       AdvanceIT();
12371       return;
12372     }
12373   } else {
12374     // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
12375     if (cond.IsNotNever() && !ra.Is(pc)) {
12376       EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
12377               rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
12378       return;
12379     }
12380   }
12381   Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra);
12382 }
12383 
usat(Condition cond,Register rd,uint32_t imm,const Operand & operand)12384 void Assembler::usat(Condition cond,
12385                      Register rd,
12386                      uint32_t imm,
12387                      const Operand& operand) {
12388   VIXL_ASSERT(AllowAssembler());
12389   CheckIT(cond);
12390   if (operand.IsImmediateShiftedRegister()) {
12391     Register rn = operand.GetBaseRegister();
12392     Shift shift = operand.GetShift();
12393     uint32_t amount = operand.GetShiftAmount();
12394     if (IsUsingT32()) {
12395       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
12396       if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31)) {
12397         EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
12398                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
12399                    ((amount & 0x1c) << 10));
12400         AdvanceIT();
12401         return;
12402       }
12403       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
12404       if ((imm <= 31) && shift.IsLSL() && (amount <= 31)) {
12405         EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm |
12406                    (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
12407                    ((amount & 0x1c) << 10));
12408         AdvanceIT();
12409         return;
12410       }
12411     } else {
12412       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
12413       if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) &&
12414           cond.IsNotNever()) {
12415         uint32_t amount_ = amount % 32;
12416         EmitA32(0x06e00050U | (cond.GetCondition() << 28) |
12417                 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
12418                 (amount_ << 7));
12419         return;
12420       }
12421       // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
12422       if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever()) {
12423         EmitA32(0x06e00010U | (cond.GetCondition() << 28) |
12424                 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
12425                 (amount << 7));
12426         return;
12427       }
12428     }
12429   }
12430   Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand);
12431 }
12432 
usat16(Condition cond,Register rd,uint32_t imm,Register rn)12433 void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) {
12434   VIXL_ASSERT(AllowAssembler());
12435   CheckIT(cond);
12436   if (IsUsingT32()) {
12437     // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
12438     if ((imm <= 15)) {
12439       EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
12440                  (rn.GetCode() << 16));
12441       AdvanceIT();
12442       return;
12443     }
12444   } else {
12445     // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
12446     if ((imm <= 15) && cond.IsNotNever()) {
12447       EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12448               (imm << 16) | rn.GetCode());
12449       return;
12450     }
12451   }
12452   Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn);
12453 }
12454 
usax(Condition cond,Register rd,Register rn,Register rm)12455 void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) {
12456   VIXL_ASSERT(AllowAssembler());
12457   CheckIT(cond);
12458   if (IsUsingT32()) {
12459     // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12460     EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12461                rm.GetCode());
12462     AdvanceIT();
12463     return;
12464   } else {
12465     // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12466     if (cond.IsNotNever()) {
12467       EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12468               (rn.GetCode() << 16) | rm.GetCode());
12469       return;
12470     }
12471   }
12472   Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm);
12473 }
12474 
usub16(Condition cond,Register rd,Register rn,Register rm)12475 void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) {
12476   VIXL_ASSERT(AllowAssembler());
12477   CheckIT(cond);
12478   if (IsUsingT32()) {
12479     // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12480     EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12481                rm.GetCode());
12482     AdvanceIT();
12483     return;
12484   } else {
12485     // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12486     if (cond.IsNotNever()) {
12487       EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12488               (rn.GetCode() << 16) | rm.GetCode());
12489       return;
12490     }
12491   }
12492   Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm);
12493 }
12494 
usub8(Condition cond,Register rd,Register rn,Register rm)12495 void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) {
12496   VIXL_ASSERT(AllowAssembler());
12497   CheckIT(cond);
12498   if (IsUsingT32()) {
12499     // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12500     EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12501                rm.GetCode());
12502     AdvanceIT();
12503     return;
12504   } else {
12505     // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12506     if (cond.IsNotNever()) {
12507       EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12508               (rn.GetCode() << 16) | rm.GetCode());
12509       return;
12510     }
12511   }
12512   Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm);
12513 }
12514 
uxtab(Condition cond,Register rd,Register rn,const Operand & operand)12515 void Assembler::uxtab(Condition cond,
12516                       Register rd,
12517                       Register rn,
12518                       const Operand& operand) {
12519   VIXL_ASSERT(AllowAssembler());
12520   CheckIT(cond);
12521   if (operand.IsImmediateShiftedRegister()) {
12522     Register rm = operand.GetBaseRegister();
12523     Shift shift = operand.GetShift();
12524     uint32_t amount = operand.GetShiftAmount();
12525     if (IsUsingT32()) {
12526       // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12527       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12528           ((amount % 8) == 0) && !rn.Is(pc)) {
12529         uint32_t amount_ = amount / 8;
12530         EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12531                    rm.GetCode() | (amount_ << 4));
12532         AdvanceIT();
12533         return;
12534       }
12535     } else {
12536       // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12537       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12538           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12539         uint32_t amount_ = amount / 8;
12540         EmitA32(0x06e00070U | (cond.GetCondition() << 28) |
12541                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12542                 (amount_ << 10));
12543         return;
12544       }
12545     }
12546   }
12547   Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand);
12548 }
12549 
uxtab16(Condition cond,Register rd,Register rn,const Operand & operand)12550 void Assembler::uxtab16(Condition cond,
12551                         Register rd,
12552                         Register rn,
12553                         const Operand& operand) {
12554   VIXL_ASSERT(AllowAssembler());
12555   CheckIT(cond);
12556   if (operand.IsImmediateShiftedRegister()) {
12557     Register rm = operand.GetBaseRegister();
12558     Shift shift = operand.GetShift();
12559     uint32_t amount = operand.GetShiftAmount();
12560     if (IsUsingT32()) {
12561       // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12562       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12563           ((amount % 8) == 0) && !rn.Is(pc)) {
12564         uint32_t amount_ = amount / 8;
12565         EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12566                    rm.GetCode() | (amount_ << 4));
12567         AdvanceIT();
12568         return;
12569       }
12570     } else {
12571       // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12572       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12573           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12574         uint32_t amount_ = amount / 8;
12575         EmitA32(0x06c00070U | (cond.GetCondition() << 28) |
12576                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12577                 (amount_ << 10));
12578         return;
12579       }
12580     }
12581   }
12582   Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand);
12583 }
12584 
uxtah(Condition cond,Register rd,Register rn,const Operand & operand)12585 void Assembler::uxtah(Condition cond,
12586                       Register rd,
12587                       Register rn,
12588                       const Operand& operand) {
12589   VIXL_ASSERT(AllowAssembler());
12590   CheckIT(cond);
12591   if (operand.IsImmediateShiftedRegister()) {
12592     Register rm = operand.GetBaseRegister();
12593     Shift shift = operand.GetShift();
12594     uint32_t amount = operand.GetShiftAmount();
12595     if (IsUsingT32()) {
12596       // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12597       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12598           ((amount % 8) == 0) && !rn.Is(pc)) {
12599         uint32_t amount_ = amount / 8;
12600         EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12601                    rm.GetCode() | (amount_ << 4));
12602         AdvanceIT();
12603         return;
12604       }
12605     } else {
12606       // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12607       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12608           ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc)) {
12609         uint32_t amount_ = amount / 8;
12610         EmitA32(0x06f00070U | (cond.GetCondition() << 28) |
12611                 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12612                 (amount_ << 10));
12613         return;
12614       }
12615     }
12616   }
12617   Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand);
12618 }
12619 
uxtb(Condition cond,EncodingSize size,Register rd,const Operand & operand)12620 void Assembler::uxtb(Condition cond,
12621                      EncodingSize size,
12622                      Register rd,
12623                      const Operand& operand) {
12624   VIXL_ASSERT(AllowAssembler());
12625   CheckIT(cond);
12626   if (operand.IsImmediateShiftedRegister()) {
12627     Register rm = operand.GetBaseRegister();
12628     if (operand.IsPlainRegister()) {
12629       if (IsUsingT32()) {
12630         // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
12631         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12632           EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3));
12633           AdvanceIT();
12634           return;
12635         }
12636       }
12637     }
12638     Shift shift = operand.GetShift();
12639     uint32_t amount = operand.GetShiftAmount();
12640     if (IsUsingT32()) {
12641       // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12642       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12643           (amount <= 24) && ((amount % 8) == 0)) {
12644         uint32_t amount_ = amount / 8;
12645         EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12646                    (amount_ << 4));
12647         AdvanceIT();
12648         return;
12649       }
12650     } else {
12651       // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12652       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12653           ((amount % 8) == 0) && cond.IsNotNever()) {
12654         uint32_t amount_ = amount / 8;
12655         EmitA32(0x06ef0070U | (cond.GetCondition() << 28) |
12656                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12657         return;
12658       }
12659     }
12660   }
12661   Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand);
12662 }
12663 
uxtb16(Condition cond,Register rd,const Operand & operand)12664 void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) {
12665   VIXL_ASSERT(AllowAssembler());
12666   CheckIT(cond);
12667   if (operand.IsImmediateShiftedRegister()) {
12668     Register rm = operand.GetBaseRegister();
12669     Shift shift = operand.GetShift();
12670     uint32_t amount = operand.GetShiftAmount();
12671     if (IsUsingT32()) {
12672       // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
12673       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12674           ((amount % 8) == 0)) {
12675         uint32_t amount_ = amount / 8;
12676         EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12677                    (amount_ << 4));
12678         AdvanceIT();
12679         return;
12680       }
12681     } else {
12682       // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12683       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12684           ((amount % 8) == 0) && cond.IsNotNever()) {
12685         uint32_t amount_ = amount / 8;
12686         EmitA32(0x06cf0070U | (cond.GetCondition() << 28) |
12687                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12688         return;
12689       }
12690     }
12691   }
12692   Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand);
12693 }
12694 
uxth(Condition cond,EncodingSize size,Register rd,const Operand & operand)12695 void Assembler::uxth(Condition cond,
12696                      EncodingSize size,
12697                      Register rd,
12698                      const Operand& operand) {
12699   VIXL_ASSERT(AllowAssembler());
12700   CheckIT(cond);
12701   if (operand.IsImmediateShiftedRegister()) {
12702     Register rm = operand.GetBaseRegister();
12703     if (operand.IsPlainRegister()) {
12704       if (IsUsingT32()) {
12705         // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
12706         if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12707           EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3));
12708           AdvanceIT();
12709           return;
12710         }
12711       }
12712     }
12713     Shift shift = operand.GetShift();
12714     uint32_t amount = operand.GetShiftAmount();
12715     if (IsUsingT32()) {
12716       // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12717       if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12718           (amount <= 24) && ((amount % 8) == 0)) {
12719         uint32_t amount_ = amount / 8;
12720         EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12721                    (amount_ << 4));
12722         AdvanceIT();
12723         return;
12724       }
12725     } else {
12726       // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12727       if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12728           ((amount % 8) == 0) && cond.IsNotNever()) {
12729         uint32_t amount_ = amount / 8;
12730         EmitA32(0x06ff0070U | (cond.GetCondition() << 28) |
12731                 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12732         return;
12733       }
12734     }
12735   }
12736   Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand);
12737 }
12738 
vaba(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)12739 void Assembler::vaba(
12740     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12741   VIXL_ASSERT(AllowAssembler());
12742   CheckIT(cond);
12743   Dt_U_size_1 encoded_dt(dt);
12744   if (IsUsingT32()) {
12745     // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1
12746     if (encoded_dt.IsValid()) {
12747       if (cond.Is(al) || AllowStronglyDiscouraged()) {
12748         EmitT32_32(0xef000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12749                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12750                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12751         AdvanceIT();
12752         return;
12753       }
12754     }
12755   } else {
12756     // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1
12757     if (encoded_dt.IsValid()) {
12758       if (cond.Is(al)) {
12759         EmitA32(0xf2000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12760                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12761                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12762         return;
12763       }
12764     }
12765   }
12766   Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
12767 }
12768 
vaba(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)12769 void Assembler::vaba(
12770     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12771   VIXL_ASSERT(AllowAssembler());
12772   CheckIT(cond);
12773   Dt_U_size_1 encoded_dt(dt);
12774   if (IsUsingT32()) {
12775     // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1
12776     if (encoded_dt.IsValid()) {
12777       if (cond.Is(al) || AllowStronglyDiscouraged()) {
12778         EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12779                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12780                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12781         AdvanceIT();
12782         return;
12783       }
12784     }
12785   } else {
12786     // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1
12787     if (encoded_dt.IsValid()) {
12788       if (cond.Is(al)) {
12789         EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12790                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12791                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12792         return;
12793       }
12794     }
12795   }
12796   Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
12797 }
12798 
vabal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)12799 void Assembler::vabal(
12800     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
12801   VIXL_ASSERT(AllowAssembler());
12802   CheckIT(cond);
12803   Dt_U_size_1 encoded_dt(dt);
12804   if (IsUsingT32()) {
12805     // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
12806     if (encoded_dt.IsValid()) {
12807       if (cond.Is(al) || AllowStronglyDiscouraged()) {
12808         EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12809                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12810                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12811         AdvanceIT();
12812         return;
12813       }
12814     }
12815   } else {
12816     // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
12817     if (encoded_dt.IsValid()) {
12818       if (cond.Is(al)) {
12819         EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12820                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12821                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12822         return;
12823       }
12824     }
12825   }
12826   Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm);
12827 }
12828 
vabd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)12829 void Assembler::vabd(
12830     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
12831   VIXL_ASSERT(AllowAssembler());
12832   CheckIT(cond);
12833   Dt_U_size_1 encoded_dt(dt);
12834   if (IsUsingT32()) {
12835     // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
12836     if (dt.Is(F32)) {
12837       if (cond.Is(al) || AllowStronglyDiscouraged()) {
12838         EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12839                    rm.Encode(5, 0));
12840         AdvanceIT();
12841         return;
12842       }
12843     }
12844     // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
12845     if (encoded_dt.IsValid()) {
12846       if (cond.Is(al) || AllowStronglyDiscouraged()) {
12847         EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12848                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12849                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12850         AdvanceIT();
12851         return;
12852       }
12853     }
12854   } else {
12855     // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
12856     if (dt.Is(F32)) {
12857       if (cond.Is(al)) {
12858         EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12859                 rm.Encode(5, 0));
12860         return;
12861       }
12862     }
12863     // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
12864     if (encoded_dt.IsValid()) {
12865       if (cond.Is(al)) {
12866         EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12867                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12868                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12869         return;
12870       }
12871     }
12872   }
12873   Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
12874 }
12875 
vabd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)12876 void Assembler::vabd(
12877     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
12878   VIXL_ASSERT(AllowAssembler());
12879   CheckIT(cond);
12880   Dt_U_size_1 encoded_dt(dt);
12881   if (IsUsingT32()) {
12882     // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
12883     if (dt.Is(F32)) {
12884       if (cond.Is(al) || AllowStronglyDiscouraged()) {
12885         EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12886                    rm.Encode(5, 0));
12887         AdvanceIT();
12888         return;
12889       }
12890     }
12891     // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
12892     if (encoded_dt.IsValid()) {
12893       if (cond.Is(al) || AllowStronglyDiscouraged()) {
12894         EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12895                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12896                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12897         AdvanceIT();
12898         return;
12899       }
12900     }
12901   } else {
12902     // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
12903     if (dt.Is(F32)) {
12904       if (cond.Is(al)) {
12905         EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
12906                 rm.Encode(5, 0));
12907         return;
12908       }
12909     }
12910     // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
12911     if (encoded_dt.IsValid()) {
12912       if (cond.Is(al)) {
12913         EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12914                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12915                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12916         return;
12917       }
12918     }
12919   }
12920   Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
12921 }
12922 
vabdl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)12923 void Assembler::vabdl(
12924     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
12925   VIXL_ASSERT(AllowAssembler());
12926   CheckIT(cond);
12927   Dt_U_size_1 encoded_dt(dt);
12928   if (IsUsingT32()) {
12929     // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
12930     if (encoded_dt.IsValid()) {
12931       if (cond.Is(al) || AllowStronglyDiscouraged()) {
12932         EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12933                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
12934                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12935         AdvanceIT();
12936         return;
12937       }
12938     }
12939   } else {
12940     // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
12941     if (encoded_dt.IsValid()) {
12942       if (cond.Is(al)) {
12943         EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
12944                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
12945                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
12946         return;
12947       }
12948     }
12949   }
12950   Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm);
12951 }
12952 
vabs(Condition cond,DataType dt,DRegister rd,DRegister rm)12953 void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
12954   VIXL_ASSERT(AllowAssembler());
12955   CheckIT(cond);
12956   Dt_F_size_1 encoded_dt(dt);
12957   if (IsUsingT32()) {
12958     // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
12959     if (encoded_dt.IsValid()) {
12960       if (cond.Is(al) || AllowStronglyDiscouraged()) {
12961         EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12962                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12963                    rd.Encode(22, 12) | rm.Encode(5, 0));
12964         AdvanceIT();
12965         return;
12966       }
12967     }
12968     // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
12969     if (dt.Is(F64)) {
12970       EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
12971       AdvanceIT();
12972       return;
12973     }
12974   } else {
12975     // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
12976     if (encoded_dt.IsValid()) {
12977       if (cond.Is(al)) {
12978         EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
12979                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
12980                 rd.Encode(22, 12) | rm.Encode(5, 0));
12981         return;
12982       }
12983     }
12984     // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
12985     if (dt.Is(F64) && cond.IsNotNever()) {
12986       EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
12987               rm.Encode(5, 0));
12988       return;
12989     }
12990   }
12991   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
12992 }
12993 
vabs(Condition cond,DataType dt,QRegister rd,QRegister rm)12994 void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
12995   VIXL_ASSERT(AllowAssembler());
12996   CheckIT(cond);
12997   Dt_F_size_1 encoded_dt(dt);
12998   if (IsUsingT32()) {
12999     // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
13000     if (encoded_dt.IsValid()) {
13001       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13002         EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13003                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13004                    rd.Encode(22, 12) | rm.Encode(5, 0));
13005         AdvanceIT();
13006         return;
13007       }
13008     }
13009   } else {
13010     // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
13011     if (encoded_dt.IsValid()) {
13012       if (cond.Is(al)) {
13013         EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13014                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13015                 rd.Encode(22, 12) | rm.Encode(5, 0));
13016         return;
13017       }
13018     }
13019   }
13020   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
13021 }
13022 
vabs(Condition cond,DataType dt,SRegister rd,SRegister rm)13023 void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) {
13024   VIXL_ASSERT(AllowAssembler());
13025   CheckIT(cond);
13026   if (IsUsingT32()) {
13027     // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
13028     if (dt.Is(F32)) {
13029       EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
13030       AdvanceIT();
13031       return;
13032     }
13033   } else {
13034     // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
13035     if (dt.Is(F32) && cond.IsNotNever()) {
13036       EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
13037               rm.Encode(5, 0));
13038       return;
13039     }
13040   }
13041   Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
13042 }
13043 
vacge(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13044 void Assembler::vacge(
13045     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13046   VIXL_ASSERT(AllowAssembler());
13047   CheckIT(cond);
13048   if (IsUsingT32()) {
13049     // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13050     if (dt.Is(F32)) {
13051       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13052         EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13053                    rm.Encode(5, 0));
13054         AdvanceIT();
13055         return;
13056       }
13057     }
13058   } else {
13059     // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13060     if (dt.Is(F32)) {
13061       if (cond.Is(al)) {
13062         EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13063                 rm.Encode(5, 0));
13064         return;
13065       }
13066     }
13067   }
13068   Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
13069 }
13070 
vacge(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)13071 void Assembler::vacge(
13072     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13073   VIXL_ASSERT(AllowAssembler());
13074   CheckIT(cond);
13075   if (IsUsingT32()) {
13076     // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13077     if (dt.Is(F32)) {
13078       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13079         EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13080                    rm.Encode(5, 0));
13081         AdvanceIT();
13082         return;
13083       }
13084     }
13085   } else {
13086     // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13087     if (dt.Is(F32)) {
13088       if (cond.Is(al)) {
13089         EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13090                 rm.Encode(5, 0));
13091         return;
13092       }
13093     }
13094   }
13095   Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
13096 }
13097 
vacgt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13098 void Assembler::vacgt(
13099     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13100   VIXL_ASSERT(AllowAssembler());
13101   CheckIT(cond);
13102   if (IsUsingT32()) {
13103     // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13104     if (dt.Is(F32)) {
13105       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13106         EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13107                    rm.Encode(5, 0));
13108         AdvanceIT();
13109         return;
13110       }
13111     }
13112   } else {
13113     // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13114     if (dt.Is(F32)) {
13115       if (cond.Is(al)) {
13116         EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13117                 rm.Encode(5, 0));
13118         return;
13119       }
13120     }
13121   }
13122   Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
13123 }
13124 
vacgt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)13125 void Assembler::vacgt(
13126     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13127   VIXL_ASSERT(AllowAssembler());
13128   CheckIT(cond);
13129   if (IsUsingT32()) {
13130     // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13131     if (dt.Is(F32)) {
13132       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13133         EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13134                    rm.Encode(5, 0));
13135         AdvanceIT();
13136         return;
13137       }
13138     }
13139   } else {
13140     // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13141     if (dt.Is(F32)) {
13142       if (cond.Is(al)) {
13143         EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13144                 rm.Encode(5, 0));
13145         return;
13146       }
13147     }
13148   }
13149   Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
13150 }
13151 
vacle(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13152 void Assembler::vacle(
13153     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13154   VIXL_ASSERT(AllowAssembler());
13155   CheckIT(cond);
13156   if (IsUsingT32()) {
13157     // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13158     if (dt.Is(F32)) {
13159       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13160         EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13161                    rm.Encode(5, 0));
13162         AdvanceIT();
13163         return;
13164       }
13165     }
13166   } else {
13167     // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13168     if (dt.Is(F32)) {
13169       if (cond.Is(al)) {
13170         EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13171                 rm.Encode(5, 0));
13172         return;
13173       }
13174     }
13175   }
13176   Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
13177 }
13178 
vacle(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)13179 void Assembler::vacle(
13180     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13181   VIXL_ASSERT(AllowAssembler());
13182   CheckIT(cond);
13183   if (IsUsingT32()) {
13184     // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13185     if (dt.Is(F32)) {
13186       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13187         EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13188                    rm.Encode(5, 0));
13189         AdvanceIT();
13190         return;
13191       }
13192     }
13193   } else {
13194     // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13195     if (dt.Is(F32)) {
13196       if (cond.Is(al)) {
13197         EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13198                 rm.Encode(5, 0));
13199         return;
13200       }
13201     }
13202   }
13203   Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
13204 }
13205 
vaclt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13206 void Assembler::vaclt(
13207     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13208   VIXL_ASSERT(AllowAssembler());
13209   CheckIT(cond);
13210   if (IsUsingT32()) {
13211     // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13212     if (dt.Is(F32)) {
13213       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13214         EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13215                    rm.Encode(5, 0));
13216         AdvanceIT();
13217         return;
13218       }
13219     }
13220   } else {
13221     // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13222     if (dt.Is(F32)) {
13223       if (cond.Is(al)) {
13224         EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13225                 rm.Encode(5, 0));
13226         return;
13227       }
13228     }
13229   }
13230   Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
13231 }
13232 
vaclt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)13233 void Assembler::vaclt(
13234     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13235   VIXL_ASSERT(AllowAssembler());
13236   CheckIT(cond);
13237   if (IsUsingT32()) {
13238     // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13239     if (dt.Is(F32)) {
13240       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13241         EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13242                    rm.Encode(5, 0));
13243         AdvanceIT();
13244         return;
13245       }
13246     }
13247   } else {
13248     // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13249     if (dt.Is(F32)) {
13250       if (cond.Is(al)) {
13251         EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13252                 rm.Encode(5, 0));
13253         return;
13254       }
13255     }
13256   }
13257   Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
13258 }
13259 
vadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13260 void Assembler::vadd(
13261     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13262   VIXL_ASSERT(AllowAssembler());
13263   CheckIT(cond);
13264   Dt_size_2 encoded_dt(dt);
13265   if (IsUsingT32()) {
13266     // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
13267     if (dt.Is(F32)) {
13268       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13269         EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13270                    rm.Encode(5, 0));
13271         AdvanceIT();
13272         return;
13273       }
13274     }
13275     // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
13276     if (dt.Is(F64)) {
13277       EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13278                  rm.Encode(5, 0));
13279       AdvanceIT();
13280       return;
13281     }
13282     // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
13283     if (encoded_dt.IsValid()) {
13284       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13285         EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) |
13286                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13287         AdvanceIT();
13288         return;
13289       }
13290     }
13291   } else {
13292     // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
13293     if (dt.Is(F32)) {
13294       if (cond.Is(al)) {
13295         EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13296                 rm.Encode(5, 0));
13297         return;
13298       }
13299     }
13300     // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
13301     if (dt.Is(F64) && cond.IsNotNever()) {
13302       EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
13303               rn.Encode(7, 16) | rm.Encode(5, 0));
13304       return;
13305     }
13306     // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
13307     if (encoded_dt.IsValid()) {
13308       if (cond.Is(al)) {
13309         EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) |
13310                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13311         return;
13312       }
13313     }
13314   }
13315   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13316 }
13317 
vadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)13318 void Assembler::vadd(
13319     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13320   VIXL_ASSERT(AllowAssembler());
13321   CheckIT(cond);
13322   Dt_size_2 encoded_dt(dt);
13323   if (IsUsingT32()) {
13324     // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
13325     if (dt.Is(F32)) {
13326       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13327         EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13328                    rm.Encode(5, 0));
13329         AdvanceIT();
13330         return;
13331       }
13332     }
13333     // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
13334     if (encoded_dt.IsValid()) {
13335       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13336         EmitT32_32(0xef000840U | (encoded_dt.GetEncodingValue() << 20) |
13337                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13338         AdvanceIT();
13339         return;
13340       }
13341     }
13342   } else {
13343     // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
13344     if (dt.Is(F32)) {
13345       if (cond.Is(al)) {
13346         EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13347                 rm.Encode(5, 0));
13348         return;
13349       }
13350     }
13351     // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
13352     if (encoded_dt.IsValid()) {
13353       if (cond.Is(al)) {
13354         EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) |
13355                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13356         return;
13357       }
13358     }
13359   }
13360   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13361 }
13362 
vadd(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)13363 void Assembler::vadd(
13364     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
13365   VIXL_ASSERT(AllowAssembler());
13366   CheckIT(cond);
13367   if (IsUsingT32()) {
13368     // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
13369     if (dt.Is(F32)) {
13370       EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13371                  rm.Encode(5, 0));
13372       AdvanceIT();
13373       return;
13374     }
13375   } else {
13376     // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
13377     if (dt.Is(F32) && cond.IsNotNever()) {
13378       EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
13379               rn.Encode(7, 16) | rm.Encode(5, 0));
13380       return;
13381     }
13382   }
13383   Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
13384 }
13385 
vaddhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)13386 void Assembler::vaddhn(
13387     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
13388   VIXL_ASSERT(AllowAssembler());
13389   CheckIT(cond);
13390   Dt_size_3 encoded_dt(dt);
13391   if (IsUsingT32()) {
13392     // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
13393     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
13394       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13395         EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) |
13396                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13397         AdvanceIT();
13398         return;
13399       }
13400     }
13401   } else {
13402     // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
13403     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
13404       if (cond.Is(al)) {
13405         EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) |
13406                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13407         return;
13408       }
13409     }
13410   }
13411   Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm);
13412 }
13413 
vaddl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)13414 void Assembler::vaddl(
13415     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
13416   VIXL_ASSERT(AllowAssembler());
13417   CheckIT(cond);
13418   Dt_U_size_1 encoded_dt(dt);
13419   if (IsUsingT32()) {
13420     // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
13421     if (encoded_dt.IsValid()) {
13422       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13423         EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13424                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13425                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13426         AdvanceIT();
13427         return;
13428       }
13429     }
13430   } else {
13431     // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
13432     if (encoded_dt.IsValid()) {
13433       if (cond.Is(al)) {
13434         EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13435                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13436                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13437         return;
13438       }
13439     }
13440   }
13441   Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm);
13442 }
13443 
vaddw(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegister rm)13444 void Assembler::vaddw(
13445     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
13446   VIXL_ASSERT(AllowAssembler());
13447   CheckIT(cond);
13448   Dt_U_size_1 encoded_dt(dt);
13449   if (IsUsingT32()) {
13450     // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
13451     if (encoded_dt.IsValid()) {
13452       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13453         EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13454                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13455                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13456         AdvanceIT();
13457         return;
13458       }
13459     }
13460   } else {
13461     // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
13462     if (encoded_dt.IsValid()) {
13463       if (cond.Is(al)) {
13464         EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13465                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13466                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13467         return;
13468       }
13469     }
13470   }
13471   Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm);
13472 }
13473 
vand(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)13474 void Assembler::vand(Condition cond,
13475                      DataType dt,
13476                      DRegister rd,
13477                      DRegister rn,
13478                      const DOperand& operand) {
13479   VIXL_ASSERT(AllowAssembler());
13480   CheckIT(cond);
13481   if (operand.IsImmediate()) {
13482     ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
13483     if (IsUsingT32()) {
13484       // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
13485       if (encoded_dt.IsValid() && rd.Is(rn)) {
13486         if (cond.Is(al) || AllowStronglyDiscouraged()) {
13487           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
13488                      rd.Encode(22, 12) |
13489                      (encoded_dt.GetEncodedImmediate() & 0xf) |
13490                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13491                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13492           AdvanceIT();
13493           return;
13494         }
13495       }
13496     } else {
13497       // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
13498       if (encoded_dt.IsValid() && rd.Is(rn)) {
13499         if (cond.Is(al)) {
13500           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
13501                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13502                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13503                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13504           return;
13505         }
13506       }
13507     }
13508   }
13509   if (operand.IsRegister()) {
13510     DRegister rm = operand.GetRegister();
13511     USE(dt);
13512     if (IsUsingT32()) {
13513       // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13514       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13515         EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13516                    rm.Encode(5, 0));
13517         AdvanceIT();
13518         return;
13519       }
13520     } else {
13521       // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13522       if (cond.Is(al)) {
13523         EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13524                 rm.Encode(5, 0));
13525         return;
13526       }
13527     }
13528   }
13529   Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
13530 }
13531 
vand(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)13532 void Assembler::vand(Condition cond,
13533                      DataType dt,
13534                      QRegister rd,
13535                      QRegister rn,
13536                      const QOperand& operand) {
13537   VIXL_ASSERT(AllowAssembler());
13538   CheckIT(cond);
13539   if (operand.IsImmediate()) {
13540     ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
13541     if (IsUsingT32()) {
13542       // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
13543       if (encoded_dt.IsValid() && rd.Is(rn)) {
13544         if (cond.Is(al) || AllowStronglyDiscouraged()) {
13545           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
13546                      rd.Encode(22, 12) |
13547                      (encoded_dt.GetEncodedImmediate() & 0xf) |
13548                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13549                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13550           AdvanceIT();
13551           return;
13552         }
13553       }
13554     } else {
13555       // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
13556       if (encoded_dt.IsValid() && rd.Is(rn)) {
13557         if (cond.Is(al)) {
13558           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
13559                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13560                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13561                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13562           return;
13563         }
13564       }
13565     }
13566   }
13567   if (operand.IsRegister()) {
13568     QRegister rm = operand.GetRegister();
13569     USE(dt);
13570     if (IsUsingT32()) {
13571       // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13572       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13573         EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13574                    rm.Encode(5, 0));
13575         AdvanceIT();
13576         return;
13577       }
13578     } else {
13579       // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13580       if (cond.Is(al)) {
13581         EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13582                 rm.Encode(5, 0));
13583         return;
13584       }
13585     }
13586   }
13587   Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
13588 }
13589 
vbic(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)13590 void Assembler::vbic(Condition cond,
13591                      DataType dt,
13592                      DRegister rd,
13593                      DRegister rn,
13594                      const DOperand& operand) {
13595   VIXL_ASSERT(AllowAssembler());
13596   CheckIT(cond);
13597   if (operand.IsImmediate()) {
13598     ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
13599     if (IsUsingT32()) {
13600       // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
13601       if (encoded_dt.IsValid() && rd.Is(rn)) {
13602         if (cond.Is(al) || AllowStronglyDiscouraged()) {
13603           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
13604                      rd.Encode(22, 12) |
13605                      (encoded_dt.GetEncodedImmediate() & 0xf) |
13606                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13607                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13608           AdvanceIT();
13609           return;
13610         }
13611       }
13612     } else {
13613       // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
13614       if (encoded_dt.IsValid() && rd.Is(rn)) {
13615         if (cond.Is(al)) {
13616           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
13617                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13618                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13619                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13620           return;
13621         }
13622       }
13623     }
13624   }
13625   if (operand.IsRegister()) {
13626     DRegister rm = operand.GetRegister();
13627     USE(dt);
13628     if (IsUsingT32()) {
13629       // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13630       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13631         EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13632                    rm.Encode(5, 0));
13633         AdvanceIT();
13634         return;
13635       }
13636     } else {
13637       // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13638       if (cond.Is(al)) {
13639         EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13640                 rm.Encode(5, 0));
13641         return;
13642       }
13643     }
13644   }
13645   Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
13646 }
13647 
vbic(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)13648 void Assembler::vbic(Condition cond,
13649                      DataType dt,
13650                      QRegister rd,
13651                      QRegister rn,
13652                      const QOperand& operand) {
13653   VIXL_ASSERT(AllowAssembler());
13654   CheckIT(cond);
13655   if (operand.IsImmediate()) {
13656     ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
13657     if (IsUsingT32()) {
13658       // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
13659       if (encoded_dt.IsValid() && rd.Is(rn)) {
13660         if (cond.Is(al) || AllowStronglyDiscouraged()) {
13661           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
13662                      rd.Encode(22, 12) |
13663                      (encoded_dt.GetEncodedImmediate() & 0xf) |
13664                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13665                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
13666           AdvanceIT();
13667           return;
13668         }
13669       }
13670     } else {
13671       // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
13672       if (encoded_dt.IsValid() && rd.Is(rn)) {
13673         if (cond.Is(al)) {
13674           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
13675                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
13676                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
13677                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
13678           return;
13679         }
13680       }
13681     }
13682   }
13683   if (operand.IsRegister()) {
13684     QRegister rm = operand.GetRegister();
13685     USE(dt);
13686     if (IsUsingT32()) {
13687       // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13688       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13689         EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13690                    rm.Encode(5, 0));
13691         AdvanceIT();
13692         return;
13693       }
13694     } else {
13695       // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13696       if (cond.Is(al)) {
13697         EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13698                 rm.Encode(5, 0));
13699         return;
13700       }
13701     }
13702   }
13703   Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
13704 }
13705 
vbif(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13706 void Assembler::vbif(
13707     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13708   VIXL_ASSERT(AllowAssembler());
13709   CheckIT(cond);
13710   USE(dt);
13711   if (IsUsingT32()) {
13712     // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13713     if (cond.Is(al) || AllowStronglyDiscouraged()) {
13714       EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13715                  rm.Encode(5, 0));
13716       AdvanceIT();
13717       return;
13718     }
13719   } else {
13720     // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13721     if (cond.Is(al)) {
13722       EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13723               rm.Encode(5, 0));
13724       return;
13725     }
13726   }
13727   Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
13728 }
13729 
vbif(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)13730 void Assembler::vbif(
13731     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13732   VIXL_ASSERT(AllowAssembler());
13733   CheckIT(cond);
13734   USE(dt);
13735   if (IsUsingT32()) {
13736     // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13737     if (cond.Is(al) || AllowStronglyDiscouraged()) {
13738       EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13739                  rm.Encode(5, 0));
13740       AdvanceIT();
13741       return;
13742     }
13743   } else {
13744     // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13745     if (cond.Is(al)) {
13746       EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13747               rm.Encode(5, 0));
13748       return;
13749     }
13750   }
13751   Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
13752 }
13753 
vbit(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13754 void Assembler::vbit(
13755     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13756   VIXL_ASSERT(AllowAssembler());
13757   CheckIT(cond);
13758   USE(dt);
13759   if (IsUsingT32()) {
13760     // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13761     if (cond.Is(al) || AllowStronglyDiscouraged()) {
13762       EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13763                  rm.Encode(5, 0));
13764       AdvanceIT();
13765       return;
13766     }
13767   } else {
13768     // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13769     if (cond.Is(al)) {
13770       EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13771               rm.Encode(5, 0));
13772       return;
13773     }
13774   }
13775   Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
13776 }
13777 
vbit(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)13778 void Assembler::vbit(
13779     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13780   VIXL_ASSERT(AllowAssembler());
13781   CheckIT(cond);
13782   USE(dt);
13783   if (IsUsingT32()) {
13784     // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13785     if (cond.Is(al) || AllowStronglyDiscouraged()) {
13786       EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13787                  rm.Encode(5, 0));
13788       AdvanceIT();
13789       return;
13790     }
13791   } else {
13792     // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13793     if (cond.Is(al)) {
13794       EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13795               rm.Encode(5, 0));
13796       return;
13797     }
13798   }
13799   Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
13800 }
13801 
vbsl(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13802 void Assembler::vbsl(
13803     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13804   VIXL_ASSERT(AllowAssembler());
13805   CheckIT(cond);
13806   USE(dt);
13807   if (IsUsingT32()) {
13808     // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
13809     if (cond.Is(al) || AllowStronglyDiscouraged()) {
13810       EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13811                  rm.Encode(5, 0));
13812       AdvanceIT();
13813       return;
13814     }
13815   } else {
13816     // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
13817     if (cond.Is(al)) {
13818       EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13819               rm.Encode(5, 0));
13820       return;
13821     }
13822   }
13823   Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
13824 }
13825 
vbsl(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)13826 void Assembler::vbsl(
13827     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13828   VIXL_ASSERT(AllowAssembler());
13829   CheckIT(cond);
13830   USE(dt);
13831   if (IsUsingT32()) {
13832     // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
13833     if (cond.Is(al) || AllowStronglyDiscouraged()) {
13834       EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13835                  rm.Encode(5, 0));
13836       AdvanceIT();
13837       return;
13838     }
13839   } else {
13840     // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
13841     if (cond.Is(al)) {
13842       EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
13843               rm.Encode(5, 0));
13844       return;
13845     }
13846   }
13847   Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
13848 }
13849 
vceq(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)13850 void Assembler::vceq(Condition cond,
13851                      DataType dt,
13852                      DRegister rd,
13853                      DRegister rm,
13854                      const DOperand& operand) {
13855   VIXL_ASSERT(AllowAssembler());
13856   CheckIT(cond);
13857   if (operand.IsImmediate()) {
13858     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13859       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13860       Dt_F_size_2 encoded_dt(dt);
13861       if (IsUsingT32()) {
13862         // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
13863         if (encoded_dt.IsValid() && (imm == 0)) {
13864           if (cond.Is(al) || AllowStronglyDiscouraged()) {
13865             EmitT32_32(0xffb10100U |
13866                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13867                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13868                        rd.Encode(22, 12) | rm.Encode(5, 0));
13869             AdvanceIT();
13870             return;
13871           }
13872         }
13873       } else {
13874         // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
13875         if (encoded_dt.IsValid() && (imm == 0)) {
13876           if (cond.Is(al)) {
13877             EmitA32(0xf3b10100U |
13878                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13879                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13880                     rd.Encode(22, 12) | rm.Encode(5, 0));
13881             return;
13882           }
13883         }
13884       }
13885     }
13886   }
13887   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
13888 }
13889 
vceq(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)13890 void Assembler::vceq(Condition cond,
13891                      DataType dt,
13892                      QRegister rd,
13893                      QRegister rm,
13894                      const QOperand& operand) {
13895   VIXL_ASSERT(AllowAssembler());
13896   CheckIT(cond);
13897   if (operand.IsImmediate()) {
13898     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
13899       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
13900       Dt_F_size_2 encoded_dt(dt);
13901       if (IsUsingT32()) {
13902         // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
13903         if (encoded_dt.IsValid() && (imm == 0)) {
13904           if (cond.Is(al) || AllowStronglyDiscouraged()) {
13905             EmitT32_32(0xffb10140U |
13906                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13907                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13908                        rd.Encode(22, 12) | rm.Encode(5, 0));
13909             AdvanceIT();
13910             return;
13911           }
13912         }
13913       } else {
13914         // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
13915         if (encoded_dt.IsValid() && (imm == 0)) {
13916           if (cond.Is(al)) {
13917             EmitA32(0xf3b10140U |
13918                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
13919                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
13920                     rd.Encode(22, 12) | rm.Encode(5, 0));
13921             return;
13922           }
13923         }
13924       }
13925     }
13926   }
13927   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
13928 }
13929 
vceq(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13930 void Assembler::vceq(
13931     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13932   VIXL_ASSERT(AllowAssembler());
13933   CheckIT(cond);
13934   Dt_size_4 encoded_dt(dt);
13935   Dt_sz_1 encoded_dt_2(dt);
13936   if (IsUsingT32()) {
13937     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
13938     if (encoded_dt.IsValid()) {
13939       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13940         EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) |
13941                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13942         AdvanceIT();
13943         return;
13944       }
13945     }
13946     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2
13947     if (encoded_dt_2.IsValid()) {
13948       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13949         EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
13950                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13951         AdvanceIT();
13952         return;
13953       }
13954     }
13955   } else {
13956     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
13957     if (encoded_dt.IsValid()) {
13958       if (cond.Is(al)) {
13959         EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) |
13960                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13961         return;
13962       }
13963     }
13964     // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2
13965     if (encoded_dt_2.IsValid()) {
13966       if (cond.Is(al)) {
13967         EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
13968                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13969         return;
13970       }
13971     }
13972   }
13973   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
13974 }
13975 
vceq(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)13976 void Assembler::vceq(
13977     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13978   VIXL_ASSERT(AllowAssembler());
13979   CheckIT(cond);
13980   Dt_size_4 encoded_dt(dt);
13981   Dt_sz_1 encoded_dt_2(dt);
13982   if (IsUsingT32()) {
13983     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
13984     if (encoded_dt.IsValid()) {
13985       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13986         EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) |
13987                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13988         AdvanceIT();
13989         return;
13990       }
13991     }
13992     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2
13993     if (encoded_dt_2.IsValid()) {
13994       if (cond.Is(al) || AllowStronglyDiscouraged()) {
13995         EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
13996                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13997         AdvanceIT();
13998         return;
13999       }
14000     }
14001   } else {
14002     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14003     if (encoded_dt.IsValid()) {
14004       if (cond.Is(al)) {
14005         EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) |
14006                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14007         return;
14008       }
14009     }
14010     // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2
14011     if (encoded_dt_2.IsValid()) {
14012       if (cond.Is(al)) {
14013         EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
14014                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14015         return;
14016       }
14017     }
14018   }
14019   Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
14020 }
14021 
vcge(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)14022 void Assembler::vcge(Condition cond,
14023                      DataType dt,
14024                      DRegister rd,
14025                      DRegister rm,
14026                      const DOperand& operand) {
14027   VIXL_ASSERT(AllowAssembler());
14028   CheckIT(cond);
14029   if (operand.IsImmediate()) {
14030     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14031       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14032       Dt_F_size_1 encoded_dt(dt);
14033       if (IsUsingT32()) {
14034         // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14035         if (encoded_dt.IsValid() && (imm == 0)) {
14036           if (cond.Is(al) || AllowStronglyDiscouraged()) {
14037             EmitT32_32(0xffb10080U |
14038                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14039                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14040                        rd.Encode(22, 12) | rm.Encode(5, 0));
14041             AdvanceIT();
14042             return;
14043           }
14044         }
14045       } else {
14046         // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14047         if (encoded_dt.IsValid() && (imm == 0)) {
14048           if (cond.Is(al)) {
14049             EmitA32(0xf3b10080U |
14050                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14051                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14052                     rd.Encode(22, 12) | rm.Encode(5, 0));
14053             return;
14054           }
14055         }
14056       }
14057     }
14058   }
14059   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
14060 }
14061 
vcge(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)14062 void Assembler::vcge(Condition cond,
14063                      DataType dt,
14064                      QRegister rd,
14065                      QRegister rm,
14066                      const QOperand& operand) {
14067   VIXL_ASSERT(AllowAssembler());
14068   CheckIT(cond);
14069   if (operand.IsImmediate()) {
14070     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14071       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14072       Dt_F_size_1 encoded_dt(dt);
14073       if (IsUsingT32()) {
14074         // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14075         if (encoded_dt.IsValid() && (imm == 0)) {
14076           if (cond.Is(al) || AllowStronglyDiscouraged()) {
14077             EmitT32_32(0xffb100c0U |
14078                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14079                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14080                        rd.Encode(22, 12) | rm.Encode(5, 0));
14081             AdvanceIT();
14082             return;
14083           }
14084         }
14085       } else {
14086         // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14087         if (encoded_dt.IsValid() && (imm == 0)) {
14088           if (cond.Is(al)) {
14089             EmitA32(0xf3b100c0U |
14090                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14091                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14092                     rd.Encode(22, 12) | rm.Encode(5, 0));
14093             return;
14094           }
14095         }
14096       }
14097     }
14098   }
14099   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
14100 }
14101 
vcge(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14102 void Assembler::vcge(
14103     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14104   VIXL_ASSERT(AllowAssembler());
14105   CheckIT(cond);
14106   Dt_U_size_1 encoded_dt(dt);
14107   if (IsUsingT32()) {
14108     // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14109     if (encoded_dt.IsValid()) {
14110       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14111         EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14112                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14113                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14114         AdvanceIT();
14115         return;
14116       }
14117     }
14118     // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14119     if (dt.Is(F32)) {
14120       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14121         EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14122                    rm.Encode(5, 0));
14123         AdvanceIT();
14124         return;
14125       }
14126     }
14127   } else {
14128     // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14129     if (encoded_dt.IsValid()) {
14130       if (cond.Is(al)) {
14131         EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14132                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14133                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14134         return;
14135       }
14136     }
14137     // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14138     if (dt.Is(F32)) {
14139       if (cond.Is(al)) {
14140         EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14141                 rm.Encode(5, 0));
14142         return;
14143       }
14144     }
14145   }
14146   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
14147 }
14148 
vcge(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14149 void Assembler::vcge(
14150     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14151   VIXL_ASSERT(AllowAssembler());
14152   CheckIT(cond);
14153   Dt_U_size_1 encoded_dt(dt);
14154   if (IsUsingT32()) {
14155     // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14156     if (encoded_dt.IsValid()) {
14157       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14158         EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14159                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14160                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14161         AdvanceIT();
14162         return;
14163       }
14164     }
14165     // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14166     if (dt.Is(F32)) {
14167       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14168         EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14169                    rm.Encode(5, 0));
14170         AdvanceIT();
14171         return;
14172       }
14173     }
14174   } else {
14175     // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14176     if (encoded_dt.IsValid()) {
14177       if (cond.Is(al)) {
14178         EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14179                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14180                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14181         return;
14182       }
14183     }
14184     // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14185     if (dt.Is(F32)) {
14186       if (cond.Is(al)) {
14187         EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14188                 rm.Encode(5, 0));
14189         return;
14190       }
14191     }
14192   }
14193   Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
14194 }
14195 
vcgt(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)14196 void Assembler::vcgt(Condition cond,
14197                      DataType dt,
14198                      DRegister rd,
14199                      DRegister rm,
14200                      const DOperand& operand) {
14201   VIXL_ASSERT(AllowAssembler());
14202   CheckIT(cond);
14203   if (operand.IsImmediate()) {
14204     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14205       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14206       Dt_F_size_1 encoded_dt(dt);
14207       if (IsUsingT32()) {
14208         // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14209         if (encoded_dt.IsValid() && (imm == 0)) {
14210           if (cond.Is(al) || AllowStronglyDiscouraged()) {
14211             EmitT32_32(0xffb10000U |
14212                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14213                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14214                        rd.Encode(22, 12) | rm.Encode(5, 0));
14215             AdvanceIT();
14216             return;
14217           }
14218         }
14219       } else {
14220         // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14221         if (encoded_dt.IsValid() && (imm == 0)) {
14222           if (cond.Is(al)) {
14223             EmitA32(0xf3b10000U |
14224                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14225                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14226                     rd.Encode(22, 12) | rm.Encode(5, 0));
14227             return;
14228           }
14229         }
14230       }
14231     }
14232   }
14233   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
14234 }
14235 
vcgt(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)14236 void Assembler::vcgt(Condition cond,
14237                      DataType dt,
14238                      QRegister rd,
14239                      QRegister rm,
14240                      const QOperand& operand) {
14241   VIXL_ASSERT(AllowAssembler());
14242   CheckIT(cond);
14243   if (operand.IsImmediate()) {
14244     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14245       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14246       Dt_F_size_1 encoded_dt(dt);
14247       if (IsUsingT32()) {
14248         // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14249         if (encoded_dt.IsValid() && (imm == 0)) {
14250           if (cond.Is(al) || AllowStronglyDiscouraged()) {
14251             EmitT32_32(0xffb10040U |
14252                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14253                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14254                        rd.Encode(22, 12) | rm.Encode(5, 0));
14255             AdvanceIT();
14256             return;
14257           }
14258         }
14259       } else {
14260         // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14261         if (encoded_dt.IsValid() && (imm == 0)) {
14262           if (cond.Is(al)) {
14263             EmitA32(0xf3b10040U |
14264                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14265                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14266                     rd.Encode(22, 12) | rm.Encode(5, 0));
14267             return;
14268           }
14269         }
14270       }
14271     }
14272   }
14273   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
14274 }
14275 
vcgt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14276 void Assembler::vcgt(
14277     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14278   VIXL_ASSERT(AllowAssembler());
14279   CheckIT(cond);
14280   Dt_U_size_1 encoded_dt(dt);
14281   if (IsUsingT32()) {
14282     // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14283     if (encoded_dt.IsValid()) {
14284       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14285         EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14286                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14287                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14288         AdvanceIT();
14289         return;
14290       }
14291     }
14292     // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14293     if (dt.Is(F32)) {
14294       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14295         EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14296                    rm.Encode(5, 0));
14297         AdvanceIT();
14298         return;
14299       }
14300     }
14301   } else {
14302     // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14303     if (encoded_dt.IsValid()) {
14304       if (cond.Is(al)) {
14305         EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14306                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14307                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14308         return;
14309       }
14310     }
14311     // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14312     if (dt.Is(F32)) {
14313       if (cond.Is(al)) {
14314         EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14315                 rm.Encode(5, 0));
14316         return;
14317       }
14318     }
14319   }
14320   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
14321 }
14322 
vcgt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14323 void Assembler::vcgt(
14324     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14325   VIXL_ASSERT(AllowAssembler());
14326   CheckIT(cond);
14327   Dt_U_size_1 encoded_dt(dt);
14328   if (IsUsingT32()) {
14329     // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14330     if (encoded_dt.IsValid()) {
14331       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14332         EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14333                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14334                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14335         AdvanceIT();
14336         return;
14337       }
14338     }
14339     // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14340     if (dt.Is(F32)) {
14341       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14342         EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14343                    rm.Encode(5, 0));
14344         AdvanceIT();
14345         return;
14346       }
14347     }
14348   } else {
14349     // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14350     if (encoded_dt.IsValid()) {
14351       if (cond.Is(al)) {
14352         EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14353                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14354                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14355         return;
14356       }
14357     }
14358     // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14359     if (dt.Is(F32)) {
14360       if (cond.Is(al)) {
14361         EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14362                 rm.Encode(5, 0));
14363         return;
14364       }
14365     }
14366   }
14367   Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
14368 }
14369 
vcle(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)14370 void Assembler::vcle(Condition cond,
14371                      DataType dt,
14372                      DRegister rd,
14373                      DRegister rm,
14374                      const DOperand& operand) {
14375   VIXL_ASSERT(AllowAssembler());
14376   CheckIT(cond);
14377   if (operand.IsImmediate()) {
14378     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14379       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14380       Dt_F_size_1 encoded_dt(dt);
14381       if (IsUsingT32()) {
14382         // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14383         if (encoded_dt.IsValid() && (imm == 0)) {
14384           if (cond.Is(al) || AllowStronglyDiscouraged()) {
14385             EmitT32_32(0xffb10180U |
14386                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14387                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14388                        rd.Encode(22, 12) | rm.Encode(5, 0));
14389             AdvanceIT();
14390             return;
14391           }
14392         }
14393       } else {
14394         // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14395         if (encoded_dt.IsValid() && (imm == 0)) {
14396           if (cond.Is(al)) {
14397             EmitA32(0xf3b10180U |
14398                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14399                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14400                     rd.Encode(22, 12) | rm.Encode(5, 0));
14401             return;
14402           }
14403         }
14404       }
14405     }
14406   }
14407   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
14408 }
14409 
vcle(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)14410 void Assembler::vcle(Condition cond,
14411                      DataType dt,
14412                      QRegister rd,
14413                      QRegister rm,
14414                      const QOperand& operand) {
14415   VIXL_ASSERT(AllowAssembler());
14416   CheckIT(cond);
14417   if (operand.IsImmediate()) {
14418     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14419       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14420       Dt_F_size_1 encoded_dt(dt);
14421       if (IsUsingT32()) {
14422         // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14423         if (encoded_dt.IsValid() && (imm == 0)) {
14424           if (cond.Is(al) || AllowStronglyDiscouraged()) {
14425             EmitT32_32(0xffb101c0U |
14426                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14427                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14428                        rd.Encode(22, 12) | rm.Encode(5, 0));
14429             AdvanceIT();
14430             return;
14431           }
14432         }
14433       } else {
14434         // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14435         if (encoded_dt.IsValid() && (imm == 0)) {
14436           if (cond.Is(al)) {
14437             EmitA32(0xf3b101c0U |
14438                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14439                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14440                     rd.Encode(22, 12) | rm.Encode(5, 0));
14441             return;
14442           }
14443         }
14444       }
14445     }
14446   }
14447   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
14448 }
14449 
vcle(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14450 void Assembler::vcle(
14451     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14452   VIXL_ASSERT(AllowAssembler());
14453   CheckIT(cond);
14454   Dt_U_size_1 encoded_dt(dt);
14455   if (IsUsingT32()) {
14456     // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14457     if (encoded_dt.IsValid()) {
14458       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14459         EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14460                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14461                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14462         AdvanceIT();
14463         return;
14464       }
14465     }
14466     // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14467     if (dt.Is(F32)) {
14468       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14469         EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14470                    rm.Encode(7, 16));
14471         AdvanceIT();
14472         return;
14473       }
14474     }
14475   } else {
14476     // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14477     if (encoded_dt.IsValid()) {
14478       if (cond.Is(al)) {
14479         EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14480                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14481                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14482         return;
14483       }
14484     }
14485     // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14486     if (dt.Is(F32)) {
14487       if (cond.Is(al)) {
14488         EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14489                 rm.Encode(7, 16));
14490         return;
14491       }
14492     }
14493   }
14494   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
14495 }
14496 
vcle(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14497 void Assembler::vcle(
14498     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14499   VIXL_ASSERT(AllowAssembler());
14500   CheckIT(cond);
14501   Dt_U_size_1 encoded_dt(dt);
14502   if (IsUsingT32()) {
14503     // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14504     if (encoded_dt.IsValid()) {
14505       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14506         EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14507                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14508                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14509         AdvanceIT();
14510         return;
14511       }
14512     }
14513     // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14514     if (dt.Is(F32)) {
14515       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14516         EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14517                    rm.Encode(7, 16));
14518         AdvanceIT();
14519         return;
14520       }
14521     }
14522   } else {
14523     // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14524     if (encoded_dt.IsValid()) {
14525       if (cond.Is(al)) {
14526         EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14527                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14528                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14529         return;
14530       }
14531     }
14532     // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14533     if (dt.Is(F32)) {
14534       if (cond.Is(al)) {
14535         EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14536                 rm.Encode(7, 16));
14537         return;
14538       }
14539     }
14540   }
14541   Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
14542 }
14543 
vcls(Condition cond,DataType dt,DRegister rd,DRegister rm)14544 void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14545   VIXL_ASSERT(AllowAssembler());
14546   CheckIT(cond);
14547   Dt_size_5 encoded_dt(dt);
14548   if (IsUsingT32()) {
14549     // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
14550     if (encoded_dt.IsValid()) {
14551       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14552         EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) |
14553                    rd.Encode(22, 12) | rm.Encode(5, 0));
14554         AdvanceIT();
14555         return;
14556       }
14557     }
14558   } else {
14559     // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
14560     if (encoded_dt.IsValid()) {
14561       if (cond.Is(al)) {
14562         EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) |
14563                 rd.Encode(22, 12) | rm.Encode(5, 0));
14564         return;
14565       }
14566     }
14567   }
14568   Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
14569 }
14570 
vcls(Condition cond,DataType dt,QRegister rd,QRegister rm)14571 void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14572   VIXL_ASSERT(AllowAssembler());
14573   CheckIT(cond);
14574   Dt_size_5 encoded_dt(dt);
14575   if (IsUsingT32()) {
14576     // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
14577     if (encoded_dt.IsValid()) {
14578       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14579         EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) |
14580                    rd.Encode(22, 12) | rm.Encode(5, 0));
14581         AdvanceIT();
14582         return;
14583       }
14584     }
14585   } else {
14586     // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
14587     if (encoded_dt.IsValid()) {
14588       if (cond.Is(al)) {
14589         EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) |
14590                 rd.Encode(22, 12) | rm.Encode(5, 0));
14591         return;
14592       }
14593     }
14594   }
14595   Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
14596 }
14597 
vclt(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)14598 void Assembler::vclt(Condition cond,
14599                      DataType dt,
14600                      DRegister rd,
14601                      DRegister rm,
14602                      const DOperand& operand) {
14603   VIXL_ASSERT(AllowAssembler());
14604   CheckIT(cond);
14605   if (operand.IsImmediate()) {
14606     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14607       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14608       Dt_F_size_1 encoded_dt(dt);
14609       if (IsUsingT32()) {
14610         // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
14611         if (encoded_dt.IsValid() && (imm == 0)) {
14612           if (cond.Is(al) || AllowStronglyDiscouraged()) {
14613             EmitT32_32(0xffb10200U |
14614                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14615                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14616                        rd.Encode(22, 12) | rm.Encode(5, 0));
14617             AdvanceIT();
14618             return;
14619           }
14620         }
14621       } else {
14622         // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
14623         if (encoded_dt.IsValid() && (imm == 0)) {
14624           if (cond.Is(al)) {
14625             EmitA32(0xf3b10200U |
14626                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14627                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14628                     rd.Encode(22, 12) | rm.Encode(5, 0));
14629             return;
14630           }
14631         }
14632       }
14633     }
14634   }
14635   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
14636 }
14637 
vclt(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)14638 void Assembler::vclt(Condition cond,
14639                      DataType dt,
14640                      QRegister rd,
14641                      QRegister rm,
14642                      const QOperand& operand) {
14643   VIXL_ASSERT(AllowAssembler());
14644   CheckIT(cond);
14645   if (operand.IsImmediate()) {
14646     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
14647       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
14648       Dt_F_size_1 encoded_dt(dt);
14649       if (IsUsingT32()) {
14650         // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
14651         if (encoded_dt.IsValid() && (imm == 0)) {
14652           if (cond.Is(al) || AllowStronglyDiscouraged()) {
14653             EmitT32_32(0xffb10240U |
14654                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14655                        ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14656                        rd.Encode(22, 12) | rm.Encode(5, 0));
14657             AdvanceIT();
14658             return;
14659           }
14660         }
14661       } else {
14662         // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
14663         if (encoded_dt.IsValid() && (imm == 0)) {
14664           if (cond.Is(al)) {
14665             EmitA32(0xf3b10240U |
14666                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14667                     ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14668                     rd.Encode(22, 12) | rm.Encode(5, 0));
14669             return;
14670           }
14671         }
14672       }
14673     }
14674   }
14675   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
14676 }
14677 
vclt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14678 void Assembler::vclt(
14679     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14680   VIXL_ASSERT(AllowAssembler());
14681   CheckIT(cond);
14682   Dt_U_size_1 encoded_dt(dt);
14683   if (IsUsingT32()) {
14684     // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14685     if (encoded_dt.IsValid()) {
14686       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14687         EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14688                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14689                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14690         AdvanceIT();
14691         return;
14692       }
14693     }
14694     // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
14695     if (dt.Is(F32)) {
14696       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14697         EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14698                    rm.Encode(7, 16));
14699         AdvanceIT();
14700         return;
14701       }
14702     }
14703   } else {
14704     // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14705     if (encoded_dt.IsValid()) {
14706       if (cond.Is(al)) {
14707         EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14708                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14709                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14710         return;
14711       }
14712     }
14713     // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
14714     if (dt.Is(F32)) {
14715       if (cond.Is(al)) {
14716         EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14717                 rm.Encode(7, 16));
14718         return;
14719       }
14720     }
14721   }
14722   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
14723 }
14724 
vclt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14725 void Assembler::vclt(
14726     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14727   VIXL_ASSERT(AllowAssembler());
14728   CheckIT(cond);
14729   Dt_U_size_1 encoded_dt(dt);
14730   if (IsUsingT32()) {
14731     // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14732     if (encoded_dt.IsValid()) {
14733       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14734         EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14735                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14736                    rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14737         AdvanceIT();
14738         return;
14739       }
14740     }
14741     // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
14742     if (dt.Is(F32)) {
14743       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14744         EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14745                    rm.Encode(7, 16));
14746         AdvanceIT();
14747         return;
14748       }
14749     }
14750   } else {
14751     // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14752     if (encoded_dt.IsValid()) {
14753       if (cond.Is(al)) {
14754         EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14755                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14756                 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
14757         return;
14758       }
14759     }
14760     // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
14761     if (dt.Is(F32)) {
14762       if (cond.Is(al)) {
14763         EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
14764                 rm.Encode(7, 16));
14765         return;
14766       }
14767     }
14768   }
14769   Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
14770 }
14771 
vclz(Condition cond,DataType dt,DRegister rd,DRegister rm)14772 void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14773   VIXL_ASSERT(AllowAssembler());
14774   CheckIT(cond);
14775   Dt_size_4 encoded_dt(dt);
14776   if (IsUsingT32()) {
14777     // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
14778     if (encoded_dt.IsValid()) {
14779       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14780         EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) |
14781                    rd.Encode(22, 12) | rm.Encode(5, 0));
14782         AdvanceIT();
14783         return;
14784       }
14785     }
14786   } else {
14787     // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
14788     if (encoded_dt.IsValid()) {
14789       if (cond.Is(al)) {
14790         EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) |
14791                 rd.Encode(22, 12) | rm.Encode(5, 0));
14792         return;
14793       }
14794     }
14795   }
14796   Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
14797 }
14798 
vclz(Condition cond,DataType dt,QRegister rd,QRegister rm)14799 void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14800   VIXL_ASSERT(AllowAssembler());
14801   CheckIT(cond);
14802   Dt_size_4 encoded_dt(dt);
14803   if (IsUsingT32()) {
14804     // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
14805     if (encoded_dt.IsValid()) {
14806       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14807         EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) |
14808                    rd.Encode(22, 12) | rm.Encode(5, 0));
14809         AdvanceIT();
14810         return;
14811       }
14812     }
14813   } else {
14814     // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
14815     if (encoded_dt.IsValid()) {
14816       if (cond.Is(al)) {
14817         EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) |
14818                 rd.Encode(22, 12) | rm.Encode(5, 0));
14819         return;
14820       }
14821     }
14822   }
14823   Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
14824 }
14825 
vcmp(Condition cond,DataType dt,SRegister rd,SRegister rm)14826 void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, SRegister rm) {
14827   VIXL_ASSERT(AllowAssembler());
14828   CheckIT(cond);
14829   if (IsUsingT32()) {
14830     // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
14831     if (dt.Is(F32)) {
14832       EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
14833       AdvanceIT();
14834       return;
14835     }
14836   } else {
14837     // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
14838     if (dt.Is(F32) && cond.IsNotNever()) {
14839       EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14840               rm.Encode(5, 0));
14841       return;
14842     }
14843   }
14844   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm);
14845 }
14846 
vcmp(Condition cond,DataType dt,DRegister rd,DRegister rm)14847 void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14848   VIXL_ASSERT(AllowAssembler());
14849   CheckIT(cond);
14850   if (IsUsingT32()) {
14851     // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
14852     if (dt.Is(F64)) {
14853       EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
14854       AdvanceIT();
14855       return;
14856     }
14857   } else {
14858     // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
14859     if (dt.Is(F64) && cond.IsNotNever()) {
14860       EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14861               rm.Encode(5, 0));
14862       return;
14863     }
14864   }
14865   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, rm);
14866 }
14867 
vcmp(Condition cond,DataType dt,SRegister rd,double imm)14868 void Assembler::vcmp(Condition cond, DataType dt, SRegister rd, double imm) {
14869   VIXL_ASSERT(AllowAssembler());
14870   CheckIT(cond);
14871   if (IsUsingT32()) {
14872     // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
14873     if (dt.Is(F32) && (imm == 0.0)) {
14874       EmitT32_32(0xeeb50a40U | rd.Encode(22, 12));
14875       AdvanceIT();
14876       return;
14877     }
14878   } else {
14879     // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
14880     if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) {
14881       EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14882       return;
14883     }
14884   }
14885   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm);
14886 }
14887 
vcmp(Condition cond,DataType dt,DRegister rd,double imm)14888 void Assembler::vcmp(Condition cond, DataType dt, DRegister rd, double imm) {
14889   VIXL_ASSERT(AllowAssembler());
14890   CheckIT(cond);
14891   if (IsUsingT32()) {
14892     // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
14893     if (dt.Is(F64) && (imm == 0.0)) {
14894       EmitT32_32(0xeeb50b40U | rd.Encode(22, 12));
14895       AdvanceIT();
14896       return;
14897     }
14898   } else {
14899     // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
14900     if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) {
14901       EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14902       return;
14903     }
14904   }
14905   Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, imm);
14906 }
14907 
vcmpe(Condition cond,DataType dt,SRegister rd,SRegister rm)14908 void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, SRegister rm) {
14909   VIXL_ASSERT(AllowAssembler());
14910   CheckIT(cond);
14911   if (IsUsingT32()) {
14912     // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
14913     if (dt.Is(F32)) {
14914       EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14915       AdvanceIT();
14916       return;
14917     }
14918   } else {
14919     // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
14920     if (dt.Is(F32) && cond.IsNotNever()) {
14921       EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14922               rm.Encode(5, 0));
14923       return;
14924     }
14925   }
14926   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm);
14927 }
14928 
vcmpe(Condition cond,DataType dt,DRegister rd,DRegister rm)14929 void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14930   VIXL_ASSERT(AllowAssembler());
14931   CheckIT(cond);
14932   if (IsUsingT32()) {
14933     // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
14934     if (dt.Is(F64)) {
14935       EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14936       AdvanceIT();
14937       return;
14938     }
14939   } else {
14940     // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
14941     if (dt.Is(F64) && cond.IsNotNever()) {
14942       EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14943               rm.Encode(5, 0));
14944       return;
14945     }
14946   }
14947   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, rm);
14948 }
14949 
vcmpe(Condition cond,DataType dt,SRegister rd,double imm)14950 void Assembler::vcmpe(Condition cond, DataType dt, SRegister rd, double imm) {
14951   VIXL_ASSERT(AllowAssembler());
14952   CheckIT(cond);
14953   if (IsUsingT32()) {
14954     // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
14955     if (dt.Is(F32) && (imm == 0.0)) {
14956       EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12));
14957       AdvanceIT();
14958       return;
14959     }
14960   } else {
14961     // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
14962     if (dt.Is(F32) && (imm == 0.0) && cond.IsNotNever()) {
14963       EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14964       return;
14965     }
14966   }
14967   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm);
14968 }
14969 
vcmpe(Condition cond,DataType dt,DRegister rd,double imm)14970 void Assembler::vcmpe(Condition cond, DataType dt, DRegister rd, double imm) {
14971   VIXL_ASSERT(AllowAssembler());
14972   CheckIT(cond);
14973   if (IsUsingT32()) {
14974     // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
14975     if (dt.Is(F64) && (imm == 0.0)) {
14976       EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12));
14977       AdvanceIT();
14978       return;
14979     }
14980   } else {
14981     // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
14982     if (dt.Is(F64) && (imm == 0.0) && cond.IsNotNever()) {
14983       EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
14984       return;
14985     }
14986   }
14987   Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, imm);
14988 }
14989 
vcnt(Condition cond,DataType dt,DRegister rd,DRegister rm)14990 void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14991   VIXL_ASSERT(AllowAssembler());
14992   CheckIT(cond);
14993   if (IsUsingT32()) {
14994     // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1
14995     if (dt.Is(Untyped8)) {
14996       if (cond.Is(al) || AllowStronglyDiscouraged()) {
14997         EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
14998         AdvanceIT();
14999         return;
15000       }
15001     }
15002   } else {
15003     // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1
15004     if (dt.Is(Untyped8)) {
15005       if (cond.Is(al)) {
15006         EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
15007         return;
15008       }
15009     }
15010   }
15011   Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
15012 }
15013 
vcnt(Condition cond,DataType dt,QRegister rd,QRegister rm)15014 void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) {
15015   VIXL_ASSERT(AllowAssembler());
15016   CheckIT(cond);
15017   if (IsUsingT32()) {
15018     // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1
15019     if (dt.Is(Untyped8)) {
15020       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15021         EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
15022         AdvanceIT();
15023         return;
15024       }
15025     }
15026   } else {
15027     // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1
15028     if (dt.Is(Untyped8)) {
15029       if (cond.Is(al)) {
15030         EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
15031         return;
15032       }
15033     }
15034   }
15035   Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
15036 }
15037 
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,SRegister rm)15038 void Assembler::vcvt(
15039     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
15040   VIXL_ASSERT(AllowAssembler());
15041   CheckIT(cond);
15042   Dt_op_2 encoded_dt(dt2);
15043   if (IsUsingT32()) {
15044     // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1
15045     if (dt1.Is(F64) && dt2.Is(F32)) {
15046       EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15047       AdvanceIT();
15048       return;
15049     }
15050     // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1
15051     if (dt1.Is(F64) && encoded_dt.IsValid()) {
15052       EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) |
15053                  rd.Encode(22, 12) | rm.Encode(5, 0));
15054       AdvanceIT();
15055       return;
15056     }
15057   } else {
15058     // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1
15059     if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) {
15060       EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15061               rm.Encode(5, 0));
15062       return;
15063     }
15064     // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1
15065     if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) {
15066       EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) |
15067               (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
15068               rm.Encode(5, 0));
15069       return;
15070     }
15071   }
15072   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15073 }
15074 
vcvt(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)15075 void Assembler::vcvt(
15076     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15077   VIXL_ASSERT(AllowAssembler());
15078   CheckIT(cond);
15079   if (IsUsingT32()) {
15080     // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1
15081     if (dt1.Is(F32) && dt2.Is(F64)) {
15082       EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15083       AdvanceIT();
15084       return;
15085     }
15086     // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
15087     if (dt1.Is(U32) && dt2.Is(F64)) {
15088       EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15089       AdvanceIT();
15090       return;
15091     }
15092     // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
15093     if (dt1.Is(S32) && dt2.Is(F64)) {
15094       EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15095       AdvanceIT();
15096       return;
15097     }
15098   } else {
15099     // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1
15100     if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) {
15101       EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15102               rm.Encode(5, 0));
15103       return;
15104     }
15105     // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
15106     if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
15107       EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15108               rm.Encode(5, 0));
15109       return;
15110     }
15111     // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
15112     if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
15113       EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15114               rm.Encode(5, 0));
15115       return;
15116     }
15117   }
15118   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15119 }
15120 
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,DRegister rm,int32_t fbits)15121 void Assembler::vcvt(Condition cond,
15122                      DataType dt1,
15123                      DataType dt2,
15124                      DRegister rd,
15125                      DRegister rm,
15126                      int32_t fbits) {
15127   VIXL_ASSERT(AllowAssembler());
15128   CheckIT(cond);
15129   Dt_op_U_1 encoded_dt(dt1, dt2);
15130   Dt_U_sx_1 encoded_dt_2(dt2);
15131   Dt_U_sx_1 encoded_dt_3(dt1);
15132   if (IsUsingT32()) {
15133     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1
15134     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15135       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15136         uint32_t fbits_ = 64 - fbits;
15137         EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
15138                    ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15139                    rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15140         AdvanceIT();
15141         return;
15142       }
15143     }
15144     // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1
15145     if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
15146         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15147          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15148       unsigned offset = 32;
15149       if (dt2.Is(S16) || dt2.Is(U16)) {
15150         offset = 16;
15151       }
15152       uint32_t fbits_ = offset - fbits;
15153       EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15154                  ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15155                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15156                  ((fbits_ & 0x1e) >> 1));
15157       AdvanceIT();
15158       return;
15159     }
15160     // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1
15161     if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
15162         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15163          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15164       unsigned offset = 32;
15165       if (dt1.Is(S16) || dt1.Is(U16)) {
15166         offset = 16;
15167       }
15168       uint32_t fbits_ = offset - fbits;
15169       EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
15170                  ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
15171                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15172                  ((fbits_ & 0x1e) >> 1));
15173       AdvanceIT();
15174       return;
15175     }
15176   } else {
15177     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1
15178     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15179       if (cond.Is(al)) {
15180         uint32_t fbits_ = 64 - fbits;
15181         EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
15182                 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15183                 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15184         return;
15185       }
15186     }
15187     // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1
15188     if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
15189         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15190          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15191         cond.IsNotNever()) {
15192       unsigned offset = 32;
15193       if (dt2.Is(S16) || dt2.Is(U16)) {
15194         offset = 16;
15195       }
15196       uint32_t fbits_ = offset - fbits;
15197       EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) |
15198               ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15199               ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15200               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15201               ((fbits_ & 0x1e) >> 1));
15202       return;
15203     }
15204     // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1
15205     if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
15206         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15207          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15208         cond.IsNotNever()) {
15209       unsigned offset = 32;
15210       if (dt1.Is(S16) || dt1.Is(U16)) {
15211         offset = 16;
15212       }
15213       uint32_t fbits_ = offset - fbits;
15214       EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) |
15215               ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
15216               ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
15217               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15218               ((fbits_ & 0x1e) >> 1));
15219       return;
15220     }
15221   }
15222   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
15223 }
15224 
vcvt(Condition cond,DataType dt1,DataType dt2,QRegister rd,QRegister rm,int32_t fbits)15225 void Assembler::vcvt(Condition cond,
15226                      DataType dt1,
15227                      DataType dt2,
15228                      QRegister rd,
15229                      QRegister rm,
15230                      int32_t fbits) {
15231   VIXL_ASSERT(AllowAssembler());
15232   CheckIT(cond);
15233   Dt_op_U_1 encoded_dt(dt1, dt2);
15234   if (IsUsingT32()) {
15235     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1
15236     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15237       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15238         uint32_t fbits_ = 64 - fbits;
15239         EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
15240                    ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15241                    rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15242         AdvanceIT();
15243         return;
15244       }
15245     }
15246   } else {
15247     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1
15248     if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
15249       if (cond.Is(al)) {
15250         uint32_t fbits_ = 64 - fbits;
15251         EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
15252                 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
15253                 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
15254         return;
15255       }
15256     }
15257   }
15258   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
15259 }
15260 
vcvt(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm,int32_t fbits)15261 void Assembler::vcvt(Condition cond,
15262                      DataType dt1,
15263                      DataType dt2,
15264                      SRegister rd,
15265                      SRegister rm,
15266                      int32_t fbits) {
15267   VIXL_ASSERT(AllowAssembler());
15268   CheckIT(cond);
15269   Dt_U_sx_1 encoded_dt(dt2);
15270   Dt_U_sx_1 encoded_dt_2(dt1);
15271   if (IsUsingT32()) {
15272     // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1
15273     if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
15274         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15275          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15276       unsigned offset = 32;
15277       if (dt2.Is(S16) || dt2.Is(U16)) {
15278         offset = 16;
15279       }
15280       uint32_t fbits_ = offset - fbits;
15281       EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
15282                  ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
15283                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15284                  ((fbits_ & 0x1e) >> 1));
15285       AdvanceIT();
15286       return;
15287     }
15288     // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1
15289     if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
15290         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15291          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
15292       unsigned offset = 32;
15293       if (dt1.Is(S16) || dt1.Is(U16)) {
15294         offset = 16;
15295       }
15296       uint32_t fbits_ = offset - fbits;
15297       EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15298                  ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15299                  rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15300                  ((fbits_ & 0x1e) >> 1));
15301       AdvanceIT();
15302       return;
15303     }
15304   } else {
15305     // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1
15306     if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
15307         (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
15308          ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15309         cond.IsNotNever()) {
15310       unsigned offset = 32;
15311       if (dt2.Is(S16) || dt2.Is(U16)) {
15312         offset = 16;
15313       }
15314       uint32_t fbits_ = offset - fbits;
15315       EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) |
15316               ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
15317               ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
15318               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15319               ((fbits_ & 0x1e) >> 1));
15320       return;
15321     }
15322     // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1
15323     if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
15324         (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
15325          ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
15326         cond.IsNotNever()) {
15327       unsigned offset = 32;
15328       if (dt1.Is(S16) || dt1.Is(U16)) {
15329         offset = 16;
15330       }
15331       uint32_t fbits_ = offset - fbits;
15332       EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) |
15333               ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
15334               ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
15335               rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
15336               ((fbits_ & 0x1e) >> 1));
15337       return;
15338     }
15339   }
15340   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
15341 }
15342 
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,DRegister rm)15343 void Assembler::vcvt(
15344     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15345   VIXL_ASSERT(AllowAssembler());
15346   CheckIT(cond);
15347   Dt_op_1 encoded_dt(dt1, dt2);
15348   if (IsUsingT32()) {
15349     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1
15350     if (encoded_dt.IsValid()) {
15351       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15352         EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) |
15353                    rd.Encode(22, 12) | rm.Encode(5, 0));
15354         AdvanceIT();
15355         return;
15356       }
15357     }
15358   } else {
15359     // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1
15360     if (encoded_dt.IsValid()) {
15361       if (cond.Is(al)) {
15362         EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) |
15363                 rd.Encode(22, 12) | rm.Encode(5, 0));
15364         return;
15365       }
15366     }
15367   }
15368   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15369 }
15370 
vcvt(Condition cond,DataType dt1,DataType dt2,QRegister rd,QRegister rm)15371 void Assembler::vcvt(
15372     Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15373   VIXL_ASSERT(AllowAssembler());
15374   CheckIT(cond);
15375   Dt_op_1 encoded_dt(dt1, dt2);
15376   if (IsUsingT32()) {
15377     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1
15378     if (encoded_dt.IsValid()) {
15379       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15380         EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) |
15381                    rd.Encode(22, 12) | rm.Encode(5, 0));
15382         AdvanceIT();
15383         return;
15384       }
15385     }
15386   } else {
15387     // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1
15388     if (encoded_dt.IsValid()) {
15389       if (cond.Is(al)) {
15390         EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) |
15391                 rd.Encode(22, 12) | rm.Encode(5, 0));
15392         return;
15393       }
15394     }
15395   }
15396   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15397 }
15398 
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,QRegister rm)15399 void Assembler::vcvt(
15400     Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) {
15401   VIXL_ASSERT(AllowAssembler());
15402   CheckIT(cond);
15403   if (IsUsingT32()) {
15404     // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1
15405     if (dt1.Is(F16) && dt2.Is(F32)) {
15406       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15407         EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
15408         AdvanceIT();
15409         return;
15410       }
15411     }
15412   } else {
15413     // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1
15414     if (dt1.Is(F16) && dt2.Is(F32)) {
15415       if (cond.Is(al)) {
15416         EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
15417         return;
15418       }
15419     }
15420   }
15421   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15422 }
15423 
vcvt(Condition cond,DataType dt1,DataType dt2,QRegister rd,DRegister rm)15424 void Assembler::vcvt(
15425     Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) {
15426   VIXL_ASSERT(AllowAssembler());
15427   CheckIT(cond);
15428   if (IsUsingT32()) {
15429     // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1
15430     if (dt1.Is(F32) && dt2.Is(F16)) {
15431       if (cond.Is(al) || AllowStronglyDiscouraged()) {
15432         EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
15433         AdvanceIT();
15434         return;
15435       }
15436     }
15437   } else {
15438     // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1
15439     if (dt1.Is(F32) && dt2.Is(F16)) {
15440       if (cond.Is(al)) {
15441         EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
15442         return;
15443       }
15444     }
15445   }
15446   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15447 }
15448 
vcvt(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)15449 void Assembler::vcvt(
15450     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15451   VIXL_ASSERT(AllowAssembler());
15452   CheckIT(cond);
15453   Dt_op_2 encoded_dt(dt2);
15454   if (IsUsingT32()) {
15455     // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
15456     if (dt1.Is(U32) && dt2.Is(F32)) {
15457       EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15458       AdvanceIT();
15459       return;
15460     }
15461     // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
15462     if (dt1.Is(S32) && dt2.Is(F32)) {
15463       EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
15464       AdvanceIT();
15465       return;
15466     }
15467     // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1
15468     if (dt1.Is(F32) && encoded_dt.IsValid()) {
15469       EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) |
15470                  rd.Encode(22, 12) | rm.Encode(5, 0));
15471       AdvanceIT();
15472       return;
15473     }
15474   } else {
15475     // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
15476     if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
15477       EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15478               rm.Encode(5, 0));
15479       return;
15480     }
15481     // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
15482     if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
15483       EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15484               rm.Encode(5, 0));
15485       return;
15486     }
15487     // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1
15488     if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) {
15489       EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) |
15490               (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
15491               rm.Encode(5, 0));
15492       return;
15493     }
15494   }
15495   Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
15496 }
15497 
vcvta(DataType dt1,DataType dt2,DRegister rd,DRegister rm)15498 void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15499   VIXL_ASSERT(AllowAssembler());
15500   CheckIT(al);
15501   Dt_op_3 encoded_dt(dt1);
15502   if (IsUsingT32()) {
15503     // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15504     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15505       EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) |
15506                  rd.Encode(22, 12) | rm.Encode(5, 0));
15507       AdvanceIT();
15508       return;
15509     }
15510   } else {
15511     // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15512     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15513       EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) |
15514               rd.Encode(22, 12) | rm.Encode(5, 0));
15515       return;
15516     }
15517   }
15518   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15519 }
15520 
vcvta(DataType dt1,DataType dt2,QRegister rd,QRegister rm)15521 void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15522   VIXL_ASSERT(AllowAssembler());
15523   CheckIT(al);
15524   Dt_op_3 encoded_dt(dt1);
15525   if (IsUsingT32()) {
15526     // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15527     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15528       EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) |
15529                  rd.Encode(22, 12) | rm.Encode(5, 0));
15530       AdvanceIT();
15531       return;
15532     }
15533   } else {
15534     // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15535     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15536       EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) |
15537               rd.Encode(22, 12) | rm.Encode(5, 0));
15538       return;
15539     }
15540   }
15541   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15542 }
15543 
vcvta(DataType dt1,DataType dt2,SRegister rd,SRegister rm)15544 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15545   VIXL_ASSERT(AllowAssembler());
15546   CheckIT(al);
15547   Dt_op_2 encoded_dt(dt1);
15548   if (IsUsingT32()) {
15549     // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15550     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15551       EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
15552                  rd.Encode(22, 12) | rm.Encode(5, 0));
15553       AdvanceIT();
15554       return;
15555     }
15556   } else {
15557     // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15558     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15559       EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
15560               rd.Encode(22, 12) | rm.Encode(5, 0));
15561       return;
15562     }
15563   }
15564   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15565 }
15566 
vcvta(DataType dt1,DataType dt2,SRegister rd,DRegister rm)15567 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15568   VIXL_ASSERT(AllowAssembler());
15569   CheckIT(al);
15570   Dt_op_2 encoded_dt(dt1);
15571   if (IsUsingT32()) {
15572     // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15573     if (encoded_dt.IsValid() && dt2.Is(F64)) {
15574       EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
15575                  rd.Encode(22, 12) | rm.Encode(5, 0));
15576       AdvanceIT();
15577       return;
15578     }
15579   } else {
15580     // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15581     if (encoded_dt.IsValid() && dt2.Is(F64)) {
15582       EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
15583               rd.Encode(22, 12) | rm.Encode(5, 0));
15584       return;
15585     }
15586   }
15587   Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
15588 }
15589 
vcvtb(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)15590 void Assembler::vcvtb(
15591     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15592   VIXL_ASSERT(AllowAssembler());
15593   CheckIT(cond);
15594   if (IsUsingT32()) {
15595     // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
15596     if (dt1.Is(F32) && dt2.Is(F16)) {
15597       EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15598       AdvanceIT();
15599       return;
15600     }
15601     // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
15602     if (dt1.Is(F16) && dt2.Is(F32)) {
15603       EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15604       AdvanceIT();
15605       return;
15606     }
15607   } else {
15608     // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
15609     if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
15610       EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15611               rm.Encode(5, 0));
15612       return;
15613     }
15614     // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
15615     if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
15616       EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15617               rm.Encode(5, 0));
15618       return;
15619     }
15620   }
15621   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15622 }
15623 
vcvtb(Condition cond,DataType dt1,DataType dt2,DRegister rd,SRegister rm)15624 void Assembler::vcvtb(
15625     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
15626   VIXL_ASSERT(AllowAssembler());
15627   CheckIT(cond);
15628   if (IsUsingT32()) {
15629     // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
15630     if (dt1.Is(F64) && dt2.Is(F16)) {
15631       EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15632       AdvanceIT();
15633       return;
15634     }
15635   } else {
15636     // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
15637     if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
15638       EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15639               rm.Encode(5, 0));
15640       return;
15641     }
15642   }
15643   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15644 }
15645 
vcvtb(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)15646 void Assembler::vcvtb(
15647     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15648   VIXL_ASSERT(AllowAssembler());
15649   CheckIT(cond);
15650   if (IsUsingT32()) {
15651     // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
15652     if (dt1.Is(F16) && dt2.Is(F64)) {
15653       EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15654       AdvanceIT();
15655       return;
15656     }
15657   } else {
15658     // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
15659     if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
15660       EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15661               rm.Encode(5, 0));
15662       return;
15663     }
15664   }
15665   Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
15666 }
15667 
vcvtm(DataType dt1,DataType dt2,DRegister rd,DRegister rm)15668 void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15669   VIXL_ASSERT(AllowAssembler());
15670   CheckIT(al);
15671   Dt_op_3 encoded_dt(dt1);
15672   if (IsUsingT32()) {
15673     // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15674     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15675       EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) |
15676                  rd.Encode(22, 12) | rm.Encode(5, 0));
15677       AdvanceIT();
15678       return;
15679     }
15680   } else {
15681     // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15682     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15683       EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) |
15684               rd.Encode(22, 12) | rm.Encode(5, 0));
15685       return;
15686     }
15687   }
15688   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15689 }
15690 
vcvtm(DataType dt1,DataType dt2,QRegister rd,QRegister rm)15691 void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15692   VIXL_ASSERT(AllowAssembler());
15693   CheckIT(al);
15694   Dt_op_3 encoded_dt(dt1);
15695   if (IsUsingT32()) {
15696     // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15697     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15698       EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) |
15699                  rd.Encode(22, 12) | rm.Encode(5, 0));
15700       AdvanceIT();
15701       return;
15702     }
15703   } else {
15704     // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15705     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15706       EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) |
15707               rd.Encode(22, 12) | rm.Encode(5, 0));
15708       return;
15709     }
15710   }
15711   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15712 }
15713 
vcvtm(DataType dt1,DataType dt2,SRegister rd,SRegister rm)15714 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15715   VIXL_ASSERT(AllowAssembler());
15716   CheckIT(al);
15717   Dt_op_2 encoded_dt(dt1);
15718   if (IsUsingT32()) {
15719     // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15720     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15721       EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
15722                  rd.Encode(22, 12) | rm.Encode(5, 0));
15723       AdvanceIT();
15724       return;
15725     }
15726   } else {
15727     // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15728     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15729       EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
15730               rd.Encode(22, 12) | rm.Encode(5, 0));
15731       return;
15732     }
15733   }
15734   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15735 }
15736 
vcvtm(DataType dt1,DataType dt2,SRegister rd,DRegister rm)15737 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15738   VIXL_ASSERT(AllowAssembler());
15739   CheckIT(al);
15740   Dt_op_2 encoded_dt(dt1);
15741   if (IsUsingT32()) {
15742     // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15743     if (encoded_dt.IsValid() && dt2.Is(F64)) {
15744       EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
15745                  rd.Encode(22, 12) | rm.Encode(5, 0));
15746       AdvanceIT();
15747       return;
15748     }
15749   } else {
15750     // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15751     if (encoded_dt.IsValid() && dt2.Is(F64)) {
15752       EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
15753               rd.Encode(22, 12) | rm.Encode(5, 0));
15754       return;
15755     }
15756   }
15757   Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
15758 }
15759 
vcvtn(DataType dt1,DataType dt2,DRegister rd,DRegister rm)15760 void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15761   VIXL_ASSERT(AllowAssembler());
15762   CheckIT(al);
15763   Dt_op_3 encoded_dt(dt1);
15764   if (IsUsingT32()) {
15765     // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15766     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15767       EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) |
15768                  rd.Encode(22, 12) | rm.Encode(5, 0));
15769       AdvanceIT();
15770       return;
15771     }
15772   } else {
15773     // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15774     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15775       EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) |
15776               rd.Encode(22, 12) | rm.Encode(5, 0));
15777       return;
15778     }
15779   }
15780   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15781 }
15782 
vcvtn(DataType dt1,DataType dt2,QRegister rd,QRegister rm)15783 void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15784   VIXL_ASSERT(AllowAssembler());
15785   CheckIT(al);
15786   Dt_op_3 encoded_dt(dt1);
15787   if (IsUsingT32()) {
15788     // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15789     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15790       EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) |
15791                  rd.Encode(22, 12) | rm.Encode(5, 0));
15792       AdvanceIT();
15793       return;
15794     }
15795   } else {
15796     // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15797     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15798       EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) |
15799               rd.Encode(22, 12) | rm.Encode(5, 0));
15800       return;
15801     }
15802   }
15803   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15804 }
15805 
vcvtn(DataType dt1,DataType dt2,SRegister rd,SRegister rm)15806 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15807   VIXL_ASSERT(AllowAssembler());
15808   CheckIT(al);
15809   Dt_op_2 encoded_dt(dt1);
15810   if (IsUsingT32()) {
15811     // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15812     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15813       EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
15814                  rd.Encode(22, 12) | rm.Encode(5, 0));
15815       AdvanceIT();
15816       return;
15817     }
15818   } else {
15819     // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15820     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15821       EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
15822               rd.Encode(22, 12) | rm.Encode(5, 0));
15823       return;
15824     }
15825   }
15826   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15827 }
15828 
vcvtn(DataType dt1,DataType dt2,SRegister rd,DRegister rm)15829 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15830   VIXL_ASSERT(AllowAssembler());
15831   CheckIT(al);
15832   Dt_op_2 encoded_dt(dt1);
15833   if (IsUsingT32()) {
15834     // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15835     if (encoded_dt.IsValid() && dt2.Is(F64)) {
15836       EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
15837                  rd.Encode(22, 12) | rm.Encode(5, 0));
15838       AdvanceIT();
15839       return;
15840     }
15841   } else {
15842     // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15843     if (encoded_dt.IsValid() && dt2.Is(F64)) {
15844       EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
15845               rd.Encode(22, 12) | rm.Encode(5, 0));
15846       return;
15847     }
15848   }
15849   Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
15850 }
15851 
vcvtp(DataType dt1,DataType dt2,DRegister rd,DRegister rm)15852 void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
15853   VIXL_ASSERT(AllowAssembler());
15854   CheckIT(al);
15855   Dt_op_3 encoded_dt(dt1);
15856   if (IsUsingT32()) {
15857     // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
15858     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15859       EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) |
15860                  rd.Encode(22, 12) | rm.Encode(5, 0));
15861       AdvanceIT();
15862       return;
15863     }
15864   } else {
15865     // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
15866     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15867       EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) |
15868               rd.Encode(22, 12) | rm.Encode(5, 0));
15869       return;
15870     }
15871   }
15872   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15873 }
15874 
vcvtp(DataType dt1,DataType dt2,QRegister rd,QRegister rm)15875 void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
15876   VIXL_ASSERT(AllowAssembler());
15877   CheckIT(al);
15878   Dt_op_3 encoded_dt(dt1);
15879   if (IsUsingT32()) {
15880     // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
15881     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15882       EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) |
15883                  rd.Encode(22, 12) | rm.Encode(5, 0));
15884       AdvanceIT();
15885       return;
15886     }
15887   } else {
15888     // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
15889     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15890       EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) |
15891               rd.Encode(22, 12) | rm.Encode(5, 0));
15892       return;
15893     }
15894   }
15895   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15896 }
15897 
vcvtp(DataType dt1,DataType dt2,SRegister rd,SRegister rm)15898 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15899   VIXL_ASSERT(AllowAssembler());
15900   CheckIT(al);
15901   Dt_op_2 encoded_dt(dt1);
15902   if (IsUsingT32()) {
15903     // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
15904     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15905       EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
15906                  rd.Encode(22, 12) | rm.Encode(5, 0));
15907       AdvanceIT();
15908       return;
15909     }
15910   } else {
15911     // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
15912     if (encoded_dt.IsValid() && dt2.Is(F32)) {
15913       EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
15914               rd.Encode(22, 12) | rm.Encode(5, 0));
15915       return;
15916     }
15917   }
15918   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15919 }
15920 
vcvtp(DataType dt1,DataType dt2,SRegister rd,DRegister rm)15921 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15922   VIXL_ASSERT(AllowAssembler());
15923   CheckIT(al);
15924   Dt_op_2 encoded_dt(dt1);
15925   if (IsUsingT32()) {
15926     // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
15927     if (encoded_dt.IsValid() && dt2.Is(F64)) {
15928       EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
15929                  rd.Encode(22, 12) | rm.Encode(5, 0));
15930       AdvanceIT();
15931       return;
15932     }
15933   } else {
15934     // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
15935     if (encoded_dt.IsValid() && dt2.Is(F64)) {
15936       EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
15937               rd.Encode(22, 12) | rm.Encode(5, 0));
15938       return;
15939     }
15940   }
15941   Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
15942 }
15943 
vcvtr(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)15944 void Assembler::vcvtr(
15945     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
15946   VIXL_ASSERT(AllowAssembler());
15947   CheckIT(cond);
15948   if (IsUsingT32()) {
15949     // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
15950     if (dt1.Is(U32) && dt2.Is(F32)) {
15951       EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15952       AdvanceIT();
15953       return;
15954     }
15955     // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
15956     if (dt1.Is(S32) && dt2.Is(F32)) {
15957       EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15958       AdvanceIT();
15959       return;
15960     }
15961   } else {
15962     // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
15963     if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
15964       EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15965               rm.Encode(5, 0));
15966       return;
15967     }
15968     // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
15969     if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
15970       EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15971               rm.Encode(5, 0));
15972       return;
15973     }
15974   }
15975   Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
15976 }
15977 
vcvtr(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)15978 void Assembler::vcvtr(
15979     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
15980   VIXL_ASSERT(AllowAssembler());
15981   CheckIT(cond);
15982   if (IsUsingT32()) {
15983     // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
15984     if (dt1.Is(U32) && dt2.Is(F64)) {
15985       EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15986       AdvanceIT();
15987       return;
15988     }
15989     // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
15990     if (dt1.Is(S32) && dt2.Is(F64)) {
15991       EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
15992       AdvanceIT();
15993       return;
15994     }
15995   } else {
15996     // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
15997     if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
15998       EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
15999               rm.Encode(5, 0));
16000       return;
16001     }
16002     // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
16003     if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
16004       EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16005               rm.Encode(5, 0));
16006       return;
16007     }
16008   }
16009   Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
16010 }
16011 
vcvtt(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)16012 void Assembler::vcvtt(
16013     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16014   VIXL_ASSERT(AllowAssembler());
16015   CheckIT(cond);
16016   if (IsUsingT32()) {
16017     // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
16018     if (dt1.Is(F32) && dt2.Is(F16)) {
16019       EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16020       AdvanceIT();
16021       return;
16022     }
16023     // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
16024     if (dt1.Is(F16) && dt2.Is(F32)) {
16025       EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16026       AdvanceIT();
16027       return;
16028     }
16029   } else {
16030     // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
16031     if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
16032       EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16033               rm.Encode(5, 0));
16034       return;
16035     }
16036     // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
16037     if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
16038       EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16039               rm.Encode(5, 0));
16040       return;
16041     }
16042   }
16043   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
16044 }
16045 
vcvtt(Condition cond,DataType dt1,DataType dt2,DRegister rd,SRegister rm)16046 void Assembler::vcvtt(
16047     Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
16048   VIXL_ASSERT(AllowAssembler());
16049   CheckIT(cond);
16050   if (IsUsingT32()) {
16051     // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
16052     if (dt1.Is(F64) && dt2.Is(F16)) {
16053       EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16054       AdvanceIT();
16055       return;
16056     }
16057   } else {
16058     // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
16059     if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
16060       EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16061               rm.Encode(5, 0));
16062       return;
16063     }
16064   }
16065   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
16066 }
16067 
vcvtt(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)16068 void Assembler::vcvtt(
16069     Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16070   VIXL_ASSERT(AllowAssembler());
16071   CheckIT(cond);
16072   if (IsUsingT32()) {
16073     // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
16074     if (dt1.Is(F16) && dt2.Is(F64)) {
16075       EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16076       AdvanceIT();
16077       return;
16078     }
16079   } else {
16080     // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
16081     if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
16082       EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16083               rm.Encode(5, 0));
16084       return;
16085     }
16086   }
16087   Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
16088 }
16089 
vdiv(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)16090 void Assembler::vdiv(
16091     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16092   VIXL_ASSERT(AllowAssembler());
16093   CheckIT(cond);
16094   if (IsUsingT32()) {
16095     // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
16096     if (dt.Is(F32)) {
16097       EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16098                  rm.Encode(5, 0));
16099       AdvanceIT();
16100       return;
16101     }
16102   } else {
16103     // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
16104     if (dt.Is(F32) && cond.IsNotNever()) {
16105       EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16106               rn.Encode(7, 16) | rm.Encode(5, 0));
16107       return;
16108     }
16109   }
16110   Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
16111 }
16112 
vdiv(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)16113 void Assembler::vdiv(
16114     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16115   VIXL_ASSERT(AllowAssembler());
16116   CheckIT(cond);
16117   if (IsUsingT32()) {
16118     // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
16119     if (dt.Is(F64)) {
16120       EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16121                  rm.Encode(5, 0));
16122       AdvanceIT();
16123       return;
16124     }
16125   } else {
16126     // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
16127     if (dt.Is(F64) && cond.IsNotNever()) {
16128       EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16129               rn.Encode(7, 16) | rm.Encode(5, 0));
16130       return;
16131     }
16132   }
16133   Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
16134 }
16135 
vdup(Condition cond,DataType dt,QRegister rd,Register rt)16136 void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) {
16137   VIXL_ASSERT(AllowAssembler());
16138   CheckIT(cond);
16139   Dt_B_E_1 encoded_dt(dt);
16140   if (IsUsingT32()) {
16141     // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1
16142     if (encoded_dt.IsValid()) {
16143       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16144         EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16145                    ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16146                    rd.Encode(7, 16) | (rt.GetCode() << 12));
16147         AdvanceIT();
16148         return;
16149       }
16150     }
16151   } else {
16152     // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1
16153     if (encoded_dt.IsValid() && cond.IsNotNever()) {
16154       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16155         EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) |
16156                 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16157                 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16158                 rd.Encode(7, 16) | (rt.GetCode() << 12));
16159         return;
16160       }
16161     }
16162   }
16163   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
16164 }
16165 
vdup(Condition cond,DataType dt,DRegister rd,Register rt)16166 void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) {
16167   VIXL_ASSERT(AllowAssembler());
16168   CheckIT(cond);
16169   Dt_B_E_1 encoded_dt(dt);
16170   if (IsUsingT32()) {
16171     // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1
16172     if (encoded_dt.IsValid()) {
16173       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16174         EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16175                    ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16176                    rd.Encode(7, 16) | (rt.GetCode() << 12));
16177         AdvanceIT();
16178         return;
16179       }
16180     }
16181   } else {
16182     // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1
16183     if (encoded_dt.IsValid() && cond.IsNotNever()) {
16184       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16185         EmitA32(0x0e800b10U | (cond.GetCondition() << 28) |
16186                 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
16187                 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
16188                 rd.Encode(7, 16) | (rt.GetCode() << 12));
16189         return;
16190       }
16191     }
16192   }
16193   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
16194 }
16195 
vdup(Condition cond,DataType dt,DRegister rd,DRegisterLane rm)16196 void Assembler::vdup(Condition cond,
16197                      DataType dt,
16198                      DRegister rd,
16199                      DRegisterLane rm) {
16200   VIXL_ASSERT(AllowAssembler());
16201   CheckIT(cond);
16202   Dt_imm4_1 encoded_dt(dt, rm);
16203   if (IsUsingT32()) {
16204     // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1
16205     if (encoded_dt.IsValid()) {
16206       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16207         EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) |
16208                    rd.Encode(22, 12) | rm.Encode(5, 0));
16209         AdvanceIT();
16210         return;
16211       }
16212     }
16213   } else {
16214     // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1
16215     if (encoded_dt.IsValid()) {
16216       if (cond.Is(al)) {
16217         EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) |
16218                 rd.Encode(22, 12) | rm.Encode(5, 0));
16219         return;
16220       }
16221     }
16222   }
16223   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
16224 }
16225 
vdup(Condition cond,DataType dt,QRegister rd,DRegisterLane rm)16226 void Assembler::vdup(Condition cond,
16227                      DataType dt,
16228                      QRegister rd,
16229                      DRegisterLane rm) {
16230   VIXL_ASSERT(AllowAssembler());
16231   CheckIT(cond);
16232   Dt_imm4_1 encoded_dt(dt, rm);
16233   if (IsUsingT32()) {
16234     // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1
16235     if (encoded_dt.IsValid()) {
16236       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16237         EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) |
16238                    rd.Encode(22, 12) | rm.Encode(5, 0));
16239         AdvanceIT();
16240         return;
16241       }
16242     }
16243   } else {
16244     // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1
16245     if (encoded_dt.IsValid()) {
16246       if (cond.Is(al)) {
16247         EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) |
16248                 rd.Encode(22, 12) | rm.Encode(5, 0));
16249         return;
16250       }
16251     }
16252   }
16253   Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
16254 }
16255 
veor(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)16256 void Assembler::veor(
16257     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16258   VIXL_ASSERT(AllowAssembler());
16259   CheckIT(cond);
16260   USE(dt);
16261   if (IsUsingT32()) {
16262     // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
16263     if (cond.Is(al) || AllowStronglyDiscouraged()) {
16264       EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16265                  rm.Encode(5, 0));
16266       AdvanceIT();
16267       return;
16268     }
16269   } else {
16270     // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
16271     if (cond.Is(al)) {
16272       EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16273               rm.Encode(5, 0));
16274       return;
16275     }
16276   }
16277   Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
16278 }
16279 
veor(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)16280 void Assembler::veor(
16281     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16282   VIXL_ASSERT(AllowAssembler());
16283   CheckIT(cond);
16284   USE(dt);
16285   if (IsUsingT32()) {
16286     // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
16287     if (cond.Is(al) || AllowStronglyDiscouraged()) {
16288       EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16289                  rm.Encode(5, 0));
16290       AdvanceIT();
16291       return;
16292     }
16293   } else {
16294     // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
16295     if (cond.Is(al)) {
16296       EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16297               rm.Encode(5, 0));
16298       return;
16299     }
16300   }
16301   Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
16302 }
16303 
vext(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm,const DOperand & operand)16304 void Assembler::vext(Condition cond,
16305                      DataType dt,
16306                      DRegister rd,
16307                      DRegister rn,
16308                      DRegister rm,
16309                      const DOperand& operand) {
16310   VIXL_ASSERT(AllowAssembler());
16311   CheckIT(cond);
16312   if (operand.IsImmediate()) {
16313     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
16314       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
16315       if (IsUsingT32()) {
16316         // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
16317         if (dt.Is(Untyped8) && (imm <= 7)) {
16318           if (cond.Is(al) || AllowStronglyDiscouraged()) {
16319             EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16320                        rm.Encode(5, 0) | (imm << 8));
16321             AdvanceIT();
16322             return;
16323           }
16324         }
16325         // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
16326         if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
16327             (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16328           if (cond.Is(al) || AllowStronglyDiscouraged()) {
16329             uint32_t imm4 = imm / dt.GetSize();
16330             EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16331                        rm.Encode(5, 0) | (imm4 << 8));
16332             AdvanceIT();
16333             return;
16334           }
16335         }
16336       } else {
16337         // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
16338         if (dt.Is(Untyped8) && (imm <= 7)) {
16339           if (cond.Is(al)) {
16340             EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16341                     rm.Encode(5, 0) | (imm << 8));
16342             return;
16343           }
16344         }
16345         // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
16346         if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
16347             (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16348           if (cond.Is(al)) {
16349             uint32_t imm4 = imm / dt.GetSize();
16350             EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16351                     rm.Encode(5, 0) | (imm4 << 8));
16352             return;
16353           }
16354         }
16355       }
16356     }
16357   }
16358   Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
16359 }
16360 
vext(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm,const QOperand & operand)16361 void Assembler::vext(Condition cond,
16362                      DataType dt,
16363                      QRegister rd,
16364                      QRegister rn,
16365                      QRegister rm,
16366                      const QOperand& operand) {
16367   VIXL_ASSERT(AllowAssembler());
16368   CheckIT(cond);
16369   if (operand.IsImmediate()) {
16370     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
16371       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
16372       if (IsUsingT32()) {
16373         // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
16374         if (dt.Is(Untyped8) && (imm <= 15)) {
16375           if (cond.Is(al) || AllowStronglyDiscouraged()) {
16376             EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16377                        rm.Encode(5, 0) | (imm << 8));
16378             AdvanceIT();
16379             return;
16380           }
16381         }
16382         // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
16383         if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
16384             (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16385           if (cond.Is(al) || AllowStronglyDiscouraged()) {
16386             uint32_t imm4 = imm / dt.GetSize();
16387             EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16388                        rm.Encode(5, 0) | (imm4 << 8));
16389             AdvanceIT();
16390             return;
16391           }
16392         }
16393       } else {
16394         // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
16395         if (dt.Is(Untyped8) && (imm <= 15)) {
16396           if (cond.Is(al)) {
16397             EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16398                     rm.Encode(5, 0) | (imm << 8));
16399             return;
16400           }
16401         }
16402         // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
16403         if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
16404             (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
16405           if (cond.Is(al)) {
16406             uint32_t imm4 = imm / dt.GetSize();
16407             EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16408                     rm.Encode(5, 0) | (imm4 << 8));
16409             return;
16410           }
16411         }
16412       }
16413     }
16414   }
16415   Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
16416 }
16417 
vfma(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)16418 void Assembler::vfma(
16419     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16420   VIXL_ASSERT(AllowAssembler());
16421   CheckIT(cond);
16422   if (IsUsingT32()) {
16423     // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
16424     if (dt.Is(F32)) {
16425       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16426         EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16427                    rm.Encode(5, 0));
16428         AdvanceIT();
16429         return;
16430       }
16431     }
16432     // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
16433     if (dt.Is(F64)) {
16434       EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16435                  rm.Encode(5, 0));
16436       AdvanceIT();
16437       return;
16438     }
16439   } else {
16440     // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
16441     if (dt.Is(F32)) {
16442       if (cond.Is(al)) {
16443         EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16444                 rm.Encode(5, 0));
16445         return;
16446       }
16447     }
16448     // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
16449     if (dt.Is(F64) && cond.IsNotNever()) {
16450       EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16451               rn.Encode(7, 16) | rm.Encode(5, 0));
16452       return;
16453     }
16454   }
16455   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16456 }
16457 
vfma(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)16458 void Assembler::vfma(
16459     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16460   VIXL_ASSERT(AllowAssembler());
16461   CheckIT(cond);
16462   if (IsUsingT32()) {
16463     // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
16464     if (dt.Is(F32)) {
16465       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16466         EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16467                    rm.Encode(5, 0));
16468         AdvanceIT();
16469         return;
16470       }
16471     }
16472   } else {
16473     // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
16474     if (dt.Is(F32)) {
16475       if (cond.Is(al)) {
16476         EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16477                 rm.Encode(5, 0));
16478         return;
16479       }
16480     }
16481   }
16482   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16483 }
16484 
vfma(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)16485 void Assembler::vfma(
16486     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16487   VIXL_ASSERT(AllowAssembler());
16488   CheckIT(cond);
16489   if (IsUsingT32()) {
16490     // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
16491     if (dt.Is(F32)) {
16492       EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16493                  rm.Encode(5, 0));
16494       AdvanceIT();
16495       return;
16496     }
16497   } else {
16498     // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
16499     if (dt.Is(F32) && cond.IsNotNever()) {
16500       EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16501               rn.Encode(7, 16) | rm.Encode(5, 0));
16502       return;
16503     }
16504   }
16505   Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
16506 }
16507 
vfms(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)16508 void Assembler::vfms(
16509     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16510   VIXL_ASSERT(AllowAssembler());
16511   CheckIT(cond);
16512   if (IsUsingT32()) {
16513     // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
16514     if (dt.Is(F32)) {
16515       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16516         EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16517                    rm.Encode(5, 0));
16518         AdvanceIT();
16519         return;
16520       }
16521     }
16522     // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
16523     if (dt.Is(F64)) {
16524       EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16525                  rm.Encode(5, 0));
16526       AdvanceIT();
16527       return;
16528     }
16529   } else {
16530     // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
16531     if (dt.Is(F32)) {
16532       if (cond.Is(al)) {
16533         EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16534                 rm.Encode(5, 0));
16535         return;
16536       }
16537     }
16538     // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
16539     if (dt.Is(F64) && cond.IsNotNever()) {
16540       EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16541               rn.Encode(7, 16) | rm.Encode(5, 0));
16542       return;
16543     }
16544   }
16545   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16546 }
16547 
vfms(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)16548 void Assembler::vfms(
16549     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16550   VIXL_ASSERT(AllowAssembler());
16551   CheckIT(cond);
16552   if (IsUsingT32()) {
16553     // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
16554     if (dt.Is(F32)) {
16555       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16556         EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16557                    rm.Encode(5, 0));
16558         AdvanceIT();
16559         return;
16560       }
16561     }
16562   } else {
16563     // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
16564     if (dt.Is(F32)) {
16565       if (cond.Is(al)) {
16566         EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16567                 rm.Encode(5, 0));
16568         return;
16569       }
16570     }
16571   }
16572   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16573 }
16574 
vfms(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)16575 void Assembler::vfms(
16576     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16577   VIXL_ASSERT(AllowAssembler());
16578   CheckIT(cond);
16579   if (IsUsingT32()) {
16580     // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
16581     if (dt.Is(F32)) {
16582       EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16583                  rm.Encode(5, 0));
16584       AdvanceIT();
16585       return;
16586     }
16587   } else {
16588     // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
16589     if (dt.Is(F32) && cond.IsNotNever()) {
16590       EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16591               rn.Encode(7, 16) | rm.Encode(5, 0));
16592       return;
16593     }
16594   }
16595   Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
16596 }
16597 
vfnma(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)16598 void Assembler::vfnma(
16599     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16600   VIXL_ASSERT(AllowAssembler());
16601   CheckIT(cond);
16602   if (IsUsingT32()) {
16603     // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
16604     if (dt.Is(F32)) {
16605       EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16606                  rm.Encode(5, 0));
16607       AdvanceIT();
16608       return;
16609     }
16610   } else {
16611     // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
16612     if (dt.Is(F32) && cond.IsNotNever()) {
16613       EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16614               rn.Encode(7, 16) | rm.Encode(5, 0));
16615       return;
16616     }
16617   }
16618   Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
16619 }
16620 
vfnma(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)16621 void Assembler::vfnma(
16622     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16623   VIXL_ASSERT(AllowAssembler());
16624   CheckIT(cond);
16625   if (IsUsingT32()) {
16626     // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
16627     if (dt.Is(F64)) {
16628       EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16629                  rm.Encode(5, 0));
16630       AdvanceIT();
16631       return;
16632     }
16633   } else {
16634     // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
16635     if (dt.Is(F64) && cond.IsNotNever()) {
16636       EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16637               rn.Encode(7, 16) | rm.Encode(5, 0));
16638       return;
16639     }
16640   }
16641   Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
16642 }
16643 
vfnms(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)16644 void Assembler::vfnms(
16645     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
16646   VIXL_ASSERT(AllowAssembler());
16647   CheckIT(cond);
16648   if (IsUsingT32()) {
16649     // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
16650     if (dt.Is(F32)) {
16651       EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16652                  rm.Encode(5, 0));
16653       AdvanceIT();
16654       return;
16655     }
16656   } else {
16657     // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
16658     if (dt.Is(F32) && cond.IsNotNever()) {
16659       EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16660               rn.Encode(7, 16) | rm.Encode(5, 0));
16661       return;
16662     }
16663   }
16664   Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
16665 }
16666 
vfnms(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)16667 void Assembler::vfnms(
16668     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16669   VIXL_ASSERT(AllowAssembler());
16670   CheckIT(cond);
16671   if (IsUsingT32()) {
16672     // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
16673     if (dt.Is(F64)) {
16674       EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
16675                  rm.Encode(5, 0));
16676       AdvanceIT();
16677       return;
16678     }
16679   } else {
16680     // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
16681     if (dt.Is(F64) && cond.IsNotNever()) {
16682       EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16683               rn.Encode(7, 16) | rm.Encode(5, 0));
16684       return;
16685     }
16686   }
16687   Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
16688 }
16689 
vhadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)16690 void Assembler::vhadd(
16691     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16692   VIXL_ASSERT(AllowAssembler());
16693   CheckIT(cond);
16694   Dt_U_size_1 encoded_dt(dt);
16695   if (IsUsingT32()) {
16696     // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
16697     if (encoded_dt.IsValid()) {
16698       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16699         EmitT32_32(0xef000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16700                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16701                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16702         AdvanceIT();
16703         return;
16704       }
16705     }
16706   } else {
16707     // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
16708     if (encoded_dt.IsValid()) {
16709       if (cond.Is(al)) {
16710         EmitA32(0xf2000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16711                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16712                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16713         return;
16714       }
16715     }
16716   }
16717   Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
16718 }
16719 
vhadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)16720 void Assembler::vhadd(
16721     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16722   VIXL_ASSERT(AllowAssembler());
16723   CheckIT(cond);
16724   Dt_U_size_1 encoded_dt(dt);
16725   if (IsUsingT32()) {
16726     // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
16727     if (encoded_dt.IsValid()) {
16728       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16729         EmitT32_32(0xef000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16730                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16731                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16732         AdvanceIT();
16733         return;
16734       }
16735     }
16736   } else {
16737     // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
16738     if (encoded_dt.IsValid()) {
16739       if (cond.Is(al)) {
16740         EmitA32(0xf2000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16741                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16742                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16743         return;
16744       }
16745     }
16746   }
16747   Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
16748 }
16749 
vhsub(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)16750 void Assembler::vhsub(
16751     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
16752   VIXL_ASSERT(AllowAssembler());
16753   CheckIT(cond);
16754   Dt_U_size_1 encoded_dt(dt);
16755   if (IsUsingT32()) {
16756     // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
16757     if (encoded_dt.IsValid()) {
16758       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16759         EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16760                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16761                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16762         AdvanceIT();
16763         return;
16764       }
16765     }
16766   } else {
16767     // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
16768     if (encoded_dt.IsValid()) {
16769       if (cond.Is(al)) {
16770         EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16771                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16772                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16773         return;
16774       }
16775     }
16776   }
16777   Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
16778 }
16779 
vhsub(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)16780 void Assembler::vhsub(
16781     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
16782   VIXL_ASSERT(AllowAssembler());
16783   CheckIT(cond);
16784   Dt_U_size_1 encoded_dt(dt);
16785   if (IsUsingT32()) {
16786     // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
16787     if (encoded_dt.IsValid()) {
16788       if (cond.Is(al) || AllowStronglyDiscouraged()) {
16789         EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16790                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
16791                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16792         AdvanceIT();
16793         return;
16794       }
16795     }
16796   } else {
16797     // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
16798     if (encoded_dt.IsValid()) {
16799       if (cond.Is(al)) {
16800         EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
16801                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
16802                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
16803         return;
16804       }
16805     }
16806   }
16807   Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
16808 }
16809 
vld1(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)16810 void Assembler::vld1(Condition cond,
16811                      DataType dt,
16812                      const NeonRegisterList& nreglist,
16813                      const AlignedMemOperand& operand) {
16814   VIXL_ASSERT(AllowAssembler());
16815   CheckIT(cond);
16816   if (operand.IsImmediateZero()) {
16817     Register rn = operand.GetBaseRegister();
16818     Alignment align = operand.GetAlignment();
16819     Dt_size_6 encoded_dt(dt);
16820     Dt_size_7 encoded_dt_2(dt);
16821     Align_align_1 encoded_align_1(align, nreglist);
16822     Align_a_1 encoded_align_2(align, dt);
16823     Align_index_align_1 encoded_align_3(align, nreglist, dt);
16824     if (IsUsingT32()) {
16825       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16826       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16827           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16828           operand.IsOffset() && encoded_align_1.IsValid() &&
16829           (!rn.IsPC() || AllowUnpredictable())) {
16830         if (cond.Is(al) || AllowStronglyDiscouraged()) {
16831           const DRegister& first = nreglist.GetFirstDRegister();
16832           uint32_t len_encoding;
16833           switch (nreglist.GetLength()) {
16834             default:
16835               VIXL_UNREACHABLE_OR_FALLTHROUGH();
16836             case 1:
16837               len_encoding = 0x7;
16838               break;
16839             case 2:
16840               len_encoding = 0xa;
16841               break;
16842             case 3:
16843               len_encoding = 0x6;
16844               break;
16845             case 4:
16846               len_encoding = 0x2;
16847               break;
16848           }
16849           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
16850                      (encoded_align_1.GetEncodingValue() << 4) |
16851                      first.Encode(22, 12) | (len_encoding << 8) |
16852                      (rn.GetCode() << 16));
16853           AdvanceIT();
16854           return;
16855         }
16856       }
16857       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16858       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16859           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16860           operand.IsPostIndex() && encoded_align_1.IsValid() &&
16861           (!rn.IsPC() || AllowUnpredictable())) {
16862         if (cond.Is(al) || AllowStronglyDiscouraged()) {
16863           const DRegister& first = nreglist.GetFirstDRegister();
16864           uint32_t len_encoding;
16865           switch (nreglist.GetLength()) {
16866             default:
16867               VIXL_UNREACHABLE_OR_FALLTHROUGH();
16868             case 1:
16869               len_encoding = 0x7;
16870               break;
16871             case 2:
16872               len_encoding = 0xa;
16873               break;
16874             case 3:
16875               len_encoding = 0x6;
16876               break;
16877             case 4:
16878               len_encoding = 0x2;
16879               break;
16880           }
16881           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
16882                      (encoded_align_1.GetEncodingValue() << 4) |
16883                      first.Encode(22, 12) | (len_encoding << 8) |
16884                      (rn.GetCode() << 16));
16885           AdvanceIT();
16886           return;
16887         }
16888       }
16889       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16890       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16891           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16892           operand.IsOffset() && encoded_align_2.IsValid() &&
16893           (!rn.IsPC() || AllowUnpredictable())) {
16894         if (cond.Is(al) || AllowStronglyDiscouraged()) {
16895           const DRegister& first = nreglist.GetFirstDRegister();
16896           uint32_t len_encoding = nreglist.GetLength() - 1;
16897           EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
16898                      (encoded_align_2.GetEncodingValue() << 4) |
16899                      first.Encode(22, 12) | (len_encoding << 5) |
16900                      (rn.GetCode() << 16));
16901           AdvanceIT();
16902           return;
16903         }
16904       }
16905       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16906       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
16907           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
16908           operand.IsPostIndex() && encoded_align_2.IsValid() &&
16909           (!rn.IsPC() || AllowUnpredictable())) {
16910         if (cond.Is(al) || AllowStronglyDiscouraged()) {
16911           const DRegister& first = nreglist.GetFirstDRegister();
16912           uint32_t len_encoding = nreglist.GetLength() - 1;
16913           EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
16914                      (encoded_align_2.GetEncodingValue() << 4) |
16915                      first.Encode(22, 12) | (len_encoding << 5) |
16916                      (rn.GetCode() << 16));
16917           AdvanceIT();
16918           return;
16919         }
16920       }
16921       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
16922       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16923           (nreglist.GetLength() == 1) && operand.IsOffset() &&
16924           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
16925         if (cond.Is(al) || AllowStronglyDiscouraged()) {
16926           const DRegister& first = nreglist.GetFirstDRegister();
16927           EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
16928                      (encoded_align_3.GetEncodingValue() << 4) |
16929                      first.Encode(22, 12) | (rn.GetCode() << 16));
16930           AdvanceIT();
16931           return;
16932         }
16933       }
16934       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
16935       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
16936           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
16937           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
16938         if (cond.Is(al) || AllowStronglyDiscouraged()) {
16939           const DRegister& first = nreglist.GetFirstDRegister();
16940           EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
16941                      (encoded_align_3.GetEncodingValue() << 4) |
16942                      first.Encode(22, 12) | (rn.GetCode() << 16));
16943           AdvanceIT();
16944           return;
16945         }
16946       }
16947     } else {
16948       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
16949       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16950           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16951           operand.IsOffset() && encoded_align_1.IsValid() &&
16952           (!rn.IsPC() || AllowUnpredictable())) {
16953         if (cond.Is(al)) {
16954           const DRegister& first = nreglist.GetFirstDRegister();
16955           uint32_t len_encoding;
16956           switch (nreglist.GetLength()) {
16957             default:
16958               VIXL_UNREACHABLE_OR_FALLTHROUGH();
16959             case 1:
16960               len_encoding = 0x7;
16961               break;
16962             case 2:
16963               len_encoding = 0xa;
16964               break;
16965             case 3:
16966               len_encoding = 0x6;
16967               break;
16968             case 4:
16969               len_encoding = 0x2;
16970               break;
16971           }
16972           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
16973                   (encoded_align_1.GetEncodingValue() << 4) |
16974                   first.Encode(22, 12) | (len_encoding << 8) |
16975                   (rn.GetCode() << 16));
16976           return;
16977         }
16978       }
16979       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
16980       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
16981           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
16982           operand.IsPostIndex() && encoded_align_1.IsValid() &&
16983           (!rn.IsPC() || AllowUnpredictable())) {
16984         if (cond.Is(al)) {
16985           const DRegister& first = nreglist.GetFirstDRegister();
16986           uint32_t len_encoding;
16987           switch (nreglist.GetLength()) {
16988             default:
16989               VIXL_UNREACHABLE_OR_FALLTHROUGH();
16990             case 1:
16991               len_encoding = 0x7;
16992               break;
16993             case 2:
16994               len_encoding = 0xa;
16995               break;
16996             case 3:
16997               len_encoding = 0x6;
16998               break;
16999             case 4:
17000               len_encoding = 0x2;
17001               break;
17002           }
17003           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17004                   (encoded_align_1.GetEncodingValue() << 4) |
17005                   first.Encode(22, 12) | (len_encoding << 8) |
17006                   (rn.GetCode() << 16));
17007           return;
17008         }
17009       }
17010       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17011       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17012           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
17013           operand.IsOffset() && encoded_align_2.IsValid() &&
17014           (!rn.IsPC() || AllowUnpredictable())) {
17015         if (cond.Is(al)) {
17016           const DRegister& first = nreglist.GetFirstDRegister();
17017           uint32_t len_encoding = nreglist.GetLength() - 1;
17018           EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
17019                   (encoded_align_2.GetEncodingValue() << 4) |
17020                   first.Encode(22, 12) | (len_encoding << 5) |
17021                   (rn.GetCode() << 16));
17022           return;
17023         }
17024       }
17025       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17026       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17027           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
17028           operand.IsPostIndex() && encoded_align_2.IsValid() &&
17029           (!rn.IsPC() || AllowUnpredictable())) {
17030         if (cond.Is(al)) {
17031           const DRegister& first = nreglist.GetFirstDRegister();
17032           uint32_t len_encoding = nreglist.GetLength() - 1;
17033           EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
17034                   (encoded_align_2.GetEncodingValue() << 4) |
17035                   first.Encode(22, 12) | (len_encoding << 5) |
17036                   (rn.GetCode() << 16));
17037           return;
17038         }
17039       }
17040       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17041       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
17042           (nreglist.GetLength() == 1) && operand.IsOffset() &&
17043           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
17044         if (cond.Is(al)) {
17045           const DRegister& first = nreglist.GetFirstDRegister();
17046           EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
17047                   (encoded_align_3.GetEncodingValue() << 4) |
17048                   first.Encode(22, 12) | (rn.GetCode() << 16));
17049           return;
17050         }
17051       }
17052       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17053       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
17054           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
17055           encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
17056         if (cond.Is(al)) {
17057           const DRegister& first = nreglist.GetFirstDRegister();
17058           EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
17059                   (encoded_align_3.GetEncodingValue() << 4) |
17060                   first.Encode(22, 12) | (rn.GetCode() << 16));
17061           return;
17062         }
17063       }
17064     }
17065   }
17066   if (operand.IsPlainRegister()) {
17067     Register rn = operand.GetBaseRegister();
17068     Alignment align = operand.GetAlignment();
17069     Register rm = operand.GetOffsetRegister();
17070     Dt_size_6 encoded_dt(dt);
17071     Dt_size_7 encoded_dt_2(dt);
17072     Align_align_1 encoded_align_1(align, nreglist);
17073     Align_a_1 encoded_align_2(align, dt);
17074     Align_index_align_1 encoded_align_3(align, nreglist, dt);
17075     if (IsUsingT32()) {
17076       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17077       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17078           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
17079           !rm.IsPC() && !rm.IsSP()) {
17080         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17081           const DRegister& first = nreglist.GetFirstDRegister();
17082           uint32_t len_encoding;
17083           switch (nreglist.GetLength()) {
17084             default:
17085               VIXL_UNREACHABLE_OR_FALLTHROUGH();
17086             case 1:
17087               len_encoding = 0x7;
17088               break;
17089             case 2:
17090               len_encoding = 0xa;
17091               break;
17092             case 3:
17093               len_encoding = 0x6;
17094               break;
17095             case 4:
17096               len_encoding = 0x2;
17097               break;
17098           }
17099           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
17100                      (encoded_align_1.GetEncodingValue() << 4) |
17101                      first.Encode(22, 12) | (len_encoding << 8) |
17102                      (rn.GetCode() << 16) | rm.GetCode());
17103           AdvanceIT();
17104           return;
17105         }
17106       }
17107       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17108       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17109           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
17110           !rm.IsPC() && !rm.IsSP()) {
17111         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17112           const DRegister& first = nreglist.GetFirstDRegister();
17113           uint32_t len_encoding = nreglist.GetLength() - 1;
17114           EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
17115                      (encoded_align_2.GetEncodingValue() << 4) |
17116                      first.Encode(22, 12) | (len_encoding << 5) |
17117                      (rn.GetCode() << 16) | rm.GetCode());
17118           AdvanceIT();
17119           return;
17120         }
17121       }
17122       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17123       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
17124           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
17125         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17126           const DRegister& first = nreglist.GetFirstDRegister();
17127           EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
17128                      (encoded_align_3.GetEncodingValue() << 4) |
17129                      first.Encode(22, 12) | (rn.GetCode() << 16) |
17130                      rm.GetCode());
17131           AdvanceIT();
17132           return;
17133         }
17134       }
17135     } else {
17136       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17137       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17138           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
17139           !rm.IsPC() && !rm.IsSP()) {
17140         if (cond.Is(al)) {
17141           const DRegister& first = nreglist.GetFirstDRegister();
17142           uint32_t len_encoding;
17143           switch (nreglist.GetLength()) {
17144             default:
17145               VIXL_UNREACHABLE_OR_FALLTHROUGH();
17146             case 1:
17147               len_encoding = 0x7;
17148               break;
17149             case 2:
17150               len_encoding = 0xa;
17151               break;
17152             case 3:
17153               len_encoding = 0x6;
17154               break;
17155             case 4:
17156               len_encoding = 0x2;
17157               break;
17158           }
17159           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17160                   (encoded_align_1.GetEncodingValue() << 4) |
17161                   first.Encode(22, 12) | (len_encoding << 8) |
17162                   (rn.GetCode() << 16) | rm.GetCode());
17163           return;
17164         }
17165       }
17166       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17167       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17168           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
17169           !rm.IsPC() && !rm.IsSP()) {
17170         if (cond.Is(al)) {
17171           const DRegister& first = nreglist.GetFirstDRegister();
17172           uint32_t len_encoding = nreglist.GetLength() - 1;
17173           EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
17174                   (encoded_align_2.GetEncodingValue() << 4) |
17175                   first.Encode(22, 12) | (len_encoding << 5) |
17176                   (rn.GetCode() << 16) | rm.GetCode());
17177           return;
17178         }
17179       }
17180       // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17181       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
17182           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
17183         if (cond.Is(al)) {
17184           const DRegister& first = nreglist.GetFirstDRegister();
17185           EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
17186                   (encoded_align_3.GetEncodingValue() << 4) |
17187                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17188           return;
17189         }
17190       }
17191     }
17192   }
17193   Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand);
17194 }
17195 
vld2(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)17196 void Assembler::vld2(Condition cond,
17197                      DataType dt,
17198                      const NeonRegisterList& nreglist,
17199                      const AlignedMemOperand& operand) {
17200   VIXL_ASSERT(AllowAssembler());
17201   CheckIT(cond);
17202   if (operand.IsImmediateZero()) {
17203     Register rn = operand.GetBaseRegister();
17204     Alignment align = operand.GetAlignment();
17205     Dt_size_7 encoded_dt(dt);
17206     Align_align_2 encoded_align_1(align, nreglist);
17207     Align_a_2 encoded_align_2(align, dt);
17208     Align_index_align_2 encoded_align_3(align, nreglist, dt);
17209     if (IsUsingT32()) {
17210       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17211       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17212           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17213            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17214            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17215           operand.IsOffset() && encoded_align_1.IsValid() &&
17216           (!rn.IsPC() || AllowUnpredictable())) {
17217         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17218           const DRegister& first = nreglist.GetFirstDRegister();
17219           uint32_t len_encoding;
17220           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17221             len_encoding = 0x8;
17222           }
17223           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17224             len_encoding = 0x9;
17225           }
17226           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17227             len_encoding = 0x3;
17228           }
17229           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
17230                      (encoded_align_1.GetEncodingValue() << 4) |
17231                      first.Encode(22, 12) | (len_encoding << 8) |
17232                      (rn.GetCode() << 16));
17233           AdvanceIT();
17234           return;
17235         }
17236       }
17237       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17238       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17239           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17240            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17241            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17242           operand.IsPostIndex() && encoded_align_1.IsValid() &&
17243           (!rn.IsPC() || AllowUnpredictable())) {
17244         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17245           const DRegister& first = nreglist.GetFirstDRegister();
17246           uint32_t len_encoding;
17247           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17248             len_encoding = 0x8;
17249           }
17250           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17251             len_encoding = 0x9;
17252           }
17253           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17254             len_encoding = 0x3;
17255           }
17256           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
17257                      (encoded_align_1.GetEncodingValue() << 4) |
17258                      first.Encode(22, 12) | (len_encoding << 8) |
17259                      (rn.GetCode() << 16));
17260           AdvanceIT();
17261           return;
17262         }
17263       }
17264       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17265       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17266           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17267            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17268           operand.IsOffset() && encoded_align_2.IsValid() &&
17269           (!rn.IsPC() || AllowUnpredictable())) {
17270         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17271           const DRegister& first = nreglist.GetFirstDRegister();
17272           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17273           EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
17274                      (encoded_align_2.GetEncodingValue() << 4) |
17275                      first.Encode(22, 12) | (len_encoding << 5) |
17276                      (rn.GetCode() << 16));
17277           AdvanceIT();
17278           return;
17279         }
17280       }
17281       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17282       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17283           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17284            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17285           operand.IsPostIndex() && encoded_align_2.IsValid() &&
17286           (!rn.IsPC() || AllowUnpredictable())) {
17287         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17288           const DRegister& first = nreglist.GetFirstDRegister();
17289           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17290           EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
17291                      (encoded_align_2.GetEncodingValue() << 4) |
17292                      first.Encode(22, 12) | (len_encoding << 5) |
17293                      (rn.GetCode() << 16));
17294           AdvanceIT();
17295           return;
17296         }
17297       }
17298       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17299       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17300           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17301            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17302           operand.IsOffset() && encoded_align_3.IsValid() &&
17303           (!rn.IsPC() || AllowUnpredictable())) {
17304         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17305           const DRegister& first = nreglist.GetFirstDRegister();
17306           EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) |
17307                      (encoded_align_3.GetEncodingValue() << 4) |
17308                      first.Encode(22, 12) | (rn.GetCode() << 16));
17309           AdvanceIT();
17310           return;
17311         }
17312       }
17313       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17314       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17315           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17316            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17317           operand.IsPostIndex() && encoded_align_3.IsValid() &&
17318           (!rn.IsPC() || AllowUnpredictable())) {
17319         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17320           const DRegister& first = nreglist.GetFirstDRegister();
17321           EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) |
17322                      (encoded_align_3.GetEncodingValue() << 4) |
17323                      first.Encode(22, 12) | (rn.GetCode() << 16));
17324           AdvanceIT();
17325           return;
17326         }
17327       }
17328     } else {
17329       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17330       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17331           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17332            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17333            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17334           operand.IsOffset() && encoded_align_1.IsValid() &&
17335           (!rn.IsPC() || AllowUnpredictable())) {
17336         if (cond.Is(al)) {
17337           const DRegister& first = nreglist.GetFirstDRegister();
17338           uint32_t len_encoding;
17339           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17340             len_encoding = 0x8;
17341           }
17342           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17343             len_encoding = 0x9;
17344           }
17345           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17346             len_encoding = 0x3;
17347           }
17348           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
17349                   (encoded_align_1.GetEncodingValue() << 4) |
17350                   first.Encode(22, 12) | (len_encoding << 8) |
17351                   (rn.GetCode() << 16));
17352           return;
17353         }
17354       }
17355       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17356       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17357           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17358            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17359            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17360           operand.IsPostIndex() && encoded_align_1.IsValid() &&
17361           (!rn.IsPC() || AllowUnpredictable())) {
17362         if (cond.Is(al)) {
17363           const DRegister& first = nreglist.GetFirstDRegister();
17364           uint32_t len_encoding;
17365           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17366             len_encoding = 0x8;
17367           }
17368           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17369             len_encoding = 0x9;
17370           }
17371           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17372             len_encoding = 0x3;
17373           }
17374           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17375                   (encoded_align_1.GetEncodingValue() << 4) |
17376                   first.Encode(22, 12) | (len_encoding << 8) |
17377                   (rn.GetCode() << 16));
17378           return;
17379         }
17380       }
17381       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17382       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17383           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17384            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17385           operand.IsOffset() && encoded_align_2.IsValid() &&
17386           (!rn.IsPC() || AllowUnpredictable())) {
17387         if (cond.Is(al)) {
17388           const DRegister& first = nreglist.GetFirstDRegister();
17389           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17390           EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
17391                   (encoded_align_2.GetEncodingValue() << 4) |
17392                   first.Encode(22, 12) | (len_encoding << 5) |
17393                   (rn.GetCode() << 16));
17394           return;
17395         }
17396       }
17397       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17398       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17399           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17400            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17401           operand.IsPostIndex() && encoded_align_2.IsValid() &&
17402           (!rn.IsPC() || AllowUnpredictable())) {
17403         if (cond.Is(al)) {
17404           const DRegister& first = nreglist.GetFirstDRegister();
17405           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17406           EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
17407                   (encoded_align_2.GetEncodingValue() << 4) |
17408                   first.Encode(22, 12) | (len_encoding << 5) |
17409                   (rn.GetCode() << 16));
17410           return;
17411         }
17412       }
17413       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17414       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17415           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17416            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17417           operand.IsOffset() && encoded_align_3.IsValid() &&
17418           (!rn.IsPC() || AllowUnpredictable())) {
17419         if (cond.Is(al)) {
17420           const DRegister& first = nreglist.GetFirstDRegister();
17421           EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) |
17422                   (encoded_align_3.GetEncodingValue() << 4) |
17423                   first.Encode(22, 12) | (rn.GetCode() << 16));
17424           return;
17425         }
17426       }
17427       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17428       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17429           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17430            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17431           operand.IsPostIndex() && encoded_align_3.IsValid() &&
17432           (!rn.IsPC() || AllowUnpredictable())) {
17433         if (cond.Is(al)) {
17434           const DRegister& first = nreglist.GetFirstDRegister();
17435           EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) |
17436                   (encoded_align_3.GetEncodingValue() << 4) |
17437                   first.Encode(22, 12) | (rn.GetCode() << 16));
17438           return;
17439         }
17440       }
17441     }
17442   }
17443   if (operand.IsPlainRegister()) {
17444     Register rn = operand.GetBaseRegister();
17445     Alignment align = operand.GetAlignment();
17446     Register rm = operand.GetOffsetRegister();
17447     Dt_size_7 encoded_dt(dt);
17448     Align_align_2 encoded_align_1(align, nreglist);
17449     Align_a_2 encoded_align_2(align, dt);
17450     Align_index_align_2 encoded_align_3(align, nreglist, dt);
17451     if (IsUsingT32()) {
17452       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17453       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17454           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17455            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17456            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17457           !rm.IsPC() && !rm.IsSP()) {
17458         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17459           const DRegister& first = nreglist.GetFirstDRegister();
17460           uint32_t len_encoding;
17461           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17462             len_encoding = 0x8;
17463           }
17464           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17465             len_encoding = 0x9;
17466           }
17467           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17468             len_encoding = 0x3;
17469           }
17470           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
17471                      (encoded_align_1.GetEncodingValue() << 4) |
17472                      first.Encode(22, 12) | (len_encoding << 8) |
17473                      (rn.GetCode() << 16) | rm.GetCode());
17474           AdvanceIT();
17475           return;
17476         }
17477       }
17478       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17479       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17480           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17481            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17482           !rm.IsPC() && !rm.IsSP()) {
17483         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17484           const DRegister& first = nreglist.GetFirstDRegister();
17485           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17486           EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) |
17487                      (encoded_align_2.GetEncodingValue() << 4) |
17488                      first.Encode(22, 12) | (len_encoding << 5) |
17489                      (rn.GetCode() << 16) | rm.GetCode());
17490           AdvanceIT();
17491           return;
17492         }
17493       }
17494       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17495       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17496           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17497            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17498           !rm.IsPC() && !rm.IsSP()) {
17499         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17500           const DRegister& first = nreglist.GetFirstDRegister();
17501           EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) |
17502                      (encoded_align_3.GetEncodingValue() << 4) |
17503                      first.Encode(22, 12) | (rn.GetCode() << 16) |
17504                      rm.GetCode());
17505           AdvanceIT();
17506           return;
17507         }
17508       }
17509     } else {
17510       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17511       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17512           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17513            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
17514            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
17515           !rm.IsPC() && !rm.IsSP()) {
17516         if (cond.Is(al)) {
17517           const DRegister& first = nreglist.GetFirstDRegister();
17518           uint32_t len_encoding;
17519           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
17520             len_encoding = 0x8;
17521           }
17522           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
17523             len_encoding = 0x9;
17524           }
17525           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
17526             len_encoding = 0x3;
17527           }
17528           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17529                   (encoded_align_1.GetEncodingValue() << 4) |
17530                   first.Encode(22, 12) | (len_encoding << 8) |
17531                   (rn.GetCode() << 16) | rm.GetCode());
17532           return;
17533         }
17534       }
17535       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17536       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17537           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17538            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17539           !rm.IsPC() && !rm.IsSP()) {
17540         if (cond.Is(al)) {
17541           const DRegister& first = nreglist.GetFirstDRegister();
17542           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17543           EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) |
17544                   (encoded_align_2.GetEncodingValue() << 4) |
17545                   first.Encode(22, 12) | (len_encoding << 5) |
17546                   (rn.GetCode() << 16) | rm.GetCode());
17547           return;
17548         }
17549       }
17550       // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17551       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17552           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
17553            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
17554           !rm.IsPC() && !rm.IsSP()) {
17555         if (cond.Is(al)) {
17556           const DRegister& first = nreglist.GetFirstDRegister();
17557           EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) |
17558                   (encoded_align_3.GetEncodingValue() << 4) |
17559                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17560           return;
17561         }
17562       }
17563     }
17564   }
17565   Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand);
17566 }
17567 
vld3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)17568 void Assembler::vld3(Condition cond,
17569                      DataType dt,
17570                      const NeonRegisterList& nreglist,
17571                      const AlignedMemOperand& operand) {
17572   VIXL_ASSERT(AllowAssembler());
17573   CheckIT(cond);
17574   if (operand.IsImmediateZero()) {
17575     Register rn = operand.GetBaseRegister();
17576     Alignment align = operand.GetAlignment();
17577     Dt_size_7 encoded_dt(dt);
17578     Align_align_3 encoded_align_1(align);
17579     if (IsUsingT32()) {
17580       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17581       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17582           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17583            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17584           operand.IsOffset() && encoded_align_1.IsValid() &&
17585           (!rn.IsPC() || AllowUnpredictable())) {
17586         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17587           const DRegister& first = nreglist.GetFirstDRegister();
17588           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17589           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
17590                      (encoded_align_1.GetEncodingValue() << 4) |
17591                      first.Encode(22, 12) | (len_encoding << 8) |
17592                      (rn.GetCode() << 16));
17593           AdvanceIT();
17594           return;
17595         }
17596       }
17597       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17598       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17599           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17600            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17601           operand.IsPostIndex() && encoded_align_1.IsValid() &&
17602           (!rn.IsPC() || AllowUnpredictable())) {
17603         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17604           const DRegister& first = nreglist.GetFirstDRegister();
17605           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17606           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
17607                      (encoded_align_1.GetEncodingValue() << 4) |
17608                      first.Encode(22, 12) | (len_encoding << 8) |
17609                      (rn.GetCode() << 16));
17610           AdvanceIT();
17611           return;
17612         }
17613       }
17614     } else {
17615       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
17616       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17617           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17618            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17619           operand.IsOffset() && encoded_align_1.IsValid() &&
17620           (!rn.IsPC() || AllowUnpredictable())) {
17621         if (cond.Is(al)) {
17622           const DRegister& first = nreglist.GetFirstDRegister();
17623           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17624           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
17625                   (encoded_align_1.GetEncodingValue() << 4) |
17626                   first.Encode(22, 12) | (len_encoding << 8) |
17627                   (rn.GetCode() << 16));
17628           return;
17629         }
17630       }
17631       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
17632       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17633           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17634            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17635           operand.IsPostIndex() && encoded_align_1.IsValid() &&
17636           (!rn.IsPC() || AllowUnpredictable())) {
17637         if (cond.Is(al)) {
17638           const DRegister& first = nreglist.GetFirstDRegister();
17639           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17640           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
17641                   (encoded_align_1.GetEncodingValue() << 4) |
17642                   first.Encode(22, 12) | (len_encoding << 8) |
17643                   (rn.GetCode() << 16));
17644           return;
17645         }
17646       }
17647     }
17648   }
17649   if (operand.IsPlainRegister()) {
17650     Register rn = operand.GetBaseRegister();
17651     Alignment align = operand.GetAlignment();
17652     Register rm = operand.GetOffsetRegister();
17653     Dt_size_7 encoded_dt(dt);
17654     Align_align_3 encoded_align_1(align);
17655     if (IsUsingT32()) {
17656       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
17657       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17658           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17659            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17660           !rm.IsPC() && !rm.IsSP()) {
17661         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17662           const DRegister& first = nreglist.GetFirstDRegister();
17663           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17664           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
17665                      (encoded_align_1.GetEncodingValue() << 4) |
17666                      first.Encode(22, 12) | (len_encoding << 8) |
17667                      (rn.GetCode() << 16) | rm.GetCode());
17668           AdvanceIT();
17669           return;
17670         }
17671       }
17672     } else {
17673       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
17674       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17675           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17676            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17677           !rm.IsPC() && !rm.IsSP()) {
17678         if (cond.Is(al)) {
17679           const DRegister& first = nreglist.GetFirstDRegister();
17680           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
17681           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
17682                   (encoded_align_1.GetEncodingValue() << 4) |
17683                   first.Encode(22, 12) | (len_encoding << 8) |
17684                   (rn.GetCode() << 16) | rm.GetCode());
17685           return;
17686         }
17687       }
17688     }
17689   }
17690   Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
17691 }
17692 
vld3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const MemOperand & operand)17693 void Assembler::vld3(Condition cond,
17694                      DataType dt,
17695                      const NeonRegisterList& nreglist,
17696                      const MemOperand& operand) {
17697   VIXL_ASSERT(AllowAssembler());
17698   CheckIT(cond);
17699   if (operand.IsImmediateZero()) {
17700     Register rn = operand.GetBaseRegister();
17701     Dt_size_7 encoded_dt(dt);
17702     Index_1 encoded_align_1(nreglist, dt);
17703     if (IsUsingT32()) {
17704       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
17705       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17706           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17707            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17708           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
17709         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17710           const DRegister& first = nreglist.GetFirstDRegister();
17711           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17712           EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
17713                      first.Encode(22, 12) | (len_encoding << 5) |
17714                      (rn.GetCode() << 16));
17715           AdvanceIT();
17716           return;
17717         }
17718       }
17719       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
17720       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17721           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17722            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17723           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
17724         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17725           const DRegister& first = nreglist.GetFirstDRegister();
17726           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17727           EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
17728                      first.Encode(22, 12) | (len_encoding << 5) |
17729                      (rn.GetCode() << 16));
17730           AdvanceIT();
17731           return;
17732         }
17733       }
17734       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
17735       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17736           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17737            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17738           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
17739         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17740           const DRegister& first = nreglist.GetFirstDRegister();
17741           EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) |
17742                      (encoded_align_1.GetEncodingValue() << 4) |
17743                      first.Encode(22, 12) | (rn.GetCode() << 16));
17744           AdvanceIT();
17745           return;
17746         }
17747       }
17748       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
17749       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17750           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17751            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17752           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
17753         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17754           const DRegister& first = nreglist.GetFirstDRegister();
17755           EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) |
17756                      (encoded_align_1.GetEncodingValue() << 4) |
17757                      first.Encode(22, 12) | (rn.GetCode() << 16));
17758           AdvanceIT();
17759           return;
17760         }
17761       }
17762     } else {
17763       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
17764       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17765           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17766            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17767           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
17768         if (cond.Is(al)) {
17769           const DRegister& first = nreglist.GetFirstDRegister();
17770           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17771           EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
17772                   first.Encode(22, 12) | (len_encoding << 5) |
17773                   (rn.GetCode() << 16));
17774           return;
17775         }
17776       }
17777       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
17778       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17779           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17780            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17781           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
17782         if (cond.Is(al)) {
17783           const DRegister& first = nreglist.GetFirstDRegister();
17784           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17785           EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
17786                   first.Encode(22, 12) | (len_encoding << 5) |
17787                   (rn.GetCode() << 16));
17788           return;
17789         }
17790       }
17791       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
17792       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17793           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17794            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17795           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
17796         if (cond.Is(al)) {
17797           const DRegister& first = nreglist.GetFirstDRegister();
17798           EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) |
17799                   (encoded_align_1.GetEncodingValue() << 4) |
17800                   first.Encode(22, 12) | (rn.GetCode() << 16));
17801           return;
17802         }
17803       }
17804       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
17805       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17806           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17807            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17808           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
17809         if (cond.Is(al)) {
17810           const DRegister& first = nreglist.GetFirstDRegister();
17811           EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) |
17812                   (encoded_align_1.GetEncodingValue() << 4) |
17813                   first.Encode(22, 12) | (rn.GetCode() << 16));
17814           return;
17815         }
17816       }
17817     }
17818   }
17819   if (operand.IsPlainRegister()) {
17820     Register rn = operand.GetBaseRegister();
17821     Sign sign = operand.GetSign();
17822     Register rm = operand.GetOffsetRegister();
17823     Dt_size_7 encoded_dt(dt);
17824     Index_1 encoded_align_1(nreglist, dt);
17825     if (IsUsingT32()) {
17826       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
17827       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17828           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17829            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17830           sign.IsPlus() && operand.IsPostIndex()) {
17831         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17832           const DRegister& first = nreglist.GetFirstDRegister();
17833           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17834           EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) |
17835                      first.Encode(22, 12) | (len_encoding << 5) |
17836                      (rn.GetCode() << 16) | rm.GetCode());
17837           AdvanceIT();
17838           return;
17839         }
17840       }
17841       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
17842       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17843           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17844            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17845           sign.IsPlus() && operand.IsPostIndex()) {
17846         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17847           const DRegister& first = nreglist.GetFirstDRegister();
17848           EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) |
17849                      (encoded_align_1.GetEncodingValue() << 4) |
17850                      first.Encode(22, 12) | (rn.GetCode() << 16) |
17851                      rm.GetCode());
17852           AdvanceIT();
17853           return;
17854         }
17855       }
17856     } else {
17857       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
17858       if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
17859           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17860            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17861           sign.IsPlus() && operand.IsPostIndex()) {
17862         if (cond.Is(al)) {
17863           const DRegister& first = nreglist.GetFirstDRegister();
17864           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17865           EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) |
17866                   first.Encode(22, 12) | (len_encoding << 5) |
17867                   (rn.GetCode() << 16) | rm.GetCode());
17868           return;
17869         }
17870       }
17871       // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
17872       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17873           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
17874            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
17875           sign.IsPlus() && operand.IsPostIndex()) {
17876         if (cond.Is(al)) {
17877           const DRegister& first = nreglist.GetFirstDRegister();
17878           EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) |
17879                   (encoded_align_1.GetEncodingValue() << 4) |
17880                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
17881           return;
17882         }
17883       }
17884     }
17885   }
17886   Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
17887 }
17888 
vld4(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)17889 void Assembler::vld4(Condition cond,
17890                      DataType dt,
17891                      const NeonRegisterList& nreglist,
17892                      const AlignedMemOperand& operand) {
17893   VIXL_ASSERT(AllowAssembler());
17894   CheckIT(cond);
17895   if (operand.IsImmediateZero()) {
17896     Register rn = operand.GetBaseRegister();
17897     Alignment align = operand.GetAlignment();
17898     Dt_size_7 encoded_dt(dt);
17899     Dt_size_8 encoded_dt_2(dt, align);
17900     Align_align_4 encoded_align_1(align);
17901     Align_a_3 encoded_align_2(align, dt);
17902     Align_index_align_3 encoded_align_3(align, nreglist, dt);
17903     if (IsUsingT32()) {
17904       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17905       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17906           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17907            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17908           operand.IsOffset() && encoded_align_1.IsValid() &&
17909           (!rn.IsPC() || AllowUnpredictable())) {
17910         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17911           const DRegister& first = nreglist.GetFirstDRegister();
17912           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17913           EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
17914                      (encoded_align_1.GetEncodingValue() << 4) |
17915                      first.Encode(22, 12) | (len_encoding << 8) |
17916                      (rn.GetCode() << 16));
17917           AdvanceIT();
17918           return;
17919         }
17920       }
17921       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17922       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
17923           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17924            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17925           operand.IsPostIndex() && encoded_align_1.IsValid() &&
17926           (!rn.IsPC() || AllowUnpredictable())) {
17927         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17928           const DRegister& first = nreglist.GetFirstDRegister();
17929           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17930           EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
17931                      (encoded_align_1.GetEncodingValue() << 4) |
17932                      first.Encode(22, 12) | (len_encoding << 8) |
17933                      (rn.GetCode() << 16));
17934           AdvanceIT();
17935           return;
17936         }
17937       }
17938       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17939       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17940           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17941            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17942           operand.IsOffset() && encoded_align_2.IsValid() &&
17943           (!rn.IsPC() || AllowUnpredictable())) {
17944         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17945           const DRegister& first = nreglist.GetFirstDRegister();
17946           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17947           EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
17948                      (encoded_align_2.GetEncodingValue() << 4) |
17949                      first.Encode(22, 12) | (len_encoding << 5) |
17950                      (rn.GetCode() << 16));
17951           AdvanceIT();
17952           return;
17953         }
17954       }
17955       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17956       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
17957           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17958            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17959           operand.IsPostIndex() && encoded_align_2.IsValid() &&
17960           (!rn.IsPC() || AllowUnpredictable())) {
17961         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17962           const DRegister& first = nreglist.GetFirstDRegister();
17963           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
17964           EmitT32_32(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
17965                      (encoded_align_2.GetEncodingValue() << 4) |
17966                      first.Encode(22, 12) | (len_encoding << 5) |
17967                      (rn.GetCode() << 16));
17968           AdvanceIT();
17969           return;
17970         }
17971       }
17972       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
17973       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17974           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17975            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17976           operand.IsOffset() && encoded_align_3.IsValid() &&
17977           (!rn.IsPC() || AllowUnpredictable())) {
17978         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17979           const DRegister& first = nreglist.GetFirstDRegister();
17980           EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) |
17981                      (encoded_align_3.GetEncodingValue() << 4) |
17982                      first.Encode(22, 12) | (rn.GetCode() << 16));
17983           AdvanceIT();
17984           return;
17985         }
17986       }
17987       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
17988       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
17989           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
17990            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
17991           operand.IsPostIndex() && encoded_align_3.IsValid() &&
17992           (!rn.IsPC() || AllowUnpredictable())) {
17993         if (cond.Is(al) || AllowStronglyDiscouraged()) {
17994           const DRegister& first = nreglist.GetFirstDRegister();
17995           EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) |
17996                      (encoded_align_3.GetEncodingValue() << 4) |
17997                      first.Encode(22, 12) | (rn.GetCode() << 16));
17998           AdvanceIT();
17999           return;
18000         }
18001       }
18002     } else {
18003       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18004       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18005           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18006            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18007           operand.IsOffset() && encoded_align_1.IsValid() &&
18008           (!rn.IsPC() || AllowUnpredictable())) {
18009         if (cond.Is(al)) {
18010           const DRegister& first = nreglist.GetFirstDRegister();
18011           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18012           EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
18013                   (encoded_align_1.GetEncodingValue() << 4) |
18014                   first.Encode(22, 12) | (len_encoding << 8) |
18015                   (rn.GetCode() << 16));
18016           return;
18017         }
18018       }
18019       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18020       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18021           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18022            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18023           operand.IsPostIndex() && encoded_align_1.IsValid() &&
18024           (!rn.IsPC() || AllowUnpredictable())) {
18025         if (cond.Is(al)) {
18026           const DRegister& first = nreglist.GetFirstDRegister();
18027           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18028           EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
18029                   (encoded_align_1.GetEncodingValue() << 4) |
18030                   first.Encode(22, 12) | (len_encoding << 8) |
18031                   (rn.GetCode() << 16));
18032           return;
18033         }
18034       }
18035       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18036       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18037           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18038            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18039           operand.IsOffset() && encoded_align_2.IsValid() &&
18040           (!rn.IsPC() || AllowUnpredictable())) {
18041         if (cond.Is(al)) {
18042           const DRegister& first = nreglist.GetFirstDRegister();
18043           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18044           EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
18045                   (encoded_align_2.GetEncodingValue() << 4) |
18046                   first.Encode(22, 12) | (len_encoding << 5) |
18047                   (rn.GetCode() << 16));
18048           return;
18049         }
18050       }
18051       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18052       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18053           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18054            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18055           operand.IsPostIndex() && encoded_align_2.IsValid() &&
18056           (!rn.IsPC() || AllowUnpredictable())) {
18057         if (cond.Is(al)) {
18058           const DRegister& first = nreglist.GetFirstDRegister();
18059           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18060           EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
18061                   (encoded_align_2.GetEncodingValue() << 4) |
18062                   first.Encode(22, 12) | (len_encoding << 5) |
18063                   (rn.GetCode() << 16));
18064           return;
18065         }
18066       }
18067       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18068       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18069           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18070            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18071           operand.IsOffset() && encoded_align_3.IsValid() &&
18072           (!rn.IsPC() || AllowUnpredictable())) {
18073         if (cond.Is(al)) {
18074           const DRegister& first = nreglist.GetFirstDRegister();
18075           EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) |
18076                   (encoded_align_3.GetEncodingValue() << 4) |
18077                   first.Encode(22, 12) | (rn.GetCode() << 16));
18078           return;
18079         }
18080       }
18081       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18082       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18083           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18084            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18085           operand.IsPostIndex() && encoded_align_3.IsValid() &&
18086           (!rn.IsPC() || AllowUnpredictable())) {
18087         if (cond.Is(al)) {
18088           const DRegister& first = nreglist.GetFirstDRegister();
18089           EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) |
18090                   (encoded_align_3.GetEncodingValue() << 4) |
18091                   first.Encode(22, 12) | (rn.GetCode() << 16));
18092           return;
18093         }
18094       }
18095     }
18096   }
18097   if (operand.IsPlainRegister()) {
18098     Register rn = operand.GetBaseRegister();
18099     Alignment align = operand.GetAlignment();
18100     Register rm = operand.GetOffsetRegister();
18101     Dt_size_7 encoded_dt(dt);
18102     Dt_size_8 encoded_dt_2(dt, align);
18103     Align_align_4 encoded_align_1(align);
18104     Align_a_3 encoded_align_2(align, dt);
18105     Align_index_align_3 encoded_align_3(align, nreglist, dt);
18106     if (IsUsingT32()) {
18107       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18108       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18109           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18110            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18111           !rm.IsPC() && !rm.IsSP()) {
18112         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18113           const DRegister& first = nreglist.GetFirstDRegister();
18114           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18115           EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
18116                      (encoded_align_1.GetEncodingValue() << 4) |
18117                      first.Encode(22, 12) | (len_encoding << 8) |
18118                      (rn.GetCode() << 16) | rm.GetCode());
18119           AdvanceIT();
18120           return;
18121         }
18122       }
18123       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18124       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18125           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18126            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18127           !rm.IsPC() && !rm.IsSP()) {
18128         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18129           const DRegister& first = nreglist.GetFirstDRegister();
18130           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18131           EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
18132                      (encoded_align_2.GetEncodingValue() << 4) |
18133                      first.Encode(22, 12) | (len_encoding << 5) |
18134                      (rn.GetCode() << 16) | rm.GetCode());
18135           AdvanceIT();
18136           return;
18137         }
18138       }
18139       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18140       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18141           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18142            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18143           !rm.IsPC() && !rm.IsSP()) {
18144         if (cond.Is(al) || AllowStronglyDiscouraged()) {
18145           const DRegister& first = nreglist.GetFirstDRegister();
18146           EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) |
18147                      (encoded_align_3.GetEncodingValue() << 4) |
18148                      first.Encode(22, 12) | (rn.GetCode() << 16) |
18149                      rm.GetCode());
18150           AdvanceIT();
18151           return;
18152         }
18153       }
18154     } else {
18155       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18156       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18157           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18158            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18159           !rm.IsPC() && !rm.IsSP()) {
18160         if (cond.Is(al)) {
18161           const DRegister& first = nreglist.GetFirstDRegister();
18162           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18163           EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
18164                   (encoded_align_1.GetEncodingValue() << 4) |
18165                   first.Encode(22, 12) | (len_encoding << 8) |
18166                   (rn.GetCode() << 16) | rm.GetCode());
18167           return;
18168         }
18169       }
18170       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18171       if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18172           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18173            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18174           !rm.IsPC() && !rm.IsSP()) {
18175         if (cond.Is(al)) {
18176           const DRegister& first = nreglist.GetFirstDRegister();
18177           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18178           EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
18179                   (encoded_align_2.GetEncodingValue() << 4) |
18180                   first.Encode(22, 12) | (len_encoding << 5) |
18181                   (rn.GetCode() << 16) | rm.GetCode());
18182           return;
18183         }
18184       }
18185       // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18186       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18187           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
18188            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
18189           !rm.IsPC() && !rm.IsSP()) {
18190         if (cond.Is(al)) {
18191           const DRegister& first = nreglist.GetFirstDRegister();
18192           EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) |
18193                   (encoded_align_3.GetEncodingValue() << 4) |
18194                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
18195           return;
18196         }
18197       }
18198     }
18199   }
18200   Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand);
18201 }
18202 
vldm(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)18203 void Assembler::vldm(Condition cond,
18204                      DataType dt,
18205                      Register rn,
18206                      WriteBack write_back,
18207                      DRegisterList dreglist) {
18208   VIXL_ASSERT(AllowAssembler());
18209   CheckIT(cond);
18210   USE(dt);
18211   if (IsUsingT32()) {
18212     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
18213     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18214       const DRegister& dreg = dreglist.GetFirstDRegister();
18215       unsigned len = dreglist.GetLength() * 2;
18216       EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
18217                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18218                  (len & 0xff));
18219       AdvanceIT();
18220       return;
18221     }
18222   } else {
18223     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
18224     if (cond.IsNotNever() &&
18225         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18226       const DRegister& dreg = dreglist.GetFirstDRegister();
18227       unsigned len = dreglist.GetLength() * 2;
18228       EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18229               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18230               (len & 0xff));
18231       return;
18232     }
18233   }
18234   Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist);
18235 }
18236 
vldm(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)18237 void Assembler::vldm(Condition cond,
18238                      DataType dt,
18239                      Register rn,
18240                      WriteBack write_back,
18241                      SRegisterList sreglist) {
18242   VIXL_ASSERT(AllowAssembler());
18243   CheckIT(cond);
18244   USE(dt);
18245   if (IsUsingT32()) {
18246     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
18247     const SRegister& sreg = sreglist.GetFirstSRegister();
18248     unsigned len = sreglist.GetLength();
18249     EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
18250                (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18251                (len & 0xff));
18252     AdvanceIT();
18253     return;
18254   } else {
18255     // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
18256     if (cond.IsNotNever()) {
18257       const SRegister& sreg = sreglist.GetFirstSRegister();
18258       unsigned len = sreglist.GetLength();
18259       EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18260               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18261               (len & 0xff));
18262       return;
18263     }
18264   }
18265   Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist);
18266 }
18267 
vldmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)18268 void Assembler::vldmdb(Condition cond,
18269                        DataType dt,
18270                        Register rn,
18271                        WriteBack write_back,
18272                        DRegisterList dreglist) {
18273   VIXL_ASSERT(AllowAssembler());
18274   CheckIT(cond);
18275   USE(dt);
18276   if (IsUsingT32()) {
18277     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
18278     if (write_back.DoesWriteBack() &&
18279         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18280       const DRegister& dreg = dreglist.GetFirstDRegister();
18281       unsigned len = dreglist.GetLength() * 2;
18282       EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
18283                  (len & 0xff));
18284       AdvanceIT();
18285       return;
18286     }
18287   } else {
18288     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
18289     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
18290         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18291       const DRegister& dreg = dreglist.GetFirstDRegister();
18292       unsigned len = dreglist.GetLength() * 2;
18293       EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18294               dreg.Encode(22, 12) | (len & 0xff));
18295       return;
18296     }
18297   }
18298   Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist);
18299 }
18300 
vldmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)18301 void Assembler::vldmdb(Condition cond,
18302                        DataType dt,
18303                        Register rn,
18304                        WriteBack write_back,
18305                        SRegisterList sreglist) {
18306   VIXL_ASSERT(AllowAssembler());
18307   CheckIT(cond);
18308   USE(dt);
18309   if (IsUsingT32()) {
18310     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
18311     if (write_back.DoesWriteBack()) {
18312       const SRegister& sreg = sreglist.GetFirstSRegister();
18313       unsigned len = sreglist.GetLength();
18314       EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
18315                  (len & 0xff));
18316       AdvanceIT();
18317       return;
18318     }
18319   } else {
18320     // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
18321     if (write_back.DoesWriteBack() && cond.IsNotNever()) {
18322       const SRegister& sreg = sreglist.GetFirstSRegister();
18323       unsigned len = sreglist.GetLength();
18324       EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18325               sreg.Encode(22, 12) | (len & 0xff));
18326       return;
18327     }
18328   }
18329   Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist);
18330 }
18331 
vldmia(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)18332 void Assembler::vldmia(Condition cond,
18333                        DataType dt,
18334                        Register rn,
18335                        WriteBack write_back,
18336                        DRegisterList dreglist) {
18337   VIXL_ASSERT(AllowAssembler());
18338   CheckIT(cond);
18339   USE(dt);
18340   if (IsUsingT32()) {
18341     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
18342     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18343       const DRegister& dreg = dreglist.GetFirstDRegister();
18344       unsigned len = dreglist.GetLength() * 2;
18345       EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
18346                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18347                  (len & 0xff));
18348       AdvanceIT();
18349       return;
18350     }
18351   } else {
18352     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
18353     if (cond.IsNotNever() &&
18354         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
18355       const DRegister& dreg = dreglist.GetFirstDRegister();
18356       unsigned len = dreglist.GetLength() * 2;
18357       EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18358               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
18359               (len & 0xff));
18360       return;
18361     }
18362   }
18363   Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist);
18364 }
18365 
vldmia(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)18366 void Assembler::vldmia(Condition cond,
18367                        DataType dt,
18368                        Register rn,
18369                        WriteBack write_back,
18370                        SRegisterList sreglist) {
18371   VIXL_ASSERT(AllowAssembler());
18372   CheckIT(cond);
18373   USE(dt);
18374   if (IsUsingT32()) {
18375     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
18376     const SRegister& sreg = sreglist.GetFirstSRegister();
18377     unsigned len = sreglist.GetLength();
18378     EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
18379                (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18380                (len & 0xff));
18381     AdvanceIT();
18382     return;
18383   } else {
18384     // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
18385     if (cond.IsNotNever()) {
18386       const SRegister& sreg = sreglist.GetFirstSRegister();
18387       unsigned len = sreglist.GetLength();
18388       EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
18389               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
18390               (len & 0xff));
18391       return;
18392     }
18393   }
18394   Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist);
18395 }
18396 
vldr(Condition cond,DataType dt,DRegister rd,Label * label)18397 void Assembler::vldr(Condition cond, DataType dt, DRegister rd, Label* label) {
18398   VIXL_ASSERT(AllowAssembler());
18399   CheckIT(cond);
18400   Label::Offset offset =
18401       label->IsBound()
18402           ? label->GetLocation() -
18403                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
18404           : 0;
18405   if (IsUsingT32()) {
18406     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
18407     if (dt.IsNoneOr(Untyped64) &&
18408         ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18409           ((offset & 0x3) == 0)) ||
18410          !label->IsBound())) {
18411       static class EmitOp : public Label::LabelEmitOperator {
18412        public:
18413         EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18414         virtual uint32_t Encode(uint32_t instr,
18415                                 Label::Offset pc,
18416                                 const Label* label) const VIXL_OVERRIDE {
18417           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18418           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18419                       ((offset & 0x3) == 0));
18420           int32_t target = offset >> 2;
18421           uint32_t U = (target >= 0) && !label->IsMinusZero();
18422           target = abs(target) | (U << 8);
18423           return instr | (target & 0xff) | ((target & 0x100) << 15);
18424         }
18425       } immop;
18426       EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12), label, immop));
18427       AdvanceIT();
18428       return;
18429     }
18430   } else {
18431     // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
18432     if (dt.IsNoneOr(Untyped64) &&
18433         ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18434           ((offset & 0x3) == 0)) ||
18435          !label->IsBound()) &&
18436         cond.IsNotNever()) {
18437       static class EmitOp : public Label::LabelEmitOperator {
18438        public:
18439         EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18440         virtual uint32_t Encode(uint32_t instr,
18441                                 Label::Offset pc,
18442                                 const Label* label) const VIXL_OVERRIDE {
18443           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18444           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18445                       ((offset & 0x3) == 0));
18446           int32_t target = offset >> 2;
18447           uint32_t U = (target >= 0) && !label->IsMinusZero();
18448           target = abs(target) | (U << 8);
18449           return instr | (target & 0xff) | ((target & 0x100) << 15);
18450         }
18451       } immop;
18452       EmitA32(
18453           Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
18454                label,
18455                immop));
18456       return;
18457     }
18458   }
18459   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label);
18460 }
18461 
vldr(Condition cond,DataType dt,DRegister rd,const MemOperand & operand)18462 void Assembler::vldr(Condition cond,
18463                      DataType dt,
18464                      DRegister rd,
18465                      const MemOperand& operand) {
18466   VIXL_ASSERT(AllowAssembler());
18467   CheckIT(cond);
18468   if (operand.IsImmediate()) {
18469     Register rn = operand.GetBaseRegister();
18470     int32_t offset = operand.GetOffsetImmediate();
18471     if (IsUsingT32()) {
18472       // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1
18473       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18474           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
18475         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18476         uint32_t offset_ = abs(offset) >> 2;
18477         EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23));
18478         AdvanceIT();
18479         return;
18480       }
18481       // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
18482       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18483           ((offset % 4) == 0) && operand.IsOffset() &&
18484           ((rn.GetCode() & 0xf) != 0xf)) {
18485         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18486         uint32_t offset_ = abs(offset) >> 2;
18487         EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
18488                    offset_ | (sign << 23));
18489         AdvanceIT();
18490         return;
18491       }
18492     } else {
18493       // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1
18494       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18495           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
18496           cond.IsNotNever()) {
18497         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18498         uint32_t offset_ = abs(offset) >> 2;
18499         EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18500                 offset_ | (sign << 23));
18501         return;
18502       }
18503       // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
18504       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
18505           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
18506           ((rn.GetCode() & 0xf) != 0xf)) {
18507         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18508         uint32_t offset_ = abs(offset) >> 2;
18509         EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18510                 (rn.GetCode() << 16) | offset_ | (sign << 23));
18511         return;
18512       }
18513     }
18514   }
18515   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
18516 }
18517 
vldr(Condition cond,DataType dt,SRegister rd,Label * label)18518 void Assembler::vldr(Condition cond, DataType dt, SRegister rd, Label* label) {
18519   VIXL_ASSERT(AllowAssembler());
18520   CheckIT(cond);
18521   Label::Offset offset =
18522       label->IsBound()
18523           ? label->GetLocation() -
18524                 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
18525           : 0;
18526   if (IsUsingT32()) {
18527     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
18528     if (dt.IsNoneOr(Untyped32) &&
18529         ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18530           ((offset & 0x3) == 0)) ||
18531          !label->IsBound())) {
18532       static class EmitOp : public Label::LabelEmitOperator {
18533        public:
18534         EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18535         virtual uint32_t Encode(uint32_t instr,
18536                                 Label::Offset pc,
18537                                 const Label* label) const VIXL_OVERRIDE {
18538           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18539           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18540                       ((offset & 0x3) == 0));
18541           int32_t target = offset >> 2;
18542           uint32_t U = (target >= 0) && !label->IsMinusZero();
18543           target = abs(target) | (U << 8);
18544           return instr | (target & 0xff) | ((target & 0x100) << 15);
18545         }
18546       } immop;
18547       EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12), label, immop));
18548       AdvanceIT();
18549       return;
18550     }
18551   } else {
18552     // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
18553     if (dt.IsNoneOr(Untyped32) &&
18554         ((label->IsBound() && (offset >= -1020) && (offset <= 1020) &&
18555           ((offset & 0x3) == 0)) ||
18556          !label->IsBound()) &&
18557         cond.IsNotNever()) {
18558       static class EmitOp : public Label::LabelEmitOperator {
18559        public:
18560         EmitOp() : Label::LabelEmitOperator(-1020, 1020) {}
18561         virtual uint32_t Encode(uint32_t instr,
18562                                 Label::Offset pc,
18563                                 const Label* label) const VIXL_OVERRIDE {
18564           Label::Offset offset = label->GetLocation() - AlignDown(pc, 4);
18565           VIXL_ASSERT((offset >= -1020) && (offset <= 1020) &&
18566                       ((offset & 0x3) == 0));
18567           int32_t target = offset >> 2;
18568           uint32_t U = (target >= 0) && !label->IsMinusZero();
18569           target = abs(target) | (U << 8);
18570           return instr | (target & 0xff) | ((target & 0x100) << 15);
18571         }
18572       } immop;
18573       EmitA32(
18574           Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
18575                label,
18576                immop));
18577       return;
18578     }
18579   }
18580   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, label);
18581 }
18582 
vldr(Condition cond,DataType dt,SRegister rd,const MemOperand & operand)18583 void Assembler::vldr(Condition cond,
18584                      DataType dt,
18585                      SRegister rd,
18586                      const MemOperand& operand) {
18587   VIXL_ASSERT(AllowAssembler());
18588   CheckIT(cond);
18589   if (operand.IsImmediate()) {
18590     Register rn = operand.GetBaseRegister();
18591     int32_t offset = operand.GetOffsetImmediate();
18592     if (IsUsingT32()) {
18593       // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2
18594       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18595           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
18596         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18597         uint32_t offset_ = abs(offset) >> 2;
18598         EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23));
18599         AdvanceIT();
18600         return;
18601       }
18602       // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
18603       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18604           ((offset % 4) == 0) && operand.IsOffset() &&
18605           ((rn.GetCode() & 0xf) != 0xf)) {
18606         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18607         uint32_t offset_ = abs(offset) >> 2;
18608         EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
18609                    offset_ | (sign << 23));
18610         AdvanceIT();
18611         return;
18612       }
18613     } else {
18614       // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2
18615       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18616           ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
18617           cond.IsNotNever()) {
18618         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18619         uint32_t offset_ = abs(offset) >> 2;
18620         EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18621                 offset_ | (sign << 23));
18622         return;
18623       }
18624       // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
18625       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
18626           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
18627           ((rn.GetCode() & 0xf) != 0xf)) {
18628         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
18629         uint32_t offset_ = abs(offset) >> 2;
18630         EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
18631                 (rn.GetCode() << 16) | offset_ | (sign << 23));
18632         return;
18633       }
18634     }
18635   }
18636   Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
18637 }
18638 
vmax(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)18639 void Assembler::vmax(
18640     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18641   VIXL_ASSERT(AllowAssembler());
18642   CheckIT(cond);
18643   Dt_U_size_1 encoded_dt(dt);
18644   if (IsUsingT32()) {
18645     // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
18646     if (dt.Is(F32)) {
18647       if (cond.Is(al) || AllowStronglyDiscouraged()) {
18648         EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18649                    rm.Encode(5, 0));
18650         AdvanceIT();
18651         return;
18652       }
18653     }
18654     // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
18655     if (encoded_dt.IsValid()) {
18656       if (cond.Is(al) || AllowStronglyDiscouraged()) {
18657         EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18658                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18659                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18660         AdvanceIT();
18661         return;
18662       }
18663     }
18664   } else {
18665     // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
18666     if (dt.Is(F32)) {
18667       if (cond.Is(al)) {
18668         EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18669                 rm.Encode(5, 0));
18670         return;
18671       }
18672     }
18673     // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
18674     if (encoded_dt.IsValid()) {
18675       if (cond.Is(al)) {
18676         EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18677                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18678                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18679         return;
18680       }
18681     }
18682   }
18683   Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
18684 }
18685 
vmax(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)18686 void Assembler::vmax(
18687     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18688   VIXL_ASSERT(AllowAssembler());
18689   CheckIT(cond);
18690   Dt_U_size_1 encoded_dt(dt);
18691   if (IsUsingT32()) {
18692     // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
18693     if (dt.Is(F32)) {
18694       if (cond.Is(al) || AllowStronglyDiscouraged()) {
18695         EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18696                    rm.Encode(5, 0));
18697         AdvanceIT();
18698         return;
18699       }
18700     }
18701     // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
18702     if (encoded_dt.IsValid()) {
18703       if (cond.Is(al) || AllowStronglyDiscouraged()) {
18704         EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18705                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18706                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18707         AdvanceIT();
18708         return;
18709       }
18710     }
18711   } else {
18712     // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
18713     if (dt.Is(F32)) {
18714       if (cond.Is(al)) {
18715         EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18716                 rm.Encode(5, 0));
18717         return;
18718       }
18719     }
18720     // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
18721     if (encoded_dt.IsValid()) {
18722       if (cond.Is(al)) {
18723         EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18724                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18725                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18726         return;
18727       }
18728     }
18729   }
18730   Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
18731 }
18732 
vmaxnm(DataType dt,DRegister rd,DRegister rn,DRegister rm)18733 void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18734   VIXL_ASSERT(AllowAssembler());
18735   CheckIT(al);
18736   if (IsUsingT32()) {
18737     // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
18738     if (OutsideITBlock() && dt.Is(F32)) {
18739       EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18740                  rm.Encode(5, 0));
18741       AdvanceIT();
18742       return;
18743     }
18744     // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
18745     if (OutsideITBlock() && dt.Is(F64)) {
18746       EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18747                  rm.Encode(5, 0));
18748       AdvanceIT();
18749       return;
18750     }
18751   } else {
18752     // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
18753     if (dt.Is(F32)) {
18754       EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18755               rm.Encode(5, 0));
18756       return;
18757     }
18758     // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
18759     if (dt.Is(F64)) {
18760       EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18761               rm.Encode(5, 0));
18762       return;
18763     }
18764   }
18765   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18766 }
18767 
vmaxnm(DataType dt,QRegister rd,QRegister rn,QRegister rm)18768 void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18769   VIXL_ASSERT(AllowAssembler());
18770   CheckIT(al);
18771   if (IsUsingT32()) {
18772     // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
18773     if (OutsideITBlock() && dt.Is(F32)) {
18774       EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18775                  rm.Encode(5, 0));
18776       AdvanceIT();
18777       return;
18778     }
18779   } else {
18780     // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
18781     if (dt.Is(F32)) {
18782       EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18783               rm.Encode(5, 0));
18784       return;
18785     }
18786   }
18787   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18788 }
18789 
vmaxnm(DataType dt,SRegister rd,SRegister rn,SRegister rm)18790 void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
18791   VIXL_ASSERT(AllowAssembler());
18792   CheckIT(al);
18793   if (IsUsingT32()) {
18794     // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
18795     if (OutsideITBlock() && dt.Is(F32)) {
18796       EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18797                  rm.Encode(5, 0));
18798       AdvanceIT();
18799       return;
18800     }
18801   } else {
18802     // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
18803     if (dt.Is(F32)) {
18804       EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18805               rm.Encode(5, 0));
18806       return;
18807     }
18808   }
18809   Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
18810 }
18811 
vmin(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)18812 void Assembler::vmin(
18813     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18814   VIXL_ASSERT(AllowAssembler());
18815   CheckIT(cond);
18816   Dt_U_size_1 encoded_dt(dt);
18817   if (IsUsingT32()) {
18818     // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
18819     if (dt.Is(F32)) {
18820       if (cond.Is(al) || AllowStronglyDiscouraged()) {
18821         EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18822                    rm.Encode(5, 0));
18823         AdvanceIT();
18824         return;
18825       }
18826     }
18827     // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
18828     if (encoded_dt.IsValid()) {
18829       if (cond.Is(al) || AllowStronglyDiscouraged()) {
18830         EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18831                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18832                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18833         AdvanceIT();
18834         return;
18835       }
18836     }
18837   } else {
18838     // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
18839     if (dt.Is(F32)) {
18840       if (cond.Is(al)) {
18841         EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18842                 rm.Encode(5, 0));
18843         return;
18844       }
18845     }
18846     // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
18847     if (encoded_dt.IsValid()) {
18848       if (cond.Is(al)) {
18849         EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18850                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18851                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18852         return;
18853       }
18854     }
18855   }
18856   Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
18857 }
18858 
vmin(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)18859 void Assembler::vmin(
18860     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18861   VIXL_ASSERT(AllowAssembler());
18862   CheckIT(cond);
18863   Dt_U_size_1 encoded_dt(dt);
18864   if (IsUsingT32()) {
18865     // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
18866     if (dt.Is(F32)) {
18867       if (cond.Is(al) || AllowStronglyDiscouraged()) {
18868         EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18869                    rm.Encode(5, 0));
18870         AdvanceIT();
18871         return;
18872       }
18873     }
18874     // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
18875     if (encoded_dt.IsValid()) {
18876       if (cond.Is(al) || AllowStronglyDiscouraged()) {
18877         EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18878                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
18879                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18880         AdvanceIT();
18881         return;
18882       }
18883     }
18884   } else {
18885     // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
18886     if (dt.Is(F32)) {
18887       if (cond.Is(al)) {
18888         EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18889                 rm.Encode(5, 0));
18890         return;
18891       }
18892     }
18893     // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
18894     if (encoded_dt.IsValid()) {
18895       if (cond.Is(al)) {
18896         EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
18897                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
18898                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
18899         return;
18900       }
18901     }
18902   }
18903   Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
18904 }
18905 
vminnm(DataType dt,DRegister rd,DRegister rn,DRegister rm)18906 void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
18907   VIXL_ASSERT(AllowAssembler());
18908   CheckIT(al);
18909   if (IsUsingT32()) {
18910     // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
18911     if (OutsideITBlock() && dt.Is(F32)) {
18912       EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18913                  rm.Encode(5, 0));
18914       AdvanceIT();
18915       return;
18916     }
18917     // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
18918     if (OutsideITBlock() && dt.Is(F64)) {
18919       EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18920                  rm.Encode(5, 0));
18921       AdvanceIT();
18922       return;
18923     }
18924   } else {
18925     // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
18926     if (dt.Is(F32)) {
18927       EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18928               rm.Encode(5, 0));
18929       return;
18930     }
18931     // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
18932     if (dt.Is(F64)) {
18933       EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18934               rm.Encode(5, 0));
18935       return;
18936     }
18937   }
18938   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18939 }
18940 
vminnm(DataType dt,QRegister rd,QRegister rn,QRegister rm)18941 void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
18942   VIXL_ASSERT(AllowAssembler());
18943   CheckIT(al);
18944   if (IsUsingT32()) {
18945     // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
18946     if (OutsideITBlock() && dt.Is(F32)) {
18947       EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18948                  rm.Encode(5, 0));
18949       AdvanceIT();
18950       return;
18951     }
18952   } else {
18953     // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
18954     if (dt.Is(F32)) {
18955       EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18956               rm.Encode(5, 0));
18957       return;
18958     }
18959   }
18960   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18961 }
18962 
vminnm(DataType dt,SRegister rd,SRegister rn,SRegister rm)18963 void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
18964   VIXL_ASSERT(AllowAssembler());
18965   CheckIT(al);
18966   if (IsUsingT32()) {
18967     // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
18968     if (OutsideITBlock() && dt.Is(F32)) {
18969       EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18970                  rm.Encode(5, 0));
18971       AdvanceIT();
18972       return;
18973     }
18974   } else {
18975     // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
18976     if (dt.Is(F32)) {
18977       EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
18978               rm.Encode(5, 0));
18979       return;
18980     }
18981   }
18982   Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
18983 }
18984 
vmla(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)18985 void Assembler::vmla(
18986     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
18987   VIXL_ASSERT(AllowAssembler());
18988   CheckIT(cond);
18989   Dt_size_9 encoded_dt(dt);
18990   if (IsUsingT32()) {
18991     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
18992     if (encoded_dt.IsValid() &&
18993         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
18994          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
18995           (rm.GetLane() <= 1)))) {
18996       if (cond.Is(al) || AllowStronglyDiscouraged()) {
18997         EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
18998                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
18999                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19000         AdvanceIT();
19001         return;
19002       }
19003     }
19004   } else {
19005     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
19006     if (encoded_dt.IsValid() &&
19007         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19008          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19009           (rm.GetLane() <= 1)))) {
19010       if (cond.Is(al)) {
19011         EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
19012                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19013                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19014         return;
19015       }
19016     }
19017   }
19018   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19019 }
19020 
vmla(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)19021 void Assembler::vmla(
19022     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
19023   VIXL_ASSERT(AllowAssembler());
19024   CheckIT(cond);
19025   Dt_size_9 encoded_dt(dt);
19026   if (IsUsingT32()) {
19027     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
19028     if (encoded_dt.IsValid() &&
19029         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19030          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19031           (rm.GetLane() <= 1)))) {
19032       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19033         EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
19034                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19035                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19036         AdvanceIT();
19037         return;
19038       }
19039     }
19040   } else {
19041     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
19042     if (encoded_dt.IsValid() &&
19043         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19044          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19045           (rm.GetLane() <= 1)))) {
19046       if (cond.Is(al)) {
19047         EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
19048                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19049                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19050         return;
19051       }
19052     }
19053   }
19054   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19055 }
19056 
vmla(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)19057 void Assembler::vmla(
19058     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
19059   VIXL_ASSERT(AllowAssembler());
19060   CheckIT(cond);
19061   Dt_size_10 encoded_dt(dt);
19062   if (IsUsingT32()) {
19063     // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
19064     if (dt.Is(F32)) {
19065       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19066         EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19067                    rm.Encode(5, 0));
19068         AdvanceIT();
19069         return;
19070       }
19071     }
19072     // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
19073     if (dt.Is(F64)) {
19074       EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19075                  rm.Encode(5, 0));
19076       AdvanceIT();
19077       return;
19078     }
19079     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
19080     if (encoded_dt.IsValid()) {
19081       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19082         EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) |
19083                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19084         AdvanceIT();
19085         return;
19086       }
19087     }
19088   } else {
19089     // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
19090     if (dt.Is(F32)) {
19091       if (cond.Is(al)) {
19092         EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19093                 rm.Encode(5, 0));
19094         return;
19095       }
19096     }
19097     // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
19098     if (dt.Is(F64) && cond.IsNotNever()) {
19099       EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19100               rn.Encode(7, 16) | rm.Encode(5, 0));
19101       return;
19102     }
19103     // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
19104     if (encoded_dt.IsValid()) {
19105       if (cond.Is(al)) {
19106         EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) |
19107                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19108         return;
19109       }
19110     }
19111   }
19112   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19113 }
19114 
vmla(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)19115 void Assembler::vmla(
19116     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
19117   VIXL_ASSERT(AllowAssembler());
19118   CheckIT(cond);
19119   Dt_size_10 encoded_dt(dt);
19120   if (IsUsingT32()) {
19121     // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
19122     if (dt.Is(F32)) {
19123       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19124         EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19125                    rm.Encode(5, 0));
19126         AdvanceIT();
19127         return;
19128       }
19129     }
19130     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
19131     if (encoded_dt.IsValid()) {
19132       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19133         EmitT32_32(0xef000940U | (encoded_dt.GetEncodingValue() << 20) |
19134                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19135         AdvanceIT();
19136         return;
19137       }
19138     }
19139   } else {
19140     // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
19141     if (dt.Is(F32)) {
19142       if (cond.Is(al)) {
19143         EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19144                 rm.Encode(5, 0));
19145         return;
19146       }
19147     }
19148     // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
19149     if (encoded_dt.IsValid()) {
19150       if (cond.Is(al)) {
19151         EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) |
19152                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19153         return;
19154       }
19155     }
19156   }
19157   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19158 }
19159 
vmla(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)19160 void Assembler::vmla(
19161     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
19162   VIXL_ASSERT(AllowAssembler());
19163   CheckIT(cond);
19164   if (IsUsingT32()) {
19165     // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
19166     if (dt.Is(F32)) {
19167       EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19168                  rm.Encode(5, 0));
19169       AdvanceIT();
19170       return;
19171     }
19172   } else {
19173     // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
19174     if (dt.Is(F32) && cond.IsNotNever()) {
19175       EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19176               rn.Encode(7, 16) | rm.Encode(5, 0));
19177       return;
19178     }
19179   }
19180   Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
19181 }
19182 
vmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegisterLane rm)19183 void Assembler::vmlal(
19184     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
19185   VIXL_ASSERT(AllowAssembler());
19186   CheckIT(cond);
19187   Dt_size_11 encoded_dt(dt);
19188   if (IsUsingT32()) {
19189     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
19190     if (encoded_dt.IsValid() &&
19191         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19192          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19193           (rm.GetLane() <= 1)))) {
19194       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19195         EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) |
19196                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19197                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19198         AdvanceIT();
19199         return;
19200       }
19201     }
19202   } else {
19203     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
19204     if (encoded_dt.IsValid() &&
19205         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19206          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19207           (rm.GetLane() <= 1)))) {
19208       if (cond.Is(al)) {
19209         EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) |
19210                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19211                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19212         return;
19213       }
19214     }
19215   }
19216   Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
19217 }
19218 
vmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)19219 void Assembler::vmlal(
19220     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
19221   VIXL_ASSERT(AllowAssembler());
19222   CheckIT(cond);
19223   Dt_size_12 encoded_dt(dt);
19224   if (IsUsingT32()) {
19225     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
19226     if (encoded_dt.IsValid()) {
19227       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19228         EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) |
19229                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19230                    rn.Encode(7, 16) | rm.Encode(5, 0));
19231         AdvanceIT();
19232         return;
19233       }
19234     }
19235   } else {
19236     // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
19237     if (encoded_dt.IsValid()) {
19238       if (cond.Is(al)) {
19239         EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) |
19240                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19241                 rn.Encode(7, 16) | rm.Encode(5, 0));
19242         return;
19243       }
19244     }
19245   }
19246   Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
19247 }
19248 
vmls(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)19249 void Assembler::vmls(
19250     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
19251   VIXL_ASSERT(AllowAssembler());
19252   CheckIT(cond);
19253   Dt_size_9 encoded_dt(dt);
19254   if (IsUsingT32()) {
19255     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
19256     if (encoded_dt.IsValid() &&
19257         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19258          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19259           (rm.GetLane() <= 1)))) {
19260       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19261         EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19262                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19263                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19264         AdvanceIT();
19265         return;
19266       }
19267     }
19268   } else {
19269     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
19270     if (encoded_dt.IsValid() &&
19271         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19272          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19273           (rm.GetLane() <= 1)))) {
19274       if (cond.Is(al)) {
19275         EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19276                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19277                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19278         return;
19279       }
19280     }
19281   }
19282   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19283 }
19284 
vmls(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)19285 void Assembler::vmls(
19286     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
19287   VIXL_ASSERT(AllowAssembler());
19288   CheckIT(cond);
19289   Dt_size_9 encoded_dt(dt);
19290   if (IsUsingT32()) {
19291     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
19292     if (encoded_dt.IsValid() &&
19293         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19294          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19295           (rm.GetLane() <= 1)))) {
19296       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19297         EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19298                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19299                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19300         AdvanceIT();
19301         return;
19302       }
19303     }
19304   } else {
19305     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
19306     if (encoded_dt.IsValid() &&
19307         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19308          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19309           (rm.GetLane() <= 1)))) {
19310       if (cond.Is(al)) {
19311         EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
19312                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19313                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19314         return;
19315       }
19316     }
19317   }
19318   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19319 }
19320 
vmls(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)19321 void Assembler::vmls(
19322     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
19323   VIXL_ASSERT(AllowAssembler());
19324   CheckIT(cond);
19325   Dt_size_10 encoded_dt(dt);
19326   if (IsUsingT32()) {
19327     // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
19328     if (dt.Is(F32)) {
19329       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19330         EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19331                    rm.Encode(5, 0));
19332         AdvanceIT();
19333         return;
19334       }
19335     }
19336     // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
19337     if (dt.Is(F64)) {
19338       EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19339                  rm.Encode(5, 0));
19340       AdvanceIT();
19341       return;
19342     }
19343     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
19344     if (encoded_dt.IsValid()) {
19345       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19346         EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) |
19347                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19348         AdvanceIT();
19349         return;
19350       }
19351     }
19352   } else {
19353     // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
19354     if (dt.Is(F32)) {
19355       if (cond.Is(al)) {
19356         EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19357                 rm.Encode(5, 0));
19358         return;
19359       }
19360     }
19361     // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
19362     if (dt.Is(F64) && cond.IsNotNever()) {
19363       EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19364               rn.Encode(7, 16) | rm.Encode(5, 0));
19365       return;
19366     }
19367     // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
19368     if (encoded_dt.IsValid()) {
19369       if (cond.Is(al)) {
19370         EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) |
19371                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19372         return;
19373       }
19374     }
19375   }
19376   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19377 }
19378 
vmls(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)19379 void Assembler::vmls(
19380     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
19381   VIXL_ASSERT(AllowAssembler());
19382   CheckIT(cond);
19383   Dt_size_10 encoded_dt(dt);
19384   if (IsUsingT32()) {
19385     // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
19386     if (dt.Is(F32)) {
19387       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19388         EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19389                    rm.Encode(5, 0));
19390         AdvanceIT();
19391         return;
19392       }
19393     }
19394     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
19395     if (encoded_dt.IsValid()) {
19396       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19397         EmitT32_32(0xff000940U | (encoded_dt.GetEncodingValue() << 20) |
19398                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19399         AdvanceIT();
19400         return;
19401       }
19402     }
19403   } else {
19404     // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
19405     if (dt.Is(F32)) {
19406       if (cond.Is(al)) {
19407         EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19408                 rm.Encode(5, 0));
19409         return;
19410       }
19411     }
19412     // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
19413     if (encoded_dt.IsValid()) {
19414       if (cond.Is(al)) {
19415         EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) |
19416                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19417         return;
19418       }
19419     }
19420   }
19421   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19422 }
19423 
vmls(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)19424 void Assembler::vmls(
19425     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
19426   VIXL_ASSERT(AllowAssembler());
19427   CheckIT(cond);
19428   if (IsUsingT32()) {
19429     // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
19430     if (dt.Is(F32)) {
19431       EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19432                  rm.Encode(5, 0));
19433       AdvanceIT();
19434       return;
19435     }
19436   } else {
19437     // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
19438     if (dt.Is(F32) && cond.IsNotNever()) {
19439       EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19440               rn.Encode(7, 16) | rm.Encode(5, 0));
19441       return;
19442     }
19443   }
19444   Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
19445 }
19446 
vmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegisterLane rm)19447 void Assembler::vmlsl(
19448     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
19449   VIXL_ASSERT(AllowAssembler());
19450   CheckIT(cond);
19451   Dt_size_11 encoded_dt(dt);
19452   if (IsUsingT32()) {
19453     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
19454     if (encoded_dt.IsValid() &&
19455         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19456          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19457           (rm.GetLane() <= 1)))) {
19458       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19459         EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) |
19460                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19461                    rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19462         AdvanceIT();
19463         return;
19464       }
19465     }
19466   } else {
19467     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
19468     if (encoded_dt.IsValid() &&
19469         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
19470          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
19471           (rm.GetLane() <= 1)))) {
19472       if (cond.Is(al)) {
19473         EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) |
19474                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19475                 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
19476         return;
19477       }
19478     }
19479   }
19480   Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
19481 }
19482 
vmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)19483 void Assembler::vmlsl(
19484     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
19485   VIXL_ASSERT(AllowAssembler());
19486   CheckIT(cond);
19487   Dt_size_12 encoded_dt(dt);
19488   if (IsUsingT32()) {
19489     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
19490     if (encoded_dt.IsValid()) {
19491       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19492         EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) |
19493                    (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19494                    rn.Encode(7, 16) | rm.Encode(5, 0));
19495         AdvanceIT();
19496         return;
19497       }
19498     }
19499   } else {
19500     // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
19501     if (encoded_dt.IsValid()) {
19502       if (cond.Is(al)) {
19503         EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) |
19504                 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
19505                 rn.Encode(7, 16) | rm.Encode(5, 0));
19506         return;
19507       }
19508     }
19509   }
19510   Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
19511 }
19512 
vmov(Condition cond,Register rt,SRegister rn)19513 void Assembler::vmov(Condition cond, Register rt, SRegister rn) {
19514   VIXL_ASSERT(AllowAssembler());
19515   CheckIT(cond);
19516   if (IsUsingT32()) {
19517     // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1
19518     EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16));
19519     AdvanceIT();
19520     return;
19521   } else {
19522     // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1
19523     if (cond.IsNotNever()) {
19524       EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19525               rn.Encode(7, 16));
19526       return;
19527     }
19528   }
19529   Delegate(kVmov, &Assembler::vmov, cond, rt, rn);
19530 }
19531 
vmov(Condition cond,SRegister rn,Register rt)19532 void Assembler::vmov(Condition cond, SRegister rn, Register rt) {
19533   VIXL_ASSERT(AllowAssembler());
19534   CheckIT(cond);
19535   if (IsUsingT32()) {
19536     // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1
19537     EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12));
19538     AdvanceIT();
19539     return;
19540   } else {
19541     // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1
19542     if (cond.IsNotNever()) {
19543       EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) |
19544               (rt.GetCode() << 12));
19545       return;
19546     }
19547   }
19548   Delegate(kVmov, &Assembler::vmov, cond, rn, rt);
19549 }
19550 
vmov(Condition cond,Register rt,Register rt2,DRegister rm)19551 void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) {
19552   VIXL_ASSERT(AllowAssembler());
19553   CheckIT(cond);
19554   if (IsUsingT32()) {
19555     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1
19556     EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
19557                rm.Encode(5, 0));
19558     AdvanceIT();
19559     return;
19560   } else {
19561     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1
19562     if (cond.IsNotNever()) {
19563       EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19564               (rt2.GetCode() << 16) | rm.Encode(5, 0));
19565       return;
19566     }
19567   }
19568   Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm);
19569 }
19570 
vmov(Condition cond,DRegister rm,Register rt,Register rt2)19571 void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) {
19572   VIXL_ASSERT(AllowAssembler());
19573   CheckIT(cond);
19574   if (IsUsingT32()) {
19575     // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1
19576     EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
19577                (rt2.GetCode() << 16));
19578     AdvanceIT();
19579     return;
19580   } else {
19581     // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1
19582     if (cond.IsNotNever()) {
19583       EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
19584               (rt.GetCode() << 12) | (rt2.GetCode() << 16));
19585       return;
19586     }
19587   }
19588   Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2);
19589 }
19590 
vmov(Condition cond,Register rt,Register rt2,SRegister rm,SRegister rm1)19591 void Assembler::vmov(
19592     Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) {
19593   VIXL_ASSERT(AllowAssembler());
19594   CheckIT(cond);
19595   if (IsUsingT32()) {
19596     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1
19597     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) {
19598       EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
19599                  rm.Encode(5, 0));
19600       AdvanceIT();
19601       return;
19602     }
19603   } else {
19604     // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1
19605     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
19606         cond.IsNotNever()) {
19607       EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19608               (rt2.GetCode() << 16) | rm.Encode(5, 0));
19609       return;
19610     }
19611   }
19612   Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1);
19613 }
19614 
vmov(Condition cond,SRegister rm,SRegister rm1,Register rt,Register rt2)19615 void Assembler::vmov(
19616     Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) {
19617   VIXL_ASSERT(AllowAssembler());
19618   CheckIT(cond);
19619   if (IsUsingT32()) {
19620     // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1
19621     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode())) {
19622       EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
19623                  (rt2.GetCode() << 16));
19624       AdvanceIT();
19625       return;
19626     }
19627   } else {
19628     // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1
19629     if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
19630         cond.IsNotNever()) {
19631       EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
19632               (rt.GetCode() << 12) | (rt2.GetCode() << 16));
19633       return;
19634     }
19635   }
19636   Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2);
19637 }
19638 
vmov(Condition cond,DataType dt,DRegisterLane rd,Register rt)19639 void Assembler::vmov(Condition cond,
19640                      DataType dt,
19641                      DRegisterLane rd,
19642                      Register rt) {
19643   VIXL_ASSERT(AllowAssembler());
19644   CheckIT(cond);
19645   Dt_opc1_opc2_1 encoded_dt(dt, rd);
19646   if (IsUsingT32()) {
19647     // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1
19648     if (encoded_dt.IsValid()) {
19649       EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19650                  ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19651                  rd.Encode(7, 16) | (rt.GetCode() << 12));
19652       AdvanceIT();
19653       return;
19654     }
19655   } else {
19656     // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1
19657     if (encoded_dt.IsValid() && cond.IsNotNever()) {
19658       EmitA32(0x0e000b10U | (cond.GetCondition() << 28) |
19659               ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19660               ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) |
19661               (rt.GetCode() << 12));
19662       return;
19663     }
19664   }
19665   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt);
19666 }
19667 
vmov(Condition cond,DataType dt,DRegister rd,const DOperand & operand)19668 void Assembler::vmov(Condition cond,
19669                      DataType dt,
19670                      DRegister rd,
19671                      const DOperand& operand) {
19672   VIXL_ASSERT(AllowAssembler());
19673   CheckIT(cond);
19674   if (operand.IsImmediate()) {
19675     ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
19676     ImmediateVFP vfp(operand.GetNeonImmediate());
19677     if (IsUsingT32()) {
19678       // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
19679       if (encoded_dt.IsValid()) {
19680         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19681           EmitT32_32(
19682               0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19683               ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19684               rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19685               ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19686               ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
19687           AdvanceIT();
19688           return;
19689         }
19690       }
19691       // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2
19692       if (dt.Is(F64) && vfp.IsValid()) {
19693         EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) |
19694                    (vfp.GetEncodingValue() & 0xf) |
19695                    ((vfp.GetEncodingValue() & 0xf0) << 12));
19696         AdvanceIT();
19697         return;
19698       }
19699     } else {
19700       // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
19701       if (encoded_dt.IsValid()) {
19702         if (cond.Is(al)) {
19703           EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19704                   ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19705                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19706                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19707                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
19708           return;
19709         }
19710       }
19711       // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2
19712       if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) {
19713         EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19714                 (vfp.GetEncodingValue() & 0xf) |
19715                 ((vfp.GetEncodingValue() & 0xf0) << 12));
19716         return;
19717       }
19718     }
19719   }
19720   if (operand.IsRegister()) {
19721     DRegister rm = operand.GetRegister();
19722     if (IsUsingT32()) {
19723       // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
19724       if (dt.Is(F64)) {
19725         EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
19726         AdvanceIT();
19727         return;
19728       }
19729       // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
19730       if (!dt.Is(F64)) {
19731         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19732           EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19733                      rm.Encode(5, 0));
19734           AdvanceIT();
19735           return;
19736         }
19737       }
19738     } else {
19739       // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
19740       if (dt.Is(F64) && cond.IsNotNever()) {
19741         EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19742                 rm.Encode(5, 0));
19743         return;
19744       }
19745       // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
19746       if (!dt.Is(F64)) {
19747         if (cond.Is(al)) {
19748           EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19749                   rm.Encode(5, 0));
19750           return;
19751         }
19752       }
19753     }
19754   }
19755   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19756 }
19757 
vmov(Condition cond,DataType dt,QRegister rd,const QOperand & operand)19758 void Assembler::vmov(Condition cond,
19759                      DataType dt,
19760                      QRegister rd,
19761                      const QOperand& operand) {
19762   VIXL_ASSERT(AllowAssembler());
19763   CheckIT(cond);
19764   if (operand.IsImmediate()) {
19765     ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
19766     if (IsUsingT32()) {
19767       // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
19768       if (encoded_dt.IsValid()) {
19769         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19770           EmitT32_32(
19771               0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19772               ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19773               rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19774               ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19775               ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
19776           AdvanceIT();
19777           return;
19778         }
19779       }
19780     } else {
19781       // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
19782       if (encoded_dt.IsValid()) {
19783         if (cond.Is(al)) {
19784           EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
19785                   ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
19786                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
19787                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
19788                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
19789           return;
19790         }
19791       }
19792     }
19793   }
19794   if (operand.IsRegister()) {
19795     QRegister rm = operand.GetRegister();
19796     if (IsUsingT32()) {
19797       // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
19798       if (!dt.Is(F64)) {
19799         if (cond.Is(al) || AllowStronglyDiscouraged()) {
19800           EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19801                      rm.Encode(5, 0));
19802           AdvanceIT();
19803           return;
19804         }
19805       }
19806     } else {
19807       // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
19808       if (!dt.Is(F64)) {
19809         if (cond.Is(al)) {
19810           EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
19811                   rm.Encode(5, 0));
19812           return;
19813         }
19814       }
19815     }
19816   }
19817   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19818 }
19819 
vmov(Condition cond,DataType dt,SRegister rd,const SOperand & operand)19820 void Assembler::vmov(Condition cond,
19821                      DataType dt,
19822                      SRegister rd,
19823                      const SOperand& operand) {
19824   VIXL_ASSERT(AllowAssembler());
19825   CheckIT(cond);
19826   if (operand.IsImmediate()) {
19827     ImmediateVFP vfp(operand.GetNeonImmediate());
19828     if (IsUsingT32()) {
19829       // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2
19830       if (dt.Is(F32) && vfp.IsValid()) {
19831         EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) |
19832                    (vfp.GetEncodingValue() & 0xf) |
19833                    ((vfp.GetEncodingValue() & 0xf0) << 12));
19834         AdvanceIT();
19835         return;
19836       }
19837     } else {
19838       // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2
19839       if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) {
19840         EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19841                 (vfp.GetEncodingValue() & 0xf) |
19842                 ((vfp.GetEncodingValue() & 0xf0) << 12));
19843         return;
19844       }
19845     }
19846   }
19847   if (operand.IsRegister()) {
19848     SRegister rm = operand.GetRegister();
19849     if (IsUsingT32()) {
19850       // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
19851       if (dt.Is(F32)) {
19852         EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
19853         AdvanceIT();
19854         return;
19855       }
19856     } else {
19857       // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
19858       if (dt.Is(F32) && cond.IsNotNever()) {
19859         EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19860                 rm.Encode(5, 0));
19861         return;
19862       }
19863     }
19864   }
19865   Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
19866 }
19867 
vmov(Condition cond,DataType dt,Register rt,DRegisterLane rn)19868 void Assembler::vmov(Condition cond,
19869                      DataType dt,
19870                      Register rt,
19871                      DRegisterLane rn) {
19872   VIXL_ASSERT(AllowAssembler());
19873   CheckIT(cond);
19874   Dt_U_opc1_opc2_1 encoded_dt(dt, rn);
19875   if (IsUsingT32()) {
19876     // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1
19877     if (encoded_dt.IsValid()) {
19878       EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19879                  ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19880                  ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
19881                  (rt.GetCode() << 12) | rn.Encode(7, 16));
19882       AdvanceIT();
19883       return;
19884     }
19885   } else {
19886     // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1
19887     if (encoded_dt.IsValid() && cond.IsNotNever()) {
19888       EmitA32(0x0e100b10U | (cond.GetCondition() << 28) |
19889               ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
19890               ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
19891               ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
19892               (rt.GetCode() << 12) | rn.Encode(7, 16));
19893       return;
19894     }
19895   }
19896   Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn);
19897 }
19898 
vmovl(Condition cond,DataType dt,QRegister rd,DRegister rm)19899 void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) {
19900   VIXL_ASSERT(AllowAssembler());
19901   CheckIT(cond);
19902   Dt_U_imm3H_1 encoded_dt(dt);
19903   if (IsUsingT32()) {
19904     // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1
19905     if (encoded_dt.IsValid()) {
19906       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19907         EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
19908                    ((encoded_dt.GetEncodingValue() & 0x8) << 25) |
19909                    rd.Encode(22, 12) | rm.Encode(5, 0));
19910         AdvanceIT();
19911         return;
19912       }
19913     }
19914   } else {
19915     // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
19916     if (encoded_dt.IsValid()) {
19917       if (cond.Is(al)) {
19918         EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
19919                 ((encoded_dt.GetEncodingValue() & 0x8) << 21) |
19920                 rd.Encode(22, 12) | rm.Encode(5, 0));
19921         return;
19922       }
19923     }
19924   }
19925   Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm);
19926 }
19927 
vmovn(Condition cond,DataType dt,DRegister rd,QRegister rm)19928 void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) {
19929   VIXL_ASSERT(AllowAssembler());
19930   CheckIT(cond);
19931   Dt_size_3 encoded_dt(dt);
19932   if (IsUsingT32()) {
19933     // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
19934     if (encoded_dt.IsValid()) {
19935       if (cond.Is(al) || AllowStronglyDiscouraged()) {
19936         EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) |
19937                    rd.Encode(22, 12) | rm.Encode(5, 0));
19938         AdvanceIT();
19939         return;
19940       }
19941     }
19942   } else {
19943     // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
19944     if (encoded_dt.IsValid()) {
19945       if (cond.Is(al)) {
19946         EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) |
19947                 rd.Encode(22, 12) | rm.Encode(5, 0));
19948         return;
19949       }
19950     }
19951   }
19952   Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm);
19953 }
19954 
vmrs(Condition cond,RegisterOrAPSR_nzcv rt,SpecialFPRegister spec_reg)19955 void Assembler::vmrs(Condition cond,
19956                      RegisterOrAPSR_nzcv rt,
19957                      SpecialFPRegister spec_reg) {
19958   VIXL_ASSERT(AllowAssembler());
19959   CheckIT(cond);
19960   if (IsUsingT32()) {
19961     // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1
19962     EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16));
19963     AdvanceIT();
19964     return;
19965   } else {
19966     // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1
19967     if (cond.IsNotNever()) {
19968       EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
19969               (spec_reg.GetReg() << 16));
19970       return;
19971     }
19972   }
19973   Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg);
19974 }
19975 
vmsr(Condition cond,SpecialFPRegister spec_reg,Register rt)19976 void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) {
19977   VIXL_ASSERT(AllowAssembler());
19978   CheckIT(cond);
19979   if (IsUsingT32()) {
19980     // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1
19981     EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
19982     AdvanceIT();
19983     return;
19984   } else {
19985     // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1
19986     if (cond.IsNotNever()) {
19987       EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) |
19988               (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
19989       return;
19990     }
19991   }
19992   Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt);
19993 }
19994 
vmul(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister dm,unsigned index)19995 void Assembler::vmul(Condition cond,
19996                      DataType dt,
19997                      DRegister rd,
19998                      DRegister rn,
19999                      DRegister dm,
20000                      unsigned index) {
20001   VIXL_ASSERT(AllowAssembler());
20002   CheckIT(cond);
20003   Dt_F_size_3 encoded_dt(dt);
20004   if (IsUsingT32()) {
20005     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1
20006     if (encoded_dt.IsValid() &&
20007         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
20008          (!dt.Is(I16) && (index <= 1)))) {
20009       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20010         uint32_t shift = 4;
20011         if (dt.Is(I16)) {
20012           shift = 3;
20013         }
20014         uint32_t mvm = dm.GetCode() | index << shift;
20015         EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20016                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
20017                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20018                    ((mvm & 0x10) << 1));
20019         AdvanceIT();
20020         return;
20021       }
20022     }
20023   } else {
20024     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1
20025     if (encoded_dt.IsValid() &&
20026         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
20027          (!dt.Is(I16) && (index <= 1)))) {
20028       if (cond.Is(al)) {
20029         uint32_t shift = 4;
20030         if (dt.Is(I16)) {
20031           shift = 3;
20032         }
20033         uint32_t mvm = dm.GetCode() | index << shift;
20034         EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20035                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
20036                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20037                 ((mvm & 0x10) << 1));
20038         return;
20039       }
20040     }
20041   }
20042   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
20043 }
20044 
vmul(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegister dm,unsigned index)20045 void Assembler::vmul(Condition cond,
20046                      DataType dt,
20047                      QRegister rd,
20048                      QRegister rn,
20049                      DRegister dm,
20050                      unsigned index) {
20051   VIXL_ASSERT(AllowAssembler());
20052   CheckIT(cond);
20053   Dt_F_size_3 encoded_dt(dt);
20054   if (IsUsingT32()) {
20055     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1
20056     if (encoded_dt.IsValid() &&
20057         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
20058          (!dt.Is(I16) && (index <= 1)))) {
20059       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20060         uint32_t shift = 4;
20061         if (dt.Is(I16)) {
20062           shift = 3;
20063         }
20064         uint32_t mvm = dm.GetCode() | index << shift;
20065         EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20066                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
20067                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20068                    ((mvm & 0x10) << 1));
20069         AdvanceIT();
20070         return;
20071       }
20072     }
20073   } else {
20074     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1
20075     if (encoded_dt.IsValid() &&
20076         ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
20077          (!dt.Is(I16) && (index <= 1)))) {
20078       if (cond.Is(al)) {
20079         uint32_t shift = 4;
20080         if (dt.Is(I16)) {
20081           shift = 3;
20082         }
20083         uint32_t mvm = dm.GetCode() | index << shift;
20084         EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20085                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
20086                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20087                 ((mvm & 0x10) << 1));
20088         return;
20089       }
20090     }
20091   }
20092   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
20093 }
20094 
vmul(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)20095 void Assembler::vmul(
20096     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20097   VIXL_ASSERT(AllowAssembler());
20098   CheckIT(cond);
20099   Dt_op_size_1 encoded_dt(dt);
20100   if (IsUsingT32()) {
20101     // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20102     if (dt.Is(F32)) {
20103       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20104         EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20105                    rm.Encode(5, 0));
20106         AdvanceIT();
20107         return;
20108       }
20109     }
20110     // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
20111     if (dt.Is(F64)) {
20112       EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20113                  rm.Encode(5, 0));
20114       AdvanceIT();
20115       return;
20116     }
20117     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20118     if (encoded_dt.IsValid()) {
20119       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20120         EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20121                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20122                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20123         AdvanceIT();
20124         return;
20125       }
20126     }
20127   } else {
20128     // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
20129     if (dt.Is(F32)) {
20130       if (cond.Is(al)) {
20131         EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20132                 rm.Encode(5, 0));
20133         return;
20134       }
20135     }
20136     // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
20137     if (dt.Is(F64) && cond.IsNotNever()) {
20138       EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20139               rn.Encode(7, 16) | rm.Encode(5, 0));
20140       return;
20141     }
20142     // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20143     if (encoded_dt.IsValid()) {
20144       if (cond.Is(al)) {
20145         EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20146                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20147                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20148         return;
20149       }
20150     }
20151   }
20152   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
20153 }
20154 
vmul(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)20155 void Assembler::vmul(
20156     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20157   VIXL_ASSERT(AllowAssembler());
20158   CheckIT(cond);
20159   Dt_op_size_1 encoded_dt(dt);
20160   if (IsUsingT32()) {
20161     // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
20162     if (dt.Is(F32)) {
20163       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20164         EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20165                    rm.Encode(5, 0));
20166         AdvanceIT();
20167         return;
20168       }
20169     }
20170     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
20171     if (encoded_dt.IsValid()) {
20172       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20173         EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20174                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20175                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20176         AdvanceIT();
20177         return;
20178       }
20179     }
20180   } else {
20181     // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
20182     if (dt.Is(F32)) {
20183       if (cond.Is(al)) {
20184         EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20185                 rm.Encode(5, 0));
20186         return;
20187       }
20188     }
20189     // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
20190     if (encoded_dt.IsValid()) {
20191       if (cond.Is(al)) {
20192         EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20193                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20194                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20195         return;
20196       }
20197     }
20198   }
20199   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
20200 }
20201 
vmul(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)20202 void Assembler::vmul(
20203     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20204   VIXL_ASSERT(AllowAssembler());
20205   CheckIT(cond);
20206   if (IsUsingT32()) {
20207     // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
20208     if (dt.Is(F32)) {
20209       EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20210                  rm.Encode(5, 0));
20211       AdvanceIT();
20212       return;
20213     }
20214   } else {
20215     // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
20216     if (dt.Is(F32) && cond.IsNotNever()) {
20217       EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20218               rn.Encode(7, 16) | rm.Encode(5, 0));
20219       return;
20220     }
20221   }
20222   Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
20223 }
20224 
vmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister dm,unsigned index)20225 void Assembler::vmull(Condition cond,
20226                       DataType dt,
20227                       QRegister rd,
20228                       DRegister rn,
20229                       DRegister dm,
20230                       unsigned index) {
20231   VIXL_ASSERT(AllowAssembler());
20232   CheckIT(cond);
20233   Dt_U_size_2 encoded_dt(dt);
20234   if (IsUsingT32()) {
20235     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1
20236     if (encoded_dt.IsValid() &&
20237         (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
20238          (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) {
20239       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20240         uint32_t shift = 4;
20241         if (dt.Is(S16) || dt.Is(U16)) {
20242           shift = 3;
20243         }
20244         uint32_t mvm = dm.GetCode() | index << shift;
20245         EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20246                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20247                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20248                    ((mvm & 0x10) << 1));
20249         AdvanceIT();
20250         return;
20251       }
20252     }
20253   } else {
20254     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1
20255     if (encoded_dt.IsValid() &&
20256         (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
20257          (!dt.Is(S16) && !dt.Is(U16) && (index <= 1)))) {
20258       if (cond.Is(al)) {
20259         uint32_t shift = 4;
20260         if (dt.Is(S16) || dt.Is(U16)) {
20261           shift = 3;
20262         }
20263         uint32_t mvm = dm.GetCode() | index << shift;
20264         EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20265                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20266                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
20267                 ((mvm & 0x10) << 1));
20268         return;
20269       }
20270     }
20271   }
20272   Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index);
20273 }
20274 
vmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)20275 void Assembler::vmull(
20276     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
20277   VIXL_ASSERT(AllowAssembler());
20278   CheckIT(cond);
20279   Dt_op_U_size_1 encoded_dt(dt);
20280   if (IsUsingT32()) {
20281     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
20282     if (encoded_dt.IsValid()) {
20283       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20284         EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20285                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20286                    ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
20287                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20288         AdvanceIT();
20289         return;
20290       }
20291     }
20292   } else {
20293     // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
20294     if (encoded_dt.IsValid()) {
20295       if (cond.Is(al)) {
20296         EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20297                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20298                 ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
20299                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20300         return;
20301       }
20302     }
20303   }
20304   Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm);
20305 }
20306 
vmvn(Condition cond,DataType dt,DRegister rd,const DOperand & operand)20307 void Assembler::vmvn(Condition cond,
20308                      DataType dt,
20309                      DRegister rd,
20310                      const DOperand& operand) {
20311   VIXL_ASSERT(AllowAssembler());
20312   CheckIT(cond);
20313   if (operand.IsImmediate()) {
20314     ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
20315     if (IsUsingT32()) {
20316       // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
20317       if (encoded_dt.IsValid()) {
20318         if (cond.Is(al) || AllowStronglyDiscouraged()) {
20319           EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
20320                      rd.Encode(22, 12) |
20321                      (encoded_dt.GetEncodedImmediate() & 0xf) |
20322                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20323                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20324           AdvanceIT();
20325           return;
20326         }
20327       }
20328     } else {
20329       // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
20330       if (encoded_dt.IsValid()) {
20331         if (cond.Is(al)) {
20332           EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
20333                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20334                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20335                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20336           return;
20337         }
20338       }
20339     }
20340   }
20341   if (operand.IsRegister()) {
20342     DRegister rm = operand.GetRegister();
20343     USE(dt);
20344     if (IsUsingT32()) {
20345       // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
20346       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20347         EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
20348         AdvanceIT();
20349         return;
20350       }
20351     } else {
20352       // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
20353       if (cond.Is(al)) {
20354         EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
20355         return;
20356       }
20357     }
20358   }
20359   Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
20360 }
20361 
vmvn(Condition cond,DataType dt,QRegister rd,const QOperand & operand)20362 void Assembler::vmvn(Condition cond,
20363                      DataType dt,
20364                      QRegister rd,
20365                      const QOperand& operand) {
20366   VIXL_ASSERT(AllowAssembler());
20367   CheckIT(cond);
20368   if (operand.IsImmediate()) {
20369     ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
20370     if (IsUsingT32()) {
20371       // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
20372       if (encoded_dt.IsValid()) {
20373         if (cond.Is(al) || AllowStronglyDiscouraged()) {
20374           EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
20375                      rd.Encode(22, 12) |
20376                      (encoded_dt.GetEncodedImmediate() & 0xf) |
20377                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20378                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20379           AdvanceIT();
20380           return;
20381         }
20382       }
20383     } else {
20384       // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
20385       if (encoded_dt.IsValid()) {
20386         if (cond.Is(al)) {
20387           EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
20388                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20389                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20390                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20391           return;
20392         }
20393       }
20394     }
20395   }
20396   if (operand.IsRegister()) {
20397     QRegister rm = operand.GetRegister();
20398     USE(dt);
20399     if (IsUsingT32()) {
20400       // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
20401       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20402         EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
20403         AdvanceIT();
20404         return;
20405       }
20406     } else {
20407       // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
20408       if (cond.Is(al)) {
20409         EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
20410         return;
20411       }
20412     }
20413   }
20414   Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
20415 }
20416 
vneg(Condition cond,DataType dt,DRegister rd,DRegister rm)20417 void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
20418   VIXL_ASSERT(AllowAssembler());
20419   CheckIT(cond);
20420   Dt_F_size_1 encoded_dt(dt);
20421   if (IsUsingT32()) {
20422     // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20423     if (encoded_dt.IsValid()) {
20424       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20425         EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20426                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20427                    rd.Encode(22, 12) | rm.Encode(5, 0));
20428         AdvanceIT();
20429         return;
20430       }
20431     }
20432     // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
20433     if (dt.Is(F64)) {
20434       EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
20435       AdvanceIT();
20436       return;
20437     }
20438   } else {
20439     // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
20440     if (encoded_dt.IsValid()) {
20441       if (cond.Is(al)) {
20442         EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20443                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20444                 rd.Encode(22, 12) | rm.Encode(5, 0));
20445         return;
20446       }
20447     }
20448     // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
20449     if (dt.Is(F64) && cond.IsNotNever()) {
20450       EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20451               rm.Encode(5, 0));
20452       return;
20453     }
20454   }
20455   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20456 }
20457 
vneg(Condition cond,DataType dt,QRegister rd,QRegister rm)20458 void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
20459   VIXL_ASSERT(AllowAssembler());
20460   CheckIT(cond);
20461   Dt_F_size_1 encoded_dt(dt);
20462   if (IsUsingT32()) {
20463     // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
20464     if (encoded_dt.IsValid()) {
20465       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20466         EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20467                    ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20468                    rd.Encode(22, 12) | rm.Encode(5, 0));
20469         AdvanceIT();
20470         return;
20471       }
20472     }
20473   } else {
20474     // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
20475     if (encoded_dt.IsValid()) {
20476       if (cond.Is(al)) {
20477         EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20478                 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
20479                 rd.Encode(22, 12) | rm.Encode(5, 0));
20480         return;
20481       }
20482     }
20483   }
20484   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20485 }
20486 
vneg(Condition cond,DataType dt,SRegister rd,SRegister rm)20487 void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) {
20488   VIXL_ASSERT(AllowAssembler());
20489   CheckIT(cond);
20490   if (IsUsingT32()) {
20491     // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
20492     if (dt.Is(F32)) {
20493       EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
20494       AdvanceIT();
20495       return;
20496     }
20497   } else {
20498     // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
20499     if (dt.Is(F32) && cond.IsNotNever()) {
20500       EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20501               rm.Encode(5, 0));
20502       return;
20503     }
20504   }
20505   Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
20506 }
20507 
vnmla(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)20508 void Assembler::vnmla(
20509     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20510   VIXL_ASSERT(AllowAssembler());
20511   CheckIT(cond);
20512   if (IsUsingT32()) {
20513     // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
20514     if (dt.Is(F32)) {
20515       EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20516                  rm.Encode(5, 0));
20517       AdvanceIT();
20518       return;
20519     }
20520   } else {
20521     // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
20522     if (dt.Is(F32) && cond.IsNotNever()) {
20523       EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20524               rn.Encode(7, 16) | rm.Encode(5, 0));
20525       return;
20526     }
20527   }
20528   Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
20529 }
20530 
vnmla(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)20531 void Assembler::vnmla(
20532     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20533   VIXL_ASSERT(AllowAssembler());
20534   CheckIT(cond);
20535   if (IsUsingT32()) {
20536     // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
20537     if (dt.Is(F64)) {
20538       EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20539                  rm.Encode(5, 0));
20540       AdvanceIT();
20541       return;
20542     }
20543   } else {
20544     // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
20545     if (dt.Is(F64) && cond.IsNotNever()) {
20546       EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20547               rn.Encode(7, 16) | rm.Encode(5, 0));
20548       return;
20549     }
20550   }
20551   Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
20552 }
20553 
vnmls(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)20554 void Assembler::vnmls(
20555     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20556   VIXL_ASSERT(AllowAssembler());
20557   CheckIT(cond);
20558   if (IsUsingT32()) {
20559     // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
20560     if (dt.Is(F32)) {
20561       EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20562                  rm.Encode(5, 0));
20563       AdvanceIT();
20564       return;
20565     }
20566   } else {
20567     // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
20568     if (dt.Is(F32) && cond.IsNotNever()) {
20569       EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20570               rn.Encode(7, 16) | rm.Encode(5, 0));
20571       return;
20572     }
20573   }
20574   Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
20575 }
20576 
vnmls(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)20577 void Assembler::vnmls(
20578     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20579   VIXL_ASSERT(AllowAssembler());
20580   CheckIT(cond);
20581   if (IsUsingT32()) {
20582     // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
20583     if (dt.Is(F64)) {
20584       EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20585                  rm.Encode(5, 0));
20586       AdvanceIT();
20587       return;
20588     }
20589   } else {
20590     // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
20591     if (dt.Is(F64) && cond.IsNotNever()) {
20592       EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20593               rn.Encode(7, 16) | rm.Encode(5, 0));
20594       return;
20595     }
20596   }
20597   Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
20598 }
20599 
vnmul(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)20600 void Assembler::vnmul(
20601     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20602   VIXL_ASSERT(AllowAssembler());
20603   CheckIT(cond);
20604   if (IsUsingT32()) {
20605     // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
20606     if (dt.Is(F32)) {
20607       EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20608                  rm.Encode(5, 0));
20609       AdvanceIT();
20610       return;
20611     }
20612   } else {
20613     // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
20614     if (dt.Is(F32) && cond.IsNotNever()) {
20615       EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20616               rn.Encode(7, 16) | rm.Encode(5, 0));
20617       return;
20618     }
20619   }
20620   Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
20621 }
20622 
vnmul(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)20623 void Assembler::vnmul(
20624     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20625   VIXL_ASSERT(AllowAssembler());
20626   CheckIT(cond);
20627   if (IsUsingT32()) {
20628     // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
20629     if (dt.Is(F64)) {
20630       EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20631                  rm.Encode(5, 0));
20632       AdvanceIT();
20633       return;
20634     }
20635   } else {
20636     // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
20637     if (dt.Is(F64) && cond.IsNotNever()) {
20638       EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20639               rn.Encode(7, 16) | rm.Encode(5, 0));
20640       return;
20641     }
20642   }
20643   Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
20644 }
20645 
vorn(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)20646 void Assembler::vorn(Condition cond,
20647                      DataType dt,
20648                      DRegister rd,
20649                      DRegister rn,
20650                      const DOperand& operand) {
20651   VIXL_ASSERT(AllowAssembler());
20652   CheckIT(cond);
20653   if (operand.IsImmediate()) {
20654     ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
20655     if (IsUsingT32()) {
20656       // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
20657       if (encoded_dt.IsValid() && rd.Is(rn)) {
20658         if (cond.Is(al) || AllowStronglyDiscouraged()) {
20659           EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
20660                      rd.Encode(22, 12) |
20661                      (encoded_dt.GetEncodedImmediate() & 0xf) |
20662                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20663                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20664           AdvanceIT();
20665           return;
20666         }
20667       }
20668     } else {
20669       // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
20670       if (encoded_dt.IsValid() && rd.Is(rn)) {
20671         if (cond.Is(al)) {
20672           EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
20673                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20674                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20675                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20676           return;
20677         }
20678       }
20679     }
20680   }
20681   if (operand.IsRegister()) {
20682     DRegister rm = operand.GetRegister();
20683     USE(dt);
20684     if (IsUsingT32()) {
20685       // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
20686       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20687         EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20688                    rm.Encode(5, 0));
20689         AdvanceIT();
20690         return;
20691       }
20692     } else {
20693       // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
20694       if (cond.Is(al)) {
20695         EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20696                 rm.Encode(5, 0));
20697         return;
20698       }
20699     }
20700   }
20701   Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
20702 }
20703 
vorn(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)20704 void Assembler::vorn(Condition cond,
20705                      DataType dt,
20706                      QRegister rd,
20707                      QRegister rn,
20708                      const QOperand& operand) {
20709   VIXL_ASSERT(AllowAssembler());
20710   CheckIT(cond);
20711   if (operand.IsImmediate()) {
20712     ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
20713     if (IsUsingT32()) {
20714       // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
20715       if (encoded_dt.IsValid() && rd.Is(rn)) {
20716         if (cond.Is(al) || AllowStronglyDiscouraged()) {
20717           EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
20718                      rd.Encode(22, 12) |
20719                      (encoded_dt.GetEncodedImmediate() & 0xf) |
20720                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20721                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20722           AdvanceIT();
20723           return;
20724         }
20725       }
20726     } else {
20727       // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
20728       if (encoded_dt.IsValid() && rd.Is(rn)) {
20729         if (cond.Is(al)) {
20730           EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
20731                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20732                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20733                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20734           return;
20735         }
20736       }
20737     }
20738   }
20739   if (operand.IsRegister()) {
20740     QRegister rm = operand.GetRegister();
20741     USE(dt);
20742     if (IsUsingT32()) {
20743       // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
20744       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20745         EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20746                    rm.Encode(5, 0));
20747         AdvanceIT();
20748         return;
20749       }
20750     } else {
20751       // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
20752       if (cond.Is(al)) {
20753         EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20754                 rm.Encode(5, 0));
20755         return;
20756       }
20757     }
20758   }
20759   Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
20760 }
20761 
vorr(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)20762 void Assembler::vorr(Condition cond,
20763                      DataType dt,
20764                      DRegister rd,
20765                      DRegister rn,
20766                      const DOperand& operand) {
20767   VIXL_ASSERT(AllowAssembler());
20768   CheckIT(cond);
20769   if (operand.IsRegister()) {
20770     DRegister rm = operand.GetRegister();
20771     USE(dt);
20772     if (IsUsingT32()) {
20773       // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
20774       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20775         EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20776                    rm.Encode(5, 0));
20777         AdvanceIT();
20778         return;
20779       }
20780     } else {
20781       // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
20782       if (cond.Is(al)) {
20783         EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20784                 rm.Encode(5, 0));
20785         return;
20786       }
20787     }
20788   }
20789   if (operand.IsImmediate()) {
20790     ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
20791     if (IsUsingT32()) {
20792       // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
20793       if (encoded_dt.IsValid() && rd.Is(rn)) {
20794         if (cond.Is(al) || AllowStronglyDiscouraged()) {
20795           EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
20796                      rd.Encode(22, 12) |
20797                      (encoded_dt.GetEncodedImmediate() & 0xf) |
20798                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20799                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20800           AdvanceIT();
20801           return;
20802         }
20803       }
20804     } else {
20805       // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
20806       if (encoded_dt.IsValid() && rd.Is(rn)) {
20807         if (cond.Is(al)) {
20808           EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
20809                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20810                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20811                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20812           return;
20813         }
20814       }
20815     }
20816   }
20817   Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
20818 }
20819 
vorr(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)20820 void Assembler::vorr(Condition cond,
20821                      DataType dt,
20822                      QRegister rd,
20823                      QRegister rn,
20824                      const QOperand& operand) {
20825   VIXL_ASSERT(AllowAssembler());
20826   CheckIT(cond);
20827   if (operand.IsRegister()) {
20828     QRegister rm = operand.GetRegister();
20829     USE(dt);
20830     if (IsUsingT32()) {
20831       // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
20832       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20833         EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20834                    rm.Encode(5, 0));
20835         AdvanceIT();
20836         return;
20837       }
20838     } else {
20839       // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
20840       if (cond.Is(al)) {
20841         EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20842                 rm.Encode(5, 0));
20843         return;
20844       }
20845     }
20846   }
20847   if (operand.IsImmediate()) {
20848     ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
20849     if (IsUsingT32()) {
20850       // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
20851       if (encoded_dt.IsValid() && rd.Is(rn)) {
20852         if (cond.Is(al) || AllowStronglyDiscouraged()) {
20853           EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
20854                      rd.Encode(22, 12) |
20855                      (encoded_dt.GetEncodedImmediate() & 0xf) |
20856                      ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20857                      ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20858           AdvanceIT();
20859           return;
20860         }
20861       }
20862     } else {
20863       // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
20864       if (encoded_dt.IsValid() && rd.Is(rn)) {
20865         if (cond.Is(al)) {
20866           EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
20867                   rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20868                   ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20869                   ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20870           return;
20871         }
20872       }
20873     }
20874   }
20875   Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
20876 }
20877 
vpadal(Condition cond,DataType dt,DRegister rd,DRegister rm)20878 void Assembler::vpadal(Condition cond,
20879                        DataType dt,
20880                        DRegister rd,
20881                        DRegister rm) {
20882   VIXL_ASSERT(AllowAssembler());
20883   CheckIT(cond);
20884   Dt_op_size_2 encoded_dt(dt);
20885   if (IsUsingT32()) {
20886     // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20887     if (encoded_dt.IsValid()) {
20888       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20889         EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20890                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20891                    rd.Encode(22, 12) | rm.Encode(5, 0));
20892         AdvanceIT();
20893         return;
20894       }
20895     }
20896   } else {
20897     // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
20898     if (encoded_dt.IsValid()) {
20899       if (cond.Is(al)) {
20900         EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20901                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20902                 rd.Encode(22, 12) | rm.Encode(5, 0));
20903         return;
20904       }
20905     }
20906   }
20907   Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
20908 }
20909 
vpadal(Condition cond,DataType dt,QRegister rd,QRegister rm)20910 void Assembler::vpadal(Condition cond,
20911                        DataType dt,
20912                        QRegister rd,
20913                        QRegister rm) {
20914   VIXL_ASSERT(AllowAssembler());
20915   CheckIT(cond);
20916   Dt_op_size_2 encoded_dt(dt);
20917   if (IsUsingT32()) {
20918     // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
20919     if (encoded_dt.IsValid()) {
20920       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20921         EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20922                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20923                    rd.Encode(22, 12) | rm.Encode(5, 0));
20924         AdvanceIT();
20925         return;
20926       }
20927     }
20928   } else {
20929     // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
20930     if (encoded_dt.IsValid()) {
20931       if (cond.Is(al)) {
20932         EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20933                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
20934                 rd.Encode(22, 12) | rm.Encode(5, 0));
20935         return;
20936       }
20937     }
20938   }
20939   Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
20940 }
20941 
vpadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)20942 void Assembler::vpadd(
20943     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20944   VIXL_ASSERT(AllowAssembler());
20945   CheckIT(cond);
20946   Dt_size_4 encoded_dt(dt);
20947   if (IsUsingT32()) {
20948     // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20949     if (dt.Is(F32)) {
20950       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20951         EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20952                    rm.Encode(5, 0));
20953         AdvanceIT();
20954         return;
20955       }
20956     }
20957     // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20958     if (encoded_dt.IsValid()) {
20959       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20960         EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) |
20961                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20962         AdvanceIT();
20963         return;
20964       }
20965     }
20966   } else {
20967     // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
20968     if (dt.Is(F32)) {
20969       if (cond.Is(al)) {
20970         EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20971                 rm.Encode(5, 0));
20972         return;
20973       }
20974     }
20975     // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20976     if (encoded_dt.IsValid()) {
20977       if (cond.Is(al)) {
20978         EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) |
20979                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20980         return;
20981       }
20982     }
20983   }
20984   Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm);
20985 }
20986 
vpaddl(Condition cond,DataType dt,DRegister rd,DRegister rm)20987 void Assembler::vpaddl(Condition cond,
20988                        DataType dt,
20989                        DRegister rd,
20990                        DRegister rm) {
20991   VIXL_ASSERT(AllowAssembler());
20992   CheckIT(cond);
20993   Dt_op_size_2 encoded_dt(dt);
20994   if (IsUsingT32()) {
20995     // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
20996     if (encoded_dt.IsValid()) {
20997       if (cond.Is(al) || AllowStronglyDiscouraged()) {
20998         EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
20999                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
21000                    rd.Encode(22, 12) | rm.Encode(5, 0));
21001         AdvanceIT();
21002         return;
21003       }
21004     }
21005   } else {
21006     // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
21007     if (encoded_dt.IsValid()) {
21008       if (cond.Is(al)) {
21009         EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21010                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
21011                 rd.Encode(22, 12) | rm.Encode(5, 0));
21012         return;
21013       }
21014     }
21015   }
21016   Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
21017 }
21018 
vpaddl(Condition cond,DataType dt,QRegister rd,QRegister rm)21019 void Assembler::vpaddl(Condition cond,
21020                        DataType dt,
21021                        QRegister rd,
21022                        QRegister rm) {
21023   VIXL_ASSERT(AllowAssembler());
21024   CheckIT(cond);
21025   Dt_op_size_2 encoded_dt(dt);
21026   if (IsUsingT32()) {
21027     // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
21028     if (encoded_dt.IsValid()) {
21029       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21030         EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21031                    ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
21032                    rd.Encode(22, 12) | rm.Encode(5, 0));
21033         AdvanceIT();
21034         return;
21035       }
21036     }
21037   } else {
21038     // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
21039     if (encoded_dt.IsValid()) {
21040       if (cond.Is(al)) {
21041         EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21042                 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
21043                 rd.Encode(22, 12) | rm.Encode(5, 0));
21044         return;
21045       }
21046     }
21047   }
21048   Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
21049 }
21050 
vpmax(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21051 void Assembler::vpmax(
21052     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21053   VIXL_ASSERT(AllowAssembler());
21054   CheckIT(cond);
21055   Dt_U_size_1 encoded_dt(dt);
21056   if (IsUsingT32()) {
21057     // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
21058     if (dt.Is(F32)) {
21059       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21060         EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21061                    rm.Encode(5, 0));
21062         AdvanceIT();
21063         return;
21064       }
21065     }
21066     // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21067     if (encoded_dt.IsValid()) {
21068       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21069         EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21070                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21071                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21072         AdvanceIT();
21073         return;
21074       }
21075     }
21076   } else {
21077     // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
21078     if (dt.Is(F32)) {
21079       if (cond.Is(al)) {
21080         EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21081                 rm.Encode(5, 0));
21082         return;
21083       }
21084     }
21085     // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21086     if (encoded_dt.IsValid()) {
21087       if (cond.Is(al)) {
21088         EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21089                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21090                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21091         return;
21092       }
21093     }
21094   }
21095   Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm);
21096 }
21097 
vpmin(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21098 void Assembler::vpmin(
21099     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21100   VIXL_ASSERT(AllowAssembler());
21101   CheckIT(cond);
21102   Dt_U_size_1 encoded_dt(dt);
21103   if (IsUsingT32()) {
21104     // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
21105     if (dt.Is(F32)) {
21106       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21107         EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21108                    rm.Encode(5, 0));
21109         AdvanceIT();
21110         return;
21111       }
21112     }
21113     // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21114     if (encoded_dt.IsValid()) {
21115       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21116         EmitT32_32(0xef000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21117                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21118                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21119         AdvanceIT();
21120         return;
21121       }
21122     }
21123   } else {
21124     // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
21125     if (dt.Is(F32)) {
21126       if (cond.Is(al)) {
21127         EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21128                 rm.Encode(5, 0));
21129         return;
21130       }
21131     }
21132     // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21133     if (encoded_dt.IsValid()) {
21134       if (cond.Is(al)) {
21135         EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21136                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21137                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21138         return;
21139       }
21140     }
21141   }
21142   Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm);
21143 }
21144 
vpop(Condition cond,DataType dt,DRegisterList dreglist)21145 void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) {
21146   VIXL_ASSERT(AllowAssembler());
21147   CheckIT(cond);
21148   USE(dt);
21149   if (IsUsingT32()) {
21150     // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1
21151     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
21152       const DRegister& dreg = dreglist.GetFirstDRegister();
21153       unsigned len = dreglist.GetLength() * 2;
21154       EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff));
21155       AdvanceIT();
21156       return;
21157     }
21158   } else {
21159     // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1
21160     if (cond.IsNotNever() &&
21161         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
21162       const DRegister& dreg = dreglist.GetFirstDRegister();
21163       unsigned len = dreglist.GetLength() * 2;
21164       EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
21165               (len & 0xff));
21166       return;
21167     }
21168   }
21169   Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist);
21170 }
21171 
vpop(Condition cond,DataType dt,SRegisterList sreglist)21172 void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) {
21173   VIXL_ASSERT(AllowAssembler());
21174   CheckIT(cond);
21175   USE(dt);
21176   if (IsUsingT32()) {
21177     // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2
21178     const SRegister& sreg = sreglist.GetFirstSRegister();
21179     unsigned len = sreglist.GetLength();
21180     EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff));
21181     AdvanceIT();
21182     return;
21183   } else {
21184     // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2
21185     if (cond.IsNotNever()) {
21186       const SRegister& sreg = sreglist.GetFirstSRegister();
21187       unsigned len = sreglist.GetLength();
21188       EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
21189               (len & 0xff));
21190       return;
21191     }
21192   }
21193   Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist);
21194 }
21195 
vpush(Condition cond,DataType dt,DRegisterList dreglist)21196 void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) {
21197   VIXL_ASSERT(AllowAssembler());
21198   CheckIT(cond);
21199   USE(dt);
21200   if (IsUsingT32()) {
21201     // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1
21202     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
21203       const DRegister& dreg = dreglist.GetFirstDRegister();
21204       unsigned len = dreglist.GetLength() * 2;
21205       EmitT32_32(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff));
21206       AdvanceIT();
21207       return;
21208     }
21209   } else {
21210     // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1
21211     if (cond.IsNotNever() &&
21212         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
21213       const DRegister& dreg = dreglist.GetFirstDRegister();
21214       unsigned len = dreglist.GetLength() * 2;
21215       EmitA32(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
21216               (len & 0xff));
21217       return;
21218     }
21219   }
21220   Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist);
21221 }
21222 
vpush(Condition cond,DataType dt,SRegisterList sreglist)21223 void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) {
21224   VIXL_ASSERT(AllowAssembler());
21225   CheckIT(cond);
21226   USE(dt);
21227   if (IsUsingT32()) {
21228     // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2
21229     const SRegister& sreg = sreglist.GetFirstSRegister();
21230     unsigned len = sreglist.GetLength();
21231     EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff));
21232     AdvanceIT();
21233     return;
21234   } else {
21235     // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2
21236     if (cond.IsNotNever()) {
21237       const SRegister& sreg = sreglist.GetFirstSRegister();
21238       unsigned len = sreglist.GetLength();
21239       EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
21240               (len & 0xff));
21241       return;
21242     }
21243   }
21244   Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist);
21245 }
21246 
vqabs(Condition cond,DataType dt,DRegister rd,DRegister rm)21247 void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
21248   VIXL_ASSERT(AllowAssembler());
21249   CheckIT(cond);
21250   Dt_size_5 encoded_dt(dt);
21251   if (IsUsingT32()) {
21252     // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
21253     if (encoded_dt.IsValid()) {
21254       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21255         EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) |
21256                    rd.Encode(22, 12) | rm.Encode(5, 0));
21257         AdvanceIT();
21258         return;
21259       }
21260     }
21261   } else {
21262     // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
21263     if (encoded_dt.IsValid()) {
21264       if (cond.Is(al)) {
21265         EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) |
21266                 rd.Encode(22, 12) | rm.Encode(5, 0));
21267         return;
21268       }
21269     }
21270   }
21271   Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
21272 }
21273 
vqabs(Condition cond,DataType dt,QRegister rd,QRegister rm)21274 void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
21275   VIXL_ASSERT(AllowAssembler());
21276   CheckIT(cond);
21277   Dt_size_5 encoded_dt(dt);
21278   if (IsUsingT32()) {
21279     // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
21280     if (encoded_dt.IsValid()) {
21281       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21282         EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) |
21283                    rd.Encode(22, 12) | rm.Encode(5, 0));
21284         AdvanceIT();
21285         return;
21286       }
21287     }
21288   } else {
21289     // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
21290     if (encoded_dt.IsValid()) {
21291       if (cond.Is(al)) {
21292         EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) |
21293                 rd.Encode(22, 12) | rm.Encode(5, 0));
21294         return;
21295       }
21296     }
21297   }
21298   Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
21299 }
21300 
vqadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21301 void Assembler::vqadd(
21302     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21303   VIXL_ASSERT(AllowAssembler());
21304   CheckIT(cond);
21305   Dt_U_size_3 encoded_dt(dt);
21306   if (IsUsingT32()) {
21307     // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21308     if (encoded_dt.IsValid()) {
21309       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21310         EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21311                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21312                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21313         AdvanceIT();
21314         return;
21315       }
21316     }
21317   } else {
21318     // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21319     if (encoded_dt.IsValid()) {
21320       if (cond.Is(al)) {
21321         EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21322                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21323                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21324         return;
21325       }
21326     }
21327   }
21328   Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
21329 }
21330 
vqadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)21331 void Assembler::vqadd(
21332     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21333   VIXL_ASSERT(AllowAssembler());
21334   CheckIT(cond);
21335   Dt_U_size_3 encoded_dt(dt);
21336   if (IsUsingT32()) {
21337     // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21338     if (encoded_dt.IsValid()) {
21339       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21340         EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21341                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21342                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21343         AdvanceIT();
21344         return;
21345       }
21346     }
21347   } else {
21348     // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21349     if (encoded_dt.IsValid()) {
21350       if (cond.Is(al)) {
21351         EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21352                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21353                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21354         return;
21355       }
21356     }
21357   }
21358   Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
21359 }
21360 
vqdmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)21361 void Assembler::vqdmlal(
21362     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21363   VIXL_ASSERT(AllowAssembler());
21364   CheckIT(cond);
21365   Dt_size_13 encoded_dt(dt);
21366   if (IsUsingT32()) {
21367     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21368     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21369       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21370         EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) |
21371                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21372         AdvanceIT();
21373         return;
21374       }
21375     }
21376   } else {
21377     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21378     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21379       if (cond.Is(al)) {
21380         EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) |
21381                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21382         return;
21383       }
21384     }
21385   }
21386   Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm);
21387 }
21388 
vqdmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister dm,unsigned index)21389 void Assembler::vqdmlal(Condition cond,
21390                         DataType dt,
21391                         QRegister rd,
21392                         DRegister rn,
21393                         DRegister dm,
21394                         unsigned index) {
21395   VIXL_ASSERT(AllowAssembler());
21396   CheckIT(cond);
21397   Dt_size_13 encoded_dt(dt);
21398   if (IsUsingT32()) {
21399     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
21400     if (encoded_dt.IsValid() &&
21401         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21402          (!dt.Is(S16) && (index <= 1))) &&
21403         (dt.Is(S16) || dt.Is(S32))) {
21404       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21405         uint32_t shift = 4;
21406         if (dt.Is(S16)) {
21407           shift = 3;
21408         }
21409         uint32_t mvm = dm.GetCode() | index << shift;
21410         EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) |
21411                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21412                    ((mvm & 0x10) << 1));
21413         AdvanceIT();
21414         return;
21415       }
21416     }
21417   } else {
21418     // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
21419     if (encoded_dt.IsValid() &&
21420         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21421          (!dt.Is(S16) && (index <= 1))) &&
21422         (dt.Is(S16) || dt.Is(S32))) {
21423       if (cond.Is(al)) {
21424         uint32_t shift = 4;
21425         if (dt.Is(S16)) {
21426           shift = 3;
21427         }
21428         uint32_t mvm = dm.GetCode() | index << shift;
21429         EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) |
21430                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21431                 ((mvm & 0x10) << 1));
21432         return;
21433       }
21434     }
21435   }
21436   Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index);
21437 }
21438 
vqdmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)21439 void Assembler::vqdmlsl(
21440     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21441   VIXL_ASSERT(AllowAssembler());
21442   CheckIT(cond);
21443   Dt_size_13 encoded_dt(dt);
21444   if (IsUsingT32()) {
21445     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21446     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21447       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21448         EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) |
21449                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21450         AdvanceIT();
21451         return;
21452       }
21453     }
21454   } else {
21455     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21456     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21457       if (cond.Is(al)) {
21458         EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) |
21459                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21460         return;
21461       }
21462     }
21463   }
21464   Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm);
21465 }
21466 
vqdmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister dm,unsigned index)21467 void Assembler::vqdmlsl(Condition cond,
21468                         DataType dt,
21469                         QRegister rd,
21470                         DRegister rn,
21471                         DRegister dm,
21472                         unsigned index) {
21473   VIXL_ASSERT(AllowAssembler());
21474   CheckIT(cond);
21475   Dt_size_13 encoded_dt(dt);
21476   if (IsUsingT32()) {
21477     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
21478     if (encoded_dt.IsValid() &&
21479         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21480          (!dt.Is(S16) && (index <= 1))) &&
21481         (dt.Is(S16) || dt.Is(S32))) {
21482       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21483         uint32_t shift = 4;
21484         if (dt.Is(S16)) {
21485           shift = 3;
21486         }
21487         uint32_t mvm = dm.GetCode() | index << shift;
21488         EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) |
21489                    rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21490                    ((mvm & 0x10) << 1));
21491         AdvanceIT();
21492         return;
21493       }
21494     }
21495   } else {
21496     // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
21497     if (encoded_dt.IsValid() &&
21498         ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21499          (!dt.Is(S16) && (index <= 1))) &&
21500         (dt.Is(S16) || dt.Is(S32))) {
21501       if (cond.Is(al)) {
21502         uint32_t shift = 4;
21503         if (dt.Is(S16)) {
21504           shift = 3;
21505         }
21506         uint32_t mvm = dm.GetCode() | index << shift;
21507         EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) |
21508                 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21509                 ((mvm & 0x10) << 1));
21510         return;
21511       }
21512     }
21513   }
21514   Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index);
21515 }
21516 
vqdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21517 void Assembler::vqdmulh(
21518     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21519   VIXL_ASSERT(AllowAssembler());
21520   CheckIT(cond);
21521   Dt_size_13 encoded_dt(dt);
21522   if (IsUsingT32()) {
21523     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21524     if (encoded_dt.IsValid()) {
21525       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21526         EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) |
21527                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21528         AdvanceIT();
21529         return;
21530       }
21531     }
21532   } else {
21533     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21534     if (encoded_dt.IsValid()) {
21535       if (cond.Is(al)) {
21536         EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) |
21537                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21538         return;
21539       }
21540     }
21541   }
21542   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21543 }
21544 
vqdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)21545 void Assembler::vqdmulh(
21546     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21547   VIXL_ASSERT(AllowAssembler());
21548   CheckIT(cond);
21549   Dt_size_13 encoded_dt(dt);
21550   if (IsUsingT32()) {
21551     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21552     if (encoded_dt.IsValid()) {
21553       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21554         EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) |
21555                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21556         AdvanceIT();
21557         return;
21558       }
21559     }
21560   } else {
21561     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21562     if (encoded_dt.IsValid()) {
21563       if (cond.Is(al)) {
21564         EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) |
21565                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21566         return;
21567       }
21568     }
21569   }
21570   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21571 }
21572 
vqdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)21573 void Assembler::vqdmulh(
21574     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
21575   VIXL_ASSERT(AllowAssembler());
21576   CheckIT(cond);
21577   Dt_size_13 encoded_dt(dt);
21578   if (IsUsingT32()) {
21579     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
21580     if (encoded_dt.IsValid() &&
21581         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21582          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21583           (rm.GetLane() <= 1))) &&
21584         (dt.Is(S16) || dt.Is(S32))) {
21585       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21586         EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) |
21587                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21588         AdvanceIT();
21589         return;
21590       }
21591     }
21592   } else {
21593     // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
21594     if (encoded_dt.IsValid() &&
21595         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21596          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21597           (rm.GetLane() <= 1))) &&
21598         (dt.Is(S16) || dt.Is(S32))) {
21599       if (cond.Is(al)) {
21600         EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) |
21601                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21602         return;
21603       }
21604     }
21605   }
21606   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21607 }
21608 
vqdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)21609 void Assembler::vqdmulh(
21610     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
21611   VIXL_ASSERT(AllowAssembler());
21612   CheckIT(cond);
21613   Dt_size_13 encoded_dt(dt);
21614   if (IsUsingT32()) {
21615     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
21616     if (encoded_dt.IsValid() &&
21617         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21618          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21619           (rm.GetLane() <= 1))) &&
21620         (dt.Is(S16) || dt.Is(S32))) {
21621       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21622         EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) |
21623                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21624         AdvanceIT();
21625         return;
21626       }
21627     }
21628   } else {
21629     // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
21630     if (encoded_dt.IsValid() &&
21631         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21632          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21633           (rm.GetLane() <= 1))) &&
21634         (dt.Is(S16) || dt.Is(S32))) {
21635       if (cond.Is(al)) {
21636         EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) |
21637                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21638         return;
21639       }
21640     }
21641   }
21642   Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
21643 }
21644 
vqdmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)21645 void Assembler::vqdmull(
21646     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21647   VIXL_ASSERT(AllowAssembler());
21648   CheckIT(cond);
21649   Dt_size_13 encoded_dt(dt);
21650   if (IsUsingT32()) {
21651     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21652     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21653       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21654         EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) |
21655                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21656         AdvanceIT();
21657         return;
21658       }
21659     }
21660   } else {
21661     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21662     if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
21663       if (cond.Is(al)) {
21664         EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) |
21665                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21666         return;
21667       }
21668     }
21669   }
21670   Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
21671 }
21672 
vqdmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegisterLane rm)21673 void Assembler::vqdmull(
21674     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
21675   VIXL_ASSERT(AllowAssembler());
21676   CheckIT(cond);
21677   Dt_size_13 encoded_dt(dt);
21678   if (IsUsingT32()) {
21679     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2
21680     if (encoded_dt.IsValid() &&
21681         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21682          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21683           (rm.GetLane() <= 1))) &&
21684         (dt.Is(S16) || dt.Is(S32))) {
21685       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21686         EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) |
21687                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21688         AdvanceIT();
21689         return;
21690       }
21691     }
21692   } else {
21693     // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2
21694     if (encoded_dt.IsValid() &&
21695         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21696          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21697           (rm.GetLane() <= 1))) &&
21698         (dt.Is(S16) || dt.Is(S32))) {
21699       if (cond.Is(al)) {
21700         EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) |
21701                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21702         return;
21703       }
21704     }
21705   }
21706   Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
21707 }
21708 
vqmovn(Condition cond,DataType dt,DRegister rd,QRegister rm)21709 void Assembler::vqmovn(Condition cond,
21710                        DataType dt,
21711                        DRegister rd,
21712                        QRegister rm) {
21713   VIXL_ASSERT(AllowAssembler());
21714   CheckIT(cond);
21715   Dt_op_size_3 encoded_dt(dt);
21716   if (IsUsingT32()) {
21717     // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
21718     if (encoded_dt.IsValid()) {
21719       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21720         EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21721                    ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21722                    rd.Encode(22, 12) | rm.Encode(5, 0));
21723         AdvanceIT();
21724         return;
21725       }
21726     }
21727   } else {
21728     // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
21729     if (encoded_dt.IsValid()) {
21730       if (cond.Is(al)) {
21731         EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21732                 ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
21733                 rd.Encode(22, 12) | rm.Encode(5, 0));
21734         return;
21735       }
21736     }
21737   }
21738   Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm);
21739 }
21740 
vqmovun(Condition cond,DataType dt,DRegister rd,QRegister rm)21741 void Assembler::vqmovun(Condition cond,
21742                         DataType dt,
21743                         DRegister rd,
21744                         QRegister rm) {
21745   VIXL_ASSERT(AllowAssembler());
21746   CheckIT(cond);
21747   Dt_size_14 encoded_dt(dt);
21748   if (IsUsingT32()) {
21749     // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
21750     if (encoded_dt.IsValid()) {
21751       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21752         EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) |
21753                    rd.Encode(22, 12) | rm.Encode(5, 0));
21754         AdvanceIT();
21755         return;
21756       }
21757     }
21758   } else {
21759     // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
21760     if (encoded_dt.IsValid()) {
21761       if (cond.Is(al)) {
21762         EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) |
21763                 rd.Encode(22, 12) | rm.Encode(5, 0));
21764         return;
21765       }
21766     }
21767   }
21768   Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm);
21769 }
21770 
vqneg(Condition cond,DataType dt,DRegister rd,DRegister rm)21771 void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
21772   VIXL_ASSERT(AllowAssembler());
21773   CheckIT(cond);
21774   Dt_size_5 encoded_dt(dt);
21775   if (IsUsingT32()) {
21776     // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
21777     if (encoded_dt.IsValid()) {
21778       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21779         EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) |
21780                    rd.Encode(22, 12) | rm.Encode(5, 0));
21781         AdvanceIT();
21782         return;
21783       }
21784     }
21785   } else {
21786     // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
21787     if (encoded_dt.IsValid()) {
21788       if (cond.Is(al)) {
21789         EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) |
21790                 rd.Encode(22, 12) | rm.Encode(5, 0));
21791         return;
21792       }
21793     }
21794   }
21795   Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
21796 }
21797 
vqneg(Condition cond,DataType dt,QRegister rd,QRegister rm)21798 void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
21799   VIXL_ASSERT(AllowAssembler());
21800   CheckIT(cond);
21801   Dt_size_5 encoded_dt(dt);
21802   if (IsUsingT32()) {
21803     // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
21804     if (encoded_dt.IsValid()) {
21805       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21806         EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) |
21807                    rd.Encode(22, 12) | rm.Encode(5, 0));
21808         AdvanceIT();
21809         return;
21810       }
21811     }
21812   } else {
21813     // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
21814     if (encoded_dt.IsValid()) {
21815       if (cond.Is(al)) {
21816         EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) |
21817                 rd.Encode(22, 12) | rm.Encode(5, 0));
21818         return;
21819       }
21820     }
21821   }
21822   Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
21823 }
21824 
vqrdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21825 void Assembler::vqrdmulh(
21826     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21827   VIXL_ASSERT(AllowAssembler());
21828   CheckIT(cond);
21829   Dt_size_13 encoded_dt(dt);
21830   if (IsUsingT32()) {
21831     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21832     if (encoded_dt.IsValid()) {
21833       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21834         EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) |
21835                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21836         AdvanceIT();
21837         return;
21838       }
21839     }
21840   } else {
21841     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21842     if (encoded_dt.IsValid()) {
21843       if (cond.Is(al)) {
21844         EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) |
21845                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21846         return;
21847       }
21848     }
21849   }
21850   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21851 }
21852 
vqrdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)21853 void Assembler::vqrdmulh(
21854     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21855   VIXL_ASSERT(AllowAssembler());
21856   CheckIT(cond);
21857   Dt_size_13 encoded_dt(dt);
21858   if (IsUsingT32()) {
21859     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21860     if (encoded_dt.IsValid()) {
21861       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21862         EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) |
21863                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21864         AdvanceIT();
21865         return;
21866       }
21867     }
21868   } else {
21869     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21870     if (encoded_dt.IsValid()) {
21871       if (cond.Is(al)) {
21872         EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) |
21873                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21874         return;
21875       }
21876     }
21877   }
21878   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21879 }
21880 
vqrdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)21881 void Assembler::vqrdmulh(
21882     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
21883   VIXL_ASSERT(AllowAssembler());
21884   CheckIT(cond);
21885   Dt_size_13 encoded_dt(dt);
21886   if (IsUsingT32()) {
21887     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
21888     if (encoded_dt.IsValid() &&
21889         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21890          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21891           (rm.GetLane() <= 1))) &&
21892         (dt.Is(S16) || dt.Is(S32))) {
21893       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21894         EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) |
21895                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21896         AdvanceIT();
21897         return;
21898       }
21899     }
21900   } else {
21901     // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
21902     if (encoded_dt.IsValid() &&
21903         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21904          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21905           (rm.GetLane() <= 1))) &&
21906         (dt.Is(S16) || dt.Is(S32))) {
21907       if (cond.Is(al)) {
21908         EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) |
21909                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21910         return;
21911       }
21912     }
21913   }
21914   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21915 }
21916 
vqrdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)21917 void Assembler::vqrdmulh(
21918     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
21919   VIXL_ASSERT(AllowAssembler());
21920   CheckIT(cond);
21921   Dt_size_13 encoded_dt(dt);
21922   if (IsUsingT32()) {
21923     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
21924     if (encoded_dt.IsValid() &&
21925         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21926          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21927           (rm.GetLane() <= 1))) &&
21928         (dt.Is(S16) || dt.Is(S32))) {
21929       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21930         EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) |
21931                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21932         AdvanceIT();
21933         return;
21934       }
21935     }
21936   } else {
21937     // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
21938     if (encoded_dt.IsValid() &&
21939         (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
21940          ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
21941           (rm.GetLane() <= 1))) &&
21942         (dt.Is(S16) || dt.Is(S32))) {
21943       if (cond.Is(al)) {
21944         EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) |
21945                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
21946         return;
21947       }
21948     }
21949   }
21950   Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
21951 }
21952 
vqrshl(Condition cond,DataType dt,DRegister rd,DRegister rm,DRegister rn)21953 void Assembler::vqrshl(
21954     Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
21955   VIXL_ASSERT(AllowAssembler());
21956   CheckIT(cond);
21957   Dt_U_size_3 encoded_dt(dt);
21958   if (IsUsingT32()) {
21959     // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
21960     if (encoded_dt.IsValid()) {
21961       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21962         EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21963                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21964                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21965         AdvanceIT();
21966         return;
21967       }
21968     }
21969   } else {
21970     // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
21971     if (encoded_dt.IsValid()) {
21972       if (cond.Is(al)) {
21973         EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21974                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21975                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21976         return;
21977       }
21978     }
21979   }
21980   Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
21981 }
21982 
vqrshl(Condition cond,DataType dt,QRegister rd,QRegister rm,QRegister rn)21983 void Assembler::vqrshl(
21984     Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
21985   VIXL_ASSERT(AllowAssembler());
21986   CheckIT(cond);
21987   Dt_U_size_3 encoded_dt(dt);
21988   if (IsUsingT32()) {
21989     // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
21990     if (encoded_dt.IsValid()) {
21991       if (cond.Is(al) || AllowStronglyDiscouraged()) {
21992         EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21993                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21994                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
21995         AdvanceIT();
21996         return;
21997       }
21998     }
21999   } else {
22000     // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
22001     if (encoded_dt.IsValid()) {
22002       if (cond.Is(al)) {
22003         EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22004                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22005                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22006         return;
22007       }
22008     }
22009   }
22010   Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
22011 }
22012 
vqrshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)22013 void Assembler::vqrshrn(Condition cond,
22014                         DataType dt,
22015                         DRegister rd,
22016                         QRegister rm,
22017                         const QOperand& operand) {
22018   VIXL_ASSERT(AllowAssembler());
22019   CheckIT(cond);
22020   if (operand.IsImmediate()) {
22021     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22022       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22023       Dt_op_size_3 encoded_dt(dt);
22024       Dt_imm6_1 encoded_dt_2(dt);
22025       if (IsUsingT32()) {
22026         // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
22027         if (encoded_dt.IsValid() && (imm == 0)) {
22028           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22029             EmitT32_32(0xffb20280U |
22030                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22031                        ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22032                        rd.Encode(22, 12) | rm.Encode(5, 0));
22033             AdvanceIT();
22034             return;
22035           }
22036         }
22037         // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
22038         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22039           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22040             uint32_t imm6 = dt.GetSize() / 2 - imm;
22041             EmitT32_32(0xef800950U |
22042                        (encoded_dt_2.GetTypeEncodingValue() << 28) |
22043                        ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
22044                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22045             AdvanceIT();
22046             return;
22047           }
22048         }
22049       } else {
22050         // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
22051         if (encoded_dt.IsValid() && (imm == 0)) {
22052           if (cond.Is(al)) {
22053             EmitA32(0xf3b20280U |
22054                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22055                     ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22056                     rd.Encode(22, 12) | rm.Encode(5, 0));
22057             return;
22058           }
22059         }
22060         // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
22061         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22062           if (cond.Is(al)) {
22063             uint32_t imm6 = dt.GetSize() / 2 - imm;
22064             EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
22065                     ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
22066                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22067             return;
22068           }
22069         }
22070       }
22071     }
22072   }
22073   Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand);
22074 }
22075 
vqrshrun(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)22076 void Assembler::vqrshrun(Condition cond,
22077                          DataType dt,
22078                          DRegister rd,
22079                          QRegister rm,
22080                          const QOperand& operand) {
22081   VIXL_ASSERT(AllowAssembler());
22082   CheckIT(cond);
22083   if (operand.IsImmediate()) {
22084     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22085       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22086       Dt_imm6_2 encoded_dt(dt);
22087       Dt_size_14 encoded_dt_2(dt);
22088       if (IsUsingT32()) {
22089         // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
22090         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22091           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22092             uint32_t imm6 = dt.GetSize() / 2 - imm;
22093             EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) |
22094                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22095                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22096             AdvanceIT();
22097             return;
22098           }
22099         }
22100         // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
22101         if (encoded_dt_2.IsValid() && (imm == 0)) {
22102           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22103             EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22104                        rd.Encode(22, 12) | rm.Encode(5, 0));
22105             AdvanceIT();
22106             return;
22107           }
22108         }
22109       } else {
22110         // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
22111         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22112           if (cond.Is(al)) {
22113             uint32_t imm6 = dt.GetSize() / 2 - imm;
22114             EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) |
22115                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22116                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22117             return;
22118           }
22119         }
22120         // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
22121         if (encoded_dt_2.IsValid() && (imm == 0)) {
22122           if (cond.Is(al)) {
22123             EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22124                     rd.Encode(22, 12) | rm.Encode(5, 0));
22125             return;
22126           }
22127         }
22128       }
22129     }
22130   }
22131   Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand);
22132 }
22133 
vqshl(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)22134 void Assembler::vqshl(Condition cond,
22135                       DataType dt,
22136                       DRegister rd,
22137                       DRegister rm,
22138                       const DOperand& operand) {
22139   VIXL_ASSERT(AllowAssembler());
22140   CheckIT(cond);
22141   if (operand.IsRegister()) {
22142     DRegister rn = operand.GetRegister();
22143     Dt_U_size_3 encoded_dt(dt);
22144     if (IsUsingT32()) {
22145       // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
22146       if (encoded_dt.IsValid()) {
22147         if (cond.Is(al) || AllowStronglyDiscouraged()) {
22148           EmitT32_32(0xef000410U |
22149                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22150                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22151                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22152           AdvanceIT();
22153           return;
22154         }
22155       }
22156     } else {
22157       // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
22158       if (encoded_dt.IsValid()) {
22159         if (cond.Is(al)) {
22160           EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22161                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22162                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22163           return;
22164         }
22165       }
22166     }
22167   }
22168   if (operand.IsImmediate()) {
22169     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22170       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22171       Dt_L_imm6_1 encoded_dt(dt);
22172       if (IsUsingT32()) {
22173         // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
22174         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22175           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22176             uint32_t imm6 = imm;
22177             EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) |
22178                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22179                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22180                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22181             AdvanceIT();
22182             return;
22183           }
22184         }
22185       } else {
22186         // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
22187         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22188           if (cond.Is(al)) {
22189             uint32_t imm6 = imm;
22190             EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) |
22191                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22192                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22193                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22194             return;
22195           }
22196         }
22197       }
22198     }
22199   }
22200   Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
22201 }
22202 
vqshl(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)22203 void Assembler::vqshl(Condition cond,
22204                       DataType dt,
22205                       QRegister rd,
22206                       QRegister rm,
22207                       const QOperand& operand) {
22208   VIXL_ASSERT(AllowAssembler());
22209   CheckIT(cond);
22210   if (operand.IsRegister()) {
22211     QRegister rn = operand.GetRegister();
22212     Dt_U_size_3 encoded_dt(dt);
22213     if (IsUsingT32()) {
22214       // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
22215       if (encoded_dt.IsValid()) {
22216         if (cond.Is(al) || AllowStronglyDiscouraged()) {
22217           EmitT32_32(0xef000450U |
22218                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22219                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22220                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22221           AdvanceIT();
22222           return;
22223         }
22224       }
22225     } else {
22226       // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
22227       if (encoded_dt.IsValid()) {
22228         if (cond.Is(al)) {
22229           EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22230                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22231                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
22232           return;
22233         }
22234       }
22235     }
22236   }
22237   if (operand.IsImmediate()) {
22238     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22239       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22240       Dt_L_imm6_1 encoded_dt(dt);
22241       if (IsUsingT32()) {
22242         // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
22243         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22244           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22245             uint32_t imm6 = imm;
22246             EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) |
22247                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22248                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22249                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22250             AdvanceIT();
22251             return;
22252           }
22253         }
22254       } else {
22255         // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
22256         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22257           if (cond.Is(al)) {
22258             uint32_t imm6 = imm;
22259             EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) |
22260                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22261                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22262                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22263             return;
22264           }
22265         }
22266       }
22267     }
22268   }
22269   Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
22270 }
22271 
vqshlu(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)22272 void Assembler::vqshlu(Condition cond,
22273                        DataType dt,
22274                        DRegister rd,
22275                        DRegister rm,
22276                        const DOperand& operand) {
22277   VIXL_ASSERT(AllowAssembler());
22278   CheckIT(cond);
22279   if (operand.IsImmediate()) {
22280     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22281       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22282       Dt_L_imm6_2 encoded_dt(dt);
22283       if (IsUsingT32()) {
22284         // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
22285         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22286           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22287             uint32_t imm6 = imm;
22288             EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) |
22289                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22290                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22291                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22292             AdvanceIT();
22293             return;
22294           }
22295         }
22296       } else {
22297         // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
22298         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22299           if (cond.Is(al)) {
22300             uint32_t imm6 = imm;
22301             EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) |
22302                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22303                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22304                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22305             return;
22306           }
22307         }
22308       }
22309     }
22310   }
22311   Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
22312 }
22313 
vqshlu(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)22314 void Assembler::vqshlu(Condition cond,
22315                        DataType dt,
22316                        QRegister rd,
22317                        QRegister rm,
22318                        const QOperand& operand) {
22319   VIXL_ASSERT(AllowAssembler());
22320   CheckIT(cond);
22321   if (operand.IsImmediate()) {
22322     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22323       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22324       Dt_L_imm6_2 encoded_dt(dt);
22325       if (IsUsingT32()) {
22326         // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
22327         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22328           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22329             uint32_t imm6 = imm;
22330             EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) |
22331                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22332                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22333                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22334             AdvanceIT();
22335             return;
22336           }
22337         }
22338       } else {
22339         // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
22340         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
22341           if (cond.Is(al)) {
22342             uint32_t imm6 = imm;
22343             EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) |
22344                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22345                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
22346                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22347             return;
22348           }
22349         }
22350       }
22351     }
22352   }
22353   Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
22354 }
22355 
vqshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)22356 void Assembler::vqshrn(Condition cond,
22357                        DataType dt,
22358                        DRegister rd,
22359                        QRegister rm,
22360                        const QOperand& operand) {
22361   VIXL_ASSERT(AllowAssembler());
22362   CheckIT(cond);
22363   if (operand.IsImmediate()) {
22364     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22365       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22366       Dt_op_size_3 encoded_dt(dt);
22367       Dt_imm6_1 encoded_dt_2(dt);
22368       if (IsUsingT32()) {
22369         // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
22370         if (encoded_dt.IsValid() && (imm == 0)) {
22371           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22372             EmitT32_32(0xffb20280U |
22373                        ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22374                        ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22375                        rd.Encode(22, 12) | rm.Encode(5, 0));
22376             AdvanceIT();
22377             return;
22378           }
22379         }
22380         // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
22381         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22382           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22383             uint32_t imm6 = dt.GetSize() / 2 - imm;
22384             EmitT32_32(0xef800910U |
22385                        (encoded_dt_2.GetTypeEncodingValue() << 28) |
22386                        ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
22387                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22388             AdvanceIT();
22389             return;
22390           }
22391         }
22392       } else {
22393         // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
22394         if (encoded_dt.IsValid() && (imm == 0)) {
22395           if (cond.Is(al)) {
22396             EmitA32(0xf3b20280U |
22397                     ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22398                     ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
22399                     rd.Encode(22, 12) | rm.Encode(5, 0));
22400             return;
22401           }
22402         }
22403         // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
22404         if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22405           if (cond.Is(al)) {
22406             uint32_t imm6 = dt.GetSize() / 2 - imm;
22407             EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
22408                     ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
22409                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22410             return;
22411           }
22412         }
22413       }
22414     }
22415   }
22416   Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand);
22417 }
22418 
vqshrun(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)22419 void Assembler::vqshrun(Condition cond,
22420                         DataType dt,
22421                         DRegister rd,
22422                         QRegister rm,
22423                         const QOperand& operand) {
22424   VIXL_ASSERT(AllowAssembler());
22425   CheckIT(cond);
22426   if (operand.IsImmediate()) {
22427     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
22428       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
22429       Dt_imm6_2 encoded_dt(dt);
22430       Dt_size_14 encoded_dt_2(dt);
22431       if (IsUsingT32()) {
22432         // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
22433         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22434           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22435             uint32_t imm6 = dt.GetSize() / 2 - imm;
22436             EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) |
22437                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22438                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22439             AdvanceIT();
22440             return;
22441           }
22442         }
22443         // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
22444         if (encoded_dt_2.IsValid() && (imm == 0)) {
22445           if (cond.Is(al) || AllowStronglyDiscouraged()) {
22446             EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22447                        rd.Encode(22, 12) | rm.Encode(5, 0));
22448             AdvanceIT();
22449             return;
22450           }
22451         }
22452       } else {
22453         // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
22454         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
22455           if (cond.Is(al)) {
22456             uint32_t imm6 = dt.GetSize() / 2 - imm;
22457             EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) |
22458                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
22459                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
22460             return;
22461           }
22462         }
22463         // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
22464         if (encoded_dt_2.IsValid() && (imm == 0)) {
22465           if (cond.Is(al)) {
22466             EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
22467                     rd.Encode(22, 12) | rm.Encode(5, 0));
22468             return;
22469           }
22470         }
22471       }
22472     }
22473   }
22474   Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand);
22475 }
22476 
vqsub(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22477 void Assembler::vqsub(
22478     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22479   VIXL_ASSERT(AllowAssembler());
22480   CheckIT(cond);
22481   Dt_U_size_3 encoded_dt(dt);
22482   if (IsUsingT32()) {
22483     // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22484     if (encoded_dt.IsValid()) {
22485       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22486         EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22487                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22488                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22489         AdvanceIT();
22490         return;
22491       }
22492     }
22493   } else {
22494     // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22495     if (encoded_dt.IsValid()) {
22496       if (cond.Is(al)) {
22497         EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22498                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22499                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22500         return;
22501       }
22502     }
22503   }
22504   Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
22505 }
22506 
vqsub(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)22507 void Assembler::vqsub(
22508     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22509   VIXL_ASSERT(AllowAssembler());
22510   CheckIT(cond);
22511   Dt_U_size_3 encoded_dt(dt);
22512   if (IsUsingT32()) {
22513     // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22514     if (encoded_dt.IsValid()) {
22515       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22516         EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22517                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22518                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22519         AdvanceIT();
22520         return;
22521       }
22522     }
22523   } else {
22524     // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22525     if (encoded_dt.IsValid()) {
22526       if (cond.Is(al)) {
22527         EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22528                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22529                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22530         return;
22531       }
22532     }
22533   }
22534   Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
22535 }
22536 
vraddhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)22537 void Assembler::vraddhn(
22538     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
22539   VIXL_ASSERT(AllowAssembler());
22540   CheckIT(cond);
22541   Dt_size_3 encoded_dt(dt);
22542   if (IsUsingT32()) {
22543     // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
22544     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
22545       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22546         EmitT32_32(0xff800400U | (encoded_dt.GetEncodingValue() << 20) |
22547                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22548         AdvanceIT();
22549         return;
22550       }
22551     }
22552   } else {
22553     // VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
22554     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
22555       if (cond.Is(al)) {
22556         EmitA32(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) |
22557                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22558         return;
22559       }
22560     }
22561   }
22562   Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm);
22563 }
22564 
vrecpe(Condition cond,DataType dt,DRegister rd,DRegister rm)22565 void Assembler::vrecpe(Condition cond,
22566                        DataType dt,
22567                        DRegister rd,
22568                        DRegister rm) {
22569   VIXL_ASSERT(AllowAssembler());
22570   CheckIT(cond);
22571   Dt_F_size_4 encoded_dt(dt);
22572   if (IsUsingT32()) {
22573     // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22574     if (encoded_dt.IsValid()) {
22575       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22576         EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22577                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22578                    rd.Encode(22, 12) | rm.Encode(5, 0));
22579         AdvanceIT();
22580         return;
22581       }
22582     }
22583   } else {
22584     // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22585     if (encoded_dt.IsValid()) {
22586       if (cond.Is(al)) {
22587         EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22588                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22589                 rd.Encode(22, 12) | rm.Encode(5, 0));
22590         return;
22591       }
22592     }
22593   }
22594   Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
22595 }
22596 
vrecpe(Condition cond,DataType dt,QRegister rd,QRegister rm)22597 void Assembler::vrecpe(Condition cond,
22598                        DataType dt,
22599                        QRegister rd,
22600                        QRegister rm) {
22601   VIXL_ASSERT(AllowAssembler());
22602   CheckIT(cond);
22603   Dt_F_size_4 encoded_dt(dt);
22604   if (IsUsingT32()) {
22605     // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22606     if (encoded_dt.IsValid()) {
22607       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22608         EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22609                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22610                    rd.Encode(22, 12) | rm.Encode(5, 0));
22611         AdvanceIT();
22612         return;
22613       }
22614     }
22615   } else {
22616     // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22617     if (encoded_dt.IsValid()) {
22618       if (cond.Is(al)) {
22619         EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22620                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
22621                 rd.Encode(22, 12) | rm.Encode(5, 0));
22622         return;
22623       }
22624     }
22625   }
22626   Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
22627 }
22628 
vrecps(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22629 void Assembler::vrecps(
22630     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22631   VIXL_ASSERT(AllowAssembler());
22632   CheckIT(cond);
22633   if (IsUsingT32()) {
22634     // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
22635     if (dt.Is(F32)) {
22636       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22637         EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22638                    rm.Encode(5, 0));
22639         AdvanceIT();
22640         return;
22641       }
22642     }
22643   } else {
22644     // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
22645     if (dt.Is(F32)) {
22646       if (cond.Is(al)) {
22647         EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22648                 rm.Encode(5, 0));
22649         return;
22650       }
22651     }
22652   }
22653   Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
22654 }
22655 
vrecps(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)22656 void Assembler::vrecps(
22657     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22658   VIXL_ASSERT(AllowAssembler());
22659   CheckIT(cond);
22660   if (IsUsingT32()) {
22661     // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
22662     if (dt.Is(F32)) {
22663       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22664         EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22665                    rm.Encode(5, 0));
22666         AdvanceIT();
22667         return;
22668       }
22669     }
22670   } else {
22671     // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
22672     if (dt.Is(F32)) {
22673       if (cond.Is(al)) {
22674         EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22675                 rm.Encode(5, 0));
22676         return;
22677       }
22678     }
22679   }
22680   Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
22681 }
22682 
vrev16(Condition cond,DataType dt,DRegister rd,DRegister rm)22683 void Assembler::vrev16(Condition cond,
22684                        DataType dt,
22685                        DRegister rd,
22686                        DRegister rm) {
22687   VIXL_ASSERT(AllowAssembler());
22688   CheckIT(cond);
22689   Dt_size_1 encoded_dt(dt);
22690   if (IsUsingT32()) {
22691     // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22692     if (encoded_dt.IsValid()) {
22693       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22694         EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) |
22695                    rd.Encode(22, 12) | rm.Encode(5, 0));
22696         AdvanceIT();
22697         return;
22698       }
22699     }
22700   } else {
22701     // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22702     if (encoded_dt.IsValid()) {
22703       if (cond.Is(al)) {
22704         EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) |
22705                 rd.Encode(22, 12) | rm.Encode(5, 0));
22706         return;
22707       }
22708     }
22709   }
22710   Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
22711 }
22712 
vrev16(Condition cond,DataType dt,QRegister rd,QRegister rm)22713 void Assembler::vrev16(Condition cond,
22714                        DataType dt,
22715                        QRegister rd,
22716                        QRegister rm) {
22717   VIXL_ASSERT(AllowAssembler());
22718   CheckIT(cond);
22719   Dt_size_1 encoded_dt(dt);
22720   if (IsUsingT32()) {
22721     // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22722     if (encoded_dt.IsValid()) {
22723       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22724         EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) |
22725                    rd.Encode(22, 12) | rm.Encode(5, 0));
22726         AdvanceIT();
22727         return;
22728       }
22729     }
22730   } else {
22731     // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22732     if (encoded_dt.IsValid()) {
22733       if (cond.Is(al)) {
22734         EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) |
22735                 rd.Encode(22, 12) | rm.Encode(5, 0));
22736         return;
22737       }
22738     }
22739   }
22740   Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
22741 }
22742 
vrev32(Condition cond,DataType dt,DRegister rd,DRegister rm)22743 void Assembler::vrev32(Condition cond,
22744                        DataType dt,
22745                        DRegister rd,
22746                        DRegister rm) {
22747   VIXL_ASSERT(AllowAssembler());
22748   CheckIT(cond);
22749   Dt_size_15 encoded_dt(dt);
22750   if (IsUsingT32()) {
22751     // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22752     if (encoded_dt.IsValid()) {
22753       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22754         EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) |
22755                    rd.Encode(22, 12) | rm.Encode(5, 0));
22756         AdvanceIT();
22757         return;
22758       }
22759     }
22760   } else {
22761     // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22762     if (encoded_dt.IsValid()) {
22763       if (cond.Is(al)) {
22764         EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) |
22765                 rd.Encode(22, 12) | rm.Encode(5, 0));
22766         return;
22767       }
22768     }
22769   }
22770   Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
22771 }
22772 
vrev32(Condition cond,DataType dt,QRegister rd,QRegister rm)22773 void Assembler::vrev32(Condition cond,
22774                        DataType dt,
22775                        QRegister rd,
22776                        QRegister rm) {
22777   VIXL_ASSERT(AllowAssembler());
22778   CheckIT(cond);
22779   Dt_size_15 encoded_dt(dt);
22780   if (IsUsingT32()) {
22781     // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22782     if (encoded_dt.IsValid()) {
22783       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22784         EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) |
22785                    rd.Encode(22, 12) | rm.Encode(5, 0));
22786         AdvanceIT();
22787         return;
22788       }
22789     }
22790   } else {
22791     // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22792     if (encoded_dt.IsValid()) {
22793       if (cond.Is(al)) {
22794         EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) |
22795                 rd.Encode(22, 12) | rm.Encode(5, 0));
22796         return;
22797       }
22798     }
22799   }
22800   Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
22801 }
22802 
vrev64(Condition cond,DataType dt,DRegister rd,DRegister rm)22803 void Assembler::vrev64(Condition cond,
22804                        DataType dt,
22805                        DRegister rd,
22806                        DRegister rm) {
22807   VIXL_ASSERT(AllowAssembler());
22808   CheckIT(cond);
22809   Dt_size_7 encoded_dt(dt);
22810   if (IsUsingT32()) {
22811     // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22812     if (encoded_dt.IsValid()) {
22813       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22814         EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) |
22815                    rd.Encode(22, 12) | rm.Encode(5, 0));
22816         AdvanceIT();
22817         return;
22818       }
22819     }
22820   } else {
22821     // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22822     if (encoded_dt.IsValid()) {
22823       if (cond.Is(al)) {
22824         EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) |
22825                 rd.Encode(22, 12) | rm.Encode(5, 0));
22826         return;
22827       }
22828     }
22829   }
22830   Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
22831 }
22832 
vrev64(Condition cond,DataType dt,QRegister rd,QRegister rm)22833 void Assembler::vrev64(Condition cond,
22834                        DataType dt,
22835                        QRegister rd,
22836                        QRegister rm) {
22837   VIXL_ASSERT(AllowAssembler());
22838   CheckIT(cond);
22839   Dt_size_7 encoded_dt(dt);
22840   if (IsUsingT32()) {
22841     // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22842     if (encoded_dt.IsValid()) {
22843       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22844         EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) |
22845                    rd.Encode(22, 12) | rm.Encode(5, 0));
22846         AdvanceIT();
22847         return;
22848       }
22849     }
22850   } else {
22851     // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22852     if (encoded_dt.IsValid()) {
22853       if (cond.Is(al)) {
22854         EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) |
22855                 rd.Encode(22, 12) | rm.Encode(5, 0));
22856         return;
22857       }
22858     }
22859   }
22860   Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
22861 }
22862 
vrhadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22863 void Assembler::vrhadd(
22864     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22865   VIXL_ASSERT(AllowAssembler());
22866   CheckIT(cond);
22867   Dt_U_size_1 encoded_dt(dt);
22868   if (IsUsingT32()) {
22869     // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22870     if (encoded_dt.IsValid()) {
22871       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22872         EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22873                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22874                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22875         AdvanceIT();
22876         return;
22877       }
22878     }
22879   } else {
22880     // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22881     if (encoded_dt.IsValid()) {
22882       if (cond.Is(al)) {
22883         EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22884                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22885                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22886         return;
22887       }
22888     }
22889   }
22890   Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
22891 }
22892 
vrhadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)22893 void Assembler::vrhadd(
22894     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22895   VIXL_ASSERT(AllowAssembler());
22896   CheckIT(cond);
22897   Dt_U_size_1 encoded_dt(dt);
22898   if (IsUsingT32()) {
22899     // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22900     if (encoded_dt.IsValid()) {
22901       if (cond.Is(al) || AllowStronglyDiscouraged()) {
22902         EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22903                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22904                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22905         AdvanceIT();
22906         return;
22907       }
22908     }
22909   } else {
22910     // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22911     if (encoded_dt.IsValid()) {
22912       if (cond.Is(al)) {
22913         EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22914                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22915                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22916         return;
22917       }
22918     }
22919   }
22920   Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
22921 }
22922 
vrinta(DataType dt1,DataType dt2,DRegister rd,DRegister rm)22923 void Assembler::vrinta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22924   VIXL_ASSERT(AllowAssembler());
22925   CheckIT(al);
22926   if (IsUsingT32()) {
22927     // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; T1
22928     if (dt1.Is(F32) && dt2.Is(F32)) {
22929       EmitT32_32(0xffba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
22930       AdvanceIT();
22931       return;
22932     }
22933     // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; T1
22934     if (dt1.Is(F64) && dt2.Is(F64)) {
22935       EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22936       AdvanceIT();
22937       return;
22938     }
22939   } else {
22940     // VRINTA{<q>}.F32.F32 <Dd>, <Dm> ; A1
22941     if (dt1.Is(F32) && dt2.Is(F32)) {
22942       EmitA32(0xf3ba0500U | rd.Encode(22, 12) | rm.Encode(5, 0));
22943       return;
22944     }
22945     // VRINTA{<q>}.F64.F64 <Dd>, <Dm> ; A1
22946     if (dt1.Is(F64) && dt2.Is(F64)) {
22947       EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22948       return;
22949     }
22950   }
22951   Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22952 }
22953 
vrinta(DataType dt1,DataType dt2,QRegister rd,QRegister rm)22954 void Assembler::vrinta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
22955   VIXL_ASSERT(AllowAssembler());
22956   CheckIT(al);
22957   if (IsUsingT32()) {
22958     // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; T1
22959     if (dt1.Is(F32) && dt2.Is(F32)) {
22960       EmitT32_32(0xffba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
22961       AdvanceIT();
22962       return;
22963     }
22964   } else {
22965     // VRINTA{<q>}.F32.F32 <Qd>, <Qm> ; A1
22966     if (dt1.Is(F32) && dt2.Is(F32)) {
22967       EmitA32(0xf3ba0540U | rd.Encode(22, 12) | rm.Encode(5, 0));
22968       return;
22969     }
22970   }
22971   Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22972 }
22973 
vrinta(DataType dt1,DataType dt2,SRegister rd,SRegister rm)22974 void Assembler::vrinta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
22975   VIXL_ASSERT(AllowAssembler());
22976   CheckIT(al);
22977   if (IsUsingT32()) {
22978     // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; T1
22979     if (dt1.Is(F32) && dt2.Is(F32)) {
22980       EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22981       AdvanceIT();
22982       return;
22983     }
22984   } else {
22985     // VRINTA{<q>}.F32.F32 <Sd>, <Sm> ; A1
22986     if (dt1.Is(F32) && dt2.Is(F32)) {
22987       EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
22988       return;
22989     }
22990   }
22991   Delegate(kVrinta, &Assembler::vrinta, dt1, dt2, rd, rm);
22992 }
22993 
vrintm(DataType dt1,DataType dt2,DRegister rd,DRegister rm)22994 void Assembler::vrintm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
22995   VIXL_ASSERT(AllowAssembler());
22996   CheckIT(al);
22997   if (IsUsingT32()) {
22998     // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; T1
22999     if (dt1.Is(F32) && dt2.Is(F32)) {
23000       EmitT32_32(0xffba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
23001       AdvanceIT();
23002       return;
23003     }
23004     // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; T1
23005     if (dt1.Is(F64) && dt2.Is(F64)) {
23006       EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23007       AdvanceIT();
23008       return;
23009     }
23010   } else {
23011     // VRINTM{<q>}.F32.F32 <Dd>, <Dm> ; A1
23012     if (dt1.Is(F32) && dt2.Is(F32)) {
23013       EmitA32(0xf3ba0680U | rd.Encode(22, 12) | rm.Encode(5, 0));
23014       return;
23015     }
23016     // VRINTM{<q>}.F64.F64 <Dd>, <Dm> ; A1
23017     if (dt1.Is(F64) && dt2.Is(F64)) {
23018       EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23019       return;
23020     }
23021   }
23022   Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
23023 }
23024 
vrintm(DataType dt1,DataType dt2,QRegister rd,QRegister rm)23025 void Assembler::vrintm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23026   VIXL_ASSERT(AllowAssembler());
23027   CheckIT(al);
23028   if (IsUsingT32()) {
23029     // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; T1
23030     if (dt1.Is(F32) && dt2.Is(F32)) {
23031       EmitT32_32(0xffba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23032       AdvanceIT();
23033       return;
23034     }
23035   } else {
23036     // VRINTM{<q>}.F32.F32 <Qd>, <Qm> ; A1
23037     if (dt1.Is(F32) && dt2.Is(F32)) {
23038       EmitA32(0xf3ba06c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23039       return;
23040     }
23041   }
23042   Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
23043 }
23044 
vrintm(DataType dt1,DataType dt2,SRegister rd,SRegister rm)23045 void Assembler::vrintm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23046   VIXL_ASSERT(AllowAssembler());
23047   CheckIT(al);
23048   if (IsUsingT32()) {
23049     // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; T1
23050     if (dt1.Is(F32) && dt2.Is(F32)) {
23051       EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23052       AdvanceIT();
23053       return;
23054     }
23055   } else {
23056     // VRINTM{<q>}.F32.F32 <Sd>, <Sm> ; A1
23057     if (dt1.Is(F32) && dt2.Is(F32)) {
23058       EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23059       return;
23060     }
23061   }
23062   Delegate(kVrintm, &Assembler::vrintm, dt1, dt2, rd, rm);
23063 }
23064 
vrintn(DataType dt1,DataType dt2,DRegister rd,DRegister rm)23065 void Assembler::vrintn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23066   VIXL_ASSERT(AllowAssembler());
23067   CheckIT(al);
23068   if (IsUsingT32()) {
23069     // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; T1
23070     if (dt1.Is(F32) && dt2.Is(F32)) {
23071       EmitT32_32(0xffba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
23072       AdvanceIT();
23073       return;
23074     }
23075     // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; T1
23076     if (dt1.Is(F64) && dt2.Is(F64)) {
23077       EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23078       AdvanceIT();
23079       return;
23080     }
23081   } else {
23082     // VRINTN{<q>}.F32.F32 <Dd>, <Dm> ; A1
23083     if (dt1.Is(F32) && dt2.Is(F32)) {
23084       EmitA32(0xf3ba0400U | rd.Encode(22, 12) | rm.Encode(5, 0));
23085       return;
23086     }
23087     // VRINTN{<q>}.F64.F64 <Dd>, <Dm> ; A1
23088     if (dt1.Is(F64) && dt2.Is(F64)) {
23089       EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23090       return;
23091     }
23092   }
23093   Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
23094 }
23095 
vrintn(DataType dt1,DataType dt2,QRegister rd,QRegister rm)23096 void Assembler::vrintn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23097   VIXL_ASSERT(AllowAssembler());
23098   CheckIT(al);
23099   if (IsUsingT32()) {
23100     // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; T1
23101     if (dt1.Is(F32) && dt2.Is(F32)) {
23102       EmitT32_32(0xffba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
23103       AdvanceIT();
23104       return;
23105     }
23106   } else {
23107     // VRINTN{<q>}.F32.F32 <Qd>, <Qm> ; A1
23108     if (dt1.Is(F32) && dt2.Is(F32)) {
23109       EmitA32(0xf3ba0440U | rd.Encode(22, 12) | rm.Encode(5, 0));
23110       return;
23111     }
23112   }
23113   Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
23114 }
23115 
vrintn(DataType dt1,DataType dt2,SRegister rd,SRegister rm)23116 void Assembler::vrintn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23117   VIXL_ASSERT(AllowAssembler());
23118   CheckIT(al);
23119   if (IsUsingT32()) {
23120     // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; T1
23121     if (dt1.Is(F32) && dt2.Is(F32)) {
23122       EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23123       AdvanceIT();
23124       return;
23125     }
23126   } else {
23127     // VRINTN{<q>}.F32.F32 <Sd>, <Sm> ; A1
23128     if (dt1.Is(F32) && dt2.Is(F32)) {
23129       EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23130       return;
23131     }
23132   }
23133   Delegate(kVrintn, &Assembler::vrintn, dt1, dt2, rd, rm);
23134 }
23135 
vrintp(DataType dt1,DataType dt2,DRegister rd,DRegister rm)23136 void Assembler::vrintp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23137   VIXL_ASSERT(AllowAssembler());
23138   CheckIT(al);
23139   if (IsUsingT32()) {
23140     // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; T1
23141     if (dt1.Is(F32) && dt2.Is(F32)) {
23142       EmitT32_32(0xffba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
23143       AdvanceIT();
23144       return;
23145     }
23146     // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; T1
23147     if (dt1.Is(F64) && dt2.Is(F64)) {
23148       EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23149       AdvanceIT();
23150       return;
23151     }
23152   } else {
23153     // VRINTP{<q>}.F32.F32 <Dd>, <Dm> ; A1
23154     if (dt1.Is(F32) && dt2.Is(F32)) {
23155       EmitA32(0xf3ba0780U | rd.Encode(22, 12) | rm.Encode(5, 0));
23156       return;
23157     }
23158     // VRINTP{<q>}.F64.F64 <Dd>, <Dm> ; A1
23159     if (dt1.Is(F64) && dt2.Is(F64)) {
23160       EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23161       return;
23162     }
23163   }
23164   Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
23165 }
23166 
vrintp(DataType dt1,DataType dt2,QRegister rd,QRegister rm)23167 void Assembler::vrintp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23168   VIXL_ASSERT(AllowAssembler());
23169   CheckIT(al);
23170   if (IsUsingT32()) {
23171     // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; T1
23172     if (dt1.Is(F32) && dt2.Is(F32)) {
23173       EmitT32_32(0xffba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23174       AdvanceIT();
23175       return;
23176     }
23177   } else {
23178     // VRINTP{<q>}.F32.F32 <Qd>, <Qm> ; A1
23179     if (dt1.Is(F32) && dt2.Is(F32)) {
23180       EmitA32(0xf3ba07c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23181       return;
23182     }
23183   }
23184   Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
23185 }
23186 
vrintp(DataType dt1,DataType dt2,SRegister rd,SRegister rm)23187 void Assembler::vrintp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23188   VIXL_ASSERT(AllowAssembler());
23189   CheckIT(al);
23190   if (IsUsingT32()) {
23191     // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; T1
23192     if (dt1.Is(F32) && dt2.Is(F32)) {
23193       EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23194       AdvanceIT();
23195       return;
23196     }
23197   } else {
23198     // VRINTP{<q>}.F32.F32 <Sd>, <Sm> ; A1
23199     if (dt1.Is(F32) && dt2.Is(F32)) {
23200       EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23201       return;
23202     }
23203   }
23204   Delegate(kVrintp, &Assembler::vrintp, dt1, dt2, rd, rm);
23205 }
23206 
vrintr(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)23207 void Assembler::vrintr(
23208     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23209   VIXL_ASSERT(AllowAssembler());
23210   CheckIT(cond);
23211   if (IsUsingT32()) {
23212     // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
23213     if (dt1.Is(F32) && dt2.Is(F32)) {
23214       EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23215       AdvanceIT();
23216       return;
23217     }
23218   } else {
23219     // VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
23220     if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
23221       EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23222               rm.Encode(5, 0));
23223       return;
23224     }
23225   }
23226   Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
23227 }
23228 
vrintr(Condition cond,DataType dt1,DataType dt2,DRegister rd,DRegister rm)23229 void Assembler::vrintr(
23230     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23231   VIXL_ASSERT(AllowAssembler());
23232   CheckIT(cond);
23233   if (IsUsingT32()) {
23234     // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
23235     if (dt1.Is(F64) && dt2.Is(F64)) {
23236       EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23237       AdvanceIT();
23238       return;
23239     }
23240   } else {
23241     // VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
23242     if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
23243       EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23244               rm.Encode(5, 0));
23245       return;
23246     }
23247   }
23248   Delegate(kVrintr, &Assembler::vrintr, cond, dt1, dt2, rd, rm);
23249 }
23250 
vrintx(Condition cond,DataType dt1,DataType dt2,DRegister rd,DRegister rm)23251 void Assembler::vrintx(
23252     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23253   VIXL_ASSERT(AllowAssembler());
23254   CheckIT(cond);
23255   if (IsUsingT32()) {
23256     // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; T1
23257     if (dt1.Is(F32) && dt2.Is(F32)) {
23258       EmitT32_32(0xffba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
23259       AdvanceIT();
23260       return;
23261     }
23262     // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
23263     if (dt1.Is(F64) && dt2.Is(F64)) {
23264       EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23265       AdvanceIT();
23266       return;
23267     }
23268   } else {
23269     // VRINTX{<q>}.F32.F32 <Dd>, <Dm> ; A1
23270     if (dt1.Is(F32) && dt2.Is(F32)) {
23271       EmitA32(0xf3ba0480U | rd.Encode(22, 12) | rm.Encode(5, 0));
23272       return;
23273     }
23274     // VRINTX{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
23275     if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
23276       EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23277               rm.Encode(5, 0));
23278       return;
23279     }
23280   }
23281   Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
23282 }
23283 
vrintx(DataType dt1,DataType dt2,QRegister rd,QRegister rm)23284 void Assembler::vrintx(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23285   VIXL_ASSERT(AllowAssembler());
23286   CheckIT(al);
23287   if (IsUsingT32()) {
23288     // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; T1
23289     if (dt1.Is(F32) && dt2.Is(F32)) {
23290       EmitT32_32(0xffba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23291       AdvanceIT();
23292       return;
23293     }
23294   } else {
23295     // VRINTX{<q>}.F32.F32 <Qd>, <Qm> ; A1
23296     if (dt1.Is(F32) && dt2.Is(F32)) {
23297       EmitA32(0xf3ba04c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23298       return;
23299     }
23300   }
23301   Delegate(kVrintx, &Assembler::vrintx, dt1, dt2, rd, rm);
23302 }
23303 
vrintx(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)23304 void Assembler::vrintx(
23305     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23306   VIXL_ASSERT(AllowAssembler());
23307   CheckIT(cond);
23308   if (IsUsingT32()) {
23309     // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
23310     if (dt1.Is(F32) && dt2.Is(F32)) {
23311       EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
23312       AdvanceIT();
23313       return;
23314     }
23315   } else {
23316     // VRINTX{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
23317     if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
23318       EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23319               rm.Encode(5, 0));
23320       return;
23321     }
23322   }
23323   Delegate(kVrintx, &Assembler::vrintx, cond, dt1, dt2, rd, rm);
23324 }
23325 
vrintz(Condition cond,DataType dt1,DataType dt2,DRegister rd,DRegister rm)23326 void Assembler::vrintz(
23327     Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
23328   VIXL_ASSERT(AllowAssembler());
23329   CheckIT(cond);
23330   if (IsUsingT32()) {
23331     // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; T1
23332     if (dt1.Is(F32) && dt2.Is(F32)) {
23333       EmitT32_32(0xffba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
23334       AdvanceIT();
23335       return;
23336     }
23337     // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; T1
23338     if (dt1.Is(F64) && dt2.Is(F64)) {
23339       EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23340       AdvanceIT();
23341       return;
23342     }
23343   } else {
23344     // VRINTZ{<q>}.F32.F32 <Dd>, <Dm> ; A1
23345     if (dt1.Is(F32) && dt2.Is(F32)) {
23346       EmitA32(0xf3ba0580U | rd.Encode(22, 12) | rm.Encode(5, 0));
23347       return;
23348     }
23349     // VRINTZ{<c>}{<q>}.F64.F64 <Dd>, <Dm> ; A1
23350     if (dt1.Is(F64) && dt2.Is(F64) && cond.IsNotNever()) {
23351       EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23352               rm.Encode(5, 0));
23353       return;
23354     }
23355   }
23356   Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
23357 }
23358 
vrintz(DataType dt1,DataType dt2,QRegister rd,QRegister rm)23359 void Assembler::vrintz(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
23360   VIXL_ASSERT(AllowAssembler());
23361   CheckIT(al);
23362   if (IsUsingT32()) {
23363     // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; T1
23364     if (dt1.Is(F32) && dt2.Is(F32)) {
23365       EmitT32_32(0xffba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23366       AdvanceIT();
23367       return;
23368     }
23369   } else {
23370     // VRINTZ{<q>}.F32.F32 <Qd>, <Qm> ; A1
23371     if (dt1.Is(F32) && dt2.Is(F32)) {
23372       EmitA32(0xf3ba05c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23373       return;
23374     }
23375   }
23376   Delegate(kVrintz, &Assembler::vrintz, dt1, dt2, rd, rm);
23377 }
23378 
vrintz(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)23379 void Assembler::vrintz(
23380     Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
23381   VIXL_ASSERT(AllowAssembler());
23382   CheckIT(cond);
23383   if (IsUsingT32()) {
23384     // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; T1
23385     if (dt1.Is(F32) && dt2.Is(F32)) {
23386       EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
23387       AdvanceIT();
23388       return;
23389     }
23390   } else {
23391     // VRINTZ{<c>}{<q>}.F32.F32 <Sd>, <Sm> ; A1
23392     if (dt1.Is(F32) && dt2.Is(F32) && cond.IsNotNever()) {
23393       EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
23394               rm.Encode(5, 0));
23395       return;
23396     }
23397   }
23398   Delegate(kVrintz, &Assembler::vrintz, cond, dt1, dt2, rd, rm);
23399 }
23400 
vrshl(Condition cond,DataType dt,DRegister rd,DRegister rm,DRegister rn)23401 void Assembler::vrshl(
23402     Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
23403   VIXL_ASSERT(AllowAssembler());
23404   CheckIT(cond);
23405   Dt_U_size_3 encoded_dt(dt);
23406   if (IsUsingT32()) {
23407     // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
23408     if (encoded_dt.IsValid()) {
23409       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23410         EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23411                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23412                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23413         AdvanceIT();
23414         return;
23415       }
23416     }
23417   } else {
23418     // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
23419     if (encoded_dt.IsValid()) {
23420       if (cond.Is(al)) {
23421         EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23422                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23423                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23424         return;
23425       }
23426     }
23427   }
23428   Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
23429 }
23430 
vrshl(Condition cond,DataType dt,QRegister rd,QRegister rm,QRegister rn)23431 void Assembler::vrshl(
23432     Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
23433   VIXL_ASSERT(AllowAssembler());
23434   CheckIT(cond);
23435   Dt_U_size_3 encoded_dt(dt);
23436   if (IsUsingT32()) {
23437     // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
23438     if (encoded_dt.IsValid()) {
23439       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23440         EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23441                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23442                    rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23443         AdvanceIT();
23444         return;
23445       }
23446     }
23447   } else {
23448     // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
23449     if (encoded_dt.IsValid()) {
23450       if (cond.Is(al)) {
23451         EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23452                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23453                 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23454         return;
23455       }
23456     }
23457   }
23458   Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
23459 }
23460 
vrshr(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)23461 void Assembler::vrshr(Condition cond,
23462                       DataType dt,
23463                       DRegister rd,
23464                       DRegister rm,
23465                       const DOperand& operand) {
23466   VIXL_ASSERT(AllowAssembler());
23467   CheckIT(cond);
23468   if (operand.IsImmediate()) {
23469     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23470       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23471       Dt_L_imm6_1 encoded_dt(dt);
23472       if (IsUsingT32()) {
23473         // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23474         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23475           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23476             uint32_t imm6 = dt.GetSize() - imm;
23477             EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) |
23478                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23479                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23480                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23481             AdvanceIT();
23482             return;
23483           }
23484         }
23485         // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
23486         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23487           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23488             EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23489                        rm.Encode(5, 0));
23490             AdvanceIT();
23491             return;
23492           }
23493         }
23494       } else {
23495         // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23496         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23497           if (cond.Is(al)) {
23498             uint32_t imm6 = dt.GetSize() - imm;
23499             EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) |
23500                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23501                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23502                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23503             return;
23504           }
23505         }
23506         // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
23507         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23508           if (cond.Is(al)) {
23509             EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23510                     rm.Encode(5, 0));
23511             return;
23512           }
23513         }
23514       }
23515     }
23516   }
23517   Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
23518 }
23519 
vrshr(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)23520 void Assembler::vrshr(Condition cond,
23521                       DataType dt,
23522                       QRegister rd,
23523                       QRegister rm,
23524                       const QOperand& operand) {
23525   VIXL_ASSERT(AllowAssembler());
23526   CheckIT(cond);
23527   if (operand.IsImmediate()) {
23528     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23529       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23530       Dt_L_imm6_1 encoded_dt(dt);
23531       if (IsUsingT32()) {
23532         // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23533         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23534           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23535             uint32_t imm6 = dt.GetSize() - imm;
23536             EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) |
23537                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23538                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23539                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23540             AdvanceIT();
23541             return;
23542           }
23543         }
23544         // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
23545         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23546           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23547             EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23548                        rm.Encode(5, 0));
23549             AdvanceIT();
23550             return;
23551           }
23552         }
23553       } else {
23554         // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23555         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23556           if (cond.Is(al)) {
23557             uint32_t imm6 = dt.GetSize() - imm;
23558             EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) |
23559                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23560                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23561                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23562             return;
23563           }
23564         }
23565         // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
23566         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
23567           if (cond.Is(al)) {
23568             EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
23569                     rm.Encode(5, 0));
23570             return;
23571           }
23572         }
23573       }
23574     }
23575   }
23576   Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
23577 }
23578 
vrshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)23579 void Assembler::vrshrn(Condition cond,
23580                        DataType dt,
23581                        DRegister rd,
23582                        QRegister rm,
23583                        const QOperand& operand) {
23584   VIXL_ASSERT(AllowAssembler());
23585   CheckIT(cond);
23586   if (operand.IsImmediate()) {
23587     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23588       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23589       Dt_imm6_3 encoded_dt(dt);
23590       Dt_size_3 encoded_dt_2(dt);
23591       if (IsUsingT32()) {
23592         // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
23593         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23594           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23595             uint32_t imm6 = dt.GetSize() / 2 - imm;
23596             EmitT32_32(0xef800850U |
23597                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23598                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23599             AdvanceIT();
23600             return;
23601           }
23602         }
23603         // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23604         if (encoded_dt_2.IsValid() && (imm == 0)) {
23605           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23606             EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
23607                        rd.Encode(22, 12) | rm.Encode(5, 0));
23608             AdvanceIT();
23609             return;
23610           }
23611         }
23612       } else {
23613         // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
23614         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23615           if (cond.Is(al)) {
23616             uint32_t imm6 = dt.GetSize() / 2 - imm;
23617             EmitA32(0xf2800850U |
23618                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23619                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23620             return;
23621           }
23622         }
23623         // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23624         if (encoded_dt_2.IsValid() && (imm == 0)) {
23625           if (cond.Is(al)) {
23626             EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
23627                     rd.Encode(22, 12) | rm.Encode(5, 0));
23628             return;
23629           }
23630         }
23631       }
23632     }
23633   }
23634   Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand);
23635 }
23636 
vrsqrte(Condition cond,DataType dt,DRegister rd,DRegister rm)23637 void Assembler::vrsqrte(Condition cond,
23638                         DataType dt,
23639                         DRegister rd,
23640                         DRegister rm) {
23641   VIXL_ASSERT(AllowAssembler());
23642   CheckIT(cond);
23643   Dt_F_size_4 encoded_dt(dt);
23644   if (IsUsingT32()) {
23645     // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
23646     if (encoded_dt.IsValid()) {
23647       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23648         EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23649                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23650                    rd.Encode(22, 12) | rm.Encode(5, 0));
23651         AdvanceIT();
23652         return;
23653       }
23654     }
23655   } else {
23656     // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
23657     if (encoded_dt.IsValid()) {
23658       if (cond.Is(al)) {
23659         EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23660                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23661                 rd.Encode(22, 12) | rm.Encode(5, 0));
23662         return;
23663       }
23664     }
23665   }
23666   Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
23667 }
23668 
vrsqrte(Condition cond,DataType dt,QRegister rd,QRegister rm)23669 void Assembler::vrsqrte(Condition cond,
23670                         DataType dt,
23671                         QRegister rd,
23672                         QRegister rm) {
23673   VIXL_ASSERT(AllowAssembler());
23674   CheckIT(cond);
23675   Dt_F_size_4 encoded_dt(dt);
23676   if (IsUsingT32()) {
23677     // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
23678     if (encoded_dt.IsValid()) {
23679       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23680         EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23681                    ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23682                    rd.Encode(22, 12) | rm.Encode(5, 0));
23683         AdvanceIT();
23684         return;
23685       }
23686     }
23687   } else {
23688     // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
23689     if (encoded_dt.IsValid()) {
23690       if (cond.Is(al)) {
23691         EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23692                 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23693                 rd.Encode(22, 12) | rm.Encode(5, 0));
23694         return;
23695       }
23696     }
23697   }
23698   Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
23699 }
23700 
vrsqrts(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)23701 void Assembler::vrsqrts(
23702     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23703   VIXL_ASSERT(AllowAssembler());
23704   CheckIT(cond);
23705   if (IsUsingT32()) {
23706     // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
23707     if (dt.Is(F32)) {
23708       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23709         EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23710                    rm.Encode(5, 0));
23711         AdvanceIT();
23712         return;
23713       }
23714     }
23715   } else {
23716     // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
23717     if (dt.Is(F32)) {
23718       if (cond.Is(al)) {
23719         EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23720                 rm.Encode(5, 0));
23721         return;
23722       }
23723     }
23724   }
23725   Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
23726 }
23727 
vrsqrts(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)23728 void Assembler::vrsqrts(
23729     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
23730   VIXL_ASSERT(AllowAssembler());
23731   CheckIT(cond);
23732   if (IsUsingT32()) {
23733     // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
23734     if (dt.Is(F32)) {
23735       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23736         EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23737                    rm.Encode(5, 0));
23738         AdvanceIT();
23739         return;
23740       }
23741     }
23742   } else {
23743     // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
23744     if (dt.Is(F32)) {
23745       if (cond.Is(al)) {
23746         EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23747                 rm.Encode(5, 0));
23748         return;
23749       }
23750     }
23751   }
23752   Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
23753 }
23754 
vrsra(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)23755 void Assembler::vrsra(Condition cond,
23756                       DataType dt,
23757                       DRegister rd,
23758                       DRegister rm,
23759                       const DOperand& operand) {
23760   VIXL_ASSERT(AllowAssembler());
23761   CheckIT(cond);
23762   if (operand.IsImmediate()) {
23763     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23764       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23765       Dt_L_imm6_1 encoded_dt(dt);
23766       if (IsUsingT32()) {
23767         // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23768         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23769           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23770             uint32_t imm6 = dt.GetSize() - imm;
23771             EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) |
23772                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23773                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23774                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23775             AdvanceIT();
23776             return;
23777           }
23778         }
23779       } else {
23780         // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23781         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23782           if (cond.Is(al)) {
23783             uint32_t imm6 = dt.GetSize() - imm;
23784             EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) |
23785                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23786                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23787                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23788             return;
23789           }
23790         }
23791       }
23792     }
23793   }
23794   Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
23795 }
23796 
vrsra(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)23797 void Assembler::vrsra(Condition cond,
23798                       DataType dt,
23799                       QRegister rd,
23800                       QRegister rm,
23801                       const QOperand& operand) {
23802   VIXL_ASSERT(AllowAssembler());
23803   CheckIT(cond);
23804   if (operand.IsImmediate()) {
23805     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23806       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23807       Dt_L_imm6_1 encoded_dt(dt);
23808       if (IsUsingT32()) {
23809         // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23810         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23811           if (cond.Is(al) || AllowStronglyDiscouraged()) {
23812             uint32_t imm6 = dt.GetSize() - imm;
23813             EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) |
23814                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23815                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23816                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23817             AdvanceIT();
23818             return;
23819           }
23820         }
23821       } else {
23822         // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23823         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
23824           if (cond.Is(al)) {
23825             uint32_t imm6 = dt.GetSize() - imm;
23826             EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) |
23827                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23828                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23829                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23830             return;
23831           }
23832         }
23833       }
23834     }
23835   }
23836   Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
23837 }
23838 
vrsubhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)23839 void Assembler::vrsubhn(
23840     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
23841   VIXL_ASSERT(AllowAssembler());
23842   CheckIT(cond);
23843   Dt_size_3 encoded_dt(dt);
23844   if (IsUsingT32()) {
23845     // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
23846     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
23847       if (cond.Is(al) || AllowStronglyDiscouraged()) {
23848         EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) |
23849                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23850         AdvanceIT();
23851         return;
23852       }
23853     }
23854   } else {
23855     // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
23856     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
23857       if (cond.Is(al)) {
23858         EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) |
23859                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23860         return;
23861       }
23862     }
23863   }
23864   Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm);
23865 }
23866 
vseleq(DataType dt,DRegister rd,DRegister rn,DRegister rm)23867 void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23868   VIXL_ASSERT(AllowAssembler());
23869   CheckIT(al);
23870   if (IsUsingT32()) {
23871     // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1
23872     if (OutsideITBlock() && dt.Is(F64)) {
23873       EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23874                  rm.Encode(5, 0));
23875       AdvanceIT();
23876       return;
23877     }
23878   } else {
23879     // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1
23880     if (dt.Is(F64)) {
23881       EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23882               rm.Encode(5, 0));
23883       return;
23884     }
23885   }
23886   Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
23887 }
23888 
vseleq(DataType dt,SRegister rd,SRegister rn,SRegister rm)23889 void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23890   VIXL_ASSERT(AllowAssembler());
23891   CheckIT(al);
23892   if (IsUsingT32()) {
23893     // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1
23894     if (OutsideITBlock() && dt.Is(F32)) {
23895       EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23896                  rm.Encode(5, 0));
23897       AdvanceIT();
23898       return;
23899     }
23900   } else {
23901     // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1
23902     if (dt.Is(F32)) {
23903       EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23904               rm.Encode(5, 0));
23905       return;
23906     }
23907   }
23908   Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
23909 }
23910 
vselge(DataType dt,DRegister rd,DRegister rn,DRegister rm)23911 void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23912   VIXL_ASSERT(AllowAssembler());
23913   CheckIT(al);
23914   if (IsUsingT32()) {
23915     // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1
23916     if (OutsideITBlock() && dt.Is(F64)) {
23917       EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23918                  rm.Encode(5, 0));
23919       AdvanceIT();
23920       return;
23921     }
23922   } else {
23923     // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1
23924     if (dt.Is(F64)) {
23925       EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23926               rm.Encode(5, 0));
23927       return;
23928     }
23929   }
23930   Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
23931 }
23932 
vselge(DataType dt,SRegister rd,SRegister rn,SRegister rm)23933 void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23934   VIXL_ASSERT(AllowAssembler());
23935   CheckIT(al);
23936   if (IsUsingT32()) {
23937     // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1
23938     if (OutsideITBlock() && dt.Is(F32)) {
23939       EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23940                  rm.Encode(5, 0));
23941       AdvanceIT();
23942       return;
23943     }
23944   } else {
23945     // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1
23946     if (dt.Is(F32)) {
23947       EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23948               rm.Encode(5, 0));
23949       return;
23950     }
23951   }
23952   Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
23953 }
23954 
vselgt(DataType dt,DRegister rd,DRegister rn,DRegister rm)23955 void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23956   VIXL_ASSERT(AllowAssembler());
23957   CheckIT(al);
23958   if (IsUsingT32()) {
23959     // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1
23960     if (OutsideITBlock() && dt.Is(F64)) {
23961       EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23962                  rm.Encode(5, 0));
23963       AdvanceIT();
23964       return;
23965     }
23966   } else {
23967     // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1
23968     if (dt.Is(F64)) {
23969       EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23970               rm.Encode(5, 0));
23971       return;
23972     }
23973   }
23974   Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
23975 }
23976 
vselgt(DataType dt,SRegister rd,SRegister rn,SRegister rm)23977 void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
23978   VIXL_ASSERT(AllowAssembler());
23979   CheckIT(al);
23980   if (IsUsingT32()) {
23981     // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1
23982     if (OutsideITBlock() && dt.Is(F32)) {
23983       EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23984                  rm.Encode(5, 0));
23985       AdvanceIT();
23986       return;
23987     }
23988   } else {
23989     // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1
23990     if (dt.Is(F32)) {
23991       EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23992               rm.Encode(5, 0));
23993       return;
23994     }
23995   }
23996   Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
23997 }
23998 
vselvs(DataType dt,DRegister rd,DRegister rn,DRegister rm)23999 void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
24000   VIXL_ASSERT(AllowAssembler());
24001   CheckIT(al);
24002   if (IsUsingT32()) {
24003     // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1
24004     if (OutsideITBlock() && dt.Is(F64)) {
24005       EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
24006                  rm.Encode(5, 0));
24007       AdvanceIT();
24008       return;
24009     }
24010   } else {
24011     // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1
24012     if (dt.Is(F64)) {
24013       EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
24014               rm.Encode(5, 0));
24015       return;
24016     }
24017   }
24018   Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
24019 }
24020 
vselvs(DataType dt,SRegister rd,SRegister rn,SRegister rm)24021 void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
24022   VIXL_ASSERT(AllowAssembler());
24023   CheckIT(al);
24024   if (IsUsingT32()) {
24025     // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1
24026     if (OutsideITBlock() && dt.Is(F32)) {
24027       EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
24028                  rm.Encode(5, 0));
24029       AdvanceIT();
24030       return;
24031     }
24032   } else {
24033     // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1
24034     if (dt.Is(F32)) {
24035       EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
24036               rm.Encode(5, 0));
24037       return;
24038     }
24039   }
24040   Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
24041 }
24042 
vshl(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)24043 void Assembler::vshl(Condition cond,
24044                      DataType dt,
24045                      DRegister rd,
24046                      DRegister rm,
24047                      const DOperand& operand) {
24048   VIXL_ASSERT(AllowAssembler());
24049   CheckIT(cond);
24050   if (operand.IsImmediate()) {
24051     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24052       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24053       Dt_L_imm6_3 encoded_dt(dt);
24054       if (IsUsingT32()) {
24055         // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1
24056         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24057           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24058             uint32_t imm6 = imm;
24059             EmitT32_32(0xef800510U |
24060                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24061                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24062                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24063             AdvanceIT();
24064             return;
24065           }
24066         }
24067       } else {
24068         // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1
24069         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24070           if (cond.Is(al)) {
24071             uint32_t imm6 = imm;
24072             EmitA32(0xf2800510U |
24073                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24074                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24075                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24076             return;
24077           }
24078         }
24079       }
24080     }
24081   }
24082   if (operand.IsRegister()) {
24083     DRegister rn = operand.GetRegister();
24084     Dt_U_size_3 encoded_dt(dt);
24085     if (IsUsingT32()) {
24086       // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
24087       if (encoded_dt.IsValid()) {
24088         if (cond.Is(al) || AllowStronglyDiscouraged()) {
24089           EmitT32_32(0xef000400U |
24090                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24091                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24092                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24093           AdvanceIT();
24094           return;
24095         }
24096       }
24097     } else {
24098       // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
24099       if (encoded_dt.IsValid()) {
24100         if (cond.Is(al)) {
24101           EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24102                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24103                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24104           return;
24105         }
24106       }
24107     }
24108   }
24109   Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
24110 }
24111 
vshl(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)24112 void Assembler::vshl(Condition cond,
24113                      DataType dt,
24114                      QRegister rd,
24115                      QRegister rm,
24116                      const QOperand& operand) {
24117   VIXL_ASSERT(AllowAssembler());
24118   CheckIT(cond);
24119   if (operand.IsImmediate()) {
24120     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24121       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24122       Dt_L_imm6_3 encoded_dt(dt);
24123       if (IsUsingT32()) {
24124         // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1
24125         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24126           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24127             uint32_t imm6 = imm;
24128             EmitT32_32(0xef800550U |
24129                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24130                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24131                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24132             AdvanceIT();
24133             return;
24134           }
24135         }
24136       } else {
24137         // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1
24138         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24139           if (cond.Is(al)) {
24140             uint32_t imm6 = imm;
24141             EmitA32(0xf2800550U |
24142                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24143                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24144                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24145             return;
24146           }
24147         }
24148       }
24149     }
24150   }
24151   if (operand.IsRegister()) {
24152     QRegister rn = operand.GetRegister();
24153     Dt_U_size_3 encoded_dt(dt);
24154     if (IsUsingT32()) {
24155       // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
24156       if (encoded_dt.IsValid()) {
24157         if (cond.Is(al) || AllowStronglyDiscouraged()) {
24158           EmitT32_32(0xef000440U |
24159                      ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24160                      ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24161                      rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24162           AdvanceIT();
24163           return;
24164         }
24165       }
24166     } else {
24167       // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
24168       if (encoded_dt.IsValid()) {
24169         if (cond.Is(al)) {
24170           EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24171                   ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24172                   rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24173           return;
24174         }
24175       }
24176     }
24177   }
24178   Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
24179 }
24180 
vshll(Condition cond,DataType dt,QRegister rd,DRegister rm,const DOperand & operand)24181 void Assembler::vshll(Condition cond,
24182                       DataType dt,
24183                       QRegister rd,
24184                       DRegister rm,
24185                       const DOperand& operand) {
24186   VIXL_ASSERT(AllowAssembler());
24187   CheckIT(cond);
24188   if (operand.IsImmediate()) {
24189     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24190       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24191       Dt_imm6_4 encoded_dt(dt);
24192       Dt_size_16 encoded_dt_2(dt);
24193       if (IsUsingT32()) {
24194         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1
24195         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
24196           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24197             uint32_t imm6 = dt.GetSize() + imm;
24198             EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) |
24199                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24200                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24201             AdvanceIT();
24202             return;
24203           }
24204         }
24205         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2
24206         if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
24207           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24208             EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) |
24209                        rd.Encode(22, 12) | rm.Encode(5, 0));
24210             AdvanceIT();
24211             return;
24212           }
24213         }
24214       } else {
24215         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1
24216         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
24217           if (cond.Is(al)) {
24218             uint32_t imm6 = dt.GetSize() + imm;
24219             EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) |
24220                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24221                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24222             return;
24223           }
24224         }
24225         // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2
24226         if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
24227           if (cond.Is(al)) {
24228             EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) |
24229                     rd.Encode(22, 12) | rm.Encode(5, 0));
24230             return;
24231           }
24232         }
24233       }
24234     }
24235   }
24236   Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand);
24237 }
24238 
vshr(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)24239 void Assembler::vshr(Condition cond,
24240                      DataType dt,
24241                      DRegister rd,
24242                      DRegister rm,
24243                      const DOperand& operand) {
24244   VIXL_ASSERT(AllowAssembler());
24245   CheckIT(cond);
24246   if (operand.IsImmediate()) {
24247     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24248       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24249       Dt_L_imm6_1 encoded_dt(dt);
24250       if (IsUsingT32()) {
24251         // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
24252         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24253           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24254             uint32_t imm6 = dt.GetSize() - imm;
24255             EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) |
24256                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24257                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24258                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24259             AdvanceIT();
24260             return;
24261           }
24262         }
24263         // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
24264         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24265           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24266             EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24267                        rm.Encode(5, 0));
24268             AdvanceIT();
24269             return;
24270           }
24271         }
24272       } else {
24273         // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
24274         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24275           if (cond.Is(al)) {
24276             uint32_t imm6 = dt.GetSize() - imm;
24277             EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) |
24278                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24279                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24280                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24281             return;
24282           }
24283         }
24284         // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
24285         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24286           if (cond.Is(al)) {
24287             EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24288                     rm.Encode(5, 0));
24289             return;
24290           }
24291         }
24292       }
24293     }
24294   }
24295   Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
24296 }
24297 
vshr(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)24298 void Assembler::vshr(Condition cond,
24299                      DataType dt,
24300                      QRegister rd,
24301                      QRegister rm,
24302                      const QOperand& operand) {
24303   VIXL_ASSERT(AllowAssembler());
24304   CheckIT(cond);
24305   if (operand.IsImmediate()) {
24306     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24307       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24308       Dt_L_imm6_1 encoded_dt(dt);
24309       if (IsUsingT32()) {
24310         // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
24311         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24312           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24313             uint32_t imm6 = dt.GetSize() - imm;
24314             EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) |
24315                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24316                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24317                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24318             AdvanceIT();
24319             return;
24320           }
24321         }
24322         // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
24323         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24324           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24325             EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24326                        rm.Encode(5, 0));
24327             AdvanceIT();
24328             return;
24329           }
24330         }
24331       } else {
24332         // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
24333         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24334           if (cond.Is(al)) {
24335             uint32_t imm6 = dt.GetSize() - imm;
24336             EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) |
24337                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24338                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24339                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24340             return;
24341           }
24342         }
24343         // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
24344         if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24345           if (cond.Is(al)) {
24346             EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24347                     rm.Encode(5, 0));
24348             return;
24349           }
24350         }
24351       }
24352     }
24353   }
24354   Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
24355 }
24356 
vshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)24357 void Assembler::vshrn(Condition cond,
24358                       DataType dt,
24359                       DRegister rd,
24360                       QRegister rm,
24361                       const QOperand& operand) {
24362   VIXL_ASSERT(AllowAssembler());
24363   CheckIT(cond);
24364   if (operand.IsImmediate()) {
24365     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24366       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24367       Dt_imm6_3 encoded_dt(dt);
24368       Dt_size_3 encoded_dt_2(dt);
24369       if (IsUsingT32()) {
24370         // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
24371         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
24372           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24373             uint32_t imm6 = dt.GetSize() / 2 - imm;
24374             EmitT32_32(0xef800810U |
24375                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24376                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24377             AdvanceIT();
24378             return;
24379           }
24380         }
24381         // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
24382         if (encoded_dt_2.IsValid() && (imm == 0)) {
24383           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24384             EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
24385                        rd.Encode(22, 12) | rm.Encode(5, 0));
24386             AdvanceIT();
24387             return;
24388           }
24389         }
24390       } else {
24391         // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
24392         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
24393           if (cond.Is(al)) {
24394             uint32_t imm6 = dt.GetSize() / 2 - imm;
24395             EmitA32(0xf2800810U |
24396                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24397                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24398             return;
24399           }
24400         }
24401         // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
24402         if (encoded_dt_2.IsValid() && (imm == 0)) {
24403           if (cond.Is(al)) {
24404             EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
24405                     rd.Encode(22, 12) | rm.Encode(5, 0));
24406             return;
24407           }
24408         }
24409       }
24410     }
24411   }
24412   Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand);
24413 }
24414 
vsli(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)24415 void Assembler::vsli(Condition cond,
24416                      DataType dt,
24417                      DRegister rd,
24418                      DRegister rm,
24419                      const DOperand& operand) {
24420   VIXL_ASSERT(AllowAssembler());
24421   CheckIT(cond);
24422   if (operand.IsImmediate()) {
24423     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24424       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24425       Dt_L_imm6_4 encoded_dt(dt);
24426       if (IsUsingT32()) {
24427         // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
24428         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24429           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24430             uint32_t imm6 = imm;
24431             EmitT32_32(0xff800510U |
24432                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24433                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24434                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24435             AdvanceIT();
24436             return;
24437           }
24438         }
24439       } else {
24440         // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
24441         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24442           if (cond.Is(al)) {
24443             uint32_t imm6 = imm;
24444             EmitA32(0xf3800510U |
24445                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24446                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24447                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24448             return;
24449           }
24450         }
24451       }
24452     }
24453   }
24454   Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
24455 }
24456 
vsli(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)24457 void Assembler::vsli(Condition cond,
24458                      DataType dt,
24459                      QRegister rd,
24460                      QRegister rm,
24461                      const QOperand& operand) {
24462   VIXL_ASSERT(AllowAssembler());
24463   CheckIT(cond);
24464   if (operand.IsImmediate()) {
24465     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24466       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24467       Dt_L_imm6_4 encoded_dt(dt);
24468       if (IsUsingT32()) {
24469         // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
24470         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24471           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24472             uint32_t imm6 = imm;
24473             EmitT32_32(0xff800550U |
24474                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24475                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24476                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24477             AdvanceIT();
24478             return;
24479           }
24480         }
24481       } else {
24482         // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
24483         if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
24484           if (cond.Is(al)) {
24485             uint32_t imm6 = imm;
24486             EmitA32(0xf3800550U |
24487                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24488                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24489                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24490             return;
24491           }
24492         }
24493       }
24494     }
24495   }
24496   Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
24497 }
24498 
vsqrt(Condition cond,DataType dt,SRegister rd,SRegister rm)24499 void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) {
24500   VIXL_ASSERT(AllowAssembler());
24501   CheckIT(cond);
24502   if (IsUsingT32()) {
24503     // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
24504     if (dt.Is(F32)) {
24505       EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
24506       AdvanceIT();
24507       return;
24508     }
24509   } else {
24510     // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
24511     if (dt.Is(F32) && cond.IsNotNever()) {
24512       EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24513               rm.Encode(5, 0));
24514       return;
24515     }
24516   }
24517   Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
24518 }
24519 
vsqrt(Condition cond,DataType dt,DRegister rd,DRegister rm)24520 void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
24521   VIXL_ASSERT(AllowAssembler());
24522   CheckIT(cond);
24523   if (IsUsingT32()) {
24524     // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
24525     if (dt.Is(F64)) {
24526       EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
24527       AdvanceIT();
24528       return;
24529     }
24530   } else {
24531     // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
24532     if (dt.Is(F64) && cond.IsNotNever()) {
24533       EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24534               rm.Encode(5, 0));
24535       return;
24536     }
24537   }
24538   Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
24539 }
24540 
vsra(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)24541 void Assembler::vsra(Condition cond,
24542                      DataType dt,
24543                      DRegister rd,
24544                      DRegister rm,
24545                      const DOperand& operand) {
24546   VIXL_ASSERT(AllowAssembler());
24547   CheckIT(cond);
24548   if (operand.IsImmediate()) {
24549     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24550       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24551       Dt_L_imm6_1 encoded_dt(dt);
24552       if (IsUsingT32()) {
24553         // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
24554         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24555           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24556             uint32_t imm6 = dt.GetSize() - imm;
24557             EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) |
24558                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24559                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24560                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24561             AdvanceIT();
24562             return;
24563           }
24564         }
24565       } else {
24566         // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
24567         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24568           if (cond.Is(al)) {
24569             uint32_t imm6 = dt.GetSize() - imm;
24570             EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) |
24571                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24572                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24573                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24574             return;
24575           }
24576         }
24577       }
24578     }
24579   }
24580   Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
24581 }
24582 
vsra(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)24583 void Assembler::vsra(Condition cond,
24584                      DataType dt,
24585                      QRegister rd,
24586                      QRegister rm,
24587                      const QOperand& operand) {
24588   VIXL_ASSERT(AllowAssembler());
24589   CheckIT(cond);
24590   if (operand.IsImmediate()) {
24591     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24592       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24593       Dt_L_imm6_1 encoded_dt(dt);
24594       if (IsUsingT32()) {
24595         // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
24596         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24597           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24598             uint32_t imm6 = dt.GetSize() - imm;
24599             EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) |
24600                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24601                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24602                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24603             AdvanceIT();
24604             return;
24605           }
24606         }
24607       } else {
24608         // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
24609         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24610           if (cond.Is(al)) {
24611             uint32_t imm6 = dt.GetSize() - imm;
24612             EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) |
24613                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24614                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24615                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24616             return;
24617           }
24618         }
24619       }
24620     }
24621   }
24622   Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
24623 }
24624 
vsri(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)24625 void Assembler::vsri(Condition cond,
24626                      DataType dt,
24627                      DRegister rd,
24628                      DRegister rm,
24629                      const DOperand& operand) {
24630   VIXL_ASSERT(AllowAssembler());
24631   CheckIT(cond);
24632   if (operand.IsImmediate()) {
24633     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24634       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24635       Dt_L_imm6_4 encoded_dt(dt);
24636       if (IsUsingT32()) {
24637         // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
24638         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24639           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24640             uint32_t imm6 = dt.GetSize() - imm;
24641             EmitT32_32(0xff800410U |
24642                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24643                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24644                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24645             AdvanceIT();
24646             return;
24647           }
24648         }
24649       } else {
24650         // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
24651         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24652           if (cond.Is(al)) {
24653             uint32_t imm6 = dt.GetSize() - imm;
24654             EmitA32(0xf3800410U |
24655                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24656                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24657                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24658             return;
24659           }
24660         }
24661       }
24662     }
24663   }
24664   Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
24665 }
24666 
vsri(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)24667 void Assembler::vsri(Condition cond,
24668                      DataType dt,
24669                      QRegister rd,
24670                      QRegister rm,
24671                      const QOperand& operand) {
24672   VIXL_ASSERT(AllowAssembler());
24673   CheckIT(cond);
24674   if (operand.IsImmediate()) {
24675     if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24676       uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24677       Dt_L_imm6_4 encoded_dt(dt);
24678       if (IsUsingT32()) {
24679         // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
24680         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24681           if (cond.Is(al) || AllowStronglyDiscouraged()) {
24682             uint32_t imm6 = dt.GetSize() - imm;
24683             EmitT32_32(0xff800450U |
24684                        ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24685                        ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24686                        rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24687             AdvanceIT();
24688             return;
24689           }
24690         }
24691       } else {
24692         // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
24693         if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24694           if (cond.Is(al)) {
24695             uint32_t imm6 = dt.GetSize() - imm;
24696             EmitA32(0xf3800450U |
24697                     ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24698                     ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24699                     rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24700             return;
24701           }
24702         }
24703       }
24704     }
24705   }
24706   Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
24707 }
24708 
vst1(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)24709 void Assembler::vst1(Condition cond,
24710                      DataType dt,
24711                      const NeonRegisterList& nreglist,
24712                      const AlignedMemOperand& operand) {
24713   VIXL_ASSERT(AllowAssembler());
24714   CheckIT(cond);
24715   if (operand.IsImmediateZero()) {
24716     Register rn = operand.GetBaseRegister();
24717     Alignment align = operand.GetAlignment();
24718     Dt_size_6 encoded_dt(dt);
24719     Dt_size_7 encoded_dt_2(dt);
24720     Align_align_5 encoded_align_1(align, nreglist);
24721     Align_index_align_1 encoded_align_2(align, nreglist, dt);
24722     if (IsUsingT32()) {
24723       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24724       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24725           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24726           operand.IsOffset() && encoded_align_1.IsValid() &&
24727           (!rn.IsPC() || AllowUnpredictable())) {
24728         if (cond.Is(al) || AllowStronglyDiscouraged()) {
24729           const DRegister& first = nreglist.GetFirstDRegister();
24730           uint32_t len_encoding;
24731           switch (nreglist.GetLength()) {
24732             default:
24733               VIXL_UNREACHABLE_OR_FALLTHROUGH();
24734             case 1:
24735               len_encoding = 0x7;
24736               break;
24737             case 2:
24738               len_encoding = 0xa;
24739               break;
24740             case 3:
24741               len_encoding = 0x6;
24742               break;
24743             case 4:
24744               len_encoding = 0x2;
24745               break;
24746           }
24747           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
24748                      (encoded_align_1.GetEncodingValue() << 4) |
24749                      first.Encode(22, 12) | (len_encoding << 8) |
24750                      (rn.GetCode() << 16));
24751           AdvanceIT();
24752           return;
24753         }
24754       }
24755       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24756       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24757           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24758           operand.IsPostIndex() && encoded_align_1.IsValid() &&
24759           (!rn.IsPC() || AllowUnpredictable())) {
24760         if (cond.Is(al) || AllowStronglyDiscouraged()) {
24761           const DRegister& first = nreglist.GetFirstDRegister();
24762           uint32_t len_encoding;
24763           switch (nreglist.GetLength()) {
24764             default:
24765               VIXL_UNREACHABLE_OR_FALLTHROUGH();
24766             case 1:
24767               len_encoding = 0x7;
24768               break;
24769             case 2:
24770               len_encoding = 0xa;
24771               break;
24772             case 3:
24773               len_encoding = 0x6;
24774               break;
24775             case 4:
24776               len_encoding = 0x2;
24777               break;
24778           }
24779           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
24780                      (encoded_align_1.GetEncodingValue() << 4) |
24781                      first.Encode(22, 12) | (len_encoding << 8) |
24782                      (rn.GetCode() << 16));
24783           AdvanceIT();
24784           return;
24785         }
24786       }
24787       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
24788       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24789           (nreglist.GetLength() == 1) && operand.IsOffset() &&
24790           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
24791         if (cond.Is(al) || AllowStronglyDiscouraged()) {
24792           const DRegister& first = nreglist.GetFirstDRegister();
24793           EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) |
24794                      (encoded_align_2.GetEncodingValue() << 4) |
24795                      first.Encode(22, 12) | (rn.GetCode() << 16));
24796           AdvanceIT();
24797           return;
24798         }
24799       }
24800       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
24801       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24802           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
24803           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
24804         if (cond.Is(al) || AllowStronglyDiscouraged()) {
24805           const DRegister& first = nreglist.GetFirstDRegister();
24806           EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) |
24807                      (encoded_align_2.GetEncodingValue() << 4) |
24808                      first.Encode(22, 12) | (rn.GetCode() << 16));
24809           AdvanceIT();
24810           return;
24811         }
24812       }
24813     } else {
24814       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
24815       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24816           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24817           operand.IsOffset() && encoded_align_1.IsValid() &&
24818           (!rn.IsPC() || AllowUnpredictable())) {
24819         if (cond.Is(al)) {
24820           const DRegister& first = nreglist.GetFirstDRegister();
24821           uint32_t len_encoding;
24822           switch (nreglist.GetLength()) {
24823             default:
24824               VIXL_UNREACHABLE_OR_FALLTHROUGH();
24825             case 1:
24826               len_encoding = 0x7;
24827               break;
24828             case 2:
24829               len_encoding = 0xa;
24830               break;
24831             case 3:
24832               len_encoding = 0x6;
24833               break;
24834             case 4:
24835               len_encoding = 0x2;
24836               break;
24837           }
24838           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
24839                   (encoded_align_1.GetEncodingValue() << 4) |
24840                   first.Encode(22, 12) | (len_encoding << 8) |
24841                   (rn.GetCode() << 16));
24842           return;
24843         }
24844       }
24845       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
24846       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24847           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24848           operand.IsPostIndex() && encoded_align_1.IsValid() &&
24849           (!rn.IsPC() || AllowUnpredictable())) {
24850         if (cond.Is(al)) {
24851           const DRegister& first = nreglist.GetFirstDRegister();
24852           uint32_t len_encoding;
24853           switch (nreglist.GetLength()) {
24854             default:
24855               VIXL_UNREACHABLE_OR_FALLTHROUGH();
24856             case 1:
24857               len_encoding = 0x7;
24858               break;
24859             case 2:
24860               len_encoding = 0xa;
24861               break;
24862             case 3:
24863               len_encoding = 0x6;
24864               break;
24865             case 4:
24866               len_encoding = 0x2;
24867               break;
24868           }
24869           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
24870                   (encoded_align_1.GetEncodingValue() << 4) |
24871                   first.Encode(22, 12) | (len_encoding << 8) |
24872                   (rn.GetCode() << 16));
24873           return;
24874         }
24875       }
24876       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
24877       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24878           (nreglist.GetLength() == 1) && operand.IsOffset() &&
24879           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
24880         if (cond.Is(al)) {
24881           const DRegister& first = nreglist.GetFirstDRegister();
24882           EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) |
24883                   (encoded_align_2.GetEncodingValue() << 4) |
24884                   first.Encode(22, 12) | (rn.GetCode() << 16));
24885           return;
24886         }
24887       }
24888       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
24889       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24890           (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
24891           encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
24892         if (cond.Is(al)) {
24893           const DRegister& first = nreglist.GetFirstDRegister();
24894           EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) |
24895                   (encoded_align_2.GetEncodingValue() << 4) |
24896                   first.Encode(22, 12) | (rn.GetCode() << 16));
24897           return;
24898         }
24899       }
24900     }
24901   }
24902   if (operand.IsPlainRegister()) {
24903     Register rn = operand.GetBaseRegister();
24904     Alignment align = operand.GetAlignment();
24905     Register rm = operand.GetOffsetRegister();
24906     Dt_size_6 encoded_dt(dt);
24907     Dt_size_7 encoded_dt_2(dt);
24908     Align_align_5 encoded_align_1(align, nreglist);
24909     Align_index_align_1 encoded_align_2(align, nreglist, dt);
24910     if (IsUsingT32()) {
24911       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
24912       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24913           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24914           !rm.IsPC() && !rm.IsSP()) {
24915         if (cond.Is(al) || AllowStronglyDiscouraged()) {
24916           const DRegister& first = nreglist.GetFirstDRegister();
24917           uint32_t len_encoding;
24918           switch (nreglist.GetLength()) {
24919             default:
24920               VIXL_UNREACHABLE_OR_FALLTHROUGH();
24921             case 1:
24922               len_encoding = 0x7;
24923               break;
24924             case 2:
24925               len_encoding = 0xa;
24926               break;
24927             case 3:
24928               len_encoding = 0x6;
24929               break;
24930             case 4:
24931               len_encoding = 0x2;
24932               break;
24933           }
24934           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
24935                      (encoded_align_1.GetEncodingValue() << 4) |
24936                      first.Encode(22, 12) | (len_encoding << 8) |
24937                      (rn.GetCode() << 16) | rm.GetCode());
24938           AdvanceIT();
24939           return;
24940         }
24941       }
24942       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
24943       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24944           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
24945         if (cond.Is(al) || AllowStronglyDiscouraged()) {
24946           const DRegister& first = nreglist.GetFirstDRegister();
24947           EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) |
24948                      (encoded_align_2.GetEncodingValue() << 4) |
24949                      first.Encode(22, 12) | (rn.GetCode() << 16) |
24950                      rm.GetCode());
24951           AdvanceIT();
24952           return;
24953         }
24954       }
24955     } else {
24956       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
24957       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
24958           (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
24959           !rm.IsPC() && !rm.IsSP()) {
24960         if (cond.Is(al)) {
24961           const DRegister& first = nreglist.GetFirstDRegister();
24962           uint32_t len_encoding;
24963           switch (nreglist.GetLength()) {
24964             default:
24965               VIXL_UNREACHABLE_OR_FALLTHROUGH();
24966             case 1:
24967               len_encoding = 0x7;
24968               break;
24969             case 2:
24970               len_encoding = 0xa;
24971               break;
24972             case 3:
24973               len_encoding = 0x6;
24974               break;
24975             case 4:
24976               len_encoding = 0x2;
24977               break;
24978           }
24979           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
24980                   (encoded_align_1.GetEncodingValue() << 4) |
24981                   first.Encode(22, 12) | (len_encoding << 8) |
24982                   (rn.GetCode() << 16) | rm.GetCode());
24983           return;
24984         }
24985       }
24986       // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
24987       if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
24988           (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP()) {
24989         if (cond.Is(al)) {
24990           const DRegister& first = nreglist.GetFirstDRegister();
24991           EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) |
24992                   (encoded_align_2.GetEncodingValue() << 4) |
24993                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
24994           return;
24995         }
24996       }
24997     }
24998   }
24999   Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand);
25000 }
25001 
vst2(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)25002 void Assembler::vst2(Condition cond,
25003                      DataType dt,
25004                      const NeonRegisterList& nreglist,
25005                      const AlignedMemOperand& operand) {
25006   VIXL_ASSERT(AllowAssembler());
25007   CheckIT(cond);
25008   if (operand.IsImmediateZero()) {
25009     Register rn = operand.GetBaseRegister();
25010     Alignment align = operand.GetAlignment();
25011     Dt_size_7 encoded_dt(dt);
25012     Align_align_2 encoded_align_1(align, nreglist);
25013     Align_index_align_2 encoded_align_2(align, nreglist, dt);
25014     if (IsUsingT32()) {
25015       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25016       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25017           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25018            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25019            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25020           operand.IsOffset() && encoded_align_1.IsValid() &&
25021           (!rn.IsPC() || AllowUnpredictable())) {
25022         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25023           const DRegister& first = nreglist.GetFirstDRegister();
25024           uint32_t len_encoding;
25025           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25026             len_encoding = 0x8;
25027           }
25028           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25029             len_encoding = 0x9;
25030           }
25031           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25032             len_encoding = 0x3;
25033           }
25034           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
25035                      (encoded_align_1.GetEncodingValue() << 4) |
25036                      first.Encode(22, 12) | (len_encoding << 8) |
25037                      (rn.GetCode() << 16));
25038           AdvanceIT();
25039           return;
25040         }
25041       }
25042       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25043       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25044           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25045            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25046            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25047           operand.IsPostIndex() && encoded_align_1.IsValid() &&
25048           (!rn.IsPC() || AllowUnpredictable())) {
25049         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25050           const DRegister& first = nreglist.GetFirstDRegister();
25051           uint32_t len_encoding;
25052           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25053             len_encoding = 0x8;
25054           }
25055           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25056             len_encoding = 0x9;
25057           }
25058           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25059             len_encoding = 0x3;
25060           }
25061           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
25062                      (encoded_align_1.GetEncodingValue() << 4) |
25063                      first.Encode(22, 12) | (len_encoding << 8) |
25064                      (rn.GetCode() << 16));
25065           AdvanceIT();
25066           return;
25067         }
25068       }
25069       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25070       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25071           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25072            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25073           operand.IsOffset() && encoded_align_2.IsValid() &&
25074           (!rn.IsPC() || AllowUnpredictable())) {
25075         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25076           const DRegister& first = nreglist.GetFirstDRegister();
25077           EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) |
25078                      (encoded_align_2.GetEncodingValue() << 4) |
25079                      first.Encode(22, 12) | (rn.GetCode() << 16));
25080           AdvanceIT();
25081           return;
25082         }
25083       }
25084       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25085       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25086           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25087            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25088           operand.IsPostIndex() && encoded_align_2.IsValid() &&
25089           (!rn.IsPC() || AllowUnpredictable())) {
25090         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25091           const DRegister& first = nreglist.GetFirstDRegister();
25092           EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) |
25093                      (encoded_align_2.GetEncodingValue() << 4) |
25094                      first.Encode(22, 12) | (rn.GetCode() << 16));
25095           AdvanceIT();
25096           return;
25097         }
25098       }
25099     } else {
25100       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25101       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25102           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25103            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25104            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25105           operand.IsOffset() && encoded_align_1.IsValid() &&
25106           (!rn.IsPC() || AllowUnpredictable())) {
25107         if (cond.Is(al)) {
25108           const DRegister& first = nreglist.GetFirstDRegister();
25109           uint32_t len_encoding;
25110           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25111             len_encoding = 0x8;
25112           }
25113           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25114             len_encoding = 0x9;
25115           }
25116           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25117             len_encoding = 0x3;
25118           }
25119           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
25120                   (encoded_align_1.GetEncodingValue() << 4) |
25121                   first.Encode(22, 12) | (len_encoding << 8) |
25122                   (rn.GetCode() << 16));
25123           return;
25124         }
25125       }
25126       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25127       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25128           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25129            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25130            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25131           operand.IsPostIndex() && encoded_align_1.IsValid() &&
25132           (!rn.IsPC() || AllowUnpredictable())) {
25133         if (cond.Is(al)) {
25134           const DRegister& first = nreglist.GetFirstDRegister();
25135           uint32_t len_encoding;
25136           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25137             len_encoding = 0x8;
25138           }
25139           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25140             len_encoding = 0x9;
25141           }
25142           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25143             len_encoding = 0x3;
25144           }
25145           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
25146                   (encoded_align_1.GetEncodingValue() << 4) |
25147                   first.Encode(22, 12) | (len_encoding << 8) |
25148                   (rn.GetCode() << 16));
25149           return;
25150         }
25151       }
25152       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25153       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25154           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25155            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25156           operand.IsOffset() && encoded_align_2.IsValid() &&
25157           (!rn.IsPC() || AllowUnpredictable())) {
25158         if (cond.Is(al)) {
25159           const DRegister& first = nreglist.GetFirstDRegister();
25160           EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) |
25161                   (encoded_align_2.GetEncodingValue() << 4) |
25162                   first.Encode(22, 12) | (rn.GetCode() << 16));
25163           return;
25164         }
25165       }
25166       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25167       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25168           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25169            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25170           operand.IsPostIndex() && encoded_align_2.IsValid() &&
25171           (!rn.IsPC() || AllowUnpredictable())) {
25172         if (cond.Is(al)) {
25173           const DRegister& first = nreglist.GetFirstDRegister();
25174           EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) |
25175                   (encoded_align_2.GetEncodingValue() << 4) |
25176                   first.Encode(22, 12) | (rn.GetCode() << 16));
25177           return;
25178         }
25179       }
25180     }
25181   }
25182   if (operand.IsPlainRegister()) {
25183     Register rn = operand.GetBaseRegister();
25184     Alignment align = operand.GetAlignment();
25185     Register rm = operand.GetOffsetRegister();
25186     Dt_size_7 encoded_dt(dt);
25187     Align_align_2 encoded_align_1(align, nreglist);
25188     Align_index_align_2 encoded_align_2(align, nreglist, dt);
25189     if (IsUsingT32()) {
25190       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25191       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25192           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25193            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25194            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25195           !rm.IsPC() && !rm.IsSP()) {
25196         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25197           const DRegister& first = nreglist.GetFirstDRegister();
25198           uint32_t len_encoding;
25199           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25200             len_encoding = 0x8;
25201           }
25202           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25203             len_encoding = 0x9;
25204           }
25205           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25206             len_encoding = 0x3;
25207           }
25208           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
25209                      (encoded_align_1.GetEncodingValue() << 4) |
25210                      first.Encode(22, 12) | (len_encoding << 8) |
25211                      (rn.GetCode() << 16) | rm.GetCode());
25212           AdvanceIT();
25213           return;
25214         }
25215       }
25216       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25217       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25218           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25219            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25220           !rm.IsPC() && !rm.IsSP()) {
25221         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25222           const DRegister& first = nreglist.GetFirstDRegister();
25223           EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) |
25224                      (encoded_align_2.GetEncodingValue() << 4) |
25225                      first.Encode(22, 12) | (rn.GetCode() << 16) |
25226                      rm.GetCode());
25227           AdvanceIT();
25228           return;
25229         }
25230       }
25231     } else {
25232       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25233       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25234           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25235            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
25236            (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
25237           !rm.IsPC() && !rm.IsSP()) {
25238         if (cond.Is(al)) {
25239           const DRegister& first = nreglist.GetFirstDRegister();
25240           uint32_t len_encoding;
25241           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
25242             len_encoding = 0x8;
25243           }
25244           if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
25245             len_encoding = 0x9;
25246           }
25247           if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
25248             len_encoding = 0x3;
25249           }
25250           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
25251                   (encoded_align_1.GetEncodingValue() << 4) |
25252                   first.Encode(22, 12) | (len_encoding << 8) |
25253                   (rn.GetCode() << 16) | rm.GetCode());
25254           return;
25255         }
25256       }
25257       // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25258       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25259           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
25260            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
25261           !rm.IsPC() && !rm.IsSP()) {
25262         if (cond.Is(al)) {
25263           const DRegister& first = nreglist.GetFirstDRegister();
25264           EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) |
25265                   (encoded_align_2.GetEncodingValue() << 4) |
25266                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
25267           return;
25268         }
25269       }
25270     }
25271   }
25272   Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand);
25273 }
25274 
vst3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)25275 void Assembler::vst3(Condition cond,
25276                      DataType dt,
25277                      const NeonRegisterList& nreglist,
25278                      const AlignedMemOperand& operand) {
25279   VIXL_ASSERT(AllowAssembler());
25280   CheckIT(cond);
25281   if (operand.IsImmediateZero()) {
25282     Register rn = operand.GetBaseRegister();
25283     Alignment align = operand.GetAlignment();
25284     Dt_size_7 encoded_dt(dt);
25285     Align_align_3 encoded_align_1(align);
25286     if (IsUsingT32()) {
25287       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25288       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25289           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25290            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25291           operand.IsOffset() && encoded_align_1.IsValid() &&
25292           (!rn.IsPC() || AllowUnpredictable())) {
25293         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25294           const DRegister& first = nreglist.GetFirstDRegister();
25295           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25296           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
25297                      (encoded_align_1.GetEncodingValue() << 4) |
25298                      first.Encode(22, 12) | (len_encoding << 8) |
25299                      (rn.GetCode() << 16));
25300           AdvanceIT();
25301           return;
25302         }
25303       }
25304       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25305       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25306           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25307            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25308           operand.IsPostIndex() && encoded_align_1.IsValid() &&
25309           (!rn.IsPC() || AllowUnpredictable())) {
25310         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25311           const DRegister& first = nreglist.GetFirstDRegister();
25312           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25313           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
25314                      (encoded_align_1.GetEncodingValue() << 4) |
25315                      first.Encode(22, 12) | (len_encoding << 8) |
25316                      (rn.GetCode() << 16));
25317           AdvanceIT();
25318           return;
25319         }
25320       }
25321     } else {
25322       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25323       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25324           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25325            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25326           operand.IsOffset() && encoded_align_1.IsValid() &&
25327           (!rn.IsPC() || AllowUnpredictable())) {
25328         if (cond.Is(al)) {
25329           const DRegister& first = nreglist.GetFirstDRegister();
25330           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25331           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
25332                   (encoded_align_1.GetEncodingValue() << 4) |
25333                   first.Encode(22, 12) | (len_encoding << 8) |
25334                   (rn.GetCode() << 16));
25335           return;
25336         }
25337       }
25338       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25339       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25340           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25341            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25342           operand.IsPostIndex() && encoded_align_1.IsValid() &&
25343           (!rn.IsPC() || AllowUnpredictable())) {
25344         if (cond.Is(al)) {
25345           const DRegister& first = nreglist.GetFirstDRegister();
25346           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25347           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
25348                   (encoded_align_1.GetEncodingValue() << 4) |
25349                   first.Encode(22, 12) | (len_encoding << 8) |
25350                   (rn.GetCode() << 16));
25351           return;
25352         }
25353       }
25354     }
25355   }
25356   if (operand.IsPlainRegister()) {
25357     Register rn = operand.GetBaseRegister();
25358     Alignment align = operand.GetAlignment();
25359     Register rm = operand.GetOffsetRegister();
25360     Dt_size_7 encoded_dt(dt);
25361     Align_align_3 encoded_align_1(align);
25362     if (IsUsingT32()) {
25363       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25364       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25365           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25366            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25367           !rm.IsPC() && !rm.IsSP()) {
25368         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25369           const DRegister& first = nreglist.GetFirstDRegister();
25370           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25371           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
25372                      (encoded_align_1.GetEncodingValue() << 4) |
25373                      first.Encode(22, 12) | (len_encoding << 8) |
25374                      (rn.GetCode() << 16) | rm.GetCode());
25375           AdvanceIT();
25376           return;
25377         }
25378       }
25379     } else {
25380       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25381       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25382           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25383            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25384           !rm.IsPC() && !rm.IsSP()) {
25385         if (cond.Is(al)) {
25386           const DRegister& first = nreglist.GetFirstDRegister();
25387           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
25388           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
25389                   (encoded_align_1.GetEncodingValue() << 4) |
25390                   first.Encode(22, 12) | (len_encoding << 8) |
25391                   (rn.GetCode() << 16) | rm.GetCode());
25392           return;
25393         }
25394       }
25395     }
25396   }
25397   Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
25398 }
25399 
vst3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const MemOperand & operand)25400 void Assembler::vst3(Condition cond,
25401                      DataType dt,
25402                      const NeonRegisterList& nreglist,
25403                      const MemOperand& operand) {
25404   VIXL_ASSERT(AllowAssembler());
25405   CheckIT(cond);
25406   if (operand.IsImmediateZero()) {
25407     Register rn = operand.GetBaseRegister();
25408     Dt_size_7 encoded_dt(dt);
25409     Index_1 encoded_align_1(nreglist, dt);
25410     if (IsUsingT32()) {
25411       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
25412       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25413           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25414            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25415           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
25416         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25417           const DRegister& first = nreglist.GetFirstDRegister();
25418           EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) |
25419                      (encoded_align_1.GetEncodingValue() << 4) |
25420                      first.Encode(22, 12) | (rn.GetCode() << 16));
25421           AdvanceIT();
25422           return;
25423         }
25424       }
25425       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
25426       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25427           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25428            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25429           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
25430         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25431           const DRegister& first = nreglist.GetFirstDRegister();
25432           EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) |
25433                      (encoded_align_1.GetEncodingValue() << 4) |
25434                      first.Encode(22, 12) | (rn.GetCode() << 16));
25435           AdvanceIT();
25436           return;
25437         }
25438       }
25439     } else {
25440       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
25441       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25442           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25443            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25444           operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
25445         if (cond.Is(al)) {
25446           const DRegister& first = nreglist.GetFirstDRegister();
25447           EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) |
25448                   (encoded_align_1.GetEncodingValue() << 4) |
25449                   first.Encode(22, 12) | (rn.GetCode() << 16));
25450           return;
25451         }
25452       }
25453       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
25454       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25455           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25456            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25457           operand.IsPreIndex() && (!rn.IsPC() || AllowUnpredictable())) {
25458         if (cond.Is(al)) {
25459           const DRegister& first = nreglist.GetFirstDRegister();
25460           EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) |
25461                   (encoded_align_1.GetEncodingValue() << 4) |
25462                   first.Encode(22, 12) | (rn.GetCode() << 16));
25463           return;
25464         }
25465       }
25466     }
25467   }
25468   if (operand.IsPlainRegister()) {
25469     Register rn = operand.GetBaseRegister();
25470     Sign sign = operand.GetSign();
25471     Register rm = operand.GetOffsetRegister();
25472     Dt_size_7 encoded_dt(dt);
25473     Index_1 encoded_align_1(nreglist, dt);
25474     if (IsUsingT32()) {
25475       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
25476       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25477           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25478            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25479           sign.IsPlus() && operand.IsPostIndex()) {
25480         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25481           const DRegister& first = nreglist.GetFirstDRegister();
25482           EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) |
25483                      (encoded_align_1.GetEncodingValue() << 4) |
25484                      first.Encode(22, 12) | (rn.GetCode() << 16) |
25485                      rm.GetCode());
25486           AdvanceIT();
25487           return;
25488         }
25489       }
25490     } else {
25491       // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
25492       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25493           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
25494            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
25495           sign.IsPlus() && operand.IsPostIndex()) {
25496         if (cond.Is(al)) {
25497           const DRegister& first = nreglist.GetFirstDRegister();
25498           EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) |
25499                   (encoded_align_1.GetEncodingValue() << 4) |
25500                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
25501           return;
25502         }
25503       }
25504     }
25505   }
25506   Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
25507 }
25508 
vst4(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)25509 void Assembler::vst4(Condition cond,
25510                      DataType dt,
25511                      const NeonRegisterList& nreglist,
25512                      const AlignedMemOperand& operand) {
25513   VIXL_ASSERT(AllowAssembler());
25514   CheckIT(cond);
25515   if (operand.IsImmediateZero()) {
25516     Register rn = operand.GetBaseRegister();
25517     Alignment align = operand.GetAlignment();
25518     Dt_size_7 encoded_dt(dt);
25519     Align_align_4 encoded_align_1(align);
25520     Align_index_align_3 encoded_align_2(align, nreglist, dt);
25521     if (IsUsingT32()) {
25522       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25523       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25524           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25525            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25526           operand.IsOffset() && encoded_align_1.IsValid() &&
25527           (!rn.IsPC() || AllowUnpredictable())) {
25528         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25529           const DRegister& first = nreglist.GetFirstDRegister();
25530           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25531           EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
25532                      (encoded_align_1.GetEncodingValue() << 4) |
25533                      first.Encode(22, 12) | (len_encoding << 8) |
25534                      (rn.GetCode() << 16));
25535           AdvanceIT();
25536           return;
25537         }
25538       }
25539       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25540       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25541           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25542            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25543           operand.IsPostIndex() && encoded_align_1.IsValid() &&
25544           (!rn.IsPC() || AllowUnpredictable())) {
25545         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25546           const DRegister& first = nreglist.GetFirstDRegister();
25547           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25548           EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
25549                      (encoded_align_1.GetEncodingValue() << 4) |
25550                      first.Encode(22, 12) | (len_encoding << 8) |
25551                      (rn.GetCode() << 16));
25552           AdvanceIT();
25553           return;
25554         }
25555       }
25556       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
25557       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25558           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25559            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25560           operand.IsOffset() && encoded_align_2.IsValid() &&
25561           (!rn.IsPC() || AllowUnpredictable())) {
25562         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25563           const DRegister& first = nreglist.GetFirstDRegister();
25564           EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) |
25565                      (encoded_align_2.GetEncodingValue() << 4) |
25566                      first.Encode(22, 12) | (rn.GetCode() << 16));
25567           AdvanceIT();
25568           return;
25569         }
25570       }
25571       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
25572       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25573           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25574            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25575           operand.IsPostIndex() && encoded_align_2.IsValid() &&
25576           (!rn.IsPC() || AllowUnpredictable())) {
25577         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25578           const DRegister& first = nreglist.GetFirstDRegister();
25579           EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) |
25580                      (encoded_align_2.GetEncodingValue() << 4) |
25581                      first.Encode(22, 12) | (rn.GetCode() << 16));
25582           AdvanceIT();
25583           return;
25584         }
25585       }
25586     } else {
25587       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25588       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25589           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25590            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25591           operand.IsOffset() && encoded_align_1.IsValid() &&
25592           (!rn.IsPC() || AllowUnpredictable())) {
25593         if (cond.Is(al)) {
25594           const DRegister& first = nreglist.GetFirstDRegister();
25595           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25596           EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
25597                   (encoded_align_1.GetEncodingValue() << 4) |
25598                   first.Encode(22, 12) | (len_encoding << 8) |
25599                   (rn.GetCode() << 16));
25600           return;
25601         }
25602       }
25603       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25604       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25605           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25606            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25607           operand.IsPostIndex() && encoded_align_1.IsValid() &&
25608           (!rn.IsPC() || AllowUnpredictable())) {
25609         if (cond.Is(al)) {
25610           const DRegister& first = nreglist.GetFirstDRegister();
25611           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25612           EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
25613                   (encoded_align_1.GetEncodingValue() << 4) |
25614                   first.Encode(22, 12) | (len_encoding << 8) |
25615                   (rn.GetCode() << 16));
25616           return;
25617         }
25618       }
25619       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
25620       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25621           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25622            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25623           operand.IsOffset() && encoded_align_2.IsValid() &&
25624           (!rn.IsPC() || AllowUnpredictable())) {
25625         if (cond.Is(al)) {
25626           const DRegister& first = nreglist.GetFirstDRegister();
25627           EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) |
25628                   (encoded_align_2.GetEncodingValue() << 4) |
25629                   first.Encode(22, 12) | (rn.GetCode() << 16));
25630           return;
25631         }
25632       }
25633       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
25634       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25635           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25636            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25637           operand.IsPostIndex() && encoded_align_2.IsValid() &&
25638           (!rn.IsPC() || AllowUnpredictable())) {
25639         if (cond.Is(al)) {
25640           const DRegister& first = nreglist.GetFirstDRegister();
25641           EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) |
25642                   (encoded_align_2.GetEncodingValue() << 4) |
25643                   first.Encode(22, 12) | (rn.GetCode() << 16));
25644           return;
25645         }
25646       }
25647     }
25648   }
25649   if (operand.IsPlainRegister()) {
25650     Register rn = operand.GetBaseRegister();
25651     Alignment align = operand.GetAlignment();
25652     Register rm = operand.GetOffsetRegister();
25653     Dt_size_7 encoded_dt(dt);
25654     Align_align_4 encoded_align_1(align);
25655     Align_index_align_3 encoded_align_2(align, nreglist, dt);
25656     if (IsUsingT32()) {
25657       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25658       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25659           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25660            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25661           !rm.IsPC() && !rm.IsSP()) {
25662         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25663           const DRegister& first = nreglist.GetFirstDRegister();
25664           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25665           EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
25666                      (encoded_align_1.GetEncodingValue() << 4) |
25667                      first.Encode(22, 12) | (len_encoding << 8) |
25668                      (rn.GetCode() << 16) | rm.GetCode());
25669           AdvanceIT();
25670           return;
25671         }
25672       }
25673       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
25674       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25675           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25676            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25677           !rm.IsPC() && !rm.IsSP()) {
25678         if (cond.Is(al) || AllowStronglyDiscouraged()) {
25679           const DRegister& first = nreglist.GetFirstDRegister();
25680           EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) |
25681                      (encoded_align_2.GetEncodingValue() << 4) |
25682                      first.Encode(22, 12) | (rn.GetCode() << 16) |
25683                      rm.GetCode());
25684           AdvanceIT();
25685           return;
25686         }
25687       }
25688     } else {
25689       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25690       if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
25691           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25692            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25693           !rm.IsPC() && !rm.IsSP()) {
25694         if (cond.Is(al)) {
25695           const DRegister& first = nreglist.GetFirstDRegister();
25696           uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
25697           EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
25698                   (encoded_align_1.GetEncodingValue() << 4) |
25699                   first.Encode(22, 12) | (len_encoding << 8) |
25700                   (rn.GetCode() << 16) | rm.GetCode());
25701           return;
25702         }
25703       }
25704       // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
25705       if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
25706           ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
25707            (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
25708           !rm.IsPC() && !rm.IsSP()) {
25709         if (cond.Is(al)) {
25710           const DRegister& first = nreglist.GetFirstDRegister();
25711           EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) |
25712                   (encoded_align_2.GetEncodingValue() << 4) |
25713                   first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
25714           return;
25715         }
25716       }
25717     }
25718   }
25719   Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand);
25720 }
25721 
vstm(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)25722 void Assembler::vstm(Condition cond,
25723                      DataType dt,
25724                      Register rn,
25725                      WriteBack write_back,
25726                      DRegisterList dreglist) {
25727   VIXL_ASSERT(AllowAssembler());
25728   CheckIT(cond);
25729   USE(dt);
25730   if (IsUsingT32()) {
25731     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
25732     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25733       const DRegister& dreg = dreglist.GetFirstDRegister();
25734       unsigned len = dreglist.GetLength() * 2;
25735       EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
25736                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25737                  (len & 0xff));
25738       AdvanceIT();
25739       return;
25740     }
25741   } else {
25742     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
25743     if (cond.IsNotNever() &&
25744         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25745       const DRegister& dreg = dreglist.GetFirstDRegister();
25746       unsigned len = dreglist.GetLength() * 2;
25747       EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25748               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25749               (len & 0xff));
25750       return;
25751     }
25752   }
25753   Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist);
25754 }
25755 
vstm(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)25756 void Assembler::vstm(Condition cond,
25757                      DataType dt,
25758                      Register rn,
25759                      WriteBack write_back,
25760                      SRegisterList sreglist) {
25761   VIXL_ASSERT(AllowAssembler());
25762   CheckIT(cond);
25763   USE(dt);
25764   if (IsUsingT32()) {
25765     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
25766     const SRegister& sreg = sreglist.GetFirstSRegister();
25767     unsigned len = sreglist.GetLength();
25768     EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
25769                (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25770                (len & 0xff));
25771     AdvanceIT();
25772     return;
25773   } else {
25774     // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
25775     if (cond.IsNotNever()) {
25776       const SRegister& sreg = sreglist.GetFirstSRegister();
25777       unsigned len = sreglist.GetLength();
25778       EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25779               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25780               (len & 0xff));
25781       return;
25782     }
25783   }
25784   Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist);
25785 }
25786 
vstmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)25787 void Assembler::vstmdb(Condition cond,
25788                        DataType dt,
25789                        Register rn,
25790                        WriteBack write_back,
25791                        DRegisterList dreglist) {
25792   VIXL_ASSERT(AllowAssembler());
25793   CheckIT(cond);
25794   USE(dt);
25795   if (IsUsingT32()) {
25796     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
25797     if (write_back.DoesWriteBack() &&
25798         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25799       const DRegister& dreg = dreglist.GetFirstDRegister();
25800       unsigned len = dreglist.GetLength() * 2;
25801       EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
25802                  (len & 0xff));
25803       AdvanceIT();
25804       return;
25805     }
25806   } else {
25807     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
25808     if (write_back.DoesWriteBack() && cond.IsNotNever() &&
25809         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25810       const DRegister& dreg = dreglist.GetFirstDRegister();
25811       unsigned len = dreglist.GetLength() * 2;
25812       EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25813               dreg.Encode(22, 12) | (len & 0xff));
25814       return;
25815     }
25816   }
25817   Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist);
25818 }
25819 
vstmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)25820 void Assembler::vstmdb(Condition cond,
25821                        DataType dt,
25822                        Register rn,
25823                        WriteBack write_back,
25824                        SRegisterList sreglist) {
25825   VIXL_ASSERT(AllowAssembler());
25826   CheckIT(cond);
25827   USE(dt);
25828   if (IsUsingT32()) {
25829     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
25830     if (write_back.DoesWriteBack()) {
25831       const SRegister& sreg = sreglist.GetFirstSRegister();
25832       unsigned len = sreglist.GetLength();
25833       EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
25834                  (len & 0xff));
25835       AdvanceIT();
25836       return;
25837     }
25838   } else {
25839     // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
25840     if (write_back.DoesWriteBack() && cond.IsNotNever()) {
25841       const SRegister& sreg = sreglist.GetFirstSRegister();
25842       unsigned len = sreglist.GetLength();
25843       EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25844               sreg.Encode(22, 12) | (len & 0xff));
25845       return;
25846     }
25847   }
25848   Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist);
25849 }
25850 
vstmia(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)25851 void Assembler::vstmia(Condition cond,
25852                        DataType dt,
25853                        Register rn,
25854                        WriteBack write_back,
25855                        DRegisterList dreglist) {
25856   VIXL_ASSERT(AllowAssembler());
25857   CheckIT(cond);
25858   USE(dt);
25859   if (IsUsingT32()) {
25860     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
25861     if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25862       const DRegister& dreg = dreglist.GetFirstDRegister();
25863       unsigned len = dreglist.GetLength() * 2;
25864       EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
25865                  (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25866                  (len & 0xff));
25867       AdvanceIT();
25868       return;
25869     }
25870   } else {
25871     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
25872     if (cond.IsNotNever() &&
25873         ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
25874       const DRegister& dreg = dreglist.GetFirstDRegister();
25875       unsigned len = dreglist.GetLength() * 2;
25876       EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25877               (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
25878               (len & 0xff));
25879       return;
25880     }
25881   }
25882   Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist);
25883 }
25884 
vstmia(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)25885 void Assembler::vstmia(Condition cond,
25886                        DataType dt,
25887                        Register rn,
25888                        WriteBack write_back,
25889                        SRegisterList sreglist) {
25890   VIXL_ASSERT(AllowAssembler());
25891   CheckIT(cond);
25892   USE(dt);
25893   if (IsUsingT32()) {
25894     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
25895     const SRegister& sreg = sreglist.GetFirstSRegister();
25896     unsigned len = sreglist.GetLength();
25897     EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
25898                (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25899                (len & 0xff));
25900     AdvanceIT();
25901     return;
25902   } else {
25903     // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
25904     if (cond.IsNotNever()) {
25905       const SRegister& sreg = sreglist.GetFirstSRegister();
25906       unsigned len = sreglist.GetLength();
25907       EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
25908               (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
25909               (len & 0xff));
25910       return;
25911     }
25912   }
25913   Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist);
25914 }
25915 
vstr(Condition cond,DataType dt,DRegister rd,const MemOperand & operand)25916 void Assembler::vstr(Condition cond,
25917                      DataType dt,
25918                      DRegister rd,
25919                      const MemOperand& operand) {
25920   VIXL_ASSERT(AllowAssembler());
25921   CheckIT(cond);
25922   if (operand.IsImmediate()) {
25923     Register rn = operand.GetBaseRegister();
25924     int32_t offset = operand.GetOffsetImmediate();
25925     if (IsUsingT32()) {
25926       // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
25927       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
25928           ((offset % 4) == 0) && operand.IsOffset()) {
25929         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25930         uint32_t offset_ = abs(offset) >> 2;
25931         EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
25932                    offset_ | (sign << 23));
25933         AdvanceIT();
25934         return;
25935       }
25936     } else {
25937       // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
25938       if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
25939           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
25940         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25941         uint32_t offset_ = abs(offset) >> 2;
25942         EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25943                 (rn.GetCode() << 16) | offset_ | (sign << 23));
25944         return;
25945       }
25946     }
25947   }
25948   Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
25949 }
25950 
vstr(Condition cond,DataType dt,SRegister rd,const MemOperand & operand)25951 void Assembler::vstr(Condition cond,
25952                      DataType dt,
25953                      SRegister rd,
25954                      const MemOperand& operand) {
25955   VIXL_ASSERT(AllowAssembler());
25956   CheckIT(cond);
25957   if (operand.IsImmediate()) {
25958     Register rn = operand.GetBaseRegister();
25959     int32_t offset = operand.GetOffsetImmediate();
25960     if (IsUsingT32()) {
25961       // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
25962       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
25963           ((offset % 4) == 0) && operand.IsOffset()) {
25964         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25965         uint32_t offset_ = abs(offset) >> 2;
25966         EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
25967                    offset_ | (sign << 23));
25968         AdvanceIT();
25969         return;
25970       }
25971     } else {
25972       // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
25973       if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
25974           ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
25975         uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
25976         uint32_t offset_ = abs(offset) >> 2;
25977         EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25978                 (rn.GetCode() << 16) | offset_ | (sign << 23));
25979         return;
25980       }
25981     }
25982   }
25983   Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
25984 }
25985 
vsub(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)25986 void Assembler::vsub(
25987     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25988   VIXL_ASSERT(AllowAssembler());
25989   CheckIT(cond);
25990   Dt_size_2 encoded_dt(dt);
25991   if (IsUsingT32()) {
25992     // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
25993     if (dt.Is(F32)) {
25994       if (cond.Is(al) || AllowStronglyDiscouraged()) {
25995         EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25996                    rm.Encode(5, 0));
25997         AdvanceIT();
25998         return;
25999       }
26000     }
26001     // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
26002     if (dt.Is(F64)) {
26003       EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26004                  rm.Encode(5, 0));
26005       AdvanceIT();
26006       return;
26007     }
26008     // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
26009     if (encoded_dt.IsValid()) {
26010       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26011         EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) |
26012                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26013         AdvanceIT();
26014         return;
26015       }
26016     }
26017   } else {
26018     // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
26019     if (dt.Is(F32)) {
26020       if (cond.Is(al)) {
26021         EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26022                 rm.Encode(5, 0));
26023         return;
26024       }
26025     }
26026     // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
26027     if (dt.Is(F64) && cond.IsNotNever()) {
26028       EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
26029               rn.Encode(7, 16) | rm.Encode(5, 0));
26030       return;
26031     }
26032     // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
26033     if (encoded_dt.IsValid()) {
26034       if (cond.Is(al)) {
26035         EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) |
26036                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26037         return;
26038       }
26039     }
26040   }
26041   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
26042 }
26043 
vsub(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)26044 void Assembler::vsub(
26045     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
26046   VIXL_ASSERT(AllowAssembler());
26047   CheckIT(cond);
26048   Dt_size_2 encoded_dt(dt);
26049   if (IsUsingT32()) {
26050     // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
26051     if (dt.Is(F32)) {
26052       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26053         EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26054                    rm.Encode(5, 0));
26055         AdvanceIT();
26056         return;
26057       }
26058     }
26059     // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
26060     if (encoded_dt.IsValid()) {
26061       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26062         EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) |
26063                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26064         AdvanceIT();
26065         return;
26066       }
26067     }
26068   } else {
26069     // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
26070     if (dt.Is(F32)) {
26071       if (cond.Is(al)) {
26072         EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26073                 rm.Encode(5, 0));
26074         return;
26075       }
26076     }
26077     // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
26078     if (encoded_dt.IsValid()) {
26079       if (cond.Is(al)) {
26080         EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) |
26081                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26082         return;
26083       }
26084     }
26085   }
26086   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
26087 }
26088 
vsub(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)26089 void Assembler::vsub(
26090     Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
26091   VIXL_ASSERT(AllowAssembler());
26092   CheckIT(cond);
26093   if (IsUsingT32()) {
26094     // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
26095     if (dt.Is(F32)) {
26096       EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
26097                  rm.Encode(5, 0));
26098       AdvanceIT();
26099       return;
26100     }
26101   } else {
26102     // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
26103     if (dt.Is(F32) && cond.IsNotNever()) {
26104       EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
26105               rn.Encode(7, 16) | rm.Encode(5, 0));
26106       return;
26107     }
26108   }
26109   Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
26110 }
26111 
vsubhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)26112 void Assembler::vsubhn(
26113     Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
26114   VIXL_ASSERT(AllowAssembler());
26115   CheckIT(cond);
26116   Dt_size_3 encoded_dt(dt);
26117   if (IsUsingT32()) {
26118     // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
26119     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
26120       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26121         EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) |
26122                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26123         AdvanceIT();
26124         return;
26125       }
26126     }
26127   } else {
26128     // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
26129     if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
26130       if (cond.Is(al)) {
26131         EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) |
26132                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26133         return;
26134       }
26135     }
26136   }
26137   Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm);
26138 }
26139 
vsubl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)26140 void Assembler::vsubl(
26141     Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
26142   VIXL_ASSERT(AllowAssembler());
26143   CheckIT(cond);
26144   Dt_U_size_1 encoded_dt(dt);
26145   if (IsUsingT32()) {
26146     // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
26147     if (encoded_dt.IsValid()) {
26148       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26149         EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26150                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
26151                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26152         AdvanceIT();
26153         return;
26154       }
26155     }
26156   } else {
26157     // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
26158     if (encoded_dt.IsValid()) {
26159       if (cond.Is(al)) {
26160         EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26161                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
26162                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26163         return;
26164       }
26165     }
26166   }
26167   Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm);
26168 }
26169 
vsubw(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegister rm)26170 void Assembler::vsubw(
26171     Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
26172   VIXL_ASSERT(AllowAssembler());
26173   CheckIT(cond);
26174   Dt_U_size_1 encoded_dt(dt);
26175   if (IsUsingT32()) {
26176     // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
26177     if (encoded_dt.IsValid()) {
26178       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26179         EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26180                    ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
26181                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26182         AdvanceIT();
26183         return;
26184       }
26185     }
26186   } else {
26187     // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
26188     if (encoded_dt.IsValid()) {
26189       if (cond.Is(al)) {
26190         EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
26191                 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
26192                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26193         return;
26194       }
26195     }
26196   }
26197   Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm);
26198 }
26199 
vswp(Condition cond,DataType dt,DRegister rd,DRegister rm)26200 void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26201   VIXL_ASSERT(AllowAssembler());
26202   CheckIT(cond);
26203   USE(dt);
26204   if (IsUsingT32()) {
26205     // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
26206     if (cond.Is(al) || AllowStronglyDiscouraged()) {
26207       EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
26208       AdvanceIT();
26209       return;
26210     }
26211   } else {
26212     // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
26213     if (cond.Is(al)) {
26214       EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
26215       return;
26216     }
26217   }
26218   Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
26219 }
26220 
vswp(Condition cond,DataType dt,QRegister rd,QRegister rm)26221 void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26222   VIXL_ASSERT(AllowAssembler());
26223   CheckIT(cond);
26224   USE(dt);
26225   if (IsUsingT32()) {
26226     // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
26227     if (cond.Is(al) || AllowStronglyDiscouraged()) {
26228       EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
26229       AdvanceIT();
26230       return;
26231     }
26232   } else {
26233     // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
26234     if (cond.Is(al)) {
26235       EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
26236       return;
26237     }
26238   }
26239   Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
26240 }
26241 
vtbl(Condition cond,DataType dt,DRegister rd,const NeonRegisterList & nreglist,DRegister rm)26242 void Assembler::vtbl(Condition cond,
26243                      DataType dt,
26244                      DRegister rd,
26245                      const NeonRegisterList& nreglist,
26246                      DRegister rm) {
26247   VIXL_ASSERT(AllowAssembler());
26248   CheckIT(cond);
26249   if (IsUsingT32()) {
26250     // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
26251     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26252         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26253       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26254         const DRegister& first = nreglist.GetFirstDRegister();
26255         uint32_t len_encoding = nreglist.GetLength() - 1;
26256         EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
26257                    (len_encoding << 8) | rm.Encode(5, 0));
26258         AdvanceIT();
26259         return;
26260       }
26261     }
26262   } else {
26263     // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
26264     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26265         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26266       if (cond.Is(al)) {
26267         const DRegister& first = nreglist.GetFirstDRegister();
26268         uint32_t len_encoding = nreglist.GetLength() - 1;
26269         EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
26270                 (len_encoding << 8) | rm.Encode(5, 0));
26271         return;
26272       }
26273     }
26274   }
26275   Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm);
26276 }
26277 
vtbx(Condition cond,DataType dt,DRegister rd,const NeonRegisterList & nreglist,DRegister rm)26278 void Assembler::vtbx(Condition cond,
26279                      DataType dt,
26280                      DRegister rd,
26281                      const NeonRegisterList& nreglist,
26282                      DRegister rm) {
26283   VIXL_ASSERT(AllowAssembler());
26284   CheckIT(cond);
26285   if (IsUsingT32()) {
26286     // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
26287     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26288         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26289       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26290         const DRegister& first = nreglist.GetFirstDRegister();
26291         uint32_t len_encoding = nreglist.GetLength() - 1;
26292         EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
26293                    (len_encoding << 8) | rm.Encode(5, 0));
26294         AdvanceIT();
26295         return;
26296       }
26297     }
26298   } else {
26299     // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
26300     if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
26301         (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
26302       if (cond.Is(al)) {
26303         const DRegister& first = nreglist.GetFirstDRegister();
26304         uint32_t len_encoding = nreglist.GetLength() - 1;
26305         EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
26306                 (len_encoding << 8) | rm.Encode(5, 0));
26307         return;
26308       }
26309     }
26310   }
26311   Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm);
26312 }
26313 
vtrn(Condition cond,DataType dt,DRegister rd,DRegister rm)26314 void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26315   VIXL_ASSERT(AllowAssembler());
26316   CheckIT(cond);
26317   Dt_size_7 encoded_dt(dt);
26318   if (IsUsingT32()) {
26319     // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
26320     if (encoded_dt.IsValid()) {
26321       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26322         EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) |
26323                    rd.Encode(22, 12) | rm.Encode(5, 0));
26324         AdvanceIT();
26325         return;
26326       }
26327     }
26328   } else {
26329     // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
26330     if (encoded_dt.IsValid()) {
26331       if (cond.Is(al)) {
26332         EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) |
26333                 rd.Encode(22, 12) | rm.Encode(5, 0));
26334         return;
26335       }
26336     }
26337   }
26338   Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
26339 }
26340 
vtrn(Condition cond,DataType dt,QRegister rd,QRegister rm)26341 void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26342   VIXL_ASSERT(AllowAssembler());
26343   CheckIT(cond);
26344   Dt_size_7 encoded_dt(dt);
26345   if (IsUsingT32()) {
26346     // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
26347     if (encoded_dt.IsValid()) {
26348       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26349         EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) |
26350                    rd.Encode(22, 12) | rm.Encode(5, 0));
26351         AdvanceIT();
26352         return;
26353       }
26354     }
26355   } else {
26356     // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
26357     if (encoded_dt.IsValid()) {
26358       if (cond.Is(al)) {
26359         EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) |
26360                 rd.Encode(22, 12) | rm.Encode(5, 0));
26361         return;
26362       }
26363     }
26364   }
26365   Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
26366 }
26367 
vtst(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)26368 void Assembler::vtst(
26369     Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
26370   VIXL_ASSERT(AllowAssembler());
26371   CheckIT(cond);
26372   Dt_size_7 encoded_dt(dt);
26373   if (IsUsingT32()) {
26374     // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
26375     if (encoded_dt.IsValid()) {
26376       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26377         EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) |
26378                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26379         AdvanceIT();
26380         return;
26381       }
26382     }
26383   } else {
26384     // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
26385     if (encoded_dt.IsValid()) {
26386       if (cond.Is(al)) {
26387         EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) |
26388                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26389         return;
26390       }
26391     }
26392   }
26393   Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
26394 }
26395 
vtst(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)26396 void Assembler::vtst(
26397     Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
26398   VIXL_ASSERT(AllowAssembler());
26399   CheckIT(cond);
26400   Dt_size_7 encoded_dt(dt);
26401   if (IsUsingT32()) {
26402     // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
26403     if (encoded_dt.IsValid()) {
26404       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26405         EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) |
26406                    rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26407         AdvanceIT();
26408         return;
26409       }
26410     }
26411   } else {
26412     // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
26413     if (encoded_dt.IsValid()) {
26414       if (cond.Is(al)) {
26415         EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) |
26416                 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
26417         return;
26418       }
26419     }
26420   }
26421   Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
26422 }
26423 
vuzp(Condition cond,DataType dt,DRegister rd,DRegister rm)26424 void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26425   VIXL_ASSERT(AllowAssembler());
26426   CheckIT(cond);
26427   Dt_size_15 encoded_dt(dt);
26428   if (IsUsingT32()) {
26429     // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
26430     if (encoded_dt.IsValid()) {
26431       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26432         EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) |
26433                    rd.Encode(22, 12) | rm.Encode(5, 0));
26434         AdvanceIT();
26435         return;
26436       }
26437     }
26438     // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
26439     if (dt.Is(Untyped32)) {
26440       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26441         EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26442         AdvanceIT();
26443         return;
26444       }
26445     }
26446   } else {
26447     // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
26448     if (encoded_dt.IsValid()) {
26449       if (cond.Is(al)) {
26450         EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) |
26451                 rd.Encode(22, 12) | rm.Encode(5, 0));
26452         return;
26453       }
26454     }
26455     // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
26456     if (dt.Is(Untyped32)) {
26457       if (cond.Is(al)) {
26458         EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26459         return;
26460       }
26461     }
26462   }
26463   Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
26464 }
26465 
vuzp(Condition cond,DataType dt,QRegister rd,QRegister rm)26466 void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26467   VIXL_ASSERT(AllowAssembler());
26468   CheckIT(cond);
26469   Dt_size_7 encoded_dt(dt);
26470   if (IsUsingT32()) {
26471     // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
26472     if (encoded_dt.IsValid()) {
26473       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26474         EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) |
26475                    rd.Encode(22, 12) | rm.Encode(5, 0));
26476         AdvanceIT();
26477         return;
26478       }
26479     }
26480   } else {
26481     // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
26482     if (encoded_dt.IsValid()) {
26483       if (cond.Is(al)) {
26484         EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) |
26485                 rd.Encode(22, 12) | rm.Encode(5, 0));
26486         return;
26487       }
26488     }
26489   }
26490   Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
26491 }
26492 
vzip(Condition cond,DataType dt,DRegister rd,DRegister rm)26493 void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) {
26494   VIXL_ASSERT(AllowAssembler());
26495   CheckIT(cond);
26496   Dt_size_15 encoded_dt(dt);
26497   if (IsUsingT32()) {
26498     // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
26499     if (encoded_dt.IsValid()) {
26500       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26501         EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) |
26502                    rd.Encode(22, 12) | rm.Encode(5, 0));
26503         AdvanceIT();
26504         return;
26505       }
26506     }
26507     // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
26508     if (dt.Is(Untyped32)) {
26509       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26510         EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26511         AdvanceIT();
26512         return;
26513       }
26514     }
26515   } else {
26516     // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
26517     if (encoded_dt.IsValid()) {
26518       if (cond.Is(al)) {
26519         EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) |
26520                 rd.Encode(22, 12) | rm.Encode(5, 0));
26521         return;
26522       }
26523     }
26524     // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
26525     if (dt.Is(Untyped32)) {
26526       if (cond.Is(al)) {
26527         EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
26528         return;
26529       }
26530     }
26531   }
26532   Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
26533 }
26534 
vzip(Condition cond,DataType dt,QRegister rd,QRegister rm)26535 void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) {
26536   VIXL_ASSERT(AllowAssembler());
26537   CheckIT(cond);
26538   Dt_size_7 encoded_dt(dt);
26539   if (IsUsingT32()) {
26540     // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
26541     if (encoded_dt.IsValid()) {
26542       if (cond.Is(al) || AllowStronglyDiscouraged()) {
26543         EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) |
26544                    rd.Encode(22, 12) | rm.Encode(5, 0));
26545         AdvanceIT();
26546         return;
26547       }
26548     }
26549   } else {
26550     // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
26551     if (encoded_dt.IsValid()) {
26552       if (cond.Is(al)) {
26553         EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) |
26554                 rd.Encode(22, 12) | rm.Encode(5, 0));
26555         return;
26556       }
26557     }
26558   }
26559   Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
26560 }
26561 
yield(Condition cond,EncodingSize size)26562 void Assembler::yield(Condition cond, EncodingSize size) {
26563   VIXL_ASSERT(AllowAssembler());
26564   CheckIT(cond);
26565   if (IsUsingT32()) {
26566     // YIELD{<c>}{<q>} ; T1
26567     if (!size.IsWide()) {
26568       EmitT32_16(0xbf10);
26569       AdvanceIT();
26570       return;
26571     }
26572     // YIELD{<c>}.W ; T2
26573     if (!size.IsNarrow()) {
26574       EmitT32_32(0xf3af8001U);
26575       AdvanceIT();
26576       return;
26577     }
26578   } else {
26579     // YIELD{<c>}{<q>} ; A1
26580     if (cond.IsNotNever()) {
26581       EmitA32(0x0320f001U | (cond.GetCondition() << 28));
26582       return;
26583     }
26584   }
26585   Delegate(kYield, &Assembler::yield, cond, size);
26586 }
26587 // End of generated code.
26588 
26589 }  // namespace aarch32
26590 }  // namespace vixl
26591