1 // Copyright 2017, VIXL authors
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright notice,
8 // this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright notice,
10 // this list of conditions and the following disclaimer in the documentation
11 // and/or other materials provided with the distribution.
12 // * Neither the name of ARM Limited nor the names of its contributors may be
13 // used to endorse or promote products derived from this software without
14 // specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 extern "C" {
28 #include <stdint.h>
29 }
30
31 #include <cassert>
32 #include <cstdio>
33 #include <cstdlib>
34 #include <cstring>
35 #include <iostream>
36
37 #include "utils-vixl.h"
38 #include "aarch32/assembler-aarch32.h"
39 #include "aarch32/constants-aarch32.h"
40 #include "aarch32/instructions-aarch32.h"
41 #include "aarch32/operands-aarch32.h"
42
43 namespace vixl {
44 namespace aarch32 {
45
EmitT32_16(uint16_t instr)46 void Assembler::EmitT32_16(uint16_t instr) {
47 VIXL_ASSERT(buffer_.Is16bitAligned());
48 buffer_.Emit16(instr);
49 }
50
51
EmitT32_32(uint32_t instr)52 void Assembler::EmitT32_32(uint32_t instr) {
53 VIXL_ASSERT(buffer_.Is16bitAligned());
54 buffer_.Emit16(static_cast<uint16_t>(instr >> 16));
55 buffer_.Emit16(static_cast<uint16_t>(instr & 0xffff));
56 }
57
58
EmitA32(uint32_t instr)59 void Assembler::EmitA32(uint32_t instr) {
60 VIXL_ASSERT(buffer_.Is32bitAligned());
61 buffer_.Emit32(instr);
62 }
63
64
65 #ifdef VIXL_DEBUG
PerformCheckIT(Condition condition)66 void Assembler::PerformCheckIT(Condition condition) {
67 if (it_mask_ == 0) {
68 VIXL_ASSERT(IsUsingA32() || condition.Is(al));
69 } else {
70 VIXL_ASSERT(condition.Is(first_condition_));
71 // For A32, AdavanceIT() is not called by the assembler. We must call it
72 // in order to check that IT instructions are used consistently with
73 // the following conditional instructions.
74 if (IsUsingA32()) AdvanceIT();
75 }
76 }
77 #endif
78
79
BindHelper(Label * label)80 void Assembler::BindHelper(Label* label) {
81 VIXL_ASSERT(!label->IsBound());
82 label->SetLocation(this, GetCursorOffset());
83 label->MarkBound();
84 }
85
Link(uint32_t instr,Location * location,const Location::EmitOperator & op,const ReferenceInfo * info)86 uint32_t Assembler::Link(uint32_t instr,
87 Location* location,
88 const Location::EmitOperator& op,
89 const ReferenceInfo* info) {
90 location->SetReferenced();
91 if (location->IsBound()) {
92 return op.Encode(instr, GetCursorOffset(), location);
93 }
94 location->AddForwardRef(GetCursorOffset(), op, info);
95 return instr;
96 }
97
98
99 // Start of generated code.
100 class Dt_L_imm6_1 : public EncodingValue {
101 uint32_t type_;
102
103 public:
104 explicit Dt_L_imm6_1(DataType dt);
GetTypeEncodingValue() const105 uint32_t GetTypeEncodingValue() const { return type_; }
106 };
107
Dt_L_imm6_1(DataType dt)108 Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) {
109 switch (dt.GetValue()) {
110 case S8:
111 type_ = 0x0;
112 SetEncodingValue(0x1);
113 break;
114 case U8:
115 type_ = 0x1;
116 SetEncodingValue(0x1);
117 break;
118 case S16:
119 type_ = 0x0;
120 SetEncodingValue(0x2);
121 break;
122 case U16:
123 type_ = 0x1;
124 SetEncodingValue(0x2);
125 break;
126 case S32:
127 type_ = 0x0;
128 SetEncodingValue(0x4);
129 break;
130 case U32:
131 type_ = 0x1;
132 SetEncodingValue(0x4);
133 break;
134 case S64:
135 type_ = 0x0;
136 SetEncodingValue(0x8);
137 break;
138 case U64:
139 type_ = 0x1;
140 SetEncodingValue(0x8);
141 break;
142 default:
143 VIXL_UNREACHABLE();
144 type_ = 0x0;
145 break;
146 }
147 }
148
149 class Dt_L_imm6_2 : public EncodingValue {
150 uint32_t type_;
151
152 public:
153 explicit Dt_L_imm6_2(DataType dt);
GetTypeEncodingValue() const154 uint32_t GetTypeEncodingValue() const { return type_; }
155 };
156
Dt_L_imm6_2(DataType dt)157 Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) {
158 switch (dt.GetValue()) {
159 case S8:
160 type_ = 0x1;
161 SetEncodingValue(0x1);
162 break;
163 case S16:
164 type_ = 0x1;
165 SetEncodingValue(0x2);
166 break;
167 case S32:
168 type_ = 0x1;
169 SetEncodingValue(0x4);
170 break;
171 case S64:
172 type_ = 0x1;
173 SetEncodingValue(0x8);
174 break;
175 default:
176 VIXL_UNREACHABLE();
177 type_ = 0x0;
178 break;
179 }
180 }
181
182 class Dt_L_imm6_3 : public EncodingValue {
183 public:
184 explicit Dt_L_imm6_3(DataType dt);
185 };
186
Dt_L_imm6_3(DataType dt)187 Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) {
188 switch (dt.GetValue()) {
189 case I8:
190 SetEncodingValue(0x1);
191 break;
192 case I16:
193 SetEncodingValue(0x2);
194 break;
195 case I32:
196 SetEncodingValue(0x4);
197 break;
198 case I64:
199 SetEncodingValue(0x8);
200 break;
201 default:
202 break;
203 }
204 }
205
206 class Dt_L_imm6_4 : public EncodingValue {
207 public:
208 explicit Dt_L_imm6_4(DataType dt);
209 };
210
Dt_L_imm6_4(DataType dt)211 Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) {
212 switch (dt.GetValue()) {
213 case Untyped8:
214 SetEncodingValue(0x1);
215 break;
216 case Untyped16:
217 SetEncodingValue(0x2);
218 break;
219 case Untyped32:
220 SetEncodingValue(0x4);
221 break;
222 case Untyped64:
223 SetEncodingValue(0x8);
224 break;
225 default:
226 break;
227 }
228 }
229
230 class Dt_imm6_1 : public EncodingValue {
231 uint32_t type_;
232
233 public:
234 explicit Dt_imm6_1(DataType dt);
GetTypeEncodingValue() const235 uint32_t GetTypeEncodingValue() const { return type_; }
236 };
237
Dt_imm6_1(DataType dt)238 Dt_imm6_1::Dt_imm6_1(DataType dt) {
239 switch (dt.GetValue()) {
240 case S16:
241 type_ = 0x0;
242 SetEncodingValue(0x1);
243 break;
244 case U16:
245 type_ = 0x1;
246 SetEncodingValue(0x1);
247 break;
248 case S32:
249 type_ = 0x0;
250 SetEncodingValue(0x2);
251 break;
252 case U32:
253 type_ = 0x1;
254 SetEncodingValue(0x2);
255 break;
256 case S64:
257 type_ = 0x0;
258 SetEncodingValue(0x4);
259 break;
260 case U64:
261 type_ = 0x1;
262 SetEncodingValue(0x4);
263 break;
264 default:
265 VIXL_UNREACHABLE();
266 type_ = 0x0;
267 break;
268 }
269 }
270
271 class Dt_imm6_2 : public EncodingValue {
272 uint32_t type_;
273
274 public:
275 explicit Dt_imm6_2(DataType dt);
GetTypeEncodingValue() const276 uint32_t GetTypeEncodingValue() const { return type_; }
277 };
278
Dt_imm6_2(DataType dt)279 Dt_imm6_2::Dt_imm6_2(DataType dt) {
280 switch (dt.GetValue()) {
281 case S16:
282 type_ = 0x1;
283 SetEncodingValue(0x1);
284 break;
285 case S32:
286 type_ = 0x1;
287 SetEncodingValue(0x2);
288 break;
289 case S64:
290 type_ = 0x1;
291 SetEncodingValue(0x4);
292 break;
293 default:
294 VIXL_UNREACHABLE();
295 type_ = 0x0;
296 break;
297 }
298 }
299
300 class Dt_imm6_3 : public EncodingValue {
301 public:
302 explicit Dt_imm6_3(DataType dt);
303 };
304
Dt_imm6_3(DataType dt)305 Dt_imm6_3::Dt_imm6_3(DataType dt) {
306 switch (dt.GetValue()) {
307 case I16:
308 SetEncodingValue(0x1);
309 break;
310 case I32:
311 SetEncodingValue(0x2);
312 break;
313 case I64:
314 SetEncodingValue(0x4);
315 break;
316 default:
317 break;
318 }
319 }
320
321 class Dt_imm6_4 : public EncodingValue {
322 uint32_t type_;
323
324 public:
325 explicit Dt_imm6_4(DataType dt);
GetTypeEncodingValue() const326 uint32_t GetTypeEncodingValue() const { return type_; }
327 };
328
Dt_imm6_4(DataType dt)329 Dt_imm6_4::Dt_imm6_4(DataType dt) {
330 switch (dt.GetValue()) {
331 case S8:
332 type_ = 0x0;
333 SetEncodingValue(0x1);
334 break;
335 case U8:
336 type_ = 0x1;
337 SetEncodingValue(0x1);
338 break;
339 case S16:
340 type_ = 0x0;
341 SetEncodingValue(0x2);
342 break;
343 case U16:
344 type_ = 0x1;
345 SetEncodingValue(0x2);
346 break;
347 case S32:
348 type_ = 0x0;
349 SetEncodingValue(0x4);
350 break;
351 case U32:
352 type_ = 0x1;
353 SetEncodingValue(0x4);
354 break;
355 default:
356 VIXL_UNREACHABLE();
357 type_ = 0x0;
358 break;
359 }
360 }
361
362 class Dt_op_U_size_1 : public EncodingValue {
363 public:
364 explicit Dt_op_U_size_1(DataType dt);
365 };
366
Dt_op_U_size_1(DataType dt)367 Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) {
368 switch (dt.GetValue()) {
369 case S8:
370 SetEncodingValue(0x0);
371 break;
372 case S16:
373 SetEncodingValue(0x1);
374 break;
375 case S32:
376 SetEncodingValue(0x2);
377 break;
378 case U8:
379 SetEncodingValue(0x4);
380 break;
381 case U16:
382 SetEncodingValue(0x5);
383 break;
384 case U32:
385 SetEncodingValue(0x6);
386 break;
387 case P8:
388 SetEncodingValue(0x8);
389 break;
390 case P64:
391 SetEncodingValue(0xa);
392 break;
393 default:
394 break;
395 }
396 }
397
398 class Dt_op_size_1 : public EncodingValue {
399 public:
400 explicit Dt_op_size_1(DataType dt);
401 };
402
Dt_op_size_1(DataType dt)403 Dt_op_size_1::Dt_op_size_1(DataType dt) {
404 switch (dt.GetValue()) {
405 case I8:
406 SetEncodingValue(0x0);
407 break;
408 case I16:
409 SetEncodingValue(0x1);
410 break;
411 case I32:
412 SetEncodingValue(0x2);
413 break;
414 case P8:
415 SetEncodingValue(0x4);
416 break;
417 default:
418 break;
419 }
420 }
421
422 class Dt_op_size_2 : public EncodingValue {
423 public:
424 explicit Dt_op_size_2(DataType dt);
425 };
426
Dt_op_size_2(DataType dt)427 Dt_op_size_2::Dt_op_size_2(DataType dt) {
428 switch (dt.GetValue()) {
429 case S8:
430 SetEncodingValue(0x0);
431 break;
432 case S16:
433 SetEncodingValue(0x1);
434 break;
435 case S32:
436 SetEncodingValue(0x2);
437 break;
438 case U8:
439 SetEncodingValue(0x4);
440 break;
441 case U16:
442 SetEncodingValue(0x5);
443 break;
444 case U32:
445 SetEncodingValue(0x6);
446 break;
447 default:
448 break;
449 }
450 }
451
452 class Dt_op_size_3 : public EncodingValue {
453 public:
454 explicit Dt_op_size_3(DataType dt);
455 };
456
Dt_op_size_3(DataType dt)457 Dt_op_size_3::Dt_op_size_3(DataType dt) {
458 switch (dt.GetValue()) {
459 case S16:
460 SetEncodingValue(0x0);
461 break;
462 case S32:
463 SetEncodingValue(0x1);
464 break;
465 case S64:
466 SetEncodingValue(0x2);
467 break;
468 case U16:
469 SetEncodingValue(0x4);
470 break;
471 case U32:
472 SetEncodingValue(0x5);
473 break;
474 case U64:
475 SetEncodingValue(0x6);
476 break;
477 default:
478 break;
479 }
480 }
481
482 class Dt_U_imm3H_1 : public EncodingValue {
483 public:
484 explicit Dt_U_imm3H_1(DataType dt);
485 };
486
Dt_U_imm3H_1(DataType dt)487 Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) {
488 switch (dt.GetValue()) {
489 case S8:
490 SetEncodingValue(0x1);
491 break;
492 case S16:
493 SetEncodingValue(0x2);
494 break;
495 case S32:
496 SetEncodingValue(0x4);
497 break;
498 case U8:
499 SetEncodingValue(0x9);
500 break;
501 case U16:
502 SetEncodingValue(0xa);
503 break;
504 case U32:
505 SetEncodingValue(0xc);
506 break;
507 default:
508 break;
509 }
510 }
511
512 class Dt_U_opc1_opc2_1 : public EncodingValue {
513 public:
514 explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
515 };
516
Dt_U_opc1_opc2_1(DataType dt,const DRegisterLane & lane)517 Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
518 switch (dt.GetValue()) {
519 case S8:
520 if ((lane.GetLane() & 7) != lane.GetLane()) {
521 return;
522 }
523 SetEncodingValue(0x8 | lane.GetLane());
524 break;
525 case S16:
526 if ((lane.GetLane() & 3) != lane.GetLane()) {
527 return;
528 }
529 SetEncodingValue(0x1 | (lane.GetLane() << 1));
530 break;
531 case U8:
532 if ((lane.GetLane() & 7) != lane.GetLane()) {
533 return;
534 }
535 SetEncodingValue(0x18 | lane.GetLane());
536 break;
537 case U16:
538 if ((lane.GetLane() & 3) != lane.GetLane()) {
539 return;
540 }
541 SetEncodingValue(0x11 | (lane.GetLane() << 1));
542 break;
543 case Untyped32:
544 if ((lane.GetLane() & 1) != lane.GetLane()) {
545 return;
546 }
547 SetEncodingValue(0x0 | (lane.GetLane() << 2));
548 break;
549 case kDataTypeValueNone:
550 if ((lane.GetLane() & 1) != lane.GetLane()) {
551 return;
552 }
553 SetEncodingValue(0x0 | (lane.GetLane() << 2));
554 break;
555 default:
556 break;
557 }
558 }
559
560 class Dt_opc1_opc2_1 : public EncodingValue {
561 public:
562 explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane);
563 };
564
Dt_opc1_opc2_1(DataType dt,const DRegisterLane & lane)565 Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) {
566 switch (dt.GetValue()) {
567 case Untyped8:
568 if ((lane.GetLane() & 7) != lane.GetLane()) {
569 return;
570 }
571 SetEncodingValue(0x8 | lane.GetLane());
572 break;
573 case Untyped16:
574 if ((lane.GetLane() & 3) != lane.GetLane()) {
575 return;
576 }
577 SetEncodingValue(0x1 | (lane.GetLane() << 1));
578 break;
579 case Untyped32:
580 if ((lane.GetLane() & 1) != lane.GetLane()) {
581 return;
582 }
583 SetEncodingValue(0x0 | (lane.GetLane() << 2));
584 break;
585 case kDataTypeValueNone:
586 if ((lane.GetLane() & 1) != lane.GetLane()) {
587 return;
588 }
589 SetEncodingValue(0x0 | (lane.GetLane() << 2));
590 break;
591 default:
592 break;
593 }
594 }
595
596 class Dt_imm4_1 : public EncodingValue {
597 public:
598 explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane);
599 };
600
Dt_imm4_1(DataType dt,const DRegisterLane & lane)601 Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) {
602 switch (dt.GetValue()) {
603 case Untyped8:
604 if ((lane.GetLane() & 7) != lane.GetLane()) {
605 return;
606 }
607 SetEncodingValue(0x1 | (lane.GetLane() << 1));
608 break;
609 case Untyped16:
610 if ((lane.GetLane() & 3) != lane.GetLane()) {
611 return;
612 }
613 SetEncodingValue(0x2 | (lane.GetLane() << 2));
614 break;
615 case Untyped32:
616 if ((lane.GetLane() & 1) != lane.GetLane()) {
617 return;
618 }
619 SetEncodingValue(0x4 | (lane.GetLane() << 3));
620 break;
621 default:
622 break;
623 }
624 }
625
626 class Dt_B_E_1 : public EncodingValue {
627 public:
628 explicit Dt_B_E_1(DataType dt);
629 };
630
Dt_B_E_1(DataType dt)631 Dt_B_E_1::Dt_B_E_1(DataType dt) {
632 switch (dt.GetValue()) {
633 case Untyped8:
634 SetEncodingValue(0x2);
635 break;
636 case Untyped16:
637 SetEncodingValue(0x1);
638 break;
639 case Untyped32:
640 SetEncodingValue(0x0);
641 break;
642 default:
643 break;
644 }
645 }
646
647 class Dt_op_1 : public EncodingValue {
648 public:
649 Dt_op_1(DataType dt1, DataType dt2);
650 };
651
Dt_op_1(DataType dt1,DataType dt2)652 Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) {
653 if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
654 SetEncodingValue(0x0);
655 return;
656 }
657 if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
658 SetEncodingValue(0x1);
659 return;
660 }
661 if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
662 SetEncodingValue(0x2);
663 return;
664 }
665 if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
666 SetEncodingValue(0x3);
667 return;
668 }
669 }
670
671 class Dt_op_2 : public EncodingValue {
672 public:
673 explicit Dt_op_2(DataType dt);
674 };
675
Dt_op_2(DataType dt)676 Dt_op_2::Dt_op_2(DataType dt) {
677 switch (dt.GetValue()) {
678 case U32:
679 SetEncodingValue(0x0);
680 break;
681 case S32:
682 SetEncodingValue(0x1);
683 break;
684 default:
685 break;
686 }
687 }
688
689 class Dt_op_3 : public EncodingValue {
690 public:
691 explicit Dt_op_3(DataType dt);
692 };
693
Dt_op_3(DataType dt)694 Dt_op_3::Dt_op_3(DataType dt) {
695 switch (dt.GetValue()) {
696 case S32:
697 SetEncodingValue(0x0);
698 break;
699 case U32:
700 SetEncodingValue(0x1);
701 break;
702 default:
703 break;
704 }
705 }
706
707 class Dt_U_sx_1 : public EncodingValue {
708 public:
709 explicit Dt_U_sx_1(DataType dt);
710 };
711
Dt_U_sx_1(DataType dt)712 Dt_U_sx_1::Dt_U_sx_1(DataType dt) {
713 switch (dt.GetValue()) {
714 case S16:
715 SetEncodingValue(0x0);
716 break;
717 case S32:
718 SetEncodingValue(0x1);
719 break;
720 case U16:
721 SetEncodingValue(0x2);
722 break;
723 case U32:
724 SetEncodingValue(0x3);
725 break;
726 default:
727 break;
728 }
729 }
730
731 class Dt_op_U_1 : public EncodingValue {
732 public:
733 Dt_op_U_1(DataType dt1, DataType dt2);
734 };
735
Dt_op_U_1(DataType dt1,DataType dt2)736 Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) {
737 if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) {
738 SetEncodingValue(0x0);
739 return;
740 }
741 if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) {
742 SetEncodingValue(0x1);
743 return;
744 }
745 if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) {
746 SetEncodingValue(0x2);
747 return;
748 }
749 if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) {
750 SetEncodingValue(0x3);
751 return;
752 }
753 }
754
755 class Dt_sz_1 : public EncodingValue {
756 public:
757 explicit Dt_sz_1(DataType dt);
758 };
759
Dt_sz_1(DataType dt)760 Dt_sz_1::Dt_sz_1(DataType dt) {
761 switch (dt.GetValue()) {
762 case F32:
763 SetEncodingValue(0x0);
764 break;
765 default:
766 break;
767 }
768 }
769
770 class Dt_F_size_1 : public EncodingValue {
771 public:
772 explicit Dt_F_size_1(DataType dt);
773 };
774
Dt_F_size_1(DataType dt)775 Dt_F_size_1::Dt_F_size_1(DataType dt) {
776 switch (dt.GetValue()) {
777 case S8:
778 SetEncodingValue(0x0);
779 break;
780 case S16:
781 SetEncodingValue(0x1);
782 break;
783 case S32:
784 SetEncodingValue(0x2);
785 break;
786 case F32:
787 SetEncodingValue(0x6);
788 break;
789 default:
790 break;
791 }
792 }
793
794 class Dt_F_size_2 : public EncodingValue {
795 public:
796 explicit Dt_F_size_2(DataType dt);
797 };
798
Dt_F_size_2(DataType dt)799 Dt_F_size_2::Dt_F_size_2(DataType dt) {
800 switch (dt.GetValue()) {
801 case I8:
802 SetEncodingValue(0x0);
803 break;
804 case I16:
805 SetEncodingValue(0x1);
806 break;
807 case I32:
808 SetEncodingValue(0x2);
809 break;
810 case F32:
811 SetEncodingValue(0x6);
812 break;
813 default:
814 break;
815 }
816 }
817
818 class Dt_F_size_3 : public EncodingValue {
819 public:
820 explicit Dt_F_size_3(DataType dt);
821 };
822
Dt_F_size_3(DataType dt)823 Dt_F_size_3::Dt_F_size_3(DataType dt) {
824 switch (dt.GetValue()) {
825 case I16:
826 SetEncodingValue(0x1);
827 break;
828 case I32:
829 SetEncodingValue(0x2);
830 break;
831 case F32:
832 SetEncodingValue(0x6);
833 break;
834 default:
835 break;
836 }
837 }
838
839 class Dt_F_size_4 : public EncodingValue {
840 public:
841 explicit Dt_F_size_4(DataType dt);
842 };
843
Dt_F_size_4(DataType dt)844 Dt_F_size_4::Dt_F_size_4(DataType dt) {
845 switch (dt.GetValue()) {
846 case U32:
847 SetEncodingValue(0x2);
848 break;
849 case F32:
850 SetEncodingValue(0x6);
851 break;
852 default:
853 break;
854 }
855 }
856
857 class Dt_U_size_1 : public EncodingValue {
858 public:
859 explicit Dt_U_size_1(DataType dt);
860 };
861
Dt_U_size_1(DataType dt)862 Dt_U_size_1::Dt_U_size_1(DataType dt) {
863 switch (dt.GetValue()) {
864 case S8:
865 SetEncodingValue(0x0);
866 break;
867 case S16:
868 SetEncodingValue(0x1);
869 break;
870 case S32:
871 SetEncodingValue(0x2);
872 break;
873 case U8:
874 SetEncodingValue(0x4);
875 break;
876 case U16:
877 SetEncodingValue(0x5);
878 break;
879 case U32:
880 SetEncodingValue(0x6);
881 break;
882 default:
883 break;
884 }
885 }
886
887 class Dt_U_size_2 : public EncodingValue {
888 public:
889 explicit Dt_U_size_2(DataType dt);
890 };
891
Dt_U_size_2(DataType dt)892 Dt_U_size_2::Dt_U_size_2(DataType dt) {
893 switch (dt.GetValue()) {
894 case S16:
895 SetEncodingValue(0x1);
896 break;
897 case S32:
898 SetEncodingValue(0x2);
899 break;
900 case U16:
901 SetEncodingValue(0x5);
902 break;
903 case U32:
904 SetEncodingValue(0x6);
905 break;
906 default:
907 break;
908 }
909 }
910
911 class Dt_U_size_3 : public EncodingValue {
912 public:
913 explicit Dt_U_size_3(DataType dt);
914 };
915
Dt_U_size_3(DataType dt)916 Dt_U_size_3::Dt_U_size_3(DataType dt) {
917 switch (dt.GetValue()) {
918 case S8:
919 SetEncodingValue(0x0);
920 break;
921 case S16:
922 SetEncodingValue(0x1);
923 break;
924 case S32:
925 SetEncodingValue(0x2);
926 break;
927 case S64:
928 SetEncodingValue(0x3);
929 break;
930 case U8:
931 SetEncodingValue(0x4);
932 break;
933 case U16:
934 SetEncodingValue(0x5);
935 break;
936 case U32:
937 SetEncodingValue(0x6);
938 break;
939 case U64:
940 SetEncodingValue(0x7);
941 break;
942 default:
943 break;
944 }
945 }
946
947 class Dt_size_1 : public EncodingValue {
948 public:
949 explicit Dt_size_1(DataType dt);
950 };
951
Dt_size_1(DataType dt)952 Dt_size_1::Dt_size_1(DataType dt) {
953 switch (dt.GetValue()) {
954 case Untyped8:
955 SetEncodingValue(0x0);
956 break;
957 default:
958 break;
959 }
960 }
961
962 class Dt_size_2 : public EncodingValue {
963 public:
964 explicit Dt_size_2(DataType dt);
965 };
966
Dt_size_2(DataType dt)967 Dt_size_2::Dt_size_2(DataType dt) {
968 switch (dt.GetValue()) {
969 case I8:
970 SetEncodingValue(0x0);
971 break;
972 case I16:
973 SetEncodingValue(0x1);
974 break;
975 case I32:
976 SetEncodingValue(0x2);
977 break;
978 case I64:
979 SetEncodingValue(0x3);
980 break;
981 default:
982 break;
983 }
984 }
985
986 class Dt_size_3 : public EncodingValue {
987 public:
988 explicit Dt_size_3(DataType dt);
989 };
990
Dt_size_3(DataType dt)991 Dt_size_3::Dt_size_3(DataType dt) {
992 switch (dt.GetValue()) {
993 case I16:
994 SetEncodingValue(0x0);
995 break;
996 case I32:
997 SetEncodingValue(0x1);
998 break;
999 case I64:
1000 SetEncodingValue(0x2);
1001 break;
1002 default:
1003 break;
1004 }
1005 }
1006
1007 class Dt_size_4 : public EncodingValue {
1008 public:
1009 explicit Dt_size_4(DataType dt);
1010 };
1011
Dt_size_4(DataType dt)1012 Dt_size_4::Dt_size_4(DataType dt) {
1013 switch (dt.GetValue()) {
1014 case I8:
1015 SetEncodingValue(0x0);
1016 break;
1017 case I16:
1018 SetEncodingValue(0x1);
1019 break;
1020 case I32:
1021 SetEncodingValue(0x2);
1022 break;
1023 default:
1024 break;
1025 }
1026 }
1027
1028 class Dt_size_5 : public EncodingValue {
1029 public:
1030 explicit Dt_size_5(DataType dt);
1031 };
1032
Dt_size_5(DataType dt)1033 Dt_size_5::Dt_size_5(DataType dt) {
1034 switch (dt.GetValue()) {
1035 case S8:
1036 SetEncodingValue(0x0);
1037 break;
1038 case S16:
1039 SetEncodingValue(0x1);
1040 break;
1041 case S32:
1042 SetEncodingValue(0x2);
1043 break;
1044 default:
1045 break;
1046 }
1047 }
1048
1049 class Dt_size_6 : public EncodingValue {
1050 public:
1051 explicit Dt_size_6(DataType dt);
1052 };
1053
Dt_size_6(DataType dt)1054 Dt_size_6::Dt_size_6(DataType dt) {
1055 switch (dt.GetValue()) {
1056 case Untyped8:
1057 SetEncodingValue(0x0);
1058 break;
1059 case Untyped16:
1060 SetEncodingValue(0x1);
1061 break;
1062 case Untyped32:
1063 SetEncodingValue(0x2);
1064 break;
1065 case Untyped64:
1066 SetEncodingValue(0x3);
1067 break;
1068 default:
1069 break;
1070 }
1071 }
1072
1073 class Dt_size_7 : public EncodingValue {
1074 public:
1075 explicit Dt_size_7(DataType dt);
1076 };
1077
Dt_size_7(DataType dt)1078 Dt_size_7::Dt_size_7(DataType dt) {
1079 switch (dt.GetValue()) {
1080 case Untyped8:
1081 SetEncodingValue(0x0);
1082 break;
1083 case Untyped16:
1084 SetEncodingValue(0x1);
1085 break;
1086 case Untyped32:
1087 SetEncodingValue(0x2);
1088 break;
1089 default:
1090 break;
1091 }
1092 }
1093
1094 class Dt_size_8 : public EncodingValue {
1095 public:
1096 Dt_size_8(DataType dt, Alignment align);
1097 };
1098
Dt_size_8(DataType dt,Alignment align)1099 Dt_size_8::Dt_size_8(DataType dt, Alignment align) {
1100 switch (dt.GetValue()) {
1101 case Untyped8:
1102 SetEncodingValue(0x0);
1103 break;
1104 case Untyped16:
1105 SetEncodingValue(0x1);
1106 break;
1107 case Untyped32:
1108 if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) {
1109 SetEncodingValue(0x2);
1110 } else if (align.Is(k128BitAlign)) {
1111 SetEncodingValue(0x3);
1112 }
1113 break;
1114 default:
1115 break;
1116 }
1117 }
1118
1119 class Dt_size_9 : public EncodingValue {
1120 uint32_t type_;
1121
1122 public:
1123 explicit Dt_size_9(DataType dt);
GetTypeEncodingValue() const1124 uint32_t GetTypeEncodingValue() const { return type_; }
1125 };
1126
Dt_size_9(DataType dt)1127 Dt_size_9::Dt_size_9(DataType dt) {
1128 switch (dt.GetValue()) {
1129 case I16:
1130 type_ = 0x0;
1131 SetEncodingValue(0x1);
1132 break;
1133 case I32:
1134 type_ = 0x0;
1135 SetEncodingValue(0x2);
1136 break;
1137 case F32:
1138 type_ = 0x1;
1139 SetEncodingValue(0x2);
1140 break;
1141 default:
1142 VIXL_UNREACHABLE();
1143 type_ = 0x0;
1144 break;
1145 }
1146 }
1147
1148 class Dt_size_10 : public EncodingValue {
1149 public:
1150 explicit Dt_size_10(DataType dt);
1151 };
1152
Dt_size_10(DataType dt)1153 Dt_size_10::Dt_size_10(DataType dt) {
1154 switch (dt.GetValue()) {
1155 case S8:
1156 case U8:
1157 case I8:
1158 SetEncodingValue(0x0);
1159 break;
1160 case S16:
1161 case U16:
1162 case I16:
1163 SetEncodingValue(0x1);
1164 break;
1165 case S32:
1166 case U32:
1167 case I32:
1168 SetEncodingValue(0x2);
1169 break;
1170 default:
1171 break;
1172 }
1173 }
1174
1175 class Dt_size_11 : public EncodingValue {
1176 uint32_t type_;
1177
1178 public:
1179 explicit Dt_size_11(DataType dt);
GetTypeEncodingValue() const1180 uint32_t GetTypeEncodingValue() const { return type_; }
1181 };
1182
Dt_size_11(DataType dt)1183 Dt_size_11::Dt_size_11(DataType dt) {
1184 switch (dt.GetValue()) {
1185 case S16:
1186 type_ = 0x0;
1187 SetEncodingValue(0x1);
1188 break;
1189 case U16:
1190 type_ = 0x1;
1191 SetEncodingValue(0x1);
1192 break;
1193 case S32:
1194 type_ = 0x0;
1195 SetEncodingValue(0x2);
1196 break;
1197 case U32:
1198 type_ = 0x1;
1199 SetEncodingValue(0x2);
1200 break;
1201 default:
1202 VIXL_UNREACHABLE();
1203 type_ = 0x0;
1204 break;
1205 }
1206 }
1207
1208 class Dt_size_12 : public EncodingValue {
1209 uint32_t type_;
1210
1211 public:
1212 explicit Dt_size_12(DataType dt);
GetTypeEncodingValue() const1213 uint32_t GetTypeEncodingValue() const { return type_; }
1214 };
1215
Dt_size_12(DataType dt)1216 Dt_size_12::Dt_size_12(DataType dt) {
1217 switch (dt.GetValue()) {
1218 case S8:
1219 type_ = 0x0;
1220 SetEncodingValue(0x0);
1221 break;
1222 case U8:
1223 type_ = 0x1;
1224 SetEncodingValue(0x0);
1225 break;
1226 case S16:
1227 type_ = 0x0;
1228 SetEncodingValue(0x1);
1229 break;
1230 case U16:
1231 type_ = 0x1;
1232 SetEncodingValue(0x1);
1233 break;
1234 case S32:
1235 type_ = 0x0;
1236 SetEncodingValue(0x2);
1237 break;
1238 case U32:
1239 type_ = 0x1;
1240 SetEncodingValue(0x2);
1241 break;
1242 default:
1243 VIXL_UNREACHABLE();
1244 type_ = 0x0;
1245 break;
1246 }
1247 }
1248
1249 class Dt_size_13 : public EncodingValue {
1250 public:
1251 explicit Dt_size_13(DataType dt);
1252 };
1253
Dt_size_13(DataType dt)1254 Dt_size_13::Dt_size_13(DataType dt) {
1255 switch (dt.GetValue()) {
1256 case S16:
1257 SetEncodingValue(0x1);
1258 break;
1259 case S32:
1260 SetEncodingValue(0x2);
1261 break;
1262 default:
1263 break;
1264 }
1265 }
1266
1267 class Dt_size_14 : public EncodingValue {
1268 public:
1269 explicit Dt_size_14(DataType dt);
1270 };
1271
Dt_size_14(DataType dt)1272 Dt_size_14::Dt_size_14(DataType dt) {
1273 switch (dt.GetValue()) {
1274 case S16:
1275 SetEncodingValue(0x0);
1276 break;
1277 case S32:
1278 SetEncodingValue(0x1);
1279 break;
1280 case S64:
1281 SetEncodingValue(0x2);
1282 break;
1283 default:
1284 break;
1285 }
1286 }
1287
1288 class Dt_size_15 : public EncodingValue {
1289 public:
1290 explicit Dt_size_15(DataType dt);
1291 };
1292
Dt_size_15(DataType dt)1293 Dt_size_15::Dt_size_15(DataType dt) {
1294 switch (dt.GetValue()) {
1295 case Untyped8:
1296 SetEncodingValue(0x0);
1297 break;
1298 case Untyped16:
1299 SetEncodingValue(0x1);
1300 break;
1301 default:
1302 break;
1303 }
1304 }
1305
1306 class Dt_size_16 : public EncodingValue {
1307 public:
1308 explicit Dt_size_16(DataType dt);
1309 };
1310
Dt_size_16(DataType dt)1311 Dt_size_16::Dt_size_16(DataType dt) {
1312 switch (dt.GetValue()) {
1313 case F32:
1314 SetEncodingValue(0x2);
1315 break;
1316 default:
1317 break;
1318 }
1319 }
1320
1321 class Dt_size_17 : public EncodingValue {
1322 public:
1323 explicit Dt_size_17(DataType dt);
1324 };
1325
Dt_size_17(DataType dt)1326 Dt_size_17::Dt_size_17(DataType dt) {
1327 switch (dt.GetValue()) {
1328 case I8:
1329 SetEncodingValue(0x0);
1330 break;
1331 case I16:
1332 SetEncodingValue(0x1);
1333 break;
1334 case I32:
1335 SetEncodingValue(0x2);
1336 break;
1337 default:
1338 break;
1339 }
1340 }
1341
1342 class Index_1 : public EncodingValue {
1343 public:
1344 Index_1(const NeonRegisterList& nreglist, DataType dt);
1345 };
1346
Index_1(const NeonRegisterList & nreglist,DataType dt)1347 Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) {
1348 switch (dt.GetValue()) {
1349 case Untyped8: {
1350 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1351 return;
1352 }
1353 uint32_t value = nreglist.GetTransferLane() << 1;
1354 if (!nreglist.IsSingleSpaced()) return;
1355 SetEncodingValue(value);
1356 break;
1357 }
1358 case Untyped16: {
1359 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1360 return;
1361 }
1362 uint32_t value = nreglist.GetTransferLane() << 2;
1363 if (nreglist.IsDoubleSpaced()) value |= 2;
1364 SetEncodingValue(value);
1365 break;
1366 }
1367 case Untyped32: {
1368 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1369 return;
1370 }
1371 uint32_t value = nreglist.GetTransferLane() << 3;
1372 if (nreglist.IsDoubleSpaced()) value |= 4;
1373 SetEncodingValue(value);
1374 break;
1375 }
1376 default:
1377 break;
1378 }
1379 }
1380
1381 class Align_index_align_1 : public EncodingValue {
1382 public:
1383 Align_index_align_1(Alignment align,
1384 const NeonRegisterList& nreglist,
1385 DataType dt);
1386 };
1387
Align_index_align_1(Alignment align,const NeonRegisterList & nreglist,DataType dt)1388 Align_index_align_1::Align_index_align_1(Alignment align,
1389 const NeonRegisterList& nreglist,
1390 DataType dt) {
1391 switch (dt.GetValue()) {
1392 case Untyped8: {
1393 uint32_t value;
1394 if (align.GetType() == kNoAlignment) {
1395 value = 0;
1396 } else {
1397 return;
1398 }
1399 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1400 return;
1401 }
1402 value |= nreglist.GetTransferLane() << 1;
1403 SetEncodingValue(value);
1404 break;
1405 }
1406 case Untyped16: {
1407 uint32_t value;
1408 if (align.GetType() == k16BitAlign) {
1409 value = 1;
1410 } else if (align.GetType() == kNoAlignment) {
1411 value = 0;
1412 } else {
1413 return;
1414 }
1415 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1416 return;
1417 }
1418 value |= nreglist.GetTransferLane() << 2;
1419 SetEncodingValue(value);
1420 break;
1421 }
1422 case Untyped32: {
1423 uint32_t value;
1424 if (align.GetType() == k32BitAlign) {
1425 value = 3;
1426 } else if (align.GetType() == kNoAlignment) {
1427 value = 0;
1428 } else {
1429 return;
1430 }
1431 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1432 return;
1433 }
1434 value |= nreglist.GetTransferLane() << 3;
1435 SetEncodingValue(value);
1436 break;
1437 }
1438 default:
1439 break;
1440 }
1441 }
1442
1443 class Align_index_align_2 : public EncodingValue {
1444 public:
1445 Align_index_align_2(Alignment align,
1446 const NeonRegisterList& nreglist,
1447 DataType dt);
1448 };
1449
Align_index_align_2(Alignment align,const NeonRegisterList & nreglist,DataType dt)1450 Align_index_align_2::Align_index_align_2(Alignment align,
1451 const NeonRegisterList& nreglist,
1452 DataType dt) {
1453 switch (dt.GetValue()) {
1454 case Untyped8: {
1455 uint32_t value;
1456 if (align.GetType() == k16BitAlign) {
1457 value = 1;
1458 } else if (align.GetType() == kNoAlignment) {
1459 value = 0;
1460 } else {
1461 return;
1462 }
1463 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1464 return;
1465 }
1466 value |= nreglist.GetTransferLane() << 1;
1467 if (!nreglist.IsSingleSpaced()) return;
1468 SetEncodingValue(value);
1469 break;
1470 }
1471 case Untyped16: {
1472 uint32_t value;
1473 if (align.GetType() == k32BitAlign) {
1474 value = 1;
1475 } else if (align.GetType() == kNoAlignment) {
1476 value = 0;
1477 } else {
1478 return;
1479 }
1480 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1481 return;
1482 }
1483 value |= nreglist.GetTransferLane() << 2;
1484 if (nreglist.IsDoubleSpaced()) value |= 2;
1485 SetEncodingValue(value);
1486 break;
1487 }
1488 case Untyped32: {
1489 uint32_t value;
1490 if (align.GetType() == k64BitAlign) {
1491 value = 1;
1492 } else if (align.GetType() == kNoAlignment) {
1493 value = 0;
1494 } else {
1495 return;
1496 }
1497 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1498 return;
1499 }
1500 value |= nreglist.GetTransferLane() << 3;
1501 if (nreglist.IsDoubleSpaced()) value |= 4;
1502 SetEncodingValue(value);
1503 break;
1504 }
1505 default:
1506 break;
1507 }
1508 }
1509
1510 class Align_index_align_3 : public EncodingValue {
1511 public:
1512 Align_index_align_3(Alignment align,
1513 const NeonRegisterList& nreglist,
1514 DataType dt);
1515 };
1516
Align_index_align_3(Alignment align,const NeonRegisterList & nreglist,DataType dt)1517 Align_index_align_3::Align_index_align_3(Alignment align,
1518 const NeonRegisterList& nreglist,
1519 DataType dt) {
1520 switch (dt.GetValue()) {
1521 case Untyped8: {
1522 uint32_t value;
1523 if (align.GetType() == k32BitAlign) {
1524 value = 1;
1525 } else if (align.GetType() == kNoAlignment) {
1526 value = 0;
1527 } else {
1528 return;
1529 }
1530 if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) {
1531 return;
1532 }
1533 value |= nreglist.GetTransferLane() << 1;
1534 if (!nreglist.IsSingleSpaced()) return;
1535 SetEncodingValue(value);
1536 break;
1537 }
1538 case Untyped16: {
1539 uint32_t value;
1540 if (align.GetType() == k64BitAlign) {
1541 value = 1;
1542 } else if (align.GetType() == kNoAlignment) {
1543 value = 0;
1544 } else {
1545 return;
1546 }
1547 if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) {
1548 return;
1549 }
1550 value |= nreglist.GetTransferLane() << 2;
1551 if (nreglist.IsDoubleSpaced()) value |= 2;
1552 SetEncodingValue(value);
1553 break;
1554 }
1555 case Untyped32: {
1556 uint32_t value;
1557 if (align.GetType() == k64BitAlign) {
1558 value = 1;
1559 } else if (align.GetType() == k128BitAlign) {
1560 value = 2;
1561 } else if (align.GetType() == kNoAlignment) {
1562 value = 0;
1563 } else {
1564 return;
1565 }
1566 if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) {
1567 return;
1568 }
1569 value |= nreglist.GetTransferLane() << 3;
1570 if (nreglist.IsDoubleSpaced()) value |= 4;
1571 SetEncodingValue(value);
1572 break;
1573 }
1574 default:
1575 break;
1576 }
1577 }
1578
1579 class Align_a_1 : public EncodingValue {
1580 public:
1581 Align_a_1(Alignment align, DataType dt);
1582 };
1583
Align_a_1(Alignment align,DataType dt)1584 Align_a_1::Align_a_1(Alignment align, DataType dt) {
1585 switch (align.GetType()) {
1586 case k16BitAlign:
1587 if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1588 break;
1589 case k32BitAlign:
1590 if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1591 break;
1592 case kNoAlignment:
1593 SetEncodingValue(0x0);
1594 break;
1595 default:
1596 break;
1597 }
1598 }
1599
1600 class Align_a_2 : public EncodingValue {
1601 public:
1602 Align_a_2(Alignment align, DataType dt);
1603 };
1604
Align_a_2(Alignment align,DataType dt)1605 Align_a_2::Align_a_2(Alignment align, DataType dt) {
1606 switch (align.GetType()) {
1607 case k16BitAlign:
1608 if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1609 break;
1610 case k32BitAlign:
1611 if (dt.Is(Untyped16)) SetEncodingValue(0x1);
1612 break;
1613 case k64BitAlign:
1614 if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1615 break;
1616 case kNoAlignment:
1617 SetEncodingValue(0x0);
1618 break;
1619 default:
1620 break;
1621 }
1622 }
1623
1624 class Align_a_3 : public EncodingValue {
1625 public:
1626 Align_a_3(Alignment align, DataType dt);
1627 };
1628
Align_a_3(Alignment align,DataType dt)1629 Align_a_3::Align_a_3(Alignment align, DataType dt) {
1630 switch (align.GetType()) {
1631 case k32BitAlign:
1632 if (dt.Is(Untyped8)) SetEncodingValue(0x1);
1633 break;
1634 case k64BitAlign:
1635 if (dt.Is(Untyped16))
1636 SetEncodingValue(0x1);
1637 else if (dt.Is(Untyped32))
1638 SetEncodingValue(0x1);
1639 break;
1640 case k128BitAlign:
1641 if (dt.Is(Untyped32)) SetEncodingValue(0x1);
1642 break;
1643 case kNoAlignment:
1644 SetEncodingValue(0x0);
1645 break;
1646 default:
1647 break;
1648 }
1649 }
1650
1651 class Align_align_1 : public EncodingValue {
1652 public:
1653 Align_align_1(Alignment align, const NeonRegisterList& nreglist);
1654 };
1655
Align_align_1(Alignment align,const NeonRegisterList & nreglist)1656 Align_align_1::Align_align_1(Alignment align,
1657 const NeonRegisterList& nreglist) {
1658 switch (align.GetType()) {
1659 case k64BitAlign:
1660 SetEncodingValue(0x1);
1661 break;
1662 case k128BitAlign:
1663 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1664 SetEncodingValue(0x2);
1665 break;
1666 case k256BitAlign:
1667 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1668 SetEncodingValue(0x3);
1669 break;
1670 case kNoAlignment:
1671 SetEncodingValue(0x0);
1672 break;
1673 default:
1674 break;
1675 }
1676 }
1677
1678 class Align_align_2 : public EncodingValue {
1679 public:
1680 Align_align_2(Alignment align, const NeonRegisterList& nreglist);
1681 };
1682
Align_align_2(Alignment align,const NeonRegisterList & nreglist)1683 Align_align_2::Align_align_2(Alignment align,
1684 const NeonRegisterList& nreglist) {
1685 switch (align.GetType()) {
1686 case k64BitAlign:
1687 SetEncodingValue(0x1);
1688 break;
1689 case k128BitAlign:
1690 SetEncodingValue(0x2);
1691 break;
1692 case k256BitAlign:
1693 if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1694 break;
1695 case kNoAlignment:
1696 SetEncodingValue(0x0);
1697 break;
1698 default:
1699 break;
1700 }
1701 }
1702
1703 class Align_align_3 : public EncodingValue {
1704 public:
1705 explicit Align_align_3(Alignment align);
1706 };
1707
Align_align_3(Alignment align)1708 Align_align_3::Align_align_3(Alignment align) {
1709 switch (align.GetType()) {
1710 case k64BitAlign:
1711 SetEncodingValue(0x1);
1712 break;
1713 case kNoAlignment:
1714 SetEncodingValue(0x0);
1715 break;
1716 default:
1717 break;
1718 }
1719 }
1720
1721 class Align_align_4 : public EncodingValue {
1722 public:
1723 explicit Align_align_4(Alignment align);
1724 };
1725
Align_align_4(Alignment align)1726 Align_align_4::Align_align_4(Alignment align) {
1727 switch (align.GetType()) {
1728 case k64BitAlign:
1729 SetEncodingValue(0x1);
1730 break;
1731 case k128BitAlign:
1732 SetEncodingValue(0x2);
1733 break;
1734 case k256BitAlign:
1735 SetEncodingValue(0x3);
1736 break;
1737 case kNoAlignment:
1738 SetEncodingValue(0x0);
1739 break;
1740 default:
1741 break;
1742 }
1743 }
1744
1745 class Align_align_5 : public EncodingValue {
1746 public:
1747 Align_align_5(Alignment align, const NeonRegisterList& nreglist);
1748 };
1749
Align_align_5(Alignment align,const NeonRegisterList & nreglist)1750 Align_align_5::Align_align_5(Alignment align,
1751 const NeonRegisterList& nreglist) {
1752 switch (align.GetType()) {
1753 case k64BitAlign:
1754 SetEncodingValue(0x1);
1755 break;
1756 case k128BitAlign:
1757 if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4))
1758 SetEncodingValue(0x2);
1759 break;
1760 case k256BitAlign:
1761 if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3);
1762 break;
1763 case kNoAlignment:
1764 SetEncodingValue(0x0);
1765 break;
1766 default:
1767 break;
1768 }
1769 }
1770
1771
1772 // CBNZ{<q>} <Rn>, <label> ; T1
1773 // CBZ{<q>} <Rn>, <label> ; T1
1774 static const struct ReferenceInfo kT16CbzInfo =
1775 {k16BitT32InstructionSizeInBytes,
1776 0, // Min offset.
1777 126, // Max offset.
1778 2, // Alignment.
1779 ReferenceInfo::kDontAlignPc};
1780
1781
1782 // B<c>{<q>} <label> ; T1
1783 static const struct ReferenceInfo kT16ConditionalBranchInfo =
1784 {k16BitT32InstructionSizeInBytes,
1785 -256, // Min offset.
1786 254, // Max offset.
1787 2, // Alignment.
1788 ReferenceInfo::kDontAlignPc};
1789
1790
1791 // ADR{<c>}{<q>} <Rd>, <label> ; T1
1792 // LDR{<c>}{<q>} <Rt>, <label> ; T1
1793 static const struct ReferenceInfo kT16DataInfo =
1794 {k16BitT32InstructionSizeInBytes,
1795 0, // Min offset.
1796 1020, // Max offset.
1797 4, // Alignment.
1798 ReferenceInfo::kAlignPc};
1799
1800
1801 // B{<c>}{<q>} <label> ; T2
1802 static const struct ReferenceInfo kT16BranchInfo =
1803 {k16BitT32InstructionSizeInBytes,
1804 -2048, // Min offset.
1805 2046, // Max offset.
1806 2, // Alignment.
1807 ReferenceInfo::kDontAlignPc};
1808
1809
1810 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
1811 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
1812 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
1813 static const struct ReferenceInfo kT32DataInfo =
1814 {k32BitT32InstructionSizeInBytes,
1815 -1020, // Min offset.
1816 1020, // Max offset.
1817 4, // Alignment.
1818 ReferenceInfo::kAlignPc};
1819
1820
1821 // ADR{<c>}{<q>} <Rd>, <label> ; T3
1822 // LDR{<c>}{<q>} <Rt>, <label> ; T2
1823 // LDRB{<c>}{<q>} <Rt>, <label> ; T1
1824 // LDRH{<c>}{<q>} <Rt>, <label> ; T1
1825 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
1826 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
1827 // PLD{<c>}{<q>} <label> ; T1
1828 // PLI{<c>}{<q>} <label> ; T3
1829 static const struct ReferenceInfo kT32FarDataInfo =
1830 {k32BitT32InstructionSizeInBytes,
1831 -4095, // Min offset.
1832 4095, // Max offset.
1833 1, // Alignment.
1834 ReferenceInfo::kAlignPc};
1835
1836
1837 // B<c>{<q>} <label> ; T3
1838 static const struct ReferenceInfo kT32ConditionalBranchInfo =
1839 {k32BitT32InstructionSizeInBytes,
1840 -1048576, // Min offset.
1841 1048574, // Max offset.
1842 2, // Alignment.
1843 ReferenceInfo::kDontAlignPc};
1844
1845
1846 // B{<c>}{<q>} <label> ; T4
1847 // BL{<c>}{<q>} <label> ; T1
1848 static const struct ReferenceInfo kT32BranchInfo =
1849 {k32BitT32InstructionSizeInBytes,
1850 -16777216, // Min offset.
1851 16777214, // Max offset.
1852 2, // Alignment.
1853 ReferenceInfo::kDontAlignPc};
1854
1855
1856 // BLX{<c>}{<q>} <label> ; T2
1857 static const struct ReferenceInfo kT32BlxInfo =
1858 {k32BitT32InstructionSizeInBytes,
1859 -16777216, // Min offset.
1860 16777212, // Max offset.
1861 4, // Alignment.
1862 ReferenceInfo::kAlignPc};
1863
1864
1865 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
1866 // LDRH{<c>}{<q>} <Rt>, <label> ; A1
1867 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
1868 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
1869 static const struct ReferenceInfo kA32VeryNearDataInfo =
1870 {kA32InstructionSizeInBytes,
1871 -255, // Min offset.
1872 255, // Max offset.
1873 1, // Alignment.
1874 ReferenceInfo::kAlignPc};
1875
1876
1877 // ADR{<c>}{<q>} <Rd>, <label> ; A1
1878 static const struct ReferenceInfo kA32AdrInfo = {kA32InstructionSizeInBytes,
1879 -256, // Min offset.
1880 256, // Max offset.
1881 1, // Alignment.
1882 ReferenceInfo::kAlignPc};
1883
1884
1885 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
1886 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
1887 static const struct ReferenceInfo kA32DataInfo = {kA32InstructionSizeInBytes,
1888 -1020, // Min offset.
1889 1020, // Max offset.
1890 4, // Alignment.
1891 ReferenceInfo::kAlignPc};
1892
1893
1894 // LDR{<c>}{<q>} <Rt>, <label> ; A1
1895 // LDRB{<c>}{<q>} <Rt>, <label> ; A1
1896 // PLD{<c>}{<q>} <label> ; A1
1897 // PLI{<c>}{<q>} <label> ; A1
1898 static const struct ReferenceInfo kA32FarDataInfo = {kA32InstructionSizeInBytes,
1899 -4095, // Min offset.
1900 4095, // Max offset.
1901 1, // Alignment.
1902 ReferenceInfo::kAlignPc};
1903
1904
1905 // B{<c>}{<q>} <label> ; A1
1906 // BL{<c>}{<q>} <label> ; A1
1907 static const struct ReferenceInfo kA32BranchInfo =
1908 {kA32InstructionSizeInBytes,
1909 -33554432, // Min offset.
1910 33554428, // Max offset.
1911 4, // Alignment.
1912 ReferenceInfo::kDontAlignPc};
1913
1914
1915 // BLX{<c>}{<q>} <label> ; A2
1916 static const struct ReferenceInfo kA32BlxInfo = {kA32InstructionSizeInBytes,
1917 -33554432, // Min offset.
1918 33554430, // Max offset.
1919 2, // Alignment.
1920 ReferenceInfo::kAlignPc};
1921
1922
adc(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)1923 void Assembler::adc(Condition cond,
1924 EncodingSize size,
1925 Register rd,
1926 Register rn,
1927 const Operand& operand) {
1928 VIXL_ASSERT(AllowAssembler());
1929 CheckIT(cond);
1930 if (operand.IsImmediate()) {
1931 uint32_t imm = operand.GetImmediate();
1932 if (IsUsingT32()) {
1933 ImmediateT32 immediate_t32(imm);
1934 // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
1935 if (!size.IsNarrow() && immediate_t32.IsValid() &&
1936 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
1937 EmitT32_32(0xf1400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1938 (immediate_t32.GetEncodingValue() & 0xff) |
1939 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
1940 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
1941 AdvanceIT();
1942 return;
1943 }
1944 } else {
1945 ImmediateA32 immediate_a32(imm);
1946 // ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
1947 if (immediate_a32.IsValid() && cond.IsNotNever()) {
1948 EmitA32(0x02a00000U | (cond.GetCondition() << 28) |
1949 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
1950 immediate_a32.GetEncodingValue());
1951 return;
1952 }
1953 }
1954 }
1955 if (operand.IsImmediateShiftedRegister()) {
1956 Register rm = operand.GetBaseRegister();
1957 if (operand.IsPlainRegister()) {
1958 if (IsUsingT32()) {
1959 // ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
1960 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
1961 rm.IsLow()) {
1962 EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
1963 AdvanceIT();
1964 return;
1965 }
1966 }
1967 }
1968 Shift shift = operand.GetShift();
1969 uint32_t amount = operand.GetShiftAmount();
1970 if (IsUsingT32()) {
1971 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
1972 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
1973 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
1974 uint32_t amount_ = amount % 32;
1975 EmitT32_32(0xeb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
1976 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
1977 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
1978 AdvanceIT();
1979 return;
1980 }
1981 } else {
1982 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
1983 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
1984 uint32_t amount_ = amount % 32;
1985 EmitA32(0x00a00000U | (cond.GetCondition() << 28) |
1986 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
1987 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
1988 return;
1989 }
1990 }
1991 }
1992 if (operand.IsRegisterShiftedRegister()) {
1993 Register rm = operand.GetBaseRegister();
1994 Shift shift = operand.GetShift();
1995 Register rs = operand.GetShiftRegister();
1996 if (IsUsingA32()) {
1997 // ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
1998 if (cond.IsNotNever() &&
1999 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2000 AllowUnpredictable())) {
2001 EmitA32(0x00a00010U | (cond.GetCondition() << 28) |
2002 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2003 (shift.GetType() << 5) | (rs.GetCode() << 8));
2004 return;
2005 }
2006 }
2007 }
2008 Delegate(kAdc, &Assembler::adc, cond, size, rd, rn, operand);
2009 }
2010
adcs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2011 void Assembler::adcs(Condition cond,
2012 EncodingSize size,
2013 Register rd,
2014 Register rn,
2015 const Operand& operand) {
2016 VIXL_ASSERT(AllowAssembler());
2017 CheckIT(cond);
2018 if (operand.IsImmediate()) {
2019 uint32_t imm = operand.GetImmediate();
2020 if (IsUsingT32()) {
2021 ImmediateT32 immediate_t32(imm);
2022 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2023 if (!size.IsNarrow() && immediate_t32.IsValid() &&
2024 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
2025 EmitT32_32(0xf1500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2026 (immediate_t32.GetEncodingValue() & 0xff) |
2027 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2028 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2029 AdvanceIT();
2030 return;
2031 }
2032 } else {
2033 ImmediateA32 immediate_a32(imm);
2034 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2035 if (immediate_a32.IsValid() && cond.IsNotNever()) {
2036 EmitA32(0x02b00000U | (cond.GetCondition() << 28) |
2037 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2038 immediate_a32.GetEncodingValue());
2039 return;
2040 }
2041 }
2042 }
2043 if (operand.IsImmediateShiftedRegister()) {
2044 Register rm = operand.GetBaseRegister();
2045 if (operand.IsPlainRegister()) {
2046 if (IsUsingT32()) {
2047 // ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2048 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2049 rm.IsLow()) {
2050 EmitT32_16(0x4140 | rd.GetCode() | (rm.GetCode() << 3));
2051 AdvanceIT();
2052 return;
2053 }
2054 }
2055 }
2056 Shift shift = operand.GetShift();
2057 uint32_t amount = operand.GetShiftAmount();
2058 if (IsUsingT32()) {
2059 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2060 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
2061 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2062 uint32_t amount_ = amount % 32;
2063 EmitT32_32(0xeb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2064 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2065 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2066 AdvanceIT();
2067 return;
2068 }
2069 } else {
2070 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2071 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2072 uint32_t amount_ = amount % 32;
2073 EmitA32(0x00b00000U | (cond.GetCondition() << 28) |
2074 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2075 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2076 return;
2077 }
2078 }
2079 }
2080 if (operand.IsRegisterShiftedRegister()) {
2081 Register rm = operand.GetBaseRegister();
2082 Shift shift = operand.GetShift();
2083 Register rs = operand.GetShiftRegister();
2084 if (IsUsingA32()) {
2085 // ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2086 if (cond.IsNotNever() &&
2087 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2088 AllowUnpredictable())) {
2089 EmitA32(0x00b00010U | (cond.GetCondition() << 28) |
2090 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2091 (shift.GetType() << 5) | (rs.GetCode() << 8));
2092 return;
2093 }
2094 }
2095 }
2096 Delegate(kAdcs, &Assembler::adcs, cond, size, rd, rn, operand);
2097 }
2098
add(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2099 void Assembler::add(Condition cond,
2100 EncodingSize size,
2101 Register rd,
2102 Register rn,
2103 const Operand& operand) {
2104 VIXL_ASSERT(AllowAssembler());
2105 CheckIT(cond);
2106 if (operand.IsImmediate()) {
2107 uint32_t imm = operand.GetImmediate();
2108 if (IsUsingT32()) {
2109 ImmediateT32 immediate_t32(imm);
2110 // ADD{<c>}{<q>} <Rd>, PC, #<imm8> ; T1
2111 if (!size.IsWide() && rd.IsLow() && rn.Is(pc) && (imm <= 1020) &&
2112 ((imm % 4) == 0)) {
2113 uint32_t imm_ = imm >> 2;
2114 EmitT32_16(0xa000 | (rd.GetCode() << 8) | imm_);
2115 AdvanceIT();
2116 return;
2117 }
2118 // ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
2119 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2120 (imm <= 7)) {
2121 EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
2122 AdvanceIT();
2123 return;
2124 }
2125 // ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
2126 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2127 (imm <= 255)) {
2128 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2129 AdvanceIT();
2130 return;
2131 }
2132 // ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1
2133 if (!size.IsWide() && rd.IsLow() && rn.Is(sp) && (imm <= 1020) &&
2134 ((imm % 4) == 0)) {
2135 uint32_t imm_ = imm >> 2;
2136 EmitT32_16(0xa800 | (rd.GetCode() << 8) | imm_);
2137 AdvanceIT();
2138 return;
2139 }
2140 // ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2
2141 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
2142 ((imm % 4) == 0)) {
2143 uint32_t imm_ = imm >> 2;
2144 EmitT32_16(0xb000 | imm_);
2145 AdvanceIT();
2146 return;
2147 }
2148 // ADD{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2149 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
2150 (!rd.IsPC() || AllowUnpredictable())) {
2151 EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2152 ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2153 AdvanceIT();
2154 return;
2155 }
2156 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2157 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
2158 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
2159 EmitT32_32(0xf1000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2160 (immediate_t32.GetEncodingValue() & 0xff) |
2161 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2162 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2163 AdvanceIT();
2164 return;
2165 }
2166 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2167 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
2168 (!rd.IsPC() || AllowUnpredictable())) {
2169 EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2170 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2171 AdvanceIT();
2172 return;
2173 }
2174 // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2175 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
2176 (!rd.IsPC() || AllowUnpredictable())) {
2177 EmitT32_32(0xf10d0000U | (rd.GetCode() << 8) |
2178 (immediate_t32.GetEncodingValue() & 0xff) |
2179 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2180 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2181 AdvanceIT();
2182 return;
2183 }
2184 // ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2185 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
2186 (!rd.IsPC() || AllowUnpredictable())) {
2187 EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2188 ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2189 AdvanceIT();
2190 return;
2191 }
2192 } else {
2193 ImmediateA32 immediate_a32(imm);
2194 // ADD{<c>}{<q>} <Rd>, PC, #<const> ; A1
2195 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
2196 EmitA32(0x028f0000U | (cond.GetCondition() << 28) |
2197 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2198 return;
2199 }
2200 // ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2201 if (immediate_a32.IsValid() && cond.IsNotNever() &&
2202 ((rn.GetCode() & 0xd) != 0xd)) {
2203 EmitA32(0x02800000U | (cond.GetCondition() << 28) |
2204 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2205 immediate_a32.GetEncodingValue());
2206 return;
2207 }
2208 // ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2209 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2210 EmitA32(0x028d0000U | (cond.GetCondition() << 28) |
2211 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2212 return;
2213 }
2214 }
2215 }
2216 if (operand.IsImmediateShiftedRegister()) {
2217 Register rm = operand.GetBaseRegister();
2218 if (operand.IsPlainRegister()) {
2219 if (IsUsingT32()) {
2220 // ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
2221 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2222 rm.IsLow()) {
2223 EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2224 (rm.GetCode() << 6));
2225 AdvanceIT();
2226 return;
2227 }
2228 // ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2
2229 if (!size.IsWide() && rd.Is(rn) && !rm.Is(sp) &&
2230 (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
2231 (!rd.IsPC() || !rm.IsPC())) ||
2232 AllowUnpredictable())) {
2233 EmitT32_16(0x4400 | (rd.GetCode() & 0x7) |
2234 ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
2235 AdvanceIT();
2236 return;
2237 }
2238 // ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1
2239 if (!size.IsWide() && rd.Is(rm) && rn.Is(sp) &&
2240 ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
2241 AllowUnpredictable())) {
2242 EmitT32_16(0x4468 | (rd.GetCode() & 0x7) |
2243 ((rd.GetCode() & 0x8) << 4));
2244 AdvanceIT();
2245 return;
2246 }
2247 // ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2
2248 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && !rm.Is(sp)) {
2249 EmitT32_16(0x4485 | (rm.GetCode() << 3));
2250 AdvanceIT();
2251 return;
2252 }
2253 }
2254 }
2255 Shift shift = operand.GetShift();
2256 uint32_t amount = operand.GetShiftAmount();
2257 if (IsUsingT32()) {
2258 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2259 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
2260 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2261 uint32_t amount_ = amount % 32;
2262 EmitT32_32(0xeb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2263 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2264 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2265 AdvanceIT();
2266 return;
2267 }
2268 // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2269 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
2270 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2271 uint32_t amount_ = amount % 32;
2272 EmitT32_32(0xeb0d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2273 (operand.GetTypeEncodingValue() << 4) |
2274 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2275 AdvanceIT();
2276 return;
2277 }
2278 } else {
2279 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2280 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2281 uint32_t amount_ = amount % 32;
2282 EmitA32(0x00800000U | (cond.GetCondition() << 28) |
2283 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2284 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2285 return;
2286 }
2287 // ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2288 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2289 uint32_t amount_ = amount % 32;
2290 EmitA32(0x008d0000U | (cond.GetCondition() << 28) |
2291 (rd.GetCode() << 12) | rm.GetCode() |
2292 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2293 return;
2294 }
2295 }
2296 }
2297 if (operand.IsRegisterShiftedRegister()) {
2298 Register rm = operand.GetBaseRegister();
2299 Shift shift = operand.GetShift();
2300 Register rs = operand.GetShiftRegister();
2301 if (IsUsingA32()) {
2302 // ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2303 if (cond.IsNotNever() &&
2304 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2305 AllowUnpredictable())) {
2306 EmitA32(0x00800010U | (cond.GetCondition() << 28) |
2307 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2308 (shift.GetType() << 5) | (rs.GetCode() << 8));
2309 return;
2310 }
2311 }
2312 }
2313 Delegate(kAdd, &Assembler::add, cond, size, rd, rn, operand);
2314 }
2315
add(Condition cond,Register rd,const Operand & operand)2316 void Assembler::add(Condition cond, Register rd, const Operand& operand) {
2317 VIXL_ASSERT(AllowAssembler());
2318 CheckIT(cond);
2319 if (operand.IsImmediate()) {
2320 uint32_t imm = operand.GetImmediate();
2321 if (IsUsingT32()) {
2322 // ADD<c>{<q>} <Rdn>, #<imm8> ; T2
2323 if (InITBlock() && rd.IsLow() && (imm <= 255)) {
2324 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2325 AdvanceIT();
2326 return;
2327 }
2328 }
2329 }
2330 if (operand.IsPlainRegister()) {
2331 Register rm = operand.GetBaseRegister();
2332 if (IsUsingT32()) {
2333 // ADD<c>{<q>} <Rdn>, <Rm> ; T2
2334 if (InITBlock() && !rm.Is(sp) &&
2335 (((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) &&
2336 (!rd.IsPC() || !rm.IsPC())) ||
2337 AllowUnpredictable())) {
2338 EmitT32_16(0x4400 | (rd.GetCode() & 0x7) | ((rd.GetCode() & 0x8) << 4) |
2339 (rm.GetCode() << 3));
2340 AdvanceIT();
2341 return;
2342 }
2343 }
2344 }
2345 Delegate(kAdd, &Assembler::add, cond, rd, operand);
2346 }
2347
adds(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2348 void Assembler::adds(Condition cond,
2349 EncodingSize size,
2350 Register rd,
2351 Register rn,
2352 const Operand& operand) {
2353 VIXL_ASSERT(AllowAssembler());
2354 CheckIT(cond);
2355 if (operand.IsImmediate()) {
2356 uint32_t imm = operand.GetImmediate();
2357 if (IsUsingT32()) {
2358 ImmediateT32 immediate_t32(imm);
2359 // ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1
2360 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2361 (imm <= 7)) {
2362 EmitT32_16(0x1c00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
2363 AdvanceIT();
2364 return;
2365 }
2366 // ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
2367 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2368 (imm <= 255)) {
2369 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2370 AdvanceIT();
2371 return;
2372 }
2373 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
2374 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
2375 !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) {
2376 EmitT32_32(0xf1100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2377 (immediate_t32.GetEncodingValue() & 0xff) |
2378 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2379 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2380 AdvanceIT();
2381 return;
2382 }
2383 // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
2384 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
2385 !rd.Is(pc)) {
2386 EmitT32_32(0xf11d0000U | (rd.GetCode() << 8) |
2387 (immediate_t32.GetEncodingValue() & 0xff) |
2388 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2389 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2390 AdvanceIT();
2391 return;
2392 }
2393 } else {
2394 ImmediateA32 immediate_a32(imm);
2395 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2396 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
2397 EmitA32(0x02900000U | (cond.GetCondition() << 28) |
2398 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2399 immediate_a32.GetEncodingValue());
2400 return;
2401 }
2402 // ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
2403 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
2404 EmitA32(0x029d0000U | (cond.GetCondition() << 28) |
2405 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
2406 return;
2407 }
2408 }
2409 }
2410 if (operand.IsImmediateShiftedRegister()) {
2411 Register rm = operand.GetBaseRegister();
2412 if (operand.IsPlainRegister()) {
2413 if (IsUsingT32()) {
2414 // ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
2415 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
2416 rm.IsLow()) {
2417 EmitT32_16(0x1800 | rd.GetCode() | (rn.GetCode() << 3) |
2418 (rm.GetCode() << 6));
2419 AdvanceIT();
2420 return;
2421 }
2422 }
2423 }
2424 Shift shift = operand.GetShift();
2425 uint32_t amount = operand.GetShiftAmount();
2426 if (IsUsingT32()) {
2427 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3
2428 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
2429 !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2430 uint32_t amount_ = amount % 32;
2431 EmitT32_32(0xeb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2432 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2433 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2434 AdvanceIT();
2435 return;
2436 }
2437 // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3
2438 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
2439 !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) {
2440 uint32_t amount_ = amount % 32;
2441 EmitT32_32(0xeb1d0000U | (rd.GetCode() << 8) | rm.GetCode() |
2442 (operand.GetTypeEncodingValue() << 4) |
2443 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2444 AdvanceIT();
2445 return;
2446 }
2447 } else {
2448 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2449 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
2450 uint32_t amount_ = amount % 32;
2451 EmitA32(0x00900000U | (cond.GetCondition() << 28) |
2452 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2453 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2454 return;
2455 }
2456 // ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
2457 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
2458 uint32_t amount_ = amount % 32;
2459 EmitA32(0x009d0000U | (cond.GetCondition() << 28) |
2460 (rd.GetCode() << 12) | rm.GetCode() |
2461 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2462 return;
2463 }
2464 }
2465 }
2466 if (operand.IsRegisterShiftedRegister()) {
2467 Register rm = operand.GetBaseRegister();
2468 Shift shift = operand.GetShift();
2469 Register rs = operand.GetShiftRegister();
2470 if (IsUsingA32()) {
2471 // ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2472 if (cond.IsNotNever() &&
2473 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2474 AllowUnpredictable())) {
2475 EmitA32(0x00900010U | (cond.GetCondition() << 28) |
2476 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2477 (shift.GetType() << 5) | (rs.GetCode() << 8));
2478 return;
2479 }
2480 }
2481 }
2482 Delegate(kAdds, &Assembler::adds, cond, size, rd, rn, operand);
2483 }
2484
adds(Register rd,const Operand & operand)2485 void Assembler::adds(Register rd, const Operand& operand) {
2486 VIXL_ASSERT(AllowAssembler());
2487 CheckIT(al);
2488 if (operand.IsImmediate()) {
2489 uint32_t imm = operand.GetImmediate();
2490 if (IsUsingT32()) {
2491 // ADDS{<q>} <Rdn>, #<imm8> ; T2
2492 if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
2493 EmitT32_16(0x3000 | (rd.GetCode() << 8) | imm);
2494 AdvanceIT();
2495 return;
2496 }
2497 }
2498 }
2499 Delegate(kAdds, &Assembler::adds, rd, operand);
2500 }
2501
addw(Condition cond,Register rd,Register rn,const Operand & operand)2502 void Assembler::addw(Condition cond,
2503 Register rd,
2504 Register rn,
2505 const Operand& operand) {
2506 VIXL_ASSERT(AllowAssembler());
2507 CheckIT(cond);
2508 if (operand.IsImmediate()) {
2509 uint32_t imm = operand.GetImmediate();
2510 if (IsUsingT32()) {
2511 // ADDW{<c>}{<q>} <Rd>, PC, #<imm12> ; T3
2512 if (rn.Is(pc) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2513 EmitT32_32(0xf20f0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2514 ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2515 AdvanceIT();
2516 return;
2517 }
2518 // ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
2519 if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
2520 (!rd.IsPC() || AllowUnpredictable())) {
2521 EmitT32_32(0xf2000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2522 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2523 AdvanceIT();
2524 return;
2525 }
2526 // ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
2527 if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2528 EmitT32_32(0xf20d0000U | (rd.GetCode() << 8) | (imm & 0xff) |
2529 ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
2530 AdvanceIT();
2531 return;
2532 }
2533 }
2534 }
2535 Delegate(kAddw, &Assembler::addw, cond, rd, rn, operand);
2536 }
2537
adr(Condition cond,EncodingSize size,Register rd,Location * location)2538 void Assembler::adr(Condition cond,
2539 EncodingSize size,
2540 Register rd,
2541 Location* location) {
2542 VIXL_ASSERT(AllowAssembler());
2543 CheckIT(cond);
2544 Location::Offset offset =
2545 location->IsBound()
2546 ? location->GetLocation() -
2547 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
2548 : 0;
2549 if (IsUsingT32()) {
2550 int32_t neg_offset = -offset;
2551 // ADR{<c>}{<q>} <Rd>, <label> ; T1
2552 if (!size.IsWide() && rd.IsLow() &&
2553 ((location->IsBound() && (offset >= 0) && (offset <= 1020) &&
2554 ((offset & 0x3) == 0)) ||
2555 (!location->IsBound() && size.IsNarrow()))) {
2556 static class EmitOp : public Location::EmitOperator {
2557 public:
2558 EmitOp() : Location::EmitOperator(T32) {}
2559 virtual uint32_t Encode(uint32_t instr,
2560 Location::Offset program_counter,
2561 const Location* loc) const VIXL_OVERRIDE {
2562 program_counter += kT32PcDelta;
2563 Location::Offset off =
2564 loc->GetLocation() - AlignDown(program_counter, 4);
2565 VIXL_ASSERT((off >= 0) && (off <= 1020) && ((off & 0x3) == 0));
2566 const int32_t target = off >> 2;
2567 return instr | (target & 0xff);
2568 }
2569 } immop;
2570 EmitT32_16(
2571 Link(0xa000 | (rd.GetCode() << 8), location, immop, &kT16DataInfo));
2572 AdvanceIT();
2573 return;
2574 }
2575 // ADR{<c>}{<q>} <Rd>, <label> ; T2
2576 if (!size.IsNarrow() && location->IsBound() && (neg_offset > 0) &&
2577 (neg_offset <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
2578 EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (neg_offset & 0xff) |
2579 ((neg_offset & 0x700) << 4) | ((neg_offset & 0x800) << 15));
2580 AdvanceIT();
2581 return;
2582 }
2583 // ADR{<c>}{<q>} <Rd>, <label> ; T3
2584 if (!size.IsNarrow() &&
2585 (!location->IsBound() || ((offset >= 0) && (offset <= 4095))) &&
2586 (!rd.IsPC() || AllowUnpredictable())) {
2587 static class EmitOp : public Location::EmitOperator {
2588 public:
2589 EmitOp() : Location::EmitOperator(T32) {}
2590 virtual uint32_t Encode(uint32_t instr,
2591 Location::Offset program_counter,
2592 const Location* loc) const VIXL_OVERRIDE {
2593 program_counter += kT32PcDelta;
2594 Location::Offset off =
2595 loc->GetLocation() - AlignDown(program_counter, 4);
2596 int32_t target;
2597 if ((off >= 0) && (off <= 4095)) {
2598 target = off;
2599 } else {
2600 target = -off;
2601 VIXL_ASSERT((target >= 0) && (target <= 4095));
2602 // Emit the T2 encoding.
2603 instr |= 0x00a00000;
2604 }
2605 return instr | (target & 0xff) | ((target & 0x700) << 4) |
2606 ((target & 0x800) << 15);
2607 }
2608 } immop;
2609 EmitT32_32(Link(0xf20f0000U | (rd.GetCode() << 8),
2610 location,
2611 immop,
2612 &kT32FarDataInfo));
2613 AdvanceIT();
2614 return;
2615 }
2616 } else {
2617 ImmediateA32 positive_immediate_a32(offset);
2618 ImmediateA32 negative_immediate_a32(-offset);
2619 // ADR{<c>}{<q>} <Rd>, <label> ; A1
2620 if ((!location->IsBound() || positive_immediate_a32.IsValid()) &&
2621 cond.IsNotNever()) {
2622 static class EmitOp : public Location::EmitOperator {
2623 public:
2624 EmitOp() : Location::EmitOperator(A32) {}
2625 virtual uint32_t Encode(uint32_t instr,
2626 Location::Offset program_counter,
2627 const Location* loc) const VIXL_OVERRIDE {
2628 program_counter += kA32PcDelta;
2629 Location::Offset off =
2630 loc->GetLocation() - AlignDown(program_counter, 4);
2631 int32_t target;
2632 ImmediateA32 pos_imm_a32(off);
2633 if (pos_imm_a32.IsValid()) {
2634 target = pos_imm_a32.GetEncodingValue();
2635 } else {
2636 ImmediateA32 neg_imm_a32(-off);
2637 VIXL_ASSERT(neg_imm_a32.IsValid());
2638 // Emit the A2 encoding.
2639 target = neg_imm_a32.GetEncodingValue();
2640 instr = (instr & ~0x00f00000) | 0x00400000;
2641 }
2642 return instr | (target & 0xfff);
2643 }
2644 } immop;
2645 EmitA32(
2646 Link(0x028f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12),
2647 location,
2648 immop,
2649 &kA32AdrInfo));
2650 return;
2651 }
2652 // ADR{<c>}{<q>} <Rd>, <label> ; A2
2653 if (location->IsBound() && negative_immediate_a32.IsValid() &&
2654 cond.IsNotNever()) {
2655 EmitA32(0x024f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
2656 negative_immediate_a32.GetEncodingValue());
2657 return;
2658 }
2659 }
2660 Delegate(kAdr, &Assembler::adr, cond, size, rd, location);
2661 }
2662
adr_info(Condition cond,EncodingSize size,Register rd,Location * location,const struct ReferenceInfo ** info)2663 bool Assembler::adr_info(Condition cond,
2664 EncodingSize size,
2665 Register rd,
2666 Location* location,
2667 const struct ReferenceInfo** info) {
2668 VIXL_ASSERT(!location->IsBound());
2669 USE(location);
2670 if (IsUsingT32()) {
2671 // ADR{<c>}{<q>} <Rd>, <label> ; T1
2672 if (!size.IsWide() && rd.IsLow() && size.IsNarrow()) {
2673 *info = &kT16DataInfo;
2674 return true;
2675 }
2676 // Skipped T2, as it is a negative offset variant.
2677 // The minimum offset is included in the corresponding
2678 // positive variant.
2679 // ADR{<c>}{<q>} <Rd>, <label> ; T3
2680 if (!size.IsNarrow()) {
2681 *info = &kT32FarDataInfo;
2682 return true;
2683 }
2684 } else {
2685 // ADR{<c>}{<q>} <Rd>, <label> ; A1
2686 if (cond.IsNotNever()) {
2687 *info = &kA32AdrInfo;
2688 return true;
2689 }
2690 // Skipped A2, as it is a negative offset variant.
2691 // The minimum offset is included in the corresponding
2692 // positive variant.
2693 }
2694 return false;
2695 }
2696
and_(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2697 void Assembler::and_(Condition cond,
2698 EncodingSize size,
2699 Register rd,
2700 Register rn,
2701 const Operand& operand) {
2702 VIXL_ASSERT(AllowAssembler());
2703 CheckIT(cond);
2704 if (operand.IsImmediate()) {
2705 uint32_t imm = operand.GetImmediate();
2706 if (IsUsingT32()) {
2707 ImmediateT32 immediate_t32(imm);
2708 // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2709 if (!size.IsNarrow() && immediate_t32.IsValid() &&
2710 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
2711 EmitT32_32(0xf0000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2712 (immediate_t32.GetEncodingValue() & 0xff) |
2713 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2714 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2715 AdvanceIT();
2716 return;
2717 }
2718 } else {
2719 ImmediateA32 immediate_a32(imm);
2720 // AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2721 if (immediate_a32.IsValid() && cond.IsNotNever()) {
2722 EmitA32(0x02000000U | (cond.GetCondition() << 28) |
2723 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2724 immediate_a32.GetEncodingValue());
2725 return;
2726 }
2727 }
2728 }
2729 if (operand.IsImmediateShiftedRegister()) {
2730 Register rm = operand.GetBaseRegister();
2731 if (operand.IsPlainRegister()) {
2732 if (IsUsingT32()) {
2733 // AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2734 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2735 rm.IsLow()) {
2736 EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2737 AdvanceIT();
2738 return;
2739 }
2740 }
2741 }
2742 Shift shift = operand.GetShift();
2743 uint32_t amount = operand.GetShiftAmount();
2744 if (IsUsingT32()) {
2745 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2746 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
2747 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2748 uint32_t amount_ = amount % 32;
2749 EmitT32_32(0xea000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2750 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2751 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2752 AdvanceIT();
2753 return;
2754 }
2755 } else {
2756 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2757 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2758 uint32_t amount_ = amount % 32;
2759 EmitA32(0x00000000U | (cond.GetCondition() << 28) |
2760 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2761 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2762 return;
2763 }
2764 }
2765 }
2766 if (operand.IsRegisterShiftedRegister()) {
2767 Register rm = operand.GetBaseRegister();
2768 Shift shift = operand.GetShift();
2769 Register rs = operand.GetShiftRegister();
2770 if (IsUsingA32()) {
2771 // AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2772 if (cond.IsNotNever() &&
2773 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2774 AllowUnpredictable())) {
2775 EmitA32(0x00000010U | (cond.GetCondition() << 28) |
2776 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2777 (shift.GetType() << 5) | (rs.GetCode() << 8));
2778 return;
2779 }
2780 }
2781 }
2782 Delegate(kAnd, &Assembler::and_, cond, size, rd, rn, operand);
2783 }
2784
ands(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)2785 void Assembler::ands(Condition cond,
2786 EncodingSize size,
2787 Register rd,
2788 Register rn,
2789 const Operand& operand) {
2790 VIXL_ASSERT(AllowAssembler());
2791 CheckIT(cond);
2792 if (operand.IsImmediate()) {
2793 uint32_t imm = operand.GetImmediate();
2794 if (IsUsingT32()) {
2795 ImmediateT32 immediate_t32(imm);
2796 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
2797 if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) &&
2798 (!rn.IsPC() || AllowUnpredictable())) {
2799 EmitT32_32(0xf0100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2800 (immediate_t32.GetEncodingValue() & 0xff) |
2801 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
2802 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
2803 AdvanceIT();
2804 return;
2805 }
2806 } else {
2807 ImmediateA32 immediate_a32(imm);
2808 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
2809 if (immediate_a32.IsValid() && cond.IsNotNever()) {
2810 EmitA32(0x02100000U | (cond.GetCondition() << 28) |
2811 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
2812 immediate_a32.GetEncodingValue());
2813 return;
2814 }
2815 }
2816 }
2817 if (operand.IsImmediateShiftedRegister()) {
2818 Register rm = operand.GetBaseRegister();
2819 if (operand.IsPlainRegister()) {
2820 if (IsUsingT32()) {
2821 // ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
2822 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
2823 rm.IsLow()) {
2824 EmitT32_16(0x4000 | rd.GetCode() | (rm.GetCode() << 3));
2825 AdvanceIT();
2826 return;
2827 }
2828 }
2829 }
2830 Shift shift = operand.GetShift();
2831 uint32_t amount = operand.GetShiftAmount();
2832 if (IsUsingT32()) {
2833 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
2834 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) &&
2835 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2836 uint32_t amount_ = amount % 32;
2837 EmitT32_32(0xea100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
2838 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
2839 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2840 AdvanceIT();
2841 return;
2842 }
2843 } else {
2844 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
2845 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
2846 uint32_t amount_ = amount % 32;
2847 EmitA32(0x00100000U | (cond.GetCondition() << 28) |
2848 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2849 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
2850 return;
2851 }
2852 }
2853 }
2854 if (operand.IsRegisterShiftedRegister()) {
2855 Register rm = operand.GetBaseRegister();
2856 Shift shift = operand.GetShift();
2857 Register rs = operand.GetShiftRegister();
2858 if (IsUsingA32()) {
2859 // ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
2860 if (cond.IsNotNever() &&
2861 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
2862 AllowUnpredictable())) {
2863 EmitA32(0x00100010U | (cond.GetCondition() << 28) |
2864 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
2865 (shift.GetType() << 5) | (rs.GetCode() << 8));
2866 return;
2867 }
2868 }
2869 }
2870 Delegate(kAnds, &Assembler::ands, cond, size, rd, rn, operand);
2871 }
2872
asr(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)2873 void Assembler::asr(Condition cond,
2874 EncodingSize size,
2875 Register rd,
2876 Register rm,
2877 const Operand& operand) {
2878 VIXL_ASSERT(AllowAssembler());
2879 CheckIT(cond);
2880 if (operand.IsImmediate()) {
2881 uint32_t imm = operand.GetImmediate();
2882 if (IsUsingT32()) {
2883 // ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2884 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2885 (imm >= 1) && (imm <= 32)) {
2886 uint32_t amount_ = imm % 32;
2887 EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2888 (amount_ << 6));
2889 AdvanceIT();
2890 return;
2891 }
2892 // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2893 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
2894 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2895 uint32_t amount_ = imm % 32;
2896 EmitT32_32(0xea4f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2897 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2898 AdvanceIT();
2899 return;
2900 }
2901 } else {
2902 // ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2903 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2904 uint32_t amount_ = imm % 32;
2905 EmitA32(0x01a00040U | (cond.GetCondition() << 28) |
2906 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2907 return;
2908 }
2909 }
2910 }
2911 if (operand.IsPlainRegister()) {
2912 Register rs = operand.GetBaseRegister();
2913 if (IsUsingT32()) {
2914 // ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2915 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2916 rs.IsLow()) {
2917 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2918 AdvanceIT();
2919 return;
2920 }
2921 // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2922 if (!size.IsNarrow() &&
2923 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
2924 EmitT32_32(0xfa40f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2925 rs.GetCode());
2926 AdvanceIT();
2927 return;
2928 }
2929 } else {
2930 // ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
2931 if (cond.IsNotNever() &&
2932 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
2933 EmitA32(0x01a00050U | (cond.GetCondition() << 28) |
2934 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
2935 return;
2936 }
2937 }
2938 }
2939 Delegate(kAsr, &Assembler::asr, cond, size, rd, rm, operand);
2940 }
2941
asrs(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)2942 void Assembler::asrs(Condition cond,
2943 EncodingSize size,
2944 Register rd,
2945 Register rm,
2946 const Operand& operand) {
2947 VIXL_ASSERT(AllowAssembler());
2948 CheckIT(cond);
2949 if (operand.IsImmediate()) {
2950 uint32_t imm = operand.GetImmediate();
2951 if (IsUsingT32()) {
2952 // ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
2953 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
2954 (imm >= 1) && (imm <= 32)) {
2955 uint32_t amount_ = imm % 32;
2956 EmitT32_16(0x1000 | rd.GetCode() | (rm.GetCode() << 3) |
2957 (amount_ << 6));
2958 AdvanceIT();
2959 return;
2960 }
2961 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
2962 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
2963 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
2964 uint32_t amount_ = imm % 32;
2965 EmitT32_32(0xea5f0020U | (rd.GetCode() << 8) | rm.GetCode() |
2966 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
2967 AdvanceIT();
2968 return;
2969 }
2970 } else {
2971 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
2972 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
2973 uint32_t amount_ = imm % 32;
2974 EmitA32(0x01b00040U | (cond.GetCondition() << 28) |
2975 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
2976 return;
2977 }
2978 }
2979 }
2980 if (operand.IsPlainRegister()) {
2981 Register rs = operand.GetBaseRegister();
2982 if (IsUsingT32()) {
2983 // ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
2984 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
2985 rs.IsLow()) {
2986 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
2987 AdvanceIT();
2988 return;
2989 }
2990 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
2991 if (!size.IsNarrow() &&
2992 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
2993 EmitT32_32(0xfa50f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
2994 rs.GetCode());
2995 AdvanceIT();
2996 return;
2997 }
2998 } else {
2999 // ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
3000 if (cond.IsNotNever() &&
3001 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
3002 EmitA32(0x01b00050U | (cond.GetCondition() << 28) |
3003 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
3004 return;
3005 }
3006 }
3007 }
3008 Delegate(kAsrs, &Assembler::asrs, cond, size, rd, rm, operand);
3009 }
3010
b(Condition cond,EncodingSize size,Location * location)3011 void Assembler::b(Condition cond, EncodingSize size, Location* location) {
3012 VIXL_ASSERT(AllowAssembler());
3013 Location::Offset offset =
3014 location->IsBound()
3015 ? location->GetLocation() -
3016 (GetCursorOffset() + GetArchitectureStatePCOffset())
3017 : 0;
3018 if (IsUsingT32()) {
3019 // B<c>{<q>} <label> ; T1
3020 if (OutsideITBlock() && !size.IsWide() &&
3021 ((location->IsBound() && (offset >= -256) && (offset <= 254) &&
3022 ((offset & 0x1) == 0)) ||
3023 (!location->IsBound() && size.IsNarrow())) &&
3024 !cond.Is(al) && cond.IsNotNever()) {
3025 static class EmitOp : public Location::EmitOperator {
3026 public:
3027 EmitOp() : Location::EmitOperator(T32) {}
3028 virtual uint32_t Encode(uint32_t instr,
3029 Location::Offset program_counter,
3030 const Location* loc) const VIXL_OVERRIDE {
3031 program_counter += kT32PcDelta;
3032 Location::Offset off = loc->GetLocation() - program_counter;
3033 VIXL_ASSERT((off >= -256) && (off <= 254) && ((off & 0x1) == 0));
3034 const int32_t target = off >> 1;
3035 return instr | (target & 0xff);
3036 }
3037 } immop;
3038 EmitT32_16(Link(0xd000 | (cond.GetCondition() << 8),
3039 location,
3040 immop,
3041 &kT16ConditionalBranchInfo));
3042 AdvanceIT();
3043 return;
3044 }
3045 // B{<c>}{<q>} <label> ; T2
3046 if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() &&
3047 ((location->IsBound() && (offset >= -2048) && (offset <= 2046) &&
3048 ((offset & 0x1) == 0)) ||
3049 (!location->IsBound() && size.IsNarrow()))) {
3050 CheckIT(cond);
3051 static class EmitOp : public Location::EmitOperator {
3052 public:
3053 EmitOp() : Location::EmitOperator(T32) {}
3054 virtual uint32_t Encode(uint32_t instr,
3055 Location::Offset program_counter,
3056 const Location* loc) const VIXL_OVERRIDE {
3057 program_counter += kT32PcDelta;
3058 Location::Offset off = loc->GetLocation() - program_counter;
3059 VIXL_ASSERT((off >= -2048) && (off <= 2046) && ((off & 0x1) == 0));
3060 const int32_t target = off >> 1;
3061 return instr | (target & 0x7ff);
3062 }
3063 } immop;
3064 EmitT32_16(Link(0xe000, location, immop, &kT16BranchInfo));
3065 AdvanceIT();
3066 return;
3067 }
3068 // B<c>{<q>} <label> ; T3
3069 if (OutsideITBlock() && !size.IsNarrow() &&
3070 ((location->IsBound() && (offset >= -1048576) && (offset <= 1048574) &&
3071 ((offset & 0x1) == 0)) ||
3072 !location->IsBound()) &&
3073 !cond.Is(al) && cond.IsNotNever()) {
3074 static class EmitOp : public Location::EmitOperator {
3075 public:
3076 EmitOp() : Location::EmitOperator(T32) {}
3077 virtual uint32_t Encode(uint32_t instr,
3078 Location::Offset program_counter,
3079 const Location* loc) const VIXL_OVERRIDE {
3080 program_counter += kT32PcDelta;
3081 Location::Offset off = loc->GetLocation() - program_counter;
3082 VIXL_ASSERT((off >= -1048576) && (off <= 1048574) &&
3083 ((off & 0x1) == 0));
3084 const int32_t target = off >> 1;
3085 return instr | (target & 0x7ff) | ((target & 0x1f800) << 5) |
3086 ((target & 0x20000) >> 4) | ((target & 0x40000) >> 7) |
3087 ((target & 0x80000) << 7);
3088 }
3089 } immop;
3090 EmitT32_32(Link(0xf0008000U | (cond.GetCondition() << 22),
3091 location,
3092 immop,
3093 &kT32ConditionalBranchInfo));
3094 AdvanceIT();
3095 return;
3096 }
3097 // B{<c>}{<q>} <label> ; T4
3098 if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow() &&
3099 ((location->IsBound() && (offset >= -16777216) &&
3100 (offset <= 16777214) && ((offset & 0x1) == 0)) ||
3101 !location->IsBound())) {
3102 CheckIT(cond);
3103 static class EmitOp : public Location::EmitOperator {
3104 public:
3105 EmitOp() : Location::EmitOperator(T32) {}
3106 virtual uint32_t Encode(uint32_t instr,
3107 Location::Offset program_counter,
3108 const Location* loc) const VIXL_OVERRIDE {
3109 program_counter += kT32PcDelta;
3110 Location::Offset off = loc->GetLocation() - program_counter;
3111 VIXL_ASSERT((off >= -16777216) && (off <= 16777214) &&
3112 ((off & 0x1) == 0));
3113 int32_t target = off >> 1;
3114 uint32_t S = target & (1 << 23);
3115 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
3116 return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
3117 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
3118 ((target & 0x800000) << 3);
3119 }
3120 } immop;
3121 EmitT32_32(Link(0xf0009000U, location, immop, &kT32BranchInfo));
3122 AdvanceIT();
3123 return;
3124 }
3125 } else {
3126 // B{<c>}{<q>} <label> ; A1
3127 if (((location->IsBound() && (offset >= -33554432) &&
3128 (offset <= 33554428) && ((offset & 0x3) == 0)) ||
3129 !location->IsBound()) &&
3130 cond.IsNotNever()) {
3131 static class EmitOp : public Location::EmitOperator {
3132 public:
3133 EmitOp() : Location::EmitOperator(A32) {}
3134 virtual uint32_t Encode(uint32_t instr,
3135 Location::Offset program_counter,
3136 const Location* loc) const VIXL_OVERRIDE {
3137 program_counter += kA32PcDelta;
3138 Location::Offset off = loc->GetLocation() - program_counter;
3139 VIXL_ASSERT((off >= -33554432) && (off <= 33554428) &&
3140 ((off & 0x3) == 0));
3141 const int32_t target = off >> 2;
3142 return instr | (target & 0xffffff);
3143 }
3144 } immop;
3145 EmitA32(Link(0x0a000000U | (cond.GetCondition() << 28),
3146 location,
3147 immop,
3148 &kA32BranchInfo));
3149 return;
3150 }
3151 }
3152 Delegate(kB, &Assembler::b, cond, size, location);
3153 }
3154
b_info(Condition cond,EncodingSize size,Location * location,const struct ReferenceInfo ** info)3155 bool Assembler::b_info(Condition cond,
3156 EncodingSize size,
3157 Location* location,
3158 const struct ReferenceInfo** info) {
3159 VIXL_ASSERT(!location->IsBound());
3160 USE(location);
3161 if (IsUsingT32()) {
3162 // B<c>{<q>} <label> ; T1
3163 if (OutsideITBlock() && !size.IsWide() && size.IsNarrow() && !cond.Is(al) &&
3164 cond.IsNotNever()) {
3165 *info = &kT16ConditionalBranchInfo;
3166 return true;
3167 }
3168 // B{<c>}{<q>} <label> ; T2
3169 if (OutsideITBlockAndAlOrLast(cond) && !size.IsWide() && size.IsNarrow()) {
3170 *info = &kT16BranchInfo;
3171 return true;
3172 }
3173 // B<c>{<q>} <label> ; T3
3174 if (OutsideITBlock() && !size.IsNarrow() && !cond.Is(al) &&
3175 cond.IsNotNever()) {
3176 *info = &kT32ConditionalBranchInfo;
3177 return true;
3178 }
3179 // B{<c>}{<q>} <label> ; T4
3180 if (OutsideITBlockAndAlOrLast(cond) && !size.IsNarrow()) {
3181 *info = &kT32BranchInfo;
3182 return true;
3183 }
3184 } else {
3185 // B{<c>}{<q>} <label> ; A1
3186 if (cond.IsNotNever()) {
3187 *info = &kA32BranchInfo;
3188 return true;
3189 }
3190 }
3191 return false;
3192 }
3193
bfc(Condition cond,Register rd,uint32_t lsb,uint32_t width)3194 void Assembler::bfc(Condition cond, Register rd, uint32_t lsb, uint32_t width) {
3195 VIXL_ASSERT(AllowAssembler());
3196 CheckIT(cond);
3197 if (IsUsingT32()) {
3198 // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1
3199 if ((lsb <= 31) && (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
3200 AllowUnpredictable())) {
3201 uint32_t msb = lsb + width - 1;
3202 EmitT32_32(0xf36f0000U | (rd.GetCode() << 8) | ((lsb & 0x3) << 6) |
3203 ((lsb & 0x1c) << 10) | msb);
3204 AdvanceIT();
3205 return;
3206 }
3207 } else {
3208 // BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1
3209 if ((lsb <= 31) && cond.IsNotNever() &&
3210 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
3211 AllowUnpredictable())) {
3212 uint32_t msb = lsb + width - 1;
3213 EmitA32(0x07c0001fU | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3214 (lsb << 7) | (msb << 16));
3215 return;
3216 }
3217 }
3218 Delegate(kBfc, &Assembler::bfc, cond, rd, lsb, width);
3219 }
3220
bfi(Condition cond,Register rd,Register rn,uint32_t lsb,uint32_t width)3221 void Assembler::bfi(
3222 Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
3223 VIXL_ASSERT(AllowAssembler());
3224 CheckIT(cond);
3225 if (IsUsingT32()) {
3226 // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
3227 if ((lsb <= 31) && !rn.Is(pc) &&
3228 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
3229 AllowUnpredictable())) {
3230 uint32_t msb = lsb + width - 1;
3231 EmitT32_32(0xf3600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3232 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | msb);
3233 AdvanceIT();
3234 return;
3235 }
3236 } else {
3237 // BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
3238 if ((lsb <= 31) && cond.IsNotNever() && !rn.Is(pc) &&
3239 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC()) ||
3240 AllowUnpredictable())) {
3241 uint32_t msb = lsb + width - 1;
3242 EmitA32(0x07c00010U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3243 rn.GetCode() | (lsb << 7) | (msb << 16));
3244 return;
3245 }
3246 }
3247 Delegate(kBfi, &Assembler::bfi, cond, rd, rn, lsb, width);
3248 }
3249
bic(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)3250 void Assembler::bic(Condition cond,
3251 EncodingSize size,
3252 Register rd,
3253 Register rn,
3254 const Operand& operand) {
3255 VIXL_ASSERT(AllowAssembler());
3256 CheckIT(cond);
3257 if (operand.IsImmediate()) {
3258 uint32_t imm = operand.GetImmediate();
3259 if (IsUsingT32()) {
3260 ImmediateT32 immediate_t32(imm);
3261 // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3262 if (!size.IsNarrow() && immediate_t32.IsValid() &&
3263 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
3264 EmitT32_32(0xf0200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3265 (immediate_t32.GetEncodingValue() & 0xff) |
3266 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3267 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3268 AdvanceIT();
3269 return;
3270 }
3271 } else {
3272 ImmediateA32 immediate_a32(imm);
3273 // BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3274 if (immediate_a32.IsValid() && cond.IsNotNever()) {
3275 EmitA32(0x03c00000U | (cond.GetCondition() << 28) |
3276 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3277 immediate_a32.GetEncodingValue());
3278 return;
3279 }
3280 }
3281 }
3282 if (operand.IsImmediateShiftedRegister()) {
3283 Register rm = operand.GetBaseRegister();
3284 if (operand.IsPlainRegister()) {
3285 if (IsUsingT32()) {
3286 // BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3287 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3288 rm.IsLow()) {
3289 EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3290 AdvanceIT();
3291 return;
3292 }
3293 }
3294 }
3295 Shift shift = operand.GetShift();
3296 uint32_t amount = operand.GetShiftAmount();
3297 if (IsUsingT32()) {
3298 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3299 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
3300 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3301 uint32_t amount_ = amount % 32;
3302 EmitT32_32(0xea200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3303 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3304 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3305 AdvanceIT();
3306 return;
3307 }
3308 } else {
3309 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3310 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3311 uint32_t amount_ = amount % 32;
3312 EmitA32(0x01c00000U | (cond.GetCondition() << 28) |
3313 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3314 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3315 return;
3316 }
3317 }
3318 }
3319 if (operand.IsRegisterShiftedRegister()) {
3320 Register rm = operand.GetBaseRegister();
3321 Shift shift = operand.GetShift();
3322 Register rs = operand.GetShiftRegister();
3323 if (IsUsingA32()) {
3324 // BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3325 if (cond.IsNotNever() &&
3326 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
3327 AllowUnpredictable())) {
3328 EmitA32(0x01c00010U | (cond.GetCondition() << 28) |
3329 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3330 (shift.GetType() << 5) | (rs.GetCode() << 8));
3331 return;
3332 }
3333 }
3334 }
3335 Delegate(kBic, &Assembler::bic, cond, size, rd, rn, operand);
3336 }
3337
bics(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)3338 void Assembler::bics(Condition cond,
3339 EncodingSize size,
3340 Register rd,
3341 Register rn,
3342 const Operand& operand) {
3343 VIXL_ASSERT(AllowAssembler());
3344 CheckIT(cond);
3345 if (operand.IsImmediate()) {
3346 uint32_t imm = operand.GetImmediate();
3347 if (IsUsingT32()) {
3348 ImmediateT32 immediate_t32(imm);
3349 // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
3350 if (!size.IsNarrow() && immediate_t32.IsValid() &&
3351 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
3352 EmitT32_32(0xf0300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3353 (immediate_t32.GetEncodingValue() & 0xff) |
3354 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3355 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3356 AdvanceIT();
3357 return;
3358 }
3359 } else {
3360 ImmediateA32 immediate_a32(imm);
3361 // BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
3362 if (immediate_a32.IsValid() && cond.IsNotNever()) {
3363 EmitA32(0x03d00000U | (cond.GetCondition() << 28) |
3364 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
3365 immediate_a32.GetEncodingValue());
3366 return;
3367 }
3368 }
3369 }
3370 if (operand.IsImmediateShiftedRegister()) {
3371 Register rm = operand.GetBaseRegister();
3372 if (operand.IsPlainRegister()) {
3373 if (IsUsingT32()) {
3374 // BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
3375 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
3376 rm.IsLow()) {
3377 EmitT32_16(0x4380 | rd.GetCode() | (rm.GetCode() << 3));
3378 AdvanceIT();
3379 return;
3380 }
3381 }
3382 }
3383 Shift shift = operand.GetShift();
3384 uint32_t amount = operand.GetShiftAmount();
3385 if (IsUsingT32()) {
3386 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
3387 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
3388 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3389 uint32_t amount_ = amount % 32;
3390 EmitT32_32(0xea300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
3391 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
3392 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3393 AdvanceIT();
3394 return;
3395 }
3396 } else {
3397 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
3398 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3399 uint32_t amount_ = amount % 32;
3400 EmitA32(0x01d00000U | (cond.GetCondition() << 28) |
3401 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3402 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3403 return;
3404 }
3405 }
3406 }
3407 if (operand.IsRegisterShiftedRegister()) {
3408 Register rm = operand.GetBaseRegister();
3409 Shift shift = operand.GetShift();
3410 Register rs = operand.GetShiftRegister();
3411 if (IsUsingA32()) {
3412 // BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
3413 if (cond.IsNotNever() &&
3414 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
3415 AllowUnpredictable())) {
3416 EmitA32(0x01d00010U | (cond.GetCondition() << 28) |
3417 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
3418 (shift.GetType() << 5) | (rs.GetCode() << 8));
3419 return;
3420 }
3421 }
3422 }
3423 Delegate(kBics, &Assembler::bics, cond, size, rd, rn, operand);
3424 }
3425
bkpt(Condition cond,uint32_t imm)3426 void Assembler::bkpt(Condition cond, uint32_t imm) {
3427 VIXL_ASSERT(AllowAssembler());
3428 CheckIT(cond);
3429 if (IsUsingT32()) {
3430 // BKPT{<q>} {#}<imm> ; T1
3431 if ((imm <= 255)) {
3432 EmitT32_16(0xbe00 | imm);
3433 AdvanceIT();
3434 return;
3435 }
3436 } else {
3437 // BKPT{<q>} {#}<imm> ; A1
3438 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
3439 EmitA32(0x01200070U | (cond.GetCondition() << 28) | (imm & 0xf) |
3440 ((imm & 0xfff0) << 4));
3441 return;
3442 }
3443 }
3444 Delegate(kBkpt, &Assembler::bkpt, cond, imm);
3445 }
3446
bl(Condition cond,Location * location)3447 void Assembler::bl(Condition cond, Location* location) {
3448 VIXL_ASSERT(AllowAssembler());
3449 CheckIT(cond);
3450 Location::Offset offset =
3451 location->IsBound()
3452 ? location->GetLocation() -
3453 (GetCursorOffset() + GetArchitectureStatePCOffset())
3454 : 0;
3455 if (IsUsingT32()) {
3456 // BL{<c>}{<q>} <label> ; T1
3457 if (((location->IsBound() && (offset >= -16777216) &&
3458 (offset <= 16777214) && ((offset & 0x1) == 0)) ||
3459 !location->IsBound()) &&
3460 (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
3461 static class EmitOp : public Location::EmitOperator {
3462 public:
3463 EmitOp() : Location::EmitOperator(T32) {}
3464 virtual uint32_t Encode(uint32_t instr,
3465 Location::Offset program_counter,
3466 const Location* loc) const VIXL_OVERRIDE {
3467 program_counter += kT32PcDelta;
3468 Location::Offset off = loc->GetLocation() - program_counter;
3469 VIXL_ASSERT((off >= -16777216) && (off <= 16777214) &&
3470 ((off & 0x1) == 0));
3471 int32_t target = off >> 1;
3472 uint32_t S = target & (1 << 23);
3473 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
3474 return instr | (target & 0x7ff) | ((target & 0x1ff800) << 5) |
3475 ((target & 0x200000) >> 10) | ((target & 0x400000) >> 9) |
3476 ((target & 0x800000) << 3);
3477 }
3478 } immop;
3479 EmitT32_32(Link(0xf000d000U, location, immop, &kT32BranchInfo));
3480 AdvanceIT();
3481 return;
3482 }
3483 } else {
3484 // BL{<c>}{<q>} <label> ; A1
3485 if (((location->IsBound() && (offset >= -33554432) &&
3486 (offset <= 33554428) && ((offset & 0x3) == 0)) ||
3487 !location->IsBound()) &&
3488 cond.IsNotNever()) {
3489 static class EmitOp : public Location::EmitOperator {
3490 public:
3491 EmitOp() : Location::EmitOperator(A32) {}
3492 virtual uint32_t Encode(uint32_t instr,
3493 Location::Offset program_counter,
3494 const Location* loc) const VIXL_OVERRIDE {
3495 program_counter += kA32PcDelta;
3496 Location::Offset off = loc->GetLocation() - program_counter;
3497 VIXL_ASSERT((off >= -33554432) && (off <= 33554428) &&
3498 ((off & 0x3) == 0));
3499 const int32_t target = off >> 2;
3500 return instr | (target & 0xffffff);
3501 }
3502 } immop;
3503 EmitA32(Link(0x0b000000U | (cond.GetCondition() << 28),
3504 location,
3505 immop,
3506 &kA32BranchInfo));
3507 return;
3508 }
3509 }
3510 Delegate(kBl, &Assembler::bl, cond, location);
3511 }
3512
bl_info(Condition cond,Location * location,const struct ReferenceInfo ** info)3513 bool Assembler::bl_info(Condition cond,
3514 Location* location,
3515 const struct ReferenceInfo** info) {
3516 VIXL_ASSERT(!location->IsBound());
3517 USE(location);
3518 if (IsUsingT32()) {
3519 // BL{<c>}{<q>} <label> ; T1
3520 if (true) {
3521 *info = &kT32BranchInfo;
3522 return true;
3523 }
3524 } else {
3525 // BL{<c>}{<q>} <label> ; A1
3526 if (cond.IsNotNever()) {
3527 *info = &kA32BranchInfo;
3528 return true;
3529 }
3530 }
3531 return false;
3532 }
3533
blx(Condition cond,Location * location)3534 void Assembler::blx(Condition cond, Location* location) {
3535 VIXL_ASSERT(AllowAssembler());
3536 CheckIT(cond);
3537 Location::Offset offset =
3538 location->IsBound()
3539 ? location->GetLocation() -
3540 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
3541 : 0;
3542 if (IsUsingT32()) {
3543 // BLX{<c>}{<q>} <label> ; T2
3544 if (((location->IsBound() && (offset >= -16777216) &&
3545 (offset <= 16777212) && ((offset & 0x3) == 0)) ||
3546 !location->IsBound()) &&
3547 (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
3548 static class EmitOp : public Location::EmitOperator {
3549 public:
3550 EmitOp() : Location::EmitOperator(T32) {}
3551 virtual uint32_t Encode(uint32_t instr,
3552 Location::Offset program_counter,
3553 const Location* loc) const VIXL_OVERRIDE {
3554 program_counter += kT32PcDelta;
3555 Location::Offset off =
3556 loc->GetLocation() - AlignDown(program_counter, 4);
3557 VIXL_ASSERT((off >= -16777216) && (off <= 16777212) &&
3558 ((off & 0x3) == 0));
3559 int32_t target = off >> 2;
3560 uint32_t S = target & (1 << 22);
3561 target ^= ((S >> 1) | (S >> 2)) ^ (3 << 20);
3562 return instr | ((target & 0x3ff) << 1) | ((target & 0xffc00) << 6) |
3563 ((target & 0x100000) >> 9) | ((target & 0x200000) >> 8) |
3564 ((target & 0x400000) << 4);
3565 }
3566 } immop;
3567 EmitT32_32(Link(0xf000c000U, location, immop, &kT32BlxInfo));
3568 AdvanceIT();
3569 return;
3570 }
3571 } else {
3572 // BLX{<c>}{<q>} <label> ; A2
3573 if (((location->IsBound() && (offset >= -33554432) &&
3574 (offset <= 33554430) && ((offset & 0x1) == 0)) ||
3575 !location->IsBound())) {
3576 if (cond.Is(al) || AllowStronglyDiscouraged()) {
3577 static class EmitOp : public Location::EmitOperator {
3578 public:
3579 EmitOp() : Location::EmitOperator(A32) {}
3580 virtual uint32_t Encode(uint32_t instr,
3581 Location::Offset program_counter,
3582 const Location* loc) const VIXL_OVERRIDE {
3583 program_counter += kA32PcDelta;
3584 Location::Offset off =
3585 loc->GetLocation() - AlignDown(program_counter, 4);
3586 VIXL_ASSERT((off >= -33554432) && (off <= 33554430) &&
3587 ((off & 0x1) == 0));
3588 const int32_t target = off >> 1;
3589 return instr | ((target & 0x1) << 24) | ((target & 0x1fffffe) >> 1);
3590 }
3591 } immop;
3592 EmitA32(Link(0xfa000000U, location, immop, &kA32BlxInfo));
3593 return;
3594 }
3595 }
3596 }
3597 Delegate(kBlx, &Assembler::blx, cond, location);
3598 }
3599
blx_info(Condition cond,Location * location,const struct ReferenceInfo ** info)3600 bool Assembler::blx_info(Condition cond,
3601 Location* location,
3602 const struct ReferenceInfo** info) {
3603 VIXL_ASSERT(!location->IsBound());
3604 USE(location);
3605 USE(cond);
3606 if (IsUsingT32()) {
3607 // BLX{<c>}{<q>} <label> ; T2
3608 if (true) {
3609 *info = &kT32BlxInfo;
3610 return true;
3611 }
3612 } else {
3613 // BLX{<c>}{<q>} <label> ; A2
3614 if (true) {
3615 *info = &kA32BlxInfo;
3616 return true;
3617 }
3618 }
3619 return false;
3620 }
3621
blx(Condition cond,Register rm)3622 void Assembler::blx(Condition cond, Register rm) {
3623 VIXL_ASSERT(AllowAssembler());
3624 CheckIT(cond);
3625 if (IsUsingT32()) {
3626 // BLX{<c>}{<q>} <Rm> ; T1
3627 if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) ||
3628 AllowUnpredictable())) {
3629 EmitT32_16(0x4780 | (rm.GetCode() << 3));
3630 AdvanceIT();
3631 return;
3632 }
3633 } else {
3634 // BLX{<c>}{<q>} <Rm> ; A1
3635 if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
3636 EmitA32(0x012fff30U | (cond.GetCondition() << 28) | rm.GetCode());
3637 return;
3638 }
3639 }
3640 Delegate(kBlx, &Assembler::blx, cond, rm);
3641 }
3642
bx(Condition cond,Register rm)3643 void Assembler::bx(Condition cond, Register rm) {
3644 VIXL_ASSERT(AllowAssembler());
3645 CheckIT(cond);
3646 if (IsUsingT32()) {
3647 // BX{<c>}{<q>} <Rm> ; T1
3648 if ((OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
3649 EmitT32_16(0x4700 | (rm.GetCode() << 3));
3650 AdvanceIT();
3651 return;
3652 }
3653 } else {
3654 // BX{<c>}{<q>} <Rm> ; A1
3655 if (cond.IsNotNever()) {
3656 EmitA32(0x012fff10U | (cond.GetCondition() << 28) | rm.GetCode());
3657 return;
3658 }
3659 }
3660 Delegate(kBx, &Assembler::bx, cond, rm);
3661 }
3662
bxj(Condition cond,Register rm)3663 void Assembler::bxj(Condition cond, Register rm) {
3664 VIXL_ASSERT(AllowAssembler());
3665 CheckIT(cond);
3666 if (IsUsingT32()) {
3667 // BXJ{<c>}{<q>} <Rm> ; T1
3668 if (((!rm.IsPC() && OutsideITBlockAndAlOrLast(cond)) ||
3669 AllowUnpredictable())) {
3670 EmitT32_32(0xf3c08f00U | (rm.GetCode() << 16));
3671 AdvanceIT();
3672 return;
3673 }
3674 } else {
3675 // BXJ{<c>}{<q>} <Rm> ; A1
3676 if (cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
3677 EmitA32(0x012fff20U | (cond.GetCondition() << 28) | rm.GetCode());
3678 return;
3679 }
3680 }
3681 Delegate(kBxj, &Assembler::bxj, cond, rm);
3682 }
3683
cbnz(Register rn,Location * location)3684 void Assembler::cbnz(Register rn, Location* location) {
3685 VIXL_ASSERT(AllowAssembler());
3686 CheckIT(al);
3687 Location::Offset offset =
3688 location->IsBound()
3689 ? location->GetLocation() -
3690 (GetCursorOffset() + GetArchitectureStatePCOffset())
3691 : 0;
3692 if (IsUsingT32()) {
3693 // CBNZ{<q>} <Rn>, <label> ; T1
3694 if (rn.IsLow() && ((location->IsBound() && (offset >= 0) &&
3695 (offset <= 126) && ((offset & 0x1) == 0)) ||
3696 !location->IsBound())) {
3697 static class EmitOp : public Location::EmitOperator {
3698 public:
3699 EmitOp() : Location::EmitOperator(T32) {}
3700 virtual uint32_t Encode(uint32_t instr,
3701 Location::Offset program_counter,
3702 const Location* loc) const VIXL_OVERRIDE {
3703 program_counter += kT32PcDelta;
3704 Location::Offset off = loc->GetLocation() - program_counter;
3705 VIXL_ASSERT((off >= 0) && (off <= 126) && ((off & 0x1) == 0));
3706 const int32_t target = off >> 1;
3707 return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3708 }
3709 } immop;
3710 EmitT32_16(Link(0xb900 | rn.GetCode(), location, immop, &kT16CbzInfo));
3711 AdvanceIT();
3712 return;
3713 }
3714 }
3715 Delegate(kCbnz, &Assembler::cbnz, rn, location);
3716 }
3717
cbnz_info(Register rn,Location * location,const struct ReferenceInfo ** info)3718 bool Assembler::cbnz_info(Register rn,
3719 Location* location,
3720 const struct ReferenceInfo** info) {
3721 VIXL_ASSERT(!location->IsBound());
3722 USE(location);
3723 if (IsUsingT32()) {
3724 // CBNZ{<q>} <Rn>, <label> ; T1
3725 if (rn.IsLow()) {
3726 *info = &kT16CbzInfo;
3727 return true;
3728 }
3729 }
3730 return false;
3731 }
3732
cbz(Register rn,Location * location)3733 void Assembler::cbz(Register rn, Location* location) {
3734 VIXL_ASSERT(AllowAssembler());
3735 CheckIT(al);
3736 Location::Offset offset =
3737 location->IsBound()
3738 ? location->GetLocation() -
3739 (GetCursorOffset() + GetArchitectureStatePCOffset())
3740 : 0;
3741 if (IsUsingT32()) {
3742 // CBZ{<q>} <Rn>, <label> ; T1
3743 if (rn.IsLow() && ((location->IsBound() && (offset >= 0) &&
3744 (offset <= 126) && ((offset & 0x1) == 0)) ||
3745 !location->IsBound())) {
3746 static class EmitOp : public Location::EmitOperator {
3747 public:
3748 EmitOp() : Location::EmitOperator(T32) {}
3749 virtual uint32_t Encode(uint32_t instr,
3750 Location::Offset program_counter,
3751 const Location* loc) const VIXL_OVERRIDE {
3752 program_counter += kT32PcDelta;
3753 Location::Offset off = loc->GetLocation() - program_counter;
3754 VIXL_ASSERT((off >= 0) && (off <= 126) && ((off & 0x1) == 0));
3755 const int32_t target = off >> 1;
3756 return instr | ((target & 0x1f) << 3) | ((target & 0x20) << 4);
3757 }
3758 } immop;
3759 EmitT32_16(Link(0xb100 | rn.GetCode(), location, immop, &kT16CbzInfo));
3760 AdvanceIT();
3761 return;
3762 }
3763 }
3764 Delegate(kCbz, &Assembler::cbz, rn, location);
3765 }
3766
cbz_info(Register rn,Location * location,const struct ReferenceInfo ** info)3767 bool Assembler::cbz_info(Register rn,
3768 Location* location,
3769 const struct ReferenceInfo** info) {
3770 VIXL_ASSERT(!location->IsBound());
3771 USE(location);
3772 if (IsUsingT32()) {
3773 // CBZ{<q>} <Rn>, <label> ; T1
3774 if (rn.IsLow()) {
3775 *info = &kT16CbzInfo;
3776 return true;
3777 }
3778 }
3779 return false;
3780 }
3781
clrex(Condition cond)3782 void Assembler::clrex(Condition cond) {
3783 VIXL_ASSERT(AllowAssembler());
3784 CheckIT(cond);
3785 if (IsUsingT32()) {
3786 // CLREX{<c>}{<q>} ; T1
3787 EmitT32_32(0xf3bf8f2fU);
3788 AdvanceIT();
3789 return;
3790 } else {
3791 // CLREX{<c>}{<q>} ; A1
3792 if (cond.Is(al)) {
3793 EmitA32(0xf57ff01fU);
3794 return;
3795 }
3796 }
3797 Delegate(kClrex, &Assembler::clrex, cond);
3798 }
3799
clz(Condition cond,Register rd,Register rm)3800 void Assembler::clz(Condition cond, Register rd, Register rm) {
3801 VIXL_ASSERT(AllowAssembler());
3802 CheckIT(cond);
3803 if (IsUsingT32()) {
3804 // CLZ{<c>}{<q>} <Rd>, <Rm> ; T1
3805 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3806 EmitT32_32(0xfab0f080U | (rd.GetCode() << 8) | rm.GetCode() |
3807 (rm.GetCode() << 16));
3808 AdvanceIT();
3809 return;
3810 }
3811 } else {
3812 // CLZ{<c>}{<q>} <Rd>, <Rm> ; A1
3813 if (cond.IsNotNever() &&
3814 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3815 EmitA32(0x016f0f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
3816 rm.GetCode());
3817 return;
3818 }
3819 }
3820 Delegate(kClz, &Assembler::clz, cond, rd, rm);
3821 }
3822
cmn(Condition cond,EncodingSize size,Register rn,const Operand & operand)3823 void Assembler::cmn(Condition cond,
3824 EncodingSize size,
3825 Register rn,
3826 const Operand& operand) {
3827 VIXL_ASSERT(AllowAssembler());
3828 CheckIT(cond);
3829 if (operand.IsImmediate()) {
3830 uint32_t imm = operand.GetImmediate();
3831 if (IsUsingT32()) {
3832 ImmediateT32 immediate_t32(imm);
3833 // CMN{<c>}{<q>} <Rn>, #<const> ; T1
3834 if (!size.IsNarrow() && immediate_t32.IsValid() &&
3835 (!rn.IsPC() || AllowUnpredictable())) {
3836 EmitT32_32(0xf1100f00U | (rn.GetCode() << 16) |
3837 (immediate_t32.GetEncodingValue() & 0xff) |
3838 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3839 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3840 AdvanceIT();
3841 return;
3842 }
3843 } else {
3844 ImmediateA32 immediate_a32(imm);
3845 // CMN{<c>}{<q>} <Rn>, #<const> ; A1
3846 if (immediate_a32.IsValid() && cond.IsNotNever()) {
3847 EmitA32(0x03700000U | (cond.GetCondition() << 28) |
3848 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3849 return;
3850 }
3851 }
3852 }
3853 if (operand.IsImmediateShiftedRegister()) {
3854 Register rm = operand.GetBaseRegister();
3855 if (operand.IsPlainRegister()) {
3856 if (IsUsingT32()) {
3857 // CMN{<c>}{<q>} <Rn>, <Rm> ; T1
3858 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3859 EmitT32_16(0x42c0 | rn.GetCode() | (rm.GetCode() << 3));
3860 AdvanceIT();
3861 return;
3862 }
3863 }
3864 }
3865 Shift shift = operand.GetShift();
3866 uint32_t amount = operand.GetShiftAmount();
3867 if (IsUsingT32()) {
3868 // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
3869 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
3870 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3871 uint32_t amount_ = amount % 32;
3872 EmitT32_32(0xeb100f00U | (rn.GetCode() << 16) | rm.GetCode() |
3873 (operand.GetTypeEncodingValue() << 4) |
3874 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3875 AdvanceIT();
3876 return;
3877 }
3878 } else {
3879 // CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3880 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3881 uint32_t amount_ = amount % 32;
3882 EmitA32(0x01700000U | (cond.GetCondition() << 28) |
3883 (rn.GetCode() << 16) | rm.GetCode() |
3884 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3885 return;
3886 }
3887 }
3888 }
3889 if (operand.IsRegisterShiftedRegister()) {
3890 Register rm = operand.GetBaseRegister();
3891 Shift shift = operand.GetShift();
3892 Register rs = operand.GetShiftRegister();
3893 if (IsUsingA32()) {
3894 // CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3895 if (cond.IsNotNever() &&
3896 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
3897 EmitA32(0x01700010U | (cond.GetCondition() << 28) |
3898 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3899 (rs.GetCode() << 8));
3900 return;
3901 }
3902 }
3903 }
3904 Delegate(kCmn, &Assembler::cmn, cond, size, rn, operand);
3905 }
3906
cmp(Condition cond,EncodingSize size,Register rn,const Operand & operand)3907 void Assembler::cmp(Condition cond,
3908 EncodingSize size,
3909 Register rn,
3910 const Operand& operand) {
3911 VIXL_ASSERT(AllowAssembler());
3912 CheckIT(cond);
3913 if (operand.IsImmediate()) {
3914 uint32_t imm = operand.GetImmediate();
3915 if (IsUsingT32()) {
3916 ImmediateT32 immediate_t32(imm);
3917 // CMP{<c>}{<q>} <Rn>, #<imm8> ; T1
3918 if (!size.IsWide() && rn.IsLow() && (imm <= 255)) {
3919 EmitT32_16(0x2800 | (rn.GetCode() << 8) | imm);
3920 AdvanceIT();
3921 return;
3922 }
3923 // CMP{<c>}{<q>} <Rn>, #<const> ; T2
3924 if (!size.IsNarrow() && immediate_t32.IsValid() &&
3925 (!rn.IsPC() || AllowUnpredictable())) {
3926 EmitT32_32(0xf1b00f00U | (rn.GetCode() << 16) |
3927 (immediate_t32.GetEncodingValue() & 0xff) |
3928 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
3929 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
3930 AdvanceIT();
3931 return;
3932 }
3933 } else {
3934 ImmediateA32 immediate_a32(imm);
3935 // CMP{<c>}{<q>} <Rn>, #<const> ; A1
3936 if (immediate_a32.IsValid() && cond.IsNotNever()) {
3937 EmitA32(0x03500000U | (cond.GetCondition() << 28) |
3938 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
3939 return;
3940 }
3941 }
3942 }
3943 if (operand.IsImmediateShiftedRegister()) {
3944 Register rm = operand.GetBaseRegister();
3945 if (operand.IsPlainRegister()) {
3946 if (IsUsingT32()) {
3947 // CMP{<c>}{<q>} <Rn>, <Rm> ; T1
3948 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
3949 EmitT32_16(0x4280 | rn.GetCode() | (rm.GetCode() << 3));
3950 AdvanceIT();
3951 return;
3952 }
3953 // CMP{<c>}{<q>} <Rn>, <Rm> ; T2
3954 if (!size.IsWide() &&
3955 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3956 EmitT32_16(0x4500 | (rn.GetCode() & 0x7) |
3957 ((rn.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
3958 AdvanceIT();
3959 return;
3960 }
3961 }
3962 }
3963 Shift shift = operand.GetShift();
3964 uint32_t amount = operand.GetShiftAmount();
3965 if (IsUsingT32()) {
3966 // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3
3967 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
3968 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
3969 uint32_t amount_ = amount % 32;
3970 EmitT32_32(0xebb00f00U | (rn.GetCode() << 16) | rm.GetCode() |
3971 (operand.GetTypeEncodingValue() << 4) |
3972 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
3973 AdvanceIT();
3974 return;
3975 }
3976 } else {
3977 // CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
3978 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
3979 uint32_t amount_ = amount % 32;
3980 EmitA32(0x01500000U | (cond.GetCondition() << 28) |
3981 (rn.GetCode() << 16) | rm.GetCode() |
3982 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
3983 return;
3984 }
3985 }
3986 }
3987 if (operand.IsRegisterShiftedRegister()) {
3988 Register rm = operand.GetBaseRegister();
3989 Shift shift = operand.GetShift();
3990 Register rs = operand.GetShiftRegister();
3991 if (IsUsingA32()) {
3992 // CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
3993 if (cond.IsNotNever() &&
3994 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
3995 EmitA32(0x01500010U | (cond.GetCondition() << 28) |
3996 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
3997 (rs.GetCode() << 8));
3998 return;
3999 }
4000 }
4001 }
4002 Delegate(kCmp, &Assembler::cmp, cond, size, rn, operand);
4003 }
4004
crc32b(Condition cond,Register rd,Register rn,Register rm)4005 void Assembler::crc32b(Condition cond, Register rd, Register rn, Register rm) {
4006 VIXL_ASSERT(AllowAssembler());
4007 CheckIT(cond);
4008 if (IsUsingT32()) {
4009 // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1
4010 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4011 AllowUnpredictable())) {
4012 EmitT32_32(0xfac0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4013 rm.GetCode());
4014 AdvanceIT();
4015 return;
4016 }
4017 } else {
4018 // CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1
4019 if ((cond.Is(al) || AllowUnpredictable()) &&
4020 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4021 EmitA32(0x01000040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4022 (rn.GetCode() << 16) | rm.GetCode());
4023 return;
4024 }
4025 }
4026 Delegate(kCrc32b, &Assembler::crc32b, cond, rd, rn, rm);
4027 }
4028
crc32cb(Condition cond,Register rd,Register rn,Register rm)4029 void Assembler::crc32cb(Condition cond, Register rd, Register rn, Register rm) {
4030 VIXL_ASSERT(AllowAssembler());
4031 CheckIT(cond);
4032 if (IsUsingT32()) {
4033 // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1
4034 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4035 AllowUnpredictable())) {
4036 EmitT32_32(0xfad0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4037 rm.GetCode());
4038 AdvanceIT();
4039 return;
4040 }
4041 } else {
4042 // CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1
4043 if ((cond.Is(al) || AllowUnpredictable()) &&
4044 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4045 EmitA32(0x01000240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4046 (rn.GetCode() << 16) | rm.GetCode());
4047 return;
4048 }
4049 }
4050 Delegate(kCrc32cb, &Assembler::crc32cb, cond, rd, rn, rm);
4051 }
4052
crc32ch(Condition cond,Register rd,Register rn,Register rm)4053 void Assembler::crc32ch(Condition cond, Register rd, Register rn, Register rm) {
4054 VIXL_ASSERT(AllowAssembler());
4055 CheckIT(cond);
4056 if (IsUsingT32()) {
4057 // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1
4058 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4059 AllowUnpredictable())) {
4060 EmitT32_32(0xfad0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4061 rm.GetCode());
4062 AdvanceIT();
4063 return;
4064 }
4065 } else {
4066 // CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1
4067 if ((cond.Is(al) || AllowUnpredictable()) &&
4068 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4069 EmitA32(0x01200240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4070 (rn.GetCode() << 16) | rm.GetCode());
4071 return;
4072 }
4073 }
4074 Delegate(kCrc32ch, &Assembler::crc32ch, cond, rd, rn, rm);
4075 }
4076
crc32cw(Condition cond,Register rd,Register rn,Register rm)4077 void Assembler::crc32cw(Condition cond, Register rd, Register rn, Register rm) {
4078 VIXL_ASSERT(AllowAssembler());
4079 CheckIT(cond);
4080 if (IsUsingT32()) {
4081 // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1
4082 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4083 AllowUnpredictable())) {
4084 EmitT32_32(0xfad0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4085 rm.GetCode());
4086 AdvanceIT();
4087 return;
4088 }
4089 } else {
4090 // CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1
4091 if ((cond.Is(al) || AllowUnpredictable()) &&
4092 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4093 EmitA32(0x01400240U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4094 (rn.GetCode() << 16) | rm.GetCode());
4095 return;
4096 }
4097 }
4098 Delegate(kCrc32cw, &Assembler::crc32cw, cond, rd, rn, rm);
4099 }
4100
crc32h(Condition cond,Register rd,Register rn,Register rm)4101 void Assembler::crc32h(Condition cond, Register rd, Register rn, Register rm) {
4102 VIXL_ASSERT(AllowAssembler());
4103 CheckIT(cond);
4104 if (IsUsingT32()) {
4105 // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1
4106 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4107 AllowUnpredictable())) {
4108 EmitT32_32(0xfac0f090U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4109 rm.GetCode());
4110 AdvanceIT();
4111 return;
4112 }
4113 } else {
4114 // CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1
4115 if ((cond.Is(al) || AllowUnpredictable()) &&
4116 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4117 EmitA32(0x01200040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4118 (rn.GetCode() << 16) | rm.GetCode());
4119 return;
4120 }
4121 }
4122 Delegate(kCrc32h, &Assembler::crc32h, cond, rd, rn, rm);
4123 }
4124
crc32w(Condition cond,Register rd,Register rn,Register rm)4125 void Assembler::crc32w(Condition cond, Register rd, Register rn, Register rm) {
4126 VIXL_ASSERT(AllowAssembler());
4127 CheckIT(cond);
4128 if (IsUsingT32()) {
4129 // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1
4130 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && OutsideITBlock()) ||
4131 AllowUnpredictable())) {
4132 EmitT32_32(0xfac0f0a0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4133 rm.GetCode());
4134 AdvanceIT();
4135 return;
4136 }
4137 } else {
4138 // CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1
4139 if ((cond.Is(al) || AllowUnpredictable()) &&
4140 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4141 EmitA32(0x01400040U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
4142 (rn.GetCode() << 16) | rm.GetCode());
4143 return;
4144 }
4145 }
4146 Delegate(kCrc32w, &Assembler::crc32w, cond, rd, rn, rm);
4147 }
4148
dmb(Condition cond,MemoryBarrier option)4149 void Assembler::dmb(Condition cond, MemoryBarrier option) {
4150 VIXL_ASSERT(AllowAssembler());
4151 CheckIT(cond);
4152 if (IsUsingT32()) {
4153 // DMB{<c>}{<q>} {<option>} ; T1
4154 EmitT32_32(0xf3bf8f50U | option.GetType());
4155 AdvanceIT();
4156 return;
4157 } else {
4158 // DMB{<c>}{<q>} {<option>} ; A1
4159 if (cond.Is(al)) {
4160 EmitA32(0xf57ff050U | option.GetType());
4161 return;
4162 }
4163 }
4164 Delegate(kDmb, &Assembler::dmb, cond, option);
4165 }
4166
dsb(Condition cond,MemoryBarrier option)4167 void Assembler::dsb(Condition cond, MemoryBarrier option) {
4168 VIXL_ASSERT(AllowAssembler());
4169 CheckIT(cond);
4170 if (IsUsingT32()) {
4171 // DSB{<c>}{<q>} {<option>} ; T1
4172 EmitT32_32(0xf3bf8f40U | option.GetType());
4173 AdvanceIT();
4174 return;
4175 } else {
4176 // DSB{<c>}{<q>} {<option>} ; A1
4177 if (cond.Is(al)) {
4178 EmitA32(0xf57ff040U | option.GetType());
4179 return;
4180 }
4181 }
4182 Delegate(kDsb, &Assembler::dsb, cond, option);
4183 }
4184
eor(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)4185 void Assembler::eor(Condition cond,
4186 EncodingSize size,
4187 Register rd,
4188 Register rn,
4189 const Operand& operand) {
4190 VIXL_ASSERT(AllowAssembler());
4191 CheckIT(cond);
4192 if (operand.IsImmediate()) {
4193 uint32_t imm = operand.GetImmediate();
4194 if (IsUsingT32()) {
4195 ImmediateT32 immediate_t32(imm);
4196 // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
4197 if (!size.IsNarrow() && immediate_t32.IsValid() &&
4198 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4199 EmitT32_32(0xf0800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4200 (immediate_t32.GetEncodingValue() & 0xff) |
4201 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
4202 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
4203 AdvanceIT();
4204 return;
4205 }
4206 } else {
4207 ImmediateA32 immediate_a32(imm);
4208 // EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
4209 if (immediate_a32.IsValid() && cond.IsNotNever()) {
4210 EmitA32(0x02200000U | (cond.GetCondition() << 28) |
4211 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
4212 immediate_a32.GetEncodingValue());
4213 return;
4214 }
4215 }
4216 }
4217 if (operand.IsImmediateShiftedRegister()) {
4218 Register rm = operand.GetBaseRegister();
4219 if (operand.IsPlainRegister()) {
4220 if (IsUsingT32()) {
4221 // EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
4222 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
4223 rm.IsLow()) {
4224 EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
4225 AdvanceIT();
4226 return;
4227 }
4228 }
4229 }
4230 Shift shift = operand.GetShift();
4231 uint32_t amount = operand.GetShiftAmount();
4232 if (IsUsingT32()) {
4233 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
4234 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
4235 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4236 uint32_t amount_ = amount % 32;
4237 EmitT32_32(0xea800000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4238 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
4239 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
4240 AdvanceIT();
4241 return;
4242 }
4243 } else {
4244 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
4245 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
4246 uint32_t amount_ = amount % 32;
4247 EmitA32(0x00200000U | (cond.GetCondition() << 28) |
4248 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4249 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
4250 return;
4251 }
4252 }
4253 }
4254 if (operand.IsRegisterShiftedRegister()) {
4255 Register rm = operand.GetBaseRegister();
4256 Shift shift = operand.GetShift();
4257 Register rs = operand.GetShiftRegister();
4258 if (IsUsingA32()) {
4259 // EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
4260 if (cond.IsNotNever() &&
4261 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
4262 AllowUnpredictable())) {
4263 EmitA32(0x00200010U | (cond.GetCondition() << 28) |
4264 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4265 (shift.GetType() << 5) | (rs.GetCode() << 8));
4266 return;
4267 }
4268 }
4269 }
4270 Delegate(kEor, &Assembler::eor, cond, size, rd, rn, operand);
4271 }
4272
eors(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)4273 void Assembler::eors(Condition cond,
4274 EncodingSize size,
4275 Register rd,
4276 Register rn,
4277 const Operand& operand) {
4278 VIXL_ASSERT(AllowAssembler());
4279 CheckIT(cond);
4280 if (operand.IsImmediate()) {
4281 uint32_t imm = operand.GetImmediate();
4282 if (IsUsingT32()) {
4283 ImmediateT32 immediate_t32(imm);
4284 // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
4285 if (!size.IsNarrow() && immediate_t32.IsValid() && !rd.Is(pc) &&
4286 (!rn.IsPC() || AllowUnpredictable())) {
4287 EmitT32_32(0xf0900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4288 (immediate_t32.GetEncodingValue() & 0xff) |
4289 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
4290 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
4291 AdvanceIT();
4292 return;
4293 }
4294 } else {
4295 ImmediateA32 immediate_a32(imm);
4296 // EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
4297 if (immediate_a32.IsValid() && cond.IsNotNever()) {
4298 EmitA32(0x02300000U | (cond.GetCondition() << 28) |
4299 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
4300 immediate_a32.GetEncodingValue());
4301 return;
4302 }
4303 }
4304 }
4305 if (operand.IsImmediateShiftedRegister()) {
4306 Register rm = operand.GetBaseRegister();
4307 if (operand.IsPlainRegister()) {
4308 if (IsUsingT32()) {
4309 // EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
4310 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
4311 rm.IsLow()) {
4312 EmitT32_16(0x4040 | rd.GetCode() | (rm.GetCode() << 3));
4313 AdvanceIT();
4314 return;
4315 }
4316 }
4317 }
4318 Shift shift = operand.GetShift();
4319 uint32_t amount = operand.GetShiftAmount();
4320 if (IsUsingT32()) {
4321 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
4322 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rd.Is(pc) &&
4323 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
4324 uint32_t amount_ = amount % 32;
4325 EmitT32_32(0xea900000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
4326 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
4327 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
4328 AdvanceIT();
4329 return;
4330 }
4331 } else {
4332 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
4333 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
4334 uint32_t amount_ = amount % 32;
4335 EmitA32(0x00300000U | (cond.GetCondition() << 28) |
4336 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4337 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
4338 return;
4339 }
4340 }
4341 }
4342 if (operand.IsRegisterShiftedRegister()) {
4343 Register rm = operand.GetBaseRegister();
4344 Shift shift = operand.GetShift();
4345 Register rs = operand.GetShiftRegister();
4346 if (IsUsingA32()) {
4347 // EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
4348 if (cond.IsNotNever() &&
4349 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
4350 AllowUnpredictable())) {
4351 EmitA32(0x00300010U | (cond.GetCondition() << 28) |
4352 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
4353 (shift.GetType() << 5) | (rs.GetCode() << 8));
4354 return;
4355 }
4356 }
4357 }
4358 Delegate(kEors, &Assembler::eors, cond, size, rd, rn, operand);
4359 }
4360
fldmdbx(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)4361 void Assembler::fldmdbx(Condition cond,
4362 Register rn,
4363 WriteBack write_back,
4364 DRegisterList dreglist) {
4365 VIXL_ASSERT(AllowAssembler());
4366 CheckIT(cond);
4367 if (IsUsingT32()) {
4368 // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
4369 if (write_back.DoesWriteBack() &&
4370 (((dreglist.GetLength() <= 16) &&
4371 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4372 AllowUnpredictable())) {
4373 const DRegister& dreg = dreglist.GetFirstDRegister();
4374 unsigned len = dreglist.GetLength() * 2;
4375 EmitT32_32(0xed300b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
4376 (len & 0xff));
4377 AdvanceIT();
4378 return;
4379 }
4380 } else {
4381 // FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
4382 if (write_back.DoesWriteBack() && cond.IsNotNever() &&
4383 (((dreglist.GetLength() <= 16) &&
4384 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4385 AllowUnpredictable())) {
4386 const DRegister& dreg = dreglist.GetFirstDRegister();
4387 unsigned len = dreglist.GetLength() * 2;
4388 EmitA32(0x0d300b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4389 dreg.Encode(22, 12) | (len & 0xff));
4390 return;
4391 }
4392 }
4393 Delegate(kFldmdbx, &Assembler::fldmdbx, cond, rn, write_back, dreglist);
4394 }
4395
fldmiax(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)4396 void Assembler::fldmiax(Condition cond,
4397 Register rn,
4398 WriteBack write_back,
4399 DRegisterList dreglist) {
4400 VIXL_ASSERT(AllowAssembler());
4401 CheckIT(cond);
4402 if (IsUsingT32()) {
4403 // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
4404 if ((((dreglist.GetLength() <= 16) &&
4405 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4406 AllowUnpredictable())) {
4407 const DRegister& dreg = dreglist.GetFirstDRegister();
4408 unsigned len = dreglist.GetLength() * 2;
4409 EmitT32_32(0xec900b01U | (rn.GetCode() << 16) |
4410 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4411 (len & 0xff));
4412 AdvanceIT();
4413 return;
4414 }
4415 } else {
4416 // FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
4417 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
4418 (dreglist.GetLastDRegister().GetCode() < 16) &&
4419 (!rn.IsPC() || !write_back.DoesWriteBack())) ||
4420 AllowUnpredictable())) {
4421 const DRegister& dreg = dreglist.GetFirstDRegister();
4422 unsigned len = dreglist.GetLength() * 2;
4423 EmitA32(0x0c900b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4424 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4425 (len & 0xff));
4426 return;
4427 }
4428 }
4429 Delegate(kFldmiax, &Assembler::fldmiax, cond, rn, write_back, dreglist);
4430 }
4431
fstmdbx(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)4432 void Assembler::fstmdbx(Condition cond,
4433 Register rn,
4434 WriteBack write_back,
4435 DRegisterList dreglist) {
4436 VIXL_ASSERT(AllowAssembler());
4437 CheckIT(cond);
4438 if (IsUsingT32()) {
4439 // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
4440 if (write_back.DoesWriteBack() &&
4441 (((dreglist.GetLength() <= 16) &&
4442 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4443 AllowUnpredictable())) {
4444 const DRegister& dreg = dreglist.GetFirstDRegister();
4445 unsigned len = dreglist.GetLength() * 2;
4446 EmitT32_32(0xed200b01U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
4447 (len & 0xff));
4448 AdvanceIT();
4449 return;
4450 }
4451 } else {
4452 // FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
4453 if (write_back.DoesWriteBack() && cond.IsNotNever() &&
4454 (((dreglist.GetLength() <= 16) &&
4455 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4456 AllowUnpredictable())) {
4457 const DRegister& dreg = dreglist.GetFirstDRegister();
4458 unsigned len = dreglist.GetLength() * 2;
4459 EmitA32(0x0d200b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4460 dreg.Encode(22, 12) | (len & 0xff));
4461 return;
4462 }
4463 }
4464 Delegate(kFstmdbx, &Assembler::fstmdbx, cond, rn, write_back, dreglist);
4465 }
4466
fstmiax(Condition cond,Register rn,WriteBack write_back,DRegisterList dreglist)4467 void Assembler::fstmiax(Condition cond,
4468 Register rn,
4469 WriteBack write_back,
4470 DRegisterList dreglist) {
4471 VIXL_ASSERT(AllowAssembler());
4472 CheckIT(cond);
4473 if (IsUsingT32()) {
4474 // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
4475 if ((((dreglist.GetLength() <= 16) &&
4476 (dreglist.GetLastDRegister().GetCode() < 16) && !rn.IsPC()) ||
4477 AllowUnpredictable())) {
4478 const DRegister& dreg = dreglist.GetFirstDRegister();
4479 unsigned len = dreglist.GetLength() * 2;
4480 EmitT32_32(0xec800b01U | (rn.GetCode() << 16) |
4481 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4482 (len & 0xff));
4483 AdvanceIT();
4484 return;
4485 }
4486 } else {
4487 // FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
4488 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
4489 (dreglist.GetLastDRegister().GetCode() < 16) &&
4490 (!rn.IsPC() || !write_back.DoesWriteBack())) ||
4491 AllowUnpredictable())) {
4492 const DRegister& dreg = dreglist.GetFirstDRegister();
4493 unsigned len = dreglist.GetLength() * 2;
4494 EmitA32(0x0c800b01U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4495 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
4496 (len & 0xff));
4497 return;
4498 }
4499 }
4500 Delegate(kFstmiax, &Assembler::fstmiax, cond, rn, write_back, dreglist);
4501 }
4502
hlt(Condition cond,uint32_t imm)4503 void Assembler::hlt(Condition cond, uint32_t imm) {
4504 VIXL_ASSERT(AllowAssembler());
4505 CheckIT(cond);
4506 if (IsUsingT32()) {
4507 // HLT{<q>} {#}<imm> ; T1
4508 if ((imm <= 63)) {
4509 EmitT32_16(0xba80 | imm);
4510 AdvanceIT();
4511 return;
4512 }
4513 } else {
4514 // HLT{<q>} {#}<imm> ; A1
4515 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4516 EmitA32(0x01000070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4517 ((imm & 0xfff0) << 4));
4518 return;
4519 }
4520 }
4521 Delegate(kHlt, &Assembler::hlt, cond, imm);
4522 }
4523
hvc(Condition cond,uint32_t imm)4524 void Assembler::hvc(Condition cond, uint32_t imm) {
4525 VIXL_ASSERT(AllowAssembler());
4526 CheckIT(cond);
4527 if (IsUsingT32()) {
4528 // HVC{<q>} {#}<imm16> ; T1
4529 if ((imm <= 65535) && (OutsideITBlock() || AllowUnpredictable())) {
4530 EmitT32_32(0xf7e08000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
4531 AdvanceIT();
4532 return;
4533 }
4534 } else {
4535 // HVC{<q>} {#}<imm16> ; A1
4536 if ((imm <= 65535) && (cond.Is(al) || AllowUnpredictable())) {
4537 EmitA32(0x01400070U | (cond.GetCondition() << 28) | (imm & 0xf) |
4538 ((imm & 0xfff0) << 4));
4539 return;
4540 }
4541 }
4542 Delegate(kHvc, &Assembler::hvc, cond, imm);
4543 }
4544
isb(Condition cond,MemoryBarrier option)4545 void Assembler::isb(Condition cond, MemoryBarrier option) {
4546 VIXL_ASSERT(AllowAssembler());
4547 CheckIT(cond);
4548 if (IsUsingT32()) {
4549 // ISB{<c>}{<q>} {<option>} ; T1
4550 EmitT32_32(0xf3bf8f60U | option.GetType());
4551 AdvanceIT();
4552 return;
4553 } else {
4554 // ISB{<c>}{<q>} {<option>} ; A1
4555 if (cond.Is(al)) {
4556 EmitA32(0xf57ff060U | option.GetType());
4557 return;
4558 }
4559 }
4560 Delegate(kIsb, &Assembler::isb, cond, option);
4561 }
4562
it(Condition cond,uint16_t mask)4563 void Assembler::it(Condition cond, uint16_t mask) {
4564 VIXL_ASSERT(AllowAssembler());
4565 CheckNotIT();
4566 if (mask != 0) {
4567 if ((cond.GetCondition() & 0x1) != 0) {
4568 if ((mask & 0x1) != 0) {
4569 mask ^= 0xE;
4570 } else if ((mask & 0x2) != 0) {
4571 mask ^= 0xC;
4572 } else if ((mask & 0x4) != 0) {
4573 mask ^= 0x8;
4574 }
4575 }
4576 if (IsUsingT32()) EmitT32_16(0xbf00 | (cond.GetCondition() << 4) | mask);
4577 SetIT(cond, mask);
4578 return;
4579 }
4580 DelegateIt(cond, mask);
4581 }
4582
lda(Condition cond,Register rt,const MemOperand & operand)4583 void Assembler::lda(Condition cond, Register rt, const MemOperand& operand) {
4584 VIXL_ASSERT(AllowAssembler());
4585 CheckIT(cond);
4586 if (operand.IsImmediateZero()) {
4587 Register rn = operand.GetBaseRegister();
4588 if (IsUsingT32()) {
4589 // LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1
4590 if (operand.IsOffset() &&
4591 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4592 EmitT32_32(0xe8d00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4593 AdvanceIT();
4594 return;
4595 }
4596 } else {
4597 // LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1
4598 if (operand.IsOffset() && cond.IsNotNever() &&
4599 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4600 EmitA32(0x01900c9fU | (cond.GetCondition() << 28) |
4601 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4602 return;
4603 }
4604 }
4605 }
4606 Delegate(kLda, &Assembler::lda, cond, rt, operand);
4607 }
4608
ldab(Condition cond,Register rt,const MemOperand & operand)4609 void Assembler::ldab(Condition cond, Register rt, const MemOperand& operand) {
4610 VIXL_ASSERT(AllowAssembler());
4611 CheckIT(cond);
4612 if (operand.IsImmediateZero()) {
4613 Register rn = operand.GetBaseRegister();
4614 if (IsUsingT32()) {
4615 // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4616 if (operand.IsOffset() &&
4617 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4618 EmitT32_32(0xe8d00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4619 AdvanceIT();
4620 return;
4621 }
4622 } else {
4623 // LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4624 if (operand.IsOffset() && cond.IsNotNever() &&
4625 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4626 EmitA32(0x01d00c9fU | (cond.GetCondition() << 28) |
4627 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4628 return;
4629 }
4630 }
4631 }
4632 Delegate(kLdab, &Assembler::ldab, cond, rt, operand);
4633 }
4634
ldaex(Condition cond,Register rt,const MemOperand & operand)4635 void Assembler::ldaex(Condition cond, Register rt, const MemOperand& operand) {
4636 VIXL_ASSERT(AllowAssembler());
4637 CheckIT(cond);
4638 if (operand.IsImmediateZero()) {
4639 Register rn = operand.GetBaseRegister();
4640 if (IsUsingT32()) {
4641 // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1
4642 if (operand.IsOffset() &&
4643 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4644 EmitT32_32(0xe8d00fefU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4645 AdvanceIT();
4646 return;
4647 }
4648 } else {
4649 // LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1
4650 if (operand.IsOffset() && cond.IsNotNever() &&
4651 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4652 EmitA32(0x01900e9fU | (cond.GetCondition() << 28) |
4653 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4654 return;
4655 }
4656 }
4657 }
4658 Delegate(kLdaex, &Assembler::ldaex, cond, rt, operand);
4659 }
4660
ldaexb(Condition cond,Register rt,const MemOperand & operand)4661 void Assembler::ldaexb(Condition cond, Register rt, const MemOperand& operand) {
4662 VIXL_ASSERT(AllowAssembler());
4663 CheckIT(cond);
4664 if (operand.IsImmediateZero()) {
4665 Register rn = operand.GetBaseRegister();
4666 if (IsUsingT32()) {
4667 // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
4668 if (operand.IsOffset() &&
4669 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4670 EmitT32_32(0xe8d00fcfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4671 AdvanceIT();
4672 return;
4673 }
4674 } else {
4675 // LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
4676 if (operand.IsOffset() && cond.IsNotNever() &&
4677 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4678 EmitA32(0x01d00e9fU | (cond.GetCondition() << 28) |
4679 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4680 return;
4681 }
4682 }
4683 }
4684 Delegate(kLdaexb, &Assembler::ldaexb, cond, rt, operand);
4685 }
4686
ldaexd(Condition cond,Register rt,Register rt2,const MemOperand & operand)4687 void Assembler::ldaexd(Condition cond,
4688 Register rt,
4689 Register rt2,
4690 const MemOperand& operand) {
4691 VIXL_ASSERT(AllowAssembler());
4692 CheckIT(cond);
4693 if (operand.IsImmediateZero()) {
4694 Register rn = operand.GetBaseRegister();
4695 if (IsUsingT32()) {
4696 // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
4697 if (operand.IsOffset() &&
4698 ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4699 EmitT32_32(0xe8d000ffU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
4700 (rn.GetCode() << 16));
4701 AdvanceIT();
4702 return;
4703 }
4704 } else {
4705 // LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
4706 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
4707 operand.IsOffset() && cond.IsNotNever() &&
4708 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) ||
4709 AllowUnpredictable())) {
4710 EmitA32(0x01b00e9fU | (cond.GetCondition() << 28) |
4711 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4712 return;
4713 }
4714 }
4715 }
4716 Delegate(kLdaexd, &Assembler::ldaexd, cond, rt, rt2, operand);
4717 }
4718
ldaexh(Condition cond,Register rt,const MemOperand & operand)4719 void Assembler::ldaexh(Condition cond, Register rt, const MemOperand& operand) {
4720 VIXL_ASSERT(AllowAssembler());
4721 CheckIT(cond);
4722 if (operand.IsImmediateZero()) {
4723 Register rn = operand.GetBaseRegister();
4724 if (IsUsingT32()) {
4725 // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4726 if (operand.IsOffset() &&
4727 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4728 EmitT32_32(0xe8d00fdfU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4729 AdvanceIT();
4730 return;
4731 }
4732 } else {
4733 // LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4734 if (operand.IsOffset() && cond.IsNotNever() &&
4735 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4736 EmitA32(0x01f00e9fU | (cond.GetCondition() << 28) |
4737 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4738 return;
4739 }
4740 }
4741 }
4742 Delegate(kLdaexh, &Assembler::ldaexh, cond, rt, operand);
4743 }
4744
ldah(Condition cond,Register rt,const MemOperand & operand)4745 void Assembler::ldah(Condition cond, Register rt, const MemOperand& operand) {
4746 VIXL_ASSERT(AllowAssembler());
4747 CheckIT(cond);
4748 if (operand.IsImmediateZero()) {
4749 Register rn = operand.GetBaseRegister();
4750 if (IsUsingT32()) {
4751 // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1
4752 if (operand.IsOffset() &&
4753 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4754 EmitT32_32(0xe8d00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
4755 AdvanceIT();
4756 return;
4757 }
4758 } else {
4759 // LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1
4760 if (operand.IsOffset() && cond.IsNotNever() &&
4761 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
4762 EmitA32(0x01f00c9fU | (cond.GetCondition() << 28) |
4763 (rt.GetCode() << 12) | (rn.GetCode() << 16));
4764 return;
4765 }
4766 }
4767 }
4768 Delegate(kLdah, &Assembler::ldah, cond, rt, operand);
4769 }
4770
ldm(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)4771 void Assembler::ldm(Condition cond,
4772 EncodingSize size,
4773 Register rn,
4774 WriteBack write_back,
4775 RegisterList registers) {
4776 VIXL_ASSERT(AllowAssembler());
4777 CheckIT(cond);
4778 if (IsUsingT32()) {
4779 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1
4780 if (!size.IsWide() && rn.IsLow() &&
4781 (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4782 write_back.DoesWriteBack()) &&
4783 ((registers.GetList() & ~0xff) == 0)) {
4784 EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4785 GetRegisterListEncoding(registers, 0, 8));
4786 AdvanceIT();
4787 return;
4788 }
4789 // LDM{<c>}{<q>} SP!, <registers> ; T1
4790 if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
4791 registers.IsR0toR7orPC()) {
4792 EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
4793 GetRegisterListEncoding(registers, 0, 8));
4794 AdvanceIT();
4795 return;
4796 }
4797 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2
4798 if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) &&
4799 (!rn.IsPC() || AllowUnpredictable())) {
4800 EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4801 (write_back.GetWriteBackUint32() << 21) |
4802 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4803 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4804 GetRegisterListEncoding(registers, 0, 13));
4805 AdvanceIT();
4806 return;
4807 }
4808 } else {
4809 // LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1
4810 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4811 EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4812 (write_back.GetWriteBackUint32() << 21) |
4813 GetRegisterListEncoding(registers, 0, 16));
4814 return;
4815 }
4816 }
4817 Delegate(kLdm, &Assembler::ldm, cond, size, rn, write_back, registers);
4818 }
4819
ldmda(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4820 void Assembler::ldmda(Condition cond,
4821 Register rn,
4822 WriteBack write_back,
4823 RegisterList registers) {
4824 VIXL_ASSERT(AllowAssembler());
4825 CheckIT(cond);
4826 if (IsUsingA32()) {
4827 // LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4828 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4829 EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4830 (write_back.GetWriteBackUint32() << 21) |
4831 GetRegisterListEncoding(registers, 0, 16));
4832 return;
4833 }
4834 }
4835 Delegate(kLdmda, &Assembler::ldmda, cond, rn, write_back, registers);
4836 }
4837
ldmdb(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4838 void Assembler::ldmdb(Condition cond,
4839 Register rn,
4840 WriteBack write_back,
4841 RegisterList registers) {
4842 VIXL_ASSERT(AllowAssembler());
4843 CheckIT(cond);
4844 if (IsUsingT32()) {
4845 // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
4846 if (((registers.GetList() & ~0xdfff) == 0) &&
4847 (!rn.IsPC() || AllowUnpredictable())) {
4848 EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4849 (write_back.GetWriteBackUint32() << 21) |
4850 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4851 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4852 GetRegisterListEncoding(registers, 0, 13));
4853 AdvanceIT();
4854 return;
4855 }
4856 } else {
4857 // LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4858 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4859 EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4860 (write_back.GetWriteBackUint32() << 21) |
4861 GetRegisterListEncoding(registers, 0, 16));
4862 return;
4863 }
4864 }
4865 Delegate(kLdmdb, &Assembler::ldmdb, cond, rn, write_back, registers);
4866 }
4867
ldmea(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4868 void Assembler::ldmea(Condition cond,
4869 Register rn,
4870 WriteBack write_back,
4871 RegisterList registers) {
4872 VIXL_ASSERT(AllowAssembler());
4873 CheckIT(cond);
4874 if (IsUsingT32()) {
4875 // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; T1
4876 if (((registers.GetList() & ~0xdfff) == 0) &&
4877 (!rn.IsPC() || AllowUnpredictable())) {
4878 EmitT32_32(0xe9100000U | (rn.GetCode() << 16) |
4879 (write_back.GetWriteBackUint32() << 21) |
4880 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4881 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4882 GetRegisterListEncoding(registers, 0, 13));
4883 AdvanceIT();
4884 return;
4885 }
4886 } else {
4887 // LDMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4888 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4889 EmitA32(0x09100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4890 (write_back.GetWriteBackUint32() << 21) |
4891 GetRegisterListEncoding(registers, 0, 16));
4892 return;
4893 }
4894 }
4895 Delegate(kLdmea, &Assembler::ldmea, cond, rn, write_back, registers);
4896 }
4897
ldmed(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4898 void Assembler::ldmed(Condition cond,
4899 Register rn,
4900 WriteBack write_back,
4901 RegisterList registers) {
4902 VIXL_ASSERT(AllowAssembler());
4903 CheckIT(cond);
4904 if (IsUsingA32()) {
4905 // LDMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
4906 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4907 EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4908 (write_back.GetWriteBackUint32() << 21) |
4909 GetRegisterListEncoding(registers, 0, 16));
4910 return;
4911 }
4912 }
4913 Delegate(kLdmed, &Assembler::ldmed, cond, rn, write_back, registers);
4914 }
4915
ldmfa(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4916 void Assembler::ldmfa(Condition cond,
4917 Register rn,
4918 WriteBack write_back,
4919 RegisterList registers) {
4920 VIXL_ASSERT(AllowAssembler());
4921 CheckIT(cond);
4922 if (IsUsingA32()) {
4923 // LDMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
4924 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4925 EmitA32(0x08100000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4926 (write_back.GetWriteBackUint32() << 21) |
4927 GetRegisterListEncoding(registers, 0, 16));
4928 return;
4929 }
4930 }
4931 Delegate(kLdmfa, &Assembler::ldmfa, cond, rn, write_back, registers);
4932 }
4933
ldmfd(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)4934 void Assembler::ldmfd(Condition cond,
4935 EncodingSize size,
4936 Register rn,
4937 WriteBack write_back,
4938 RegisterList registers) {
4939 VIXL_ASSERT(AllowAssembler());
4940 CheckIT(cond);
4941 if (IsUsingT32()) {
4942 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
4943 if (!size.IsWide() && rn.IsLow() &&
4944 (((registers.GetList() & (1 << rn.GetCode())) == 0) ==
4945 write_back.DoesWriteBack()) &&
4946 ((registers.GetList() & ~0xff) == 0)) {
4947 EmitT32_16(0xc800 | (rn.GetCode() << 8) |
4948 GetRegisterListEncoding(registers, 0, 8));
4949 AdvanceIT();
4950 return;
4951 }
4952 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; T2
4953 if (!size.IsNarrow() && ((registers.GetList() & ~0xdfff) == 0) &&
4954 (!rn.IsPC() || AllowUnpredictable())) {
4955 EmitT32_32(0xe8900000U | (rn.GetCode() << 16) |
4956 (write_back.GetWriteBackUint32() << 21) |
4957 (GetRegisterListEncoding(registers, 15, 1) << 15) |
4958 (GetRegisterListEncoding(registers, 14, 1) << 14) |
4959 GetRegisterListEncoding(registers, 0, 13));
4960 AdvanceIT();
4961 return;
4962 }
4963 } else {
4964 // LDMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
4965 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4966 EmitA32(0x08900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4967 (write_back.GetWriteBackUint32() << 21) |
4968 GetRegisterListEncoding(registers, 0, 16));
4969 return;
4970 }
4971 }
4972 Delegate(kLdmfd, &Assembler::ldmfd, cond, size, rn, write_back, registers);
4973 }
4974
ldmib(Condition cond,Register rn,WriteBack write_back,RegisterList registers)4975 void Assembler::ldmib(Condition cond,
4976 Register rn,
4977 WriteBack write_back,
4978 RegisterList registers) {
4979 VIXL_ASSERT(AllowAssembler());
4980 CheckIT(cond);
4981 if (IsUsingA32()) {
4982 // LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
4983 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
4984 EmitA32(0x09900000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
4985 (write_back.GetWriteBackUint32() << 21) |
4986 GetRegisterListEncoding(registers, 0, 16));
4987 return;
4988 }
4989 }
4990 Delegate(kLdmib, &Assembler::ldmib, cond, rn, write_back, registers);
4991 }
4992
ldr(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)4993 void Assembler::ldr(Condition cond,
4994 EncodingSize size,
4995 Register rt,
4996 const MemOperand& operand) {
4997 VIXL_ASSERT(AllowAssembler());
4998 CheckIT(cond);
4999 if (operand.IsImmediate()) {
5000 Register rn = operand.GetBaseRegister();
5001 int32_t offset = operand.GetOffsetImmediate();
5002 if (IsUsingT32()) {
5003 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5004 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
5005 (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
5006 int32_t offset_ = offset >> 2;
5007 EmitT32_16(0x6800 | rt.GetCode() | (rn.GetCode() << 3) |
5008 ((offset_ & 0x1f) << 6));
5009 AdvanceIT();
5010 return;
5011 }
5012 // LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
5013 if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
5014 ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
5015 int32_t offset_ = offset >> 2;
5016 EmitT32_16(0x9800 | (rt.GetCode() << 8) | (offset_ & 0xff));
5017 AdvanceIT();
5018 return;
5019 }
5020 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
5021 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5022 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
5023 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5024 AllowUnpredictable())) {
5025 EmitT32_32(0xf8d00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5026 (offset & 0xfff));
5027 AdvanceIT();
5028 return;
5029 }
5030 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
5031 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5032 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
5033 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5034 AllowUnpredictable())) {
5035 EmitT32_32(0xf8500c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5036 (-offset & 0xff));
5037 AdvanceIT();
5038 return;
5039 }
5040 // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
5041 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5042 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
5043 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5044 AllowUnpredictable())) {
5045 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5046 uint32_t offset_ = abs(offset);
5047 EmitT32_32(0xf8500900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5048 offset_ | (sign << 9));
5049 AdvanceIT();
5050 return;
5051 }
5052 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
5053 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5054 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
5055 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5056 AllowUnpredictable())) {
5057 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5058 uint32_t offset_ = abs(offset);
5059 EmitT32_32(0xf8500d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5060 offset_ | (sign << 9));
5061 AdvanceIT();
5062 return;
5063 }
5064 // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T2
5065 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5066 rn.Is(pc) && operand.IsOffset() &&
5067 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5068 AllowUnpredictable())) {
5069 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5070 uint32_t offset_ = abs(offset);
5071 EmitT32_32(0xf85f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5072 AdvanceIT();
5073 return;
5074 }
5075 } else {
5076 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
5077 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
5078 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5079 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5080 uint32_t offset_ = abs(offset);
5081 EmitA32(0x05100000U | (cond.GetCondition() << 28) |
5082 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5083 (sign << 23));
5084 return;
5085 }
5086 // LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
5087 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
5088 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5089 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5090 uint32_t offset_ = abs(offset);
5091 EmitA32(0x04100000U | (cond.GetCondition() << 28) |
5092 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5093 (sign << 23));
5094 return;
5095 }
5096 // LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
5097 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
5098 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf)) {
5099 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5100 uint32_t offset_ = abs(offset);
5101 EmitA32(0x05300000U | (cond.GetCondition() << 28) |
5102 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5103 (sign << 23));
5104 return;
5105 }
5106 // LDR{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5107 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
5108 operand.IsOffset() && cond.IsNotNever()) {
5109 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5110 uint32_t offset_ = abs(offset);
5111 EmitA32(0x051f0000U | (cond.GetCondition() << 28) |
5112 (rt.GetCode() << 12) | offset_ | (sign << 23));
5113 return;
5114 }
5115 }
5116 }
5117 if (operand.IsPlainRegister()) {
5118 Register rn = operand.GetBaseRegister();
5119 Sign sign = operand.GetSign();
5120 Register rm = operand.GetOffsetRegister();
5121 if (IsUsingT32()) {
5122 // LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5123 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5124 sign.IsPlus() && operand.IsOffset()) {
5125 EmitT32_16(0x5800 | rt.GetCode() | (rn.GetCode() << 3) |
5126 (rm.GetCode() << 6));
5127 AdvanceIT();
5128 return;
5129 }
5130 }
5131 }
5132 if (operand.IsShiftedRegister()) {
5133 Register rn = operand.GetBaseRegister();
5134 Sign sign = operand.GetSign();
5135 Register rm = operand.GetOffsetRegister();
5136 Shift shift = operand.GetShift();
5137 uint32_t amount = operand.GetShiftAmount();
5138 if (IsUsingT32()) {
5139 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5140 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5141 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
5142 ((!rm.IsPC() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond))) ||
5143 AllowUnpredictable())) {
5144 EmitT32_32(0xf8500000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5145 rm.GetCode() | (amount << 4));
5146 AdvanceIT();
5147 return;
5148 }
5149 } else {
5150 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
5151 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
5152 (!rm.IsPC() || AllowUnpredictable())) {
5153 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5154 uint32_t shift_ = TypeEncodingValue(shift);
5155 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5156 EmitA32(0x07100000U | (cond.GetCondition() << 28) |
5157 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5158 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5159 return;
5160 }
5161 // LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
5162 if (operand.IsShiftValid() && operand.IsPostIndex() &&
5163 cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
5164 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5165 uint32_t shift_ = TypeEncodingValue(shift);
5166 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5167 EmitA32(0x06100000U | (cond.GetCondition() << 28) |
5168 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5169 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5170 return;
5171 }
5172 // LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
5173 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
5174 (!rm.IsPC() || AllowUnpredictable())) {
5175 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5176 uint32_t shift_ = TypeEncodingValue(shift);
5177 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5178 EmitA32(0x07300000U | (cond.GetCondition() << 28) |
5179 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5180 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5181 return;
5182 }
5183 }
5184 }
5185 Delegate(kLdr, &Assembler::ldr, cond, size, rt, operand);
5186 }
5187
ldr(Condition cond,EncodingSize size,Register rt,Location * location)5188 void Assembler::ldr(Condition cond,
5189 EncodingSize size,
5190 Register rt,
5191 Location* location) {
5192 VIXL_ASSERT(AllowAssembler());
5193 CheckIT(cond);
5194 Location::Offset offset =
5195 location->IsBound()
5196 ? location->GetLocation() -
5197 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5198 : 0;
5199 if (IsUsingT32()) {
5200 // LDR{<c>}{<q>} <Rt>, <label> ; T1
5201 if (!size.IsWide() && rt.IsLow() &&
5202 ((location->IsBound() && (offset >= 0) && (offset <= 1020) &&
5203 ((offset & 0x3) == 0)) ||
5204 (!location->IsBound() && size.IsNarrow()))) {
5205 static class EmitOp : public Location::EmitOperator {
5206 public:
5207 EmitOp() : Location::EmitOperator(T32) {}
5208 virtual uint32_t Encode(uint32_t instr,
5209 Location::Offset program_counter,
5210 const Location* loc) const VIXL_OVERRIDE {
5211 program_counter += kT32PcDelta;
5212 Location::Offset off =
5213 loc->GetLocation() - AlignDown(program_counter, 4);
5214 VIXL_ASSERT((off >= 0) && (off <= 1020) && ((off & 0x3) == 0));
5215 const int32_t target = off >> 2;
5216 return instr | (target & 0xff);
5217 }
5218 } immop;
5219 EmitT32_16(
5220 Link(0x4800 | (rt.GetCode() << 8), location, immop, &kT16DataInfo));
5221 AdvanceIT();
5222 return;
5223 }
5224 // LDR{<c>}{<q>} <Rt>, <label> ; T2
5225 if (!size.IsNarrow() &&
5226 ((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5227 !location->IsBound()) &&
5228 ((!rt.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
5229 AllowUnpredictable())) {
5230 static class EmitOp : public Location::EmitOperator {
5231 public:
5232 EmitOp() : Location::EmitOperator(T32) {}
5233 virtual uint32_t Encode(uint32_t instr,
5234 Location::Offset program_counter,
5235 const Location* loc) const VIXL_OVERRIDE {
5236 program_counter += kT32PcDelta;
5237 Location::Offset off =
5238 loc->GetLocation() - AlignDown(program_counter, 4);
5239 VIXL_ASSERT((off >= -4095) && (off <= 4095));
5240 uint32_t U = (off >= 0);
5241 int32_t target = abs(off) | (U << 12);
5242 return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5243 }
5244 } immop;
5245 EmitT32_32(Link(0xf85f0000U | (rt.GetCode() << 12),
5246 location,
5247 immop,
5248 &kT32FarDataInfo));
5249 AdvanceIT();
5250 return;
5251 }
5252 } else {
5253 // LDR{<c>}{<q>} <Rt>, <label> ; A1
5254 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5255 !location->IsBound()) &&
5256 cond.IsNotNever()) {
5257 static class EmitOp : public Location::EmitOperator {
5258 public:
5259 EmitOp() : Location::EmitOperator(A32) {}
5260 virtual uint32_t Encode(uint32_t instr,
5261 Location::Offset program_counter,
5262 const Location* loc) const VIXL_OVERRIDE {
5263 program_counter += kA32PcDelta;
5264 Location::Offset off =
5265 loc->GetLocation() - AlignDown(program_counter, 4);
5266 VIXL_ASSERT((off >= -4095) && (off <= 4095));
5267 uint32_t U = (off >= 0);
5268 int32_t target = abs(off) | (U << 12);
5269 return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5270 }
5271 } immop;
5272 EmitA32(
5273 Link(0x051f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5274 location,
5275 immop,
5276 &kA32FarDataInfo));
5277 return;
5278 }
5279 }
5280 Delegate(kLdr, &Assembler::ldr, cond, size, rt, location);
5281 }
5282
ldr_info(Condition cond,EncodingSize size,Register rt,Location * location,const struct ReferenceInfo ** info)5283 bool Assembler::ldr_info(Condition cond,
5284 EncodingSize size,
5285 Register rt,
5286 Location* location,
5287 const struct ReferenceInfo** info) {
5288 VIXL_ASSERT(!location->IsBound());
5289 USE(location);
5290 if (IsUsingT32()) {
5291 // LDR{<c>}{<q>} <Rt>, <label> ; T1
5292 if (!size.IsWide() && rt.IsLow() && size.IsNarrow()) {
5293 *info = &kT16DataInfo;
5294 return true;
5295 }
5296 // LDR{<c>}{<q>} <Rt>, <label> ; T2
5297 if (!size.IsNarrow()) {
5298 *info = &kT32FarDataInfo;
5299 return true;
5300 }
5301 } else {
5302 // LDR{<c>}{<q>} <Rt>, <label> ; A1
5303 if (cond.IsNotNever()) {
5304 *info = &kA32FarDataInfo;
5305 return true;
5306 }
5307 }
5308 return false;
5309 }
5310
ldrb(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)5311 void Assembler::ldrb(Condition cond,
5312 EncodingSize size,
5313 Register rt,
5314 const MemOperand& operand) {
5315 VIXL_ASSERT(AllowAssembler());
5316 CheckIT(cond);
5317 if (operand.IsImmediate()) {
5318 Register rn = operand.GetBaseRegister();
5319 int32_t offset = operand.GetOffsetImmediate();
5320 if (IsUsingT32()) {
5321 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5322 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
5323 (offset <= 31) && operand.IsOffset()) {
5324 EmitT32_16(0x7800 | rt.GetCode() | (rn.GetCode() << 3) |
5325 ((offset & 0x1f) << 6));
5326 AdvanceIT();
5327 return;
5328 }
5329 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
5330 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5331 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5332 EmitT32_32(0xf8900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5333 (offset & 0xfff));
5334 AdvanceIT();
5335 return;
5336 }
5337 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
5338 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5339 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5340 EmitT32_32(0xf8100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5341 (-offset & 0xff));
5342 AdvanceIT();
5343 return;
5344 }
5345 // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
5346 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5347 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5348 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5349 uint32_t offset_ = abs(offset);
5350 EmitT32_32(0xf8100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5351 offset_ | (sign << 9));
5352 AdvanceIT();
5353 return;
5354 }
5355 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
5356 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5357 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5358 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5359 uint32_t offset_ = abs(offset);
5360 EmitT32_32(0xf8100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5361 offset_ | (sign << 9));
5362 AdvanceIT();
5363 return;
5364 }
5365 // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5366 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
5367 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
5368 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5369 uint32_t offset_ = abs(offset);
5370 EmitT32_32(0xf81f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
5371 AdvanceIT();
5372 return;
5373 }
5374 } else {
5375 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
5376 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
5377 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5378 (!rt.IsPC() || AllowUnpredictable())) {
5379 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5380 uint32_t offset_ = abs(offset);
5381 EmitA32(0x05500000U | (cond.GetCondition() << 28) |
5382 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5383 (sign << 23));
5384 return;
5385 }
5386 // LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
5387 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
5388 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5389 (!rt.IsPC() || AllowUnpredictable())) {
5390 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5391 uint32_t offset_ = abs(offset);
5392 EmitA32(0x04500000U | (cond.GetCondition() << 28) |
5393 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5394 (sign << 23));
5395 return;
5396 }
5397 // LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
5398 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
5399 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5400 (!rt.IsPC() || AllowUnpredictable())) {
5401 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5402 uint32_t offset_ = abs(offset);
5403 EmitA32(0x05700000U | (cond.GetCondition() << 28) |
5404 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
5405 (sign << 23));
5406 return;
5407 }
5408 // LDRB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
5409 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
5410 operand.IsOffset() && cond.IsNotNever() &&
5411 (!rt.IsPC() || AllowUnpredictable())) {
5412 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5413 uint32_t offset_ = abs(offset);
5414 EmitA32(0x055f0000U | (cond.GetCondition() << 28) |
5415 (rt.GetCode() << 12) | offset_ | (sign << 23));
5416 return;
5417 }
5418 }
5419 }
5420 if (operand.IsPlainRegister()) {
5421 Register rn = operand.GetBaseRegister();
5422 Sign sign = operand.GetSign();
5423 Register rm = operand.GetOffsetRegister();
5424 if (IsUsingT32()) {
5425 // LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
5426 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
5427 sign.IsPlus() && operand.IsOffset()) {
5428 EmitT32_16(0x5c00 | rt.GetCode() | (rn.GetCode() << 3) |
5429 (rm.GetCode() << 6));
5430 AdvanceIT();
5431 return;
5432 }
5433 }
5434 }
5435 if (operand.IsShiftedRegister()) {
5436 Register rn = operand.GetBaseRegister();
5437 Sign sign = operand.GetSign();
5438 Register rm = operand.GetOffsetRegister();
5439 Shift shift = operand.GetShift();
5440 uint32_t amount = operand.GetShiftAmount();
5441 if (IsUsingT32()) {
5442 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
5443 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
5444 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
5445 (!rm.IsPC() || AllowUnpredictable())) {
5446 EmitT32_32(0xf8100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5447 rm.GetCode() | (amount << 4));
5448 AdvanceIT();
5449 return;
5450 }
5451 } else {
5452 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
5453 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
5454 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
5455 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5456 uint32_t shift_ = TypeEncodingValue(shift);
5457 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5458 EmitA32(0x07500000U | (cond.GetCondition() << 28) |
5459 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5460 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5461 return;
5462 }
5463 // LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
5464 if (operand.IsShiftValid() && operand.IsPostIndex() &&
5465 cond.IsNotNever() &&
5466 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
5467 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5468 uint32_t shift_ = TypeEncodingValue(shift);
5469 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5470 EmitA32(0x06500000U | (cond.GetCondition() << 28) |
5471 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5472 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5473 return;
5474 }
5475 // LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
5476 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
5477 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
5478 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5479 uint32_t shift_ = TypeEncodingValue(shift);
5480 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
5481 EmitA32(0x07700000U | (cond.GetCondition() << 28) |
5482 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5483 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
5484 return;
5485 }
5486 }
5487 }
5488 Delegate(kLdrb, &Assembler::ldrb, cond, size, rt, operand);
5489 }
5490
ldrb(Condition cond,Register rt,Location * location)5491 void Assembler::ldrb(Condition cond, Register rt, Location* location) {
5492 VIXL_ASSERT(AllowAssembler());
5493 CheckIT(cond);
5494 Location::Offset offset =
5495 location->IsBound()
5496 ? location->GetLocation() -
5497 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5498 : 0;
5499 if (IsUsingT32()) {
5500 // LDRB{<c>}{<q>} <Rt>, <label> ; T1
5501 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5502 !location->IsBound()) &&
5503 !rt.Is(pc)) {
5504 static class EmitOp : public Location::EmitOperator {
5505 public:
5506 EmitOp() : Location::EmitOperator(T32) {}
5507 virtual uint32_t Encode(uint32_t instr,
5508 Location::Offset program_counter,
5509 const Location* loc) const VIXL_OVERRIDE {
5510 program_counter += kT32PcDelta;
5511 Location::Offset off =
5512 loc->GetLocation() - AlignDown(program_counter, 4);
5513 VIXL_ASSERT((off >= -4095) && (off <= 4095));
5514 uint32_t U = (off >= 0);
5515 int32_t target = abs(off) | (U << 12);
5516 return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5517 }
5518 } immop;
5519 EmitT32_32(Link(0xf81f0000U | (rt.GetCode() << 12),
5520 location,
5521 immop,
5522 &kT32FarDataInfo));
5523 AdvanceIT();
5524 return;
5525 }
5526 } else {
5527 // LDRB{<c>}{<q>} <Rt>, <label> ; A1
5528 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
5529 !location->IsBound()) &&
5530 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
5531 static class EmitOp : public Location::EmitOperator {
5532 public:
5533 EmitOp() : Location::EmitOperator(A32) {}
5534 virtual uint32_t Encode(uint32_t instr,
5535 Location::Offset program_counter,
5536 const Location* loc) const VIXL_OVERRIDE {
5537 program_counter += kA32PcDelta;
5538 Location::Offset off =
5539 loc->GetLocation() - AlignDown(program_counter, 4);
5540 VIXL_ASSERT((off >= -4095) && (off <= 4095));
5541 uint32_t U = (off >= 0);
5542 int32_t target = abs(off) | (U << 12);
5543 return instr | (target & 0xfff) | ((target & 0x1000) << 11);
5544 }
5545 } immop;
5546 EmitA32(
5547 Link(0x055f0000U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5548 location,
5549 immop,
5550 &kA32FarDataInfo));
5551 return;
5552 }
5553 }
5554 Delegate(kLdrb, &Assembler::ldrb, cond, rt, location);
5555 }
5556
ldrb_info(Condition cond,Register rt,Location * location,const struct ReferenceInfo ** info)5557 bool Assembler::ldrb_info(Condition cond,
5558 Register rt,
5559 Location* location,
5560 const struct ReferenceInfo** info) {
5561 VIXL_ASSERT(!location->IsBound());
5562 USE(location);
5563 if (IsUsingT32()) {
5564 // LDRB{<c>}{<q>} <Rt>, <label> ; T1
5565 if (!rt.Is(pc)) {
5566 *info = &kT32FarDataInfo;
5567 return true;
5568 }
5569 } else {
5570 // LDRB{<c>}{<q>} <Rt>, <label> ; A1
5571 if (cond.IsNotNever()) {
5572 *info = &kA32FarDataInfo;
5573 return true;
5574 }
5575 }
5576 return false;
5577 }
5578
ldrd(Condition cond,Register rt,Register rt2,const MemOperand & operand)5579 void Assembler::ldrd(Condition cond,
5580 Register rt,
5581 Register rt2,
5582 const MemOperand& operand) {
5583 VIXL_ASSERT(AllowAssembler());
5584 CheckIT(cond);
5585 if (operand.IsImmediate()) {
5586 Register rn = operand.GetBaseRegister();
5587 int32_t offset = operand.GetOffsetImmediate();
5588 if (IsUsingT32()) {
5589 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
5590 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5591 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
5592 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
5593 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5594 uint32_t offset_ = abs(offset) >> 2;
5595 EmitT32_32(0xe9500000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5596 (rn.GetCode() << 16) | offset_ | (sign << 23));
5597 AdvanceIT();
5598 return;
5599 }
5600 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
5601 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5602 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
5603 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
5604 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5605 uint32_t offset_ = abs(offset) >> 2;
5606 EmitT32_32(0xe8700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5607 (rn.GetCode() << 16) | offset_ | (sign << 23));
5608 AdvanceIT();
5609 return;
5610 }
5611 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
5612 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
5613 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
5614 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
5615 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5616 uint32_t offset_ = abs(offset) >> 2;
5617 EmitT32_32(0xe9700000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5618 (rn.GetCode() << 16) | offset_ | (sign << 23));
5619 AdvanceIT();
5620 return;
5621 }
5622 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm>] ; T1
5623 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5624 operand.IsOffset() &&
5625 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
5626 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5627 uint32_t offset_ = abs(offset);
5628 EmitT32_32(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5629 offset_ | (sign << 23));
5630 AdvanceIT();
5631 return;
5632 }
5633 } else {
5634 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
5635 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5636 (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
5637 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5638 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
5639 AllowUnpredictable())) {
5640 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5641 uint32_t offset_ = abs(offset);
5642 EmitA32(0x014000d0U | (cond.GetCondition() << 28) |
5643 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5644 ((offset_ & 0xf0) << 4) | (sign << 23));
5645 return;
5646 }
5647 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
5648 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5649 (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
5650 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5651 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
5652 AllowUnpredictable())) {
5653 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5654 uint32_t offset_ = abs(offset);
5655 EmitA32(0x004000d0U | (cond.GetCondition() << 28) |
5656 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5657 ((offset_ & 0xf0) << 4) | (sign << 23));
5658 return;
5659 }
5660 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
5661 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5662 (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
5663 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
5664 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
5665 AllowUnpredictable())) {
5666 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5667 uint32_t offset_ = abs(offset);
5668 EmitA32(0x016000d0U | (cond.GetCondition() << 28) |
5669 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
5670 ((offset_ & 0xf0) << 4) | (sign << 23));
5671 return;
5672 }
5673 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [PC, #<_plusminus_><imm_1>] ; A1
5674 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5675 (offset >= -255) && (offset <= 255) && rn.Is(pc) &&
5676 operand.IsOffset() && cond.IsNotNever() &&
5677 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
5678 AllowUnpredictable())) {
5679 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5680 uint32_t offset_ = abs(offset);
5681 EmitA32(0x014f00d0U | (cond.GetCondition() << 28) |
5682 (rt.GetCode() << 12) | (offset_ & 0xf) |
5683 ((offset_ & 0xf0) << 4) | (sign << 23));
5684 return;
5685 }
5686 }
5687 }
5688 if (operand.IsPlainRegister()) {
5689 Register rn = operand.GetBaseRegister();
5690 Sign sign = operand.GetSign();
5691 Register rm = operand.GetOffsetRegister();
5692 if (IsUsingA32()) {
5693 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
5694 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5695 operand.IsOffset() && cond.IsNotNever() &&
5696 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
5697 AllowUnpredictable())) {
5698 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5699 EmitA32(0x010000d0U | (cond.GetCondition() << 28) |
5700 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5701 (sign_ << 23));
5702 return;
5703 }
5704 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
5705 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5706 operand.IsPostIndex() && cond.IsNotNever() &&
5707 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
5708 AllowUnpredictable())) {
5709 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5710 EmitA32(0x000000d0U | (cond.GetCondition() << 28) |
5711 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5712 (sign_ << 23));
5713 return;
5714 }
5715 // LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
5716 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5717 operand.IsPreIndex() && cond.IsNotNever() &&
5718 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
5719 AllowUnpredictable())) {
5720 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
5721 EmitA32(0x012000d0U | (cond.GetCondition() << 28) |
5722 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
5723 (sign_ << 23));
5724 return;
5725 }
5726 }
5727 }
5728 Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, operand);
5729 }
5730
ldrd(Condition cond,Register rt,Register rt2,Location * location)5731 void Assembler::ldrd(Condition cond,
5732 Register rt,
5733 Register rt2,
5734 Location* location) {
5735 VIXL_ASSERT(AllowAssembler());
5736 CheckIT(cond);
5737 Location::Offset offset =
5738 location->IsBound()
5739 ? location->GetLocation() -
5740 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
5741 : 0;
5742 if (IsUsingT32()) {
5743 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
5744 if (((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
5745 ((offset & 0x3) == 0)) ||
5746 !location->IsBound()) &&
5747 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
5748 static class EmitOp : public Location::EmitOperator {
5749 public:
5750 EmitOp() : Location::EmitOperator(T32) {}
5751 virtual uint32_t Encode(uint32_t instr,
5752 Location::Offset program_counter,
5753 const Location* loc) const VIXL_OVERRIDE {
5754 program_counter += kT32PcDelta;
5755 Location::Offset off =
5756 loc->GetLocation() - AlignDown(program_counter, 4);
5757 VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0));
5758 int32_t target = off >> 2;
5759 uint32_t U = (target >= 0);
5760 target = abs(target) | (U << 8);
5761 return instr | (target & 0xff) | ((target & 0x100) << 15);
5762 }
5763 } immop;
5764 EmitT32_32(Link(0xe95f0000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8),
5765 location,
5766 immop,
5767 &kT32DataInfo));
5768 AdvanceIT();
5769 return;
5770 }
5771 } else {
5772 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
5773 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5774 ((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
5775 !location->IsBound()) &&
5776 cond.IsNotNever() &&
5777 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) || AllowUnpredictable())) {
5778 static class EmitOp : public Location::EmitOperator {
5779 public:
5780 EmitOp() : Location::EmitOperator(A32) {}
5781 virtual uint32_t Encode(uint32_t instr,
5782 Location::Offset program_counter,
5783 const Location* loc) const VIXL_OVERRIDE {
5784 program_counter += kA32PcDelta;
5785 Location::Offset off =
5786 loc->GetLocation() - AlignDown(program_counter, 4);
5787 VIXL_ASSERT((off >= -255) && (off <= 255));
5788 uint32_t U = (off >= 0);
5789 int32_t target = abs(off) | (U << 8);
5790 return instr | (target & 0xf) | ((target & 0xf0) << 4) |
5791 ((target & 0x100) << 15);
5792 }
5793 } immop;
5794 EmitA32(
5795 Link(0x014f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
5796 location,
5797 immop,
5798 &kA32VeryNearDataInfo));
5799 return;
5800 }
5801 }
5802 Delegate(kLdrd, &Assembler::ldrd, cond, rt, rt2, location);
5803 }
5804
ldrd_info(Condition cond,Register rt,Register rt2,Location * location,const struct ReferenceInfo ** info)5805 bool Assembler::ldrd_info(Condition cond,
5806 Register rt,
5807 Register rt2,
5808 Location* location,
5809 const struct ReferenceInfo** info) {
5810 VIXL_ASSERT(!location->IsBound());
5811 USE(location);
5812 if (IsUsingT32()) {
5813 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
5814 if (true) {
5815 *info = &kT32DataInfo;
5816 return true;
5817 }
5818 } else {
5819 // LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
5820 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5821 cond.IsNotNever()) {
5822 *info = &kA32VeryNearDataInfo;
5823 return true;
5824 }
5825 }
5826 return false;
5827 }
5828
ldrex(Condition cond,Register rt,const MemOperand & operand)5829 void Assembler::ldrex(Condition cond, Register rt, const MemOperand& operand) {
5830 VIXL_ASSERT(AllowAssembler());
5831 CheckIT(cond);
5832 if (operand.IsImmediate()) {
5833 Register rn = operand.GetBaseRegister();
5834 int32_t offset = operand.GetOffsetImmediate();
5835 if (IsUsingT32()) {
5836 // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1
5837 if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
5838 operand.IsOffset() &&
5839 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5840 int32_t offset_ = offset >> 2;
5841 EmitT32_32(0xe8500f00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5842 (offset_ & 0xff));
5843 AdvanceIT();
5844 return;
5845 }
5846 } else {
5847 // LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1
5848 if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() &&
5849 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5850 EmitA32(0x01900f9fU | (cond.GetCondition() << 28) |
5851 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5852 return;
5853 }
5854 }
5855 }
5856 Delegate(kLdrex, &Assembler::ldrex, cond, rt, operand);
5857 }
5858
ldrexb(Condition cond,Register rt,const MemOperand & operand)5859 void Assembler::ldrexb(Condition cond, Register rt, const MemOperand& operand) {
5860 VIXL_ASSERT(AllowAssembler());
5861 CheckIT(cond);
5862 if (operand.IsImmediateZero()) {
5863 Register rn = operand.GetBaseRegister();
5864 if (IsUsingT32()) {
5865 // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
5866 if (operand.IsOffset() &&
5867 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5868 EmitT32_32(0xe8d00f4fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5869 AdvanceIT();
5870 return;
5871 }
5872 } else {
5873 // LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
5874 if (operand.IsOffset() && cond.IsNotNever() &&
5875 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5876 EmitA32(0x01d00f9fU | (cond.GetCondition() << 28) |
5877 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5878 return;
5879 }
5880 }
5881 }
5882 Delegate(kLdrexb, &Assembler::ldrexb, cond, rt, operand);
5883 }
5884
ldrexd(Condition cond,Register rt,Register rt2,const MemOperand & operand)5885 void Assembler::ldrexd(Condition cond,
5886 Register rt,
5887 Register rt2,
5888 const MemOperand& operand) {
5889 VIXL_ASSERT(AllowAssembler());
5890 CheckIT(cond);
5891 if (operand.IsImmediateZero()) {
5892 Register rn = operand.GetBaseRegister();
5893 if (IsUsingT32()) {
5894 // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
5895 if (operand.IsOffset() &&
5896 ((!rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5897 EmitT32_32(0xe8d0007fU | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
5898 (rn.GetCode() << 16));
5899 AdvanceIT();
5900 return;
5901 }
5902 } else {
5903 // LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
5904 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
5905 operand.IsOffset() && cond.IsNotNever() &&
5906 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rn.IsPC()) ||
5907 AllowUnpredictable())) {
5908 EmitA32(0x01b00f9fU | (cond.GetCondition() << 28) |
5909 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5910 return;
5911 }
5912 }
5913 }
5914 Delegate(kLdrexd, &Assembler::ldrexd, cond, rt, rt2, operand);
5915 }
5916
ldrexh(Condition cond,Register rt,const MemOperand & operand)5917 void Assembler::ldrexh(Condition cond, Register rt, const MemOperand& operand) {
5918 VIXL_ASSERT(AllowAssembler());
5919 CheckIT(cond);
5920 if (operand.IsImmediateZero()) {
5921 Register rn = operand.GetBaseRegister();
5922 if (IsUsingT32()) {
5923 // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
5924 if (operand.IsOffset() &&
5925 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5926 EmitT32_32(0xe8d00f5fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
5927 AdvanceIT();
5928 return;
5929 }
5930 } else {
5931 // LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
5932 if (operand.IsOffset() && cond.IsNotNever() &&
5933 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
5934 EmitA32(0x01f00f9fU | (cond.GetCondition() << 28) |
5935 (rt.GetCode() << 12) | (rn.GetCode() << 16));
5936 return;
5937 }
5938 }
5939 }
5940 Delegate(kLdrexh, &Assembler::ldrexh, cond, rt, operand);
5941 }
5942
ldrh(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)5943 void Assembler::ldrh(Condition cond,
5944 EncodingSize size,
5945 Register rt,
5946 const MemOperand& operand) {
5947 VIXL_ASSERT(AllowAssembler());
5948 CheckIT(cond);
5949 if (operand.IsImmediate()) {
5950 Register rn = operand.GetBaseRegister();
5951 int32_t offset = operand.GetOffsetImmediate();
5952 if (IsUsingT32()) {
5953 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
5954 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
5955 (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
5956 int32_t offset_ = offset >> 1;
5957 EmitT32_16(0x8800 | rt.GetCode() | (rn.GetCode() << 3) |
5958 ((offset_ & 0x1f) << 6));
5959 AdvanceIT();
5960 return;
5961 }
5962 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
5963 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
5964 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5965 EmitT32_32(0xf8b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5966 (offset & 0xfff));
5967 AdvanceIT();
5968 return;
5969 }
5970 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
5971 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
5972 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
5973 EmitT32_32(0xf8300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5974 (-offset & 0xff));
5975 AdvanceIT();
5976 return;
5977 }
5978 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
5979 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5980 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5981 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5982 uint32_t offset_ = abs(offset);
5983 EmitT32_32(0xf8300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5984 offset_ | (sign << 9));
5985 AdvanceIT();
5986 return;
5987 }
5988 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
5989 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
5990 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
5991 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
5992 uint32_t offset_ = abs(offset);
5993 EmitT32_32(0xf8300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
5994 offset_ | (sign << 9));
5995 AdvanceIT();
5996 return;
5997 }
5998 // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
5999 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
6000 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
6001 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6002 uint32_t offset_ = abs(offset);
6003 EmitT32_32(0xf83f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
6004 AdvanceIT();
6005 return;
6006 }
6007 } else {
6008 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
6009 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
6010 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6011 (!rt.IsPC() || AllowUnpredictable())) {
6012 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6013 uint32_t offset_ = abs(offset);
6014 EmitA32(0x015000b0U | (cond.GetCondition() << 28) |
6015 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6016 ((offset_ & 0xf0) << 4) | (sign << 23));
6017 return;
6018 }
6019 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
6020 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
6021 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6022 (!rt.IsPC() || AllowUnpredictable())) {
6023 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6024 uint32_t offset_ = abs(offset);
6025 EmitA32(0x005000b0U | (cond.GetCondition() << 28) |
6026 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6027 ((offset_ & 0xf0) << 4) | (sign << 23));
6028 return;
6029 }
6030 // LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
6031 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
6032 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6033 (!rt.IsPC() || AllowUnpredictable())) {
6034 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6035 uint32_t offset_ = abs(offset);
6036 EmitA32(0x017000b0U | (cond.GetCondition() << 28) |
6037 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6038 ((offset_ & 0xf0) << 4) | (sign << 23));
6039 return;
6040 }
6041 // LDRH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
6042 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
6043 operand.IsOffset() && cond.IsNotNever() &&
6044 (!rt.IsPC() || AllowUnpredictable())) {
6045 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6046 uint32_t offset_ = abs(offset);
6047 EmitA32(0x015f00b0U | (cond.GetCondition() << 28) |
6048 (rt.GetCode() << 12) | (offset_ & 0xf) |
6049 ((offset_ & 0xf0) << 4) | (sign << 23));
6050 return;
6051 }
6052 }
6053 }
6054 if (operand.IsPlainRegister()) {
6055 Register rn = operand.GetBaseRegister();
6056 Sign sign = operand.GetSign();
6057 Register rm = operand.GetOffsetRegister();
6058 if (IsUsingT32()) {
6059 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
6060 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
6061 sign.IsPlus() && operand.IsOffset()) {
6062 EmitT32_16(0x5a00 | rt.GetCode() | (rn.GetCode() << 3) |
6063 (rm.GetCode() << 6));
6064 AdvanceIT();
6065 return;
6066 }
6067 } else {
6068 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
6069 if (operand.IsOffset() && cond.IsNotNever() &&
6070 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6071 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6072 EmitA32(0x011000b0U | (cond.GetCondition() << 28) |
6073 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6074 (sign_ << 23));
6075 return;
6076 }
6077 // LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
6078 if (operand.IsPostIndex() && cond.IsNotNever() &&
6079 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6080 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6081 EmitA32(0x001000b0U | (cond.GetCondition() << 28) |
6082 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6083 (sign_ << 23));
6084 return;
6085 }
6086 // LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
6087 if (operand.IsPreIndex() && cond.IsNotNever() &&
6088 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6089 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6090 EmitA32(0x013000b0U | (cond.GetCondition() << 28) |
6091 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6092 (sign_ << 23));
6093 return;
6094 }
6095 }
6096 }
6097 if (operand.IsShiftedRegister()) {
6098 Register rn = operand.GetBaseRegister();
6099 Sign sign = operand.GetSign();
6100 Register rm = operand.GetOffsetRegister();
6101 Shift shift = operand.GetShift();
6102 uint32_t amount = operand.GetShiftAmount();
6103 if (IsUsingT32()) {
6104 // LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
6105 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
6106 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
6107 (!rm.IsPC() || AllowUnpredictable())) {
6108 EmitT32_32(0xf8300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6109 rm.GetCode() | (amount << 4));
6110 AdvanceIT();
6111 return;
6112 }
6113 }
6114 }
6115 Delegate(kLdrh, &Assembler::ldrh, cond, size, rt, operand);
6116 }
6117
ldrh(Condition cond,Register rt,Location * location)6118 void Assembler::ldrh(Condition cond, Register rt, Location* location) {
6119 VIXL_ASSERT(AllowAssembler());
6120 CheckIT(cond);
6121 Location::Offset offset =
6122 location->IsBound()
6123 ? location->GetLocation() -
6124 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
6125 : 0;
6126 if (IsUsingT32()) {
6127 // LDRH{<c>}{<q>} <Rt>, <label> ; T1
6128 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
6129 !location->IsBound()) &&
6130 !rt.Is(pc)) {
6131 static class EmitOp : public Location::EmitOperator {
6132 public:
6133 EmitOp() : Location::EmitOperator(T32) {}
6134 virtual uint32_t Encode(uint32_t instr,
6135 Location::Offset program_counter,
6136 const Location* loc) const VIXL_OVERRIDE {
6137 program_counter += kT32PcDelta;
6138 Location::Offset off =
6139 loc->GetLocation() - AlignDown(program_counter, 4);
6140 VIXL_ASSERT((off >= -4095) && (off <= 4095));
6141 uint32_t U = (off >= 0);
6142 int32_t target = abs(off) | (U << 12);
6143 return instr | (target & 0xfff) | ((target & 0x1000) << 11);
6144 }
6145 } immop;
6146 EmitT32_32(Link(0xf83f0000U | (rt.GetCode() << 12),
6147 location,
6148 immop,
6149 &kT32FarDataInfo));
6150 AdvanceIT();
6151 return;
6152 }
6153 } else {
6154 // LDRH{<c>}{<q>} <Rt>, <label> ; A1
6155 if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
6156 !location->IsBound()) &&
6157 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
6158 static class EmitOp : public Location::EmitOperator {
6159 public:
6160 EmitOp() : Location::EmitOperator(A32) {}
6161 virtual uint32_t Encode(uint32_t instr,
6162 Location::Offset program_counter,
6163 const Location* loc) const VIXL_OVERRIDE {
6164 program_counter += kA32PcDelta;
6165 Location::Offset off =
6166 loc->GetLocation() - AlignDown(program_counter, 4);
6167 VIXL_ASSERT((off >= -255) && (off <= 255));
6168 uint32_t U = (off >= 0);
6169 int32_t target = abs(off) | (U << 8);
6170 return instr | (target & 0xf) | ((target & 0xf0) << 4) |
6171 ((target & 0x100) << 15);
6172 }
6173 } immop;
6174 EmitA32(
6175 Link(0x015f00b0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
6176 location,
6177 immop,
6178 &kA32VeryNearDataInfo));
6179 return;
6180 }
6181 }
6182 Delegate(kLdrh, &Assembler::ldrh, cond, rt, location);
6183 }
6184
ldrh_info(Condition cond,Register rt,Location * location,const struct ReferenceInfo ** info)6185 bool Assembler::ldrh_info(Condition cond,
6186 Register rt,
6187 Location* location,
6188 const struct ReferenceInfo** info) {
6189 VIXL_ASSERT(!location->IsBound());
6190 USE(location);
6191 if (IsUsingT32()) {
6192 // LDRH{<c>}{<q>} <Rt>, <label> ; T1
6193 if (!rt.Is(pc)) {
6194 *info = &kT32FarDataInfo;
6195 return true;
6196 }
6197 } else {
6198 // LDRH{<c>}{<q>} <Rt>, <label> ; A1
6199 if (cond.IsNotNever()) {
6200 *info = &kA32VeryNearDataInfo;
6201 return true;
6202 }
6203 }
6204 return false;
6205 }
6206
ldrsb(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)6207 void Assembler::ldrsb(Condition cond,
6208 EncodingSize size,
6209 Register rt,
6210 const MemOperand& operand) {
6211 VIXL_ASSERT(AllowAssembler());
6212 CheckIT(cond);
6213 if (operand.IsImmediate()) {
6214 Register rn = operand.GetBaseRegister();
6215 int32_t offset = operand.GetOffsetImmediate();
6216 if (IsUsingT32()) {
6217 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
6218 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
6219 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
6220 EmitT32_32(0xf9900000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6221 (offset & 0xfff));
6222 AdvanceIT();
6223 return;
6224 }
6225 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
6226 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
6227 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
6228 EmitT32_32(0xf9100c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6229 (-offset & 0xff));
6230 AdvanceIT();
6231 return;
6232 }
6233 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
6234 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
6235 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
6236 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6237 uint32_t offset_ = abs(offset);
6238 EmitT32_32(0xf9100900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6239 offset_ | (sign << 9));
6240 AdvanceIT();
6241 return;
6242 }
6243 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
6244 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
6245 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
6246 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6247 uint32_t offset_ = abs(offset);
6248 EmitT32_32(0xf9100d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6249 offset_ | (sign << 9));
6250 AdvanceIT();
6251 return;
6252 }
6253 // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
6254 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
6255 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
6256 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6257 uint32_t offset_ = abs(offset);
6258 EmitT32_32(0xf91f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
6259 AdvanceIT();
6260 return;
6261 }
6262 } else {
6263 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
6264 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
6265 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6266 (!rt.IsPC() || AllowUnpredictable())) {
6267 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6268 uint32_t offset_ = abs(offset);
6269 EmitA32(0x015000d0U | (cond.GetCondition() << 28) |
6270 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6271 ((offset_ & 0xf0) << 4) | (sign << 23));
6272 return;
6273 }
6274 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
6275 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
6276 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6277 (!rt.IsPC() || AllowUnpredictable())) {
6278 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6279 uint32_t offset_ = abs(offset);
6280 EmitA32(0x005000d0U | (cond.GetCondition() << 28) |
6281 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6282 ((offset_ & 0xf0) << 4) | (sign << 23));
6283 return;
6284 }
6285 // LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
6286 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
6287 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6288 (!rt.IsPC() || AllowUnpredictable())) {
6289 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6290 uint32_t offset_ = abs(offset);
6291 EmitA32(0x017000d0U | (cond.GetCondition() << 28) |
6292 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6293 ((offset_ & 0xf0) << 4) | (sign << 23));
6294 return;
6295 }
6296 // LDRSB{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
6297 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
6298 operand.IsOffset() && cond.IsNotNever() &&
6299 (!rt.IsPC() || AllowUnpredictable())) {
6300 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6301 uint32_t offset_ = abs(offset);
6302 EmitA32(0x015f00d0U | (cond.GetCondition() << 28) |
6303 (rt.GetCode() << 12) | (offset_ & 0xf) |
6304 ((offset_ & 0xf0) << 4) | (sign << 23));
6305 return;
6306 }
6307 }
6308 }
6309 if (operand.IsPlainRegister()) {
6310 Register rn = operand.GetBaseRegister();
6311 Sign sign = operand.GetSign();
6312 Register rm = operand.GetOffsetRegister();
6313 if (IsUsingT32()) {
6314 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
6315 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
6316 sign.IsPlus() && operand.IsOffset()) {
6317 EmitT32_16(0x5600 | rt.GetCode() | (rn.GetCode() << 3) |
6318 (rm.GetCode() << 6));
6319 AdvanceIT();
6320 return;
6321 }
6322 } else {
6323 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
6324 if (operand.IsOffset() && cond.IsNotNever() &&
6325 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6326 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6327 EmitA32(0x011000d0U | (cond.GetCondition() << 28) |
6328 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6329 (sign_ << 23));
6330 return;
6331 }
6332 // LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
6333 if (operand.IsPostIndex() && cond.IsNotNever() &&
6334 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6335 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6336 EmitA32(0x001000d0U | (cond.GetCondition() << 28) |
6337 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6338 (sign_ << 23));
6339 return;
6340 }
6341 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
6342 if (operand.IsPreIndex() && cond.IsNotNever() &&
6343 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6344 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6345 EmitA32(0x013000d0U | (cond.GetCondition() << 28) |
6346 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6347 (sign_ << 23));
6348 return;
6349 }
6350 }
6351 }
6352 if (operand.IsShiftedRegister()) {
6353 Register rn = operand.GetBaseRegister();
6354 Sign sign = operand.GetSign();
6355 Register rm = operand.GetOffsetRegister();
6356 Shift shift = operand.GetShift();
6357 uint32_t amount = operand.GetShiftAmount();
6358 if (IsUsingT32()) {
6359 // LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
6360 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
6361 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
6362 (!rm.IsPC() || AllowUnpredictable())) {
6363 EmitT32_32(0xf9100000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6364 rm.GetCode() | (amount << 4));
6365 AdvanceIT();
6366 return;
6367 }
6368 }
6369 }
6370 Delegate(kLdrsb, &Assembler::ldrsb, cond, size, rt, operand);
6371 }
6372
ldrsb(Condition cond,Register rt,Location * location)6373 void Assembler::ldrsb(Condition cond, Register rt, Location* location) {
6374 VIXL_ASSERT(AllowAssembler());
6375 CheckIT(cond);
6376 Location::Offset offset =
6377 location->IsBound()
6378 ? location->GetLocation() -
6379 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
6380 : 0;
6381 if (IsUsingT32()) {
6382 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
6383 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
6384 !location->IsBound()) &&
6385 !rt.Is(pc)) {
6386 static class EmitOp : public Location::EmitOperator {
6387 public:
6388 EmitOp() : Location::EmitOperator(T32) {}
6389 virtual uint32_t Encode(uint32_t instr,
6390 Location::Offset program_counter,
6391 const Location* loc) const VIXL_OVERRIDE {
6392 program_counter += kT32PcDelta;
6393 Location::Offset off =
6394 loc->GetLocation() - AlignDown(program_counter, 4);
6395 VIXL_ASSERT((off >= -4095) && (off <= 4095));
6396 uint32_t U = (off >= 0);
6397 int32_t target = abs(off) | (U << 12);
6398 return instr | (target & 0xfff) | ((target & 0x1000) << 11);
6399 }
6400 } immop;
6401 EmitT32_32(Link(0xf91f0000U | (rt.GetCode() << 12),
6402 location,
6403 immop,
6404 &kT32FarDataInfo));
6405 AdvanceIT();
6406 return;
6407 }
6408 } else {
6409 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
6410 if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
6411 !location->IsBound()) &&
6412 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
6413 static class EmitOp : public Location::EmitOperator {
6414 public:
6415 EmitOp() : Location::EmitOperator(A32) {}
6416 virtual uint32_t Encode(uint32_t instr,
6417 Location::Offset program_counter,
6418 const Location* loc) const VIXL_OVERRIDE {
6419 program_counter += kA32PcDelta;
6420 Location::Offset off =
6421 loc->GetLocation() - AlignDown(program_counter, 4);
6422 VIXL_ASSERT((off >= -255) && (off <= 255));
6423 uint32_t U = (off >= 0);
6424 int32_t target = abs(off) | (U << 8);
6425 return instr | (target & 0xf) | ((target & 0xf0) << 4) |
6426 ((target & 0x100) << 15);
6427 }
6428 } immop;
6429 EmitA32(
6430 Link(0x015f00d0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
6431 location,
6432 immop,
6433 &kA32VeryNearDataInfo));
6434 return;
6435 }
6436 }
6437 Delegate(kLdrsb, &Assembler::ldrsb, cond, rt, location);
6438 }
6439
ldrsb_info(Condition cond,Register rt,Location * location,const struct ReferenceInfo ** info)6440 bool Assembler::ldrsb_info(Condition cond,
6441 Register rt,
6442 Location* location,
6443 const struct ReferenceInfo** info) {
6444 VIXL_ASSERT(!location->IsBound());
6445 USE(location);
6446 if (IsUsingT32()) {
6447 // LDRSB{<c>}{<q>} <Rt>, <label> ; T1
6448 if (!rt.Is(pc)) {
6449 *info = &kT32FarDataInfo;
6450 return true;
6451 }
6452 } else {
6453 // LDRSB{<c>}{<q>} <Rt>, <label> ; A1
6454 if (cond.IsNotNever()) {
6455 *info = &kA32VeryNearDataInfo;
6456 return true;
6457 }
6458 }
6459 return false;
6460 }
6461
ldrsh(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)6462 void Assembler::ldrsh(Condition cond,
6463 EncodingSize size,
6464 Register rt,
6465 const MemOperand& operand) {
6466 VIXL_ASSERT(AllowAssembler());
6467 CheckIT(cond);
6468 if (operand.IsImmediate()) {
6469 Register rn = operand.GetBaseRegister();
6470 int32_t offset = operand.GetOffsetImmediate();
6471 if (IsUsingT32()) {
6472 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
6473 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
6474 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
6475 EmitT32_32(0xf9b00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6476 (offset & 0xfff));
6477 AdvanceIT();
6478 return;
6479 }
6480 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2
6481 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
6482 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc)) {
6483 EmitT32_32(0xf9300c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6484 (-offset & 0xff));
6485 AdvanceIT();
6486 return;
6487 }
6488 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2
6489 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
6490 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
6491 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6492 uint32_t offset_ = abs(offset);
6493 EmitT32_32(0xf9300900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6494 offset_ | (sign << 9));
6495 AdvanceIT();
6496 return;
6497 }
6498 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2
6499 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
6500 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf)) {
6501 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6502 uint32_t offset_ = abs(offset);
6503 EmitT32_32(0xf9300d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6504 offset_ | (sign << 9));
6505 AdvanceIT();
6506 return;
6507 }
6508 // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm>] ; T1
6509 if (!size.IsNarrow() && (offset >= -4095) && (offset <= 4095) &&
6510 rn.Is(pc) && operand.IsOffset() && !rt.Is(pc)) {
6511 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6512 uint32_t offset_ = abs(offset);
6513 EmitT32_32(0xf93f0000U | (rt.GetCode() << 12) | offset_ | (sign << 23));
6514 AdvanceIT();
6515 return;
6516 }
6517 } else {
6518 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1
6519 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
6520 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6521 (!rt.IsPC() || AllowUnpredictable())) {
6522 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6523 uint32_t offset_ = abs(offset);
6524 EmitA32(0x015000f0U | (cond.GetCondition() << 28) |
6525 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6526 ((offset_ & 0xf0) << 4) | (sign << 23));
6527 return;
6528 }
6529 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
6530 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
6531 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6532 (!rt.IsPC() || AllowUnpredictable())) {
6533 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6534 uint32_t offset_ = abs(offset);
6535 EmitA32(0x005000f0U | (cond.GetCondition() << 28) |
6536 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6537 ((offset_ & 0xf0) << 4) | (sign << 23));
6538 return;
6539 }
6540 // LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1
6541 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
6542 cond.IsNotNever() && ((rn.GetCode() & 0xf) != 0xf) &&
6543 (!rt.IsPC() || AllowUnpredictable())) {
6544 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6545 uint32_t offset_ = abs(offset);
6546 EmitA32(0x017000f0U | (cond.GetCondition() << 28) |
6547 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
6548 ((offset_ & 0xf0) << 4) | (sign << 23));
6549 return;
6550 }
6551 // LDRSH{<c>}{<q>} <Rt>, [PC, #<_plusminus_><imm_1>] ; A1
6552 if ((offset >= -255) && (offset <= 255) && rn.Is(pc) &&
6553 operand.IsOffset() && cond.IsNotNever() &&
6554 (!rt.IsPC() || AllowUnpredictable())) {
6555 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
6556 uint32_t offset_ = abs(offset);
6557 EmitA32(0x015f00f0U | (cond.GetCondition() << 28) |
6558 (rt.GetCode() << 12) | (offset_ & 0xf) |
6559 ((offset_ & 0xf0) << 4) | (sign << 23));
6560 return;
6561 }
6562 }
6563 }
6564 if (operand.IsPlainRegister()) {
6565 Register rn = operand.GetBaseRegister();
6566 Sign sign = operand.GetSign();
6567 Register rm = operand.GetOffsetRegister();
6568 if (IsUsingT32()) {
6569 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
6570 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
6571 sign.IsPlus() && operand.IsOffset()) {
6572 EmitT32_16(0x5e00 | rt.GetCode() | (rn.GetCode() << 3) |
6573 (rm.GetCode() << 6));
6574 AdvanceIT();
6575 return;
6576 }
6577 } else {
6578 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
6579 if (operand.IsOffset() && cond.IsNotNever() &&
6580 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6581 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6582 EmitA32(0x011000f0U | (cond.GetCondition() << 28) |
6583 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6584 (sign_ << 23));
6585 return;
6586 }
6587 // LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
6588 if (operand.IsPostIndex() && cond.IsNotNever() &&
6589 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6590 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6591 EmitA32(0x001000f0U | (cond.GetCondition() << 28) |
6592 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6593 (sign_ << 23));
6594 return;
6595 }
6596 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
6597 if (operand.IsPreIndex() && cond.IsNotNever() &&
6598 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6599 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
6600 EmitA32(0x013000f0U | (cond.GetCondition() << 28) |
6601 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
6602 (sign_ << 23));
6603 return;
6604 }
6605 }
6606 }
6607 if (operand.IsShiftedRegister()) {
6608 Register rn = operand.GetBaseRegister();
6609 Sign sign = operand.GetSign();
6610 Register rm = operand.GetOffsetRegister();
6611 Shift shift = operand.GetShift();
6612 uint32_t amount = operand.GetShiftAmount();
6613 if (IsUsingT32()) {
6614 // LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
6615 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
6616 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) && !rt.Is(pc) &&
6617 (!rm.IsPC() || AllowUnpredictable())) {
6618 EmitT32_32(0xf9300000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
6619 rm.GetCode() | (amount << 4));
6620 AdvanceIT();
6621 return;
6622 }
6623 }
6624 }
6625 Delegate(kLdrsh, &Assembler::ldrsh, cond, size, rt, operand);
6626 }
6627
ldrsh(Condition cond,Register rt,Location * location)6628 void Assembler::ldrsh(Condition cond, Register rt, Location* location) {
6629 VIXL_ASSERT(AllowAssembler());
6630 CheckIT(cond);
6631 Location::Offset offset =
6632 location->IsBound()
6633 ? location->GetLocation() -
6634 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
6635 : 0;
6636 if (IsUsingT32()) {
6637 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
6638 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
6639 !location->IsBound()) &&
6640 !rt.Is(pc)) {
6641 static class EmitOp : public Location::EmitOperator {
6642 public:
6643 EmitOp() : Location::EmitOperator(T32) {}
6644 virtual uint32_t Encode(uint32_t instr,
6645 Location::Offset program_counter,
6646 const Location* loc) const VIXL_OVERRIDE {
6647 program_counter += kT32PcDelta;
6648 Location::Offset off =
6649 loc->GetLocation() - AlignDown(program_counter, 4);
6650 VIXL_ASSERT((off >= -4095) && (off <= 4095));
6651 uint32_t U = (off >= 0);
6652 int32_t target = abs(off) | (U << 12);
6653 return instr | (target & 0xfff) | ((target & 0x1000) << 11);
6654 }
6655 } immop;
6656 EmitT32_32(Link(0xf93f0000U | (rt.GetCode() << 12),
6657 location,
6658 immop,
6659 &kT32FarDataInfo));
6660 AdvanceIT();
6661 return;
6662 }
6663 } else {
6664 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
6665 if (((location->IsBound() && (offset >= -255) && (offset <= 255)) ||
6666 !location->IsBound()) &&
6667 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
6668 static class EmitOp : public Location::EmitOperator {
6669 public:
6670 EmitOp() : Location::EmitOperator(A32) {}
6671 virtual uint32_t Encode(uint32_t instr,
6672 Location::Offset program_counter,
6673 const Location* loc) const VIXL_OVERRIDE {
6674 program_counter += kA32PcDelta;
6675 Location::Offset off =
6676 loc->GetLocation() - AlignDown(program_counter, 4);
6677 VIXL_ASSERT((off >= -255) && (off <= 255));
6678 uint32_t U = (off >= 0);
6679 int32_t target = abs(off) | (U << 8);
6680 return instr | (target & 0xf) | ((target & 0xf0) << 4) |
6681 ((target & 0x100) << 15);
6682 }
6683 } immop;
6684 EmitA32(
6685 Link(0x015f00f0U | (cond.GetCondition() << 28) | (rt.GetCode() << 12),
6686 location,
6687 immop,
6688 &kA32VeryNearDataInfo));
6689 return;
6690 }
6691 }
6692 Delegate(kLdrsh, &Assembler::ldrsh, cond, rt, location);
6693 }
6694
ldrsh_info(Condition cond,Register rt,Location * location,const struct ReferenceInfo ** info)6695 bool Assembler::ldrsh_info(Condition cond,
6696 Register rt,
6697 Location* location,
6698 const struct ReferenceInfo** info) {
6699 VIXL_ASSERT(!location->IsBound());
6700 USE(location);
6701 if (IsUsingT32()) {
6702 // LDRSH{<c>}{<q>} <Rt>, <label> ; T1
6703 if (!rt.Is(pc)) {
6704 *info = &kT32FarDataInfo;
6705 return true;
6706 }
6707 } else {
6708 // LDRSH{<c>}{<q>} <Rt>, <label> ; A1
6709 if (cond.IsNotNever()) {
6710 *info = &kA32VeryNearDataInfo;
6711 return true;
6712 }
6713 }
6714 return false;
6715 }
6716
lsl(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6717 void Assembler::lsl(Condition cond,
6718 EncodingSize size,
6719 Register rd,
6720 Register rm,
6721 const Operand& operand) {
6722 VIXL_ASSERT(AllowAssembler());
6723 CheckIT(cond);
6724 if (operand.IsImmediate()) {
6725 uint32_t imm = operand.GetImmediate();
6726 if (IsUsingT32()) {
6727 // LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6728 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6729 (imm >= 1) && (imm <= 31)) {
6730 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6731 AdvanceIT();
6732 return;
6733 }
6734 // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6735 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
6736 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6737 EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6738 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6739 AdvanceIT();
6740 return;
6741 }
6742 } else {
6743 // LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6744 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6745 EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
6746 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6747 return;
6748 }
6749 }
6750 }
6751 if (operand.IsPlainRegister()) {
6752 Register rs = operand.GetBaseRegister();
6753 if (IsUsingT32()) {
6754 // LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6755 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6756 rs.IsLow()) {
6757 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6758 AdvanceIT();
6759 return;
6760 }
6761 // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6762 if (!size.IsNarrow() &&
6763 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6764 EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6765 rs.GetCode());
6766 AdvanceIT();
6767 return;
6768 }
6769 } else {
6770 // LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6771 if (cond.IsNotNever() &&
6772 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6773 EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
6774 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6775 return;
6776 }
6777 }
6778 }
6779 Delegate(kLsl, &Assembler::lsl, cond, size, rd, rm, operand);
6780 }
6781
lsls(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6782 void Assembler::lsls(Condition cond,
6783 EncodingSize size,
6784 Register rd,
6785 Register rm,
6786 const Operand& operand) {
6787 VIXL_ASSERT(AllowAssembler());
6788 CheckIT(cond);
6789 if (operand.IsImmediate()) {
6790 uint32_t imm = operand.GetImmediate();
6791 if (IsUsingT32()) {
6792 // LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6793 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6794 (imm >= 1) && (imm <= 31)) {
6795 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) | (imm << 6));
6796 AdvanceIT();
6797 return;
6798 }
6799 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6800 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
6801 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6802 EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
6803 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
6804 AdvanceIT();
6805 return;
6806 }
6807 } else {
6808 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6809 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
6810 EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
6811 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
6812 return;
6813 }
6814 }
6815 }
6816 if (operand.IsPlainRegister()) {
6817 Register rs = operand.GetBaseRegister();
6818 if (IsUsingT32()) {
6819 // LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6820 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6821 rs.IsLow()) {
6822 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
6823 AdvanceIT();
6824 return;
6825 }
6826 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6827 if (!size.IsNarrow() &&
6828 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6829 EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6830 rs.GetCode());
6831 AdvanceIT();
6832 return;
6833 }
6834 } else {
6835 // LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6836 if (cond.IsNotNever() &&
6837 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6838 EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
6839 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6840 return;
6841 }
6842 }
6843 }
6844 Delegate(kLsls, &Assembler::lsls, cond, size, rd, rm, operand);
6845 }
6846
lsr(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6847 void Assembler::lsr(Condition cond,
6848 EncodingSize size,
6849 Register rd,
6850 Register rm,
6851 const Operand& operand) {
6852 VIXL_ASSERT(AllowAssembler());
6853 CheckIT(cond);
6854 if (operand.IsImmediate()) {
6855 uint32_t imm = operand.GetImmediate();
6856 if (IsUsingT32()) {
6857 // LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6858 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6859 (imm >= 1) && (imm <= 32)) {
6860 uint32_t amount_ = imm % 32;
6861 EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6862 (amount_ << 6));
6863 AdvanceIT();
6864 return;
6865 }
6866 // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6867 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
6868 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6869 uint32_t amount_ = imm % 32;
6870 EmitT32_32(0xea4f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6871 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6872 AdvanceIT();
6873 return;
6874 }
6875 } else {
6876 // LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6877 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6878 uint32_t amount_ = imm % 32;
6879 EmitA32(0x01a00020U | (cond.GetCondition() << 28) |
6880 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6881 return;
6882 }
6883 }
6884 }
6885 if (operand.IsPlainRegister()) {
6886 Register rs = operand.GetBaseRegister();
6887 if (IsUsingT32()) {
6888 // LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6889 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6890 rs.IsLow()) {
6891 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6892 AdvanceIT();
6893 return;
6894 }
6895 // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6896 if (!size.IsNarrow() &&
6897 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6898 EmitT32_32(0xfa20f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6899 rs.GetCode());
6900 AdvanceIT();
6901 return;
6902 }
6903 } else {
6904 // LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6905 if (cond.IsNotNever() &&
6906 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6907 EmitA32(0x01a00030U | (cond.GetCondition() << 28) |
6908 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6909 return;
6910 }
6911 }
6912 }
6913 Delegate(kLsr, &Assembler::lsr, cond, size, rd, rm, operand);
6914 }
6915
lsrs(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)6916 void Assembler::lsrs(Condition cond,
6917 EncodingSize size,
6918 Register rd,
6919 Register rm,
6920 const Operand& operand) {
6921 VIXL_ASSERT(AllowAssembler());
6922 CheckIT(cond);
6923 if (operand.IsImmediate()) {
6924 uint32_t imm = operand.GetImmediate();
6925 if (IsUsingT32()) {
6926 // LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
6927 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow() &&
6928 (imm >= 1) && (imm <= 32)) {
6929 uint32_t amount_ = imm % 32;
6930 EmitT32_16(0x0800 | rd.GetCode() | (rm.GetCode() << 3) |
6931 (amount_ << 6));
6932 AdvanceIT();
6933 return;
6934 }
6935 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
6936 if (!size.IsNarrow() && (imm >= 1) && (imm <= 32) &&
6937 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6938 uint32_t amount_ = imm % 32;
6939 EmitT32_32(0xea5f0010U | (rd.GetCode() << 8) | rm.GetCode() |
6940 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
6941 AdvanceIT();
6942 return;
6943 }
6944 } else {
6945 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
6946 if ((imm >= 1) && (imm <= 32) && cond.IsNotNever()) {
6947 uint32_t amount_ = imm % 32;
6948 EmitA32(0x01b00020U | (cond.GetCondition() << 28) |
6949 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 7));
6950 return;
6951 }
6952 }
6953 }
6954 if (operand.IsPlainRegister()) {
6955 Register rs = operand.GetBaseRegister();
6956 if (IsUsingT32()) {
6957 // LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
6958 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
6959 rs.IsLow()) {
6960 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
6961 AdvanceIT();
6962 return;
6963 }
6964 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
6965 if (!size.IsNarrow() &&
6966 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6967 EmitT32_32(0xfa30f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
6968 rs.GetCode());
6969 AdvanceIT();
6970 return;
6971 }
6972 } else {
6973 // LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
6974 if (cond.IsNotNever() &&
6975 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
6976 EmitA32(0x01b00030U | (cond.GetCondition() << 28) |
6977 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
6978 return;
6979 }
6980 }
6981 }
6982 Delegate(kLsrs, &Assembler::lsrs, cond, size, rd, rm, operand);
6983 }
6984
mla(Condition cond,Register rd,Register rn,Register rm,Register ra)6985 void Assembler::mla(
6986 Condition cond, Register rd, Register rn, Register rm, Register ra) {
6987 VIXL_ASSERT(AllowAssembler());
6988 CheckIT(cond);
6989 if (IsUsingT32()) {
6990 // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
6991 if (!ra.Is(pc) &&
6992 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
6993 EmitT32_32(0xfb000000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
6994 rm.GetCode() | (ra.GetCode() << 12));
6995 AdvanceIT();
6996 return;
6997 }
6998 } else {
6999 // MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
7000 if (cond.IsNotNever() &&
7001 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
7002 AllowUnpredictable())) {
7003 EmitA32(0x00200090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
7004 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
7005 return;
7006 }
7007 }
7008 Delegate(kMla, &Assembler::mla, cond, rd, rn, rm, ra);
7009 }
7010
mlas(Condition cond,Register rd,Register rn,Register rm,Register ra)7011 void Assembler::mlas(
7012 Condition cond, Register rd, Register rn, Register rm, Register ra) {
7013 VIXL_ASSERT(AllowAssembler());
7014 CheckIT(cond);
7015 if (IsUsingA32()) {
7016 // MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
7017 if (cond.IsNotNever() &&
7018 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
7019 AllowUnpredictable())) {
7020 EmitA32(0x00300090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
7021 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
7022 return;
7023 }
7024 }
7025 Delegate(kMlas, &Assembler::mlas, cond, rd, rn, rm, ra);
7026 }
7027
mls(Condition cond,Register rd,Register rn,Register rm,Register ra)7028 void Assembler::mls(
7029 Condition cond, Register rd, Register rn, Register rm, Register ra) {
7030 VIXL_ASSERT(AllowAssembler());
7031 CheckIT(cond);
7032 if (IsUsingT32()) {
7033 // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
7034 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
7035 AllowUnpredictable())) {
7036 EmitT32_32(0xfb000010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7037 rm.GetCode() | (ra.GetCode() << 12));
7038 AdvanceIT();
7039 return;
7040 }
7041 } else {
7042 // MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
7043 if (cond.IsNotNever() &&
7044 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
7045 AllowUnpredictable())) {
7046 EmitA32(0x00600090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
7047 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
7048 return;
7049 }
7050 }
7051 Delegate(kMls, &Assembler::mls, cond, rd, rn, rm, ra);
7052 }
7053
mov(Condition cond,EncodingSize size,Register rd,const Operand & operand)7054 void Assembler::mov(Condition cond,
7055 EncodingSize size,
7056 Register rd,
7057 const Operand& operand) {
7058 VIXL_ASSERT(AllowAssembler());
7059 CheckIT(cond);
7060 if (operand.IsImmediateShiftedRegister()) {
7061 Register rm = operand.GetBaseRegister();
7062 if (operand.IsPlainRegister()) {
7063 if (IsUsingT32()) {
7064 // MOV{<c>}{<q>} <Rd>, <Rm> ; T1
7065 if (!size.IsWide() &&
7066 ((!rd.IsPC() || OutsideITBlockAndAlOrLast(cond)) ||
7067 AllowUnpredictable())) {
7068 EmitT32_16(0x4600 | (rd.GetCode() & 0x7) |
7069 ((rd.GetCode() & 0x8) << 4) | (rm.GetCode() << 3));
7070 AdvanceIT();
7071 return;
7072 }
7073 }
7074 }
7075 Shift shift = operand.GetShift();
7076 uint32_t amount = operand.GetShiftAmount();
7077 if (IsUsingT32()) {
7078 // MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
7079 if (InITBlock() && !size.IsWide() && rd.IsLow() &&
7080 shift.IsValidAmount(amount) && rm.IsLow() &&
7081 (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR)) &&
7082 ((!shift.Is(LSL) || (amount != 0)) || AllowUnpredictable())) {
7083 uint32_t amount_ = amount % 32;
7084 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
7085 (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
7086 AdvanceIT();
7087 return;
7088 }
7089 // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
7090 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
7091 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7092 uint32_t amount_ = amount % 32;
7093 EmitT32_32(0xea4f0000U | (rd.GetCode() << 8) | rm.GetCode() |
7094 (operand.GetTypeEncodingValue() << 4) |
7095 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7096 AdvanceIT();
7097 return;
7098 }
7099 } else {
7100 // MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
7101 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7102 uint32_t amount_ = amount % 32;
7103 EmitA32(0x01a00000U | (cond.GetCondition() << 28) |
7104 (rd.GetCode() << 12) | rm.GetCode() |
7105 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7106 return;
7107 }
7108 }
7109 }
7110 if (operand.IsRegisterShiftedRegister()) {
7111 Register rm = operand.GetBaseRegister();
7112 Shift shift = operand.GetShift();
7113 Register rs = operand.GetShiftRegister();
7114 if (IsUsingT32()) {
7115 // MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
7116 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7117 shift.IsASR() && rs.IsLow()) {
7118 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
7119 AdvanceIT();
7120 return;
7121 }
7122 // MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
7123 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7124 shift.IsLSL() && rs.IsLow()) {
7125 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
7126 AdvanceIT();
7127 return;
7128 }
7129 // MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
7130 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7131 shift.IsLSR() && rs.IsLow()) {
7132 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
7133 AdvanceIT();
7134 return;
7135 }
7136 // MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
7137 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7138 shift.IsROR() && rs.IsLow()) {
7139 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
7140 AdvanceIT();
7141 return;
7142 }
7143 // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
7144 if (!size.IsNarrow() &&
7145 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7146 EmitT32_32(0xfa00f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
7147 (shift.GetType() << 21) | rs.GetCode());
7148 AdvanceIT();
7149 return;
7150 }
7151 } else {
7152 // MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
7153 if (cond.IsNotNever() &&
7154 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7155 EmitA32(0x01a00010U | (cond.GetCondition() << 28) |
7156 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
7157 (rs.GetCode() << 8));
7158 return;
7159 }
7160 }
7161 }
7162 if (operand.IsImmediate()) {
7163 uint32_t imm = operand.GetImmediate();
7164 if (IsUsingT32()) {
7165 ImmediateT32 immediate_t32(imm);
7166 // MOV<c>{<q>} <Rd>, #<imm8> ; T1
7167 if (InITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
7168 EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
7169 AdvanceIT();
7170 return;
7171 }
7172 // MOV{<c>}{<q>} <Rd>, #<const> ; T2
7173 if (!size.IsNarrow() && immediate_t32.IsValid() &&
7174 (!rd.IsPC() || AllowUnpredictable())) {
7175 EmitT32_32(0xf04f0000U | (rd.GetCode() << 8) |
7176 (immediate_t32.GetEncodingValue() & 0xff) |
7177 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7178 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7179 AdvanceIT();
7180 return;
7181 }
7182 // MOV{<c>}{<q>} <Rd>, #<imm16> ; T3
7183 if (!size.IsNarrow() && (imm <= 65535) &&
7184 (!rd.IsPC() || AllowUnpredictable())) {
7185 EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
7186 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
7187 ((imm & 0xf000) << 4));
7188 AdvanceIT();
7189 return;
7190 }
7191 } else {
7192 ImmediateA32 immediate_a32(imm);
7193 // MOV{<c>}{<q>} <Rd>, #<const> ; A1
7194 if (immediate_a32.IsValid() && cond.IsNotNever()) {
7195 EmitA32(0x03a00000U | (cond.GetCondition() << 28) |
7196 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
7197 return;
7198 }
7199 // MOV{<c>}{<q>} <Rd>, #<imm16> ; A2
7200 if ((imm <= 65535) && cond.IsNotNever() &&
7201 (!rd.IsPC() || AllowUnpredictable())) {
7202 EmitA32(0x03000000U | (cond.GetCondition() << 28) |
7203 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
7204 return;
7205 }
7206 }
7207 }
7208 Delegate(kMov, &Assembler::mov, cond, size, rd, operand);
7209 }
7210
movs(Condition cond,EncodingSize size,Register rd,const Operand & operand)7211 void Assembler::movs(Condition cond,
7212 EncodingSize size,
7213 Register rd,
7214 const Operand& operand) {
7215 VIXL_ASSERT(AllowAssembler());
7216 CheckIT(cond);
7217 if (operand.IsImmediateShiftedRegister()) {
7218 Register rm = operand.GetBaseRegister();
7219 Shift shift = operand.GetShift();
7220 uint32_t amount = operand.GetShiftAmount();
7221 if (IsUsingT32()) {
7222 // MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
7223 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() &&
7224 shift.IsValidAmount(amount) && rm.IsLow() &&
7225 (shift.Is(LSL) || shift.Is(LSR) || shift.Is(ASR))) {
7226 uint32_t amount_ = amount % 32;
7227 EmitT32_16(0x0000 | rd.GetCode() | (rm.GetCode() << 3) |
7228 (operand.GetTypeEncodingValue() << 11) | (amount_ << 6));
7229 AdvanceIT();
7230 return;
7231 }
7232 // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3
7233 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
7234 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7235 uint32_t amount_ = amount % 32;
7236 EmitT32_32(0xea5f0000U | (rd.GetCode() << 8) | rm.GetCode() |
7237 (operand.GetTypeEncodingValue() << 4) |
7238 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7239 AdvanceIT();
7240 return;
7241 }
7242 } else {
7243 // MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
7244 if (shift.IsValidAmount(amount) && cond.IsNotNever() &&
7245 (!rd.IsPC() || AllowUnpredictable())) {
7246 uint32_t amount_ = amount % 32;
7247 EmitA32(0x01b00000U | (cond.GetCondition() << 28) |
7248 (rd.GetCode() << 12) | rm.GetCode() |
7249 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7250 return;
7251 }
7252 }
7253 }
7254 if (operand.IsRegisterShiftedRegister()) {
7255 Register rm = operand.GetBaseRegister();
7256 Shift shift = operand.GetShift();
7257 Register rs = operand.GetShiftRegister();
7258 if (IsUsingT32()) {
7259 // MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
7260 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7261 shift.IsASR() && rs.IsLow()) {
7262 EmitT32_16(0x4100 | rd.GetCode() | (rs.GetCode() << 3));
7263 AdvanceIT();
7264 return;
7265 }
7266 // MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
7267 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7268 shift.IsLSL() && rs.IsLow()) {
7269 EmitT32_16(0x4080 | rd.GetCode() | (rs.GetCode() << 3));
7270 AdvanceIT();
7271 return;
7272 }
7273 // MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
7274 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7275 shift.IsLSR() && rs.IsLow()) {
7276 EmitT32_16(0x40c0 | rd.GetCode() | (rs.GetCode() << 3));
7277 AdvanceIT();
7278 return;
7279 }
7280 // MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
7281 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
7282 shift.IsROR() && rs.IsLow()) {
7283 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
7284 AdvanceIT();
7285 return;
7286 }
7287 // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
7288 if (!size.IsNarrow() &&
7289 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7290 EmitT32_32(0xfa10f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
7291 (shift.GetType() << 21) | rs.GetCode());
7292 AdvanceIT();
7293 return;
7294 }
7295 } else {
7296 // MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
7297 if (cond.IsNotNever() &&
7298 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7299 EmitA32(0x01b00010U | (cond.GetCondition() << 28) |
7300 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
7301 (rs.GetCode() << 8));
7302 return;
7303 }
7304 }
7305 }
7306 if (operand.IsImmediate()) {
7307 uint32_t imm = operand.GetImmediate();
7308 if (IsUsingT32()) {
7309 ImmediateT32 immediate_t32(imm);
7310 // MOVS{<q>} <Rd>, #<imm8> ; T1
7311 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && (imm <= 255)) {
7312 EmitT32_16(0x2000 | (rd.GetCode() << 8) | imm);
7313 AdvanceIT();
7314 return;
7315 }
7316 // MOVS{<c>}{<q>} <Rd>, #<const> ; T2
7317 if (!size.IsNarrow() && immediate_t32.IsValid() &&
7318 (!rd.IsPC() || AllowUnpredictable())) {
7319 EmitT32_32(0xf05f0000U | (rd.GetCode() << 8) |
7320 (immediate_t32.GetEncodingValue() & 0xff) |
7321 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7322 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7323 AdvanceIT();
7324 return;
7325 }
7326 } else {
7327 ImmediateA32 immediate_a32(imm);
7328 // MOVS{<c>}{<q>} <Rd>, #<const> ; A1
7329 if (immediate_a32.IsValid() && cond.IsNotNever()) {
7330 EmitA32(0x03b00000U | (cond.GetCondition() << 28) |
7331 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
7332 return;
7333 }
7334 }
7335 }
7336 Delegate(kMovs, &Assembler::movs, cond, size, rd, operand);
7337 }
7338
movt(Condition cond,Register rd,const Operand & operand)7339 void Assembler::movt(Condition cond, Register rd, const Operand& operand) {
7340 VIXL_ASSERT(AllowAssembler());
7341 CheckIT(cond);
7342 if (operand.IsImmediate()) {
7343 uint32_t imm = operand.GetImmediate();
7344 if (IsUsingT32()) {
7345 // MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1
7346 if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
7347 EmitT32_32(0xf2c00000U | (rd.GetCode() << 8) | (imm & 0xff) |
7348 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
7349 ((imm & 0xf000) << 4));
7350 AdvanceIT();
7351 return;
7352 }
7353 } else {
7354 // MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1
7355 if ((imm <= 65535) && cond.IsNotNever() &&
7356 (!rd.IsPC() || AllowUnpredictable())) {
7357 EmitA32(0x03400000U | (cond.GetCondition() << 28) |
7358 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
7359 return;
7360 }
7361 }
7362 }
7363 Delegate(kMovt, &Assembler::movt, cond, rd, operand);
7364 }
7365
movw(Condition cond,Register rd,const Operand & operand)7366 void Assembler::movw(Condition cond, Register rd, const Operand& operand) {
7367 VIXL_ASSERT(AllowAssembler());
7368 CheckIT(cond);
7369 if (operand.IsImmediate()) {
7370 uint32_t imm = operand.GetImmediate();
7371 if (IsUsingT32()) {
7372 // MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3
7373 if ((imm <= 65535) && (!rd.IsPC() || AllowUnpredictable())) {
7374 EmitT32_32(0xf2400000U | (rd.GetCode() << 8) | (imm & 0xff) |
7375 ((imm & 0x700) << 4) | ((imm & 0x800) << 15) |
7376 ((imm & 0xf000) << 4));
7377 AdvanceIT();
7378 return;
7379 }
7380 } else {
7381 // MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2
7382 if ((imm <= 65535) && cond.IsNotNever() &&
7383 (!rd.IsPC() || AllowUnpredictable())) {
7384 EmitA32(0x03000000U | (cond.GetCondition() << 28) |
7385 (rd.GetCode() << 12) | (imm & 0xfff) | ((imm & 0xf000) << 4));
7386 return;
7387 }
7388 }
7389 }
7390 Delegate(kMovw, &Assembler::movw, cond, rd, operand);
7391 }
7392
mrs(Condition cond,Register rd,SpecialRegister spec_reg)7393 void Assembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) {
7394 VIXL_ASSERT(AllowAssembler());
7395 CheckIT(cond);
7396 if (IsUsingT32()) {
7397 // MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1
7398 if ((!rd.IsPC() || AllowUnpredictable())) {
7399 EmitT32_32(0xf3ef8000U | (rd.GetCode() << 8) | (spec_reg.GetReg() << 20));
7400 AdvanceIT();
7401 return;
7402 }
7403 } else {
7404 // MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1
7405 if (cond.IsNotNever() && (!rd.IsPC() || AllowUnpredictable())) {
7406 EmitA32(0x010f0000U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
7407 (spec_reg.GetReg() << 22));
7408 return;
7409 }
7410 }
7411 Delegate(kMrs, &Assembler::mrs, cond, rd, spec_reg);
7412 }
7413
msr(Condition cond,MaskedSpecialRegister spec_reg,const Operand & operand)7414 void Assembler::msr(Condition cond,
7415 MaskedSpecialRegister spec_reg,
7416 const Operand& operand) {
7417 VIXL_ASSERT(AllowAssembler());
7418 CheckIT(cond);
7419 if (operand.IsImmediate()) {
7420 uint32_t imm = operand.GetImmediate();
7421 if (IsUsingA32()) {
7422 ImmediateA32 immediate_a32(imm);
7423 // MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1
7424 if (immediate_a32.IsValid() && cond.IsNotNever()) {
7425 EmitA32(0x0320f000U | (cond.GetCondition() << 28) |
7426 ((spec_reg.GetReg() & 0xf) << 16) |
7427 ((spec_reg.GetReg() & 0x10) << 18) |
7428 immediate_a32.GetEncodingValue());
7429 return;
7430 }
7431 }
7432 }
7433 if (operand.IsPlainRegister()) {
7434 Register rn = operand.GetBaseRegister();
7435 if (IsUsingT32()) {
7436 // MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1
7437 if ((!rn.IsPC() || AllowUnpredictable())) {
7438 EmitT32_32(0xf3808000U | ((spec_reg.GetReg() & 0xf) << 8) |
7439 ((spec_reg.GetReg() & 0x10) << 16) | (rn.GetCode() << 16));
7440 AdvanceIT();
7441 return;
7442 }
7443 } else {
7444 // MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1
7445 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
7446 EmitA32(0x0120f000U | (cond.GetCondition() << 28) |
7447 ((spec_reg.GetReg() & 0xf) << 16) |
7448 ((spec_reg.GetReg() & 0x10) << 18) | rn.GetCode());
7449 return;
7450 }
7451 }
7452 }
7453 Delegate(kMsr, &Assembler::msr, cond, spec_reg, operand);
7454 }
7455
mul(Condition cond,EncodingSize size,Register rd,Register rn,Register rm)7456 void Assembler::mul(
7457 Condition cond, EncodingSize size, Register rd, Register rn, Register rm) {
7458 VIXL_ASSERT(AllowAssembler());
7459 CheckIT(cond);
7460 if (IsUsingT32()) {
7461 // MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
7462 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rn.IsLow() &&
7463 rm.IsLow()) {
7464 EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
7465 AdvanceIT();
7466 return;
7467 }
7468 // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2
7469 if (!size.IsNarrow() &&
7470 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7471 EmitT32_32(0xfb00f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7472 rm.GetCode());
7473 AdvanceIT();
7474 return;
7475 }
7476 } else {
7477 // MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
7478 if (cond.IsNotNever() &&
7479 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7480 EmitA32(0x00000090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
7481 rn.GetCode() | (rm.GetCode() << 8));
7482 return;
7483 }
7484 }
7485 Delegate(kMul, &Assembler::mul, cond, size, rd, rn, rm);
7486 }
7487
muls(Condition cond,Register rd,Register rn,Register rm)7488 void Assembler::muls(Condition cond, Register rd, Register rn, Register rm) {
7489 VIXL_ASSERT(AllowAssembler());
7490 CheckIT(cond);
7491 if (IsUsingT32()) {
7492 // MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
7493 if (OutsideITBlock() && rd.Is(rm) && rn.IsLow() && rm.IsLow()) {
7494 EmitT32_16(0x4340 | rd.GetCode() | (rn.GetCode() << 3));
7495 AdvanceIT();
7496 return;
7497 }
7498 } else {
7499 // MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
7500 if (cond.IsNotNever() &&
7501 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7502 EmitA32(0x00100090U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
7503 rn.GetCode() | (rm.GetCode() << 8));
7504 return;
7505 }
7506 }
7507 Delegate(kMuls, &Assembler::muls, cond, rd, rn, rm);
7508 }
7509
mvn(Condition cond,EncodingSize size,Register rd,const Operand & operand)7510 void Assembler::mvn(Condition cond,
7511 EncodingSize size,
7512 Register rd,
7513 const Operand& operand) {
7514 VIXL_ASSERT(AllowAssembler());
7515 CheckIT(cond);
7516 if (operand.IsImmediate()) {
7517 uint32_t imm = operand.GetImmediate();
7518 if (IsUsingT32()) {
7519 ImmediateT32 immediate_t32(imm);
7520 // MVN{<c>}{<q>} <Rd>, #<const> ; T1
7521 if (!size.IsNarrow() && immediate_t32.IsValid() &&
7522 (!rd.IsPC() || AllowUnpredictable())) {
7523 EmitT32_32(0xf06f0000U | (rd.GetCode() << 8) |
7524 (immediate_t32.GetEncodingValue() & 0xff) |
7525 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7526 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7527 AdvanceIT();
7528 return;
7529 }
7530 } else {
7531 ImmediateA32 immediate_a32(imm);
7532 // MVN{<c>}{<q>} <Rd>, #<const> ; A1
7533 if (immediate_a32.IsValid() && cond.IsNotNever()) {
7534 EmitA32(0x03e00000U | (cond.GetCondition() << 28) |
7535 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
7536 return;
7537 }
7538 }
7539 }
7540 if (operand.IsImmediateShiftedRegister()) {
7541 Register rm = operand.GetBaseRegister();
7542 if (operand.IsPlainRegister()) {
7543 if (IsUsingT32()) {
7544 // MVN<c>{<q>} <Rd>, <Rm> ; T1
7545 if (InITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
7546 EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
7547 AdvanceIT();
7548 return;
7549 }
7550 }
7551 }
7552 Shift shift = operand.GetShift();
7553 uint32_t amount = operand.GetShiftAmount();
7554 if (IsUsingT32()) {
7555 // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
7556 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
7557 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7558 uint32_t amount_ = amount % 32;
7559 EmitT32_32(0xea6f0000U | (rd.GetCode() << 8) | rm.GetCode() |
7560 (operand.GetTypeEncodingValue() << 4) |
7561 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7562 AdvanceIT();
7563 return;
7564 }
7565 } else {
7566 // MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
7567 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7568 uint32_t amount_ = amount % 32;
7569 EmitA32(0x01e00000U | (cond.GetCondition() << 28) |
7570 (rd.GetCode() << 12) | rm.GetCode() |
7571 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7572 return;
7573 }
7574 }
7575 }
7576 if (operand.IsRegisterShiftedRegister()) {
7577 Register rm = operand.GetBaseRegister();
7578 Shift shift = operand.GetShift();
7579 Register rs = operand.GetShiftRegister();
7580 if (IsUsingA32()) {
7581 // MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
7582 if (cond.IsNotNever() &&
7583 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7584 EmitA32(0x01e00010U | (cond.GetCondition() << 28) |
7585 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
7586 (rs.GetCode() << 8));
7587 return;
7588 }
7589 }
7590 }
7591 Delegate(kMvn, &Assembler::mvn, cond, size, rd, operand);
7592 }
7593
mvns(Condition cond,EncodingSize size,Register rd,const Operand & operand)7594 void Assembler::mvns(Condition cond,
7595 EncodingSize size,
7596 Register rd,
7597 const Operand& operand) {
7598 VIXL_ASSERT(AllowAssembler());
7599 CheckIT(cond);
7600 if (operand.IsImmediate()) {
7601 uint32_t imm = operand.GetImmediate();
7602 if (IsUsingT32()) {
7603 ImmediateT32 immediate_t32(imm);
7604 // MVNS{<c>}{<q>} <Rd>, #<const> ; T1
7605 if (!size.IsNarrow() && immediate_t32.IsValid() &&
7606 (!rd.IsPC() || AllowUnpredictable())) {
7607 EmitT32_32(0xf07f0000U | (rd.GetCode() << 8) |
7608 (immediate_t32.GetEncodingValue() & 0xff) |
7609 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7610 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7611 AdvanceIT();
7612 return;
7613 }
7614 } else {
7615 ImmediateA32 immediate_a32(imm);
7616 // MVNS{<c>}{<q>} <Rd>, #<const> ; A1
7617 if (immediate_a32.IsValid() && cond.IsNotNever()) {
7618 EmitA32(0x03f00000U | (cond.GetCondition() << 28) |
7619 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
7620 return;
7621 }
7622 }
7623 }
7624 if (operand.IsImmediateShiftedRegister()) {
7625 Register rm = operand.GetBaseRegister();
7626 if (operand.IsPlainRegister()) {
7627 if (IsUsingT32()) {
7628 // MVNS{<q>} <Rd>, <Rm> ; T1
7629 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rm.IsLow()) {
7630 EmitT32_16(0x43c0 | rd.GetCode() | (rm.GetCode() << 3));
7631 AdvanceIT();
7632 return;
7633 }
7634 }
7635 }
7636 Shift shift = operand.GetShift();
7637 uint32_t amount = operand.GetShiftAmount();
7638 if (IsUsingT32()) {
7639 // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
7640 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
7641 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7642 uint32_t amount_ = amount % 32;
7643 EmitT32_32(0xea7f0000U | (rd.GetCode() << 8) | rm.GetCode() |
7644 (operand.GetTypeEncodingValue() << 4) |
7645 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7646 AdvanceIT();
7647 return;
7648 }
7649 } else {
7650 // MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
7651 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7652 uint32_t amount_ = amount % 32;
7653 EmitA32(0x01f00000U | (cond.GetCondition() << 28) |
7654 (rd.GetCode() << 12) | rm.GetCode() |
7655 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7656 return;
7657 }
7658 }
7659 }
7660 if (operand.IsRegisterShiftedRegister()) {
7661 Register rm = operand.GetBaseRegister();
7662 Shift shift = operand.GetShift();
7663 Register rs = operand.GetShiftRegister();
7664 if (IsUsingA32()) {
7665 // MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
7666 if (cond.IsNotNever() &&
7667 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
7668 EmitA32(0x01f00010U | (cond.GetCondition() << 28) |
7669 (rd.GetCode() << 12) | rm.GetCode() | (shift.GetType() << 5) |
7670 (rs.GetCode() << 8));
7671 return;
7672 }
7673 }
7674 }
7675 Delegate(kMvns, &Assembler::mvns, cond, size, rd, operand);
7676 }
7677
nop(Condition cond,EncodingSize size)7678 void Assembler::nop(Condition cond, EncodingSize size) {
7679 VIXL_ASSERT(AllowAssembler());
7680 CheckIT(cond);
7681 if (IsUsingT32()) {
7682 // NOP{<c>}{<q>} ; T1
7683 if (!size.IsWide()) {
7684 EmitT32_16(0xbf00);
7685 AdvanceIT();
7686 return;
7687 }
7688 // NOP{<c>}.W ; T2
7689 if (!size.IsNarrow()) {
7690 EmitT32_32(0xf3af8000U);
7691 AdvanceIT();
7692 return;
7693 }
7694 } else {
7695 // NOP{<c>}{<q>} ; A1
7696 if (cond.IsNotNever()) {
7697 EmitA32(0x0320f000U | (cond.GetCondition() << 28));
7698 return;
7699 }
7700 }
7701 Delegate(kNop, &Assembler::nop, cond, size);
7702 }
7703
orn(Condition cond,Register rd,Register rn,const Operand & operand)7704 void Assembler::orn(Condition cond,
7705 Register rd,
7706 Register rn,
7707 const Operand& operand) {
7708 VIXL_ASSERT(AllowAssembler());
7709 CheckIT(cond);
7710 if (operand.IsImmediate()) {
7711 uint32_t imm = operand.GetImmediate();
7712 if (IsUsingT32()) {
7713 ImmediateT32 immediate_t32(imm);
7714 // ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7715 if (immediate_t32.IsValid() && !rn.Is(pc) &&
7716 (!rd.IsPC() || AllowUnpredictable())) {
7717 EmitT32_32(0xf0600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7718 (immediate_t32.GetEncodingValue() & 0xff) |
7719 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7720 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7721 AdvanceIT();
7722 return;
7723 }
7724 }
7725 }
7726 if (operand.IsImmediateShiftedRegister()) {
7727 Register rm = operand.GetBaseRegister();
7728 Shift shift = operand.GetShift();
7729 uint32_t amount = operand.GetShiftAmount();
7730 if (IsUsingT32()) {
7731 // ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
7732 if (shift.IsValidAmount(amount) && !rn.Is(pc) &&
7733 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7734 uint32_t amount_ = amount % 32;
7735 EmitT32_32(0xea600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7736 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7737 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7738 AdvanceIT();
7739 return;
7740 }
7741 }
7742 }
7743 Delegate(kOrn, &Assembler::orn, cond, rd, rn, operand);
7744 }
7745
orns(Condition cond,Register rd,Register rn,const Operand & operand)7746 void Assembler::orns(Condition cond,
7747 Register rd,
7748 Register rn,
7749 const Operand& operand) {
7750 VIXL_ASSERT(AllowAssembler());
7751 CheckIT(cond);
7752 if (operand.IsImmediate()) {
7753 uint32_t imm = operand.GetImmediate();
7754 if (IsUsingT32()) {
7755 ImmediateT32 immediate_t32(imm);
7756 // ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7757 if (immediate_t32.IsValid() && !rn.Is(pc) &&
7758 (!rd.IsPC() || AllowUnpredictable())) {
7759 EmitT32_32(0xf0700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7760 (immediate_t32.GetEncodingValue() & 0xff) |
7761 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7762 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7763 AdvanceIT();
7764 return;
7765 }
7766 }
7767 }
7768 if (operand.IsImmediateShiftedRegister()) {
7769 Register rm = operand.GetBaseRegister();
7770 Shift shift = operand.GetShift();
7771 uint32_t amount = operand.GetShiftAmount();
7772 if (IsUsingT32()) {
7773 // ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
7774 if (shift.IsValidAmount(amount) && !rn.Is(pc) &&
7775 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7776 uint32_t amount_ = amount % 32;
7777 EmitT32_32(0xea700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7778 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7779 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7780 AdvanceIT();
7781 return;
7782 }
7783 }
7784 }
7785 Delegate(kOrns, &Assembler::orns, cond, rd, rn, operand);
7786 }
7787
orr(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)7788 void Assembler::orr(Condition cond,
7789 EncodingSize size,
7790 Register rd,
7791 Register rn,
7792 const Operand& operand) {
7793 VIXL_ASSERT(AllowAssembler());
7794 CheckIT(cond);
7795 if (operand.IsImmediate()) {
7796 uint32_t imm = operand.GetImmediate();
7797 if (IsUsingT32()) {
7798 ImmediateT32 immediate_t32(imm);
7799 // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7800 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) &&
7801 (!rd.IsPC() || AllowUnpredictable())) {
7802 EmitT32_32(0xf0400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7803 (immediate_t32.GetEncodingValue() & 0xff) |
7804 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7805 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7806 AdvanceIT();
7807 return;
7808 }
7809 } else {
7810 ImmediateA32 immediate_a32(imm);
7811 // ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7812 if (immediate_a32.IsValid() && cond.IsNotNever()) {
7813 EmitA32(0x03800000U | (cond.GetCondition() << 28) |
7814 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7815 immediate_a32.GetEncodingValue());
7816 return;
7817 }
7818 }
7819 }
7820 if (operand.IsImmediateShiftedRegister()) {
7821 Register rm = operand.GetBaseRegister();
7822 if (operand.IsPlainRegister()) {
7823 if (IsUsingT32()) {
7824 // ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7825 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7826 rm.IsLow()) {
7827 EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7828 AdvanceIT();
7829 return;
7830 }
7831 }
7832 }
7833 Shift shift = operand.GetShift();
7834 uint32_t amount = operand.GetShiftAmount();
7835 if (IsUsingT32()) {
7836 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7837 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) &&
7838 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7839 uint32_t amount_ = amount % 32;
7840 EmitT32_32(0xea400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7841 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7842 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7843 AdvanceIT();
7844 return;
7845 }
7846 } else {
7847 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7848 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7849 uint32_t amount_ = amount % 32;
7850 EmitA32(0x01800000U | (cond.GetCondition() << 28) |
7851 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7852 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7853 return;
7854 }
7855 }
7856 }
7857 if (operand.IsRegisterShiftedRegister()) {
7858 Register rm = operand.GetBaseRegister();
7859 Shift shift = operand.GetShift();
7860 Register rs = operand.GetShiftRegister();
7861 if (IsUsingA32()) {
7862 // ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7863 if (cond.IsNotNever() &&
7864 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
7865 AllowUnpredictable())) {
7866 EmitA32(0x01800010U | (cond.GetCondition() << 28) |
7867 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7868 (shift.GetType() << 5) | (rs.GetCode() << 8));
7869 return;
7870 }
7871 }
7872 }
7873 Delegate(kOrr, &Assembler::orr, cond, size, rd, rn, operand);
7874 }
7875
orrs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)7876 void Assembler::orrs(Condition cond,
7877 EncodingSize size,
7878 Register rd,
7879 Register rn,
7880 const Operand& operand) {
7881 VIXL_ASSERT(AllowAssembler());
7882 CheckIT(cond);
7883 if (operand.IsImmediate()) {
7884 uint32_t imm = operand.GetImmediate();
7885 if (IsUsingT32()) {
7886 ImmediateT32 immediate_t32(imm);
7887 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
7888 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(pc) &&
7889 (!rd.IsPC() || AllowUnpredictable())) {
7890 EmitT32_32(0xf0500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7891 (immediate_t32.GetEncodingValue() & 0xff) |
7892 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
7893 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
7894 AdvanceIT();
7895 return;
7896 }
7897 } else {
7898 ImmediateA32 immediate_a32(imm);
7899 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
7900 if (immediate_a32.IsValid() && cond.IsNotNever()) {
7901 EmitA32(0x03900000U | (cond.GetCondition() << 28) |
7902 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
7903 immediate_a32.GetEncodingValue());
7904 return;
7905 }
7906 }
7907 }
7908 if (operand.IsImmediateShiftedRegister()) {
7909 Register rm = operand.GetBaseRegister();
7910 if (operand.IsPlainRegister()) {
7911 if (IsUsingT32()) {
7912 // ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
7913 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
7914 rm.IsLow()) {
7915 EmitT32_16(0x4300 | rd.GetCode() | (rm.GetCode() << 3));
7916 AdvanceIT();
7917 return;
7918 }
7919 }
7920 }
7921 Shift shift = operand.GetShift();
7922 uint32_t amount = operand.GetShiftAmount();
7923 if (IsUsingT32()) {
7924 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
7925 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(pc) &&
7926 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7927 uint32_t amount_ = amount % 32;
7928 EmitT32_32(0xea500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7929 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
7930 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
7931 AdvanceIT();
7932 return;
7933 }
7934 } else {
7935 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
7936 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
7937 uint32_t amount_ = amount % 32;
7938 EmitA32(0x01900000U | (cond.GetCondition() << 28) |
7939 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7940 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
7941 return;
7942 }
7943 }
7944 }
7945 if (operand.IsRegisterShiftedRegister()) {
7946 Register rm = operand.GetBaseRegister();
7947 Shift shift = operand.GetShift();
7948 Register rs = operand.GetShiftRegister();
7949 if (IsUsingA32()) {
7950 // ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
7951 if (cond.IsNotNever() &&
7952 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
7953 AllowUnpredictable())) {
7954 EmitA32(0x01900010U | (cond.GetCondition() << 28) |
7955 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7956 (shift.GetType() << 5) | (rs.GetCode() << 8));
7957 return;
7958 }
7959 }
7960 }
7961 Delegate(kOrrs, &Assembler::orrs, cond, size, rd, rn, operand);
7962 }
7963
pkhbt(Condition cond,Register rd,Register rn,const Operand & operand)7964 void Assembler::pkhbt(Condition cond,
7965 Register rd,
7966 Register rn,
7967 const Operand& operand) {
7968 VIXL_ASSERT(AllowAssembler());
7969 CheckIT(cond);
7970 if (operand.IsImmediateShiftedRegister()) {
7971 Register rm = operand.GetBaseRegister();
7972 Shift shift = operand.GetShift();
7973 uint32_t amount = operand.GetShiftAmount();
7974 if (IsUsingT32()) {
7975 // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1
7976 if (shift.IsLSL() && shift.IsValidAmount(amount) &&
7977 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7978 EmitT32_32(0xeac00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
7979 rm.GetCode() | ((amount & 0x3) << 6) |
7980 ((amount & 0x1c) << 10));
7981 AdvanceIT();
7982 return;
7983 }
7984 } else {
7985 // PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1
7986 if (shift.IsLSL() && shift.IsValidAmount(amount) && cond.IsNotNever() &&
7987 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
7988 EmitA32(0x06800010U | (cond.GetCondition() << 28) |
7989 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
7990 (amount << 7));
7991 return;
7992 }
7993 }
7994 }
7995 Delegate(kPkhbt, &Assembler::pkhbt, cond, rd, rn, operand);
7996 }
7997
pkhtb(Condition cond,Register rd,Register rn,const Operand & operand)7998 void Assembler::pkhtb(Condition cond,
7999 Register rd,
8000 Register rn,
8001 const Operand& operand) {
8002 VIXL_ASSERT(AllowAssembler());
8003 CheckIT(cond);
8004 if (operand.IsImmediateShiftedRegister()) {
8005 Register rm = operand.GetBaseRegister();
8006 Shift shift = operand.GetShift();
8007 uint32_t amount = operand.GetShiftAmount();
8008 if (IsUsingT32()) {
8009 // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1
8010 if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
8011 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8012 uint32_t amount_ = amount % 32;
8013 EmitT32_32(0xeac00020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8014 rm.GetCode() | ((amount_ & 0x3) << 6) |
8015 ((amount_ & 0x1c) << 10));
8016 AdvanceIT();
8017 return;
8018 }
8019 } else {
8020 // PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1
8021 if ((shift.IsASR() || (amount == 0)) && shift.IsValidAmount(amount) &&
8022 cond.IsNotNever() &&
8023 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8024 uint32_t amount_ = amount % 32;
8025 EmitA32(0x06800050U | (cond.GetCondition() << 28) |
8026 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
8027 (amount_ << 7));
8028 return;
8029 }
8030 }
8031 }
8032 Delegate(kPkhtb, &Assembler::pkhtb, cond, rd, rn, operand);
8033 }
8034
pld(Condition cond,Location * location)8035 void Assembler::pld(Condition cond, Location* location) {
8036 VIXL_ASSERT(AllowAssembler());
8037 CheckIT(cond);
8038 Location::Offset offset =
8039 location->IsBound()
8040 ? location->GetLocation() -
8041 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
8042 : 0;
8043 if (IsUsingT32()) {
8044 // PLD{<c>}{<q>} <label> ; T1
8045 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
8046 !location->IsBound())) {
8047 static class EmitOp : public Location::EmitOperator {
8048 public:
8049 EmitOp() : Location::EmitOperator(T32) {}
8050 virtual uint32_t Encode(uint32_t instr,
8051 Location::Offset program_counter,
8052 const Location* loc) const VIXL_OVERRIDE {
8053 program_counter += kT32PcDelta;
8054 Location::Offset off =
8055 loc->GetLocation() - AlignDown(program_counter, 4);
8056 VIXL_ASSERT((off >= -4095) && (off <= 4095));
8057 uint32_t U = (off >= 0);
8058 int32_t target = abs(off) | (U << 12);
8059 return instr | (target & 0xfff) | ((target & 0x1000) << 11);
8060 }
8061 } immop;
8062 EmitT32_32(Link(0xf81ff000U, location, immop, &kT32FarDataInfo));
8063 AdvanceIT();
8064 return;
8065 }
8066 } else {
8067 // PLD{<c>}{<q>} <label> ; A1
8068 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
8069 !location->IsBound())) {
8070 if (cond.Is(al)) {
8071 static class EmitOp : public Location::EmitOperator {
8072 public:
8073 EmitOp() : Location::EmitOperator(A32) {}
8074 virtual uint32_t Encode(uint32_t instr,
8075 Location::Offset program_counter,
8076 const Location* loc) const VIXL_OVERRIDE {
8077 program_counter += kA32PcDelta;
8078 Location::Offset off =
8079 loc->GetLocation() - AlignDown(program_counter, 4);
8080 VIXL_ASSERT((off >= -4095) && (off <= 4095));
8081 uint32_t U = (off >= 0);
8082 int32_t target = abs(off) | (U << 12);
8083 return instr | (target & 0xfff) | ((target & 0x1000) << 11);
8084 }
8085 } immop;
8086 EmitA32(Link(0xf55ff000U, location, immop, &kA32FarDataInfo));
8087 return;
8088 }
8089 }
8090 }
8091 Delegate(kPld, &Assembler::pld, cond, location);
8092 }
8093
pld_info(Condition cond,Location * location,const struct ReferenceInfo ** info)8094 bool Assembler::pld_info(Condition cond,
8095 Location* location,
8096 const struct ReferenceInfo** info) {
8097 VIXL_ASSERT(!location->IsBound());
8098 USE(location);
8099 USE(cond);
8100 if (IsUsingT32()) {
8101 // PLD{<c>}{<q>} <label> ; T1
8102 if (true) {
8103 *info = &kT32FarDataInfo;
8104 return true;
8105 }
8106 } else {
8107 // PLD{<c>}{<q>} <label> ; A1
8108 if (true) {
8109 *info = &kA32FarDataInfo;
8110 return true;
8111 }
8112 }
8113 return false;
8114 }
8115
pld(Condition cond,const MemOperand & operand)8116 void Assembler::pld(Condition cond, const MemOperand& operand) {
8117 VIXL_ASSERT(AllowAssembler());
8118 CheckIT(cond);
8119 if (operand.IsImmediate()) {
8120 Register rn = operand.GetBaseRegister();
8121 int32_t offset = operand.GetOffsetImmediate();
8122 if (IsUsingT32()) {
8123 // PLD{<c>}{<q>} [PC, #<_plusminus_><imm>] ; T1
8124 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
8125 operand.IsOffset()) {
8126 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8127 uint32_t offset_ = abs(offset);
8128 EmitT32_32(0xf81ff000U | offset_ | (sign << 23));
8129 AdvanceIT();
8130 return;
8131 }
8132 } else {
8133 // PLD{<c>}{<q>} [PC, #<_plusminus_><imm_1>] ; A1
8134 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
8135 operand.IsOffset()) {
8136 if (cond.Is(al)) {
8137 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8138 uint32_t offset_ = abs(offset);
8139 EmitA32(0xf55ff000U | offset_ | (sign << 23));
8140 return;
8141 }
8142 }
8143 }
8144 }
8145 if (operand.IsImmediate()) {
8146 Register rn = operand.GetBaseRegister();
8147 int32_t offset = operand.GetOffsetImmediate();
8148 if (IsUsingT32()) {
8149 // PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
8150 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
8151 ((rn.GetCode() & 0xf) != 0xf)) {
8152 EmitT32_32(0xf890f000U | (rn.GetCode() << 16) | (offset & 0xfff));
8153 AdvanceIT();
8154 return;
8155 }
8156 // PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
8157 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
8158 ((rn.GetCode() & 0xf) != 0xf)) {
8159 EmitT32_32(0xf810fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
8160 AdvanceIT();
8161 return;
8162 }
8163 } else {
8164 // PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
8165 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
8166 ((rn.GetCode() & 0xf) != 0xf)) {
8167 if (cond.Is(al)) {
8168 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8169 uint32_t offset_ = abs(offset);
8170 EmitA32(0xf550f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
8171 return;
8172 }
8173 }
8174 }
8175 }
8176 if (operand.IsShiftedRegister()) {
8177 Register rn = operand.GetBaseRegister();
8178 Sign sign = operand.GetSign();
8179 Register rm = operand.GetOffsetRegister();
8180 Shift shift = operand.GetShift();
8181 uint32_t amount = operand.GetShiftAmount();
8182 if (IsUsingT32()) {
8183 // PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
8184 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
8185 ((rn.GetCode() & 0xf) != 0xf) &&
8186 (!rm.IsPC() || AllowUnpredictable())) {
8187 EmitT32_32(0xf810f000U | (rn.GetCode() << 16) | rm.GetCode() |
8188 (amount << 4));
8189 AdvanceIT();
8190 return;
8191 }
8192 } else {
8193 // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
8194 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
8195 (!rm.IsPC() || AllowUnpredictable())) {
8196 if (cond.Is(al)) {
8197 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8198 uint32_t amount_ = amount % 32;
8199 EmitA32(0xf750f000U | (rn.GetCode() << 16) | rm.GetCode() |
8200 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
8201 return;
8202 }
8203 }
8204 // PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
8205 if (shift.IsRRX() && operand.IsOffset() &&
8206 (!rm.IsPC() || AllowUnpredictable())) {
8207 if (cond.Is(al)) {
8208 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8209 EmitA32(0xf750f060U | (rn.GetCode() << 16) | rm.GetCode() |
8210 (sign_ << 23));
8211 return;
8212 }
8213 }
8214 }
8215 }
8216 Delegate(kPld, &Assembler::pld, cond, operand);
8217 }
8218
pldw(Condition cond,const MemOperand & operand)8219 void Assembler::pldw(Condition cond, const MemOperand& operand) {
8220 VIXL_ASSERT(AllowAssembler());
8221 CheckIT(cond);
8222 if (operand.IsImmediate()) {
8223 Register rn = operand.GetBaseRegister();
8224 int32_t offset = operand.GetOffsetImmediate();
8225 if (IsUsingT32()) {
8226 // PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
8227 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
8228 ((rn.GetCode() & 0xf) != 0xf)) {
8229 EmitT32_32(0xf8b0f000U | (rn.GetCode() << 16) | (offset & 0xfff));
8230 AdvanceIT();
8231 return;
8232 }
8233 // PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
8234 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
8235 ((rn.GetCode() & 0xf) != 0xf)) {
8236 EmitT32_32(0xf830fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
8237 AdvanceIT();
8238 return;
8239 }
8240 } else {
8241 // PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
8242 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
8243 ((rn.GetCode() & 0xf) != 0xf)) {
8244 if (cond.Is(al)) {
8245 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8246 uint32_t offset_ = abs(offset);
8247 EmitA32(0xf510f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
8248 return;
8249 }
8250 }
8251 }
8252 }
8253 if (operand.IsShiftedRegister()) {
8254 Register rn = operand.GetBaseRegister();
8255 Sign sign = operand.GetSign();
8256 Register rm = operand.GetOffsetRegister();
8257 Shift shift = operand.GetShift();
8258 uint32_t amount = operand.GetShiftAmount();
8259 if (IsUsingT32()) {
8260 // PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
8261 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
8262 ((rn.GetCode() & 0xf) != 0xf) &&
8263 (!rm.IsPC() || AllowUnpredictable())) {
8264 EmitT32_32(0xf830f000U | (rn.GetCode() << 16) | rm.GetCode() |
8265 (amount << 4));
8266 AdvanceIT();
8267 return;
8268 }
8269 } else {
8270 // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
8271 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
8272 (!rm.IsPC() || AllowUnpredictable())) {
8273 if (cond.Is(al)) {
8274 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8275 uint32_t amount_ = amount % 32;
8276 EmitA32(0xf710f000U | (rn.GetCode() << 16) | rm.GetCode() |
8277 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
8278 return;
8279 }
8280 }
8281 // PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
8282 if (shift.IsRRX() && operand.IsOffset() &&
8283 (!rm.IsPC() || AllowUnpredictable())) {
8284 if (cond.Is(al)) {
8285 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8286 EmitA32(0xf710f060U | (rn.GetCode() << 16) | rm.GetCode() |
8287 (sign_ << 23));
8288 return;
8289 }
8290 }
8291 }
8292 }
8293 Delegate(kPldw, &Assembler::pldw, cond, operand);
8294 }
8295
pli(Condition cond,const MemOperand & operand)8296 void Assembler::pli(Condition cond, const MemOperand& operand) {
8297 VIXL_ASSERT(AllowAssembler());
8298 CheckIT(cond);
8299 if (operand.IsImmediate()) {
8300 Register rn = operand.GetBaseRegister();
8301 int32_t offset = operand.GetOffsetImmediate();
8302 if (IsUsingT32()) {
8303 // PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
8304 if ((offset >= 0) && (offset <= 4095) && operand.IsOffset() &&
8305 ((rn.GetCode() & 0xf) != 0xf)) {
8306 EmitT32_32(0xf990f000U | (rn.GetCode() << 16) | (offset & 0xfff));
8307 AdvanceIT();
8308 return;
8309 }
8310 // PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2
8311 if ((-offset >= 0) && (-offset <= 255) && operand.IsOffset() &&
8312 ((rn.GetCode() & 0xf) != 0xf)) {
8313 EmitT32_32(0xf910fc00U | (rn.GetCode() << 16) | (-offset & 0xff));
8314 AdvanceIT();
8315 return;
8316 }
8317 } else {
8318 // PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1
8319 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
8320 ((rn.GetCode() & 0xf) != 0xf)) {
8321 if (cond.Is(al)) {
8322 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8323 uint32_t offset_ = abs(offset);
8324 EmitA32(0xf450f000U | (rn.GetCode() << 16) | offset_ | (sign << 23));
8325 return;
8326 }
8327 }
8328 }
8329 }
8330 if (operand.IsImmediate()) {
8331 Register rn = operand.GetBaseRegister();
8332 int32_t offset = operand.GetOffsetImmediate();
8333 if (IsUsingT32()) {
8334 // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_2>] ; T3
8335 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
8336 operand.IsOffset()) {
8337 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8338 uint32_t offset_ = abs(offset);
8339 EmitT32_32(0xf91ff000U | offset_ | (sign << 23));
8340 AdvanceIT();
8341 return;
8342 }
8343 } else {
8344 // PLI{<c>}{<q>} [PC, #<_plusminus_><imm_3>] ; A1
8345 if ((offset >= -4095) && (offset <= 4095) && rn.Is(pc) &&
8346 operand.IsOffset()) {
8347 if (cond.Is(al)) {
8348 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
8349 uint32_t offset_ = abs(offset);
8350 EmitA32(0xf45ff000U | offset_ | (sign << 23));
8351 return;
8352 }
8353 }
8354 }
8355 }
8356 if (operand.IsShiftedRegister()) {
8357 Register rn = operand.GetBaseRegister();
8358 Sign sign = operand.GetSign();
8359 Register rm = operand.GetOffsetRegister();
8360 Shift shift = operand.GetShift();
8361 uint32_t amount = operand.GetShiftAmount();
8362 if (IsUsingT32()) {
8363 // PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1
8364 if (sign.IsPlus() && shift.IsLSL() && operand.IsOffset() &&
8365 ((rn.GetCode() & 0xf) != 0xf) &&
8366 (!rm.IsPC() || AllowUnpredictable())) {
8367 EmitT32_32(0xf910f000U | (rn.GetCode() << 16) | rm.GetCode() |
8368 (amount << 4));
8369 AdvanceIT();
8370 return;
8371 }
8372 } else {
8373 // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
8374 if (shift.IsRRX() && operand.IsOffset() &&
8375 (!rm.IsPC() || AllowUnpredictable())) {
8376 if (cond.Is(al)) {
8377 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8378 EmitA32(0xf650f060U | (rn.GetCode() << 16) | rm.GetCode() |
8379 (sign_ << 23));
8380 return;
8381 }
8382 }
8383 // PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
8384 if (!shift.IsRRX() && shift.IsValidAmount(amount) && operand.IsOffset() &&
8385 (!rm.IsPC() || AllowUnpredictable())) {
8386 if (cond.Is(al)) {
8387 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
8388 uint32_t amount_ = amount % 32;
8389 EmitA32(0xf650f000U | (rn.GetCode() << 16) | rm.GetCode() |
8390 (sign_ << 23) | (shift.GetType() << 5) | (amount_ << 7));
8391 return;
8392 }
8393 }
8394 }
8395 }
8396 Delegate(kPli, &Assembler::pli, cond, operand);
8397 }
8398
pli(Condition cond,Location * location)8399 void Assembler::pli(Condition cond, Location* location) {
8400 VIXL_ASSERT(AllowAssembler());
8401 CheckIT(cond);
8402 Location::Offset offset =
8403 location->IsBound()
8404 ? location->GetLocation() -
8405 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
8406 : 0;
8407 if (IsUsingT32()) {
8408 // PLI{<c>}{<q>} <label> ; T3
8409 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
8410 !location->IsBound())) {
8411 static class EmitOp : public Location::EmitOperator {
8412 public:
8413 EmitOp() : Location::EmitOperator(T32) {}
8414 virtual uint32_t Encode(uint32_t instr,
8415 Location::Offset program_counter,
8416 const Location* loc) const VIXL_OVERRIDE {
8417 program_counter += kT32PcDelta;
8418 Location::Offset off =
8419 loc->GetLocation() - AlignDown(program_counter, 4);
8420 VIXL_ASSERT((off >= -4095) && (off <= 4095));
8421 uint32_t U = (off >= 0);
8422 int32_t target = abs(off) | (U << 12);
8423 return instr | (target & 0xfff) | ((target & 0x1000) << 11);
8424 }
8425 } immop;
8426 EmitT32_32(Link(0xf91ff000U, location, immop, &kT32FarDataInfo));
8427 AdvanceIT();
8428 return;
8429 }
8430 } else {
8431 // PLI{<c>}{<q>} <label> ; A1
8432 if (((location->IsBound() && (offset >= -4095) && (offset <= 4095)) ||
8433 !location->IsBound())) {
8434 if (cond.Is(al)) {
8435 static class EmitOp : public Location::EmitOperator {
8436 public:
8437 EmitOp() : Location::EmitOperator(A32) {}
8438 virtual uint32_t Encode(uint32_t instr,
8439 Location::Offset program_counter,
8440 const Location* loc) const VIXL_OVERRIDE {
8441 program_counter += kA32PcDelta;
8442 Location::Offset off =
8443 loc->GetLocation() - AlignDown(program_counter, 4);
8444 VIXL_ASSERT((off >= -4095) && (off <= 4095));
8445 uint32_t U = (off >= 0);
8446 int32_t target = abs(off) | (U << 12);
8447 return instr | (target & 0xfff) | ((target & 0x1000) << 11);
8448 }
8449 } immop;
8450 EmitA32(Link(0xf45ff000U, location, immop, &kA32FarDataInfo));
8451 return;
8452 }
8453 }
8454 }
8455 Delegate(kPli, &Assembler::pli, cond, location);
8456 }
8457
pli_info(Condition cond,Location * location,const struct ReferenceInfo ** info)8458 bool Assembler::pli_info(Condition cond,
8459 Location* location,
8460 const struct ReferenceInfo** info) {
8461 VIXL_ASSERT(!location->IsBound());
8462 USE(location);
8463 USE(cond);
8464 if (IsUsingT32()) {
8465 // PLI{<c>}{<q>} <label> ; T3
8466 if (true) {
8467 *info = &kT32FarDataInfo;
8468 return true;
8469 }
8470 } else {
8471 // PLI{<c>}{<q>} <label> ; A1
8472 if (true) {
8473 *info = &kA32FarDataInfo;
8474 return true;
8475 }
8476 }
8477 return false;
8478 }
8479
pop(Condition cond,EncodingSize size,RegisterList registers)8480 void Assembler::pop(Condition cond, EncodingSize size, RegisterList registers) {
8481 VIXL_ASSERT(AllowAssembler());
8482 CheckIT(cond);
8483 if (!registers.IsEmpty() || AllowUnpredictable()) {
8484 if (IsUsingT32()) {
8485 // A branch out of an IT block should be the last instruction in the
8486 // block.
8487 if (!registers.Includes(pc) || OutsideITBlockAndAlOrLast(cond) ||
8488 AllowUnpredictable()) {
8489 // POP{<c>}{<q>} <registers> ; T1
8490 if (!size.IsWide() && registers.IsR0toR7orPC()) {
8491 EmitT32_16(0xbc00 | (GetRegisterListEncoding(registers, 15, 1) << 8) |
8492 GetRegisterListEncoding(registers, 0, 8));
8493 AdvanceIT();
8494 return;
8495 }
8496 // POP{<c>}{<q>} <registers> ; T2
8497 // Alias of: LDM{<c>}{<q>} SP!, <registers> ; T2
8498 if (!size.IsNarrow() &&
8499 ((!registers.Includes(sp) && (registers.GetCount() > 1) &&
8500 !(registers.Includes(pc) && registers.Includes(lr))) ||
8501 AllowUnpredictable())) {
8502 EmitT32_32(0xe8bd0000U | GetRegisterListEncoding(registers, 0, 16));
8503 AdvanceIT();
8504 return;
8505 }
8506 }
8507 } else {
8508 // POP{<c>}{<q>} <registers> ; A1
8509 // Alias of: LDM{<c>}{<q>} SP!, <registers> ; A1
8510 if (cond.IsNotNever() &&
8511 (!registers.Includes(sp) || AllowUnpredictable())) {
8512 EmitA32(0x08bd0000U | (cond.GetCondition() << 28) |
8513 GetRegisterListEncoding(registers, 0, 16));
8514 return;
8515 }
8516 }
8517 }
8518 Delegate(kPop, &Assembler::pop, cond, size, registers);
8519 }
8520
pop(Condition cond,EncodingSize size,Register rt)8521 void Assembler::pop(Condition cond, EncodingSize size, Register rt) {
8522 VIXL_ASSERT(AllowAssembler());
8523 CheckIT(cond);
8524 if (!rt.IsSP() || AllowUnpredictable()) {
8525 if (IsUsingT32()) {
8526 // POP{<c>}{<q>} <single_register_list> ; T4
8527 // Alias of: LDR{<c>}{<q>} <Rt>, [SP], #4 ; T4
8528 if (!size.IsNarrow() && (!rt.IsPC() || OutsideITBlockAndAlOrLast(cond) ||
8529 AllowUnpredictable())) {
8530 EmitT32_32(0xf85d0b04U | (rt.GetCode() << 12));
8531 AdvanceIT();
8532 return;
8533 }
8534 } else {
8535 // POP{<c>}{<q>} <single_register_list> ; A1
8536 // Alias of: LDR{<c>}{<q>} <Rt>, [SP], #4 ; T1
8537 if (cond.IsNotNever()) {
8538 EmitA32(0x049d0004U | (cond.GetCondition() << 28) |
8539 (rt.GetCode() << 12));
8540 return;
8541 }
8542 }
8543 }
8544 Delegate(kPop, &Assembler::pop, cond, size, rt);
8545 }
8546
push(Condition cond,EncodingSize size,RegisterList registers)8547 void Assembler::push(Condition cond,
8548 EncodingSize size,
8549 RegisterList registers) {
8550 VIXL_ASSERT(AllowAssembler());
8551 CheckIT(cond);
8552 if (!registers.IsEmpty() || AllowUnpredictable()) {
8553 if (IsUsingT32()) {
8554 // PUSH{<c>}{<q>} <registers> ; T1
8555 if (!size.IsWide() && registers.IsR0toR7orLR()) {
8556 EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
8557 GetRegisterListEncoding(registers, 0, 8));
8558 AdvanceIT();
8559 return;
8560 }
8561 // PUSH{<c>}{<q>} <registers> ; T1
8562 // Alias of: STMDB SP!, <registers> ; T1
8563 if (!size.IsNarrow() && !registers.Includes(pc) &&
8564 ((!registers.Includes(sp) && (registers.GetCount() > 1)) ||
8565 AllowUnpredictable())) {
8566 EmitT32_32(0xe92d0000U | GetRegisterListEncoding(registers, 0, 15));
8567 AdvanceIT();
8568 return;
8569 }
8570 } else {
8571 // PUSH{<c>}{<q>} <registers> ; A1
8572 // Alias of: STMDB SP!, <registers> ; A1
8573 if (cond.IsNotNever() &&
8574 // For A32, sp can appear in the list, but stores an UNKNOWN value if
8575 // it is not the lowest-valued register.
8576 (!registers.Includes(sp) ||
8577 registers.GetFirstAvailableRegister().IsSP() ||
8578 AllowUnpredictable())) {
8579 EmitA32(0x092d0000U | (cond.GetCondition() << 28) |
8580 GetRegisterListEncoding(registers, 0, 16));
8581 return;
8582 }
8583 }
8584 }
8585 Delegate(kPush, &Assembler::push, cond, size, registers);
8586 }
8587
push(Condition cond,EncodingSize size,Register rt)8588 void Assembler::push(Condition cond, EncodingSize size, Register rt) {
8589 VIXL_ASSERT(AllowAssembler());
8590 CheckIT(cond);
8591 if (IsUsingT32()) {
8592 // PUSH{<c>}{<q>} <single_register_list> ; T4
8593 // Alias of: STR{<c>}{<q>} <Rt>, [SP, #4]! ; T4
8594 if (!size.IsNarrow() &&
8595 ((!rt.IsPC() && !rt.IsSP()) || AllowUnpredictable())) {
8596 EmitT32_32(0xf84d0d04U | (rt.GetCode() << 12));
8597 AdvanceIT();
8598 return;
8599 }
8600 } else {
8601 // PUSH{<c>}{<q>} <single_register_list> ; A1
8602 // Alias of: STR{<c>}{<q>} <Rt>, [SP, #4]! ; A1
8603 if (cond.IsNotNever() && (!rt.IsSP() || AllowUnpredictable())) {
8604 EmitA32(0x052d0004U | (cond.GetCondition() << 28) | (rt.GetCode() << 12));
8605 return;
8606 }
8607 }
8608 Delegate(kPush, &Assembler::push, cond, size, rt);
8609 }
8610
qadd(Condition cond,Register rd,Register rm,Register rn)8611 void Assembler::qadd(Condition cond, Register rd, Register rm, Register rn) {
8612 VIXL_ASSERT(AllowAssembler());
8613 CheckIT(cond);
8614 if (IsUsingT32()) {
8615 // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
8616 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8617 EmitT32_32(0xfa80f080U | (rd.GetCode() << 8) | rm.GetCode() |
8618 (rn.GetCode() << 16));
8619 AdvanceIT();
8620 return;
8621 }
8622 } else {
8623 // QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
8624 if (cond.IsNotNever() &&
8625 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8626 EmitA32(0x01000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8627 rm.GetCode() | (rn.GetCode() << 16));
8628 return;
8629 }
8630 }
8631 Delegate(kQadd, &Assembler::qadd, cond, rd, rm, rn);
8632 }
8633
qadd16(Condition cond,Register rd,Register rn,Register rm)8634 void Assembler::qadd16(Condition cond, Register rd, Register rn, Register rm) {
8635 VIXL_ASSERT(AllowAssembler());
8636 CheckIT(cond);
8637 if (IsUsingT32()) {
8638 // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8639 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8640 EmitT32_32(0xfa90f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8641 rm.GetCode());
8642 AdvanceIT();
8643 return;
8644 }
8645 } else {
8646 // QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8647 if (cond.IsNotNever() &&
8648 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8649 EmitA32(0x06200f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8650 (rn.GetCode() << 16) | rm.GetCode());
8651 return;
8652 }
8653 }
8654 Delegate(kQadd16, &Assembler::qadd16, cond, rd, rn, rm);
8655 }
8656
qadd8(Condition cond,Register rd,Register rn,Register rm)8657 void Assembler::qadd8(Condition cond, Register rd, Register rn, Register rm) {
8658 VIXL_ASSERT(AllowAssembler());
8659 CheckIT(cond);
8660 if (IsUsingT32()) {
8661 // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8662 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8663 EmitT32_32(0xfa80f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8664 rm.GetCode());
8665 AdvanceIT();
8666 return;
8667 }
8668 } else {
8669 // QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8670 if (cond.IsNotNever() &&
8671 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8672 EmitA32(0x06200f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8673 (rn.GetCode() << 16) | rm.GetCode());
8674 return;
8675 }
8676 }
8677 Delegate(kQadd8, &Assembler::qadd8, cond, rd, rn, rm);
8678 }
8679
qasx(Condition cond,Register rd,Register rn,Register rm)8680 void Assembler::qasx(Condition cond, Register rd, Register rn, Register rm) {
8681 VIXL_ASSERT(AllowAssembler());
8682 CheckIT(cond);
8683 if (IsUsingT32()) {
8684 // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8685 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8686 EmitT32_32(0xfaa0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8687 rm.GetCode());
8688 AdvanceIT();
8689 return;
8690 }
8691 } else {
8692 // QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8693 if (cond.IsNotNever() &&
8694 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8695 EmitA32(0x06200f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8696 (rn.GetCode() << 16) | rm.GetCode());
8697 return;
8698 }
8699 }
8700 Delegate(kQasx, &Assembler::qasx, cond, rd, rn, rm);
8701 }
8702
qdadd(Condition cond,Register rd,Register rm,Register rn)8703 void Assembler::qdadd(Condition cond, Register rd, Register rm, Register rn) {
8704 VIXL_ASSERT(AllowAssembler());
8705 CheckIT(cond);
8706 if (IsUsingT32()) {
8707 // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
8708 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8709 EmitT32_32(0xfa80f090U | (rd.GetCode() << 8) | rm.GetCode() |
8710 (rn.GetCode() << 16));
8711 AdvanceIT();
8712 return;
8713 }
8714 } else {
8715 // QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
8716 if (cond.IsNotNever() &&
8717 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8718 EmitA32(0x01400050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8719 rm.GetCode() | (rn.GetCode() << 16));
8720 return;
8721 }
8722 }
8723 Delegate(kQdadd, &Assembler::qdadd, cond, rd, rm, rn);
8724 }
8725
qdsub(Condition cond,Register rd,Register rm,Register rn)8726 void Assembler::qdsub(Condition cond, Register rd, Register rm, Register rn) {
8727 VIXL_ASSERT(AllowAssembler());
8728 CheckIT(cond);
8729 if (IsUsingT32()) {
8730 // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
8731 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8732 EmitT32_32(0xfa80f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
8733 (rn.GetCode() << 16));
8734 AdvanceIT();
8735 return;
8736 }
8737 } else {
8738 // QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
8739 if (cond.IsNotNever() &&
8740 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8741 EmitA32(0x01600050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8742 rm.GetCode() | (rn.GetCode() << 16));
8743 return;
8744 }
8745 }
8746 Delegate(kQdsub, &Assembler::qdsub, cond, rd, rm, rn);
8747 }
8748
qsax(Condition cond,Register rd,Register rn,Register rm)8749 void Assembler::qsax(Condition cond, Register rd, Register rn, Register rm) {
8750 VIXL_ASSERT(AllowAssembler());
8751 CheckIT(cond);
8752 if (IsUsingT32()) {
8753 // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8754 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8755 EmitT32_32(0xfae0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8756 rm.GetCode());
8757 AdvanceIT();
8758 return;
8759 }
8760 } else {
8761 // QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8762 if (cond.IsNotNever() &&
8763 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8764 EmitA32(0x06200f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8765 (rn.GetCode() << 16) | rm.GetCode());
8766 return;
8767 }
8768 }
8769 Delegate(kQsax, &Assembler::qsax, cond, rd, rn, rm);
8770 }
8771
qsub(Condition cond,Register rd,Register rm,Register rn)8772 void Assembler::qsub(Condition cond, Register rd, Register rm, Register rn) {
8773 VIXL_ASSERT(AllowAssembler());
8774 CheckIT(cond);
8775 if (IsUsingT32()) {
8776 // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
8777 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8778 EmitT32_32(0xfa80f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
8779 (rn.GetCode() << 16));
8780 AdvanceIT();
8781 return;
8782 }
8783 } else {
8784 // QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
8785 if (cond.IsNotNever() &&
8786 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8787 EmitA32(0x01200050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8788 rm.GetCode() | (rn.GetCode() << 16));
8789 return;
8790 }
8791 }
8792 Delegate(kQsub, &Assembler::qsub, cond, rd, rm, rn);
8793 }
8794
qsub16(Condition cond,Register rd,Register rn,Register rm)8795 void Assembler::qsub16(Condition cond, Register rd, Register rn, Register rm) {
8796 VIXL_ASSERT(AllowAssembler());
8797 CheckIT(cond);
8798 if (IsUsingT32()) {
8799 // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8800 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8801 EmitT32_32(0xfad0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8802 rm.GetCode());
8803 AdvanceIT();
8804 return;
8805 }
8806 } else {
8807 // QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8808 if (cond.IsNotNever() &&
8809 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8810 EmitA32(0x06200f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8811 (rn.GetCode() << 16) | rm.GetCode());
8812 return;
8813 }
8814 }
8815 Delegate(kQsub16, &Assembler::qsub16, cond, rd, rn, rm);
8816 }
8817
qsub8(Condition cond,Register rd,Register rn,Register rm)8818 void Assembler::qsub8(Condition cond, Register rd, Register rn, Register rm) {
8819 VIXL_ASSERT(AllowAssembler());
8820 CheckIT(cond);
8821 if (IsUsingT32()) {
8822 // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
8823 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8824 EmitT32_32(0xfac0f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
8825 rm.GetCode());
8826 AdvanceIT();
8827 return;
8828 }
8829 } else {
8830 // QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
8831 if (cond.IsNotNever() &&
8832 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8833 EmitA32(0x06200ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8834 (rn.GetCode() << 16) | rm.GetCode());
8835 return;
8836 }
8837 }
8838 Delegate(kQsub8, &Assembler::qsub8, cond, rd, rn, rm);
8839 }
8840
rbit(Condition cond,Register rd,Register rm)8841 void Assembler::rbit(Condition cond, Register rd, Register rm) {
8842 VIXL_ASSERT(AllowAssembler());
8843 CheckIT(cond);
8844 if (IsUsingT32()) {
8845 // RBIT{<c>}{<q>} <Rd>, <Rm> ; T1
8846 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8847 EmitT32_32(0xfa90f0a0U | (rd.GetCode() << 8) | rm.GetCode() |
8848 (rm.GetCode() << 16));
8849 AdvanceIT();
8850 return;
8851 }
8852 } else {
8853 // RBIT{<c>}{<q>} <Rd>, <Rm> ; A1
8854 if (cond.IsNotNever() &&
8855 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8856 EmitA32(0x06ff0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8857 rm.GetCode());
8858 return;
8859 }
8860 }
8861 Delegate(kRbit, &Assembler::rbit, cond, rd, rm);
8862 }
8863
rev(Condition cond,EncodingSize size,Register rd,Register rm)8864 void Assembler::rev(Condition cond,
8865 EncodingSize size,
8866 Register rd,
8867 Register rm) {
8868 VIXL_ASSERT(AllowAssembler());
8869 CheckIT(cond);
8870 if (IsUsingT32()) {
8871 // REV{<c>}{<q>} <Rd>, <Rm> ; T1
8872 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8873 EmitT32_16(0xba00 | rd.GetCode() | (rm.GetCode() << 3));
8874 AdvanceIT();
8875 return;
8876 }
8877 // REV{<c>}{<q>} <Rd>, <Rm> ; T2
8878 if (!size.IsNarrow() &&
8879 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8880 EmitT32_32(0xfa90f080U | (rd.GetCode() << 8) | rm.GetCode() |
8881 (rm.GetCode() << 16));
8882 AdvanceIT();
8883 return;
8884 }
8885 } else {
8886 // REV{<c>}{<q>} <Rd>, <Rm> ; A1
8887 if (cond.IsNotNever() &&
8888 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8889 EmitA32(0x06bf0f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8890 rm.GetCode());
8891 return;
8892 }
8893 }
8894 Delegate(kRev, &Assembler::rev, cond, size, rd, rm);
8895 }
8896
rev16(Condition cond,EncodingSize size,Register rd,Register rm)8897 void Assembler::rev16(Condition cond,
8898 EncodingSize size,
8899 Register rd,
8900 Register rm) {
8901 VIXL_ASSERT(AllowAssembler());
8902 CheckIT(cond);
8903 if (IsUsingT32()) {
8904 // REV16{<c>}{<q>} <Rd>, <Rm> ; T1
8905 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8906 EmitT32_16(0xba40 | rd.GetCode() | (rm.GetCode() << 3));
8907 AdvanceIT();
8908 return;
8909 }
8910 // REV16{<c>}{<q>} <Rd>, <Rm> ; T2
8911 if (!size.IsNarrow() &&
8912 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8913 EmitT32_32(0xfa90f090U | (rd.GetCode() << 8) | rm.GetCode() |
8914 (rm.GetCode() << 16));
8915 AdvanceIT();
8916 return;
8917 }
8918 } else {
8919 // REV16{<c>}{<q>} <Rd>, <Rm> ; A1
8920 if (cond.IsNotNever() &&
8921 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8922 EmitA32(0x06bf0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8923 rm.GetCode());
8924 return;
8925 }
8926 }
8927 Delegate(kRev16, &Assembler::rev16, cond, size, rd, rm);
8928 }
8929
revsh(Condition cond,EncodingSize size,Register rd,Register rm)8930 void Assembler::revsh(Condition cond,
8931 EncodingSize size,
8932 Register rd,
8933 Register rm) {
8934 VIXL_ASSERT(AllowAssembler());
8935 CheckIT(cond);
8936 if (IsUsingT32()) {
8937 // REVSH{<c>}{<q>} <Rd>, <Rm> ; T1
8938 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
8939 EmitT32_16(0xbac0 | rd.GetCode() | (rm.GetCode() << 3));
8940 AdvanceIT();
8941 return;
8942 }
8943 // REVSH{<c>}{<q>} <Rd>, <Rm> ; T2
8944 if (!size.IsNarrow() &&
8945 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8946 EmitT32_32(0xfa90f0b0U | (rd.GetCode() << 8) | rm.GetCode() |
8947 (rm.GetCode() << 16));
8948 AdvanceIT();
8949 return;
8950 }
8951 } else {
8952 // REVSH{<c>}{<q>} <Rd>, <Rm> ; A1
8953 if (cond.IsNotNever() &&
8954 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8955 EmitA32(0x06ff0fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
8956 rm.GetCode());
8957 return;
8958 }
8959 }
8960 Delegate(kRevsh, &Assembler::revsh, cond, size, rd, rm);
8961 }
8962
ror(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)8963 void Assembler::ror(Condition cond,
8964 EncodingSize size,
8965 Register rd,
8966 Register rm,
8967 const Operand& operand) {
8968 VIXL_ASSERT(AllowAssembler());
8969 CheckIT(cond);
8970 if (operand.IsImmediate()) {
8971 uint32_t imm = operand.GetImmediate();
8972 if (IsUsingT32()) {
8973 // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
8974 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
8975 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
8976 EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode() |
8977 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
8978 AdvanceIT();
8979 return;
8980 }
8981 } else {
8982 // ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
8983 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
8984 EmitA32(0x01a00060U | (cond.GetCondition() << 28) |
8985 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
8986 return;
8987 }
8988 }
8989 }
8990 if (operand.IsPlainRegister()) {
8991 Register rs = operand.GetBaseRegister();
8992 if (IsUsingT32()) {
8993 // ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
8994 if (InITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
8995 rs.IsLow()) {
8996 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
8997 AdvanceIT();
8998 return;
8999 }
9000 // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
9001 if (!size.IsNarrow() &&
9002 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
9003 EmitT32_32(0xfa60f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
9004 rs.GetCode());
9005 AdvanceIT();
9006 return;
9007 }
9008 } else {
9009 // ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
9010 if (cond.IsNotNever() &&
9011 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
9012 EmitA32(0x01a00070U | (cond.GetCondition() << 28) |
9013 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
9014 return;
9015 }
9016 }
9017 }
9018 Delegate(kRor, &Assembler::ror, cond, size, rd, rm, operand);
9019 }
9020
rors(Condition cond,EncodingSize size,Register rd,Register rm,const Operand & operand)9021 void Assembler::rors(Condition cond,
9022 EncodingSize size,
9023 Register rd,
9024 Register rm,
9025 const Operand& operand) {
9026 VIXL_ASSERT(AllowAssembler());
9027 CheckIT(cond);
9028 if (operand.IsImmediate()) {
9029 uint32_t imm = operand.GetImmediate();
9030 if (IsUsingT32()) {
9031 // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
9032 if (!size.IsNarrow() && (imm >= 1) && (imm <= 31) &&
9033 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9034 EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode() |
9035 ((imm & 0x3) << 6) | ((imm & 0x1c) << 10));
9036 AdvanceIT();
9037 return;
9038 }
9039 } else {
9040 // RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
9041 if ((imm >= 1) && (imm <= 31) && cond.IsNotNever()) {
9042 EmitA32(0x01b00060U | (cond.GetCondition() << 28) |
9043 (rd.GetCode() << 12) | rm.GetCode() | (imm << 7));
9044 return;
9045 }
9046 }
9047 }
9048 if (operand.IsPlainRegister()) {
9049 Register rs = operand.GetBaseRegister();
9050 if (IsUsingT32()) {
9051 // RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
9052 if (OutsideITBlock() && !size.IsWide() && rd.Is(rm) && rm.IsLow() &&
9053 rs.IsLow()) {
9054 EmitT32_16(0x41c0 | rd.GetCode() | (rs.GetCode() << 3));
9055 AdvanceIT();
9056 return;
9057 }
9058 // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
9059 if (!size.IsNarrow() &&
9060 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
9061 EmitT32_32(0xfa70f000U | (rd.GetCode() << 8) | (rm.GetCode() << 16) |
9062 rs.GetCode());
9063 AdvanceIT();
9064 return;
9065 }
9066 } else {
9067 // RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
9068 if (cond.IsNotNever() &&
9069 ((!rd.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
9070 EmitA32(0x01b00070U | (cond.GetCondition() << 28) |
9071 (rd.GetCode() << 12) | rm.GetCode() | (rs.GetCode() << 8));
9072 return;
9073 }
9074 }
9075 }
9076 Delegate(kRors, &Assembler::rors, cond, size, rd, rm, operand);
9077 }
9078
rrx(Condition cond,Register rd,Register rm)9079 void Assembler::rrx(Condition cond, Register rd, Register rm) {
9080 VIXL_ASSERT(AllowAssembler());
9081 CheckIT(cond);
9082 if (IsUsingT32()) {
9083 // RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3
9084 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9085 EmitT32_32(0xea4f0030U | (rd.GetCode() << 8) | rm.GetCode());
9086 AdvanceIT();
9087 return;
9088 }
9089 } else {
9090 // RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1
9091 if (cond.IsNotNever()) {
9092 EmitA32(0x01a00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9093 rm.GetCode());
9094 return;
9095 }
9096 }
9097 Delegate(kRrx, &Assembler::rrx, cond, rd, rm);
9098 }
9099
rrxs(Condition cond,Register rd,Register rm)9100 void Assembler::rrxs(Condition cond, Register rd, Register rm) {
9101 VIXL_ASSERT(AllowAssembler());
9102 CheckIT(cond);
9103 if (IsUsingT32()) {
9104 // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3
9105 if (((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9106 EmitT32_32(0xea5f0030U | (rd.GetCode() << 8) | rm.GetCode());
9107 AdvanceIT();
9108 return;
9109 }
9110 } else {
9111 // RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1
9112 if (cond.IsNotNever()) {
9113 EmitA32(0x01b00060U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9114 rm.GetCode());
9115 return;
9116 }
9117 }
9118 Delegate(kRrxs, &Assembler::rrxs, cond, rd, rm);
9119 }
9120
rsb(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)9121 void Assembler::rsb(Condition cond,
9122 EncodingSize size,
9123 Register rd,
9124 Register rn,
9125 const Operand& operand) {
9126 VIXL_ASSERT(AllowAssembler());
9127 CheckIT(cond);
9128 if (operand.IsImmediate()) {
9129 uint32_t imm = operand.GetImmediate();
9130 if (IsUsingT32()) {
9131 ImmediateT32 immediate_t32(imm);
9132 // RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1
9133 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
9134 (imm == 0)) {
9135 EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
9136 AdvanceIT();
9137 return;
9138 }
9139 // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
9140 if (!size.IsNarrow() && immediate_t32.IsValid() &&
9141 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
9142 EmitT32_32(0xf1c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9143 (immediate_t32.GetEncodingValue() & 0xff) |
9144 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
9145 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
9146 AdvanceIT();
9147 return;
9148 }
9149 } else {
9150 ImmediateA32 immediate_a32(imm);
9151 // RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9152 if (immediate_a32.IsValid() && cond.IsNotNever()) {
9153 EmitA32(0x02600000U | (cond.GetCondition() << 28) |
9154 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9155 immediate_a32.GetEncodingValue());
9156 return;
9157 }
9158 }
9159 }
9160 if (operand.IsImmediateShiftedRegister()) {
9161 Register rm = operand.GetBaseRegister();
9162 Shift shift = operand.GetShift();
9163 uint32_t amount = operand.GetShiftAmount();
9164 if (IsUsingT32()) {
9165 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
9166 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
9167 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9168 uint32_t amount_ = amount % 32;
9169 EmitT32_32(0xebc00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9170 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
9171 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
9172 AdvanceIT();
9173 return;
9174 }
9175 } else {
9176 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9177 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9178 uint32_t amount_ = amount % 32;
9179 EmitA32(0x00600000U | (cond.GetCondition() << 28) |
9180 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9181 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9182 return;
9183 }
9184 }
9185 }
9186 if (operand.IsRegisterShiftedRegister()) {
9187 Register rm = operand.GetBaseRegister();
9188 Shift shift = operand.GetShift();
9189 Register rs = operand.GetShiftRegister();
9190 if (IsUsingA32()) {
9191 // RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9192 if (cond.IsNotNever() &&
9193 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9194 AllowUnpredictable())) {
9195 EmitA32(0x00600010U | (cond.GetCondition() << 28) |
9196 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9197 (shift.GetType() << 5) | (rs.GetCode() << 8));
9198 return;
9199 }
9200 }
9201 }
9202 Delegate(kRsb, &Assembler::rsb, cond, size, rd, rn, operand);
9203 }
9204
rsbs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)9205 void Assembler::rsbs(Condition cond,
9206 EncodingSize size,
9207 Register rd,
9208 Register rn,
9209 const Operand& operand) {
9210 VIXL_ASSERT(AllowAssembler());
9211 CheckIT(cond);
9212 if (operand.IsImmediate()) {
9213 uint32_t imm = operand.GetImmediate();
9214 if (IsUsingT32()) {
9215 ImmediateT32 immediate_t32(imm);
9216 // RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1
9217 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
9218 (imm == 0)) {
9219 EmitT32_16(0x4240 | rd.GetCode() | (rn.GetCode() << 3));
9220 AdvanceIT();
9221 return;
9222 }
9223 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
9224 if (!size.IsNarrow() && immediate_t32.IsValid() &&
9225 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
9226 EmitT32_32(0xf1d00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9227 (immediate_t32.GetEncodingValue() & 0xff) |
9228 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
9229 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
9230 AdvanceIT();
9231 return;
9232 }
9233 } else {
9234 ImmediateA32 immediate_a32(imm);
9235 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9236 if (immediate_a32.IsValid() && cond.IsNotNever()) {
9237 EmitA32(0x02700000U | (cond.GetCondition() << 28) |
9238 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9239 immediate_a32.GetEncodingValue());
9240 return;
9241 }
9242 }
9243 }
9244 if (operand.IsImmediateShiftedRegister()) {
9245 Register rm = operand.GetBaseRegister();
9246 Shift shift = operand.GetShift();
9247 uint32_t amount = operand.GetShiftAmount();
9248 if (IsUsingT32()) {
9249 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1
9250 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
9251 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9252 uint32_t amount_ = amount % 32;
9253 EmitT32_32(0xebd00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9254 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
9255 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
9256 AdvanceIT();
9257 return;
9258 }
9259 } else {
9260 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9261 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9262 uint32_t amount_ = amount % 32;
9263 EmitA32(0x00700000U | (cond.GetCondition() << 28) |
9264 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9265 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9266 return;
9267 }
9268 }
9269 }
9270 if (operand.IsRegisterShiftedRegister()) {
9271 Register rm = operand.GetBaseRegister();
9272 Shift shift = operand.GetShift();
9273 Register rs = operand.GetShiftRegister();
9274 if (IsUsingA32()) {
9275 // RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9276 if (cond.IsNotNever() &&
9277 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9278 AllowUnpredictable())) {
9279 EmitA32(0x00700010U | (cond.GetCondition() << 28) |
9280 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9281 (shift.GetType() << 5) | (rs.GetCode() << 8));
9282 return;
9283 }
9284 }
9285 }
9286 Delegate(kRsbs, &Assembler::rsbs, cond, size, rd, rn, operand);
9287 }
9288
rsc(Condition cond,Register rd,Register rn,const Operand & operand)9289 void Assembler::rsc(Condition cond,
9290 Register rd,
9291 Register rn,
9292 const Operand& operand) {
9293 VIXL_ASSERT(AllowAssembler());
9294 CheckIT(cond);
9295 if (operand.IsImmediate()) {
9296 uint32_t imm = operand.GetImmediate();
9297 if (IsUsingA32()) {
9298 ImmediateA32 immediate_a32(imm);
9299 // RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9300 if (immediate_a32.IsValid() && cond.IsNotNever()) {
9301 EmitA32(0x02e00000U | (cond.GetCondition() << 28) |
9302 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9303 immediate_a32.GetEncodingValue());
9304 return;
9305 }
9306 }
9307 }
9308 if (operand.IsImmediateShiftedRegister()) {
9309 Register rm = operand.GetBaseRegister();
9310 Shift shift = operand.GetShift();
9311 uint32_t amount = operand.GetShiftAmount();
9312 if (IsUsingA32()) {
9313 // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9314 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9315 uint32_t amount_ = amount % 32;
9316 EmitA32(0x00e00000U | (cond.GetCondition() << 28) |
9317 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9318 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9319 return;
9320 }
9321 }
9322 }
9323 if (operand.IsRegisterShiftedRegister()) {
9324 Register rm = operand.GetBaseRegister();
9325 Shift shift = operand.GetShift();
9326 Register rs = operand.GetShiftRegister();
9327 if (IsUsingA32()) {
9328 // RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9329 if (cond.IsNotNever() &&
9330 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9331 AllowUnpredictable())) {
9332 EmitA32(0x00e00010U | (cond.GetCondition() << 28) |
9333 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9334 (shift.GetType() << 5) | (rs.GetCode() << 8));
9335 return;
9336 }
9337 }
9338 }
9339 Delegate(kRsc, &Assembler::rsc, cond, rd, rn, operand);
9340 }
9341
rscs(Condition cond,Register rd,Register rn,const Operand & operand)9342 void Assembler::rscs(Condition cond,
9343 Register rd,
9344 Register rn,
9345 const Operand& operand) {
9346 VIXL_ASSERT(AllowAssembler());
9347 CheckIT(cond);
9348 if (operand.IsImmediate()) {
9349 uint32_t imm = operand.GetImmediate();
9350 if (IsUsingA32()) {
9351 ImmediateA32 immediate_a32(imm);
9352 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9353 if (immediate_a32.IsValid() && cond.IsNotNever()) {
9354 EmitA32(0x02f00000U | (cond.GetCondition() << 28) |
9355 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9356 immediate_a32.GetEncodingValue());
9357 return;
9358 }
9359 }
9360 }
9361 if (operand.IsImmediateShiftedRegister()) {
9362 Register rm = operand.GetBaseRegister();
9363 Shift shift = operand.GetShift();
9364 uint32_t amount = operand.GetShiftAmount();
9365 if (IsUsingA32()) {
9366 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9367 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9368 uint32_t amount_ = amount % 32;
9369 EmitA32(0x00f00000U | (cond.GetCondition() << 28) |
9370 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9371 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9372 return;
9373 }
9374 }
9375 }
9376 if (operand.IsRegisterShiftedRegister()) {
9377 Register rm = operand.GetBaseRegister();
9378 Shift shift = operand.GetShift();
9379 Register rs = operand.GetShiftRegister();
9380 if (IsUsingA32()) {
9381 // RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9382 if (cond.IsNotNever() &&
9383 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9384 AllowUnpredictable())) {
9385 EmitA32(0x00f00010U | (cond.GetCondition() << 28) |
9386 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9387 (shift.GetType() << 5) | (rs.GetCode() << 8));
9388 return;
9389 }
9390 }
9391 }
9392 Delegate(kRscs, &Assembler::rscs, cond, rd, rn, operand);
9393 }
9394
sadd16(Condition cond,Register rd,Register rn,Register rm)9395 void Assembler::sadd16(Condition cond, Register rd, Register rn, Register rm) {
9396 VIXL_ASSERT(AllowAssembler());
9397 CheckIT(cond);
9398 if (IsUsingT32()) {
9399 // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9400 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9401 EmitT32_32(0xfa90f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9402 rm.GetCode());
9403 AdvanceIT();
9404 return;
9405 }
9406 } else {
9407 // SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9408 if (cond.IsNotNever() &&
9409 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9410 EmitA32(0x06100f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9411 (rn.GetCode() << 16) | rm.GetCode());
9412 return;
9413 }
9414 }
9415 Delegate(kSadd16, &Assembler::sadd16, cond, rd, rn, rm);
9416 }
9417
sadd8(Condition cond,Register rd,Register rn,Register rm)9418 void Assembler::sadd8(Condition cond, Register rd, Register rn, Register rm) {
9419 VIXL_ASSERT(AllowAssembler());
9420 CheckIT(cond);
9421 if (IsUsingT32()) {
9422 // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9423 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9424 EmitT32_32(0xfa80f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9425 rm.GetCode());
9426 AdvanceIT();
9427 return;
9428 }
9429 } else {
9430 // SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9431 if (cond.IsNotNever() &&
9432 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9433 EmitA32(0x06100f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9434 (rn.GetCode() << 16) | rm.GetCode());
9435 return;
9436 }
9437 }
9438 Delegate(kSadd8, &Assembler::sadd8, cond, rd, rn, rm);
9439 }
9440
sasx(Condition cond,Register rd,Register rn,Register rm)9441 void Assembler::sasx(Condition cond, Register rd, Register rn, Register rm) {
9442 VIXL_ASSERT(AllowAssembler());
9443 CheckIT(cond);
9444 if (IsUsingT32()) {
9445 // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9446 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9447 EmitT32_32(0xfaa0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9448 rm.GetCode());
9449 AdvanceIT();
9450 return;
9451 }
9452 } else {
9453 // SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9454 if (cond.IsNotNever() &&
9455 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9456 EmitA32(0x06100f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9457 (rn.GetCode() << 16) | rm.GetCode());
9458 return;
9459 }
9460 }
9461 Delegate(kSasx, &Assembler::sasx, cond, rd, rn, rm);
9462 }
9463
sbc(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)9464 void Assembler::sbc(Condition cond,
9465 EncodingSize size,
9466 Register rd,
9467 Register rn,
9468 const Operand& operand) {
9469 VIXL_ASSERT(AllowAssembler());
9470 CheckIT(cond);
9471 if (operand.IsImmediate()) {
9472 uint32_t imm = operand.GetImmediate();
9473 if (IsUsingT32()) {
9474 ImmediateT32 immediate_t32(imm);
9475 // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
9476 if (!size.IsNarrow() && immediate_t32.IsValid() &&
9477 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
9478 EmitT32_32(0xf1600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9479 (immediate_t32.GetEncodingValue() & 0xff) |
9480 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
9481 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
9482 AdvanceIT();
9483 return;
9484 }
9485 } else {
9486 ImmediateA32 immediate_a32(imm);
9487 // SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9488 if (immediate_a32.IsValid() && cond.IsNotNever()) {
9489 EmitA32(0x02c00000U | (cond.GetCondition() << 28) |
9490 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9491 immediate_a32.GetEncodingValue());
9492 return;
9493 }
9494 }
9495 }
9496 if (operand.IsImmediateShiftedRegister()) {
9497 Register rm = operand.GetBaseRegister();
9498 if (operand.IsPlainRegister()) {
9499 if (IsUsingT32()) {
9500 // SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
9501 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
9502 rm.IsLow()) {
9503 EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
9504 AdvanceIT();
9505 return;
9506 }
9507 }
9508 }
9509 Shift shift = operand.GetShift();
9510 uint32_t amount = operand.GetShiftAmount();
9511 if (IsUsingT32()) {
9512 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
9513 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
9514 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9515 uint32_t amount_ = amount % 32;
9516 EmitT32_32(0xeb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9517 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
9518 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
9519 AdvanceIT();
9520 return;
9521 }
9522 } else {
9523 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9524 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9525 uint32_t amount_ = amount % 32;
9526 EmitA32(0x00c00000U | (cond.GetCondition() << 28) |
9527 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9528 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9529 return;
9530 }
9531 }
9532 }
9533 if (operand.IsRegisterShiftedRegister()) {
9534 Register rm = operand.GetBaseRegister();
9535 Shift shift = operand.GetShift();
9536 Register rs = operand.GetShiftRegister();
9537 if (IsUsingA32()) {
9538 // SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9539 if (cond.IsNotNever() &&
9540 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9541 AllowUnpredictable())) {
9542 EmitA32(0x00c00010U | (cond.GetCondition() << 28) |
9543 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9544 (shift.GetType() << 5) | (rs.GetCode() << 8));
9545 return;
9546 }
9547 }
9548 }
9549 Delegate(kSbc, &Assembler::sbc, cond, size, rd, rn, operand);
9550 }
9551
sbcs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)9552 void Assembler::sbcs(Condition cond,
9553 EncodingSize size,
9554 Register rd,
9555 Register rn,
9556 const Operand& operand) {
9557 VIXL_ASSERT(AllowAssembler());
9558 CheckIT(cond);
9559 if (operand.IsImmediate()) {
9560 uint32_t imm = operand.GetImmediate();
9561 if (IsUsingT32()) {
9562 ImmediateT32 immediate_t32(imm);
9563 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
9564 if (!size.IsNarrow() && immediate_t32.IsValid() &&
9565 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
9566 EmitT32_32(0xf1700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9567 (immediate_t32.GetEncodingValue() & 0xff) |
9568 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
9569 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
9570 AdvanceIT();
9571 return;
9572 }
9573 } else {
9574 ImmediateA32 immediate_a32(imm);
9575 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
9576 if (immediate_a32.IsValid() && cond.IsNotNever()) {
9577 EmitA32(0x02d00000U | (cond.GetCondition() << 28) |
9578 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
9579 immediate_a32.GetEncodingValue());
9580 return;
9581 }
9582 }
9583 }
9584 if (operand.IsImmediateShiftedRegister()) {
9585 Register rm = operand.GetBaseRegister();
9586 if (operand.IsPlainRegister()) {
9587 if (IsUsingT32()) {
9588 // SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
9589 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
9590 rm.IsLow()) {
9591 EmitT32_16(0x4180 | rd.GetCode() | (rm.GetCode() << 3));
9592 AdvanceIT();
9593 return;
9594 }
9595 }
9596 }
9597 Shift shift = operand.GetShift();
9598 uint32_t amount = operand.GetShiftAmount();
9599 if (IsUsingT32()) {
9600 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
9601 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
9602 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9603 uint32_t amount_ = amount % 32;
9604 EmitT32_32(0xeb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9605 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
9606 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
9607 AdvanceIT();
9608 return;
9609 }
9610 } else {
9611 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
9612 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
9613 uint32_t amount_ = amount % 32;
9614 EmitA32(0x00d00000U | (cond.GetCondition() << 28) |
9615 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9616 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
9617 return;
9618 }
9619 }
9620 }
9621 if (operand.IsRegisterShiftedRegister()) {
9622 Register rm = operand.GetBaseRegister();
9623 Shift shift = operand.GetShift();
9624 Register rs = operand.GetShiftRegister();
9625 if (IsUsingA32()) {
9626 // SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
9627 if (cond.IsNotNever() &&
9628 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
9629 AllowUnpredictable())) {
9630 EmitA32(0x00d00010U | (cond.GetCondition() << 28) |
9631 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
9632 (shift.GetType() << 5) | (rs.GetCode() << 8));
9633 return;
9634 }
9635 }
9636 }
9637 Delegate(kSbcs, &Assembler::sbcs, cond, size, rd, rn, operand);
9638 }
9639
sbfx(Condition cond,Register rd,Register rn,uint32_t lsb,uint32_t width)9640 void Assembler::sbfx(
9641 Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
9642 VIXL_ASSERT(AllowAssembler());
9643 CheckIT(cond);
9644 if (IsUsingT32()) {
9645 // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
9646 if ((lsb <= 31) &&
9647 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
9648 AllowUnpredictable())) {
9649 uint32_t widthm1 = width - 1;
9650 EmitT32_32(0xf3400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9651 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
9652 AdvanceIT();
9653 return;
9654 }
9655 } else {
9656 // SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
9657 if ((lsb <= 31) && cond.IsNotNever() &&
9658 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
9659 AllowUnpredictable())) {
9660 uint32_t widthm1 = width - 1;
9661 EmitA32(0x07a00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9662 rn.GetCode() | (lsb << 7) | (widthm1 << 16));
9663 return;
9664 }
9665 }
9666 Delegate(kSbfx, &Assembler::sbfx, cond, rd, rn, lsb, width);
9667 }
9668
sdiv(Condition cond,Register rd,Register rn,Register rm)9669 void Assembler::sdiv(Condition cond, Register rd, Register rn, Register rm) {
9670 VIXL_ASSERT(AllowAssembler());
9671 CheckIT(cond);
9672 if (IsUsingT32()) {
9673 // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9674 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9675 EmitT32_32(0xfb90f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9676 rm.GetCode());
9677 AdvanceIT();
9678 return;
9679 }
9680 } else {
9681 // SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9682 if (cond.IsNotNever() &&
9683 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9684 EmitA32(0x0710f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9685 rn.GetCode() | (rm.GetCode() << 8));
9686 return;
9687 }
9688 }
9689 Delegate(kSdiv, &Assembler::sdiv, cond, rd, rn, rm);
9690 }
9691
sel(Condition cond,Register rd,Register rn,Register rm)9692 void Assembler::sel(Condition cond, Register rd, Register rn, Register rm) {
9693 VIXL_ASSERT(AllowAssembler());
9694 CheckIT(cond);
9695 if (IsUsingT32()) {
9696 // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9697 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9698 EmitT32_32(0xfaa0f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9699 rm.GetCode());
9700 AdvanceIT();
9701 return;
9702 }
9703 } else {
9704 // SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9705 if (cond.IsNotNever() &&
9706 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9707 EmitA32(0x06800fb0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9708 (rn.GetCode() << 16) | rm.GetCode());
9709 return;
9710 }
9711 }
9712 Delegate(kSel, &Assembler::sel, cond, rd, rn, rm);
9713 }
9714
shadd16(Condition cond,Register rd,Register rn,Register rm)9715 void Assembler::shadd16(Condition cond, Register rd, Register rn, Register rm) {
9716 VIXL_ASSERT(AllowAssembler());
9717 CheckIT(cond);
9718 if (IsUsingT32()) {
9719 // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9720 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9721 EmitT32_32(0xfa90f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9722 rm.GetCode());
9723 AdvanceIT();
9724 return;
9725 }
9726 } else {
9727 // SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9728 if (cond.IsNotNever() &&
9729 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9730 EmitA32(0x06300f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9731 (rn.GetCode() << 16) | rm.GetCode());
9732 return;
9733 }
9734 }
9735 Delegate(kShadd16, &Assembler::shadd16, cond, rd, rn, rm);
9736 }
9737
shadd8(Condition cond,Register rd,Register rn,Register rm)9738 void Assembler::shadd8(Condition cond, Register rd, Register rn, Register rm) {
9739 VIXL_ASSERT(AllowAssembler());
9740 CheckIT(cond);
9741 if (IsUsingT32()) {
9742 // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9743 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9744 EmitT32_32(0xfa80f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9745 rm.GetCode());
9746 AdvanceIT();
9747 return;
9748 }
9749 } else {
9750 // SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9751 if (cond.IsNotNever() &&
9752 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9753 EmitA32(0x06300f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9754 (rn.GetCode() << 16) | rm.GetCode());
9755 return;
9756 }
9757 }
9758 Delegate(kShadd8, &Assembler::shadd8, cond, rd, rn, rm);
9759 }
9760
shasx(Condition cond,Register rd,Register rn,Register rm)9761 void Assembler::shasx(Condition cond, Register rd, Register rn, Register rm) {
9762 VIXL_ASSERT(AllowAssembler());
9763 CheckIT(cond);
9764 if (IsUsingT32()) {
9765 // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9766 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9767 EmitT32_32(0xfaa0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9768 rm.GetCode());
9769 AdvanceIT();
9770 return;
9771 }
9772 } else {
9773 // SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9774 if (cond.IsNotNever() &&
9775 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9776 EmitA32(0x06300f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9777 (rn.GetCode() << 16) | rm.GetCode());
9778 return;
9779 }
9780 }
9781 Delegate(kShasx, &Assembler::shasx, cond, rd, rn, rm);
9782 }
9783
shsax(Condition cond,Register rd,Register rn,Register rm)9784 void Assembler::shsax(Condition cond, Register rd, Register rn, Register rm) {
9785 VIXL_ASSERT(AllowAssembler());
9786 CheckIT(cond);
9787 if (IsUsingT32()) {
9788 // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9789 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9790 EmitT32_32(0xfae0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9791 rm.GetCode());
9792 AdvanceIT();
9793 return;
9794 }
9795 } else {
9796 // SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9797 if (cond.IsNotNever() &&
9798 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9799 EmitA32(0x06300f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9800 (rn.GetCode() << 16) | rm.GetCode());
9801 return;
9802 }
9803 }
9804 Delegate(kShsax, &Assembler::shsax, cond, rd, rn, rm);
9805 }
9806
shsub16(Condition cond,Register rd,Register rn,Register rm)9807 void Assembler::shsub16(Condition cond, Register rd, Register rn, Register rm) {
9808 VIXL_ASSERT(AllowAssembler());
9809 CheckIT(cond);
9810 if (IsUsingT32()) {
9811 // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9812 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9813 EmitT32_32(0xfad0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9814 rm.GetCode());
9815 AdvanceIT();
9816 return;
9817 }
9818 } else {
9819 // SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9820 if (cond.IsNotNever() &&
9821 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9822 EmitA32(0x06300f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9823 (rn.GetCode() << 16) | rm.GetCode());
9824 return;
9825 }
9826 }
9827 Delegate(kShsub16, &Assembler::shsub16, cond, rd, rn, rm);
9828 }
9829
shsub8(Condition cond,Register rd,Register rn,Register rm)9830 void Assembler::shsub8(Condition cond, Register rd, Register rn, Register rm) {
9831 VIXL_ASSERT(AllowAssembler());
9832 CheckIT(cond);
9833 if (IsUsingT32()) {
9834 // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
9835 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9836 EmitT32_32(0xfac0f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9837 rm.GetCode());
9838 AdvanceIT();
9839 return;
9840 }
9841 } else {
9842 // SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
9843 if (cond.IsNotNever() &&
9844 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9845 EmitA32(0x06300ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
9846 (rn.GetCode() << 16) | rm.GetCode());
9847 return;
9848 }
9849 }
9850 Delegate(kShsub8, &Assembler::shsub8, cond, rd, rn, rm);
9851 }
9852
smlabb(Condition cond,Register rd,Register rn,Register rm,Register ra)9853 void Assembler::smlabb(
9854 Condition cond, Register rd, Register rn, Register rm, Register ra) {
9855 VIXL_ASSERT(AllowAssembler());
9856 CheckIT(cond);
9857 if (IsUsingT32()) {
9858 // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9859 if (!ra.Is(pc) &&
9860 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9861 EmitT32_32(0xfb100000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9862 rm.GetCode() | (ra.GetCode() << 12));
9863 AdvanceIT();
9864 return;
9865 }
9866 } else {
9867 // SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9868 if (cond.IsNotNever() &&
9869 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
9870 AllowUnpredictable())) {
9871 EmitA32(0x01000080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9872 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9873 return;
9874 }
9875 }
9876 Delegate(kSmlabb, &Assembler::smlabb, cond, rd, rn, rm, ra);
9877 }
9878
smlabt(Condition cond,Register rd,Register rn,Register rm,Register ra)9879 void Assembler::smlabt(
9880 Condition cond, Register rd, Register rn, Register rm, Register ra) {
9881 VIXL_ASSERT(AllowAssembler());
9882 CheckIT(cond);
9883 if (IsUsingT32()) {
9884 // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9885 if (!ra.Is(pc) &&
9886 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9887 EmitT32_32(0xfb100010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9888 rm.GetCode() | (ra.GetCode() << 12));
9889 AdvanceIT();
9890 return;
9891 }
9892 } else {
9893 // SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9894 if (cond.IsNotNever() &&
9895 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
9896 AllowUnpredictable())) {
9897 EmitA32(0x010000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9898 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9899 return;
9900 }
9901 }
9902 Delegate(kSmlabt, &Assembler::smlabt, cond, rd, rn, rm, ra);
9903 }
9904
smlad(Condition cond,Register rd,Register rn,Register rm,Register ra)9905 void Assembler::smlad(
9906 Condition cond, Register rd, Register rn, Register rm, Register ra) {
9907 VIXL_ASSERT(AllowAssembler());
9908 CheckIT(cond);
9909 if (IsUsingT32()) {
9910 // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9911 if (!ra.Is(pc) &&
9912 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9913 EmitT32_32(0xfb200000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9914 rm.GetCode() | (ra.GetCode() << 12));
9915 AdvanceIT();
9916 return;
9917 }
9918 } else {
9919 // SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9920 if (cond.IsNotNever() && !ra.Is(pc) &&
9921 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9922 EmitA32(0x07000010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9923 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9924 return;
9925 }
9926 }
9927 Delegate(kSmlad, &Assembler::smlad, cond, rd, rn, rm, ra);
9928 }
9929
smladx(Condition cond,Register rd,Register rn,Register rm,Register ra)9930 void Assembler::smladx(
9931 Condition cond, Register rd, Register rn, Register rm, Register ra) {
9932 VIXL_ASSERT(AllowAssembler());
9933 CheckIT(cond);
9934 if (IsUsingT32()) {
9935 // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
9936 if (!ra.Is(pc) &&
9937 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9938 EmitT32_32(0xfb200010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
9939 rm.GetCode() | (ra.GetCode() << 12));
9940 AdvanceIT();
9941 return;
9942 }
9943 } else {
9944 // SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
9945 if (cond.IsNotNever() && !ra.Is(pc) &&
9946 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
9947 EmitA32(0x07000030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
9948 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
9949 return;
9950 }
9951 }
9952 Delegate(kSmladx, &Assembler::smladx, cond, rd, rn, rm, ra);
9953 }
9954
smlal(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9955 void Assembler::smlal(
9956 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9957 VIXL_ASSERT(AllowAssembler());
9958 CheckIT(cond);
9959 if (IsUsingT32()) {
9960 // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9961 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
9962 AllowUnpredictable())) {
9963 EmitT32_32(0xfbc00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9964 (rn.GetCode() << 16) | rm.GetCode());
9965 AdvanceIT();
9966 return;
9967 }
9968 } else {
9969 // SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9970 if (cond.IsNotNever() &&
9971 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
9972 AllowUnpredictable())) {
9973 EmitA32(0x00e00090U | (cond.GetCondition() << 28) |
9974 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
9975 (rm.GetCode() << 8));
9976 return;
9977 }
9978 }
9979 Delegate(kSmlal, &Assembler::smlal, cond, rdlo, rdhi, rn, rm);
9980 }
9981
smlalbb(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)9982 void Assembler::smlalbb(
9983 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
9984 VIXL_ASSERT(AllowAssembler());
9985 CheckIT(cond);
9986 if (IsUsingT32()) {
9987 // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
9988 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
9989 AllowUnpredictable())) {
9990 EmitT32_32(0xfbc00080U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
9991 (rn.GetCode() << 16) | rm.GetCode());
9992 AdvanceIT();
9993 return;
9994 }
9995 } else {
9996 // SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
9997 if (cond.IsNotNever() &&
9998 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
9999 AllowUnpredictable())) {
10000 EmitA32(0x01400080U | (cond.GetCondition() << 28) |
10001 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10002 (rm.GetCode() << 8));
10003 return;
10004 }
10005 }
10006 Delegate(kSmlalbb, &Assembler::smlalbb, cond, rdlo, rdhi, rn, rm);
10007 }
10008
smlalbt(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10009 void Assembler::smlalbt(
10010 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10011 VIXL_ASSERT(AllowAssembler());
10012 CheckIT(cond);
10013 if (IsUsingT32()) {
10014 // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10015 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10016 AllowUnpredictable())) {
10017 EmitT32_32(0xfbc00090U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10018 (rn.GetCode() << 16) | rm.GetCode());
10019 AdvanceIT();
10020 return;
10021 }
10022 } else {
10023 // SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10024 if (cond.IsNotNever() &&
10025 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10026 AllowUnpredictable())) {
10027 EmitA32(0x014000c0U | (cond.GetCondition() << 28) |
10028 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10029 (rm.GetCode() << 8));
10030 return;
10031 }
10032 }
10033 Delegate(kSmlalbt, &Assembler::smlalbt, cond, rdlo, rdhi, rn, rm);
10034 }
10035
smlald(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10036 void Assembler::smlald(
10037 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10038 VIXL_ASSERT(AllowAssembler());
10039 CheckIT(cond);
10040 if (IsUsingT32()) {
10041 // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10042 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10043 AllowUnpredictable())) {
10044 EmitT32_32(0xfbc000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10045 (rn.GetCode() << 16) | rm.GetCode());
10046 AdvanceIT();
10047 return;
10048 }
10049 } else {
10050 // SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10051 if (cond.IsNotNever() &&
10052 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10053 AllowUnpredictable())) {
10054 EmitA32(0x07400010U | (cond.GetCondition() << 28) |
10055 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10056 (rm.GetCode() << 8));
10057 return;
10058 }
10059 }
10060 Delegate(kSmlald, &Assembler::smlald, cond, rdlo, rdhi, rn, rm);
10061 }
10062
smlaldx(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10063 void Assembler::smlaldx(
10064 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10065 VIXL_ASSERT(AllowAssembler());
10066 CheckIT(cond);
10067 if (IsUsingT32()) {
10068 // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10069 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10070 AllowUnpredictable())) {
10071 EmitT32_32(0xfbc000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10072 (rn.GetCode() << 16) | rm.GetCode());
10073 AdvanceIT();
10074 return;
10075 }
10076 } else {
10077 // SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10078 if (cond.IsNotNever() &&
10079 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10080 AllowUnpredictable())) {
10081 EmitA32(0x07400030U | (cond.GetCondition() << 28) |
10082 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10083 (rm.GetCode() << 8));
10084 return;
10085 }
10086 }
10087 Delegate(kSmlaldx, &Assembler::smlaldx, cond, rdlo, rdhi, rn, rm);
10088 }
10089
smlals(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10090 void Assembler::smlals(
10091 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10092 VIXL_ASSERT(AllowAssembler());
10093 CheckIT(cond);
10094 if (IsUsingA32()) {
10095 // SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10096 if (cond.IsNotNever() &&
10097 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10098 AllowUnpredictable())) {
10099 EmitA32(0x00f00090U | (cond.GetCondition() << 28) |
10100 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10101 (rm.GetCode() << 8));
10102 return;
10103 }
10104 }
10105 Delegate(kSmlals, &Assembler::smlals, cond, rdlo, rdhi, rn, rm);
10106 }
10107
smlaltb(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10108 void Assembler::smlaltb(
10109 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10110 VIXL_ASSERT(AllowAssembler());
10111 CheckIT(cond);
10112 if (IsUsingT32()) {
10113 // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10114 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10115 AllowUnpredictable())) {
10116 EmitT32_32(0xfbc000a0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10117 (rn.GetCode() << 16) | rm.GetCode());
10118 AdvanceIT();
10119 return;
10120 }
10121 } else {
10122 // SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10123 if (cond.IsNotNever() &&
10124 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10125 AllowUnpredictable())) {
10126 EmitA32(0x014000a0U | (cond.GetCondition() << 28) |
10127 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10128 (rm.GetCode() << 8));
10129 return;
10130 }
10131 }
10132 Delegate(kSmlaltb, &Assembler::smlaltb, cond, rdlo, rdhi, rn, rm);
10133 }
10134
smlaltt(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10135 void Assembler::smlaltt(
10136 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10137 VIXL_ASSERT(AllowAssembler());
10138 CheckIT(cond);
10139 if (IsUsingT32()) {
10140 // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10141 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10142 AllowUnpredictable())) {
10143 EmitT32_32(0xfbc000b0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10144 (rn.GetCode() << 16) | rm.GetCode());
10145 AdvanceIT();
10146 return;
10147 }
10148 } else {
10149 // SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10150 if (cond.IsNotNever() &&
10151 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10152 AllowUnpredictable())) {
10153 EmitA32(0x014000e0U | (cond.GetCondition() << 28) |
10154 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10155 (rm.GetCode() << 8));
10156 return;
10157 }
10158 }
10159 Delegate(kSmlaltt, &Assembler::smlaltt, cond, rdlo, rdhi, rn, rm);
10160 }
10161
smlatb(Condition cond,Register rd,Register rn,Register rm,Register ra)10162 void Assembler::smlatb(
10163 Condition cond, Register rd, Register rn, Register rm, Register ra) {
10164 VIXL_ASSERT(AllowAssembler());
10165 CheckIT(cond);
10166 if (IsUsingT32()) {
10167 // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10168 if (!ra.Is(pc) &&
10169 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10170 EmitT32_32(0xfb100020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10171 rm.GetCode() | (ra.GetCode() << 12));
10172 AdvanceIT();
10173 return;
10174 }
10175 } else {
10176 // SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10177 if (cond.IsNotNever() &&
10178 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10179 AllowUnpredictable())) {
10180 EmitA32(0x010000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10181 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10182 return;
10183 }
10184 }
10185 Delegate(kSmlatb, &Assembler::smlatb, cond, rd, rn, rm, ra);
10186 }
10187
smlatt(Condition cond,Register rd,Register rn,Register rm,Register ra)10188 void Assembler::smlatt(
10189 Condition cond, Register rd, Register rn, Register rm, Register ra) {
10190 VIXL_ASSERT(AllowAssembler());
10191 CheckIT(cond);
10192 if (IsUsingT32()) {
10193 // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10194 if (!ra.Is(pc) &&
10195 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10196 EmitT32_32(0xfb100030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10197 rm.GetCode() | (ra.GetCode() << 12));
10198 AdvanceIT();
10199 return;
10200 }
10201 } else {
10202 // SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10203 if (cond.IsNotNever() &&
10204 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10205 AllowUnpredictable())) {
10206 EmitA32(0x010000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10207 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10208 return;
10209 }
10210 }
10211 Delegate(kSmlatt, &Assembler::smlatt, cond, rd, rn, rm, ra);
10212 }
10213
smlawb(Condition cond,Register rd,Register rn,Register rm,Register ra)10214 void Assembler::smlawb(
10215 Condition cond, Register rd, Register rn, Register rm, Register ra) {
10216 VIXL_ASSERT(AllowAssembler());
10217 CheckIT(cond);
10218 if (IsUsingT32()) {
10219 // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10220 if (!ra.Is(pc) &&
10221 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10222 EmitT32_32(0xfb300000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10223 rm.GetCode() | (ra.GetCode() << 12));
10224 AdvanceIT();
10225 return;
10226 }
10227 } else {
10228 // SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10229 if (cond.IsNotNever() &&
10230 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10231 AllowUnpredictable())) {
10232 EmitA32(0x01200080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10233 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10234 return;
10235 }
10236 }
10237 Delegate(kSmlawb, &Assembler::smlawb, cond, rd, rn, rm, ra);
10238 }
10239
smlawt(Condition cond,Register rd,Register rn,Register rm,Register ra)10240 void Assembler::smlawt(
10241 Condition cond, Register rd, Register rn, Register rm, Register ra) {
10242 VIXL_ASSERT(AllowAssembler());
10243 CheckIT(cond);
10244 if (IsUsingT32()) {
10245 // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10246 if (!ra.Is(pc) &&
10247 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10248 EmitT32_32(0xfb300010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10249 rm.GetCode() | (ra.GetCode() << 12));
10250 AdvanceIT();
10251 return;
10252 }
10253 } else {
10254 // SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10255 if (cond.IsNotNever() &&
10256 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10257 AllowUnpredictable())) {
10258 EmitA32(0x012000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10259 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10260 return;
10261 }
10262 }
10263 Delegate(kSmlawt, &Assembler::smlawt, cond, rd, rn, rm, ra);
10264 }
10265
smlsd(Condition cond,Register rd,Register rn,Register rm,Register ra)10266 void Assembler::smlsd(
10267 Condition cond, Register rd, Register rn, Register rm, Register ra) {
10268 VIXL_ASSERT(AllowAssembler());
10269 CheckIT(cond);
10270 if (IsUsingT32()) {
10271 // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10272 if (!ra.Is(pc) &&
10273 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10274 EmitT32_32(0xfb400000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10275 rm.GetCode() | (ra.GetCode() << 12));
10276 AdvanceIT();
10277 return;
10278 }
10279 } else {
10280 // SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10281 if (cond.IsNotNever() && !ra.Is(pc) &&
10282 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10283 EmitA32(0x07000050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10284 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10285 return;
10286 }
10287 }
10288 Delegate(kSmlsd, &Assembler::smlsd, cond, rd, rn, rm, ra);
10289 }
10290
smlsdx(Condition cond,Register rd,Register rn,Register rm,Register ra)10291 void Assembler::smlsdx(
10292 Condition cond, Register rd, Register rn, Register rm, Register ra) {
10293 VIXL_ASSERT(AllowAssembler());
10294 CheckIT(cond);
10295 if (IsUsingT32()) {
10296 // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10297 if (!ra.Is(pc) &&
10298 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10299 EmitT32_32(0xfb400010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10300 rm.GetCode() | (ra.GetCode() << 12));
10301 AdvanceIT();
10302 return;
10303 }
10304 } else {
10305 // SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10306 if (cond.IsNotNever() && !ra.Is(pc) &&
10307 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10308 EmitA32(0x07000070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10309 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10310 return;
10311 }
10312 }
10313 Delegate(kSmlsdx, &Assembler::smlsdx, cond, rd, rn, rm, ra);
10314 }
10315
smlsld(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10316 void Assembler::smlsld(
10317 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10318 VIXL_ASSERT(AllowAssembler());
10319 CheckIT(cond);
10320 if (IsUsingT32()) {
10321 // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10322 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10323 AllowUnpredictable())) {
10324 EmitT32_32(0xfbd000c0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10325 (rn.GetCode() << 16) | rm.GetCode());
10326 AdvanceIT();
10327 return;
10328 }
10329 } else {
10330 // SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10331 if (cond.IsNotNever() &&
10332 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10333 AllowUnpredictable())) {
10334 EmitA32(0x07400050U | (cond.GetCondition() << 28) |
10335 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10336 (rm.GetCode() << 8));
10337 return;
10338 }
10339 }
10340 Delegate(kSmlsld, &Assembler::smlsld, cond, rdlo, rdhi, rn, rm);
10341 }
10342
smlsldx(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10343 void Assembler::smlsldx(
10344 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10345 VIXL_ASSERT(AllowAssembler());
10346 CheckIT(cond);
10347 if (IsUsingT32()) {
10348 // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10349 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10350 AllowUnpredictable())) {
10351 EmitT32_32(0xfbd000d0U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10352 (rn.GetCode() << 16) | rm.GetCode());
10353 AdvanceIT();
10354 return;
10355 }
10356 } else {
10357 // SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10358 if (cond.IsNotNever() &&
10359 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10360 AllowUnpredictable())) {
10361 EmitA32(0x07400070U | (cond.GetCondition() << 28) |
10362 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10363 (rm.GetCode() << 8));
10364 return;
10365 }
10366 }
10367 Delegate(kSmlsldx, &Assembler::smlsldx, cond, rdlo, rdhi, rn, rm);
10368 }
10369
smmla(Condition cond,Register rd,Register rn,Register rm,Register ra)10370 void Assembler::smmla(
10371 Condition cond, Register rd, Register rn, Register rm, Register ra) {
10372 VIXL_ASSERT(AllowAssembler());
10373 CheckIT(cond);
10374 if (IsUsingT32()) {
10375 // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10376 if (!ra.Is(pc) &&
10377 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10378 EmitT32_32(0xfb500000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10379 rm.GetCode() | (ra.GetCode() << 12));
10380 AdvanceIT();
10381 return;
10382 }
10383 } else {
10384 // SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10385 if (cond.IsNotNever() && !ra.Is(pc) &&
10386 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10387 EmitA32(0x07500010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10388 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10389 return;
10390 }
10391 }
10392 Delegate(kSmmla, &Assembler::smmla, cond, rd, rn, rm, ra);
10393 }
10394
smmlar(Condition cond,Register rd,Register rn,Register rm,Register ra)10395 void Assembler::smmlar(
10396 Condition cond, Register rd, Register rn, Register rm, Register ra) {
10397 VIXL_ASSERT(AllowAssembler());
10398 CheckIT(cond);
10399 if (IsUsingT32()) {
10400 // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10401 if (!ra.Is(pc) &&
10402 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10403 EmitT32_32(0xfb500010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10404 rm.GetCode() | (ra.GetCode() << 12));
10405 AdvanceIT();
10406 return;
10407 }
10408 } else {
10409 // SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10410 if (cond.IsNotNever() && !ra.Is(pc) &&
10411 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10412 EmitA32(0x07500030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10413 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10414 return;
10415 }
10416 }
10417 Delegate(kSmmlar, &Assembler::smmlar, cond, rd, rn, rm, ra);
10418 }
10419
smmls(Condition cond,Register rd,Register rn,Register rm,Register ra)10420 void Assembler::smmls(
10421 Condition cond, Register rd, Register rn, Register rm, Register ra) {
10422 VIXL_ASSERT(AllowAssembler());
10423 CheckIT(cond);
10424 if (IsUsingT32()) {
10425 // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10426 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10427 AllowUnpredictable())) {
10428 EmitT32_32(0xfb600000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10429 rm.GetCode() | (ra.GetCode() << 12));
10430 AdvanceIT();
10431 return;
10432 }
10433 } else {
10434 // SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10435 if (cond.IsNotNever() &&
10436 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10437 AllowUnpredictable())) {
10438 EmitA32(0x075000d0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10439 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10440 return;
10441 }
10442 }
10443 Delegate(kSmmls, &Assembler::smmls, cond, rd, rn, rm, ra);
10444 }
10445
smmlsr(Condition cond,Register rd,Register rn,Register rm,Register ra)10446 void Assembler::smmlsr(
10447 Condition cond, Register rd, Register rn, Register rm, Register ra) {
10448 VIXL_ASSERT(AllowAssembler());
10449 CheckIT(cond);
10450 if (IsUsingT32()) {
10451 // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
10452 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10453 AllowUnpredictable())) {
10454 EmitT32_32(0xfb600010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10455 rm.GetCode() | (ra.GetCode() << 12));
10456 AdvanceIT();
10457 return;
10458 }
10459 } else {
10460 // SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
10461 if (cond.IsNotNever() &&
10462 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !ra.IsPC()) ||
10463 AllowUnpredictable())) {
10464 EmitA32(0x075000f0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10465 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
10466 return;
10467 }
10468 }
10469 Delegate(kSmmlsr, &Assembler::smmlsr, cond, rd, rn, rm, ra);
10470 }
10471
smmul(Condition cond,Register rd,Register rn,Register rm)10472 void Assembler::smmul(Condition cond, Register rd, Register rn, Register rm) {
10473 VIXL_ASSERT(AllowAssembler());
10474 CheckIT(cond);
10475 if (IsUsingT32()) {
10476 // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10477 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10478 EmitT32_32(0xfb50f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10479 rm.GetCode());
10480 AdvanceIT();
10481 return;
10482 }
10483 } else {
10484 // SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10485 if (cond.IsNotNever() &&
10486 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10487 EmitA32(0x0750f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10488 rn.GetCode() | (rm.GetCode() << 8));
10489 return;
10490 }
10491 }
10492 Delegate(kSmmul, &Assembler::smmul, cond, rd, rn, rm);
10493 }
10494
smmulr(Condition cond,Register rd,Register rn,Register rm)10495 void Assembler::smmulr(Condition cond, Register rd, Register rn, Register rm) {
10496 VIXL_ASSERT(AllowAssembler());
10497 CheckIT(cond);
10498 if (IsUsingT32()) {
10499 // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10500 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10501 EmitT32_32(0xfb50f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10502 rm.GetCode());
10503 AdvanceIT();
10504 return;
10505 }
10506 } else {
10507 // SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10508 if (cond.IsNotNever() &&
10509 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10510 EmitA32(0x0750f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10511 rn.GetCode() | (rm.GetCode() << 8));
10512 return;
10513 }
10514 }
10515 Delegate(kSmmulr, &Assembler::smmulr, cond, rd, rn, rm);
10516 }
10517
smuad(Condition cond,Register rd,Register rn,Register rm)10518 void Assembler::smuad(Condition cond, Register rd, Register rn, Register rm) {
10519 VIXL_ASSERT(AllowAssembler());
10520 CheckIT(cond);
10521 if (IsUsingT32()) {
10522 // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10523 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10524 EmitT32_32(0xfb20f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10525 rm.GetCode());
10526 AdvanceIT();
10527 return;
10528 }
10529 } else {
10530 // SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10531 if (cond.IsNotNever() &&
10532 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10533 EmitA32(0x0700f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10534 rn.GetCode() | (rm.GetCode() << 8));
10535 return;
10536 }
10537 }
10538 Delegate(kSmuad, &Assembler::smuad, cond, rd, rn, rm);
10539 }
10540
smuadx(Condition cond,Register rd,Register rn,Register rm)10541 void Assembler::smuadx(Condition cond, Register rd, Register rn, Register rm) {
10542 VIXL_ASSERT(AllowAssembler());
10543 CheckIT(cond);
10544 if (IsUsingT32()) {
10545 // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10546 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10547 EmitT32_32(0xfb20f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10548 rm.GetCode());
10549 AdvanceIT();
10550 return;
10551 }
10552 } else {
10553 // SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10554 if (cond.IsNotNever() &&
10555 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10556 EmitA32(0x0700f030U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10557 rn.GetCode() | (rm.GetCode() << 8));
10558 return;
10559 }
10560 }
10561 Delegate(kSmuadx, &Assembler::smuadx, cond, rd, rn, rm);
10562 }
10563
smulbb(Condition cond,Register rd,Register rn,Register rm)10564 void Assembler::smulbb(Condition cond, Register rd, Register rn, Register rm) {
10565 VIXL_ASSERT(AllowAssembler());
10566 CheckIT(cond);
10567 if (IsUsingT32()) {
10568 // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10569 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10570 EmitT32_32(0xfb10f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10571 rm.GetCode());
10572 AdvanceIT();
10573 return;
10574 }
10575 } else {
10576 // SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10577 if (cond.IsNotNever() &&
10578 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10579 EmitA32(0x01600080U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10580 rn.GetCode() | (rm.GetCode() << 8));
10581 return;
10582 }
10583 }
10584 Delegate(kSmulbb, &Assembler::smulbb, cond, rd, rn, rm);
10585 }
10586
smulbt(Condition cond,Register rd,Register rn,Register rm)10587 void Assembler::smulbt(Condition cond, Register rd, Register rn, Register rm) {
10588 VIXL_ASSERT(AllowAssembler());
10589 CheckIT(cond);
10590 if (IsUsingT32()) {
10591 // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10592 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10593 EmitT32_32(0xfb10f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10594 rm.GetCode());
10595 AdvanceIT();
10596 return;
10597 }
10598 } else {
10599 // SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10600 if (cond.IsNotNever() &&
10601 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10602 EmitA32(0x016000c0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10603 rn.GetCode() | (rm.GetCode() << 8));
10604 return;
10605 }
10606 }
10607 Delegate(kSmulbt, &Assembler::smulbt, cond, rd, rn, rm);
10608 }
10609
smull(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10610 void Assembler::smull(
10611 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10612 VIXL_ASSERT(AllowAssembler());
10613 CheckIT(cond);
10614 if (IsUsingT32()) {
10615 // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
10616 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10617 AllowUnpredictable())) {
10618 EmitT32_32(0xfb800000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
10619 (rn.GetCode() << 16) | rm.GetCode());
10620 AdvanceIT();
10621 return;
10622 }
10623 } else {
10624 // SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10625 if (cond.IsNotNever() &&
10626 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10627 AllowUnpredictable())) {
10628 EmitA32(0x00c00090U | (cond.GetCondition() << 28) |
10629 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10630 (rm.GetCode() << 8));
10631 return;
10632 }
10633 }
10634 Delegate(kSmull, &Assembler::smull, cond, rdlo, rdhi, rn, rm);
10635 }
10636
smulls(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)10637 void Assembler::smulls(
10638 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
10639 VIXL_ASSERT(AllowAssembler());
10640 CheckIT(cond);
10641 if (IsUsingA32()) {
10642 // SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
10643 if (cond.IsNotNever() &&
10644 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
10645 AllowUnpredictable())) {
10646 EmitA32(0x00d00090U | (cond.GetCondition() << 28) |
10647 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
10648 (rm.GetCode() << 8));
10649 return;
10650 }
10651 }
10652 Delegate(kSmulls, &Assembler::smulls, cond, rdlo, rdhi, rn, rm);
10653 }
10654
smultb(Condition cond,Register rd,Register rn,Register rm)10655 void Assembler::smultb(Condition cond, Register rd, Register rn, Register rm) {
10656 VIXL_ASSERT(AllowAssembler());
10657 CheckIT(cond);
10658 if (IsUsingT32()) {
10659 // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10660 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10661 EmitT32_32(0xfb10f020U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10662 rm.GetCode());
10663 AdvanceIT();
10664 return;
10665 }
10666 } else {
10667 // SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10668 if (cond.IsNotNever() &&
10669 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10670 EmitA32(0x016000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10671 rn.GetCode() | (rm.GetCode() << 8));
10672 return;
10673 }
10674 }
10675 Delegate(kSmultb, &Assembler::smultb, cond, rd, rn, rm);
10676 }
10677
smultt(Condition cond,Register rd,Register rn,Register rm)10678 void Assembler::smultt(Condition cond, Register rd, Register rn, Register rm) {
10679 VIXL_ASSERT(AllowAssembler());
10680 CheckIT(cond);
10681 if (IsUsingT32()) {
10682 // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10683 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10684 EmitT32_32(0xfb10f030U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10685 rm.GetCode());
10686 AdvanceIT();
10687 return;
10688 }
10689 } else {
10690 // SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10691 if (cond.IsNotNever() &&
10692 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10693 EmitA32(0x016000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10694 rn.GetCode() | (rm.GetCode() << 8));
10695 return;
10696 }
10697 }
10698 Delegate(kSmultt, &Assembler::smultt, cond, rd, rn, rm);
10699 }
10700
smulwb(Condition cond,Register rd,Register rn,Register rm)10701 void Assembler::smulwb(Condition cond, Register rd, Register rn, Register rm) {
10702 VIXL_ASSERT(AllowAssembler());
10703 CheckIT(cond);
10704 if (IsUsingT32()) {
10705 // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10706 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10707 EmitT32_32(0xfb30f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10708 rm.GetCode());
10709 AdvanceIT();
10710 return;
10711 }
10712 } else {
10713 // SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10714 if (cond.IsNotNever() &&
10715 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10716 EmitA32(0x012000a0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10717 rn.GetCode() | (rm.GetCode() << 8));
10718 return;
10719 }
10720 }
10721 Delegate(kSmulwb, &Assembler::smulwb, cond, rd, rn, rm);
10722 }
10723
smulwt(Condition cond,Register rd,Register rn,Register rm)10724 void Assembler::smulwt(Condition cond, Register rd, Register rn, Register rm) {
10725 VIXL_ASSERT(AllowAssembler());
10726 CheckIT(cond);
10727 if (IsUsingT32()) {
10728 // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10729 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10730 EmitT32_32(0xfb30f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10731 rm.GetCode());
10732 AdvanceIT();
10733 return;
10734 }
10735 } else {
10736 // SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10737 if (cond.IsNotNever() &&
10738 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10739 EmitA32(0x012000e0U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10740 rn.GetCode() | (rm.GetCode() << 8));
10741 return;
10742 }
10743 }
10744 Delegate(kSmulwt, &Assembler::smulwt, cond, rd, rn, rm);
10745 }
10746
smusd(Condition cond,Register rd,Register rn,Register rm)10747 void Assembler::smusd(Condition cond, Register rd, Register rn, Register rm) {
10748 VIXL_ASSERT(AllowAssembler());
10749 CheckIT(cond);
10750 if (IsUsingT32()) {
10751 // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10752 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10753 EmitT32_32(0xfb40f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10754 rm.GetCode());
10755 AdvanceIT();
10756 return;
10757 }
10758 } else {
10759 // SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10760 if (cond.IsNotNever() &&
10761 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10762 EmitA32(0x0700f050U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10763 rn.GetCode() | (rm.GetCode() << 8));
10764 return;
10765 }
10766 }
10767 Delegate(kSmusd, &Assembler::smusd, cond, rd, rn, rm);
10768 }
10769
smusdx(Condition cond,Register rd,Register rn,Register rm)10770 void Assembler::smusdx(Condition cond, Register rd, Register rn, Register rm) {
10771 VIXL_ASSERT(AllowAssembler());
10772 CheckIT(cond);
10773 if (IsUsingT32()) {
10774 // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10775 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10776 EmitT32_32(0xfb40f010U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10777 rm.GetCode());
10778 AdvanceIT();
10779 return;
10780 }
10781 } else {
10782 // SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10783 if (cond.IsNotNever() &&
10784 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10785 EmitA32(0x0700f070U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
10786 rn.GetCode() | (rm.GetCode() << 8));
10787 return;
10788 }
10789 }
10790 Delegate(kSmusdx, &Assembler::smusdx, cond, rd, rn, rm);
10791 }
10792
ssat(Condition cond,Register rd,uint32_t imm,const Operand & operand)10793 void Assembler::ssat(Condition cond,
10794 Register rd,
10795 uint32_t imm,
10796 const Operand& operand) {
10797 VIXL_ASSERT(AllowAssembler());
10798 CheckIT(cond);
10799 if (operand.IsImmediateShiftedRegister()) {
10800 Register rn = operand.GetBaseRegister();
10801 Shift shift = operand.GetShift();
10802 uint32_t amount = operand.GetShiftAmount();
10803 if (IsUsingT32()) {
10804 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
10805 if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
10806 (amount <= 31) &&
10807 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10808 uint32_t imm_ = imm - 1;
10809 EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
10810 (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
10811 ((amount & 0x1c) << 10));
10812 AdvanceIT();
10813 return;
10814 }
10815 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
10816 if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
10817 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10818 uint32_t imm_ = imm - 1;
10819 EmitT32_32(0xf3000000U | (rd.GetCode() << 8) | imm_ |
10820 (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
10821 ((amount & 0x1c) << 10));
10822 AdvanceIT();
10823 return;
10824 }
10825 } else {
10826 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
10827 if ((imm >= 1) && (imm <= 32) && shift.IsASR() && (amount >= 1) &&
10828 (amount <= 32) && cond.IsNotNever() &&
10829 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10830 uint32_t imm_ = imm - 1;
10831 uint32_t amount_ = amount % 32;
10832 EmitA32(0x06a00050U | (cond.GetCondition() << 28) |
10833 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
10834 (amount_ << 7));
10835 return;
10836 }
10837 // SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
10838 if ((imm >= 1) && (imm <= 32) && shift.IsLSL() && (amount <= 31) &&
10839 cond.IsNotNever() &&
10840 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10841 uint32_t imm_ = imm - 1;
10842 EmitA32(0x06a00010U | (cond.GetCondition() << 28) |
10843 (rd.GetCode() << 12) | (imm_ << 16) | rn.GetCode() |
10844 (amount << 7));
10845 return;
10846 }
10847 }
10848 }
10849 Delegate(kSsat, &Assembler::ssat, cond, rd, imm, operand);
10850 }
10851
ssat16(Condition cond,Register rd,uint32_t imm,Register rn)10852 void Assembler::ssat16(Condition cond, Register rd, uint32_t imm, Register rn) {
10853 VIXL_ASSERT(AllowAssembler());
10854 CheckIT(cond);
10855 if (IsUsingT32()) {
10856 // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
10857 if ((imm >= 1) && (imm <= 16) &&
10858 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10859 uint32_t imm_ = imm - 1;
10860 EmitT32_32(0xf3200000U | (rd.GetCode() << 8) | imm_ |
10861 (rn.GetCode() << 16));
10862 AdvanceIT();
10863 return;
10864 }
10865 } else {
10866 // SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
10867 if ((imm >= 1) && (imm <= 16) && cond.IsNotNever() &&
10868 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10869 uint32_t imm_ = imm - 1;
10870 EmitA32(0x06a00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
10871 (imm_ << 16) | rn.GetCode());
10872 return;
10873 }
10874 }
10875 Delegate(kSsat16, &Assembler::ssat16, cond, rd, imm, rn);
10876 }
10877
ssax(Condition cond,Register rd,Register rn,Register rm)10878 void Assembler::ssax(Condition cond, Register rd, Register rn, Register rm) {
10879 VIXL_ASSERT(AllowAssembler());
10880 CheckIT(cond);
10881 if (IsUsingT32()) {
10882 // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10883 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10884 EmitT32_32(0xfae0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10885 rm.GetCode());
10886 AdvanceIT();
10887 return;
10888 }
10889 } else {
10890 // SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10891 if (cond.IsNotNever() &&
10892 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10893 EmitA32(0x06100f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
10894 (rn.GetCode() << 16) | rm.GetCode());
10895 return;
10896 }
10897 }
10898 Delegate(kSsax, &Assembler::ssax, cond, rd, rn, rm);
10899 }
10900
ssub16(Condition cond,Register rd,Register rn,Register rm)10901 void Assembler::ssub16(Condition cond, Register rd, Register rn, Register rm) {
10902 VIXL_ASSERT(AllowAssembler());
10903 CheckIT(cond);
10904 if (IsUsingT32()) {
10905 // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10906 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10907 EmitT32_32(0xfad0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10908 rm.GetCode());
10909 AdvanceIT();
10910 return;
10911 }
10912 } else {
10913 // SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10914 if (cond.IsNotNever() &&
10915 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10916 EmitA32(0x06100f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
10917 (rn.GetCode() << 16) | rm.GetCode());
10918 return;
10919 }
10920 }
10921 Delegate(kSsub16, &Assembler::ssub16, cond, rd, rn, rm);
10922 }
10923
ssub8(Condition cond,Register rd,Register rn,Register rm)10924 void Assembler::ssub8(Condition cond, Register rd, Register rn, Register rm) {
10925 VIXL_ASSERT(AllowAssembler());
10926 CheckIT(cond);
10927 if (IsUsingT32()) {
10928 // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
10929 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10930 EmitT32_32(0xfac0f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
10931 rm.GetCode());
10932 AdvanceIT();
10933 return;
10934 }
10935 } else {
10936 // SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
10937 if (cond.IsNotNever() &&
10938 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
10939 EmitA32(0x06100ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
10940 (rn.GetCode() << 16) | rm.GetCode());
10941 return;
10942 }
10943 }
10944 Delegate(kSsub8, &Assembler::ssub8, cond, rd, rn, rm);
10945 }
10946
stl(Condition cond,Register rt,const MemOperand & operand)10947 void Assembler::stl(Condition cond, Register rt, const MemOperand& operand) {
10948 VIXL_ASSERT(AllowAssembler());
10949 CheckIT(cond);
10950 if (operand.IsImmediateZero()) {
10951 Register rn = operand.GetBaseRegister();
10952 if (IsUsingT32()) {
10953 // STL{<c>}{<q>} <Rt>, [<Rn>] ; T1
10954 if (operand.IsOffset() &&
10955 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10956 EmitT32_32(0xe8c00fafU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
10957 AdvanceIT();
10958 return;
10959 }
10960 } else {
10961 // STL{<c>}{<q>} <Rt>, [<Rn>] ; A1
10962 if (operand.IsOffset() && cond.IsNotNever() &&
10963 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10964 EmitA32(0x0180fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
10965 (rn.GetCode() << 16));
10966 return;
10967 }
10968 }
10969 }
10970 Delegate(kStl, &Assembler::stl, cond, rt, operand);
10971 }
10972
stlb(Condition cond,Register rt,const MemOperand & operand)10973 void Assembler::stlb(Condition cond, Register rt, const MemOperand& operand) {
10974 VIXL_ASSERT(AllowAssembler());
10975 CheckIT(cond);
10976 if (operand.IsImmediateZero()) {
10977 Register rn = operand.GetBaseRegister();
10978 if (IsUsingT32()) {
10979 // STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1
10980 if (operand.IsOffset() &&
10981 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10982 EmitT32_32(0xe8c00f8fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
10983 AdvanceIT();
10984 return;
10985 }
10986 } else {
10987 // STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1
10988 if (operand.IsOffset() && cond.IsNotNever() &&
10989 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
10990 EmitA32(0x01c0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
10991 (rn.GetCode() << 16));
10992 return;
10993 }
10994 }
10995 }
10996 Delegate(kStlb, &Assembler::stlb, cond, rt, operand);
10997 }
10998
stlex(Condition cond,Register rd,Register rt,const MemOperand & operand)10999 void Assembler::stlex(Condition cond,
11000 Register rd,
11001 Register rt,
11002 const MemOperand& operand) {
11003 VIXL_ASSERT(AllowAssembler());
11004 CheckIT(cond);
11005 if (operand.IsImmediateZero()) {
11006 Register rn = operand.GetBaseRegister();
11007 if (IsUsingT32()) {
11008 // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
11009 if (operand.IsOffset() &&
11010 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11011 EmitT32_32(0xe8c00fe0U | rd.GetCode() | (rt.GetCode() << 12) |
11012 (rn.GetCode() << 16));
11013 AdvanceIT();
11014 return;
11015 }
11016 } else {
11017 // STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
11018 if (operand.IsOffset() && cond.IsNotNever() &&
11019 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11020 EmitA32(0x01800e90U | (cond.GetCondition() << 28) |
11021 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11022 return;
11023 }
11024 }
11025 }
11026 Delegate(kStlex, &Assembler::stlex, cond, rd, rt, operand);
11027 }
11028
stlexb(Condition cond,Register rd,Register rt,const MemOperand & operand)11029 void Assembler::stlexb(Condition cond,
11030 Register rd,
11031 Register rt,
11032 const MemOperand& operand) {
11033 VIXL_ASSERT(AllowAssembler());
11034 CheckIT(cond);
11035 if (operand.IsImmediateZero()) {
11036 Register rn = operand.GetBaseRegister();
11037 if (IsUsingT32()) {
11038 // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
11039 if (operand.IsOffset() &&
11040 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11041 EmitT32_32(0xe8c00fc0U | rd.GetCode() | (rt.GetCode() << 12) |
11042 (rn.GetCode() << 16));
11043 AdvanceIT();
11044 return;
11045 }
11046 } else {
11047 // STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
11048 if (operand.IsOffset() && cond.IsNotNever() &&
11049 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11050 EmitA32(0x01c00e90U | (cond.GetCondition() << 28) |
11051 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11052 return;
11053 }
11054 }
11055 }
11056 Delegate(kStlexb, &Assembler::stlexb, cond, rd, rt, operand);
11057 }
11058
stlexd(Condition cond,Register rd,Register rt,Register rt2,const MemOperand & operand)11059 void Assembler::stlexd(Condition cond,
11060 Register rd,
11061 Register rt,
11062 Register rt2,
11063 const MemOperand& operand) {
11064 VIXL_ASSERT(AllowAssembler());
11065 CheckIT(cond);
11066 if (operand.IsImmediateZero()) {
11067 Register rn = operand.GetBaseRegister();
11068 if (IsUsingT32()) {
11069 // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
11070 if (operand.IsOffset() &&
11071 ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) ||
11072 AllowUnpredictable())) {
11073 EmitT32_32(0xe8c000f0U | rd.GetCode() | (rt.GetCode() << 12) |
11074 (rt2.GetCode() << 8) | (rn.GetCode() << 16));
11075 AdvanceIT();
11076 return;
11077 }
11078 } else {
11079 // STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
11080 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11081 operand.IsOffset() && cond.IsNotNever() &&
11082 ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() &&
11083 !rn.IsPC()) ||
11084 AllowUnpredictable())) {
11085 EmitA32(0x01a00e90U | (cond.GetCondition() << 28) |
11086 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11087 return;
11088 }
11089 }
11090 }
11091 Delegate(kStlexd, &Assembler::stlexd, cond, rd, rt, rt2, operand);
11092 }
11093
stlexh(Condition cond,Register rd,Register rt,const MemOperand & operand)11094 void Assembler::stlexh(Condition cond,
11095 Register rd,
11096 Register rt,
11097 const MemOperand& operand) {
11098 VIXL_ASSERT(AllowAssembler());
11099 CheckIT(cond);
11100 if (operand.IsImmediateZero()) {
11101 Register rn = operand.GetBaseRegister();
11102 if (IsUsingT32()) {
11103 // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
11104 if (operand.IsOffset() &&
11105 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11106 EmitT32_32(0xe8c00fd0U | rd.GetCode() | (rt.GetCode() << 12) |
11107 (rn.GetCode() << 16));
11108 AdvanceIT();
11109 return;
11110 }
11111 } else {
11112 // STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
11113 if (operand.IsOffset() && cond.IsNotNever() &&
11114 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11115 EmitA32(0x01e00e90U | (cond.GetCondition() << 28) |
11116 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11117 return;
11118 }
11119 }
11120 }
11121 Delegate(kStlexh, &Assembler::stlexh, cond, rd, rt, operand);
11122 }
11123
stlh(Condition cond,Register rt,const MemOperand & operand)11124 void Assembler::stlh(Condition cond, Register rt, const MemOperand& operand) {
11125 VIXL_ASSERT(AllowAssembler());
11126 CheckIT(cond);
11127 if (operand.IsImmediateZero()) {
11128 Register rn = operand.GetBaseRegister();
11129 if (IsUsingT32()) {
11130 // STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1
11131 if (operand.IsOffset() &&
11132 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11133 EmitT32_32(0xe8c00f9fU | (rt.GetCode() << 12) | (rn.GetCode() << 16));
11134 AdvanceIT();
11135 return;
11136 }
11137 } else {
11138 // STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1
11139 if (operand.IsOffset() && cond.IsNotNever() &&
11140 ((!rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11141 EmitA32(0x01e0fc90U | (cond.GetCondition() << 28) | rt.GetCode() |
11142 (rn.GetCode() << 16));
11143 return;
11144 }
11145 }
11146 }
11147 Delegate(kStlh, &Assembler::stlh, cond, rt, operand);
11148 }
11149
stm(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)11150 void Assembler::stm(Condition cond,
11151 EncodingSize size,
11152 Register rn,
11153 WriteBack write_back,
11154 RegisterList registers) {
11155 VIXL_ASSERT(AllowAssembler());
11156 CheckIT(cond);
11157 if (IsUsingT32()) {
11158 // STM{<c>}{<q>} <Rn>!, <registers> ; T1
11159 if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
11160 ((registers.GetList() & ~0xff) == 0)) {
11161 EmitT32_16(0xc000 | (rn.GetCode() << 8) |
11162 GetRegisterListEncoding(registers, 0, 8));
11163 AdvanceIT();
11164 return;
11165 }
11166 // STM{<c>}{<q>} <Rn>{!}, <registers> ; T2
11167 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
11168 (!rn.IsPC() || AllowUnpredictable())) {
11169 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
11170 (write_back.GetWriteBackUint32() << 21) |
11171 (GetRegisterListEncoding(registers, 14, 1) << 14) |
11172 GetRegisterListEncoding(registers, 0, 13));
11173 AdvanceIT();
11174 return;
11175 }
11176 } else {
11177 // STM{<c>}{<q>} <Rn>{!}, <registers> ; A1
11178 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11179 EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11180 (write_back.GetWriteBackUint32() << 21) |
11181 GetRegisterListEncoding(registers, 0, 16));
11182 return;
11183 }
11184 }
11185 Delegate(kStm, &Assembler::stm, cond, size, rn, write_back, registers);
11186 }
11187
stmda(Condition cond,Register rn,WriteBack write_back,RegisterList registers)11188 void Assembler::stmda(Condition cond,
11189 Register rn,
11190 WriteBack write_back,
11191 RegisterList registers) {
11192 VIXL_ASSERT(AllowAssembler());
11193 CheckIT(cond);
11194 if (IsUsingA32()) {
11195 // STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
11196 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11197 EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11198 (write_back.GetWriteBackUint32() << 21) |
11199 GetRegisterListEncoding(registers, 0, 16));
11200 return;
11201 }
11202 }
11203 Delegate(kStmda, &Assembler::stmda, cond, rn, write_back, registers);
11204 }
11205
stmdb(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)11206 void Assembler::stmdb(Condition cond,
11207 EncodingSize size,
11208 Register rn,
11209 WriteBack write_back,
11210 RegisterList registers) {
11211 VIXL_ASSERT(AllowAssembler());
11212 CheckIT(cond);
11213 if (IsUsingT32()) {
11214 // STMDB{<c>}{<q>} SP!, <registers> ; T1
11215 if (!size.IsWide() && rn.Is(sp) && write_back.DoesWriteBack() &&
11216 registers.IsR0toR7orLR()) {
11217 EmitT32_16(0xb400 | (GetRegisterListEncoding(registers, 14, 1) << 8) |
11218 GetRegisterListEncoding(registers, 0, 8));
11219 AdvanceIT();
11220 return;
11221 }
11222 // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
11223 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
11224 (!rn.IsPC() || AllowUnpredictable())) {
11225 EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
11226 (write_back.GetWriteBackUint32() << 21) |
11227 (GetRegisterListEncoding(registers, 14, 1) << 14) |
11228 GetRegisterListEncoding(registers, 0, 13));
11229 AdvanceIT();
11230 return;
11231 }
11232 } else {
11233 // STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
11234 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11235 EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11236 (write_back.GetWriteBackUint32() << 21) |
11237 GetRegisterListEncoding(registers, 0, 16));
11238 return;
11239 }
11240 }
11241 Delegate(kStmdb, &Assembler::stmdb, cond, size, rn, write_back, registers);
11242 }
11243
stmea(Condition cond,EncodingSize size,Register rn,WriteBack write_back,RegisterList registers)11244 void Assembler::stmea(Condition cond,
11245 EncodingSize size,
11246 Register rn,
11247 WriteBack write_back,
11248 RegisterList registers) {
11249 VIXL_ASSERT(AllowAssembler());
11250 CheckIT(cond);
11251 if (IsUsingT32()) {
11252 // STMEA{<c>}{<q>} <Rn>!, <registers> ; T1
11253 if (!size.IsWide() && rn.IsLow() && write_back.DoesWriteBack() &&
11254 ((registers.GetList() & ~0xff) == 0)) {
11255 EmitT32_16(0xc000 | (rn.GetCode() << 8) |
11256 GetRegisterListEncoding(registers, 0, 8));
11257 AdvanceIT();
11258 return;
11259 }
11260 // STMEA{<c>}.W <Rn>{!}, <registers> ; T2
11261 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
11262 (!rn.IsPC() || AllowUnpredictable())) {
11263 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
11264 (write_back.GetWriteBackUint32() << 21) |
11265 (GetRegisterListEncoding(registers, 14, 1) << 14) |
11266 GetRegisterListEncoding(registers, 0, 13));
11267 AdvanceIT();
11268 return;
11269 }
11270 // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; T2
11271 if (!size.IsNarrow() && ((registers.GetList() & ~0x5fff) == 0) &&
11272 (!rn.IsPC() || AllowUnpredictable())) {
11273 EmitT32_32(0xe8800000U | (rn.GetCode() << 16) |
11274 (write_back.GetWriteBackUint32() << 21) |
11275 (GetRegisterListEncoding(registers, 14, 1) << 14) |
11276 GetRegisterListEncoding(registers, 0, 13));
11277 AdvanceIT();
11278 return;
11279 }
11280 } else {
11281 // STMEA{<c>}{<q>} <Rn>{!}, <registers> ; A1
11282 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11283 EmitA32(0x08800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11284 (write_back.GetWriteBackUint32() << 21) |
11285 GetRegisterListEncoding(registers, 0, 16));
11286 return;
11287 }
11288 }
11289 Delegate(kStmea, &Assembler::stmea, cond, size, rn, write_back, registers);
11290 }
11291
stmed(Condition cond,Register rn,WriteBack write_back,RegisterList registers)11292 void Assembler::stmed(Condition cond,
11293 Register rn,
11294 WriteBack write_back,
11295 RegisterList registers) {
11296 VIXL_ASSERT(AllowAssembler());
11297 CheckIT(cond);
11298 if (IsUsingA32()) {
11299 // STMED{<c>}{<q>} <Rn>{!}, <registers> ; A1
11300 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11301 EmitA32(0x08000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11302 (write_back.GetWriteBackUint32() << 21) |
11303 GetRegisterListEncoding(registers, 0, 16));
11304 return;
11305 }
11306 }
11307 Delegate(kStmed, &Assembler::stmed, cond, rn, write_back, registers);
11308 }
11309
stmfa(Condition cond,Register rn,WriteBack write_back,RegisterList registers)11310 void Assembler::stmfa(Condition cond,
11311 Register rn,
11312 WriteBack write_back,
11313 RegisterList registers) {
11314 VIXL_ASSERT(AllowAssembler());
11315 CheckIT(cond);
11316 if (IsUsingA32()) {
11317 // STMFA{<c>}{<q>} <Rn>{!}, <registers> ; A1
11318 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11319 EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11320 (write_back.GetWriteBackUint32() << 21) |
11321 GetRegisterListEncoding(registers, 0, 16));
11322 return;
11323 }
11324 }
11325 Delegate(kStmfa, &Assembler::stmfa, cond, rn, write_back, registers);
11326 }
11327
stmfd(Condition cond,Register rn,WriteBack write_back,RegisterList registers)11328 void Assembler::stmfd(Condition cond,
11329 Register rn,
11330 WriteBack write_back,
11331 RegisterList registers) {
11332 VIXL_ASSERT(AllowAssembler());
11333 CheckIT(cond);
11334 if (IsUsingT32()) {
11335 // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; T1
11336 if (((registers.GetList() & ~0x5fff) == 0) &&
11337 (!rn.IsPC() || AllowUnpredictable())) {
11338 EmitT32_32(0xe9000000U | (rn.GetCode() << 16) |
11339 (write_back.GetWriteBackUint32() << 21) |
11340 (GetRegisterListEncoding(registers, 14, 1) << 14) |
11341 GetRegisterListEncoding(registers, 0, 13));
11342 AdvanceIT();
11343 return;
11344 }
11345 } else {
11346 // STMFD{<c>}{<q>} <Rn>{!}, <registers> ; A1
11347 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11348 EmitA32(0x09000000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11349 (write_back.GetWriteBackUint32() << 21) |
11350 GetRegisterListEncoding(registers, 0, 16));
11351 return;
11352 }
11353 }
11354 Delegate(kStmfd, &Assembler::stmfd, cond, rn, write_back, registers);
11355 }
11356
stmib(Condition cond,Register rn,WriteBack write_back,RegisterList registers)11357 void Assembler::stmib(Condition cond,
11358 Register rn,
11359 WriteBack write_back,
11360 RegisterList registers) {
11361 VIXL_ASSERT(AllowAssembler());
11362 CheckIT(cond);
11363 if (IsUsingA32()) {
11364 // STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
11365 if (cond.IsNotNever() && (!rn.IsPC() || AllowUnpredictable())) {
11366 EmitA32(0x09800000U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
11367 (write_back.GetWriteBackUint32() << 21) |
11368 GetRegisterListEncoding(registers, 0, 16));
11369 return;
11370 }
11371 }
11372 Delegate(kStmib, &Assembler::stmib, cond, rn, write_back, registers);
11373 }
11374
str(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)11375 void Assembler::str(Condition cond,
11376 EncodingSize size,
11377 Register rt,
11378 const MemOperand& operand) {
11379 VIXL_ASSERT(AllowAssembler());
11380 CheckIT(cond);
11381 if (operand.IsImmediate()) {
11382 Register rn = operand.GetBaseRegister();
11383 int32_t offset = operand.GetOffsetImmediate();
11384 if (IsUsingT32()) {
11385 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
11386 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
11387 (offset <= 124) && ((offset % 4) == 0) && operand.IsOffset()) {
11388 int32_t offset_ = offset >> 2;
11389 EmitT32_16(0x6000 | rt.GetCode() | (rn.GetCode() << 3) |
11390 ((offset_ & 0x1f) << 6));
11391 AdvanceIT();
11392 return;
11393 }
11394 // STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
11395 if (!size.IsWide() && rt.IsLow() && (offset >= 0) && (offset <= 1020) &&
11396 ((offset % 4) == 0) && rn.Is(sp) && operand.IsOffset()) {
11397 int32_t offset_ = offset >> 2;
11398 EmitT32_16(0x9000 | (rt.GetCode() << 8) | (offset_ & 0xff));
11399 AdvanceIT();
11400 return;
11401 }
11402 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
11403 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
11404 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11405 (!rt.IsPC() || AllowUnpredictable())) {
11406 EmitT32_32(0xf8c00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11407 (offset & 0xfff));
11408 AdvanceIT();
11409 return;
11410 }
11411 // STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
11412 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
11413 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11414 (!rt.IsPC() || AllowUnpredictable())) {
11415 EmitT32_32(0xf8400c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11416 (-offset & 0xff));
11417 AdvanceIT();
11418 return;
11419 }
11420 // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
11421 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
11422 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11423 (!rt.IsPC() || AllowUnpredictable())) {
11424 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11425 uint32_t offset_ = abs(offset);
11426 EmitT32_32(0xf8400900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11427 offset_ | (sign << 9));
11428 AdvanceIT();
11429 return;
11430 }
11431 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
11432 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
11433 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11434 (!rt.IsPC() || AllowUnpredictable())) {
11435 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11436 uint32_t offset_ = abs(offset);
11437 EmitT32_32(0xf8400d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11438 offset_ | (sign << 9));
11439 AdvanceIT();
11440 return;
11441 }
11442 } else {
11443 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
11444 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
11445 cond.IsNotNever()) {
11446 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11447 uint32_t offset_ = abs(offset);
11448 EmitA32(0x05000000U | (cond.GetCondition() << 28) |
11449 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11450 (sign << 23));
11451 return;
11452 }
11453 // STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
11454 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
11455 cond.IsNotNever()) {
11456 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11457 uint32_t offset_ = abs(offset);
11458 EmitA32(0x04000000U | (cond.GetCondition() << 28) |
11459 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11460 (sign << 23));
11461 return;
11462 }
11463 // STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
11464 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
11465 cond.IsNotNever()) {
11466 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11467 uint32_t offset_ = abs(offset);
11468 EmitA32(0x05200000U | (cond.GetCondition() << 28) |
11469 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11470 (sign << 23));
11471 return;
11472 }
11473 }
11474 }
11475 if (operand.IsPlainRegister()) {
11476 Register rn = operand.GetBaseRegister();
11477 Sign sign = operand.GetSign();
11478 Register rm = operand.GetOffsetRegister();
11479 if (IsUsingT32()) {
11480 // STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
11481 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
11482 sign.IsPlus() && operand.IsOffset()) {
11483 EmitT32_16(0x5000 | rt.GetCode() | (rn.GetCode() << 3) |
11484 (rm.GetCode() << 6));
11485 AdvanceIT();
11486 return;
11487 }
11488 }
11489 }
11490 if (operand.IsShiftedRegister()) {
11491 Register rn = operand.GetBaseRegister();
11492 Sign sign = operand.GetSign();
11493 Register rm = operand.GetOffsetRegister();
11494 Shift shift = operand.GetShift();
11495 uint32_t amount = operand.GetShiftAmount();
11496 if (IsUsingT32()) {
11497 // STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
11498 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
11499 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11500 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
11501 EmitT32_32(0xf8400000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11502 rm.GetCode() | (amount << 4));
11503 AdvanceIT();
11504 return;
11505 }
11506 } else {
11507 // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
11508 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
11509 (!rm.IsPC() || AllowUnpredictable())) {
11510 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11511 uint32_t shift_ = TypeEncodingValue(shift);
11512 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11513 EmitA32(0x07000000U | (cond.GetCondition() << 28) |
11514 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11515 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11516 return;
11517 }
11518 // STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
11519 if (operand.IsShiftValid() && operand.IsPostIndex() &&
11520 cond.IsNotNever() && (!rm.IsPC() || AllowUnpredictable())) {
11521 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11522 uint32_t shift_ = TypeEncodingValue(shift);
11523 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11524 EmitA32(0x06000000U | (cond.GetCondition() << 28) |
11525 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11526 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11527 return;
11528 }
11529 // STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
11530 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
11531 (!rm.IsPC() || AllowUnpredictable())) {
11532 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11533 uint32_t shift_ = TypeEncodingValue(shift);
11534 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11535 EmitA32(0x07200000U | (cond.GetCondition() << 28) |
11536 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11537 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11538 return;
11539 }
11540 }
11541 }
11542 Delegate(kStr, &Assembler::str, cond, size, rt, operand);
11543 }
11544
strb(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)11545 void Assembler::strb(Condition cond,
11546 EncodingSize size,
11547 Register rt,
11548 const MemOperand& operand) {
11549 VIXL_ASSERT(AllowAssembler());
11550 CheckIT(cond);
11551 if (operand.IsImmediate()) {
11552 Register rn = operand.GetBaseRegister();
11553 int32_t offset = operand.GetOffsetImmediate();
11554 if (IsUsingT32()) {
11555 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
11556 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
11557 (offset <= 31) && operand.IsOffset()) {
11558 EmitT32_16(0x7000 | rt.GetCode() | (rn.GetCode() << 3) |
11559 ((offset & 0x1f) << 6));
11560 AdvanceIT();
11561 return;
11562 }
11563 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
11564 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
11565 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11566 (!rt.IsPC() || AllowUnpredictable())) {
11567 EmitT32_32(0xf8800000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11568 (offset & 0xfff));
11569 AdvanceIT();
11570 return;
11571 }
11572 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
11573 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
11574 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11575 (!rt.IsPC() || AllowUnpredictable())) {
11576 EmitT32_32(0xf8000c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11577 (-offset & 0xff));
11578 AdvanceIT();
11579 return;
11580 }
11581 // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
11582 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
11583 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11584 (!rt.IsPC() || AllowUnpredictable())) {
11585 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11586 uint32_t offset_ = abs(offset);
11587 EmitT32_32(0xf8000900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11588 offset_ | (sign << 9));
11589 AdvanceIT();
11590 return;
11591 }
11592 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
11593 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
11594 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11595 (!rt.IsPC() || AllowUnpredictable())) {
11596 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11597 uint32_t offset_ = abs(offset);
11598 EmitT32_32(0xf8000d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11599 offset_ | (sign << 9));
11600 AdvanceIT();
11601 return;
11602 }
11603 } else {
11604 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
11605 if ((offset >= -4095) && (offset <= 4095) && operand.IsOffset() &&
11606 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
11607 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11608 uint32_t offset_ = abs(offset);
11609 EmitA32(0x05400000U | (cond.GetCondition() << 28) |
11610 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11611 (sign << 23));
11612 return;
11613 }
11614 // STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
11615 if ((offset >= -4095) && (offset <= 4095) && operand.IsPostIndex() &&
11616 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
11617 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11618 uint32_t offset_ = abs(offset);
11619 EmitA32(0x04400000U | (cond.GetCondition() << 28) |
11620 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11621 (sign << 23));
11622 return;
11623 }
11624 // STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
11625 if ((offset >= -4095) && (offset <= 4095) && operand.IsPreIndex() &&
11626 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
11627 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11628 uint32_t offset_ = abs(offset);
11629 EmitA32(0x05600000U | (cond.GetCondition() << 28) |
11630 (rt.GetCode() << 12) | (rn.GetCode() << 16) | offset_ |
11631 (sign << 23));
11632 return;
11633 }
11634 }
11635 }
11636 if (operand.IsPlainRegister()) {
11637 Register rn = operand.GetBaseRegister();
11638 Sign sign = operand.GetSign();
11639 Register rm = operand.GetOffsetRegister();
11640 if (IsUsingT32()) {
11641 // STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
11642 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
11643 sign.IsPlus() && operand.IsOffset()) {
11644 EmitT32_16(0x5400 | rt.GetCode() | (rn.GetCode() << 3) |
11645 (rm.GetCode() << 6));
11646 AdvanceIT();
11647 return;
11648 }
11649 }
11650 }
11651 if (operand.IsShiftedRegister()) {
11652 Register rn = operand.GetBaseRegister();
11653 Sign sign = operand.GetSign();
11654 Register rm = operand.GetOffsetRegister();
11655 Shift shift = operand.GetShift();
11656 uint32_t amount = operand.GetShiftAmount();
11657 if (IsUsingT32()) {
11658 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
11659 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
11660 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11661 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
11662 EmitT32_32(0xf8000000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11663 rm.GetCode() | (amount << 4));
11664 AdvanceIT();
11665 return;
11666 }
11667 } else {
11668 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
11669 if (operand.IsShiftValid() && operand.IsOffset() && cond.IsNotNever() &&
11670 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
11671 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11672 uint32_t shift_ = TypeEncodingValue(shift);
11673 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11674 EmitA32(0x07400000U | (cond.GetCondition() << 28) |
11675 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11676 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11677 return;
11678 }
11679 // STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
11680 if (operand.IsShiftValid() && operand.IsPostIndex() &&
11681 cond.IsNotNever() &&
11682 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
11683 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11684 uint32_t shift_ = TypeEncodingValue(shift);
11685 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11686 EmitA32(0x06400000U | (cond.GetCondition() << 28) |
11687 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11688 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11689 return;
11690 }
11691 // STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
11692 if (operand.IsShiftValid() && operand.IsPreIndex() && cond.IsNotNever() &&
11693 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
11694 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11695 uint32_t shift_ = TypeEncodingValue(shift);
11696 uint32_t imm_and_type_ = (((amount % 32) << 2) | shift_);
11697 EmitA32(0x07600000U | (cond.GetCondition() << 28) |
11698 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11699 (sign_ << 23) | ((imm_and_type_ & 0x7f) << 5));
11700 return;
11701 }
11702 }
11703 }
11704 Delegate(kStrb, &Assembler::strb, cond, size, rt, operand);
11705 }
11706
strd(Condition cond,Register rt,Register rt2,const MemOperand & operand)11707 void Assembler::strd(Condition cond,
11708 Register rt,
11709 Register rt2,
11710 const MemOperand& operand) {
11711 VIXL_ASSERT(AllowAssembler());
11712 CheckIT(cond);
11713 if (operand.IsImmediate()) {
11714 Register rn = operand.GetBaseRegister();
11715 int32_t offset = operand.GetOffsetImmediate();
11716 if (IsUsingT32()) {
11717 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1
11718 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
11719 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11720 ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
11721 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11722 uint32_t offset_ = abs(offset) >> 2;
11723 EmitT32_32(0xe9400000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
11724 (rn.GetCode() << 16) | offset_ | (sign << 23));
11725 AdvanceIT();
11726 return;
11727 }
11728 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1
11729 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
11730 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11731 ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
11732 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11733 uint32_t offset_ = abs(offset) >> 2;
11734 EmitT32_32(0xe8600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
11735 (rn.GetCode() << 16) | offset_ | (sign << 23));
11736 AdvanceIT();
11737 return;
11738 }
11739 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1
11740 if ((offset >= -1020) && (offset <= 1020) && ((offset % 4) == 0) &&
11741 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
11742 ((!rn.IsPC() && !rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
11743 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11744 uint32_t offset_ = abs(offset) >> 2;
11745 EmitT32_32(0xe9600000U | (rt.GetCode() << 12) | (rt2.GetCode() << 8) |
11746 (rn.GetCode() << 16) | offset_ | (sign << 23));
11747 AdvanceIT();
11748 return;
11749 }
11750 } else {
11751 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1
11752 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11753 (offset >= -255) && (offset <= 255) && operand.IsOffset() &&
11754 cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
11755 AllowUnpredictable())) {
11756 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11757 uint32_t offset_ = abs(offset);
11758 EmitA32(0x014000f0U | (cond.GetCondition() << 28) |
11759 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
11760 ((offset_ & 0xf0) << 4) | (sign << 23));
11761 return;
11762 }
11763 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1
11764 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11765 (offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
11766 cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
11767 AllowUnpredictable())) {
11768 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11769 uint32_t offset_ = abs(offset);
11770 EmitA32(0x004000f0U | (cond.GetCondition() << 28) |
11771 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
11772 ((offset_ & 0xf0) << 4) | (sign << 23));
11773 return;
11774 }
11775 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1
11776 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11777 (offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
11778 cond.IsNotNever() && ((((rt.GetCode() & 1) == 0) && !rt2.IsPC()) ||
11779 AllowUnpredictable())) {
11780 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
11781 uint32_t offset_ = abs(offset);
11782 EmitA32(0x016000f0U | (cond.GetCondition() << 28) |
11783 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
11784 ((offset_ & 0xf0) << 4) | (sign << 23));
11785 return;
11786 }
11787 }
11788 }
11789 if (operand.IsPlainRegister()) {
11790 Register rn = operand.GetBaseRegister();
11791 Sign sign = operand.GetSign();
11792 Register rm = operand.GetOffsetRegister();
11793 if (IsUsingA32()) {
11794 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
11795 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11796 operand.IsOffset() && cond.IsNotNever() &&
11797 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
11798 AllowUnpredictable())) {
11799 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11800 EmitA32(0x010000f0U | (cond.GetCondition() << 28) |
11801 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11802 (sign_ << 23));
11803 return;
11804 }
11805 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
11806 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11807 operand.IsPostIndex() && cond.IsNotNever() &&
11808 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
11809 AllowUnpredictable())) {
11810 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11811 EmitA32(0x000000f0U | (cond.GetCondition() << 28) |
11812 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11813 (sign_ << 23));
11814 return;
11815 }
11816 // STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
11817 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11818 operand.IsPreIndex() && cond.IsNotNever() &&
11819 ((((rt.GetCode() & 1) == 0) && !rt2.IsPC() && !rm.IsPC()) ||
11820 AllowUnpredictable())) {
11821 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
11822 EmitA32(0x012000f0U | (cond.GetCondition() << 28) |
11823 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
11824 (sign_ << 23));
11825 return;
11826 }
11827 }
11828 }
11829 Delegate(kStrd, &Assembler::strd, cond, rt, rt2, operand);
11830 }
11831
strex(Condition cond,Register rd,Register rt,const MemOperand & operand)11832 void Assembler::strex(Condition cond,
11833 Register rd,
11834 Register rt,
11835 const MemOperand& operand) {
11836 VIXL_ASSERT(AllowAssembler());
11837 CheckIT(cond);
11838 if (operand.IsImmediate()) {
11839 Register rn = operand.GetBaseRegister();
11840 int32_t offset = operand.GetOffsetImmediate();
11841 if (IsUsingT32()) {
11842 // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1
11843 if ((offset >= 0) && (offset <= 1020) && ((offset % 4) == 0) &&
11844 operand.IsOffset() &&
11845 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11846 int32_t offset_ = offset >> 2;
11847 EmitT32_32(0xe8400000U | (rd.GetCode() << 8) | (rt.GetCode() << 12) |
11848 (rn.GetCode() << 16) | (offset_ & 0xff));
11849 AdvanceIT();
11850 return;
11851 }
11852 } else {
11853 // STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1
11854 if ((offset == 0) && operand.IsOffset() && cond.IsNotNever() &&
11855 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11856 EmitA32(0x01800f90U | (cond.GetCondition() << 28) |
11857 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11858 return;
11859 }
11860 }
11861 }
11862 Delegate(kStrex, &Assembler::strex, cond, rd, rt, operand);
11863 }
11864
strexb(Condition cond,Register rd,Register rt,const MemOperand & operand)11865 void Assembler::strexb(Condition cond,
11866 Register rd,
11867 Register rt,
11868 const MemOperand& operand) {
11869 VIXL_ASSERT(AllowAssembler());
11870 CheckIT(cond);
11871 if (operand.IsImmediateZero()) {
11872 Register rn = operand.GetBaseRegister();
11873 if (IsUsingT32()) {
11874 // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
11875 if (operand.IsOffset() &&
11876 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11877 EmitT32_32(0xe8c00f40U | rd.GetCode() | (rt.GetCode() << 12) |
11878 (rn.GetCode() << 16));
11879 AdvanceIT();
11880 return;
11881 }
11882 } else {
11883 // STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
11884 if (operand.IsOffset() && cond.IsNotNever() &&
11885 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11886 EmitA32(0x01c00f90U | (cond.GetCondition() << 28) |
11887 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11888 return;
11889 }
11890 }
11891 }
11892 Delegate(kStrexb, &Assembler::strexb, cond, rd, rt, operand);
11893 }
11894
strexd(Condition cond,Register rd,Register rt,Register rt2,const MemOperand & operand)11895 void Assembler::strexd(Condition cond,
11896 Register rd,
11897 Register rt,
11898 Register rt2,
11899 const MemOperand& operand) {
11900 VIXL_ASSERT(AllowAssembler());
11901 CheckIT(cond);
11902 if (operand.IsImmediateZero()) {
11903 Register rn = operand.GetBaseRegister();
11904 if (IsUsingT32()) {
11905 // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1
11906 if (operand.IsOffset() &&
11907 ((!rd.IsPC() && !rt.IsPC() && !rt2.IsPC() && !rn.IsPC()) ||
11908 AllowUnpredictable())) {
11909 EmitT32_32(0xe8c00070U | rd.GetCode() | (rt.GetCode() << 12) |
11910 (rt2.GetCode() << 8) | (rn.GetCode() << 16));
11911 AdvanceIT();
11912 return;
11913 }
11914 } else {
11915 // STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
11916 if ((((rt.GetCode() + 1) % kNumberOfRegisters) == rt2.GetCode()) &&
11917 operand.IsOffset() && cond.IsNotNever() &&
11918 ((!rd.IsPC() && ((rt.GetCode() & 1) == 0) && !rt2.IsPC() &&
11919 !rn.IsPC()) ||
11920 AllowUnpredictable())) {
11921 EmitA32(0x01a00f90U | (cond.GetCondition() << 28) |
11922 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11923 return;
11924 }
11925 }
11926 }
11927 Delegate(kStrexd, &Assembler::strexd, cond, rd, rt, rt2, operand);
11928 }
11929
strexh(Condition cond,Register rd,Register rt,const MemOperand & operand)11930 void Assembler::strexh(Condition cond,
11931 Register rd,
11932 Register rt,
11933 const MemOperand& operand) {
11934 VIXL_ASSERT(AllowAssembler());
11935 CheckIT(cond);
11936 if (operand.IsImmediateZero()) {
11937 Register rn = operand.GetBaseRegister();
11938 if (IsUsingT32()) {
11939 // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
11940 if (operand.IsOffset() &&
11941 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11942 EmitT32_32(0xe8c00f50U | rd.GetCode() | (rt.GetCode() << 12) |
11943 (rn.GetCode() << 16));
11944 AdvanceIT();
11945 return;
11946 }
11947 } else {
11948 // STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
11949 if (operand.IsOffset() && cond.IsNotNever() &&
11950 ((!rd.IsPC() && !rt.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
11951 EmitA32(0x01e00f90U | (cond.GetCondition() << 28) |
11952 (rd.GetCode() << 12) | rt.GetCode() | (rn.GetCode() << 16));
11953 return;
11954 }
11955 }
11956 }
11957 Delegate(kStrexh, &Assembler::strexh, cond, rd, rt, operand);
11958 }
11959
strh(Condition cond,EncodingSize size,Register rt,const MemOperand & operand)11960 void Assembler::strh(Condition cond,
11961 EncodingSize size,
11962 Register rt,
11963 const MemOperand& operand) {
11964 VIXL_ASSERT(AllowAssembler());
11965 CheckIT(cond);
11966 if (operand.IsImmediate()) {
11967 Register rn = operand.GetBaseRegister();
11968 int32_t offset = operand.GetOffsetImmediate();
11969 if (IsUsingT32()) {
11970 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
11971 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && (offset >= 0) &&
11972 (offset <= 62) && ((offset % 2) == 0) && operand.IsOffset()) {
11973 int32_t offset_ = offset >> 1;
11974 EmitT32_16(0x8000 | rt.GetCode() | (rn.GetCode() << 3) |
11975 ((offset_ & 0x1f) << 6));
11976 AdvanceIT();
11977 return;
11978 }
11979 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
11980 if (!size.IsNarrow() && (offset >= 0) && (offset <= 4095) &&
11981 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11982 (!rt.IsPC() || AllowUnpredictable())) {
11983 EmitT32_32(0xf8a00000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11984 (offset & 0xfff));
11985 AdvanceIT();
11986 return;
11987 }
11988 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
11989 if (!size.IsNarrow() && (-offset >= 0) && (-offset <= 255) &&
11990 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
11991 (!rt.IsPC() || AllowUnpredictable())) {
11992 EmitT32_32(0xf8200c00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
11993 (-offset & 0xff));
11994 AdvanceIT();
11995 return;
11996 }
11997 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
11998 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
11999 operand.IsPostIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
12000 (!rt.IsPC() || AllowUnpredictable())) {
12001 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
12002 uint32_t offset_ = abs(offset);
12003 EmitT32_32(0xf8200900U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
12004 offset_ | (sign << 9));
12005 AdvanceIT();
12006 return;
12007 }
12008 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
12009 if (!size.IsNarrow() && (offset >= -255) && (offset <= 255) &&
12010 operand.IsPreIndex() && ((rn.GetCode() & 0xf) != 0xf) &&
12011 (!rt.IsPC() || AllowUnpredictable())) {
12012 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
12013 uint32_t offset_ = abs(offset);
12014 EmitT32_32(0xf8200d00U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
12015 offset_ | (sign << 9));
12016 AdvanceIT();
12017 return;
12018 }
12019 } else {
12020 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
12021 if ((offset >= -255) && (offset <= 255) && operand.IsOffset() &&
12022 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
12023 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
12024 uint32_t offset_ = abs(offset);
12025 EmitA32(0x014000b0U | (cond.GetCondition() << 28) |
12026 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
12027 ((offset_ & 0xf0) << 4) | (sign << 23));
12028 return;
12029 }
12030 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
12031 if ((offset >= -255) && (offset <= 255) && operand.IsPostIndex() &&
12032 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
12033 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
12034 uint32_t offset_ = abs(offset);
12035 EmitA32(0x004000b0U | (cond.GetCondition() << 28) |
12036 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
12037 ((offset_ & 0xf0) << 4) | (sign << 23));
12038 return;
12039 }
12040 // STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
12041 if ((offset >= -255) && (offset <= 255) && operand.IsPreIndex() &&
12042 cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
12043 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
12044 uint32_t offset_ = abs(offset);
12045 EmitA32(0x016000b0U | (cond.GetCondition() << 28) |
12046 (rt.GetCode() << 12) | (rn.GetCode() << 16) | (offset_ & 0xf) |
12047 ((offset_ & 0xf0) << 4) | (sign << 23));
12048 return;
12049 }
12050 }
12051 }
12052 if (operand.IsPlainRegister()) {
12053 Register rn = operand.GetBaseRegister();
12054 Sign sign = operand.GetSign();
12055 Register rm = operand.GetOffsetRegister();
12056 if (IsUsingT32()) {
12057 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
12058 if (!size.IsWide() && rt.IsLow() && rn.IsLow() && rm.IsLow() &&
12059 sign.IsPlus() && operand.IsOffset()) {
12060 EmitT32_16(0x5200 | rt.GetCode() | (rn.GetCode() << 3) |
12061 (rm.GetCode() << 6));
12062 AdvanceIT();
12063 return;
12064 }
12065 } else {
12066 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
12067 if (operand.IsOffset() && cond.IsNotNever() &&
12068 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12069 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
12070 EmitA32(0x010000b0U | (cond.GetCondition() << 28) |
12071 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12072 (sign_ << 23));
12073 return;
12074 }
12075 // STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
12076 if (operand.IsPostIndex() && cond.IsNotNever() &&
12077 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12078 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
12079 EmitA32(0x000000b0U | (cond.GetCondition() << 28) |
12080 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12081 (sign_ << 23));
12082 return;
12083 }
12084 // STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
12085 if (operand.IsPreIndex() && cond.IsNotNever() &&
12086 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12087 uint32_t sign_ = sign.IsPlus() ? 1 : 0;
12088 EmitA32(0x012000b0U | (cond.GetCondition() << 28) |
12089 (rt.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12090 (sign_ << 23));
12091 return;
12092 }
12093 }
12094 }
12095 if (operand.IsShiftedRegister()) {
12096 Register rn = operand.GetBaseRegister();
12097 Sign sign = operand.GetSign();
12098 Register rm = operand.GetOffsetRegister();
12099 Shift shift = operand.GetShift();
12100 uint32_t amount = operand.GetShiftAmount();
12101 if (IsUsingT32()) {
12102 // STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2
12103 if (!size.IsNarrow() && sign.IsPlus() && shift.IsLSL() && (amount <= 3) &&
12104 operand.IsOffset() && ((rn.GetCode() & 0xf) != 0xf) &&
12105 ((!rt.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12106 EmitT32_32(0xf8200000U | (rt.GetCode() << 12) | (rn.GetCode() << 16) |
12107 rm.GetCode() | (amount << 4));
12108 AdvanceIT();
12109 return;
12110 }
12111 }
12112 }
12113 Delegate(kStrh, &Assembler::strh, cond, size, rt, operand);
12114 }
12115
sub(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)12116 void Assembler::sub(Condition cond,
12117 EncodingSize size,
12118 Register rd,
12119 Register rn,
12120 const Operand& operand) {
12121 VIXL_ASSERT(AllowAssembler());
12122 CheckIT(cond);
12123 if (operand.IsImmediate()) {
12124 uint32_t imm = operand.GetImmediate();
12125 if (IsUsingT32()) {
12126 ImmediateT32 immediate_t32(imm);
12127 // SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
12128 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
12129 (imm <= 7)) {
12130 EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
12131 AdvanceIT();
12132 return;
12133 }
12134 // SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
12135 if (InITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
12136 (imm <= 255)) {
12137 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
12138 AdvanceIT();
12139 return;
12140 }
12141 // SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1
12142 if (!size.IsWide() && rd.Is(sp) && rn.Is(sp) && (imm <= 508) &&
12143 ((imm % 4) == 0)) {
12144 uint32_t imm_ = imm >> 2;
12145 EmitT32_16(0xb080 | imm_);
12146 AdvanceIT();
12147 return;
12148 }
12149 // SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2
12150 if (!size.IsNarrow() && rn.Is(pc) && (imm <= 4095) &&
12151 (!rd.IsPC() || AllowUnpredictable())) {
12152 EmitT32_32(0xf2af0000U | (rd.GetCode() << 8) | (imm & 0xff) |
12153 ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
12154 AdvanceIT();
12155 return;
12156 }
12157 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
12158 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
12159 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
12160 EmitT32_32(0xf1a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12161 (immediate_t32.GetEncodingValue() & 0xff) |
12162 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12163 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12164 AdvanceIT();
12165 return;
12166 }
12167 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
12168 if (!size.IsNarrow() && (imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
12169 (!rd.IsPC() || AllowUnpredictable())) {
12170 EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12171 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
12172 AdvanceIT();
12173 return;
12174 }
12175 // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
12176 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
12177 (!rd.IsPC() || AllowUnpredictable())) {
12178 EmitT32_32(0xf1ad0000U | (rd.GetCode() << 8) |
12179 (immediate_t32.GetEncodingValue() & 0xff) |
12180 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12181 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12182 AdvanceIT();
12183 return;
12184 }
12185 // SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
12186 if (!size.IsNarrow() && rn.Is(sp) && (imm <= 4095) &&
12187 (!rd.IsPC() || AllowUnpredictable())) {
12188 EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
12189 ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
12190 AdvanceIT();
12191 return;
12192 }
12193 } else {
12194 ImmediateA32 immediate_a32(imm);
12195 // SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2
12196 if (rn.Is(pc) && immediate_a32.IsValid() && cond.IsNotNever()) {
12197 EmitA32(0x024f0000U | (cond.GetCondition() << 28) |
12198 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
12199 return;
12200 }
12201 // SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
12202 if (immediate_a32.IsValid() && cond.IsNotNever() &&
12203 ((rn.GetCode() & 0xd) != 0xd)) {
12204 EmitA32(0x02400000U | (cond.GetCondition() << 28) |
12205 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
12206 immediate_a32.GetEncodingValue());
12207 return;
12208 }
12209 // SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
12210 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
12211 EmitA32(0x024d0000U | (cond.GetCondition() << 28) |
12212 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
12213 return;
12214 }
12215 }
12216 }
12217 if (operand.IsImmediateShiftedRegister()) {
12218 Register rm = operand.GetBaseRegister();
12219 if (operand.IsPlainRegister()) {
12220 if (IsUsingT32()) {
12221 // SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
12222 if (InITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
12223 rm.IsLow()) {
12224 EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
12225 (rm.GetCode() << 6));
12226 AdvanceIT();
12227 return;
12228 }
12229 // SUB{<c>} {<Rd>}, SP, <Rm> ; T1
12230 if (rn.Is(sp) && ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12231 EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode());
12232 AdvanceIT();
12233 return;
12234 }
12235 }
12236 }
12237 Shift shift = operand.GetShift();
12238 uint32_t amount = operand.GetShiftAmount();
12239 if (IsUsingT32()) {
12240 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
12241 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
12242 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12243 uint32_t amount_ = amount % 32;
12244 EmitT32_32(0xeba00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12245 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
12246 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12247 AdvanceIT();
12248 return;
12249 }
12250 // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
12251 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
12252 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12253 uint32_t amount_ = amount % 32;
12254 EmitT32_32(0xebad0000U | (rd.GetCode() << 8) | rm.GetCode() |
12255 (operand.GetTypeEncodingValue() << 4) |
12256 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12257 AdvanceIT();
12258 return;
12259 }
12260 } else {
12261 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
12262 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
12263 uint32_t amount_ = amount % 32;
12264 EmitA32(0x00400000U | (cond.GetCondition() << 28) |
12265 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12266 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12267 return;
12268 }
12269 // SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
12270 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
12271 uint32_t amount_ = amount % 32;
12272 EmitA32(0x004d0000U | (cond.GetCondition() << 28) |
12273 (rd.GetCode() << 12) | rm.GetCode() |
12274 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12275 return;
12276 }
12277 }
12278 }
12279 if (operand.IsRegisterShiftedRegister()) {
12280 Register rm = operand.GetBaseRegister();
12281 Shift shift = operand.GetShift();
12282 Register rs = operand.GetShiftRegister();
12283 if (IsUsingA32()) {
12284 // SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
12285 if (cond.IsNotNever() &&
12286 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
12287 AllowUnpredictable())) {
12288 EmitA32(0x00400010U | (cond.GetCondition() << 28) |
12289 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12290 (shift.GetType() << 5) | (rs.GetCode() << 8));
12291 return;
12292 }
12293 }
12294 }
12295 Delegate(kSub, &Assembler::sub, cond, size, rd, rn, operand);
12296 }
12297
sub(Condition cond,Register rd,const Operand & operand)12298 void Assembler::sub(Condition cond, Register rd, const Operand& operand) {
12299 VIXL_ASSERT(AllowAssembler());
12300 CheckIT(cond);
12301 if (operand.IsImmediate()) {
12302 uint32_t imm = operand.GetImmediate();
12303 if (IsUsingT32()) {
12304 // SUB<c>{<q>} <Rdn>, #<imm8> ; T2
12305 if (InITBlock() && rd.IsLow() && (imm <= 255)) {
12306 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
12307 AdvanceIT();
12308 return;
12309 }
12310 }
12311 }
12312 Delegate(kSub, &Assembler::sub, cond, rd, operand);
12313 }
12314
subs(Condition cond,EncodingSize size,Register rd,Register rn,const Operand & operand)12315 void Assembler::subs(Condition cond,
12316 EncodingSize size,
12317 Register rd,
12318 Register rn,
12319 const Operand& operand) {
12320 VIXL_ASSERT(AllowAssembler());
12321 CheckIT(cond);
12322 if (operand.IsImmediate()) {
12323 uint32_t imm = operand.GetImmediate();
12324 if (IsUsingT32()) {
12325 ImmediateT32 immediate_t32(imm);
12326 // SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1
12327 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
12328 (imm <= 7)) {
12329 EmitT32_16(0x1e00 | rd.GetCode() | (rn.GetCode() << 3) | (imm << 6));
12330 AdvanceIT();
12331 return;
12332 }
12333 // SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
12334 if (OutsideITBlock() && !size.IsWide() && rd.Is(rn) && rn.IsLow() &&
12335 (imm <= 255)) {
12336 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
12337 AdvanceIT();
12338 return;
12339 }
12340 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
12341 if (!size.IsNarrow() && immediate_t32.IsValid() && !rn.Is(sp) &&
12342 !rd.Is(pc) && (!rn.IsPC() || AllowUnpredictable())) {
12343 EmitT32_32(0xf1b00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12344 (immediate_t32.GetEncodingValue() & 0xff) |
12345 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12346 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12347 AdvanceIT();
12348 return;
12349 }
12350 // SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5
12351 if (!size.IsNarrow() && rd.Is(pc) && rn.Is(lr) && (imm <= 255) &&
12352 (OutsideITBlockAndAlOrLast(cond) || AllowUnpredictable())) {
12353 EmitT32_32(0xf3de8f00U | imm);
12354 AdvanceIT();
12355 return;
12356 }
12357 // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
12358 if (!size.IsNarrow() && rn.Is(sp) && immediate_t32.IsValid() &&
12359 !rd.Is(pc)) {
12360 EmitT32_32(0xf1bd0000U | (rd.GetCode() << 8) |
12361 (immediate_t32.GetEncodingValue() & 0xff) |
12362 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12363 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12364 AdvanceIT();
12365 return;
12366 }
12367 } else {
12368 ImmediateA32 immediate_a32(imm);
12369 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
12370 if (immediate_a32.IsValid() && cond.IsNotNever() && !rn.Is(sp)) {
12371 EmitA32(0x02500000U | (cond.GetCondition() << 28) |
12372 (rd.GetCode() << 12) | (rn.GetCode() << 16) |
12373 immediate_a32.GetEncodingValue());
12374 return;
12375 }
12376 // SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
12377 if (rn.Is(sp) && immediate_a32.IsValid() && cond.IsNotNever()) {
12378 EmitA32(0x025d0000U | (cond.GetCondition() << 28) |
12379 (rd.GetCode() << 12) | immediate_a32.GetEncodingValue());
12380 return;
12381 }
12382 }
12383 }
12384 if (operand.IsImmediateShiftedRegister()) {
12385 Register rm = operand.GetBaseRegister();
12386 if (operand.IsPlainRegister()) {
12387 if (IsUsingT32()) {
12388 // SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12389 if (OutsideITBlock() && !size.IsWide() && rd.IsLow() && rn.IsLow() &&
12390 rm.IsLow()) {
12391 EmitT32_16(0x1a00 | rd.GetCode() | (rn.GetCode() << 3) |
12392 (rm.GetCode() << 6));
12393 AdvanceIT();
12394 return;
12395 }
12396 }
12397 }
12398 Shift shift = operand.GetShift();
12399 uint32_t amount = operand.GetShiftAmount();
12400 if (IsUsingT32()) {
12401 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2
12402 if (!size.IsNarrow() && shift.IsValidAmount(amount) && !rn.Is(sp) &&
12403 !rd.Is(pc) && ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12404 uint32_t amount_ = amount % 32;
12405 EmitT32_32(0xebb00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12406 rm.GetCode() | (operand.GetTypeEncodingValue() << 4) |
12407 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12408 AdvanceIT();
12409 return;
12410 }
12411 // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1
12412 if (!size.IsNarrow() && rn.Is(sp) && shift.IsValidAmount(amount) &&
12413 !rd.Is(pc) && (!rm.IsPC() || AllowUnpredictable())) {
12414 uint32_t amount_ = amount % 32;
12415 EmitT32_32(0xebbd0000U | (rd.GetCode() << 8) | rm.GetCode() |
12416 (operand.GetTypeEncodingValue() << 4) |
12417 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12418 AdvanceIT();
12419 return;
12420 }
12421 } else {
12422 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1
12423 if (shift.IsValidAmount(amount) && cond.IsNotNever() && !rn.Is(sp)) {
12424 uint32_t amount_ = amount % 32;
12425 EmitA32(0x00500000U | (cond.GetCondition() << 28) |
12426 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12427 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12428 return;
12429 }
12430 // SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1
12431 if (rn.Is(sp) && shift.IsValidAmount(amount) && cond.IsNotNever()) {
12432 uint32_t amount_ = amount % 32;
12433 EmitA32(0x005d0000U | (cond.GetCondition() << 28) |
12434 (rd.GetCode() << 12) | rm.GetCode() |
12435 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12436 return;
12437 }
12438 }
12439 }
12440 if (operand.IsRegisterShiftedRegister()) {
12441 Register rm = operand.GetBaseRegister();
12442 Shift shift = operand.GetShift();
12443 Register rs = operand.GetShiftRegister();
12444 if (IsUsingA32()) {
12445 // SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
12446 if (cond.IsNotNever() &&
12447 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC() && !rs.IsPC()) ||
12448 AllowUnpredictable())) {
12449 EmitA32(0x00500010U | (cond.GetCondition() << 28) |
12450 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12451 (shift.GetType() << 5) | (rs.GetCode() << 8));
12452 return;
12453 }
12454 }
12455 }
12456 Delegate(kSubs, &Assembler::subs, cond, size, rd, rn, operand);
12457 }
12458
subs(Register rd,const Operand & operand)12459 void Assembler::subs(Register rd, const Operand& operand) {
12460 VIXL_ASSERT(AllowAssembler());
12461 CheckIT(al);
12462 if (operand.IsImmediate()) {
12463 uint32_t imm = operand.GetImmediate();
12464 if (IsUsingT32()) {
12465 // SUBS{<q>} <Rdn>, #<imm8> ; T2
12466 if (OutsideITBlock() && rd.IsLow() && (imm <= 255)) {
12467 EmitT32_16(0x3800 | (rd.GetCode() << 8) | imm);
12468 AdvanceIT();
12469 return;
12470 }
12471 }
12472 }
12473 Delegate(kSubs, &Assembler::subs, rd, operand);
12474 }
12475
subw(Condition cond,Register rd,Register rn,const Operand & operand)12476 void Assembler::subw(Condition cond,
12477 Register rd,
12478 Register rn,
12479 const Operand& operand) {
12480 VIXL_ASSERT(AllowAssembler());
12481 CheckIT(cond);
12482 if (operand.IsImmediate()) {
12483 uint32_t imm = operand.GetImmediate();
12484 if (IsUsingT32()) {
12485 // SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
12486 if ((imm <= 4095) && ((rn.GetCode() & 0xd) != 0xd) &&
12487 (!rd.IsPC() || AllowUnpredictable())) {
12488 EmitT32_32(0xf2a00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12489 (imm & 0xff) | ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
12490 AdvanceIT();
12491 return;
12492 }
12493 // SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
12494 if (rn.Is(sp) && (imm <= 4095) && (!rd.IsPC() || AllowUnpredictable())) {
12495 EmitT32_32(0xf2ad0000U | (rd.GetCode() << 8) | (imm & 0xff) |
12496 ((imm & 0x700) << 4) | ((imm & 0x800) << 15));
12497 AdvanceIT();
12498 return;
12499 }
12500 }
12501 }
12502 Delegate(kSubw, &Assembler::subw, cond, rd, rn, operand);
12503 }
12504
svc(Condition cond,uint32_t imm)12505 void Assembler::svc(Condition cond, uint32_t imm) {
12506 VIXL_ASSERT(AllowAssembler());
12507 CheckIT(cond);
12508 if (IsUsingT32()) {
12509 // SVC{<c>}{<q>} {#}<imm> ; T1
12510 if ((imm <= 255)) {
12511 EmitT32_16(0xdf00 | imm);
12512 AdvanceIT();
12513 return;
12514 }
12515 } else {
12516 // SVC{<c>}{<q>} {#}<imm> ; A1
12517 if ((imm <= 16777215) && cond.IsNotNever()) {
12518 EmitA32(0x0f000000U | (cond.GetCondition() << 28) | imm);
12519 return;
12520 }
12521 }
12522 Delegate(kSvc, &Assembler::svc, cond, imm);
12523 }
12524
sxtab(Condition cond,Register rd,Register rn,const Operand & operand)12525 void Assembler::sxtab(Condition cond,
12526 Register rd,
12527 Register rn,
12528 const Operand& operand) {
12529 VIXL_ASSERT(AllowAssembler());
12530 CheckIT(cond);
12531 if (operand.IsImmediateShiftedRegister()) {
12532 Register rm = operand.GetBaseRegister();
12533 Shift shift = operand.GetShift();
12534 uint32_t amount = operand.GetShiftAmount();
12535 if (IsUsingT32()) {
12536 // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12537 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12538 ((amount % 8) == 0) && !rn.Is(pc) &&
12539 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12540 uint32_t amount_ = amount / 8;
12541 EmitT32_32(0xfa40f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12542 rm.GetCode() | (amount_ << 4));
12543 AdvanceIT();
12544 return;
12545 }
12546 } else {
12547 // SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12548 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12549 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
12550 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12551 uint32_t amount_ = amount / 8;
12552 EmitA32(0x06a00070U | (cond.GetCondition() << 28) |
12553 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12554 (amount_ << 10));
12555 return;
12556 }
12557 }
12558 }
12559 Delegate(kSxtab, &Assembler::sxtab, cond, rd, rn, operand);
12560 }
12561
sxtab16(Condition cond,Register rd,Register rn,const Operand & operand)12562 void Assembler::sxtab16(Condition cond,
12563 Register rd,
12564 Register rn,
12565 const Operand& operand) {
12566 VIXL_ASSERT(AllowAssembler());
12567 CheckIT(cond);
12568 if (operand.IsImmediateShiftedRegister()) {
12569 Register rm = operand.GetBaseRegister();
12570 Shift shift = operand.GetShift();
12571 uint32_t amount = operand.GetShiftAmount();
12572 if (IsUsingT32()) {
12573 // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12574 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12575 ((amount % 8) == 0) && !rn.Is(pc) &&
12576 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12577 uint32_t amount_ = amount / 8;
12578 EmitT32_32(0xfa20f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12579 rm.GetCode() | (amount_ << 4));
12580 AdvanceIT();
12581 return;
12582 }
12583 } else {
12584 // SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12585 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12586 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
12587 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12588 uint32_t amount_ = amount / 8;
12589 EmitA32(0x06800070U | (cond.GetCondition() << 28) |
12590 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12591 (amount_ << 10));
12592 return;
12593 }
12594 }
12595 }
12596 Delegate(kSxtab16, &Assembler::sxtab16, cond, rd, rn, operand);
12597 }
12598
sxtah(Condition cond,Register rd,Register rn,const Operand & operand)12599 void Assembler::sxtah(Condition cond,
12600 Register rd,
12601 Register rn,
12602 const Operand& operand) {
12603 VIXL_ASSERT(AllowAssembler());
12604 CheckIT(cond);
12605 if (operand.IsImmediateShiftedRegister()) {
12606 Register rm = operand.GetBaseRegister();
12607 Shift shift = operand.GetShift();
12608 uint32_t amount = operand.GetShiftAmount();
12609 if (IsUsingT32()) {
12610 // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
12611 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12612 ((amount % 8) == 0) && !rn.Is(pc) &&
12613 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12614 uint32_t amount_ = amount / 8;
12615 EmitT32_32(0xfa00f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12616 rm.GetCode() | (amount_ << 4));
12617 AdvanceIT();
12618 return;
12619 }
12620 } else {
12621 // SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
12622 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12623 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
12624 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12625 uint32_t amount_ = amount / 8;
12626 EmitA32(0x06b00070U | (cond.GetCondition() << 28) |
12627 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
12628 (amount_ << 10));
12629 return;
12630 }
12631 }
12632 }
12633 Delegate(kSxtah, &Assembler::sxtah, cond, rd, rn, operand);
12634 }
12635
sxtb(Condition cond,EncodingSize size,Register rd,const Operand & operand)12636 void Assembler::sxtb(Condition cond,
12637 EncodingSize size,
12638 Register rd,
12639 const Operand& operand) {
12640 VIXL_ASSERT(AllowAssembler());
12641 CheckIT(cond);
12642 if (operand.IsImmediateShiftedRegister()) {
12643 Register rm = operand.GetBaseRegister();
12644 if (operand.IsPlainRegister()) {
12645 if (IsUsingT32()) {
12646 // SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
12647 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12648 EmitT32_16(0xb240 | rd.GetCode() | (rm.GetCode() << 3));
12649 AdvanceIT();
12650 return;
12651 }
12652 }
12653 }
12654 Shift shift = operand.GetShift();
12655 uint32_t amount = operand.GetShiftAmount();
12656 if (IsUsingT32()) {
12657 // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12658 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12659 (amount <= 24) && ((amount % 8) == 0) &&
12660 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12661 uint32_t amount_ = amount / 8;
12662 EmitT32_32(0xfa4ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12663 (amount_ << 4));
12664 AdvanceIT();
12665 return;
12666 }
12667 } else {
12668 // SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12669 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12670 ((amount % 8) == 0) && cond.IsNotNever() &&
12671 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12672 uint32_t amount_ = amount / 8;
12673 EmitA32(0x06af0070U | (cond.GetCondition() << 28) |
12674 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12675 return;
12676 }
12677 }
12678 }
12679 Delegate(kSxtb, &Assembler::sxtb, cond, size, rd, operand);
12680 }
12681
sxtb16(Condition cond,Register rd,const Operand & operand)12682 void Assembler::sxtb16(Condition cond, Register rd, const Operand& operand) {
12683 VIXL_ASSERT(AllowAssembler());
12684 CheckIT(cond);
12685 if (operand.IsImmediateShiftedRegister()) {
12686 Register rm = operand.GetBaseRegister();
12687 Shift shift = operand.GetShift();
12688 uint32_t amount = operand.GetShiftAmount();
12689 if (IsUsingT32()) {
12690 // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
12691 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12692 ((amount % 8) == 0) &&
12693 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12694 uint32_t amount_ = amount / 8;
12695 EmitT32_32(0xfa2ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12696 (amount_ << 4));
12697 AdvanceIT();
12698 return;
12699 }
12700 } else {
12701 // SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12702 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12703 ((amount % 8) == 0) && cond.IsNotNever() &&
12704 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12705 uint32_t amount_ = amount / 8;
12706 EmitA32(0x068f0070U | (cond.GetCondition() << 28) |
12707 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12708 return;
12709 }
12710 }
12711 }
12712 Delegate(kSxtb16, &Assembler::sxtb16, cond, rd, operand);
12713 }
12714
sxth(Condition cond,EncodingSize size,Register rd,const Operand & operand)12715 void Assembler::sxth(Condition cond,
12716 EncodingSize size,
12717 Register rd,
12718 const Operand& operand) {
12719 VIXL_ASSERT(AllowAssembler());
12720 CheckIT(cond);
12721 if (operand.IsImmediateShiftedRegister()) {
12722 Register rm = operand.GetBaseRegister();
12723 if (operand.IsPlainRegister()) {
12724 if (IsUsingT32()) {
12725 // SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
12726 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
12727 EmitT32_16(0xb200 | rd.GetCode() | (rm.GetCode() << 3));
12728 AdvanceIT();
12729 return;
12730 }
12731 }
12732 }
12733 Shift shift = operand.GetShift();
12734 uint32_t amount = operand.GetShiftAmount();
12735 if (IsUsingT32()) {
12736 // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
12737 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
12738 (amount <= 24) && ((amount % 8) == 0) &&
12739 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12740 uint32_t amount_ = amount / 8;
12741 EmitT32_32(0xfa0ff080U | (rd.GetCode() << 8) | rm.GetCode() |
12742 (amount_ << 4));
12743 AdvanceIT();
12744 return;
12745 }
12746 } else {
12747 // SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
12748 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
12749 ((amount % 8) == 0) && cond.IsNotNever() &&
12750 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12751 uint32_t amount_ = amount / 8;
12752 EmitA32(0x06bf0070U | (cond.GetCondition() << 28) |
12753 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
12754 return;
12755 }
12756 }
12757 }
12758 Delegate(kSxth, &Assembler::sxth, cond, size, rd, operand);
12759 }
12760
tbb(Condition cond,Register rn,Register rm)12761 void Assembler::tbb(Condition cond, Register rn, Register rm) {
12762 VIXL_ASSERT(AllowAssembler());
12763 CheckIT(cond);
12764 if (IsUsingT32()) {
12765 // TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1
12766 if (OutsideITBlockAndAlOrLast(cond) &&
12767 (!rm.IsPC() || AllowUnpredictable())) {
12768 EmitT32_32(0xe8d0f000U | (rn.GetCode() << 16) | rm.GetCode());
12769 AdvanceIT();
12770 return;
12771 }
12772 }
12773 Delegate(kTbb, &Assembler::tbb, cond, rn, rm);
12774 }
12775
tbh(Condition cond,Register rn,Register rm)12776 void Assembler::tbh(Condition cond, Register rn, Register rm) {
12777 VIXL_ASSERT(AllowAssembler());
12778 CheckIT(cond);
12779 if (IsUsingT32()) {
12780 // TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1
12781 if (OutsideITBlockAndAlOrLast(cond) &&
12782 (!rm.IsPC() || AllowUnpredictable())) {
12783 EmitT32_32(0xe8d0f010U | (rn.GetCode() << 16) | rm.GetCode());
12784 AdvanceIT();
12785 return;
12786 }
12787 }
12788 Delegate(kTbh, &Assembler::tbh, cond, rn, rm);
12789 }
12790
teq(Condition cond,Register rn,const Operand & operand)12791 void Assembler::teq(Condition cond, Register rn, const Operand& operand) {
12792 VIXL_ASSERT(AllowAssembler());
12793 CheckIT(cond);
12794 if (operand.IsImmediate()) {
12795 uint32_t imm = operand.GetImmediate();
12796 if (IsUsingT32()) {
12797 ImmediateT32 immediate_t32(imm);
12798 // TEQ{<c>}{<q>} <Rn>, #<const> ; T1
12799 if (immediate_t32.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
12800 EmitT32_32(0xf0900f00U | (rn.GetCode() << 16) |
12801 (immediate_t32.GetEncodingValue() & 0xff) |
12802 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12803 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12804 AdvanceIT();
12805 return;
12806 }
12807 } else {
12808 ImmediateA32 immediate_a32(imm);
12809 // TEQ{<c>}{<q>} <Rn>, #<const> ; A1
12810 if (immediate_a32.IsValid() && cond.IsNotNever()) {
12811 EmitA32(0x03300000U | (cond.GetCondition() << 28) |
12812 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
12813 return;
12814 }
12815 }
12816 }
12817 if (operand.IsImmediateShiftedRegister()) {
12818 Register rm = operand.GetBaseRegister();
12819 Shift shift = operand.GetShift();
12820 uint32_t amount = operand.GetShiftAmount();
12821 if (IsUsingT32()) {
12822 // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1
12823 if (shift.IsValidAmount(amount) &&
12824 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12825 uint32_t amount_ = amount % 32;
12826 EmitT32_32(0xea900f00U | (rn.GetCode() << 16) | rm.GetCode() |
12827 (operand.GetTypeEncodingValue() << 4) |
12828 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12829 AdvanceIT();
12830 return;
12831 }
12832 } else {
12833 // TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
12834 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
12835 uint32_t amount_ = amount % 32;
12836 EmitA32(0x01300000U | (cond.GetCondition() << 28) |
12837 (rn.GetCode() << 16) | rm.GetCode() |
12838 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12839 return;
12840 }
12841 }
12842 }
12843 if (operand.IsRegisterShiftedRegister()) {
12844 Register rm = operand.GetBaseRegister();
12845 Shift shift = operand.GetShift();
12846 Register rs = operand.GetShiftRegister();
12847 if (IsUsingA32()) {
12848 // TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
12849 if (cond.IsNotNever() &&
12850 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
12851 EmitA32(0x01300010U | (cond.GetCondition() << 28) |
12852 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
12853 (rs.GetCode() << 8));
12854 return;
12855 }
12856 }
12857 }
12858 Delegate(kTeq, &Assembler::teq, cond, rn, operand);
12859 }
12860
tst(Condition cond,EncodingSize size,Register rn,const Operand & operand)12861 void Assembler::tst(Condition cond,
12862 EncodingSize size,
12863 Register rn,
12864 const Operand& operand) {
12865 VIXL_ASSERT(AllowAssembler());
12866 CheckIT(cond);
12867 if (operand.IsImmediate()) {
12868 uint32_t imm = operand.GetImmediate();
12869 if (IsUsingT32()) {
12870 ImmediateT32 immediate_t32(imm);
12871 // TST{<c>}{<q>} <Rn>, #<const> ; T1
12872 if (!size.IsNarrow() && immediate_t32.IsValid() &&
12873 (!rn.IsPC() || AllowUnpredictable())) {
12874 EmitT32_32(0xf0100f00U | (rn.GetCode() << 16) |
12875 (immediate_t32.GetEncodingValue() & 0xff) |
12876 ((immediate_t32.GetEncodingValue() & 0x700) << 4) |
12877 ((immediate_t32.GetEncodingValue() & 0x800) << 15));
12878 AdvanceIT();
12879 return;
12880 }
12881 } else {
12882 ImmediateA32 immediate_a32(imm);
12883 // TST{<c>}{<q>} <Rn>, #<const> ; A1
12884 if (immediate_a32.IsValid() && cond.IsNotNever()) {
12885 EmitA32(0x03100000U | (cond.GetCondition() << 28) |
12886 (rn.GetCode() << 16) | immediate_a32.GetEncodingValue());
12887 return;
12888 }
12889 }
12890 }
12891 if (operand.IsImmediateShiftedRegister()) {
12892 Register rm = operand.GetBaseRegister();
12893 if (operand.IsPlainRegister()) {
12894 if (IsUsingT32()) {
12895 // TST{<c>}{<q>} <Rn>, <Rm> ; T1
12896 if (!size.IsWide() && rn.IsLow() && rm.IsLow()) {
12897 EmitT32_16(0x4200 | rn.GetCode() | (rm.GetCode() << 3));
12898 AdvanceIT();
12899 return;
12900 }
12901 }
12902 }
12903 Shift shift = operand.GetShift();
12904 uint32_t amount = operand.GetShiftAmount();
12905 if (IsUsingT32()) {
12906 // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2
12907 if (!size.IsNarrow() && shift.IsValidAmount(amount) &&
12908 ((!rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12909 uint32_t amount_ = amount % 32;
12910 EmitT32_32(0xea100f00U | (rn.GetCode() << 16) | rm.GetCode() |
12911 (operand.GetTypeEncodingValue() << 4) |
12912 ((amount_ & 0x3) << 6) | ((amount_ & 0x1c) << 10));
12913 AdvanceIT();
12914 return;
12915 }
12916 } else {
12917 // TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
12918 if (shift.IsValidAmount(amount) && cond.IsNotNever()) {
12919 uint32_t amount_ = amount % 32;
12920 EmitA32(0x01100000U | (cond.GetCondition() << 28) |
12921 (rn.GetCode() << 16) | rm.GetCode() |
12922 (operand.GetTypeEncodingValue() << 5) | (amount_ << 7));
12923 return;
12924 }
12925 }
12926 }
12927 if (operand.IsRegisterShiftedRegister()) {
12928 Register rm = operand.GetBaseRegister();
12929 Shift shift = operand.GetShift();
12930 Register rs = operand.GetShiftRegister();
12931 if (IsUsingA32()) {
12932 // TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
12933 if (cond.IsNotNever() &&
12934 ((!rn.IsPC() && !rm.IsPC() && !rs.IsPC()) || AllowUnpredictable())) {
12935 EmitA32(0x01100010U | (cond.GetCondition() << 28) |
12936 (rn.GetCode() << 16) | rm.GetCode() | (shift.GetType() << 5) |
12937 (rs.GetCode() << 8));
12938 return;
12939 }
12940 }
12941 }
12942 Delegate(kTst, &Assembler::tst, cond, size, rn, operand);
12943 }
12944
uadd16(Condition cond,Register rd,Register rn,Register rm)12945 void Assembler::uadd16(Condition cond, Register rd, Register rn, Register rm) {
12946 VIXL_ASSERT(AllowAssembler());
12947 CheckIT(cond);
12948 if (IsUsingT32()) {
12949 // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12950 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12951 EmitT32_32(0xfa90f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12952 rm.GetCode());
12953 AdvanceIT();
12954 return;
12955 }
12956 } else {
12957 // UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12958 if (cond.IsNotNever() &&
12959 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12960 EmitA32(0x06500f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12961 (rn.GetCode() << 16) | rm.GetCode());
12962 return;
12963 }
12964 }
12965 Delegate(kUadd16, &Assembler::uadd16, cond, rd, rn, rm);
12966 }
12967
uadd8(Condition cond,Register rd,Register rn,Register rm)12968 void Assembler::uadd8(Condition cond, Register rd, Register rn, Register rm) {
12969 VIXL_ASSERT(AllowAssembler());
12970 CheckIT(cond);
12971 if (IsUsingT32()) {
12972 // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12973 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12974 EmitT32_32(0xfa80f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12975 rm.GetCode());
12976 AdvanceIT();
12977 return;
12978 }
12979 } else {
12980 // UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
12981 if (cond.IsNotNever() &&
12982 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12983 EmitA32(0x06500f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
12984 (rn.GetCode() << 16) | rm.GetCode());
12985 return;
12986 }
12987 }
12988 Delegate(kUadd8, &Assembler::uadd8, cond, rd, rn, rm);
12989 }
12990
uasx(Condition cond,Register rd,Register rn,Register rm)12991 void Assembler::uasx(Condition cond, Register rd, Register rn, Register rm) {
12992 VIXL_ASSERT(AllowAssembler());
12993 CheckIT(cond);
12994 if (IsUsingT32()) {
12995 // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
12996 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
12997 EmitT32_32(0xfaa0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
12998 rm.GetCode());
12999 AdvanceIT();
13000 return;
13001 }
13002 } else {
13003 // UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13004 if (cond.IsNotNever() &&
13005 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13006 EmitA32(0x06500f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13007 (rn.GetCode() << 16) | rm.GetCode());
13008 return;
13009 }
13010 }
13011 Delegate(kUasx, &Assembler::uasx, cond, rd, rn, rm);
13012 }
13013
ubfx(Condition cond,Register rd,Register rn,uint32_t lsb,uint32_t width)13014 void Assembler::ubfx(
13015 Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
13016 VIXL_ASSERT(AllowAssembler());
13017 CheckIT(cond);
13018 if (IsUsingT32()) {
13019 // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
13020 if ((lsb <= 31) &&
13021 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
13022 AllowUnpredictable())) {
13023 uint32_t widthm1 = width - 1;
13024 EmitT32_32(0xf3c00000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13025 ((lsb & 0x3) << 6) | ((lsb & 0x1c) << 10) | widthm1);
13026 AdvanceIT();
13027 return;
13028 }
13029 } else {
13030 // UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
13031 if ((lsb <= 31) && cond.IsNotNever() &&
13032 (((width >= 1) && (width <= 32 - lsb) && !rd.IsPC() && !rn.IsPC()) ||
13033 AllowUnpredictable())) {
13034 uint32_t widthm1 = width - 1;
13035 EmitA32(0x07e00050U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13036 rn.GetCode() | (lsb << 7) | (widthm1 << 16));
13037 return;
13038 }
13039 }
13040 Delegate(kUbfx, &Assembler::ubfx, cond, rd, rn, lsb, width);
13041 }
13042
udf(Condition cond,EncodingSize size,uint32_t imm)13043 void Assembler::udf(Condition cond, EncodingSize size, uint32_t imm) {
13044 VIXL_ASSERT(AllowAssembler());
13045 CheckIT(cond);
13046 if (IsUsingT32()) {
13047 // UDF{<c>}{<q>} {#}<imm> ; T1
13048 if (!size.IsWide() && (imm <= 255)) {
13049 if (cond.Is(al) || AllowStronglyDiscouraged()) {
13050 EmitT32_16(0xde00 | imm);
13051 AdvanceIT();
13052 return;
13053 }
13054 }
13055 // UDF{<c>}{<q>} {#}<imm> ; T2
13056 if (!size.IsNarrow() && (imm <= 65535)) {
13057 if (cond.Is(al) || AllowStronglyDiscouraged()) {
13058 EmitT32_32(0xf7f0a000U | (imm & 0xfff) | ((imm & 0xf000) << 4));
13059 AdvanceIT();
13060 return;
13061 }
13062 }
13063 } else {
13064 // UDF{<c>}{<q>} {#}<imm> ; A1
13065 if ((imm <= 65535)) {
13066 if (cond.Is(al) || AllowStronglyDiscouraged()) {
13067 EmitA32(0xe7f000f0U | (imm & 0xf) | ((imm & 0xfff0) << 4));
13068 return;
13069 }
13070 }
13071 }
13072 Delegate(kUdf, &Assembler::udf, cond, size, imm);
13073 }
13074
udiv(Condition cond,Register rd,Register rn,Register rm)13075 void Assembler::udiv(Condition cond, Register rd, Register rn, Register rm) {
13076 VIXL_ASSERT(AllowAssembler());
13077 CheckIT(cond);
13078 if (IsUsingT32()) {
13079 // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13080 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13081 EmitT32_32(0xfbb0f0f0U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13082 rm.GetCode());
13083 AdvanceIT();
13084 return;
13085 }
13086 } else {
13087 // UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13088 if (cond.IsNotNever() &&
13089 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13090 EmitA32(0x0730f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
13091 rn.GetCode() | (rm.GetCode() << 8));
13092 return;
13093 }
13094 }
13095 Delegate(kUdiv, &Assembler::udiv, cond, rd, rn, rm);
13096 }
13097
uhadd16(Condition cond,Register rd,Register rn,Register rm)13098 void Assembler::uhadd16(Condition cond, Register rd, Register rn, Register rm) {
13099 VIXL_ASSERT(AllowAssembler());
13100 CheckIT(cond);
13101 if (IsUsingT32()) {
13102 // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13103 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13104 EmitT32_32(0xfa90f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13105 rm.GetCode());
13106 AdvanceIT();
13107 return;
13108 }
13109 } else {
13110 // UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13111 if (cond.IsNotNever() &&
13112 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13113 EmitA32(0x06700f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13114 (rn.GetCode() << 16) | rm.GetCode());
13115 return;
13116 }
13117 }
13118 Delegate(kUhadd16, &Assembler::uhadd16, cond, rd, rn, rm);
13119 }
13120
uhadd8(Condition cond,Register rd,Register rn,Register rm)13121 void Assembler::uhadd8(Condition cond, Register rd, Register rn, Register rm) {
13122 VIXL_ASSERT(AllowAssembler());
13123 CheckIT(cond);
13124 if (IsUsingT32()) {
13125 // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13126 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13127 EmitT32_32(0xfa80f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13128 rm.GetCode());
13129 AdvanceIT();
13130 return;
13131 }
13132 } else {
13133 // UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13134 if (cond.IsNotNever() &&
13135 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13136 EmitA32(0x06700f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13137 (rn.GetCode() << 16) | rm.GetCode());
13138 return;
13139 }
13140 }
13141 Delegate(kUhadd8, &Assembler::uhadd8, cond, rd, rn, rm);
13142 }
13143
uhasx(Condition cond,Register rd,Register rn,Register rm)13144 void Assembler::uhasx(Condition cond, Register rd, Register rn, Register rm) {
13145 VIXL_ASSERT(AllowAssembler());
13146 CheckIT(cond);
13147 if (IsUsingT32()) {
13148 // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13149 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13150 EmitT32_32(0xfaa0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13151 rm.GetCode());
13152 AdvanceIT();
13153 return;
13154 }
13155 } else {
13156 // UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13157 if (cond.IsNotNever() &&
13158 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13159 EmitA32(0x06700f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13160 (rn.GetCode() << 16) | rm.GetCode());
13161 return;
13162 }
13163 }
13164 Delegate(kUhasx, &Assembler::uhasx, cond, rd, rn, rm);
13165 }
13166
uhsax(Condition cond,Register rd,Register rn,Register rm)13167 void Assembler::uhsax(Condition cond, Register rd, Register rn, Register rm) {
13168 VIXL_ASSERT(AllowAssembler());
13169 CheckIT(cond);
13170 if (IsUsingT32()) {
13171 // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13172 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13173 EmitT32_32(0xfae0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13174 rm.GetCode());
13175 AdvanceIT();
13176 return;
13177 }
13178 } else {
13179 // UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13180 if (cond.IsNotNever() &&
13181 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13182 EmitA32(0x06700f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13183 (rn.GetCode() << 16) | rm.GetCode());
13184 return;
13185 }
13186 }
13187 Delegate(kUhsax, &Assembler::uhsax, cond, rd, rn, rm);
13188 }
13189
uhsub16(Condition cond,Register rd,Register rn,Register rm)13190 void Assembler::uhsub16(Condition cond, Register rd, Register rn, Register rm) {
13191 VIXL_ASSERT(AllowAssembler());
13192 CheckIT(cond);
13193 if (IsUsingT32()) {
13194 // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13195 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13196 EmitT32_32(0xfad0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13197 rm.GetCode());
13198 AdvanceIT();
13199 return;
13200 }
13201 } else {
13202 // UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13203 if (cond.IsNotNever() &&
13204 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13205 EmitA32(0x06700f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13206 (rn.GetCode() << 16) | rm.GetCode());
13207 return;
13208 }
13209 }
13210 Delegate(kUhsub16, &Assembler::uhsub16, cond, rd, rn, rm);
13211 }
13212
uhsub8(Condition cond,Register rd,Register rn,Register rm)13213 void Assembler::uhsub8(Condition cond, Register rd, Register rn, Register rm) {
13214 VIXL_ASSERT(AllowAssembler());
13215 CheckIT(cond);
13216 if (IsUsingT32()) {
13217 // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13218 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13219 EmitT32_32(0xfac0f060U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13220 rm.GetCode());
13221 AdvanceIT();
13222 return;
13223 }
13224 } else {
13225 // UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13226 if (cond.IsNotNever() &&
13227 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13228 EmitA32(0x06700ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13229 (rn.GetCode() << 16) | rm.GetCode());
13230 return;
13231 }
13232 }
13233 Delegate(kUhsub8, &Assembler::uhsub8, cond, rd, rn, rm);
13234 }
13235
umaal(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)13236 void Assembler::umaal(
13237 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
13238 VIXL_ASSERT(AllowAssembler());
13239 CheckIT(cond);
13240 if (IsUsingT32()) {
13241 // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
13242 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13243 AllowUnpredictable())) {
13244 EmitT32_32(0xfbe00060U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
13245 (rn.GetCode() << 16) | rm.GetCode());
13246 AdvanceIT();
13247 return;
13248 }
13249 } else {
13250 // UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
13251 if (cond.IsNotNever() &&
13252 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13253 AllowUnpredictable())) {
13254 EmitA32(0x00400090U | (cond.GetCondition() << 28) |
13255 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
13256 (rm.GetCode() << 8));
13257 return;
13258 }
13259 }
13260 Delegate(kUmaal, &Assembler::umaal, cond, rdlo, rdhi, rn, rm);
13261 }
13262
umlal(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)13263 void Assembler::umlal(
13264 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
13265 VIXL_ASSERT(AllowAssembler());
13266 CheckIT(cond);
13267 if (IsUsingT32()) {
13268 // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
13269 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13270 AllowUnpredictable())) {
13271 EmitT32_32(0xfbe00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
13272 (rn.GetCode() << 16) | rm.GetCode());
13273 AdvanceIT();
13274 return;
13275 }
13276 } else {
13277 // UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
13278 if (cond.IsNotNever() &&
13279 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13280 AllowUnpredictable())) {
13281 EmitA32(0x00a00090U | (cond.GetCondition() << 28) |
13282 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
13283 (rm.GetCode() << 8));
13284 return;
13285 }
13286 }
13287 Delegate(kUmlal, &Assembler::umlal, cond, rdlo, rdhi, rn, rm);
13288 }
13289
umlals(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)13290 void Assembler::umlals(
13291 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
13292 VIXL_ASSERT(AllowAssembler());
13293 CheckIT(cond);
13294 if (IsUsingA32()) {
13295 // UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
13296 if (cond.IsNotNever() &&
13297 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13298 AllowUnpredictable())) {
13299 EmitA32(0x00b00090U | (cond.GetCondition() << 28) |
13300 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
13301 (rm.GetCode() << 8));
13302 return;
13303 }
13304 }
13305 Delegate(kUmlals, &Assembler::umlals, cond, rdlo, rdhi, rn, rm);
13306 }
13307
umull(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)13308 void Assembler::umull(
13309 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
13310 VIXL_ASSERT(AllowAssembler());
13311 CheckIT(cond);
13312 if (IsUsingT32()) {
13313 // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
13314 if (((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13315 AllowUnpredictable())) {
13316 EmitT32_32(0xfba00000U | (rdlo.GetCode() << 12) | (rdhi.GetCode() << 8) |
13317 (rn.GetCode() << 16) | rm.GetCode());
13318 AdvanceIT();
13319 return;
13320 }
13321 } else {
13322 // UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
13323 if (cond.IsNotNever() &&
13324 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13325 AllowUnpredictable())) {
13326 EmitA32(0x00800090U | (cond.GetCondition() << 28) |
13327 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
13328 (rm.GetCode() << 8));
13329 return;
13330 }
13331 }
13332 Delegate(kUmull, &Assembler::umull, cond, rdlo, rdhi, rn, rm);
13333 }
13334
umulls(Condition cond,Register rdlo,Register rdhi,Register rn,Register rm)13335 void Assembler::umulls(
13336 Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
13337 VIXL_ASSERT(AllowAssembler());
13338 CheckIT(cond);
13339 if (IsUsingA32()) {
13340 // UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
13341 if (cond.IsNotNever() &&
13342 ((!rdlo.IsPC() && !rdhi.IsPC() && !rn.IsPC() && !rm.IsPC()) ||
13343 AllowUnpredictable())) {
13344 EmitA32(0x00900090U | (cond.GetCondition() << 28) |
13345 (rdlo.GetCode() << 12) | (rdhi.GetCode() << 16) | rn.GetCode() |
13346 (rm.GetCode() << 8));
13347 return;
13348 }
13349 }
13350 Delegate(kUmulls, &Assembler::umulls, cond, rdlo, rdhi, rn, rm);
13351 }
13352
uqadd16(Condition cond,Register rd,Register rn,Register rm)13353 void Assembler::uqadd16(Condition cond, Register rd, Register rn, Register rm) {
13354 VIXL_ASSERT(AllowAssembler());
13355 CheckIT(cond);
13356 if (IsUsingT32()) {
13357 // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13358 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13359 EmitT32_32(0xfa90f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13360 rm.GetCode());
13361 AdvanceIT();
13362 return;
13363 }
13364 } else {
13365 // UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13366 if (cond.IsNotNever() &&
13367 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13368 EmitA32(0x06600f10U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13369 (rn.GetCode() << 16) | rm.GetCode());
13370 return;
13371 }
13372 }
13373 Delegate(kUqadd16, &Assembler::uqadd16, cond, rd, rn, rm);
13374 }
13375
uqadd8(Condition cond,Register rd,Register rn,Register rm)13376 void Assembler::uqadd8(Condition cond, Register rd, Register rn, Register rm) {
13377 VIXL_ASSERT(AllowAssembler());
13378 CheckIT(cond);
13379 if (IsUsingT32()) {
13380 // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13381 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13382 EmitT32_32(0xfa80f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13383 rm.GetCode());
13384 AdvanceIT();
13385 return;
13386 }
13387 } else {
13388 // UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13389 if (cond.IsNotNever() &&
13390 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13391 EmitA32(0x06600f90U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13392 (rn.GetCode() << 16) | rm.GetCode());
13393 return;
13394 }
13395 }
13396 Delegate(kUqadd8, &Assembler::uqadd8, cond, rd, rn, rm);
13397 }
13398
uqasx(Condition cond,Register rd,Register rn,Register rm)13399 void Assembler::uqasx(Condition cond, Register rd, Register rn, Register rm) {
13400 VIXL_ASSERT(AllowAssembler());
13401 CheckIT(cond);
13402 if (IsUsingT32()) {
13403 // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13404 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13405 EmitT32_32(0xfaa0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13406 rm.GetCode());
13407 AdvanceIT();
13408 return;
13409 }
13410 } else {
13411 // UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13412 if (cond.IsNotNever() &&
13413 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13414 EmitA32(0x06600f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13415 (rn.GetCode() << 16) | rm.GetCode());
13416 return;
13417 }
13418 }
13419 Delegate(kUqasx, &Assembler::uqasx, cond, rd, rn, rm);
13420 }
13421
uqsax(Condition cond,Register rd,Register rn,Register rm)13422 void Assembler::uqsax(Condition cond, Register rd, Register rn, Register rm) {
13423 VIXL_ASSERT(AllowAssembler());
13424 CheckIT(cond);
13425 if (IsUsingT32()) {
13426 // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13427 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13428 EmitT32_32(0xfae0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13429 rm.GetCode());
13430 AdvanceIT();
13431 return;
13432 }
13433 } else {
13434 // UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13435 if (cond.IsNotNever() &&
13436 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13437 EmitA32(0x06600f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13438 (rn.GetCode() << 16) | rm.GetCode());
13439 return;
13440 }
13441 }
13442 Delegate(kUqsax, &Assembler::uqsax, cond, rd, rn, rm);
13443 }
13444
uqsub16(Condition cond,Register rd,Register rn,Register rm)13445 void Assembler::uqsub16(Condition cond, Register rd, Register rn, Register rm) {
13446 VIXL_ASSERT(AllowAssembler());
13447 CheckIT(cond);
13448 if (IsUsingT32()) {
13449 // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13450 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13451 EmitT32_32(0xfad0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13452 rm.GetCode());
13453 AdvanceIT();
13454 return;
13455 }
13456 } else {
13457 // UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13458 if (cond.IsNotNever() &&
13459 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13460 EmitA32(0x06600f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13461 (rn.GetCode() << 16) | rm.GetCode());
13462 return;
13463 }
13464 }
13465 Delegate(kUqsub16, &Assembler::uqsub16, cond, rd, rn, rm);
13466 }
13467
uqsub8(Condition cond,Register rd,Register rn,Register rm)13468 void Assembler::uqsub8(Condition cond, Register rd, Register rn, Register rm) {
13469 VIXL_ASSERT(AllowAssembler());
13470 CheckIT(cond);
13471 if (IsUsingT32()) {
13472 // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13473 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13474 EmitT32_32(0xfac0f050U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13475 rm.GetCode());
13476 AdvanceIT();
13477 return;
13478 }
13479 } else {
13480 // UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13481 if (cond.IsNotNever() &&
13482 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13483 EmitA32(0x06600ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13484 (rn.GetCode() << 16) | rm.GetCode());
13485 return;
13486 }
13487 }
13488 Delegate(kUqsub8, &Assembler::uqsub8, cond, rd, rn, rm);
13489 }
13490
usad8(Condition cond,Register rd,Register rn,Register rm)13491 void Assembler::usad8(Condition cond, Register rd, Register rn, Register rm) {
13492 VIXL_ASSERT(AllowAssembler());
13493 CheckIT(cond);
13494 if (IsUsingT32()) {
13495 // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13496 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13497 EmitT32_32(0xfb70f000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13498 rm.GetCode());
13499 AdvanceIT();
13500 return;
13501 }
13502 } else {
13503 // USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13504 if (cond.IsNotNever() &&
13505 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13506 EmitA32(0x0780f010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
13507 rn.GetCode() | (rm.GetCode() << 8));
13508 return;
13509 }
13510 }
13511 Delegate(kUsad8, &Assembler::usad8, cond, rd, rn, rm);
13512 }
13513
usada8(Condition cond,Register rd,Register rn,Register rm,Register ra)13514 void Assembler::usada8(
13515 Condition cond, Register rd, Register rn, Register rm, Register ra) {
13516 VIXL_ASSERT(AllowAssembler());
13517 CheckIT(cond);
13518 if (IsUsingT32()) {
13519 // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
13520 if (!ra.Is(pc) &&
13521 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13522 EmitT32_32(0xfb700000U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13523 rm.GetCode() | (ra.GetCode() << 12));
13524 AdvanceIT();
13525 return;
13526 }
13527 } else {
13528 // USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
13529 if (cond.IsNotNever() && !ra.Is(pc) &&
13530 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13531 EmitA32(0x07800010U | (cond.GetCondition() << 28) | (rd.GetCode() << 16) |
13532 rn.GetCode() | (rm.GetCode() << 8) | (ra.GetCode() << 12));
13533 return;
13534 }
13535 }
13536 Delegate(kUsada8, &Assembler::usada8, cond, rd, rn, rm, ra);
13537 }
13538
usat(Condition cond,Register rd,uint32_t imm,const Operand & operand)13539 void Assembler::usat(Condition cond,
13540 Register rd,
13541 uint32_t imm,
13542 const Operand& operand) {
13543 VIXL_ASSERT(AllowAssembler());
13544 CheckIT(cond);
13545 if (operand.IsImmediateShiftedRegister()) {
13546 Register rn = operand.GetBaseRegister();
13547 Shift shift = operand.GetShift();
13548 uint32_t amount = operand.GetShiftAmount();
13549 if (IsUsingT32()) {
13550 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1
13551 if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 31) &&
13552 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13553 EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
13554 (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
13555 ((amount & 0x1c) << 10));
13556 AdvanceIT();
13557 return;
13558 }
13559 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1
13560 if ((imm <= 31) && shift.IsLSL() && (amount <= 31) &&
13561 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13562 EmitT32_32(0xf3800000U | (rd.GetCode() << 8) | imm |
13563 (rn.GetCode() << 16) | ((amount & 0x3) << 6) |
13564 ((amount & 0x1c) << 10));
13565 AdvanceIT();
13566 return;
13567 }
13568 } else {
13569 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
13570 if ((imm <= 31) && shift.IsASR() && (amount >= 1) && (amount <= 32) &&
13571 cond.IsNotNever() &&
13572 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13573 uint32_t amount_ = amount % 32;
13574 EmitA32(0x06e00050U | (cond.GetCondition() << 28) |
13575 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
13576 (amount_ << 7));
13577 return;
13578 }
13579 // USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
13580 if ((imm <= 31) && shift.IsLSL() && (amount <= 31) && cond.IsNotNever() &&
13581 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13582 EmitA32(0x06e00010U | (cond.GetCondition() << 28) |
13583 (rd.GetCode() << 12) | (imm << 16) | rn.GetCode() |
13584 (amount << 7));
13585 return;
13586 }
13587 }
13588 }
13589 Delegate(kUsat, &Assembler::usat, cond, rd, imm, operand);
13590 }
13591
usat16(Condition cond,Register rd,uint32_t imm,Register rn)13592 void Assembler::usat16(Condition cond, Register rd, uint32_t imm, Register rn) {
13593 VIXL_ASSERT(AllowAssembler());
13594 CheckIT(cond);
13595 if (IsUsingT32()) {
13596 // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
13597 if ((imm <= 15) && ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13598 EmitT32_32(0xf3a00000U | (rd.GetCode() << 8) | imm |
13599 (rn.GetCode() << 16));
13600 AdvanceIT();
13601 return;
13602 }
13603 } else {
13604 // USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
13605 if ((imm <= 15) && cond.IsNotNever() &&
13606 ((!rd.IsPC() && !rn.IsPC()) || AllowUnpredictable())) {
13607 EmitA32(0x06e00f30U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13608 (imm << 16) | rn.GetCode());
13609 return;
13610 }
13611 }
13612 Delegate(kUsat16, &Assembler::usat16, cond, rd, imm, rn);
13613 }
13614
usax(Condition cond,Register rd,Register rn,Register rm)13615 void Assembler::usax(Condition cond, Register rd, Register rn, Register rm) {
13616 VIXL_ASSERT(AllowAssembler());
13617 CheckIT(cond);
13618 if (IsUsingT32()) {
13619 // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13620 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13621 EmitT32_32(0xfae0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13622 rm.GetCode());
13623 AdvanceIT();
13624 return;
13625 }
13626 } else {
13627 // USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13628 if (cond.IsNotNever() &&
13629 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13630 EmitA32(0x06500f50U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13631 (rn.GetCode() << 16) | rm.GetCode());
13632 return;
13633 }
13634 }
13635 Delegate(kUsax, &Assembler::usax, cond, rd, rn, rm);
13636 }
13637
usub16(Condition cond,Register rd,Register rn,Register rm)13638 void Assembler::usub16(Condition cond, Register rd, Register rn, Register rm) {
13639 VIXL_ASSERT(AllowAssembler());
13640 CheckIT(cond);
13641 if (IsUsingT32()) {
13642 // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13643 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13644 EmitT32_32(0xfad0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13645 rm.GetCode());
13646 AdvanceIT();
13647 return;
13648 }
13649 } else {
13650 // USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13651 if (cond.IsNotNever() &&
13652 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13653 EmitA32(0x06500f70U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13654 (rn.GetCode() << 16) | rm.GetCode());
13655 return;
13656 }
13657 }
13658 Delegate(kUsub16, &Assembler::usub16, cond, rd, rn, rm);
13659 }
13660
usub8(Condition cond,Register rd,Register rn,Register rm)13661 void Assembler::usub8(Condition cond, Register rd, Register rn, Register rm) {
13662 VIXL_ASSERT(AllowAssembler());
13663 CheckIT(cond);
13664 if (IsUsingT32()) {
13665 // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
13666 if (((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13667 EmitT32_32(0xfac0f040U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13668 rm.GetCode());
13669 AdvanceIT();
13670 return;
13671 }
13672 } else {
13673 // USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
13674 if (cond.IsNotNever() &&
13675 ((!rd.IsPC() && !rn.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13676 EmitA32(0x06500ff0U | (cond.GetCondition() << 28) | (rd.GetCode() << 12) |
13677 (rn.GetCode() << 16) | rm.GetCode());
13678 return;
13679 }
13680 }
13681 Delegate(kUsub8, &Assembler::usub8, cond, rd, rn, rm);
13682 }
13683
uxtab(Condition cond,Register rd,Register rn,const Operand & operand)13684 void Assembler::uxtab(Condition cond,
13685 Register rd,
13686 Register rn,
13687 const Operand& operand) {
13688 VIXL_ASSERT(AllowAssembler());
13689 CheckIT(cond);
13690 if (operand.IsImmediateShiftedRegister()) {
13691 Register rm = operand.GetBaseRegister();
13692 Shift shift = operand.GetShift();
13693 uint32_t amount = operand.GetShiftAmount();
13694 if (IsUsingT32()) {
13695 // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
13696 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13697 ((amount % 8) == 0) && !rn.Is(pc) &&
13698 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13699 uint32_t amount_ = amount / 8;
13700 EmitT32_32(0xfa50f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13701 rm.GetCode() | (amount_ << 4));
13702 AdvanceIT();
13703 return;
13704 }
13705 } else {
13706 // UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
13707 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13708 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
13709 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13710 uint32_t amount_ = amount / 8;
13711 EmitA32(0x06e00070U | (cond.GetCondition() << 28) |
13712 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
13713 (amount_ << 10));
13714 return;
13715 }
13716 }
13717 }
13718 Delegate(kUxtab, &Assembler::uxtab, cond, rd, rn, operand);
13719 }
13720
uxtab16(Condition cond,Register rd,Register rn,const Operand & operand)13721 void Assembler::uxtab16(Condition cond,
13722 Register rd,
13723 Register rn,
13724 const Operand& operand) {
13725 VIXL_ASSERT(AllowAssembler());
13726 CheckIT(cond);
13727 if (operand.IsImmediateShiftedRegister()) {
13728 Register rm = operand.GetBaseRegister();
13729 Shift shift = operand.GetShift();
13730 uint32_t amount = operand.GetShiftAmount();
13731 if (IsUsingT32()) {
13732 // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
13733 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13734 ((amount % 8) == 0) && !rn.Is(pc) &&
13735 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13736 uint32_t amount_ = amount / 8;
13737 EmitT32_32(0xfa30f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13738 rm.GetCode() | (amount_ << 4));
13739 AdvanceIT();
13740 return;
13741 }
13742 } else {
13743 // UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
13744 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13745 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
13746 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13747 uint32_t amount_ = amount / 8;
13748 EmitA32(0x06c00070U | (cond.GetCondition() << 28) |
13749 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
13750 (amount_ << 10));
13751 return;
13752 }
13753 }
13754 }
13755 Delegate(kUxtab16, &Assembler::uxtab16, cond, rd, rn, operand);
13756 }
13757
uxtah(Condition cond,Register rd,Register rn,const Operand & operand)13758 void Assembler::uxtah(Condition cond,
13759 Register rd,
13760 Register rn,
13761 const Operand& operand) {
13762 VIXL_ASSERT(AllowAssembler());
13763 CheckIT(cond);
13764 if (operand.IsImmediateShiftedRegister()) {
13765 Register rm = operand.GetBaseRegister();
13766 Shift shift = operand.GetShift();
13767 uint32_t amount = operand.GetShiftAmount();
13768 if (IsUsingT32()) {
13769 // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1
13770 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13771 ((amount % 8) == 0) && !rn.Is(pc) &&
13772 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13773 uint32_t amount_ = amount / 8;
13774 EmitT32_32(0xfa10f080U | (rd.GetCode() << 8) | (rn.GetCode() << 16) |
13775 rm.GetCode() | (amount_ << 4));
13776 AdvanceIT();
13777 return;
13778 }
13779 } else {
13780 // UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1
13781 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13782 ((amount % 8) == 0) && cond.IsNotNever() && !rn.Is(pc) &&
13783 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13784 uint32_t amount_ = amount / 8;
13785 EmitA32(0x06f00070U | (cond.GetCondition() << 28) |
13786 (rd.GetCode() << 12) | (rn.GetCode() << 16) | rm.GetCode() |
13787 (amount_ << 10));
13788 return;
13789 }
13790 }
13791 }
13792 Delegate(kUxtah, &Assembler::uxtah, cond, rd, rn, operand);
13793 }
13794
uxtb(Condition cond,EncodingSize size,Register rd,const Operand & operand)13795 void Assembler::uxtb(Condition cond,
13796 EncodingSize size,
13797 Register rd,
13798 const Operand& operand) {
13799 VIXL_ASSERT(AllowAssembler());
13800 CheckIT(cond);
13801 if (operand.IsImmediateShiftedRegister()) {
13802 Register rm = operand.GetBaseRegister();
13803 if (operand.IsPlainRegister()) {
13804 if (IsUsingT32()) {
13805 // UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
13806 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
13807 EmitT32_16(0xb2c0 | rd.GetCode() | (rm.GetCode() << 3));
13808 AdvanceIT();
13809 return;
13810 }
13811 }
13812 }
13813 Shift shift = operand.GetShift();
13814 uint32_t amount = operand.GetShiftAmount();
13815 if (IsUsingT32()) {
13816 // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
13817 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
13818 (amount <= 24) && ((amount % 8) == 0) &&
13819 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13820 uint32_t amount_ = amount / 8;
13821 EmitT32_32(0xfa5ff080U | (rd.GetCode() << 8) | rm.GetCode() |
13822 (amount_ << 4));
13823 AdvanceIT();
13824 return;
13825 }
13826 } else {
13827 // UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
13828 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13829 ((amount % 8) == 0) && cond.IsNotNever() &&
13830 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13831 uint32_t amount_ = amount / 8;
13832 EmitA32(0x06ef0070U | (cond.GetCondition() << 28) |
13833 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
13834 return;
13835 }
13836 }
13837 }
13838 Delegate(kUxtb, &Assembler::uxtb, cond, size, rd, operand);
13839 }
13840
uxtb16(Condition cond,Register rd,const Operand & operand)13841 void Assembler::uxtb16(Condition cond, Register rd, const Operand& operand) {
13842 VIXL_ASSERT(AllowAssembler());
13843 CheckIT(cond);
13844 if (operand.IsImmediateShiftedRegister()) {
13845 Register rm = operand.GetBaseRegister();
13846 Shift shift = operand.GetShift();
13847 uint32_t amount = operand.GetShiftAmount();
13848 if (IsUsingT32()) {
13849 // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1
13850 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13851 ((amount % 8) == 0) &&
13852 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13853 uint32_t amount_ = amount / 8;
13854 EmitT32_32(0xfa3ff080U | (rd.GetCode() << 8) | rm.GetCode() |
13855 (amount_ << 4));
13856 AdvanceIT();
13857 return;
13858 }
13859 } else {
13860 // UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
13861 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13862 ((amount % 8) == 0) && cond.IsNotNever() &&
13863 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13864 uint32_t amount_ = amount / 8;
13865 EmitA32(0x06cf0070U | (cond.GetCondition() << 28) |
13866 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
13867 return;
13868 }
13869 }
13870 }
13871 Delegate(kUxtb16, &Assembler::uxtb16, cond, rd, operand);
13872 }
13873
uxth(Condition cond,EncodingSize size,Register rd,const Operand & operand)13874 void Assembler::uxth(Condition cond,
13875 EncodingSize size,
13876 Register rd,
13877 const Operand& operand) {
13878 VIXL_ASSERT(AllowAssembler());
13879 CheckIT(cond);
13880 if (operand.IsImmediateShiftedRegister()) {
13881 Register rm = operand.GetBaseRegister();
13882 if (operand.IsPlainRegister()) {
13883 if (IsUsingT32()) {
13884 // UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
13885 if (!size.IsWide() && rd.IsLow() && rm.IsLow()) {
13886 EmitT32_16(0xb280 | rd.GetCode() | (rm.GetCode() << 3));
13887 AdvanceIT();
13888 return;
13889 }
13890 }
13891 }
13892 Shift shift = operand.GetShift();
13893 uint32_t amount = operand.GetShiftAmount();
13894 if (IsUsingT32()) {
13895 // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2
13896 if (!size.IsNarrow() && (shift.IsROR() || (amount == 0)) &&
13897 (amount <= 24) && ((amount % 8) == 0) &&
13898 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13899 uint32_t amount_ = amount / 8;
13900 EmitT32_32(0xfa1ff080U | (rd.GetCode() << 8) | rm.GetCode() |
13901 (amount_ << 4));
13902 AdvanceIT();
13903 return;
13904 }
13905 } else {
13906 // UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
13907 if ((shift.IsROR() || (amount == 0)) && (amount <= 24) &&
13908 ((amount % 8) == 0) && cond.IsNotNever() &&
13909 ((!rd.IsPC() && !rm.IsPC()) || AllowUnpredictable())) {
13910 uint32_t amount_ = amount / 8;
13911 EmitA32(0x06ff0070U | (cond.GetCondition() << 28) |
13912 (rd.GetCode() << 12) | rm.GetCode() | (amount_ << 10));
13913 return;
13914 }
13915 }
13916 }
13917 Delegate(kUxth, &Assembler::uxth, cond, size, rd, operand);
13918 }
13919
vaba(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)13920 void Assembler::vaba(
13921 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
13922 VIXL_ASSERT(AllowAssembler());
13923 CheckIT(cond);
13924 Dt_U_size_1 encoded_dt(dt);
13925 if (IsUsingT32()) {
13926 // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1
13927 if (encoded_dt.IsValid()) {
13928 if (cond.Is(al) || AllowStronglyDiscouraged()) {
13929 EmitT32_32(0xef000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13930 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13931 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13932 AdvanceIT();
13933 return;
13934 }
13935 }
13936 } else {
13937 // VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1
13938 if (encoded_dt.IsValid()) {
13939 if (cond.Is(al)) {
13940 EmitA32(0xf2000710U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13941 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13942 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13943 return;
13944 }
13945 }
13946 }
13947 Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
13948 }
13949
vaba(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)13950 void Assembler::vaba(
13951 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
13952 VIXL_ASSERT(AllowAssembler());
13953 CheckIT(cond);
13954 Dt_U_size_1 encoded_dt(dt);
13955 if (IsUsingT32()) {
13956 // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1
13957 if (encoded_dt.IsValid()) {
13958 if (cond.Is(al) || AllowStronglyDiscouraged()) {
13959 EmitT32_32(0xef000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13960 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13961 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13962 AdvanceIT();
13963 return;
13964 }
13965 }
13966 } else {
13967 // VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1
13968 if (encoded_dt.IsValid()) {
13969 if (cond.Is(al)) {
13970 EmitA32(0xf2000750U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13971 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
13972 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13973 return;
13974 }
13975 }
13976 }
13977 Delegate(kVaba, &Assembler::vaba, cond, dt, rd, rn, rm);
13978 }
13979
vabal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)13980 void Assembler::vabal(
13981 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
13982 VIXL_ASSERT(AllowAssembler());
13983 CheckIT(cond);
13984 Dt_U_size_1 encoded_dt(dt);
13985 if (IsUsingT32()) {
13986 // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
13987 if (encoded_dt.IsValid()) {
13988 if (cond.Is(al) || AllowStronglyDiscouraged()) {
13989 EmitT32_32(0xef800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
13990 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
13991 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
13992 AdvanceIT();
13993 return;
13994 }
13995 }
13996 } else {
13997 // VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
13998 if (encoded_dt.IsValid()) {
13999 if (cond.Is(al)) {
14000 EmitA32(0xf2800500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14001 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14002 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14003 return;
14004 }
14005 }
14006 }
14007 Delegate(kVabal, &Assembler::vabal, cond, dt, rd, rn, rm);
14008 }
14009
vabd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14010 void Assembler::vabd(
14011 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14012 VIXL_ASSERT(AllowAssembler());
14013 CheckIT(cond);
14014 Dt_U_size_1 encoded_dt(dt);
14015 if (IsUsingT32()) {
14016 // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
14017 if (dt.Is(F32)) {
14018 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14019 EmitT32_32(0xff200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14020 rm.Encode(5, 0));
14021 AdvanceIT();
14022 return;
14023 }
14024 }
14025 // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14026 if (encoded_dt.IsValid()) {
14027 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14028 EmitT32_32(0xef000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14029 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14030 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14031 AdvanceIT();
14032 return;
14033 }
14034 }
14035 } else {
14036 // VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14037 if (dt.Is(F32)) {
14038 if (cond.Is(al)) {
14039 EmitA32(0xf3200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14040 rm.Encode(5, 0));
14041 return;
14042 }
14043 }
14044 // VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14045 if (encoded_dt.IsValid()) {
14046 if (cond.Is(al)) {
14047 EmitA32(0xf2000700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14048 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14049 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14050 return;
14051 }
14052 }
14053 }
14054 Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
14055 }
14056
vabd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14057 void Assembler::vabd(
14058 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14059 VIXL_ASSERT(AllowAssembler());
14060 CheckIT(cond);
14061 Dt_U_size_1 encoded_dt(dt);
14062 if (IsUsingT32()) {
14063 // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14064 if (dt.Is(F32)) {
14065 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14066 EmitT32_32(0xff200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14067 rm.Encode(5, 0));
14068 AdvanceIT();
14069 return;
14070 }
14071 }
14072 // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14073 if (encoded_dt.IsValid()) {
14074 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14075 EmitT32_32(0xef000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14076 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14077 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14078 AdvanceIT();
14079 return;
14080 }
14081 }
14082 } else {
14083 // VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14084 if (dt.Is(F32)) {
14085 if (cond.Is(al)) {
14086 EmitA32(0xf3200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14087 rm.Encode(5, 0));
14088 return;
14089 }
14090 }
14091 // VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14092 if (encoded_dt.IsValid()) {
14093 if (cond.Is(al)) {
14094 EmitA32(0xf2000740U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14095 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14096 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14097 return;
14098 }
14099 }
14100 }
14101 Delegate(kVabd, &Assembler::vabd, cond, dt, rd, rn, rm);
14102 }
14103
vabdl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)14104 void Assembler::vabdl(
14105 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
14106 VIXL_ASSERT(AllowAssembler());
14107 CheckIT(cond);
14108 Dt_U_size_1 encoded_dt(dt);
14109 if (IsUsingT32()) {
14110 // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
14111 if (encoded_dt.IsValid()) {
14112 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14113 EmitT32_32(0xef800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14114 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14115 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14116 AdvanceIT();
14117 return;
14118 }
14119 }
14120 } else {
14121 // VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
14122 if (encoded_dt.IsValid()) {
14123 if (cond.Is(al)) {
14124 EmitA32(0xf2800700U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14125 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14126 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14127 return;
14128 }
14129 }
14130 }
14131 Delegate(kVabdl, &Assembler::vabdl, cond, dt, rd, rn, rm);
14132 }
14133
vabs(Condition cond,DataType dt,DRegister rd,DRegister rm)14134 void Assembler::vabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
14135 VIXL_ASSERT(AllowAssembler());
14136 CheckIT(cond);
14137 Dt_F_size_1 encoded_dt(dt);
14138 if (IsUsingT32()) {
14139 // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
14140 if (encoded_dt.IsValid()) {
14141 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14142 EmitT32_32(0xffb10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14143 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14144 rd.Encode(22, 12) | rm.Encode(5, 0));
14145 AdvanceIT();
14146 return;
14147 }
14148 }
14149 // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
14150 if (dt.Is(F64)) {
14151 EmitT32_32(0xeeb00bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14152 AdvanceIT();
14153 return;
14154 }
14155 } else {
14156 // VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
14157 if (encoded_dt.IsValid()) {
14158 if (cond.Is(al)) {
14159 EmitA32(0xf3b10300U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14160 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14161 rd.Encode(22, 12) | rm.Encode(5, 0));
14162 return;
14163 }
14164 }
14165 // VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
14166 if (dt.Is(F64) && cond.IsNotNever()) {
14167 EmitA32(0x0eb00bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14168 rm.Encode(5, 0));
14169 return;
14170 }
14171 }
14172 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
14173 }
14174
vabs(Condition cond,DataType dt,QRegister rd,QRegister rm)14175 void Assembler::vabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
14176 VIXL_ASSERT(AllowAssembler());
14177 CheckIT(cond);
14178 Dt_F_size_1 encoded_dt(dt);
14179 if (IsUsingT32()) {
14180 // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
14181 if (encoded_dt.IsValid()) {
14182 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14183 EmitT32_32(0xffb10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14184 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14185 rd.Encode(22, 12) | rm.Encode(5, 0));
14186 AdvanceIT();
14187 return;
14188 }
14189 }
14190 } else {
14191 // VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
14192 if (encoded_dt.IsValid()) {
14193 if (cond.Is(al)) {
14194 EmitA32(0xf3b10340U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
14195 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
14196 rd.Encode(22, 12) | rm.Encode(5, 0));
14197 return;
14198 }
14199 }
14200 }
14201 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
14202 }
14203
vabs(Condition cond,DataType dt,SRegister rd,SRegister rm)14204 void Assembler::vabs(Condition cond, DataType dt, SRegister rd, SRegister rm) {
14205 VIXL_ASSERT(AllowAssembler());
14206 CheckIT(cond);
14207 if (IsUsingT32()) {
14208 // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
14209 if (dt.Is(F32)) {
14210 EmitT32_32(0xeeb00ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
14211 AdvanceIT();
14212 return;
14213 }
14214 } else {
14215 // VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
14216 if (dt.Is(F32) && cond.IsNotNever()) {
14217 EmitA32(0x0eb00ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14218 rm.Encode(5, 0));
14219 return;
14220 }
14221 }
14222 Delegate(kVabs, &Assembler::vabs, cond, dt, rd, rm);
14223 }
14224
vacge(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14225 void Assembler::vacge(
14226 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14227 VIXL_ASSERT(AllowAssembler());
14228 CheckIT(cond);
14229 if (IsUsingT32()) {
14230 // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
14231 if (dt.Is(F32)) {
14232 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14233 EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14234 rm.Encode(5, 0));
14235 AdvanceIT();
14236 return;
14237 }
14238 }
14239 } else {
14240 // VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14241 if (dt.Is(F32)) {
14242 if (cond.Is(al)) {
14243 EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14244 rm.Encode(5, 0));
14245 return;
14246 }
14247 }
14248 }
14249 Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
14250 }
14251
vacge(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14252 void Assembler::vacge(
14253 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14254 VIXL_ASSERT(AllowAssembler());
14255 CheckIT(cond);
14256 if (IsUsingT32()) {
14257 // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14258 if (dt.Is(F32)) {
14259 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14260 EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14261 rm.Encode(5, 0));
14262 AdvanceIT();
14263 return;
14264 }
14265 }
14266 } else {
14267 // VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14268 if (dt.Is(F32)) {
14269 if (cond.Is(al)) {
14270 EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14271 rm.Encode(5, 0));
14272 return;
14273 }
14274 }
14275 }
14276 Delegate(kVacge, &Assembler::vacge, cond, dt, rd, rn, rm);
14277 }
14278
vacgt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14279 void Assembler::vacgt(
14280 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14281 VIXL_ASSERT(AllowAssembler());
14282 CheckIT(cond);
14283 if (IsUsingT32()) {
14284 // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
14285 if (dt.Is(F32)) {
14286 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14287 EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14288 rm.Encode(5, 0));
14289 AdvanceIT();
14290 return;
14291 }
14292 }
14293 } else {
14294 // VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14295 if (dt.Is(F32)) {
14296 if (cond.Is(al)) {
14297 EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14298 rm.Encode(5, 0));
14299 return;
14300 }
14301 }
14302 }
14303 Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
14304 }
14305
vacgt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14306 void Assembler::vacgt(
14307 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14308 VIXL_ASSERT(AllowAssembler());
14309 CheckIT(cond);
14310 if (IsUsingT32()) {
14311 // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14312 if (dt.Is(F32)) {
14313 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14314 EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14315 rm.Encode(5, 0));
14316 AdvanceIT();
14317 return;
14318 }
14319 }
14320 } else {
14321 // VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14322 if (dt.Is(F32)) {
14323 if (cond.Is(al)) {
14324 EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14325 rm.Encode(5, 0));
14326 return;
14327 }
14328 }
14329 }
14330 Delegate(kVacgt, &Assembler::vacgt, cond, dt, rd, rn, rm);
14331 }
14332
vacle(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14333 void Assembler::vacle(
14334 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14335 VIXL_ASSERT(AllowAssembler());
14336 CheckIT(cond);
14337 if (IsUsingT32()) {
14338 // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
14339 if (dt.Is(F32)) {
14340 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14341 EmitT32_32(0xff000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14342 rm.Encode(5, 0));
14343 AdvanceIT();
14344 return;
14345 }
14346 }
14347 } else {
14348 // VACLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14349 if (dt.Is(F32)) {
14350 if (cond.Is(al)) {
14351 EmitA32(0xf3000e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14352 rm.Encode(5, 0));
14353 return;
14354 }
14355 }
14356 }
14357 Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
14358 }
14359
vacle(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14360 void Assembler::vacle(
14361 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14362 VIXL_ASSERT(AllowAssembler());
14363 CheckIT(cond);
14364 if (IsUsingT32()) {
14365 // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14366 if (dt.Is(F32)) {
14367 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14368 EmitT32_32(0xff000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14369 rm.Encode(5, 0));
14370 AdvanceIT();
14371 return;
14372 }
14373 }
14374 } else {
14375 // VACLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14376 if (dt.Is(F32)) {
14377 if (cond.Is(al)) {
14378 EmitA32(0xf3000e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14379 rm.Encode(5, 0));
14380 return;
14381 }
14382 }
14383 }
14384 Delegate(kVacle, &Assembler::vacle, cond, dt, rd, rn, rm);
14385 }
14386
vaclt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14387 void Assembler::vaclt(
14388 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14389 VIXL_ASSERT(AllowAssembler());
14390 CheckIT(cond);
14391 if (IsUsingT32()) {
14392 // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
14393 if (dt.Is(F32)) {
14394 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14395 EmitT32_32(0xff200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14396 rm.Encode(5, 0));
14397 AdvanceIT();
14398 return;
14399 }
14400 }
14401 } else {
14402 // VACLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14403 if (dt.Is(F32)) {
14404 if (cond.Is(al)) {
14405 EmitA32(0xf3200e10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14406 rm.Encode(5, 0));
14407 return;
14408 }
14409 }
14410 }
14411 Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
14412 }
14413
vaclt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14414 void Assembler::vaclt(
14415 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14416 VIXL_ASSERT(AllowAssembler());
14417 CheckIT(cond);
14418 if (IsUsingT32()) {
14419 // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14420 if (dt.Is(F32)) {
14421 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14422 EmitT32_32(0xff200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14423 rm.Encode(5, 0));
14424 AdvanceIT();
14425 return;
14426 }
14427 }
14428 } else {
14429 // VACLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14430 if (dt.Is(F32)) {
14431 if (cond.Is(al)) {
14432 EmitA32(0xf3200e50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14433 rm.Encode(5, 0));
14434 return;
14435 }
14436 }
14437 }
14438 Delegate(kVaclt, &Assembler::vaclt, cond, dt, rd, rn, rm);
14439 }
14440
vadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14441 void Assembler::vadd(
14442 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14443 VIXL_ASSERT(AllowAssembler());
14444 CheckIT(cond);
14445 Dt_size_2 encoded_dt(dt);
14446 if (IsUsingT32()) {
14447 // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
14448 if (dt.Is(F32)) {
14449 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14450 EmitT32_32(0xef000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14451 rm.Encode(5, 0));
14452 AdvanceIT();
14453 return;
14454 }
14455 }
14456 // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
14457 if (dt.Is(F64)) {
14458 EmitT32_32(0xee300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14459 rm.Encode(5, 0));
14460 AdvanceIT();
14461 return;
14462 }
14463 // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
14464 if (encoded_dt.IsValid()) {
14465 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14466 EmitT32_32(0xef000800U | (encoded_dt.GetEncodingValue() << 20) |
14467 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14468 AdvanceIT();
14469 return;
14470 }
14471 }
14472 } else {
14473 // VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
14474 if (dt.Is(F32)) {
14475 if (cond.Is(al)) {
14476 EmitA32(0xf2000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14477 rm.Encode(5, 0));
14478 return;
14479 }
14480 }
14481 // VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
14482 if (dt.Is(F64) && cond.IsNotNever()) {
14483 EmitA32(0x0e300b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14484 rn.Encode(7, 16) | rm.Encode(5, 0));
14485 return;
14486 }
14487 // VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
14488 if (encoded_dt.IsValid()) {
14489 if (cond.Is(al)) {
14490 EmitA32(0xf2000800U | (encoded_dt.GetEncodingValue() << 20) |
14491 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14492 return;
14493 }
14494 }
14495 }
14496 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
14497 }
14498
vadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14499 void Assembler::vadd(
14500 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14501 VIXL_ASSERT(AllowAssembler());
14502 CheckIT(cond);
14503 Dt_size_2 encoded_dt(dt);
14504 if (IsUsingT32()) {
14505 // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
14506 if (dt.Is(F32)) {
14507 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14508 EmitT32_32(0xef000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14509 rm.Encode(5, 0));
14510 AdvanceIT();
14511 return;
14512 }
14513 }
14514 // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
14515 if (encoded_dt.IsValid()) {
14516 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14517 EmitT32_32(0xef000840U | (encoded_dt.GetEncodingValue() << 20) |
14518 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14519 AdvanceIT();
14520 return;
14521 }
14522 }
14523 } else {
14524 // VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
14525 if (dt.Is(F32)) {
14526 if (cond.Is(al)) {
14527 EmitA32(0xf2000d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14528 rm.Encode(5, 0));
14529 return;
14530 }
14531 }
14532 // VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
14533 if (encoded_dt.IsValid()) {
14534 if (cond.Is(al)) {
14535 EmitA32(0xf2000840U | (encoded_dt.GetEncodingValue() << 20) |
14536 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14537 return;
14538 }
14539 }
14540 }
14541 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
14542 }
14543
vadd(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)14544 void Assembler::vadd(
14545 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
14546 VIXL_ASSERT(AllowAssembler());
14547 CheckIT(cond);
14548 if (IsUsingT32()) {
14549 // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
14550 if (dt.Is(F32)) {
14551 EmitT32_32(0xee300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14552 rm.Encode(5, 0));
14553 AdvanceIT();
14554 return;
14555 }
14556 } else {
14557 // VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
14558 if (dt.Is(F32) && cond.IsNotNever()) {
14559 EmitA32(0x0e300a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
14560 rn.Encode(7, 16) | rm.Encode(5, 0));
14561 return;
14562 }
14563 }
14564 Delegate(kVadd, &Assembler::vadd, cond, dt, rd, rn, rm);
14565 }
14566
vaddhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)14567 void Assembler::vaddhn(
14568 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
14569 VIXL_ASSERT(AllowAssembler());
14570 CheckIT(cond);
14571 Dt_size_3 encoded_dt(dt);
14572 if (IsUsingT32()) {
14573 // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
14574 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
14575 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14576 EmitT32_32(0xef800400U | (encoded_dt.GetEncodingValue() << 20) |
14577 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14578 AdvanceIT();
14579 return;
14580 }
14581 }
14582 } else {
14583 // VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
14584 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
14585 if (cond.Is(al)) {
14586 EmitA32(0xf2800400U | (encoded_dt.GetEncodingValue() << 20) |
14587 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14588 return;
14589 }
14590 }
14591 }
14592 Delegate(kVaddhn, &Assembler::vaddhn, cond, dt, rd, rn, rm);
14593 }
14594
vaddl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)14595 void Assembler::vaddl(
14596 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
14597 VIXL_ASSERT(AllowAssembler());
14598 CheckIT(cond);
14599 Dt_U_size_1 encoded_dt(dt);
14600 if (IsUsingT32()) {
14601 // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
14602 if (encoded_dt.IsValid()) {
14603 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14604 EmitT32_32(0xef800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14605 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14606 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14607 AdvanceIT();
14608 return;
14609 }
14610 }
14611 } else {
14612 // VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
14613 if (encoded_dt.IsValid()) {
14614 if (cond.Is(al)) {
14615 EmitA32(0xf2800000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14616 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14617 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14618 return;
14619 }
14620 }
14621 }
14622 Delegate(kVaddl, &Assembler::vaddl, cond, dt, rd, rn, rm);
14623 }
14624
vaddw(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegister rm)14625 void Assembler::vaddw(
14626 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
14627 VIXL_ASSERT(AllowAssembler());
14628 CheckIT(cond);
14629 Dt_U_size_1 encoded_dt(dt);
14630 if (IsUsingT32()) {
14631 // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
14632 if (encoded_dt.IsValid()) {
14633 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14634 EmitT32_32(0xef800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14635 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
14636 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14637 AdvanceIT();
14638 return;
14639 }
14640 }
14641 } else {
14642 // VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
14643 if (encoded_dt.IsValid()) {
14644 if (cond.Is(al)) {
14645 EmitA32(0xf2800100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
14646 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
14647 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
14648 return;
14649 }
14650 }
14651 }
14652 Delegate(kVaddw, &Assembler::vaddw, cond, dt, rd, rn, rm);
14653 }
14654
vand(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)14655 void Assembler::vand(Condition cond,
14656 DataType dt,
14657 DRegister rd,
14658 DRegister rn,
14659 const DOperand& operand) {
14660 VIXL_ASSERT(AllowAssembler());
14661 CheckIT(cond);
14662 if (operand.IsImmediate()) {
14663 ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
14664 if (IsUsingT32()) {
14665 // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
14666 if (encoded_dt.IsValid() && rd.Is(rn)) {
14667 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14668 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
14669 rd.Encode(22, 12) |
14670 (encoded_dt.GetEncodedImmediate() & 0xf) |
14671 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14672 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
14673 AdvanceIT();
14674 return;
14675 }
14676 }
14677 } else {
14678 // VAND{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
14679 if (encoded_dt.IsValid() && rd.Is(rn)) {
14680 if (cond.Is(al)) {
14681 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
14682 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
14683 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14684 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
14685 return;
14686 }
14687 }
14688 }
14689 }
14690 if (operand.IsRegister()) {
14691 DRegister rm = operand.GetRegister();
14692 USE(dt);
14693 if (IsUsingT32()) {
14694 // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
14695 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14696 EmitT32_32(0xef000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14697 rm.Encode(5, 0));
14698 AdvanceIT();
14699 return;
14700 }
14701 } else {
14702 // VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
14703 if (cond.Is(al)) {
14704 EmitA32(0xf2000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14705 rm.Encode(5, 0));
14706 return;
14707 }
14708 }
14709 }
14710 Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
14711 }
14712
vand(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)14713 void Assembler::vand(Condition cond,
14714 DataType dt,
14715 QRegister rd,
14716 QRegister rn,
14717 const QOperand& operand) {
14718 VIXL_ASSERT(AllowAssembler());
14719 CheckIT(cond);
14720 if (operand.IsImmediate()) {
14721 ImmediateVand encoded_dt(dt, operand.GetNeonImmediate());
14722 if (IsUsingT32()) {
14723 // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
14724 if (encoded_dt.IsValid() && rd.Is(rn)) {
14725 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14726 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
14727 rd.Encode(22, 12) |
14728 (encoded_dt.GetEncodedImmediate() & 0xf) |
14729 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14730 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
14731 AdvanceIT();
14732 return;
14733 }
14734 }
14735 } else {
14736 // VAND{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
14737 if (encoded_dt.IsValid() && rd.Is(rn)) {
14738 if (cond.Is(al)) {
14739 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
14740 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
14741 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14742 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
14743 return;
14744 }
14745 }
14746 }
14747 }
14748 if (operand.IsRegister()) {
14749 QRegister rm = operand.GetRegister();
14750 USE(dt);
14751 if (IsUsingT32()) {
14752 // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
14753 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14754 EmitT32_32(0xef000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14755 rm.Encode(5, 0));
14756 AdvanceIT();
14757 return;
14758 }
14759 } else {
14760 // VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
14761 if (cond.Is(al)) {
14762 EmitA32(0xf2000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14763 rm.Encode(5, 0));
14764 return;
14765 }
14766 }
14767 }
14768 Delegate(kVand, &Assembler::vand, cond, dt, rd, rn, operand);
14769 }
14770
vbic(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)14771 void Assembler::vbic(Condition cond,
14772 DataType dt,
14773 DRegister rd,
14774 DRegister rn,
14775 const DOperand& operand) {
14776 VIXL_ASSERT(AllowAssembler());
14777 CheckIT(cond);
14778 if (operand.IsImmediate()) {
14779 ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
14780 if (IsUsingT32()) {
14781 // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
14782 if (encoded_dt.IsValid() && rd.Is(rn)) {
14783 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14784 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
14785 rd.Encode(22, 12) |
14786 (encoded_dt.GetEncodedImmediate() & 0xf) |
14787 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14788 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
14789 AdvanceIT();
14790 return;
14791 }
14792 }
14793 } else {
14794 // VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
14795 if (encoded_dt.IsValid() && rd.Is(rn)) {
14796 if (cond.Is(al)) {
14797 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
14798 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
14799 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14800 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
14801 return;
14802 }
14803 }
14804 }
14805 }
14806 if (operand.IsRegister()) {
14807 DRegister rm = operand.GetRegister();
14808 USE(dt);
14809 if (IsUsingT32()) {
14810 // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
14811 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14812 EmitT32_32(0xef100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14813 rm.Encode(5, 0));
14814 AdvanceIT();
14815 return;
14816 }
14817 } else {
14818 // VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
14819 if (cond.Is(al)) {
14820 EmitA32(0xf2100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14821 rm.Encode(5, 0));
14822 return;
14823 }
14824 }
14825 }
14826 Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
14827 }
14828
vbic(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)14829 void Assembler::vbic(Condition cond,
14830 DataType dt,
14831 QRegister rd,
14832 QRegister rn,
14833 const QOperand& operand) {
14834 VIXL_ASSERT(AllowAssembler());
14835 CheckIT(cond);
14836 if (operand.IsImmediate()) {
14837 ImmediateVbic encoded_dt(dt, operand.GetNeonImmediate());
14838 if (IsUsingT32()) {
14839 // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
14840 if (encoded_dt.IsValid() && rd.Is(rn)) {
14841 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14842 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
14843 rd.Encode(22, 12) |
14844 (encoded_dt.GetEncodedImmediate() & 0xf) |
14845 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14846 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
14847 AdvanceIT();
14848 return;
14849 }
14850 }
14851 } else {
14852 // VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
14853 if (encoded_dt.IsValid() && rd.Is(rn)) {
14854 if (cond.Is(al)) {
14855 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
14856 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
14857 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
14858 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
14859 return;
14860 }
14861 }
14862 }
14863 }
14864 if (operand.IsRegister()) {
14865 QRegister rm = operand.GetRegister();
14866 USE(dt);
14867 if (IsUsingT32()) {
14868 // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
14869 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14870 EmitT32_32(0xef100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14871 rm.Encode(5, 0));
14872 AdvanceIT();
14873 return;
14874 }
14875 } else {
14876 // VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
14877 if (cond.Is(al)) {
14878 EmitA32(0xf2100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14879 rm.Encode(5, 0));
14880 return;
14881 }
14882 }
14883 }
14884 Delegate(kVbic, &Assembler::vbic, cond, dt, rd, rn, operand);
14885 }
14886
vbif(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14887 void Assembler::vbif(
14888 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14889 VIXL_ASSERT(AllowAssembler());
14890 CheckIT(cond);
14891 USE(dt);
14892 if (IsUsingT32()) {
14893 // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
14894 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14895 EmitT32_32(0xff300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14896 rm.Encode(5, 0));
14897 AdvanceIT();
14898 return;
14899 }
14900 } else {
14901 // VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
14902 if (cond.Is(al)) {
14903 EmitA32(0xf3300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14904 rm.Encode(5, 0));
14905 return;
14906 }
14907 }
14908 Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
14909 }
14910
vbif(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14911 void Assembler::vbif(
14912 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14913 VIXL_ASSERT(AllowAssembler());
14914 CheckIT(cond);
14915 USE(dt);
14916 if (IsUsingT32()) {
14917 // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
14918 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14919 EmitT32_32(0xff300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14920 rm.Encode(5, 0));
14921 AdvanceIT();
14922 return;
14923 }
14924 } else {
14925 // VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
14926 if (cond.Is(al)) {
14927 EmitA32(0xf3300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14928 rm.Encode(5, 0));
14929 return;
14930 }
14931 }
14932 Delegate(kVbif, &Assembler::vbif, cond, dt, rd, rn, rm);
14933 }
14934
vbit(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14935 void Assembler::vbit(
14936 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14937 VIXL_ASSERT(AllowAssembler());
14938 CheckIT(cond);
14939 USE(dt);
14940 if (IsUsingT32()) {
14941 // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
14942 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14943 EmitT32_32(0xff200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14944 rm.Encode(5, 0));
14945 AdvanceIT();
14946 return;
14947 }
14948 } else {
14949 // VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
14950 if (cond.Is(al)) {
14951 EmitA32(0xf3200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14952 rm.Encode(5, 0));
14953 return;
14954 }
14955 }
14956 Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
14957 }
14958
vbit(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)14959 void Assembler::vbit(
14960 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
14961 VIXL_ASSERT(AllowAssembler());
14962 CheckIT(cond);
14963 USE(dt);
14964 if (IsUsingT32()) {
14965 // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
14966 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14967 EmitT32_32(0xff200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14968 rm.Encode(5, 0));
14969 AdvanceIT();
14970 return;
14971 }
14972 } else {
14973 // VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
14974 if (cond.Is(al)) {
14975 EmitA32(0xf3200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14976 rm.Encode(5, 0));
14977 return;
14978 }
14979 }
14980 Delegate(kVbit, &Assembler::vbit, cond, dt, rd, rn, rm);
14981 }
14982
vbsl(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)14983 void Assembler::vbsl(
14984 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
14985 VIXL_ASSERT(AllowAssembler());
14986 CheckIT(cond);
14987 USE(dt);
14988 if (IsUsingT32()) {
14989 // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
14990 if (cond.Is(al) || AllowStronglyDiscouraged()) {
14991 EmitT32_32(0xff100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
14992 rm.Encode(5, 0));
14993 AdvanceIT();
14994 return;
14995 }
14996 } else {
14997 // VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
14998 if (cond.Is(al)) {
14999 EmitA32(0xf3100110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15000 rm.Encode(5, 0));
15001 return;
15002 }
15003 }
15004 Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
15005 }
15006
vbsl(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)15007 void Assembler::vbsl(
15008 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15009 VIXL_ASSERT(AllowAssembler());
15010 CheckIT(cond);
15011 USE(dt);
15012 if (IsUsingT32()) {
15013 // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
15014 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15015 EmitT32_32(0xff100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15016 rm.Encode(5, 0));
15017 AdvanceIT();
15018 return;
15019 }
15020 } else {
15021 // VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
15022 if (cond.Is(al)) {
15023 EmitA32(0xf3100150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15024 rm.Encode(5, 0));
15025 return;
15026 }
15027 }
15028 Delegate(kVbsl, &Assembler::vbsl, cond, dt, rd, rn, rm);
15029 }
15030
vceq(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)15031 void Assembler::vceq(Condition cond,
15032 DataType dt,
15033 DRegister rd,
15034 DRegister rm,
15035 const DOperand& operand) {
15036 VIXL_ASSERT(AllowAssembler());
15037 CheckIT(cond);
15038 if (operand.IsImmediate()) {
15039 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15040 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15041 Dt_F_size_2 encoded_dt(dt);
15042 if (IsUsingT32()) {
15043 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
15044 if (encoded_dt.IsValid() && (imm == 0)) {
15045 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15046 EmitT32_32(0xffb10100U |
15047 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15048 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15049 rd.Encode(22, 12) | rm.Encode(5, 0));
15050 AdvanceIT();
15051 return;
15052 }
15053 }
15054 } else {
15055 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
15056 if (encoded_dt.IsValid() && (imm == 0)) {
15057 if (cond.Is(al)) {
15058 EmitA32(0xf3b10100U |
15059 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15060 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15061 rd.Encode(22, 12) | rm.Encode(5, 0));
15062 return;
15063 }
15064 }
15065 }
15066 }
15067 }
15068 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
15069 }
15070
vceq(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)15071 void Assembler::vceq(Condition cond,
15072 DataType dt,
15073 QRegister rd,
15074 QRegister rm,
15075 const QOperand& operand) {
15076 VIXL_ASSERT(AllowAssembler());
15077 CheckIT(cond);
15078 if (operand.IsImmediate()) {
15079 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15080 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15081 Dt_F_size_2 encoded_dt(dt);
15082 if (IsUsingT32()) {
15083 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
15084 if (encoded_dt.IsValid() && (imm == 0)) {
15085 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15086 EmitT32_32(0xffb10140U |
15087 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15088 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15089 rd.Encode(22, 12) | rm.Encode(5, 0));
15090 AdvanceIT();
15091 return;
15092 }
15093 }
15094 } else {
15095 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
15096 if (encoded_dt.IsValid() && (imm == 0)) {
15097 if (cond.Is(al)) {
15098 EmitA32(0xf3b10140U |
15099 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15100 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15101 rd.Encode(22, 12) | rm.Encode(5, 0));
15102 return;
15103 }
15104 }
15105 }
15106 }
15107 }
15108 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rm, operand);
15109 }
15110
vceq(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)15111 void Assembler::vceq(
15112 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15113 VIXL_ASSERT(AllowAssembler());
15114 CheckIT(cond);
15115 Dt_size_4 encoded_dt(dt);
15116 Dt_sz_1 encoded_dt_2(dt);
15117 if (IsUsingT32()) {
15118 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
15119 if (encoded_dt.IsValid()) {
15120 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15121 EmitT32_32(0xff000810U | (encoded_dt.GetEncodingValue() << 20) |
15122 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15123 AdvanceIT();
15124 return;
15125 }
15126 }
15127 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2
15128 if (encoded_dt_2.IsValid()) {
15129 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15130 EmitT32_32(0xef000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
15131 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15132 AdvanceIT();
15133 return;
15134 }
15135 }
15136 } else {
15137 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
15138 if (encoded_dt.IsValid()) {
15139 if (cond.Is(al)) {
15140 EmitA32(0xf3000810U | (encoded_dt.GetEncodingValue() << 20) |
15141 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15142 return;
15143 }
15144 }
15145 // VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2
15146 if (encoded_dt_2.IsValid()) {
15147 if (cond.Is(al)) {
15148 EmitA32(0xf2000e00U | (encoded_dt_2.GetEncodingValue() << 20) |
15149 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15150 return;
15151 }
15152 }
15153 }
15154 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
15155 }
15156
vceq(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)15157 void Assembler::vceq(
15158 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15159 VIXL_ASSERT(AllowAssembler());
15160 CheckIT(cond);
15161 Dt_size_4 encoded_dt(dt);
15162 Dt_sz_1 encoded_dt_2(dt);
15163 if (IsUsingT32()) {
15164 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
15165 if (encoded_dt.IsValid()) {
15166 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15167 EmitT32_32(0xff000850U | (encoded_dt.GetEncodingValue() << 20) |
15168 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15169 AdvanceIT();
15170 return;
15171 }
15172 }
15173 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2
15174 if (encoded_dt_2.IsValid()) {
15175 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15176 EmitT32_32(0xef000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
15177 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15178 AdvanceIT();
15179 return;
15180 }
15181 }
15182 } else {
15183 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
15184 if (encoded_dt.IsValid()) {
15185 if (cond.Is(al)) {
15186 EmitA32(0xf3000850U | (encoded_dt.GetEncodingValue() << 20) |
15187 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15188 return;
15189 }
15190 }
15191 // VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2
15192 if (encoded_dt_2.IsValid()) {
15193 if (cond.Is(al)) {
15194 EmitA32(0xf2000e40U | (encoded_dt_2.GetEncodingValue() << 20) |
15195 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15196 return;
15197 }
15198 }
15199 }
15200 Delegate(kVceq, &Assembler::vceq, cond, dt, rd, rn, rm);
15201 }
15202
vcge(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)15203 void Assembler::vcge(Condition cond,
15204 DataType dt,
15205 DRegister rd,
15206 DRegister rm,
15207 const DOperand& operand) {
15208 VIXL_ASSERT(AllowAssembler());
15209 CheckIT(cond);
15210 if (operand.IsImmediate()) {
15211 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15212 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15213 Dt_F_size_1 encoded_dt(dt);
15214 if (IsUsingT32()) {
15215 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
15216 if (encoded_dt.IsValid() && (imm == 0)) {
15217 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15218 EmitT32_32(0xffb10080U |
15219 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15220 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15221 rd.Encode(22, 12) | rm.Encode(5, 0));
15222 AdvanceIT();
15223 return;
15224 }
15225 }
15226 } else {
15227 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
15228 if (encoded_dt.IsValid() && (imm == 0)) {
15229 if (cond.Is(al)) {
15230 EmitA32(0xf3b10080U |
15231 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15232 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15233 rd.Encode(22, 12) | rm.Encode(5, 0));
15234 return;
15235 }
15236 }
15237 }
15238 }
15239 }
15240 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
15241 }
15242
vcge(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)15243 void Assembler::vcge(Condition cond,
15244 DataType dt,
15245 QRegister rd,
15246 QRegister rm,
15247 const QOperand& operand) {
15248 VIXL_ASSERT(AllowAssembler());
15249 CheckIT(cond);
15250 if (operand.IsImmediate()) {
15251 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15252 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15253 Dt_F_size_1 encoded_dt(dt);
15254 if (IsUsingT32()) {
15255 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
15256 if (encoded_dt.IsValid() && (imm == 0)) {
15257 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15258 EmitT32_32(0xffb100c0U |
15259 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15260 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15261 rd.Encode(22, 12) | rm.Encode(5, 0));
15262 AdvanceIT();
15263 return;
15264 }
15265 }
15266 } else {
15267 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
15268 if (encoded_dt.IsValid() && (imm == 0)) {
15269 if (cond.Is(al)) {
15270 EmitA32(0xf3b100c0U |
15271 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15272 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15273 rd.Encode(22, 12) | rm.Encode(5, 0));
15274 return;
15275 }
15276 }
15277 }
15278 }
15279 }
15280 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rm, operand);
15281 }
15282
vcge(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)15283 void Assembler::vcge(
15284 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15285 VIXL_ASSERT(AllowAssembler());
15286 CheckIT(cond);
15287 Dt_U_size_1 encoded_dt(dt);
15288 if (IsUsingT32()) {
15289 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
15290 if (encoded_dt.IsValid()) {
15291 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15292 EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15293 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15294 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15295 AdvanceIT();
15296 return;
15297 }
15298 }
15299 // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
15300 if (dt.Is(F32)) {
15301 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15302 EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15303 rm.Encode(5, 0));
15304 AdvanceIT();
15305 return;
15306 }
15307 }
15308 } else {
15309 // VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
15310 if (encoded_dt.IsValid()) {
15311 if (cond.Is(al)) {
15312 EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15313 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15314 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15315 return;
15316 }
15317 }
15318 // VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
15319 if (dt.Is(F32)) {
15320 if (cond.Is(al)) {
15321 EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15322 rm.Encode(5, 0));
15323 return;
15324 }
15325 }
15326 }
15327 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
15328 }
15329
vcge(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)15330 void Assembler::vcge(
15331 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15332 VIXL_ASSERT(AllowAssembler());
15333 CheckIT(cond);
15334 Dt_U_size_1 encoded_dt(dt);
15335 if (IsUsingT32()) {
15336 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
15337 if (encoded_dt.IsValid()) {
15338 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15339 EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15340 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15341 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15342 AdvanceIT();
15343 return;
15344 }
15345 }
15346 // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
15347 if (dt.Is(F32)) {
15348 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15349 EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15350 rm.Encode(5, 0));
15351 AdvanceIT();
15352 return;
15353 }
15354 }
15355 } else {
15356 // VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
15357 if (encoded_dt.IsValid()) {
15358 if (cond.Is(al)) {
15359 EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15360 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15361 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15362 return;
15363 }
15364 }
15365 // VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
15366 if (dt.Is(F32)) {
15367 if (cond.Is(al)) {
15368 EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15369 rm.Encode(5, 0));
15370 return;
15371 }
15372 }
15373 }
15374 Delegate(kVcge, &Assembler::vcge, cond, dt, rd, rn, rm);
15375 }
15376
vcgt(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)15377 void Assembler::vcgt(Condition cond,
15378 DataType dt,
15379 DRegister rd,
15380 DRegister rm,
15381 const DOperand& operand) {
15382 VIXL_ASSERT(AllowAssembler());
15383 CheckIT(cond);
15384 if (operand.IsImmediate()) {
15385 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15386 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15387 Dt_F_size_1 encoded_dt(dt);
15388 if (IsUsingT32()) {
15389 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
15390 if (encoded_dt.IsValid() && (imm == 0)) {
15391 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15392 EmitT32_32(0xffb10000U |
15393 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15394 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15395 rd.Encode(22, 12) | rm.Encode(5, 0));
15396 AdvanceIT();
15397 return;
15398 }
15399 }
15400 } else {
15401 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
15402 if (encoded_dt.IsValid() && (imm == 0)) {
15403 if (cond.Is(al)) {
15404 EmitA32(0xf3b10000U |
15405 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15406 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15407 rd.Encode(22, 12) | rm.Encode(5, 0));
15408 return;
15409 }
15410 }
15411 }
15412 }
15413 }
15414 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
15415 }
15416
vcgt(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)15417 void Assembler::vcgt(Condition cond,
15418 DataType dt,
15419 QRegister rd,
15420 QRegister rm,
15421 const QOperand& operand) {
15422 VIXL_ASSERT(AllowAssembler());
15423 CheckIT(cond);
15424 if (operand.IsImmediate()) {
15425 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15426 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15427 Dt_F_size_1 encoded_dt(dt);
15428 if (IsUsingT32()) {
15429 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
15430 if (encoded_dt.IsValid() && (imm == 0)) {
15431 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15432 EmitT32_32(0xffb10040U |
15433 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15434 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15435 rd.Encode(22, 12) | rm.Encode(5, 0));
15436 AdvanceIT();
15437 return;
15438 }
15439 }
15440 } else {
15441 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
15442 if (encoded_dt.IsValid() && (imm == 0)) {
15443 if (cond.Is(al)) {
15444 EmitA32(0xf3b10040U |
15445 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15446 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15447 rd.Encode(22, 12) | rm.Encode(5, 0));
15448 return;
15449 }
15450 }
15451 }
15452 }
15453 }
15454 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rm, operand);
15455 }
15456
vcgt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)15457 void Assembler::vcgt(
15458 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15459 VIXL_ASSERT(AllowAssembler());
15460 CheckIT(cond);
15461 Dt_U_size_1 encoded_dt(dt);
15462 if (IsUsingT32()) {
15463 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
15464 if (encoded_dt.IsValid()) {
15465 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15466 EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15467 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15468 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15469 AdvanceIT();
15470 return;
15471 }
15472 }
15473 // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
15474 if (dt.Is(F32)) {
15475 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15476 EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15477 rm.Encode(5, 0));
15478 AdvanceIT();
15479 return;
15480 }
15481 }
15482 } else {
15483 // VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
15484 if (encoded_dt.IsValid()) {
15485 if (cond.Is(al)) {
15486 EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15487 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15488 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15489 return;
15490 }
15491 }
15492 // VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
15493 if (dt.Is(F32)) {
15494 if (cond.Is(al)) {
15495 EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15496 rm.Encode(5, 0));
15497 return;
15498 }
15499 }
15500 }
15501 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
15502 }
15503
vcgt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)15504 void Assembler::vcgt(
15505 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15506 VIXL_ASSERT(AllowAssembler());
15507 CheckIT(cond);
15508 Dt_U_size_1 encoded_dt(dt);
15509 if (IsUsingT32()) {
15510 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
15511 if (encoded_dt.IsValid()) {
15512 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15513 EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15514 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15515 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15516 AdvanceIT();
15517 return;
15518 }
15519 }
15520 // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
15521 if (dt.Is(F32)) {
15522 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15523 EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15524 rm.Encode(5, 0));
15525 AdvanceIT();
15526 return;
15527 }
15528 }
15529 } else {
15530 // VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
15531 if (encoded_dt.IsValid()) {
15532 if (cond.Is(al)) {
15533 EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15534 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15535 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
15536 return;
15537 }
15538 }
15539 // VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
15540 if (dt.Is(F32)) {
15541 if (cond.Is(al)) {
15542 EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
15543 rm.Encode(5, 0));
15544 return;
15545 }
15546 }
15547 }
15548 Delegate(kVcgt, &Assembler::vcgt, cond, dt, rd, rn, rm);
15549 }
15550
vcle(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)15551 void Assembler::vcle(Condition cond,
15552 DataType dt,
15553 DRegister rd,
15554 DRegister rm,
15555 const DOperand& operand) {
15556 VIXL_ASSERT(AllowAssembler());
15557 CheckIT(cond);
15558 if (operand.IsImmediate()) {
15559 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15560 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15561 Dt_F_size_1 encoded_dt(dt);
15562 if (IsUsingT32()) {
15563 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
15564 if (encoded_dt.IsValid() && (imm == 0)) {
15565 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15566 EmitT32_32(0xffb10180U |
15567 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15568 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15569 rd.Encode(22, 12) | rm.Encode(5, 0));
15570 AdvanceIT();
15571 return;
15572 }
15573 }
15574 } else {
15575 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
15576 if (encoded_dt.IsValid() && (imm == 0)) {
15577 if (cond.Is(al)) {
15578 EmitA32(0xf3b10180U |
15579 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15580 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15581 rd.Encode(22, 12) | rm.Encode(5, 0));
15582 return;
15583 }
15584 }
15585 }
15586 }
15587 }
15588 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
15589 }
15590
vcle(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)15591 void Assembler::vcle(Condition cond,
15592 DataType dt,
15593 QRegister rd,
15594 QRegister rm,
15595 const QOperand& operand) {
15596 VIXL_ASSERT(AllowAssembler());
15597 CheckIT(cond);
15598 if (operand.IsImmediate()) {
15599 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15600 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15601 Dt_F_size_1 encoded_dt(dt);
15602 if (IsUsingT32()) {
15603 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
15604 if (encoded_dt.IsValid() && (imm == 0)) {
15605 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15606 EmitT32_32(0xffb101c0U |
15607 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15608 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15609 rd.Encode(22, 12) | rm.Encode(5, 0));
15610 AdvanceIT();
15611 return;
15612 }
15613 }
15614 } else {
15615 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
15616 if (encoded_dt.IsValid() && (imm == 0)) {
15617 if (cond.Is(al)) {
15618 EmitA32(0xf3b101c0U |
15619 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15620 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15621 rd.Encode(22, 12) | rm.Encode(5, 0));
15622 return;
15623 }
15624 }
15625 }
15626 }
15627 }
15628 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rm, operand);
15629 }
15630
vcle(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)15631 void Assembler::vcle(
15632 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15633 VIXL_ASSERT(AllowAssembler());
15634 CheckIT(cond);
15635 Dt_U_size_1 encoded_dt(dt);
15636 if (IsUsingT32()) {
15637 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
15638 if (encoded_dt.IsValid()) {
15639 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15640 EmitT32_32(0xef000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15641 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15642 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15643 AdvanceIT();
15644 return;
15645 }
15646 }
15647 // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
15648 if (dt.Is(F32)) {
15649 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15650 EmitT32_32(0xff000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15651 rm.Encode(7, 16));
15652 AdvanceIT();
15653 return;
15654 }
15655 }
15656 } else {
15657 // VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
15658 if (encoded_dt.IsValid()) {
15659 if (cond.Is(al)) {
15660 EmitA32(0xf2000310U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15661 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15662 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15663 return;
15664 }
15665 }
15666 // VCLE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
15667 if (dt.Is(F32)) {
15668 if (cond.Is(al)) {
15669 EmitA32(0xf3000e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15670 rm.Encode(7, 16));
15671 return;
15672 }
15673 }
15674 }
15675 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
15676 }
15677
vcle(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)15678 void Assembler::vcle(
15679 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15680 VIXL_ASSERT(AllowAssembler());
15681 CheckIT(cond);
15682 Dt_U_size_1 encoded_dt(dt);
15683 if (IsUsingT32()) {
15684 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
15685 if (encoded_dt.IsValid()) {
15686 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15687 EmitT32_32(0xef000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15688 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15689 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15690 AdvanceIT();
15691 return;
15692 }
15693 }
15694 // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
15695 if (dt.Is(F32)) {
15696 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15697 EmitT32_32(0xff000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15698 rm.Encode(7, 16));
15699 AdvanceIT();
15700 return;
15701 }
15702 }
15703 } else {
15704 // VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
15705 if (encoded_dt.IsValid()) {
15706 if (cond.Is(al)) {
15707 EmitA32(0xf2000350U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15708 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15709 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15710 return;
15711 }
15712 }
15713 // VCLE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
15714 if (dt.Is(F32)) {
15715 if (cond.Is(al)) {
15716 EmitA32(0xf3000e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15717 rm.Encode(7, 16));
15718 return;
15719 }
15720 }
15721 }
15722 Delegate(kVcle, &Assembler::vcle, cond, dt, rd, rn, rm);
15723 }
15724
vcls(Condition cond,DataType dt,DRegister rd,DRegister rm)15725 void Assembler::vcls(Condition cond, DataType dt, DRegister rd, DRegister rm) {
15726 VIXL_ASSERT(AllowAssembler());
15727 CheckIT(cond);
15728 Dt_size_5 encoded_dt(dt);
15729 if (IsUsingT32()) {
15730 // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
15731 if (encoded_dt.IsValid()) {
15732 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15733 EmitT32_32(0xffb00400U | (encoded_dt.GetEncodingValue() << 18) |
15734 rd.Encode(22, 12) | rm.Encode(5, 0));
15735 AdvanceIT();
15736 return;
15737 }
15738 }
15739 } else {
15740 // VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
15741 if (encoded_dt.IsValid()) {
15742 if (cond.Is(al)) {
15743 EmitA32(0xf3b00400U | (encoded_dt.GetEncodingValue() << 18) |
15744 rd.Encode(22, 12) | rm.Encode(5, 0));
15745 return;
15746 }
15747 }
15748 }
15749 Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
15750 }
15751
vcls(Condition cond,DataType dt,QRegister rd,QRegister rm)15752 void Assembler::vcls(Condition cond, DataType dt, QRegister rd, QRegister rm) {
15753 VIXL_ASSERT(AllowAssembler());
15754 CheckIT(cond);
15755 Dt_size_5 encoded_dt(dt);
15756 if (IsUsingT32()) {
15757 // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
15758 if (encoded_dt.IsValid()) {
15759 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15760 EmitT32_32(0xffb00440U | (encoded_dt.GetEncodingValue() << 18) |
15761 rd.Encode(22, 12) | rm.Encode(5, 0));
15762 AdvanceIT();
15763 return;
15764 }
15765 }
15766 } else {
15767 // VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
15768 if (encoded_dt.IsValid()) {
15769 if (cond.Is(al)) {
15770 EmitA32(0xf3b00440U | (encoded_dt.GetEncodingValue() << 18) |
15771 rd.Encode(22, 12) | rm.Encode(5, 0));
15772 return;
15773 }
15774 }
15775 }
15776 Delegate(kVcls, &Assembler::vcls, cond, dt, rd, rm);
15777 }
15778
vclt(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)15779 void Assembler::vclt(Condition cond,
15780 DataType dt,
15781 DRegister rd,
15782 DRegister rm,
15783 const DOperand& operand) {
15784 VIXL_ASSERT(AllowAssembler());
15785 CheckIT(cond);
15786 if (operand.IsImmediate()) {
15787 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15788 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15789 Dt_F_size_1 encoded_dt(dt);
15790 if (IsUsingT32()) {
15791 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1
15792 if (encoded_dt.IsValid() && (imm == 0)) {
15793 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15794 EmitT32_32(0xffb10200U |
15795 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15796 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15797 rd.Encode(22, 12) | rm.Encode(5, 0));
15798 AdvanceIT();
15799 return;
15800 }
15801 }
15802 } else {
15803 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
15804 if (encoded_dt.IsValid() && (imm == 0)) {
15805 if (cond.Is(al)) {
15806 EmitA32(0xf3b10200U |
15807 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15808 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15809 rd.Encode(22, 12) | rm.Encode(5, 0));
15810 return;
15811 }
15812 }
15813 }
15814 }
15815 }
15816 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
15817 }
15818
vclt(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)15819 void Assembler::vclt(Condition cond,
15820 DataType dt,
15821 QRegister rd,
15822 QRegister rm,
15823 const QOperand& operand) {
15824 VIXL_ASSERT(AllowAssembler());
15825 CheckIT(cond);
15826 if (operand.IsImmediate()) {
15827 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
15828 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
15829 Dt_F_size_1 encoded_dt(dt);
15830 if (IsUsingT32()) {
15831 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1
15832 if (encoded_dt.IsValid() && (imm == 0)) {
15833 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15834 EmitT32_32(0xffb10240U |
15835 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15836 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15837 rd.Encode(22, 12) | rm.Encode(5, 0));
15838 AdvanceIT();
15839 return;
15840 }
15841 }
15842 } else {
15843 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
15844 if (encoded_dt.IsValid() && (imm == 0)) {
15845 if (cond.Is(al)) {
15846 EmitA32(0xf3b10240U |
15847 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
15848 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
15849 rd.Encode(22, 12) | rm.Encode(5, 0));
15850 return;
15851 }
15852 }
15853 }
15854 }
15855 }
15856 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rm, operand);
15857 }
15858
vclt(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)15859 void Assembler::vclt(
15860 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
15861 VIXL_ASSERT(AllowAssembler());
15862 CheckIT(cond);
15863 Dt_U_size_1 encoded_dt(dt);
15864 if (IsUsingT32()) {
15865 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
15866 if (encoded_dt.IsValid()) {
15867 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15868 EmitT32_32(0xef000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15869 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15870 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15871 AdvanceIT();
15872 return;
15873 }
15874 }
15875 // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
15876 if (dt.Is(F32)) {
15877 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15878 EmitT32_32(0xff200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15879 rm.Encode(7, 16));
15880 AdvanceIT();
15881 return;
15882 }
15883 }
15884 } else {
15885 // VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
15886 if (encoded_dt.IsValid()) {
15887 if (cond.Is(al)) {
15888 EmitA32(0xf2000300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15889 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15890 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15891 return;
15892 }
15893 }
15894 // VCLT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
15895 if (dt.Is(F32)) {
15896 if (cond.Is(al)) {
15897 EmitA32(0xf3200e00U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15898 rm.Encode(7, 16));
15899 return;
15900 }
15901 }
15902 }
15903 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
15904 }
15905
vclt(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)15906 void Assembler::vclt(
15907 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
15908 VIXL_ASSERT(AllowAssembler());
15909 CheckIT(cond);
15910 Dt_U_size_1 encoded_dt(dt);
15911 if (IsUsingT32()) {
15912 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
15913 if (encoded_dt.IsValid()) {
15914 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15915 EmitT32_32(0xef000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15916 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
15917 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15918 AdvanceIT();
15919 return;
15920 }
15921 }
15922 // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
15923 if (dt.Is(F32)) {
15924 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15925 EmitT32_32(0xff200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15926 rm.Encode(7, 16));
15927 AdvanceIT();
15928 return;
15929 }
15930 }
15931 } else {
15932 // VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
15933 if (encoded_dt.IsValid()) {
15934 if (cond.Is(al)) {
15935 EmitA32(0xf2000340U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
15936 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
15937 rd.Encode(22, 12) | rn.Encode(5, 0) | rm.Encode(7, 16));
15938 return;
15939 }
15940 }
15941 // VCLT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
15942 if (dt.Is(F32)) {
15943 if (cond.Is(al)) {
15944 EmitA32(0xf3200e40U | rd.Encode(22, 12) | rn.Encode(5, 0) |
15945 rm.Encode(7, 16));
15946 return;
15947 }
15948 }
15949 }
15950 Delegate(kVclt, &Assembler::vclt, cond, dt, rd, rn, rm);
15951 }
15952
vclz(Condition cond,DataType dt,DRegister rd,DRegister rm)15953 void Assembler::vclz(Condition cond, DataType dt, DRegister rd, DRegister rm) {
15954 VIXL_ASSERT(AllowAssembler());
15955 CheckIT(cond);
15956 Dt_size_4 encoded_dt(dt);
15957 if (IsUsingT32()) {
15958 // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
15959 if (encoded_dt.IsValid()) {
15960 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15961 EmitT32_32(0xffb00480U | (encoded_dt.GetEncodingValue() << 18) |
15962 rd.Encode(22, 12) | rm.Encode(5, 0));
15963 AdvanceIT();
15964 return;
15965 }
15966 }
15967 } else {
15968 // VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
15969 if (encoded_dt.IsValid()) {
15970 if (cond.Is(al)) {
15971 EmitA32(0xf3b00480U | (encoded_dt.GetEncodingValue() << 18) |
15972 rd.Encode(22, 12) | rm.Encode(5, 0));
15973 return;
15974 }
15975 }
15976 }
15977 Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
15978 }
15979
vclz(Condition cond,DataType dt,QRegister rd,QRegister rm)15980 void Assembler::vclz(Condition cond, DataType dt, QRegister rd, QRegister rm) {
15981 VIXL_ASSERT(AllowAssembler());
15982 CheckIT(cond);
15983 Dt_size_4 encoded_dt(dt);
15984 if (IsUsingT32()) {
15985 // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
15986 if (encoded_dt.IsValid()) {
15987 if (cond.Is(al) || AllowStronglyDiscouraged()) {
15988 EmitT32_32(0xffb004c0U | (encoded_dt.GetEncodingValue() << 18) |
15989 rd.Encode(22, 12) | rm.Encode(5, 0));
15990 AdvanceIT();
15991 return;
15992 }
15993 }
15994 } else {
15995 // VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
15996 if (encoded_dt.IsValid()) {
15997 if (cond.Is(al)) {
15998 EmitA32(0xf3b004c0U | (encoded_dt.GetEncodingValue() << 18) |
15999 rd.Encode(22, 12) | rm.Encode(5, 0));
16000 return;
16001 }
16002 }
16003 }
16004 Delegate(kVclz, &Assembler::vclz, cond, dt, rd, rm);
16005 }
16006
vcmp(Condition cond,DataType dt,SRegister rd,const SOperand & operand)16007 void Assembler::vcmp(Condition cond,
16008 DataType dt,
16009 SRegister rd,
16010 const SOperand& operand) {
16011 VIXL_ASSERT(AllowAssembler());
16012 CheckIT(cond);
16013 if (operand.IsRegister()) {
16014 SRegister rm = operand.GetRegister();
16015 if (IsUsingT32()) {
16016 // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
16017 if (dt.Is(F32)) {
16018 EmitT32_32(0xeeb40a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
16019 AdvanceIT();
16020 return;
16021 }
16022 } else {
16023 // VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
16024 if (dt.Is(F32) && cond.IsNotNever()) {
16025 EmitA32(0x0eb40a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16026 rm.Encode(5, 0));
16027 return;
16028 }
16029 }
16030 }
16031 if (operand.IsImmediate()) {
16032 if (IsUsingT32()) {
16033 // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
16034 if (dt.Is(F32) && (operand.IsFloatZero())) {
16035 EmitT32_32(0xeeb50a40U | rd.Encode(22, 12));
16036 AdvanceIT();
16037 return;
16038 }
16039 } else {
16040 // VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
16041 if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) {
16042 EmitA32(0x0eb50a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
16043 return;
16044 }
16045 }
16046 }
16047 Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand);
16048 }
16049
vcmp(Condition cond,DataType dt,DRegister rd,const DOperand & operand)16050 void Assembler::vcmp(Condition cond,
16051 DataType dt,
16052 DRegister rd,
16053 const DOperand& operand) {
16054 VIXL_ASSERT(AllowAssembler());
16055 CheckIT(cond);
16056 if (operand.IsRegister()) {
16057 DRegister rm = operand.GetRegister();
16058 if (IsUsingT32()) {
16059 // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
16060 if (dt.Is(F64)) {
16061 EmitT32_32(0xeeb40b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
16062 AdvanceIT();
16063 return;
16064 }
16065 } else {
16066 // VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
16067 if (dt.Is(F64) && cond.IsNotNever()) {
16068 EmitA32(0x0eb40b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16069 rm.Encode(5, 0));
16070 return;
16071 }
16072 }
16073 }
16074 if (operand.IsImmediate()) {
16075 if (IsUsingT32()) {
16076 // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
16077 if (dt.Is(F64) && (operand.IsFloatZero())) {
16078 EmitT32_32(0xeeb50b40U | rd.Encode(22, 12));
16079 AdvanceIT();
16080 return;
16081 }
16082 } else {
16083 // VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
16084 if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) {
16085 EmitA32(0x0eb50b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
16086 return;
16087 }
16088 }
16089 }
16090 Delegate(kVcmp, &Assembler::vcmp, cond, dt, rd, operand);
16091 }
16092
vcmpe(Condition cond,DataType dt,SRegister rd,const SOperand & operand)16093 void Assembler::vcmpe(Condition cond,
16094 DataType dt,
16095 SRegister rd,
16096 const SOperand& operand) {
16097 VIXL_ASSERT(AllowAssembler());
16098 CheckIT(cond);
16099 if (operand.IsRegister()) {
16100 SRegister rm = operand.GetRegister();
16101 if (IsUsingT32()) {
16102 // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
16103 if (dt.Is(F32)) {
16104 EmitT32_32(0xeeb40ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16105 AdvanceIT();
16106 return;
16107 }
16108 } else {
16109 // VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
16110 if (dt.Is(F32) && cond.IsNotNever()) {
16111 EmitA32(0x0eb40ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16112 rm.Encode(5, 0));
16113 return;
16114 }
16115 }
16116 }
16117 if (operand.IsImmediate()) {
16118 if (IsUsingT32()) {
16119 // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
16120 if (dt.Is(F32) && (operand.IsFloatZero())) {
16121 EmitT32_32(0xeeb50ac0U | rd.Encode(22, 12));
16122 AdvanceIT();
16123 return;
16124 }
16125 } else {
16126 // VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
16127 if (dt.Is(F32) && (operand.IsFloatZero()) && cond.IsNotNever()) {
16128 EmitA32(0x0eb50ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
16129 return;
16130 }
16131 }
16132 }
16133 Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand);
16134 }
16135
vcmpe(Condition cond,DataType dt,DRegister rd,const DOperand & operand)16136 void Assembler::vcmpe(Condition cond,
16137 DataType dt,
16138 DRegister rd,
16139 const DOperand& operand) {
16140 VIXL_ASSERT(AllowAssembler());
16141 CheckIT(cond);
16142 if (operand.IsRegister()) {
16143 DRegister rm = operand.GetRegister();
16144 if (IsUsingT32()) {
16145 // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
16146 if (dt.Is(F64)) {
16147 EmitT32_32(0xeeb40bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16148 AdvanceIT();
16149 return;
16150 }
16151 } else {
16152 // VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
16153 if (dt.Is(F64) && cond.IsNotNever()) {
16154 EmitA32(0x0eb40bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16155 rm.Encode(5, 0));
16156 return;
16157 }
16158 }
16159 }
16160 if (operand.IsImmediate()) {
16161 if (IsUsingT32()) {
16162 // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
16163 if (dt.Is(F64) && (operand.IsFloatZero())) {
16164 EmitT32_32(0xeeb50bc0U | rd.Encode(22, 12));
16165 AdvanceIT();
16166 return;
16167 }
16168 } else {
16169 // VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
16170 if (dt.Is(F64) && (operand.IsFloatZero()) && cond.IsNotNever()) {
16171 EmitA32(0x0eb50bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12));
16172 return;
16173 }
16174 }
16175 }
16176 Delegate(kVcmpe, &Assembler::vcmpe, cond, dt, rd, operand);
16177 }
16178
vcnt(Condition cond,DataType dt,DRegister rd,DRegister rm)16179 void Assembler::vcnt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
16180 VIXL_ASSERT(AllowAssembler());
16181 CheckIT(cond);
16182 if (IsUsingT32()) {
16183 // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1
16184 if (dt.Is(Untyped8)) {
16185 if (cond.Is(al) || AllowStronglyDiscouraged()) {
16186 EmitT32_32(0xffb00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
16187 AdvanceIT();
16188 return;
16189 }
16190 }
16191 } else {
16192 // VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1
16193 if (dt.Is(Untyped8)) {
16194 if (cond.Is(al)) {
16195 EmitA32(0xf3b00500U | rd.Encode(22, 12) | rm.Encode(5, 0));
16196 return;
16197 }
16198 }
16199 }
16200 Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
16201 }
16202
vcnt(Condition cond,DataType dt,QRegister rd,QRegister rm)16203 void Assembler::vcnt(Condition cond, DataType dt, QRegister rd, QRegister rm) {
16204 VIXL_ASSERT(AllowAssembler());
16205 CheckIT(cond);
16206 if (IsUsingT32()) {
16207 // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1
16208 if (dt.Is(Untyped8)) {
16209 if (cond.Is(al) || AllowStronglyDiscouraged()) {
16210 EmitT32_32(0xffb00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
16211 AdvanceIT();
16212 return;
16213 }
16214 }
16215 } else {
16216 // VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1
16217 if (dt.Is(Untyped8)) {
16218 if (cond.Is(al)) {
16219 EmitA32(0xf3b00540U | rd.Encode(22, 12) | rm.Encode(5, 0));
16220 return;
16221 }
16222 }
16223 }
16224 Delegate(kVcnt, &Assembler::vcnt, cond, dt, rd, rm);
16225 }
16226
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,SRegister rm)16227 void Assembler::vcvt(
16228 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
16229 VIXL_ASSERT(AllowAssembler());
16230 CheckIT(cond);
16231 Dt_op_2 encoded_dt(dt2);
16232 if (IsUsingT32()) {
16233 // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1
16234 if (dt1.Is(F64) && dt2.Is(F32)) {
16235 EmitT32_32(0xeeb70ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16236 AdvanceIT();
16237 return;
16238 }
16239 // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1
16240 if (dt1.Is(F64) && encoded_dt.IsValid()) {
16241 EmitT32_32(0xeeb80b40U | (encoded_dt.GetEncodingValue() << 7) |
16242 rd.Encode(22, 12) | rm.Encode(5, 0));
16243 AdvanceIT();
16244 return;
16245 }
16246 } else {
16247 // VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1
16248 if (dt1.Is(F64) && dt2.Is(F32) && cond.IsNotNever()) {
16249 EmitA32(0x0eb70ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16250 rm.Encode(5, 0));
16251 return;
16252 }
16253 // VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1
16254 if (dt1.Is(F64) && encoded_dt.IsValid() && cond.IsNotNever()) {
16255 EmitA32(0x0eb80b40U | (cond.GetCondition() << 28) |
16256 (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
16257 rm.Encode(5, 0));
16258 return;
16259 }
16260 }
16261 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16262 }
16263
vcvt(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)16264 void Assembler::vcvt(
16265 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16266 VIXL_ASSERT(AllowAssembler());
16267 CheckIT(cond);
16268 if (IsUsingT32()) {
16269 // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1
16270 if (dt1.Is(F32) && dt2.Is(F64)) {
16271 EmitT32_32(0xeeb70bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16272 AdvanceIT();
16273 return;
16274 }
16275 // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
16276 if (dt1.Is(U32) && dt2.Is(F64)) {
16277 EmitT32_32(0xeebc0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16278 AdvanceIT();
16279 return;
16280 }
16281 // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
16282 if (dt1.Is(S32) && dt2.Is(F64)) {
16283 EmitT32_32(0xeebd0bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16284 AdvanceIT();
16285 return;
16286 }
16287 } else {
16288 // VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1
16289 if (dt1.Is(F32) && dt2.Is(F64) && cond.IsNotNever()) {
16290 EmitA32(0x0eb70bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16291 rm.Encode(5, 0));
16292 return;
16293 }
16294 // VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
16295 if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
16296 EmitA32(0x0ebc0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16297 rm.Encode(5, 0));
16298 return;
16299 }
16300 // VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
16301 if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
16302 EmitA32(0x0ebd0bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16303 rm.Encode(5, 0));
16304 return;
16305 }
16306 }
16307 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16308 }
16309
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,DRegister rm,int32_t fbits)16310 void Assembler::vcvt(Condition cond,
16311 DataType dt1,
16312 DataType dt2,
16313 DRegister rd,
16314 DRegister rm,
16315 int32_t fbits) {
16316 VIXL_ASSERT(AllowAssembler());
16317 CheckIT(cond);
16318 Dt_op_U_1 encoded_dt(dt1, dt2);
16319 Dt_U_sx_1 encoded_dt_2(dt2);
16320 Dt_U_sx_1 encoded_dt_3(dt1);
16321 if (IsUsingT32()) {
16322 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1
16323 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
16324 if (cond.Is(al) || AllowStronglyDiscouraged()) {
16325 uint32_t fbits_ = 64 - fbits;
16326 EmitT32_32(0xef800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
16327 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
16328 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
16329 AdvanceIT();
16330 return;
16331 }
16332 }
16333 // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1
16334 if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
16335 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
16336 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
16337 unsigned offset = 32;
16338 if (dt2.Is(S16) || dt2.Is(U16)) {
16339 offset = 16;
16340 }
16341 uint32_t fbits_ = offset - fbits;
16342 EmitT32_32(0xeeba0b40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
16343 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
16344 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16345 ((fbits_ & 0x1e) >> 1));
16346 AdvanceIT();
16347 return;
16348 }
16349 // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1
16350 if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
16351 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
16352 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
16353 unsigned offset = 32;
16354 if (dt1.Is(S16) || dt1.Is(U16)) {
16355 offset = 16;
16356 }
16357 uint32_t fbits_ = offset - fbits;
16358 EmitT32_32(0xeebe0b40U | ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
16359 ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
16360 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16361 ((fbits_ & 0x1e) >> 1));
16362 AdvanceIT();
16363 return;
16364 }
16365 } else {
16366 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1
16367 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
16368 if (cond.Is(al)) {
16369 uint32_t fbits_ = 64 - fbits;
16370 EmitA32(0xf2800e10U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
16371 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
16372 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
16373 return;
16374 }
16375 }
16376 // VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1
16377 if (dt1.Is(F64) && encoded_dt_2.IsValid() && rd.Is(rm) &&
16378 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
16379 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
16380 cond.IsNotNever()) {
16381 unsigned offset = 32;
16382 if (dt2.Is(S16) || dt2.Is(U16)) {
16383 offset = 16;
16384 }
16385 uint32_t fbits_ = offset - fbits;
16386 EmitA32(0x0eba0b40U | (cond.GetCondition() << 28) |
16387 ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
16388 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
16389 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16390 ((fbits_ & 0x1e) >> 1));
16391 return;
16392 }
16393 // VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1
16394 if (encoded_dt_3.IsValid() && dt2.Is(F64) && rd.Is(rm) &&
16395 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
16396 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
16397 cond.IsNotNever()) {
16398 unsigned offset = 32;
16399 if (dt1.Is(S16) || dt1.Is(U16)) {
16400 offset = 16;
16401 }
16402 uint32_t fbits_ = offset - fbits;
16403 EmitA32(0x0ebe0b40U | (cond.GetCondition() << 28) |
16404 ((encoded_dt_3.GetEncodingValue() & 0x1) << 7) |
16405 ((encoded_dt_3.GetEncodingValue() & 0x2) << 15) |
16406 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16407 ((fbits_ & 0x1e) >> 1));
16408 return;
16409 }
16410 }
16411 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
16412 }
16413
vcvt(Condition cond,DataType dt1,DataType dt2,QRegister rd,QRegister rm,int32_t fbits)16414 void Assembler::vcvt(Condition cond,
16415 DataType dt1,
16416 DataType dt2,
16417 QRegister rd,
16418 QRegister rm,
16419 int32_t fbits) {
16420 VIXL_ASSERT(AllowAssembler());
16421 CheckIT(cond);
16422 Dt_op_U_1 encoded_dt(dt1, dt2);
16423 if (IsUsingT32()) {
16424 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1
16425 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
16426 if (cond.Is(al) || AllowStronglyDiscouraged()) {
16427 uint32_t fbits_ = 64 - fbits;
16428 EmitT32_32(0xef800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 28) |
16429 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
16430 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
16431 AdvanceIT();
16432 return;
16433 }
16434 }
16435 } else {
16436 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1
16437 if (encoded_dt.IsValid() && (fbits >= 1) && (fbits <= 32)) {
16438 if (cond.Is(al)) {
16439 uint32_t fbits_ = 64 - fbits;
16440 EmitA32(0xf2800e50U | ((encoded_dt.GetEncodingValue() & 0x1) << 24) |
16441 ((encoded_dt.GetEncodingValue() & 0x2) << 7) |
16442 rd.Encode(22, 12) | rm.Encode(5, 0) | (fbits_ << 16));
16443 return;
16444 }
16445 }
16446 }
16447 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
16448 }
16449
vcvt(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm,int32_t fbits)16450 void Assembler::vcvt(Condition cond,
16451 DataType dt1,
16452 DataType dt2,
16453 SRegister rd,
16454 SRegister rm,
16455 int32_t fbits) {
16456 VIXL_ASSERT(AllowAssembler());
16457 CheckIT(cond);
16458 Dt_U_sx_1 encoded_dt(dt2);
16459 Dt_U_sx_1 encoded_dt_2(dt1);
16460 if (IsUsingT32()) {
16461 // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1
16462 if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
16463 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
16464 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
16465 unsigned offset = 32;
16466 if (dt2.Is(S16) || dt2.Is(U16)) {
16467 offset = 16;
16468 }
16469 uint32_t fbits_ = offset - fbits;
16470 EmitT32_32(0xeeba0a40U | ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
16471 ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
16472 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16473 ((fbits_ & 0x1e) >> 1));
16474 AdvanceIT();
16475 return;
16476 }
16477 // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1
16478 if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
16479 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
16480 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32)))) {
16481 unsigned offset = 32;
16482 if (dt1.Is(S16) || dt1.Is(U16)) {
16483 offset = 16;
16484 }
16485 uint32_t fbits_ = offset - fbits;
16486 EmitT32_32(0xeebe0a40U | ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
16487 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
16488 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16489 ((fbits_ & 0x1e) >> 1));
16490 AdvanceIT();
16491 return;
16492 }
16493 } else {
16494 // VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1
16495 if (dt1.Is(F32) && encoded_dt.IsValid() && rd.Is(rm) &&
16496 (((dt2.Is(S16) || dt2.Is(U16)) && (fbits <= 16)) ||
16497 ((dt2.Is(S32) || dt2.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
16498 cond.IsNotNever()) {
16499 unsigned offset = 32;
16500 if (dt2.Is(S16) || dt2.Is(U16)) {
16501 offset = 16;
16502 }
16503 uint32_t fbits_ = offset - fbits;
16504 EmitA32(0x0eba0a40U | (cond.GetCondition() << 28) |
16505 ((encoded_dt.GetEncodingValue() & 0x1) << 7) |
16506 ((encoded_dt.GetEncodingValue() & 0x2) << 15) |
16507 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16508 ((fbits_ & 0x1e) >> 1));
16509 return;
16510 }
16511 // VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1
16512 if (encoded_dt_2.IsValid() && dt2.Is(F32) && rd.Is(rm) &&
16513 (((dt1.Is(S16) || dt1.Is(U16)) && (fbits <= 16)) ||
16514 ((dt1.Is(S32) || dt1.Is(U32)) && (fbits >= 1) && (fbits <= 32))) &&
16515 cond.IsNotNever()) {
16516 unsigned offset = 32;
16517 if (dt1.Is(S16) || dt1.Is(U16)) {
16518 offset = 16;
16519 }
16520 uint32_t fbits_ = offset - fbits;
16521 EmitA32(0x0ebe0a40U | (cond.GetCondition() << 28) |
16522 ((encoded_dt_2.GetEncodingValue() & 0x1) << 7) |
16523 ((encoded_dt_2.GetEncodingValue() & 0x2) << 15) |
16524 rd.Encode(22, 12) | ((fbits_ & 0x1) << 5) |
16525 ((fbits_ & 0x1e) >> 1));
16526 return;
16527 }
16528 }
16529 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm, fbits);
16530 }
16531
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,DRegister rm)16532 void Assembler::vcvt(
16533 Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
16534 VIXL_ASSERT(AllowAssembler());
16535 CheckIT(cond);
16536 Dt_op_1 encoded_dt(dt1, dt2);
16537 if (IsUsingT32()) {
16538 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1
16539 if (encoded_dt.IsValid()) {
16540 if (cond.Is(al) || AllowStronglyDiscouraged()) {
16541 EmitT32_32(0xffbb0600U | (encoded_dt.GetEncodingValue() << 7) |
16542 rd.Encode(22, 12) | rm.Encode(5, 0));
16543 AdvanceIT();
16544 return;
16545 }
16546 }
16547 } else {
16548 // VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1
16549 if (encoded_dt.IsValid()) {
16550 if (cond.Is(al)) {
16551 EmitA32(0xf3bb0600U | (encoded_dt.GetEncodingValue() << 7) |
16552 rd.Encode(22, 12) | rm.Encode(5, 0));
16553 return;
16554 }
16555 }
16556 }
16557 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16558 }
16559
vcvt(Condition cond,DataType dt1,DataType dt2,QRegister rd,QRegister rm)16560 void Assembler::vcvt(
16561 Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
16562 VIXL_ASSERT(AllowAssembler());
16563 CheckIT(cond);
16564 Dt_op_1 encoded_dt(dt1, dt2);
16565 if (IsUsingT32()) {
16566 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1
16567 if (encoded_dt.IsValid()) {
16568 if (cond.Is(al) || AllowStronglyDiscouraged()) {
16569 EmitT32_32(0xffbb0640U | (encoded_dt.GetEncodingValue() << 7) |
16570 rd.Encode(22, 12) | rm.Encode(5, 0));
16571 AdvanceIT();
16572 return;
16573 }
16574 }
16575 } else {
16576 // VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1
16577 if (encoded_dt.IsValid()) {
16578 if (cond.Is(al)) {
16579 EmitA32(0xf3bb0640U | (encoded_dt.GetEncodingValue() << 7) |
16580 rd.Encode(22, 12) | rm.Encode(5, 0));
16581 return;
16582 }
16583 }
16584 }
16585 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16586 }
16587
vcvt(Condition cond,DataType dt1,DataType dt2,DRegister rd,QRegister rm)16588 void Assembler::vcvt(
16589 Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) {
16590 VIXL_ASSERT(AllowAssembler());
16591 CheckIT(cond);
16592 if (IsUsingT32()) {
16593 // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1
16594 if (dt1.Is(F16) && dt2.Is(F32)) {
16595 if (cond.Is(al) || AllowStronglyDiscouraged()) {
16596 EmitT32_32(0xffb60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
16597 AdvanceIT();
16598 return;
16599 }
16600 }
16601 } else {
16602 // VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1
16603 if (dt1.Is(F16) && dt2.Is(F32)) {
16604 if (cond.Is(al)) {
16605 EmitA32(0xf3b60600U | rd.Encode(22, 12) | rm.Encode(5, 0));
16606 return;
16607 }
16608 }
16609 }
16610 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16611 }
16612
vcvt(Condition cond,DataType dt1,DataType dt2,QRegister rd,DRegister rm)16613 void Assembler::vcvt(
16614 Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) {
16615 VIXL_ASSERT(AllowAssembler());
16616 CheckIT(cond);
16617 if (IsUsingT32()) {
16618 // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1
16619 if (dt1.Is(F32) && dt2.Is(F16)) {
16620 if (cond.Is(al) || AllowStronglyDiscouraged()) {
16621 EmitT32_32(0xffb60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
16622 AdvanceIT();
16623 return;
16624 }
16625 }
16626 } else {
16627 // VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1
16628 if (dt1.Is(F32) && dt2.Is(F16)) {
16629 if (cond.Is(al)) {
16630 EmitA32(0xf3b60700U | rd.Encode(22, 12) | rm.Encode(5, 0));
16631 return;
16632 }
16633 }
16634 }
16635 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16636 }
16637
vcvt(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)16638 void Assembler::vcvt(
16639 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16640 VIXL_ASSERT(AllowAssembler());
16641 CheckIT(cond);
16642 Dt_op_2 encoded_dt(dt2);
16643 if (IsUsingT32()) {
16644 // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
16645 if (dt1.Is(U32) && dt2.Is(F32)) {
16646 EmitT32_32(0xeebc0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16647 AdvanceIT();
16648 return;
16649 }
16650 // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
16651 if (dt1.Is(S32) && dt2.Is(F32)) {
16652 EmitT32_32(0xeebd0ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
16653 AdvanceIT();
16654 return;
16655 }
16656 // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1
16657 if (dt1.Is(F32) && encoded_dt.IsValid()) {
16658 EmitT32_32(0xeeb80a40U | (encoded_dt.GetEncodingValue() << 7) |
16659 rd.Encode(22, 12) | rm.Encode(5, 0));
16660 AdvanceIT();
16661 return;
16662 }
16663 } else {
16664 // VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
16665 if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
16666 EmitA32(0x0ebc0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16667 rm.Encode(5, 0));
16668 return;
16669 }
16670 // VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
16671 if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
16672 EmitA32(0x0ebd0ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16673 rm.Encode(5, 0));
16674 return;
16675 }
16676 // VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1
16677 if (dt1.Is(F32) && encoded_dt.IsValid() && cond.IsNotNever()) {
16678 EmitA32(0x0eb80a40U | (cond.GetCondition() << 28) |
16679 (encoded_dt.GetEncodingValue() << 7) | rd.Encode(22, 12) |
16680 rm.Encode(5, 0));
16681 return;
16682 }
16683 }
16684 Delegate(kVcvt, &Assembler::vcvt, cond, dt1, dt2, rd, rm);
16685 }
16686
vcvta(DataType dt1,DataType dt2,DRegister rd,DRegister rm)16687 void Assembler::vcvta(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
16688 VIXL_ASSERT(AllowAssembler());
16689 CheckIT(al);
16690 Dt_op_3 encoded_dt(dt1);
16691 if (IsUsingT32()) {
16692 // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
16693 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16694 EmitT32_32(0xffbb0000U | (encoded_dt.GetEncodingValue() << 7) |
16695 rd.Encode(22, 12) | rm.Encode(5, 0));
16696 AdvanceIT();
16697 return;
16698 }
16699 } else {
16700 // VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
16701 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16702 EmitA32(0xf3bb0000U | (encoded_dt.GetEncodingValue() << 7) |
16703 rd.Encode(22, 12) | rm.Encode(5, 0));
16704 return;
16705 }
16706 }
16707 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
16708 }
16709
vcvta(DataType dt1,DataType dt2,QRegister rd,QRegister rm)16710 void Assembler::vcvta(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
16711 VIXL_ASSERT(AllowAssembler());
16712 CheckIT(al);
16713 Dt_op_3 encoded_dt(dt1);
16714 if (IsUsingT32()) {
16715 // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
16716 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16717 EmitT32_32(0xffbb0040U | (encoded_dt.GetEncodingValue() << 7) |
16718 rd.Encode(22, 12) | rm.Encode(5, 0));
16719 AdvanceIT();
16720 return;
16721 }
16722 } else {
16723 // VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
16724 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16725 EmitA32(0xf3bb0040U | (encoded_dt.GetEncodingValue() << 7) |
16726 rd.Encode(22, 12) | rm.Encode(5, 0));
16727 return;
16728 }
16729 }
16730 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
16731 }
16732
vcvta(DataType dt1,DataType dt2,SRegister rd,SRegister rm)16733 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16734 VIXL_ASSERT(AllowAssembler());
16735 CheckIT(al);
16736 Dt_op_2 encoded_dt(dt1);
16737 if (IsUsingT32()) {
16738 // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
16739 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16740 EmitT32_32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
16741 rd.Encode(22, 12) | rm.Encode(5, 0));
16742 AdvanceIT();
16743 return;
16744 }
16745 } else {
16746 // VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
16747 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16748 EmitA32(0xfebc0a40U | (encoded_dt.GetEncodingValue() << 7) |
16749 rd.Encode(22, 12) | rm.Encode(5, 0));
16750 return;
16751 }
16752 }
16753 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
16754 }
16755
vcvta(DataType dt1,DataType dt2,SRegister rd,DRegister rm)16756 void Assembler::vcvta(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16757 VIXL_ASSERT(AllowAssembler());
16758 CheckIT(al);
16759 Dt_op_2 encoded_dt(dt1);
16760 if (IsUsingT32()) {
16761 // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
16762 if (encoded_dt.IsValid() && dt2.Is(F64)) {
16763 EmitT32_32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
16764 rd.Encode(22, 12) | rm.Encode(5, 0));
16765 AdvanceIT();
16766 return;
16767 }
16768 } else {
16769 // VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
16770 if (encoded_dt.IsValid() && dt2.Is(F64)) {
16771 EmitA32(0xfebc0b40U | (encoded_dt.GetEncodingValue() << 7) |
16772 rd.Encode(22, 12) | rm.Encode(5, 0));
16773 return;
16774 }
16775 }
16776 Delegate(kVcvta, &Assembler::vcvta, dt1, dt2, rd, rm);
16777 }
16778
vcvtb(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)16779 void Assembler::vcvtb(
16780 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16781 VIXL_ASSERT(AllowAssembler());
16782 CheckIT(cond);
16783 if (IsUsingT32()) {
16784 // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
16785 if (dt1.Is(F32) && dt2.Is(F16)) {
16786 EmitT32_32(0xeeb20a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
16787 AdvanceIT();
16788 return;
16789 }
16790 // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
16791 if (dt1.Is(F16) && dt2.Is(F32)) {
16792 EmitT32_32(0xeeb30a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
16793 AdvanceIT();
16794 return;
16795 }
16796 } else {
16797 // VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
16798 if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
16799 EmitA32(0x0eb20a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16800 rm.Encode(5, 0));
16801 return;
16802 }
16803 // VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
16804 if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
16805 EmitA32(0x0eb30a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16806 rm.Encode(5, 0));
16807 return;
16808 }
16809 }
16810 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
16811 }
16812
vcvtb(Condition cond,DataType dt1,DataType dt2,DRegister rd,SRegister rm)16813 void Assembler::vcvtb(
16814 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
16815 VIXL_ASSERT(AllowAssembler());
16816 CheckIT(cond);
16817 if (IsUsingT32()) {
16818 // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
16819 if (dt1.Is(F64) && dt2.Is(F16)) {
16820 EmitT32_32(0xeeb20b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
16821 AdvanceIT();
16822 return;
16823 }
16824 } else {
16825 // VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
16826 if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
16827 EmitA32(0x0eb20b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16828 rm.Encode(5, 0));
16829 return;
16830 }
16831 }
16832 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
16833 }
16834
vcvtb(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)16835 void Assembler::vcvtb(
16836 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16837 VIXL_ASSERT(AllowAssembler());
16838 CheckIT(cond);
16839 if (IsUsingT32()) {
16840 // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
16841 if (dt1.Is(F16) && dt2.Is(F64)) {
16842 EmitT32_32(0xeeb30b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
16843 AdvanceIT();
16844 return;
16845 }
16846 } else {
16847 // VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
16848 if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
16849 EmitA32(0x0eb30b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
16850 rm.Encode(5, 0));
16851 return;
16852 }
16853 }
16854 Delegate(kVcvtb, &Assembler::vcvtb, cond, dt1, dt2, rd, rm);
16855 }
16856
vcvtm(DataType dt1,DataType dt2,DRegister rd,DRegister rm)16857 void Assembler::vcvtm(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
16858 VIXL_ASSERT(AllowAssembler());
16859 CheckIT(al);
16860 Dt_op_3 encoded_dt(dt1);
16861 if (IsUsingT32()) {
16862 // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
16863 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16864 EmitT32_32(0xffbb0300U | (encoded_dt.GetEncodingValue() << 7) |
16865 rd.Encode(22, 12) | rm.Encode(5, 0));
16866 AdvanceIT();
16867 return;
16868 }
16869 } else {
16870 // VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
16871 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16872 EmitA32(0xf3bb0300U | (encoded_dt.GetEncodingValue() << 7) |
16873 rd.Encode(22, 12) | rm.Encode(5, 0));
16874 return;
16875 }
16876 }
16877 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
16878 }
16879
vcvtm(DataType dt1,DataType dt2,QRegister rd,QRegister rm)16880 void Assembler::vcvtm(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
16881 VIXL_ASSERT(AllowAssembler());
16882 CheckIT(al);
16883 Dt_op_3 encoded_dt(dt1);
16884 if (IsUsingT32()) {
16885 // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
16886 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16887 EmitT32_32(0xffbb0340U | (encoded_dt.GetEncodingValue() << 7) |
16888 rd.Encode(22, 12) | rm.Encode(5, 0));
16889 AdvanceIT();
16890 return;
16891 }
16892 } else {
16893 // VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
16894 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16895 EmitA32(0xf3bb0340U | (encoded_dt.GetEncodingValue() << 7) |
16896 rd.Encode(22, 12) | rm.Encode(5, 0));
16897 return;
16898 }
16899 }
16900 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
16901 }
16902
vcvtm(DataType dt1,DataType dt2,SRegister rd,SRegister rm)16903 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16904 VIXL_ASSERT(AllowAssembler());
16905 CheckIT(al);
16906 Dt_op_2 encoded_dt(dt1);
16907 if (IsUsingT32()) {
16908 // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
16909 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16910 EmitT32_32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
16911 rd.Encode(22, 12) | rm.Encode(5, 0));
16912 AdvanceIT();
16913 return;
16914 }
16915 } else {
16916 // VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
16917 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16918 EmitA32(0xfebf0a40U | (encoded_dt.GetEncodingValue() << 7) |
16919 rd.Encode(22, 12) | rm.Encode(5, 0));
16920 return;
16921 }
16922 }
16923 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
16924 }
16925
vcvtm(DataType dt1,DataType dt2,SRegister rd,DRegister rm)16926 void Assembler::vcvtm(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
16927 VIXL_ASSERT(AllowAssembler());
16928 CheckIT(al);
16929 Dt_op_2 encoded_dt(dt1);
16930 if (IsUsingT32()) {
16931 // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
16932 if (encoded_dt.IsValid() && dt2.Is(F64)) {
16933 EmitT32_32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
16934 rd.Encode(22, 12) | rm.Encode(5, 0));
16935 AdvanceIT();
16936 return;
16937 }
16938 } else {
16939 // VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
16940 if (encoded_dt.IsValid() && dt2.Is(F64)) {
16941 EmitA32(0xfebf0b40U | (encoded_dt.GetEncodingValue() << 7) |
16942 rd.Encode(22, 12) | rm.Encode(5, 0));
16943 return;
16944 }
16945 }
16946 Delegate(kVcvtm, &Assembler::vcvtm, dt1, dt2, rd, rm);
16947 }
16948
vcvtn(DataType dt1,DataType dt2,DRegister rd,DRegister rm)16949 void Assembler::vcvtn(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
16950 VIXL_ASSERT(AllowAssembler());
16951 CheckIT(al);
16952 Dt_op_3 encoded_dt(dt1);
16953 if (IsUsingT32()) {
16954 // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
16955 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16956 EmitT32_32(0xffbb0100U | (encoded_dt.GetEncodingValue() << 7) |
16957 rd.Encode(22, 12) | rm.Encode(5, 0));
16958 AdvanceIT();
16959 return;
16960 }
16961 } else {
16962 // VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
16963 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16964 EmitA32(0xf3bb0100U | (encoded_dt.GetEncodingValue() << 7) |
16965 rd.Encode(22, 12) | rm.Encode(5, 0));
16966 return;
16967 }
16968 }
16969 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
16970 }
16971
vcvtn(DataType dt1,DataType dt2,QRegister rd,QRegister rm)16972 void Assembler::vcvtn(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
16973 VIXL_ASSERT(AllowAssembler());
16974 CheckIT(al);
16975 Dt_op_3 encoded_dt(dt1);
16976 if (IsUsingT32()) {
16977 // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
16978 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16979 EmitT32_32(0xffbb0140U | (encoded_dt.GetEncodingValue() << 7) |
16980 rd.Encode(22, 12) | rm.Encode(5, 0));
16981 AdvanceIT();
16982 return;
16983 }
16984 } else {
16985 // VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
16986 if (encoded_dt.IsValid() && dt2.Is(F32)) {
16987 EmitA32(0xf3bb0140U | (encoded_dt.GetEncodingValue() << 7) |
16988 rd.Encode(22, 12) | rm.Encode(5, 0));
16989 return;
16990 }
16991 }
16992 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
16993 }
16994
vcvtn(DataType dt1,DataType dt2,SRegister rd,SRegister rm)16995 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
16996 VIXL_ASSERT(AllowAssembler());
16997 CheckIT(al);
16998 Dt_op_2 encoded_dt(dt1);
16999 if (IsUsingT32()) {
17000 // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
17001 if (encoded_dt.IsValid() && dt2.Is(F32)) {
17002 EmitT32_32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
17003 rd.Encode(22, 12) | rm.Encode(5, 0));
17004 AdvanceIT();
17005 return;
17006 }
17007 } else {
17008 // VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
17009 if (encoded_dt.IsValid() && dt2.Is(F32)) {
17010 EmitA32(0xfebd0a40U | (encoded_dt.GetEncodingValue() << 7) |
17011 rd.Encode(22, 12) | rm.Encode(5, 0));
17012 return;
17013 }
17014 }
17015 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
17016 }
17017
vcvtn(DataType dt1,DataType dt2,SRegister rd,DRegister rm)17018 void Assembler::vcvtn(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
17019 VIXL_ASSERT(AllowAssembler());
17020 CheckIT(al);
17021 Dt_op_2 encoded_dt(dt1);
17022 if (IsUsingT32()) {
17023 // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
17024 if (encoded_dt.IsValid() && dt2.Is(F64)) {
17025 EmitT32_32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
17026 rd.Encode(22, 12) | rm.Encode(5, 0));
17027 AdvanceIT();
17028 return;
17029 }
17030 } else {
17031 // VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
17032 if (encoded_dt.IsValid() && dt2.Is(F64)) {
17033 EmitA32(0xfebd0b40U | (encoded_dt.GetEncodingValue() << 7) |
17034 rd.Encode(22, 12) | rm.Encode(5, 0));
17035 return;
17036 }
17037 }
17038 Delegate(kVcvtn, &Assembler::vcvtn, dt1, dt2, rd, rm);
17039 }
17040
vcvtp(DataType dt1,DataType dt2,DRegister rd,DRegister rm)17041 void Assembler::vcvtp(DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
17042 VIXL_ASSERT(AllowAssembler());
17043 CheckIT(al);
17044 Dt_op_3 encoded_dt(dt1);
17045 if (IsUsingT32()) {
17046 // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1
17047 if (encoded_dt.IsValid() && dt2.Is(F32)) {
17048 EmitT32_32(0xffbb0200U | (encoded_dt.GetEncodingValue() << 7) |
17049 rd.Encode(22, 12) | rm.Encode(5, 0));
17050 AdvanceIT();
17051 return;
17052 }
17053 } else {
17054 // VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
17055 if (encoded_dt.IsValid() && dt2.Is(F32)) {
17056 EmitA32(0xf3bb0200U | (encoded_dt.GetEncodingValue() << 7) |
17057 rd.Encode(22, 12) | rm.Encode(5, 0));
17058 return;
17059 }
17060 }
17061 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
17062 }
17063
vcvtp(DataType dt1,DataType dt2,QRegister rd,QRegister rm)17064 void Assembler::vcvtp(DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
17065 VIXL_ASSERT(AllowAssembler());
17066 CheckIT(al);
17067 Dt_op_3 encoded_dt(dt1);
17068 if (IsUsingT32()) {
17069 // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1
17070 if (encoded_dt.IsValid() && dt2.Is(F32)) {
17071 EmitT32_32(0xffbb0240U | (encoded_dt.GetEncodingValue() << 7) |
17072 rd.Encode(22, 12) | rm.Encode(5, 0));
17073 AdvanceIT();
17074 return;
17075 }
17076 } else {
17077 // VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
17078 if (encoded_dt.IsValid() && dt2.Is(F32)) {
17079 EmitA32(0xf3bb0240U | (encoded_dt.GetEncodingValue() << 7) |
17080 rd.Encode(22, 12) | rm.Encode(5, 0));
17081 return;
17082 }
17083 }
17084 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
17085 }
17086
vcvtp(DataType dt1,DataType dt2,SRegister rd,SRegister rm)17087 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
17088 VIXL_ASSERT(AllowAssembler());
17089 CheckIT(al);
17090 Dt_op_2 encoded_dt(dt1);
17091 if (IsUsingT32()) {
17092 // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
17093 if (encoded_dt.IsValid() && dt2.Is(F32)) {
17094 EmitT32_32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
17095 rd.Encode(22, 12) | rm.Encode(5, 0));
17096 AdvanceIT();
17097 return;
17098 }
17099 } else {
17100 // VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
17101 if (encoded_dt.IsValid() && dt2.Is(F32)) {
17102 EmitA32(0xfebe0a40U | (encoded_dt.GetEncodingValue() << 7) |
17103 rd.Encode(22, 12) | rm.Encode(5, 0));
17104 return;
17105 }
17106 }
17107 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
17108 }
17109
vcvtp(DataType dt1,DataType dt2,SRegister rd,DRegister rm)17110 void Assembler::vcvtp(DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
17111 VIXL_ASSERT(AllowAssembler());
17112 CheckIT(al);
17113 Dt_op_2 encoded_dt(dt1);
17114 if (IsUsingT32()) {
17115 // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
17116 if (encoded_dt.IsValid() && dt2.Is(F64)) {
17117 EmitT32_32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
17118 rd.Encode(22, 12) | rm.Encode(5, 0));
17119 AdvanceIT();
17120 return;
17121 }
17122 } else {
17123 // VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
17124 if (encoded_dt.IsValid() && dt2.Is(F64)) {
17125 EmitA32(0xfebe0b40U | (encoded_dt.GetEncodingValue() << 7) |
17126 rd.Encode(22, 12) | rm.Encode(5, 0));
17127 return;
17128 }
17129 }
17130 Delegate(kVcvtp, &Assembler::vcvtp, dt1, dt2, rd, rm);
17131 }
17132
vcvtr(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)17133 void Assembler::vcvtr(
17134 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
17135 VIXL_ASSERT(AllowAssembler());
17136 CheckIT(cond);
17137 if (IsUsingT32()) {
17138 // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
17139 if (dt1.Is(U32) && dt2.Is(F32)) {
17140 EmitT32_32(0xeebc0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
17141 AdvanceIT();
17142 return;
17143 }
17144 // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
17145 if (dt1.Is(S32) && dt2.Is(F32)) {
17146 EmitT32_32(0xeebd0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
17147 AdvanceIT();
17148 return;
17149 }
17150 } else {
17151 // VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
17152 if (dt1.Is(U32) && dt2.Is(F32) && cond.IsNotNever()) {
17153 EmitA32(0x0ebc0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17154 rm.Encode(5, 0));
17155 return;
17156 }
17157 // VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
17158 if (dt1.Is(S32) && dt2.Is(F32) && cond.IsNotNever()) {
17159 EmitA32(0x0ebd0a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17160 rm.Encode(5, 0));
17161 return;
17162 }
17163 }
17164 Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
17165 }
17166
vcvtr(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)17167 void Assembler::vcvtr(
17168 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
17169 VIXL_ASSERT(AllowAssembler());
17170 CheckIT(cond);
17171 if (IsUsingT32()) {
17172 // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
17173 if (dt1.Is(U32) && dt2.Is(F64)) {
17174 EmitT32_32(0xeebc0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
17175 AdvanceIT();
17176 return;
17177 }
17178 // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
17179 if (dt1.Is(S32) && dt2.Is(F64)) {
17180 EmitT32_32(0xeebd0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
17181 AdvanceIT();
17182 return;
17183 }
17184 } else {
17185 // VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
17186 if (dt1.Is(U32) && dt2.Is(F64) && cond.IsNotNever()) {
17187 EmitA32(0x0ebc0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17188 rm.Encode(5, 0));
17189 return;
17190 }
17191 // VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
17192 if (dt1.Is(S32) && dt2.Is(F64) && cond.IsNotNever()) {
17193 EmitA32(0x0ebd0b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17194 rm.Encode(5, 0));
17195 return;
17196 }
17197 }
17198 Delegate(kVcvtr, &Assembler::vcvtr, cond, dt1, dt2, rd, rm);
17199 }
17200
vcvtt(Condition cond,DataType dt1,DataType dt2,SRegister rd,SRegister rm)17201 void Assembler::vcvtt(
17202 Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
17203 VIXL_ASSERT(AllowAssembler());
17204 CheckIT(cond);
17205 if (IsUsingT32()) {
17206 // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
17207 if (dt1.Is(F32) && dt2.Is(F16)) {
17208 EmitT32_32(0xeeb20ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
17209 AdvanceIT();
17210 return;
17211 }
17212 // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
17213 if (dt1.Is(F16) && dt2.Is(F32)) {
17214 EmitT32_32(0xeeb30ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
17215 AdvanceIT();
17216 return;
17217 }
17218 } else {
17219 // VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
17220 if (dt1.Is(F32) && dt2.Is(F16) && cond.IsNotNever()) {
17221 EmitA32(0x0eb20ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17222 rm.Encode(5, 0));
17223 return;
17224 }
17225 // VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
17226 if (dt1.Is(F16) && dt2.Is(F32) && cond.IsNotNever()) {
17227 EmitA32(0x0eb30ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17228 rm.Encode(5, 0));
17229 return;
17230 }
17231 }
17232 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
17233 }
17234
vcvtt(Condition cond,DataType dt1,DataType dt2,DRegister rd,SRegister rm)17235 void Assembler::vcvtt(
17236 Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
17237 VIXL_ASSERT(AllowAssembler());
17238 CheckIT(cond);
17239 if (IsUsingT32()) {
17240 // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
17241 if (dt1.Is(F64) && dt2.Is(F16)) {
17242 EmitT32_32(0xeeb20bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
17243 AdvanceIT();
17244 return;
17245 }
17246 } else {
17247 // VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
17248 if (dt1.Is(F64) && dt2.Is(F16) && cond.IsNotNever()) {
17249 EmitA32(0x0eb20bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17250 rm.Encode(5, 0));
17251 return;
17252 }
17253 }
17254 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
17255 }
17256
vcvtt(Condition cond,DataType dt1,DataType dt2,SRegister rd,DRegister rm)17257 void Assembler::vcvtt(
17258 Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
17259 VIXL_ASSERT(AllowAssembler());
17260 CheckIT(cond);
17261 if (IsUsingT32()) {
17262 // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
17263 if (dt1.Is(F16) && dt2.Is(F64)) {
17264 EmitT32_32(0xeeb30bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
17265 AdvanceIT();
17266 return;
17267 }
17268 } else {
17269 // VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
17270 if (dt1.Is(F16) && dt2.Is(F64) && cond.IsNotNever()) {
17271 EmitA32(0x0eb30bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17272 rm.Encode(5, 0));
17273 return;
17274 }
17275 }
17276 Delegate(kVcvtt, &Assembler::vcvtt, cond, dt1, dt2, rd, rm);
17277 }
17278
vdiv(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)17279 void Assembler::vdiv(
17280 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
17281 VIXL_ASSERT(AllowAssembler());
17282 CheckIT(cond);
17283 if (IsUsingT32()) {
17284 // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
17285 if (dt.Is(F32)) {
17286 EmitT32_32(0xee800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17287 rm.Encode(5, 0));
17288 AdvanceIT();
17289 return;
17290 }
17291 } else {
17292 // VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
17293 if (dt.Is(F32) && cond.IsNotNever()) {
17294 EmitA32(0x0e800a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17295 rn.Encode(7, 16) | rm.Encode(5, 0));
17296 return;
17297 }
17298 }
17299 Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
17300 }
17301
vdiv(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17302 void Assembler::vdiv(
17303 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17304 VIXL_ASSERT(AllowAssembler());
17305 CheckIT(cond);
17306 if (IsUsingT32()) {
17307 // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
17308 if (dt.Is(F64)) {
17309 EmitT32_32(0xee800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17310 rm.Encode(5, 0));
17311 AdvanceIT();
17312 return;
17313 }
17314 } else {
17315 // VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
17316 if (dt.Is(F64) && cond.IsNotNever()) {
17317 EmitA32(0x0e800b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17318 rn.Encode(7, 16) | rm.Encode(5, 0));
17319 return;
17320 }
17321 }
17322 Delegate(kVdiv, &Assembler::vdiv, cond, dt, rd, rn, rm);
17323 }
17324
vdup(Condition cond,DataType dt,QRegister rd,Register rt)17325 void Assembler::vdup(Condition cond, DataType dt, QRegister rd, Register rt) {
17326 VIXL_ASSERT(AllowAssembler());
17327 CheckIT(cond);
17328 Dt_B_E_1 encoded_dt(dt);
17329 if (IsUsingT32()) {
17330 // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1
17331 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
17332 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17333 EmitT32_32(0xeea00b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
17334 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
17335 rd.Encode(7, 16) | (rt.GetCode() << 12));
17336 AdvanceIT();
17337 return;
17338 }
17339 }
17340 } else {
17341 // VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1
17342 if (encoded_dt.IsValid() && cond.IsNotNever() &&
17343 (!rt.IsPC() || AllowUnpredictable())) {
17344 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17345 EmitA32(0x0ea00b10U | (cond.GetCondition() << 28) |
17346 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
17347 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
17348 rd.Encode(7, 16) | (rt.GetCode() << 12));
17349 return;
17350 }
17351 }
17352 }
17353 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
17354 }
17355
vdup(Condition cond,DataType dt,DRegister rd,Register rt)17356 void Assembler::vdup(Condition cond, DataType dt, DRegister rd, Register rt) {
17357 VIXL_ASSERT(AllowAssembler());
17358 CheckIT(cond);
17359 Dt_B_E_1 encoded_dt(dt);
17360 if (IsUsingT32()) {
17361 // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1
17362 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
17363 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17364 EmitT32_32(0xee800b10U | ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
17365 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
17366 rd.Encode(7, 16) | (rt.GetCode() << 12));
17367 AdvanceIT();
17368 return;
17369 }
17370 }
17371 } else {
17372 // VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1
17373 if (encoded_dt.IsValid() && cond.IsNotNever() &&
17374 (!rt.IsPC() || AllowUnpredictable())) {
17375 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17376 EmitA32(0x0e800b10U | (cond.GetCondition() << 28) |
17377 ((encoded_dt.GetEncodingValue() & 0x1) << 5) |
17378 ((encoded_dt.GetEncodingValue() & 0x2) << 21) |
17379 rd.Encode(7, 16) | (rt.GetCode() << 12));
17380 return;
17381 }
17382 }
17383 }
17384 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rt);
17385 }
17386
vdup(Condition cond,DataType dt,DRegister rd,DRegisterLane rm)17387 void Assembler::vdup(Condition cond,
17388 DataType dt,
17389 DRegister rd,
17390 DRegisterLane rm) {
17391 VIXL_ASSERT(AllowAssembler());
17392 CheckIT(cond);
17393 Dt_imm4_1 encoded_dt(dt, rm);
17394 if (IsUsingT32()) {
17395 // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1
17396 if (encoded_dt.IsValid()) {
17397 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17398 EmitT32_32(0xffb00c00U | (encoded_dt.GetEncodingValue() << 16) |
17399 rd.Encode(22, 12) | rm.Encode(5, 0));
17400 AdvanceIT();
17401 return;
17402 }
17403 }
17404 } else {
17405 // VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1
17406 if (encoded_dt.IsValid()) {
17407 if (cond.Is(al)) {
17408 EmitA32(0xf3b00c00U | (encoded_dt.GetEncodingValue() << 16) |
17409 rd.Encode(22, 12) | rm.Encode(5, 0));
17410 return;
17411 }
17412 }
17413 }
17414 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
17415 }
17416
vdup(Condition cond,DataType dt,QRegister rd,DRegisterLane rm)17417 void Assembler::vdup(Condition cond,
17418 DataType dt,
17419 QRegister rd,
17420 DRegisterLane rm) {
17421 VIXL_ASSERT(AllowAssembler());
17422 CheckIT(cond);
17423 Dt_imm4_1 encoded_dt(dt, rm);
17424 if (IsUsingT32()) {
17425 // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1
17426 if (encoded_dt.IsValid()) {
17427 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17428 EmitT32_32(0xffb00c40U | (encoded_dt.GetEncodingValue() << 16) |
17429 rd.Encode(22, 12) | rm.Encode(5, 0));
17430 AdvanceIT();
17431 return;
17432 }
17433 }
17434 } else {
17435 // VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1
17436 if (encoded_dt.IsValid()) {
17437 if (cond.Is(al)) {
17438 EmitA32(0xf3b00c40U | (encoded_dt.GetEncodingValue() << 16) |
17439 rd.Encode(22, 12) | rm.Encode(5, 0));
17440 return;
17441 }
17442 }
17443 }
17444 Delegate(kVdup, &Assembler::vdup, cond, dt, rd, rm);
17445 }
17446
veor(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17447 void Assembler::veor(
17448 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17449 VIXL_ASSERT(AllowAssembler());
17450 CheckIT(cond);
17451 USE(dt);
17452 if (IsUsingT32()) {
17453 // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
17454 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17455 EmitT32_32(0xff000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17456 rm.Encode(5, 0));
17457 AdvanceIT();
17458 return;
17459 }
17460 } else {
17461 // VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
17462 if (cond.Is(al)) {
17463 EmitA32(0xf3000110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17464 rm.Encode(5, 0));
17465 return;
17466 }
17467 }
17468 Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
17469 }
17470
veor(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)17471 void Assembler::veor(
17472 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
17473 VIXL_ASSERT(AllowAssembler());
17474 CheckIT(cond);
17475 USE(dt);
17476 if (IsUsingT32()) {
17477 // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
17478 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17479 EmitT32_32(0xff000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17480 rm.Encode(5, 0));
17481 AdvanceIT();
17482 return;
17483 }
17484 } else {
17485 // VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
17486 if (cond.Is(al)) {
17487 EmitA32(0xf3000150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17488 rm.Encode(5, 0));
17489 return;
17490 }
17491 }
17492 Delegate(kVeor, &Assembler::veor, cond, dt, rd, rn, rm);
17493 }
17494
vext(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm,const DOperand & operand)17495 void Assembler::vext(Condition cond,
17496 DataType dt,
17497 DRegister rd,
17498 DRegister rn,
17499 DRegister rm,
17500 const DOperand& operand) {
17501 VIXL_ASSERT(AllowAssembler());
17502 CheckIT(cond);
17503 if (operand.IsImmediate()) {
17504 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
17505 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
17506 if (IsUsingT32()) {
17507 // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
17508 if (dt.Is(Untyped8) && (imm <= 7)) {
17509 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17510 EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17511 rm.Encode(5, 0) | (imm << 8));
17512 AdvanceIT();
17513 return;
17514 }
17515 }
17516 // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; T1
17517 if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
17518 (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
17519 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17520 uint32_t imm4 = imm / dt.GetSize();
17521 EmitT32_32(0xefb00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17522 rm.Encode(5, 0) | (imm4 << 8));
17523 AdvanceIT();
17524 return;
17525 }
17526 }
17527 } else {
17528 // VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
17529 if (dt.Is(Untyped8) && (imm <= 7)) {
17530 if (cond.Is(al)) {
17531 EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17532 rm.Encode(5, 0) | (imm << 8));
17533 return;
17534 }
17535 }
17536 // VEXT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
17537 if ((dt.Is(Untyped16) || dt.Is(Untyped32)) &&
17538 (imm <= (128 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
17539 if (cond.Is(al)) {
17540 uint32_t imm4 = imm / dt.GetSize();
17541 EmitA32(0xf2b00000U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17542 rm.Encode(5, 0) | (imm4 << 8));
17543 return;
17544 }
17545 }
17546 }
17547 }
17548 }
17549 Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
17550 }
17551
vext(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm,const QOperand & operand)17552 void Assembler::vext(Condition cond,
17553 DataType dt,
17554 QRegister rd,
17555 QRegister rn,
17556 QRegister rm,
17557 const QOperand& operand) {
17558 VIXL_ASSERT(AllowAssembler());
17559 CheckIT(cond);
17560 if (operand.IsImmediate()) {
17561 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
17562 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
17563 if (IsUsingT32()) {
17564 // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
17565 if (dt.Is(Untyped8) && (imm <= 15)) {
17566 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17567 EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17568 rm.Encode(5, 0) | (imm << 8));
17569 AdvanceIT();
17570 return;
17571 }
17572 }
17573 // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; T1
17574 if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
17575 (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
17576 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17577 uint32_t imm4 = imm / dt.GetSize();
17578 EmitT32_32(0xefb00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17579 rm.Encode(5, 0) | (imm4 << 8));
17580 AdvanceIT();
17581 return;
17582 }
17583 }
17584 } else {
17585 // VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
17586 if (dt.Is(Untyped8) && (imm <= 15)) {
17587 if (cond.Is(al)) {
17588 EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17589 rm.Encode(5, 0) | (imm << 8));
17590 return;
17591 }
17592 }
17593 // VEXT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
17594 if ((dt.Is(Untyped16) || dt.Is(Untyped32) || dt.Is(Untyped64)) &&
17595 (imm <= (64 / dt.GetSize()) - 1) && ((imm % dt.GetSize()) == 0)) {
17596 if (cond.Is(al)) {
17597 uint32_t imm4 = imm / dt.GetSize();
17598 EmitA32(0xf2b00040U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17599 rm.Encode(5, 0) | (imm4 << 8));
17600 return;
17601 }
17602 }
17603 }
17604 }
17605 }
17606 Delegate(kVext, &Assembler::vext, cond, dt, rd, rn, rm, operand);
17607 }
17608
vfma(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17609 void Assembler::vfma(
17610 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17611 VIXL_ASSERT(AllowAssembler());
17612 CheckIT(cond);
17613 if (IsUsingT32()) {
17614 // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
17615 if (dt.Is(F32)) {
17616 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17617 EmitT32_32(0xef000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17618 rm.Encode(5, 0));
17619 AdvanceIT();
17620 return;
17621 }
17622 }
17623 // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
17624 if (dt.Is(F64)) {
17625 EmitT32_32(0xeea00b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17626 rm.Encode(5, 0));
17627 AdvanceIT();
17628 return;
17629 }
17630 } else {
17631 // VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
17632 if (dt.Is(F32)) {
17633 if (cond.Is(al)) {
17634 EmitA32(0xf2000c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17635 rm.Encode(5, 0));
17636 return;
17637 }
17638 }
17639 // VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
17640 if (dt.Is(F64) && cond.IsNotNever()) {
17641 EmitA32(0x0ea00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17642 rn.Encode(7, 16) | rm.Encode(5, 0));
17643 return;
17644 }
17645 }
17646 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
17647 }
17648
vfma(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)17649 void Assembler::vfma(
17650 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
17651 VIXL_ASSERT(AllowAssembler());
17652 CheckIT(cond);
17653 if (IsUsingT32()) {
17654 // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
17655 if (dt.Is(F32)) {
17656 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17657 EmitT32_32(0xef000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17658 rm.Encode(5, 0));
17659 AdvanceIT();
17660 return;
17661 }
17662 }
17663 } else {
17664 // VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
17665 if (dt.Is(F32)) {
17666 if (cond.Is(al)) {
17667 EmitA32(0xf2000c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17668 rm.Encode(5, 0));
17669 return;
17670 }
17671 }
17672 }
17673 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
17674 }
17675
vfma(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)17676 void Assembler::vfma(
17677 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
17678 VIXL_ASSERT(AllowAssembler());
17679 CheckIT(cond);
17680 if (IsUsingT32()) {
17681 // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
17682 if (dt.Is(F32)) {
17683 EmitT32_32(0xeea00a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17684 rm.Encode(5, 0));
17685 AdvanceIT();
17686 return;
17687 }
17688 } else {
17689 // VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
17690 if (dt.Is(F32) && cond.IsNotNever()) {
17691 EmitA32(0x0ea00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17692 rn.Encode(7, 16) | rm.Encode(5, 0));
17693 return;
17694 }
17695 }
17696 Delegate(kVfma, &Assembler::vfma, cond, dt, rd, rn, rm);
17697 }
17698
vfms(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17699 void Assembler::vfms(
17700 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17701 VIXL_ASSERT(AllowAssembler());
17702 CheckIT(cond);
17703 if (IsUsingT32()) {
17704 // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
17705 if (dt.Is(F32)) {
17706 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17707 EmitT32_32(0xef200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17708 rm.Encode(5, 0));
17709 AdvanceIT();
17710 return;
17711 }
17712 }
17713 // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
17714 if (dt.Is(F64)) {
17715 EmitT32_32(0xeea00b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17716 rm.Encode(5, 0));
17717 AdvanceIT();
17718 return;
17719 }
17720 } else {
17721 // VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
17722 if (dt.Is(F32)) {
17723 if (cond.Is(al)) {
17724 EmitA32(0xf2200c10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17725 rm.Encode(5, 0));
17726 return;
17727 }
17728 }
17729 // VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
17730 if (dt.Is(F64) && cond.IsNotNever()) {
17731 EmitA32(0x0ea00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17732 rn.Encode(7, 16) | rm.Encode(5, 0));
17733 return;
17734 }
17735 }
17736 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
17737 }
17738
vfms(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)17739 void Assembler::vfms(
17740 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
17741 VIXL_ASSERT(AllowAssembler());
17742 CheckIT(cond);
17743 if (IsUsingT32()) {
17744 // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
17745 if (dt.Is(F32)) {
17746 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17747 EmitT32_32(0xef200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17748 rm.Encode(5, 0));
17749 AdvanceIT();
17750 return;
17751 }
17752 }
17753 } else {
17754 // VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
17755 if (dt.Is(F32)) {
17756 if (cond.Is(al)) {
17757 EmitA32(0xf2200c50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17758 rm.Encode(5, 0));
17759 return;
17760 }
17761 }
17762 }
17763 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
17764 }
17765
vfms(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)17766 void Assembler::vfms(
17767 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
17768 VIXL_ASSERT(AllowAssembler());
17769 CheckIT(cond);
17770 if (IsUsingT32()) {
17771 // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
17772 if (dt.Is(F32)) {
17773 EmitT32_32(0xeea00a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17774 rm.Encode(5, 0));
17775 AdvanceIT();
17776 return;
17777 }
17778 } else {
17779 // VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
17780 if (dt.Is(F32) && cond.IsNotNever()) {
17781 EmitA32(0x0ea00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17782 rn.Encode(7, 16) | rm.Encode(5, 0));
17783 return;
17784 }
17785 }
17786 Delegate(kVfms, &Assembler::vfms, cond, dt, rd, rn, rm);
17787 }
17788
vfnma(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)17789 void Assembler::vfnma(
17790 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
17791 VIXL_ASSERT(AllowAssembler());
17792 CheckIT(cond);
17793 if (IsUsingT32()) {
17794 // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
17795 if (dt.Is(F32)) {
17796 EmitT32_32(0xee900a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17797 rm.Encode(5, 0));
17798 AdvanceIT();
17799 return;
17800 }
17801 } else {
17802 // VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
17803 if (dt.Is(F32) && cond.IsNotNever()) {
17804 EmitA32(0x0e900a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17805 rn.Encode(7, 16) | rm.Encode(5, 0));
17806 return;
17807 }
17808 }
17809 Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
17810 }
17811
vfnma(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17812 void Assembler::vfnma(
17813 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17814 VIXL_ASSERT(AllowAssembler());
17815 CheckIT(cond);
17816 if (IsUsingT32()) {
17817 // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
17818 if (dt.Is(F64)) {
17819 EmitT32_32(0xee900b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17820 rm.Encode(5, 0));
17821 AdvanceIT();
17822 return;
17823 }
17824 } else {
17825 // VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
17826 if (dt.Is(F64) && cond.IsNotNever()) {
17827 EmitA32(0x0e900b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17828 rn.Encode(7, 16) | rm.Encode(5, 0));
17829 return;
17830 }
17831 }
17832 Delegate(kVfnma, &Assembler::vfnma, cond, dt, rd, rn, rm);
17833 }
17834
vfnms(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)17835 void Assembler::vfnms(
17836 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
17837 VIXL_ASSERT(AllowAssembler());
17838 CheckIT(cond);
17839 if (IsUsingT32()) {
17840 // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
17841 if (dt.Is(F32)) {
17842 EmitT32_32(0xee900a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17843 rm.Encode(5, 0));
17844 AdvanceIT();
17845 return;
17846 }
17847 } else {
17848 // VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
17849 if (dt.Is(F32) && cond.IsNotNever()) {
17850 EmitA32(0x0e900a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17851 rn.Encode(7, 16) | rm.Encode(5, 0));
17852 return;
17853 }
17854 }
17855 Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
17856 }
17857
vfnms(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17858 void Assembler::vfnms(
17859 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17860 VIXL_ASSERT(AllowAssembler());
17861 CheckIT(cond);
17862 if (IsUsingT32()) {
17863 // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
17864 if (dt.Is(F64)) {
17865 EmitT32_32(0xee900b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
17866 rm.Encode(5, 0));
17867 AdvanceIT();
17868 return;
17869 }
17870 } else {
17871 // VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
17872 if (dt.Is(F64) && cond.IsNotNever()) {
17873 EmitA32(0x0e900b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
17874 rn.Encode(7, 16) | rm.Encode(5, 0));
17875 return;
17876 }
17877 }
17878 Delegate(kVfnms, &Assembler::vfnms, cond, dt, rd, rn, rm);
17879 }
17880
vhadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17881 void Assembler::vhadd(
17882 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17883 VIXL_ASSERT(AllowAssembler());
17884 CheckIT(cond);
17885 Dt_U_size_1 encoded_dt(dt);
17886 if (IsUsingT32()) {
17887 // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
17888 if (encoded_dt.IsValid()) {
17889 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17890 EmitT32_32(0xef000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17891 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
17892 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17893 AdvanceIT();
17894 return;
17895 }
17896 }
17897 } else {
17898 // VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
17899 if (encoded_dt.IsValid()) {
17900 if (cond.Is(al)) {
17901 EmitA32(0xf2000000U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17902 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
17903 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17904 return;
17905 }
17906 }
17907 }
17908 Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
17909 }
17910
vhadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)17911 void Assembler::vhadd(
17912 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
17913 VIXL_ASSERT(AllowAssembler());
17914 CheckIT(cond);
17915 Dt_U_size_1 encoded_dt(dt);
17916 if (IsUsingT32()) {
17917 // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
17918 if (encoded_dt.IsValid()) {
17919 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17920 EmitT32_32(0xef000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17921 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
17922 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17923 AdvanceIT();
17924 return;
17925 }
17926 }
17927 } else {
17928 // VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
17929 if (encoded_dt.IsValid()) {
17930 if (cond.Is(al)) {
17931 EmitA32(0xf2000040U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17932 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
17933 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17934 return;
17935 }
17936 }
17937 }
17938 Delegate(kVhadd, &Assembler::vhadd, cond, dt, rd, rn, rm);
17939 }
17940
vhsub(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)17941 void Assembler::vhsub(
17942 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
17943 VIXL_ASSERT(AllowAssembler());
17944 CheckIT(cond);
17945 Dt_U_size_1 encoded_dt(dt);
17946 if (IsUsingT32()) {
17947 // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
17948 if (encoded_dt.IsValid()) {
17949 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17950 EmitT32_32(0xef000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17951 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
17952 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17953 AdvanceIT();
17954 return;
17955 }
17956 }
17957 } else {
17958 // VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
17959 if (encoded_dt.IsValid()) {
17960 if (cond.Is(al)) {
17961 EmitA32(0xf2000200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17962 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
17963 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17964 return;
17965 }
17966 }
17967 }
17968 Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
17969 }
17970
vhsub(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)17971 void Assembler::vhsub(
17972 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
17973 VIXL_ASSERT(AllowAssembler());
17974 CheckIT(cond);
17975 Dt_U_size_1 encoded_dt(dt);
17976 if (IsUsingT32()) {
17977 // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
17978 if (encoded_dt.IsValid()) {
17979 if (cond.Is(al) || AllowStronglyDiscouraged()) {
17980 EmitT32_32(0xef000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17981 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
17982 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17983 AdvanceIT();
17984 return;
17985 }
17986 }
17987 } else {
17988 // VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
17989 if (encoded_dt.IsValid()) {
17990 if (cond.Is(al)) {
17991 EmitA32(0xf2000240U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
17992 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
17993 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
17994 return;
17995 }
17996 }
17997 }
17998 Delegate(kVhsub, &Assembler::vhsub, cond, dt, rd, rn, rm);
17999 }
18000
vld1(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)18001 void Assembler::vld1(Condition cond,
18002 DataType dt,
18003 const NeonRegisterList& nreglist,
18004 const AlignedMemOperand& operand) {
18005 VIXL_ASSERT(AllowAssembler());
18006 CheckIT(cond);
18007 if (operand.IsImmediateZero()) {
18008 Register rn = operand.GetBaseRegister();
18009 Alignment align = operand.GetAlignment();
18010 Dt_size_6 encoded_dt(dt);
18011 Dt_size_7 encoded_dt_2(dt);
18012 Align_align_1 encoded_align_1(align, nreglist);
18013 Align_a_1 encoded_align_2(align, dt);
18014 Align_index_align_1 encoded_align_3(align, nreglist, dt);
18015 if (IsUsingT32()) {
18016 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18017 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18018 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
18019 operand.IsOffset() && encoded_align_1.IsValid() &&
18020 (!rn.IsPC() || AllowUnpredictable())) {
18021 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18022 const DRegister& first = nreglist.GetFirstDRegister();
18023 uint32_t len_encoding;
18024 switch (nreglist.GetLength()) {
18025 default:
18026 VIXL_UNREACHABLE_OR_FALLTHROUGH();
18027 case 1:
18028 len_encoding = 0x7;
18029 break;
18030 case 2:
18031 len_encoding = 0xa;
18032 break;
18033 case 3:
18034 len_encoding = 0x6;
18035 break;
18036 case 4:
18037 len_encoding = 0x2;
18038 break;
18039 }
18040 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
18041 (encoded_align_1.GetEncodingValue() << 4) |
18042 first.Encode(22, 12) | (len_encoding << 8) |
18043 (rn.GetCode() << 16));
18044 AdvanceIT();
18045 return;
18046 }
18047 }
18048 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18049 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18050 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
18051 operand.IsPostIndex() && encoded_align_1.IsValid() &&
18052 (!rn.IsPC() || AllowUnpredictable())) {
18053 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18054 const DRegister& first = nreglist.GetFirstDRegister();
18055 uint32_t len_encoding;
18056 switch (nreglist.GetLength()) {
18057 default:
18058 VIXL_UNREACHABLE_OR_FALLTHROUGH();
18059 case 1:
18060 len_encoding = 0x7;
18061 break;
18062 case 2:
18063 len_encoding = 0xa;
18064 break;
18065 case 3:
18066 len_encoding = 0x6;
18067 break;
18068 case 4:
18069 len_encoding = 0x2;
18070 break;
18071 }
18072 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
18073 (encoded_align_1.GetEncodingValue() << 4) |
18074 first.Encode(22, 12) | (len_encoding << 8) |
18075 (rn.GetCode() << 16));
18076 AdvanceIT();
18077 return;
18078 }
18079 }
18080 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18081 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18082 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18083 operand.IsOffset() && encoded_align_2.IsValid() &&
18084 (!rn.IsPC() || AllowUnpredictable())) {
18085 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18086 const DRegister& first = nreglist.GetFirstDRegister();
18087 uint32_t len_encoding = nreglist.GetLength() - 1;
18088 EmitT32_32(0xf9a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
18089 (encoded_align_2.GetEncodingValue() << 4) |
18090 first.Encode(22, 12) | (len_encoding << 5) |
18091 (rn.GetCode() << 16));
18092 AdvanceIT();
18093 return;
18094 }
18095 }
18096 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18097 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18098 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18099 operand.IsPostIndex() && encoded_align_2.IsValid() &&
18100 (!rn.IsPC() || AllowUnpredictable())) {
18101 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18102 const DRegister& first = nreglist.GetFirstDRegister();
18103 uint32_t len_encoding = nreglist.GetLength() - 1;
18104 EmitT32_32(0xf9a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
18105 (encoded_align_2.GetEncodingValue() << 4) |
18106 first.Encode(22, 12) | (len_encoding << 5) |
18107 (rn.GetCode() << 16));
18108 AdvanceIT();
18109 return;
18110 }
18111 }
18112 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18113 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18114 (nreglist.GetLength() == 1) && operand.IsOffset() &&
18115 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
18116 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18117 const DRegister& first = nreglist.GetFirstDRegister();
18118 EmitT32_32(0xf9a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
18119 (encoded_align_3.GetEncodingValue() << 4) |
18120 first.Encode(22, 12) | (rn.GetCode() << 16));
18121 AdvanceIT();
18122 return;
18123 }
18124 }
18125 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18126 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18127 (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
18128 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
18129 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18130 const DRegister& first = nreglist.GetFirstDRegister();
18131 EmitT32_32(0xf9a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
18132 (encoded_align_3.GetEncodingValue() << 4) |
18133 first.Encode(22, 12) | (rn.GetCode() << 16));
18134 AdvanceIT();
18135 return;
18136 }
18137 }
18138 } else {
18139 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18140 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18141 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
18142 operand.IsOffset() && encoded_align_1.IsValid() &&
18143 (!rn.IsPC() || AllowUnpredictable())) {
18144 if (cond.Is(al)) {
18145 const DRegister& first = nreglist.GetFirstDRegister();
18146 uint32_t len_encoding;
18147 switch (nreglist.GetLength()) {
18148 default:
18149 VIXL_UNREACHABLE_OR_FALLTHROUGH();
18150 case 1:
18151 len_encoding = 0x7;
18152 break;
18153 case 2:
18154 len_encoding = 0xa;
18155 break;
18156 case 3:
18157 len_encoding = 0x6;
18158 break;
18159 case 4:
18160 len_encoding = 0x2;
18161 break;
18162 }
18163 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
18164 (encoded_align_1.GetEncodingValue() << 4) |
18165 first.Encode(22, 12) | (len_encoding << 8) |
18166 (rn.GetCode() << 16));
18167 return;
18168 }
18169 }
18170 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18171 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18172 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
18173 operand.IsPostIndex() && encoded_align_1.IsValid() &&
18174 (!rn.IsPC() || AllowUnpredictable())) {
18175 if (cond.Is(al)) {
18176 const DRegister& first = nreglist.GetFirstDRegister();
18177 uint32_t len_encoding;
18178 switch (nreglist.GetLength()) {
18179 default:
18180 VIXL_UNREACHABLE_OR_FALLTHROUGH();
18181 case 1:
18182 len_encoding = 0x7;
18183 break;
18184 case 2:
18185 len_encoding = 0xa;
18186 break;
18187 case 3:
18188 len_encoding = 0x6;
18189 break;
18190 case 4:
18191 len_encoding = 0x2;
18192 break;
18193 }
18194 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
18195 (encoded_align_1.GetEncodingValue() << 4) |
18196 first.Encode(22, 12) | (len_encoding << 8) |
18197 (rn.GetCode() << 16));
18198 return;
18199 }
18200 }
18201 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18202 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18203 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18204 operand.IsOffset() && encoded_align_2.IsValid() &&
18205 (!rn.IsPC() || AllowUnpredictable())) {
18206 if (cond.Is(al)) {
18207 const DRegister& first = nreglist.GetFirstDRegister();
18208 uint32_t len_encoding = nreglist.GetLength() - 1;
18209 EmitA32(0xf4a00c0fU | (encoded_dt_2.GetEncodingValue() << 6) |
18210 (encoded_align_2.GetEncodingValue() << 4) |
18211 first.Encode(22, 12) | (len_encoding << 5) |
18212 (rn.GetCode() << 16));
18213 return;
18214 }
18215 }
18216 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18217 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18218 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18219 operand.IsPostIndex() && encoded_align_2.IsValid() &&
18220 (!rn.IsPC() || AllowUnpredictable())) {
18221 if (cond.Is(al)) {
18222 const DRegister& first = nreglist.GetFirstDRegister();
18223 uint32_t len_encoding = nreglist.GetLength() - 1;
18224 EmitA32(0xf4a00c0dU | (encoded_dt_2.GetEncodingValue() << 6) |
18225 (encoded_align_2.GetEncodingValue() << 4) |
18226 first.Encode(22, 12) | (len_encoding << 5) |
18227 (rn.GetCode() << 16));
18228 return;
18229 }
18230 }
18231 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18232 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18233 (nreglist.GetLength() == 1) && operand.IsOffset() &&
18234 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
18235 if (cond.Is(al)) {
18236 const DRegister& first = nreglist.GetFirstDRegister();
18237 EmitA32(0xf4a0000fU | (encoded_dt_2.GetEncodingValue() << 10) |
18238 (encoded_align_3.GetEncodingValue() << 4) |
18239 first.Encode(22, 12) | (rn.GetCode() << 16));
18240 return;
18241 }
18242 }
18243 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18244 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18245 (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
18246 encoded_align_3.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
18247 if (cond.Is(al)) {
18248 const DRegister& first = nreglist.GetFirstDRegister();
18249 EmitA32(0xf4a0000dU | (encoded_dt_2.GetEncodingValue() << 10) |
18250 (encoded_align_3.GetEncodingValue() << 4) |
18251 first.Encode(22, 12) | (rn.GetCode() << 16));
18252 return;
18253 }
18254 }
18255 }
18256 }
18257 if (operand.IsPlainRegister()) {
18258 Register rn = operand.GetBaseRegister();
18259 Alignment align = operand.GetAlignment();
18260 Register rm = operand.GetOffsetRegister();
18261 Dt_size_6 encoded_dt(dt);
18262 Dt_size_7 encoded_dt_2(dt);
18263 Align_align_1 encoded_align_1(align, nreglist);
18264 Align_a_1 encoded_align_2(align, dt);
18265 Align_index_align_1 encoded_align_3(align, nreglist, dt);
18266 if (IsUsingT32()) {
18267 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18268 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18269 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
18270 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18271 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18272 const DRegister& first = nreglist.GetFirstDRegister();
18273 uint32_t len_encoding;
18274 switch (nreglist.GetLength()) {
18275 default:
18276 VIXL_UNREACHABLE_OR_FALLTHROUGH();
18277 case 1:
18278 len_encoding = 0x7;
18279 break;
18280 case 2:
18281 len_encoding = 0xa;
18282 break;
18283 case 3:
18284 len_encoding = 0x6;
18285 break;
18286 case 4:
18287 len_encoding = 0x2;
18288 break;
18289 }
18290 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
18291 (encoded_align_1.GetEncodingValue() << 4) |
18292 first.Encode(22, 12) | (len_encoding << 8) |
18293 (rn.GetCode() << 16) | rm.GetCode());
18294 AdvanceIT();
18295 return;
18296 }
18297 }
18298 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18299 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18300 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18301 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18302 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18303 const DRegister& first = nreglist.GetFirstDRegister();
18304 uint32_t len_encoding = nreglist.GetLength() - 1;
18305 EmitT32_32(0xf9a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
18306 (encoded_align_2.GetEncodingValue() << 4) |
18307 first.Encode(22, 12) | (len_encoding << 5) |
18308 (rn.GetCode() << 16) | rm.GetCode());
18309 AdvanceIT();
18310 return;
18311 }
18312 }
18313 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18314 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18315 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
18316 (!rn.IsPC() || AllowUnpredictable())) {
18317 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18318 const DRegister& first = nreglist.GetFirstDRegister();
18319 EmitT32_32(0xf9a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
18320 (encoded_align_3.GetEncodingValue() << 4) |
18321 first.Encode(22, 12) | (rn.GetCode() << 16) |
18322 rm.GetCode());
18323 AdvanceIT();
18324 return;
18325 }
18326 }
18327 } else {
18328 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18329 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18330 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
18331 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18332 if (cond.Is(al)) {
18333 const DRegister& first = nreglist.GetFirstDRegister();
18334 uint32_t len_encoding;
18335 switch (nreglist.GetLength()) {
18336 default:
18337 VIXL_UNREACHABLE_OR_FALLTHROUGH();
18338 case 1:
18339 len_encoding = 0x7;
18340 break;
18341 case 2:
18342 len_encoding = 0xa;
18343 break;
18344 case 3:
18345 len_encoding = 0x6;
18346 break;
18347 case 4:
18348 len_encoding = 0x2;
18349 break;
18350 }
18351 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
18352 (encoded_align_1.GetEncodingValue() << 4) |
18353 first.Encode(22, 12) | (len_encoding << 8) |
18354 (rn.GetCode() << 16) | rm.GetCode());
18355 return;
18356 }
18357 }
18358 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18359 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
18360 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 2) &&
18361 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18362 if (cond.Is(al)) {
18363 const DRegister& first = nreglist.GetFirstDRegister();
18364 uint32_t len_encoding = nreglist.GetLength() - 1;
18365 EmitA32(0xf4a00c00U | (encoded_dt_2.GetEncodingValue() << 6) |
18366 (encoded_align_2.GetEncodingValue() << 4) |
18367 first.Encode(22, 12) | (len_encoding << 5) |
18368 (rn.GetCode() << 16) | rm.GetCode());
18369 return;
18370 }
18371 }
18372 // VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18373 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
18374 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
18375 (!rn.IsPC() || AllowUnpredictable())) {
18376 if (cond.Is(al)) {
18377 const DRegister& first = nreglist.GetFirstDRegister();
18378 EmitA32(0xf4a00000U | (encoded_dt_2.GetEncodingValue() << 10) |
18379 (encoded_align_3.GetEncodingValue() << 4) |
18380 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
18381 return;
18382 }
18383 }
18384 }
18385 }
18386 Delegate(kVld1, &Assembler::vld1, cond, dt, nreglist, operand);
18387 }
18388
vld2(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)18389 void Assembler::vld2(Condition cond,
18390 DataType dt,
18391 const NeonRegisterList& nreglist,
18392 const AlignedMemOperand& operand) {
18393 VIXL_ASSERT(AllowAssembler());
18394 CheckIT(cond);
18395 if (operand.IsImmediateZero()) {
18396 Register rn = operand.GetBaseRegister();
18397 Alignment align = operand.GetAlignment();
18398 Dt_size_7 encoded_dt(dt);
18399 Align_align_2 encoded_align_1(align, nreglist);
18400 Align_a_2 encoded_align_2(align, dt);
18401 Align_index_align_2 encoded_align_3(align, nreglist, dt);
18402 if (IsUsingT32()) {
18403 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18404 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18405 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18406 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18407 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18408 operand.IsOffset() && encoded_align_1.IsValid() &&
18409 (!rn.IsPC() || AllowUnpredictable())) {
18410 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18411 const DRegister& first = nreglist.GetFirstDRegister();
18412 uint32_t len_encoding;
18413 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18414 len_encoding = 0x8;
18415 }
18416 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18417 len_encoding = 0x9;
18418 }
18419 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18420 len_encoding = 0x3;
18421 }
18422 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
18423 (encoded_align_1.GetEncodingValue() << 4) |
18424 first.Encode(22, 12) | (len_encoding << 8) |
18425 (rn.GetCode() << 16));
18426 AdvanceIT();
18427 return;
18428 }
18429 }
18430 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18431 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18432 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18433 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18434 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18435 operand.IsPostIndex() && encoded_align_1.IsValid() &&
18436 (!rn.IsPC() || AllowUnpredictable())) {
18437 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18438 const DRegister& first = nreglist.GetFirstDRegister();
18439 uint32_t len_encoding;
18440 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18441 len_encoding = 0x8;
18442 }
18443 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18444 len_encoding = 0x9;
18445 }
18446 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18447 len_encoding = 0x3;
18448 }
18449 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
18450 (encoded_align_1.GetEncodingValue() << 4) |
18451 first.Encode(22, 12) | (len_encoding << 8) |
18452 (rn.GetCode() << 16));
18453 AdvanceIT();
18454 return;
18455 }
18456 }
18457 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18458 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18459 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18460 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18461 operand.IsOffset() && encoded_align_2.IsValid() &&
18462 (!rn.IsPC() || AllowUnpredictable())) {
18463 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18464 const DRegister& first = nreglist.GetFirstDRegister();
18465 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18466 EmitT32_32(0xf9a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
18467 (encoded_align_2.GetEncodingValue() << 4) |
18468 first.Encode(22, 12) | (len_encoding << 5) |
18469 (rn.GetCode() << 16));
18470 AdvanceIT();
18471 return;
18472 }
18473 }
18474 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18475 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18476 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18477 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18478 operand.IsPostIndex() && encoded_align_2.IsValid() &&
18479 (!rn.IsPC() || AllowUnpredictable())) {
18480 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18481 const DRegister& first = nreglist.GetFirstDRegister();
18482 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18483 EmitT32_32(0xf9a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
18484 (encoded_align_2.GetEncodingValue() << 4) |
18485 first.Encode(22, 12) | (len_encoding << 5) |
18486 (rn.GetCode() << 16));
18487 AdvanceIT();
18488 return;
18489 }
18490 }
18491 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18492 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18493 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18494 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18495 operand.IsOffset() && encoded_align_3.IsValid() &&
18496 (!rn.IsPC() || AllowUnpredictable())) {
18497 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18498 const DRegister& first = nreglist.GetFirstDRegister();
18499 EmitT32_32(0xf9a0010fU | (encoded_dt.GetEncodingValue() << 10) |
18500 (encoded_align_3.GetEncodingValue() << 4) |
18501 first.Encode(22, 12) | (rn.GetCode() << 16));
18502 AdvanceIT();
18503 return;
18504 }
18505 }
18506 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18507 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18508 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18509 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18510 operand.IsPostIndex() && encoded_align_3.IsValid() &&
18511 (!rn.IsPC() || AllowUnpredictable())) {
18512 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18513 const DRegister& first = nreglist.GetFirstDRegister();
18514 EmitT32_32(0xf9a0010dU | (encoded_dt.GetEncodingValue() << 10) |
18515 (encoded_align_3.GetEncodingValue() << 4) |
18516 first.Encode(22, 12) | (rn.GetCode() << 16));
18517 AdvanceIT();
18518 return;
18519 }
18520 }
18521 } else {
18522 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18523 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18524 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18525 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18526 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18527 operand.IsOffset() && encoded_align_1.IsValid() &&
18528 (!rn.IsPC() || AllowUnpredictable())) {
18529 if (cond.Is(al)) {
18530 const DRegister& first = nreglist.GetFirstDRegister();
18531 uint32_t len_encoding;
18532 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18533 len_encoding = 0x8;
18534 }
18535 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18536 len_encoding = 0x9;
18537 }
18538 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18539 len_encoding = 0x3;
18540 }
18541 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
18542 (encoded_align_1.GetEncodingValue() << 4) |
18543 first.Encode(22, 12) | (len_encoding << 8) |
18544 (rn.GetCode() << 16));
18545 return;
18546 }
18547 }
18548 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18549 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18550 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18551 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18552 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18553 operand.IsPostIndex() && encoded_align_1.IsValid() &&
18554 (!rn.IsPC() || AllowUnpredictable())) {
18555 if (cond.Is(al)) {
18556 const DRegister& first = nreglist.GetFirstDRegister();
18557 uint32_t len_encoding;
18558 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18559 len_encoding = 0x8;
18560 }
18561 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18562 len_encoding = 0x9;
18563 }
18564 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18565 len_encoding = 0x3;
18566 }
18567 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
18568 (encoded_align_1.GetEncodingValue() << 4) |
18569 first.Encode(22, 12) | (len_encoding << 8) |
18570 (rn.GetCode() << 16));
18571 return;
18572 }
18573 }
18574 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18575 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18576 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18577 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18578 operand.IsOffset() && encoded_align_2.IsValid() &&
18579 (!rn.IsPC() || AllowUnpredictable())) {
18580 if (cond.Is(al)) {
18581 const DRegister& first = nreglist.GetFirstDRegister();
18582 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18583 EmitA32(0xf4a00d0fU | (encoded_dt.GetEncodingValue() << 6) |
18584 (encoded_align_2.GetEncodingValue() << 4) |
18585 first.Encode(22, 12) | (len_encoding << 5) |
18586 (rn.GetCode() << 16));
18587 return;
18588 }
18589 }
18590 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18591 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18592 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18593 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18594 operand.IsPostIndex() && encoded_align_2.IsValid() &&
18595 (!rn.IsPC() || AllowUnpredictable())) {
18596 if (cond.Is(al)) {
18597 const DRegister& first = nreglist.GetFirstDRegister();
18598 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18599 EmitA32(0xf4a00d0dU | (encoded_dt.GetEncodingValue() << 6) |
18600 (encoded_align_2.GetEncodingValue() << 4) |
18601 first.Encode(22, 12) | (len_encoding << 5) |
18602 (rn.GetCode() << 16));
18603 return;
18604 }
18605 }
18606 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18607 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18608 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18609 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18610 operand.IsOffset() && encoded_align_3.IsValid() &&
18611 (!rn.IsPC() || AllowUnpredictable())) {
18612 if (cond.Is(al)) {
18613 const DRegister& first = nreglist.GetFirstDRegister();
18614 EmitA32(0xf4a0010fU | (encoded_dt.GetEncodingValue() << 10) |
18615 (encoded_align_3.GetEncodingValue() << 4) |
18616 first.Encode(22, 12) | (rn.GetCode() << 16));
18617 return;
18618 }
18619 }
18620 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18621 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18622 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18623 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18624 operand.IsPostIndex() && encoded_align_3.IsValid() &&
18625 (!rn.IsPC() || AllowUnpredictable())) {
18626 if (cond.Is(al)) {
18627 const DRegister& first = nreglist.GetFirstDRegister();
18628 EmitA32(0xf4a0010dU | (encoded_dt.GetEncodingValue() << 10) |
18629 (encoded_align_3.GetEncodingValue() << 4) |
18630 first.Encode(22, 12) | (rn.GetCode() << 16));
18631 return;
18632 }
18633 }
18634 }
18635 }
18636 if (operand.IsPlainRegister()) {
18637 Register rn = operand.GetBaseRegister();
18638 Alignment align = operand.GetAlignment();
18639 Register rm = operand.GetOffsetRegister();
18640 Dt_size_7 encoded_dt(dt);
18641 Align_align_2 encoded_align_1(align, nreglist);
18642 Align_a_2 encoded_align_2(align, dt);
18643 Align_index_align_2 encoded_align_3(align, nreglist, dt);
18644 if (IsUsingT32()) {
18645 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18646 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18647 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18648 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18649 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18650 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18651 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18652 const DRegister& first = nreglist.GetFirstDRegister();
18653 uint32_t len_encoding;
18654 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18655 len_encoding = 0x8;
18656 }
18657 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18658 len_encoding = 0x9;
18659 }
18660 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18661 len_encoding = 0x3;
18662 }
18663 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
18664 (encoded_align_1.GetEncodingValue() << 4) |
18665 first.Encode(22, 12) | (len_encoding << 8) |
18666 (rn.GetCode() << 16) | rm.GetCode());
18667 AdvanceIT();
18668 return;
18669 }
18670 }
18671 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18672 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18673 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18674 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18675 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18676 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18677 const DRegister& first = nreglist.GetFirstDRegister();
18678 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18679 EmitT32_32(0xf9a00d00U | (encoded_dt.GetEncodingValue() << 6) |
18680 (encoded_align_2.GetEncodingValue() << 4) |
18681 first.Encode(22, 12) | (len_encoding << 5) |
18682 (rn.GetCode() << 16) | rm.GetCode());
18683 AdvanceIT();
18684 return;
18685 }
18686 }
18687 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18688 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18689 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18690 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18691 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18692 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18693 const DRegister& first = nreglist.GetFirstDRegister();
18694 EmitT32_32(0xf9a00100U | (encoded_dt.GetEncodingValue() << 10) |
18695 (encoded_align_3.GetEncodingValue() << 4) |
18696 first.Encode(22, 12) | (rn.GetCode() << 16) |
18697 rm.GetCode());
18698 AdvanceIT();
18699 return;
18700 }
18701 }
18702 } else {
18703 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18704 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18705 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18706 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
18707 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
18708 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18709 if (cond.Is(al)) {
18710 const DRegister& first = nreglist.GetFirstDRegister();
18711 uint32_t len_encoding;
18712 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
18713 len_encoding = 0x8;
18714 }
18715 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
18716 len_encoding = 0x9;
18717 }
18718 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
18719 len_encoding = 0x3;
18720 }
18721 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
18722 (encoded_align_1.GetEncodingValue() << 4) |
18723 first.Encode(22, 12) | (len_encoding << 8) |
18724 (rn.GetCode() << 16) | rm.GetCode());
18725 return;
18726 }
18727 }
18728 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18729 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18730 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18731 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18732 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18733 if (cond.Is(al)) {
18734 const DRegister& first = nreglist.GetFirstDRegister();
18735 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18736 EmitA32(0xf4a00d00U | (encoded_dt.GetEncodingValue() << 6) |
18737 (encoded_align_2.GetEncodingValue() << 4) |
18738 first.Encode(22, 12) | (len_encoding << 5) |
18739 (rn.GetCode() << 16) | rm.GetCode());
18740 return;
18741 }
18742 }
18743 // VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18744 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18745 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
18746 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
18747 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18748 if (cond.Is(al)) {
18749 const DRegister& first = nreglist.GetFirstDRegister();
18750 EmitA32(0xf4a00100U | (encoded_dt.GetEncodingValue() << 10) |
18751 (encoded_align_3.GetEncodingValue() << 4) |
18752 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
18753 return;
18754 }
18755 }
18756 }
18757 }
18758 Delegate(kVld2, &Assembler::vld2, cond, dt, nreglist, operand);
18759 }
18760
vld3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)18761 void Assembler::vld3(Condition cond,
18762 DataType dt,
18763 const NeonRegisterList& nreglist,
18764 const AlignedMemOperand& operand) {
18765 VIXL_ASSERT(AllowAssembler());
18766 CheckIT(cond);
18767 if (operand.IsImmediateZero()) {
18768 Register rn = operand.GetBaseRegister();
18769 Alignment align = operand.GetAlignment();
18770 Dt_size_7 encoded_dt(dt);
18771 Align_align_3 encoded_align_1(align);
18772 if (IsUsingT32()) {
18773 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
18774 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18775 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18776 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18777 operand.IsOffset() && encoded_align_1.IsValid() &&
18778 (!rn.IsPC() || AllowUnpredictable())) {
18779 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18780 const DRegister& first = nreglist.GetFirstDRegister();
18781 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18782 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
18783 (encoded_align_1.GetEncodingValue() << 4) |
18784 first.Encode(22, 12) | (len_encoding << 8) |
18785 (rn.GetCode() << 16));
18786 AdvanceIT();
18787 return;
18788 }
18789 }
18790 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
18791 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18792 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18793 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18794 operand.IsPostIndex() && encoded_align_1.IsValid() &&
18795 (!rn.IsPC() || AllowUnpredictable())) {
18796 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18797 const DRegister& first = nreglist.GetFirstDRegister();
18798 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18799 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
18800 (encoded_align_1.GetEncodingValue() << 4) |
18801 first.Encode(22, 12) | (len_encoding << 8) |
18802 (rn.GetCode() << 16));
18803 AdvanceIT();
18804 return;
18805 }
18806 }
18807 } else {
18808 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
18809 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18810 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18811 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18812 operand.IsOffset() && encoded_align_1.IsValid() &&
18813 (!rn.IsPC() || AllowUnpredictable())) {
18814 if (cond.Is(al)) {
18815 const DRegister& first = nreglist.GetFirstDRegister();
18816 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18817 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
18818 (encoded_align_1.GetEncodingValue() << 4) |
18819 first.Encode(22, 12) | (len_encoding << 8) |
18820 (rn.GetCode() << 16));
18821 return;
18822 }
18823 }
18824 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
18825 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18826 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18827 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18828 operand.IsPostIndex() && encoded_align_1.IsValid() &&
18829 (!rn.IsPC() || AllowUnpredictable())) {
18830 if (cond.Is(al)) {
18831 const DRegister& first = nreglist.GetFirstDRegister();
18832 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18833 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
18834 (encoded_align_1.GetEncodingValue() << 4) |
18835 first.Encode(22, 12) | (len_encoding << 8) |
18836 (rn.GetCode() << 16));
18837 return;
18838 }
18839 }
18840 }
18841 }
18842 if (operand.IsPlainRegister()) {
18843 Register rn = operand.GetBaseRegister();
18844 Alignment align = operand.GetAlignment();
18845 Register rm = operand.GetOffsetRegister();
18846 Dt_size_7 encoded_dt(dt);
18847 Align_align_3 encoded_align_1(align);
18848 if (IsUsingT32()) {
18849 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
18850 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18851 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18852 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18853 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18854 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18855 const DRegister& first = nreglist.GetFirstDRegister();
18856 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18857 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
18858 (encoded_align_1.GetEncodingValue() << 4) |
18859 first.Encode(22, 12) | (len_encoding << 8) |
18860 (rn.GetCode() << 16) | rm.GetCode());
18861 AdvanceIT();
18862 return;
18863 }
18864 }
18865 } else {
18866 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
18867 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
18868 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18869 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18870 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
18871 if (cond.Is(al)) {
18872 const DRegister& first = nreglist.GetFirstDRegister();
18873 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
18874 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
18875 (encoded_align_1.GetEncodingValue() << 4) |
18876 first.Encode(22, 12) | (len_encoding << 8) |
18877 (rn.GetCode() << 16) | rm.GetCode());
18878 return;
18879 }
18880 }
18881 }
18882 }
18883 Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
18884 }
18885
vld3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const MemOperand & operand)18886 void Assembler::vld3(Condition cond,
18887 DataType dt,
18888 const NeonRegisterList& nreglist,
18889 const MemOperand& operand) {
18890 VIXL_ASSERT(AllowAssembler());
18891 CheckIT(cond);
18892 if (operand.IsImmediateZero()) {
18893 Register rn = operand.GetBaseRegister();
18894 Dt_size_7 encoded_dt(dt);
18895 Index_1 encoded_align_1(nreglist, dt);
18896 if (IsUsingT32()) {
18897 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
18898 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18899 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18900 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18901 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
18902 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18903 const DRegister& first = nreglist.GetFirstDRegister();
18904 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18905 EmitT32_32(0xf9a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
18906 first.Encode(22, 12) | (len_encoding << 5) |
18907 (rn.GetCode() << 16));
18908 AdvanceIT();
18909 return;
18910 }
18911 }
18912 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
18913 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18914 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18915 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18916 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
18917 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18918 const DRegister& first = nreglist.GetFirstDRegister();
18919 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18920 EmitT32_32(0xf9a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
18921 first.Encode(22, 12) | (len_encoding << 5) |
18922 (rn.GetCode() << 16));
18923 AdvanceIT();
18924 return;
18925 }
18926 }
18927 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
18928 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18929 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18930 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18931 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
18932 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18933 const DRegister& first = nreglist.GetFirstDRegister();
18934 EmitT32_32(0xf9a0020fU | (encoded_dt.GetEncodingValue() << 10) |
18935 (encoded_align_1.GetEncodingValue() << 4) |
18936 first.Encode(22, 12) | (rn.GetCode() << 16));
18937 AdvanceIT();
18938 return;
18939 }
18940 }
18941 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
18942 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18943 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18944 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18945 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
18946 if (cond.Is(al) || AllowStronglyDiscouraged()) {
18947 const DRegister& first = nreglist.GetFirstDRegister();
18948 EmitT32_32(0xf9a0020dU | (encoded_dt.GetEncodingValue() << 10) |
18949 (encoded_align_1.GetEncodingValue() << 4) |
18950 first.Encode(22, 12) | (rn.GetCode() << 16));
18951 AdvanceIT();
18952 return;
18953 }
18954 }
18955 } else {
18956 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
18957 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18958 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18959 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18960 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
18961 if (cond.Is(al)) {
18962 const DRegister& first = nreglist.GetFirstDRegister();
18963 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18964 EmitA32(0xf4a00e0fU | (encoded_dt.GetEncodingValue() << 6) |
18965 first.Encode(22, 12) | (len_encoding << 5) |
18966 (rn.GetCode() << 16));
18967 return;
18968 }
18969 }
18970 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
18971 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
18972 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18973 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18974 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
18975 if (cond.Is(al)) {
18976 const DRegister& first = nreglist.GetFirstDRegister();
18977 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
18978 EmitA32(0xf4a00e0dU | (encoded_dt.GetEncodingValue() << 6) |
18979 first.Encode(22, 12) | (len_encoding << 5) |
18980 (rn.GetCode() << 16));
18981 return;
18982 }
18983 }
18984 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
18985 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18986 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
18987 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
18988 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
18989 if (cond.Is(al)) {
18990 const DRegister& first = nreglist.GetFirstDRegister();
18991 EmitA32(0xf4a0020fU | (encoded_dt.GetEncodingValue() << 10) |
18992 (encoded_align_1.GetEncodingValue() << 4) |
18993 first.Encode(22, 12) | (rn.GetCode() << 16));
18994 return;
18995 }
18996 }
18997 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
18998 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
18999 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
19000 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
19001 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
19002 if (cond.Is(al)) {
19003 const DRegister& first = nreglist.GetFirstDRegister();
19004 EmitA32(0xf4a0020dU | (encoded_dt.GetEncodingValue() << 10) |
19005 (encoded_align_1.GetEncodingValue() << 4) |
19006 first.Encode(22, 12) | (rn.GetCode() << 16));
19007 return;
19008 }
19009 }
19010 }
19011 }
19012 if (operand.IsPlainRegister()) {
19013 Register rn = operand.GetBaseRegister();
19014 Sign sign = operand.GetSign();
19015 Register rm = operand.GetOffsetRegister();
19016 Dt_size_7 encoded_dt(dt);
19017 Index_1 encoded_align_1(nreglist, dt);
19018 if (IsUsingT32()) {
19019 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
19020 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
19021 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
19022 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
19023 sign.IsPlus() && operand.IsPostIndex() &&
19024 (!rn.IsPC() || AllowUnpredictable())) {
19025 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19026 const DRegister& first = nreglist.GetFirstDRegister();
19027 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19028 EmitT32_32(0xf9a00e00U | (encoded_dt.GetEncodingValue() << 6) |
19029 first.Encode(22, 12) | (len_encoding << 5) |
19030 (rn.GetCode() << 16) | rm.GetCode());
19031 AdvanceIT();
19032 return;
19033 }
19034 }
19035 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
19036 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19037 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
19038 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
19039 sign.IsPlus() && operand.IsPostIndex() &&
19040 (!rn.IsPC() || AllowUnpredictable())) {
19041 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19042 const DRegister& first = nreglist.GetFirstDRegister();
19043 EmitT32_32(0xf9a00200U | (encoded_dt.GetEncodingValue() << 10) |
19044 (encoded_align_1.GetEncodingValue() << 4) |
19045 first.Encode(22, 12) | (rn.GetCode() << 16) |
19046 rm.GetCode());
19047 AdvanceIT();
19048 return;
19049 }
19050 }
19051 } else {
19052 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
19053 if (encoded_dt.IsValid() && nreglist.IsTransferAllLanes() &&
19054 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
19055 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
19056 sign.IsPlus() && operand.IsPostIndex() &&
19057 (!rn.IsPC() || AllowUnpredictable())) {
19058 if (cond.Is(al)) {
19059 const DRegister& first = nreglist.GetFirstDRegister();
19060 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19061 EmitA32(0xf4a00e00U | (encoded_dt.GetEncodingValue() << 6) |
19062 first.Encode(22, 12) | (len_encoding << 5) |
19063 (rn.GetCode() << 16) | rm.GetCode());
19064 return;
19065 }
19066 }
19067 // VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
19068 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19069 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
19070 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
19071 sign.IsPlus() && operand.IsPostIndex() &&
19072 (!rn.IsPC() || AllowUnpredictable())) {
19073 if (cond.Is(al)) {
19074 const DRegister& first = nreglist.GetFirstDRegister();
19075 EmitA32(0xf4a00200U | (encoded_dt.GetEncodingValue() << 10) |
19076 (encoded_align_1.GetEncodingValue() << 4) |
19077 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
19078 return;
19079 }
19080 }
19081 }
19082 }
19083 Delegate(kVld3, &Assembler::vld3, cond, dt, nreglist, operand);
19084 }
19085
vld4(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)19086 void Assembler::vld4(Condition cond,
19087 DataType dt,
19088 const NeonRegisterList& nreglist,
19089 const AlignedMemOperand& operand) {
19090 VIXL_ASSERT(AllowAssembler());
19091 CheckIT(cond);
19092 if (operand.IsImmediateZero()) {
19093 Register rn = operand.GetBaseRegister();
19094 Alignment align = operand.GetAlignment();
19095 Dt_size_7 encoded_dt(dt);
19096 Dt_size_8 encoded_dt_2(dt, align);
19097 Align_align_4 encoded_align_1(align);
19098 Align_a_3 encoded_align_2(align, dt);
19099 Align_index_align_3 encoded_align_3(align, nreglist, dt);
19100 if (IsUsingT32()) {
19101 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
19102 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19103 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19104 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19105 operand.IsOffset() && encoded_align_1.IsValid() &&
19106 (!rn.IsPC() || AllowUnpredictable())) {
19107 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19108 const DRegister& first = nreglist.GetFirstDRegister();
19109 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19110 EmitT32_32(0xf920000fU | (encoded_dt.GetEncodingValue() << 6) |
19111 (encoded_align_1.GetEncodingValue() << 4) |
19112 first.Encode(22, 12) | (len_encoding << 8) |
19113 (rn.GetCode() << 16));
19114 AdvanceIT();
19115 return;
19116 }
19117 }
19118 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
19119 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19120 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19121 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19122 operand.IsPostIndex() && encoded_align_1.IsValid() &&
19123 (!rn.IsPC() || AllowUnpredictable())) {
19124 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19125 const DRegister& first = nreglist.GetFirstDRegister();
19126 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19127 EmitT32_32(0xf920000dU | (encoded_dt.GetEncodingValue() << 6) |
19128 (encoded_align_1.GetEncodingValue() << 4) |
19129 first.Encode(22, 12) | (len_encoding << 8) |
19130 (rn.GetCode() << 16));
19131 AdvanceIT();
19132 return;
19133 }
19134 }
19135 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
19136 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19137 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19138 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19139 operand.IsOffset() && encoded_align_2.IsValid() &&
19140 (!rn.IsPC() || AllowUnpredictable())) {
19141 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19142 const DRegister& first = nreglist.GetFirstDRegister();
19143 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19144 EmitT32_32(0xf9a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
19145 (encoded_align_2.GetEncodingValue() << 4) |
19146 first.Encode(22, 12) | (len_encoding << 5) |
19147 (rn.GetCode() << 16));
19148 AdvanceIT();
19149 return;
19150 }
19151 }
19152 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
19153 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19154 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19155 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19156 operand.IsPostIndex() && encoded_align_2.IsValid() &&
19157 (!rn.IsPC() || AllowUnpredictable())) {
19158 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19159 const DRegister& first = nreglist.GetFirstDRegister();
19160 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19161 EmitT32_32(0xf9a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
19162 (encoded_align_2.GetEncodingValue() << 4) |
19163 first.Encode(22, 12) | (len_encoding << 5) |
19164 (rn.GetCode() << 16));
19165 AdvanceIT();
19166 return;
19167 }
19168 }
19169 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
19170 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19171 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19172 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19173 operand.IsOffset() && encoded_align_3.IsValid() &&
19174 (!rn.IsPC() || AllowUnpredictable())) {
19175 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19176 const DRegister& first = nreglist.GetFirstDRegister();
19177 EmitT32_32(0xf9a0030fU | (encoded_dt.GetEncodingValue() << 10) |
19178 (encoded_align_3.GetEncodingValue() << 4) |
19179 first.Encode(22, 12) | (rn.GetCode() << 16));
19180 AdvanceIT();
19181 return;
19182 }
19183 }
19184 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
19185 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19186 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19187 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19188 operand.IsPostIndex() && encoded_align_3.IsValid() &&
19189 (!rn.IsPC() || AllowUnpredictable())) {
19190 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19191 const DRegister& first = nreglist.GetFirstDRegister();
19192 EmitT32_32(0xf9a0030dU | (encoded_dt.GetEncodingValue() << 10) |
19193 (encoded_align_3.GetEncodingValue() << 4) |
19194 first.Encode(22, 12) | (rn.GetCode() << 16));
19195 AdvanceIT();
19196 return;
19197 }
19198 }
19199 } else {
19200 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
19201 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19202 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19203 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19204 operand.IsOffset() && encoded_align_1.IsValid() &&
19205 (!rn.IsPC() || AllowUnpredictable())) {
19206 if (cond.Is(al)) {
19207 const DRegister& first = nreglist.GetFirstDRegister();
19208 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19209 EmitA32(0xf420000fU | (encoded_dt.GetEncodingValue() << 6) |
19210 (encoded_align_1.GetEncodingValue() << 4) |
19211 first.Encode(22, 12) | (len_encoding << 8) |
19212 (rn.GetCode() << 16));
19213 return;
19214 }
19215 }
19216 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
19217 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19218 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19219 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19220 operand.IsPostIndex() && encoded_align_1.IsValid() &&
19221 (!rn.IsPC() || AllowUnpredictable())) {
19222 if (cond.Is(al)) {
19223 const DRegister& first = nreglist.GetFirstDRegister();
19224 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19225 EmitA32(0xf420000dU | (encoded_dt.GetEncodingValue() << 6) |
19226 (encoded_align_1.GetEncodingValue() << 4) |
19227 first.Encode(22, 12) | (len_encoding << 8) |
19228 (rn.GetCode() << 16));
19229 return;
19230 }
19231 }
19232 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
19233 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19234 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19235 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19236 operand.IsOffset() && encoded_align_2.IsValid() &&
19237 (!rn.IsPC() || AllowUnpredictable())) {
19238 if (cond.Is(al)) {
19239 const DRegister& first = nreglist.GetFirstDRegister();
19240 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19241 EmitA32(0xf4a00f0fU | (encoded_dt_2.GetEncodingValue() << 6) |
19242 (encoded_align_2.GetEncodingValue() << 4) |
19243 first.Encode(22, 12) | (len_encoding << 5) |
19244 (rn.GetCode() << 16));
19245 return;
19246 }
19247 }
19248 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
19249 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19250 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19251 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19252 operand.IsPostIndex() && encoded_align_2.IsValid() &&
19253 (!rn.IsPC() || AllowUnpredictable())) {
19254 if (cond.Is(al)) {
19255 const DRegister& first = nreglist.GetFirstDRegister();
19256 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19257 EmitA32(0xf4a00f0dU | (encoded_dt_2.GetEncodingValue() << 6) |
19258 (encoded_align_2.GetEncodingValue() << 4) |
19259 first.Encode(22, 12) | (len_encoding << 5) |
19260 (rn.GetCode() << 16));
19261 return;
19262 }
19263 }
19264 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
19265 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19266 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19267 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19268 operand.IsOffset() && encoded_align_3.IsValid() &&
19269 (!rn.IsPC() || AllowUnpredictable())) {
19270 if (cond.Is(al)) {
19271 const DRegister& first = nreglist.GetFirstDRegister();
19272 EmitA32(0xf4a0030fU | (encoded_dt.GetEncodingValue() << 10) |
19273 (encoded_align_3.GetEncodingValue() << 4) |
19274 first.Encode(22, 12) | (rn.GetCode() << 16));
19275 return;
19276 }
19277 }
19278 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
19279 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19280 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19281 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19282 operand.IsPostIndex() && encoded_align_3.IsValid() &&
19283 (!rn.IsPC() || AllowUnpredictable())) {
19284 if (cond.Is(al)) {
19285 const DRegister& first = nreglist.GetFirstDRegister();
19286 EmitA32(0xf4a0030dU | (encoded_dt.GetEncodingValue() << 10) |
19287 (encoded_align_3.GetEncodingValue() << 4) |
19288 first.Encode(22, 12) | (rn.GetCode() << 16));
19289 return;
19290 }
19291 }
19292 }
19293 }
19294 if (operand.IsPlainRegister()) {
19295 Register rn = operand.GetBaseRegister();
19296 Alignment align = operand.GetAlignment();
19297 Register rm = operand.GetOffsetRegister();
19298 Dt_size_7 encoded_dt(dt);
19299 Dt_size_8 encoded_dt_2(dt, align);
19300 Align_align_4 encoded_align_1(align);
19301 Align_a_3 encoded_align_2(align, dt);
19302 Align_index_align_3 encoded_align_3(align, nreglist, dt);
19303 if (IsUsingT32()) {
19304 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
19305 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19306 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19307 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19308 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19309 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19310 const DRegister& first = nreglist.GetFirstDRegister();
19311 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19312 EmitT32_32(0xf9200000U | (encoded_dt.GetEncodingValue() << 6) |
19313 (encoded_align_1.GetEncodingValue() << 4) |
19314 first.Encode(22, 12) | (len_encoding << 8) |
19315 (rn.GetCode() << 16) | rm.GetCode());
19316 AdvanceIT();
19317 return;
19318 }
19319 }
19320 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
19321 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19322 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19323 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19324 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19325 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19326 const DRegister& first = nreglist.GetFirstDRegister();
19327 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19328 EmitT32_32(0xf9a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
19329 (encoded_align_2.GetEncodingValue() << 4) |
19330 first.Encode(22, 12) | (len_encoding << 5) |
19331 (rn.GetCode() << 16) | rm.GetCode());
19332 AdvanceIT();
19333 return;
19334 }
19335 }
19336 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
19337 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19338 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19339 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19340 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19341 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19342 const DRegister& first = nreglist.GetFirstDRegister();
19343 EmitT32_32(0xf9a00300U | (encoded_dt.GetEncodingValue() << 10) |
19344 (encoded_align_3.GetEncodingValue() << 4) |
19345 first.Encode(22, 12) | (rn.GetCode() << 16) |
19346 rm.GetCode());
19347 AdvanceIT();
19348 return;
19349 }
19350 }
19351 } else {
19352 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
19353 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
19354 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19355 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19356 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19357 if (cond.Is(al)) {
19358 const DRegister& first = nreglist.GetFirstDRegister();
19359 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19360 EmitA32(0xf4200000U | (encoded_dt.GetEncodingValue() << 6) |
19361 (encoded_align_1.GetEncodingValue() << 4) |
19362 first.Encode(22, 12) | (len_encoding << 8) |
19363 (rn.GetCode() << 16) | rm.GetCode());
19364 return;
19365 }
19366 }
19367 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
19368 if (encoded_dt_2.IsValid() && nreglist.IsTransferAllLanes() &&
19369 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19370 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19371 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19372 if (cond.Is(al)) {
19373 const DRegister& first = nreglist.GetFirstDRegister();
19374 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
19375 EmitA32(0xf4a00f00U | (encoded_dt_2.GetEncodingValue() << 6) |
19376 (encoded_align_2.GetEncodingValue() << 4) |
19377 first.Encode(22, 12) | (len_encoding << 5) |
19378 (rn.GetCode() << 16) | rm.GetCode());
19379 return;
19380 }
19381 }
19382 // VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
19383 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
19384 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
19385 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
19386 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
19387 if (cond.Is(al)) {
19388 const DRegister& first = nreglist.GetFirstDRegister();
19389 EmitA32(0xf4a00300U | (encoded_dt.GetEncodingValue() << 10) |
19390 (encoded_align_3.GetEncodingValue() << 4) |
19391 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
19392 return;
19393 }
19394 }
19395 }
19396 }
19397 Delegate(kVld4, &Assembler::vld4, cond, dt, nreglist, operand);
19398 }
19399
vldm(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)19400 void Assembler::vldm(Condition cond,
19401 DataType dt,
19402 Register rn,
19403 WriteBack write_back,
19404 DRegisterList dreglist) {
19405 VIXL_ASSERT(AllowAssembler());
19406 CheckIT(cond);
19407 USE(dt);
19408 if (IsUsingT32()) {
19409 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
19410 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
19411 AllowUnpredictable())) {
19412 const DRegister& dreg = dreglist.GetFirstDRegister();
19413 unsigned len = dreglist.GetLength() * 2;
19414 EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
19415 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
19416 (len & 0xff));
19417 AdvanceIT();
19418 return;
19419 }
19420 } else {
19421 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
19422 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
19423 (!rn.IsPC() || !write_back.DoesWriteBack())) ||
19424 AllowUnpredictable())) {
19425 const DRegister& dreg = dreglist.GetFirstDRegister();
19426 unsigned len = dreglist.GetLength() * 2;
19427 EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19428 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
19429 (len & 0xff));
19430 return;
19431 }
19432 }
19433 Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, dreglist);
19434 }
19435
vldm(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)19436 void Assembler::vldm(Condition cond,
19437 DataType dt,
19438 Register rn,
19439 WriteBack write_back,
19440 SRegisterList sreglist) {
19441 VIXL_ASSERT(AllowAssembler());
19442 CheckIT(cond);
19443 USE(dt);
19444 if (IsUsingT32()) {
19445 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
19446 if ((!rn.IsPC() || AllowUnpredictable())) {
19447 const SRegister& sreg = sreglist.GetFirstSRegister();
19448 unsigned len = sreglist.GetLength();
19449 EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
19450 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
19451 (len & 0xff));
19452 AdvanceIT();
19453 return;
19454 }
19455 } else {
19456 // VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
19457 if (cond.IsNotNever() &&
19458 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
19459 const SRegister& sreg = sreglist.GetFirstSRegister();
19460 unsigned len = sreglist.GetLength();
19461 EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19462 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
19463 (len & 0xff));
19464 return;
19465 }
19466 }
19467 Delegate(kVldm, &Assembler::vldm, cond, dt, rn, write_back, sreglist);
19468 }
19469
vldmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)19470 void Assembler::vldmdb(Condition cond,
19471 DataType dt,
19472 Register rn,
19473 WriteBack write_back,
19474 DRegisterList dreglist) {
19475 VIXL_ASSERT(AllowAssembler());
19476 CheckIT(cond);
19477 USE(dt);
19478 if (IsUsingT32()) {
19479 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
19480 if (write_back.DoesWriteBack() &&
19481 (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
19482 AllowUnpredictable())) {
19483 const DRegister& dreg = dreglist.GetFirstDRegister();
19484 unsigned len = dreglist.GetLength() * 2;
19485 EmitT32_32(0xed300b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
19486 (len & 0xff));
19487 AdvanceIT();
19488 return;
19489 }
19490 } else {
19491 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
19492 if (write_back.DoesWriteBack() && cond.IsNotNever() &&
19493 (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
19494 AllowUnpredictable())) {
19495 const DRegister& dreg = dreglist.GetFirstDRegister();
19496 unsigned len = dreglist.GetLength() * 2;
19497 EmitA32(0x0d300b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19498 dreg.Encode(22, 12) | (len & 0xff));
19499 return;
19500 }
19501 }
19502 Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, dreglist);
19503 }
19504
vldmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)19505 void Assembler::vldmdb(Condition cond,
19506 DataType dt,
19507 Register rn,
19508 WriteBack write_back,
19509 SRegisterList sreglist) {
19510 VIXL_ASSERT(AllowAssembler());
19511 CheckIT(cond);
19512 USE(dt);
19513 if (IsUsingT32()) {
19514 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
19515 if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) {
19516 const SRegister& sreg = sreglist.GetFirstSRegister();
19517 unsigned len = sreglist.GetLength();
19518 EmitT32_32(0xed300a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
19519 (len & 0xff));
19520 AdvanceIT();
19521 return;
19522 }
19523 } else {
19524 // VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
19525 if (write_back.DoesWriteBack() && cond.IsNotNever() &&
19526 (!rn.IsPC() || AllowUnpredictable())) {
19527 const SRegister& sreg = sreglist.GetFirstSRegister();
19528 unsigned len = sreglist.GetLength();
19529 EmitA32(0x0d300a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19530 sreg.Encode(22, 12) | (len & 0xff));
19531 return;
19532 }
19533 }
19534 Delegate(kVldmdb, &Assembler::vldmdb, cond, dt, rn, write_back, sreglist);
19535 }
19536
vldmia(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)19537 void Assembler::vldmia(Condition cond,
19538 DataType dt,
19539 Register rn,
19540 WriteBack write_back,
19541 DRegisterList dreglist) {
19542 VIXL_ASSERT(AllowAssembler());
19543 CheckIT(cond);
19544 USE(dt);
19545 if (IsUsingT32()) {
19546 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
19547 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
19548 AllowUnpredictable())) {
19549 const DRegister& dreg = dreglist.GetFirstDRegister();
19550 unsigned len = dreglist.GetLength() * 2;
19551 EmitT32_32(0xec900b00U | (rn.GetCode() << 16) |
19552 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
19553 (len & 0xff));
19554 AdvanceIT();
19555 return;
19556 }
19557 } else {
19558 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
19559 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
19560 (!rn.IsPC() || !write_back.DoesWriteBack())) ||
19561 AllowUnpredictable())) {
19562 const DRegister& dreg = dreglist.GetFirstDRegister();
19563 unsigned len = dreglist.GetLength() * 2;
19564 EmitA32(0x0c900b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19565 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
19566 (len & 0xff));
19567 return;
19568 }
19569 }
19570 Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, dreglist);
19571 }
19572
vldmia(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)19573 void Assembler::vldmia(Condition cond,
19574 DataType dt,
19575 Register rn,
19576 WriteBack write_back,
19577 SRegisterList sreglist) {
19578 VIXL_ASSERT(AllowAssembler());
19579 CheckIT(cond);
19580 USE(dt);
19581 if (IsUsingT32()) {
19582 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
19583 if ((!rn.IsPC() || AllowUnpredictable())) {
19584 const SRegister& sreg = sreglist.GetFirstSRegister();
19585 unsigned len = sreglist.GetLength();
19586 EmitT32_32(0xec900a00U | (rn.GetCode() << 16) |
19587 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
19588 (len & 0xff));
19589 AdvanceIT();
19590 return;
19591 }
19592 } else {
19593 // VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
19594 if (cond.IsNotNever() &&
19595 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
19596 const SRegister& sreg = sreglist.GetFirstSRegister();
19597 unsigned len = sreglist.GetLength();
19598 EmitA32(0x0c900a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
19599 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
19600 (len & 0xff));
19601 return;
19602 }
19603 }
19604 Delegate(kVldmia, &Assembler::vldmia, cond, dt, rn, write_back, sreglist);
19605 }
19606
vldr(Condition cond,DataType dt,DRegister rd,Location * location)19607 void Assembler::vldr(Condition cond,
19608 DataType dt,
19609 DRegister rd,
19610 Location* location) {
19611 VIXL_ASSERT(AllowAssembler());
19612 CheckIT(cond);
19613 Location::Offset offset =
19614 location->IsBound()
19615 ? location->GetLocation() -
19616 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
19617 : 0;
19618 if (IsUsingT32()) {
19619 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
19620 if (dt.IsNoneOr(Untyped64) &&
19621 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
19622 ((offset & 0x3) == 0)) ||
19623 !location->IsBound())) {
19624 static class EmitOp : public Location::EmitOperator {
19625 public:
19626 EmitOp() : Location::EmitOperator(T32) {}
19627 virtual uint32_t Encode(uint32_t instr,
19628 Location::Offset program_counter,
19629 const Location* loc) const VIXL_OVERRIDE {
19630 program_counter += kT32PcDelta;
19631 Location::Offset off =
19632 loc->GetLocation() - AlignDown(program_counter, 4);
19633 VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0));
19634 int32_t target = off >> 2;
19635 uint32_t U = (target >= 0);
19636 target = abs(target) | (U << 8);
19637 return instr | (target & 0xff) | ((target & 0x100) << 15);
19638 }
19639 } immop;
19640 EmitT32_32(Link(0xed1f0b00U | rd.Encode(22, 12),
19641 location,
19642 immop,
19643 &kT32DataInfo));
19644 AdvanceIT();
19645 return;
19646 }
19647 } else {
19648 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
19649 if (dt.IsNoneOr(Untyped64) &&
19650 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
19651 ((offset & 0x3) == 0)) ||
19652 !location->IsBound()) &&
19653 cond.IsNotNever()) {
19654 static class EmitOp : public Location::EmitOperator {
19655 public:
19656 EmitOp() : Location::EmitOperator(A32) {}
19657 virtual uint32_t Encode(uint32_t instr,
19658 Location::Offset program_counter,
19659 const Location* loc) const VIXL_OVERRIDE {
19660 program_counter += kA32PcDelta;
19661 Location::Offset off =
19662 loc->GetLocation() - AlignDown(program_counter, 4);
19663 VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0));
19664 int32_t target = off >> 2;
19665 uint32_t U = (target >= 0);
19666 target = abs(target) | (U << 8);
19667 return instr | (target & 0xff) | ((target & 0x100) << 15);
19668 }
19669 } immop;
19670 EmitA32(
19671 Link(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
19672 location,
19673 immop,
19674 &kA32DataInfo));
19675 return;
19676 }
19677 }
19678 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location);
19679 }
19680
vldr_info(Condition cond,DataType dt,DRegister rd,Location * location,const struct ReferenceInfo ** info)19681 bool Assembler::vldr_info(Condition cond,
19682 DataType dt,
19683 DRegister rd,
19684 Location* location,
19685 const struct ReferenceInfo** info) {
19686 VIXL_ASSERT(!location->IsBound());
19687 USE(location);
19688 USE(rd);
19689 if (IsUsingT32()) {
19690 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
19691 if (dt.IsNoneOr(Untyped64)) {
19692 *info = &kT32DataInfo;
19693 return true;
19694 }
19695 } else {
19696 // VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
19697 if (dt.IsNoneOr(Untyped64) && cond.IsNotNever()) {
19698 *info = &kA32DataInfo;
19699 return true;
19700 }
19701 }
19702 return false;
19703 }
19704
vldr(Condition cond,DataType dt,DRegister rd,const MemOperand & operand)19705 void Assembler::vldr(Condition cond,
19706 DataType dt,
19707 DRegister rd,
19708 const MemOperand& operand) {
19709 VIXL_ASSERT(AllowAssembler());
19710 CheckIT(cond);
19711 if (operand.IsImmediate()) {
19712 Register rn = operand.GetBaseRegister();
19713 int32_t offset = operand.GetOffsetImmediate();
19714 if (IsUsingT32()) {
19715 // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; T1
19716 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
19717 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
19718 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19719 uint32_t offset_ = abs(offset) >> 2;
19720 EmitT32_32(0xed1f0b00U | rd.Encode(22, 12) | offset_ | (sign << 23));
19721 AdvanceIT();
19722 return;
19723 }
19724 // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
19725 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
19726 ((offset % 4) == 0) && operand.IsOffset() &&
19727 ((rn.GetCode() & 0xf) != 0xf)) {
19728 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19729 uint32_t offset_ = abs(offset) >> 2;
19730 EmitT32_32(0xed100b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
19731 offset_ | (sign << 23));
19732 AdvanceIT();
19733 return;
19734 }
19735 } else {
19736 // VLDR{<c>}{<q>}{.64} <Dd>, [PC, #<_plusminus_><imm>] ; A1
19737 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
19738 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
19739 cond.IsNotNever()) {
19740 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19741 uint32_t offset_ = abs(offset) >> 2;
19742 EmitA32(0x0d1f0b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19743 offset_ | (sign << 23));
19744 return;
19745 }
19746 // VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
19747 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
19748 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
19749 ((rn.GetCode() & 0xf) != 0xf)) {
19750 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19751 uint32_t offset_ = abs(offset) >> 2;
19752 EmitA32(0x0d100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19753 (rn.GetCode() << 16) | offset_ | (sign << 23));
19754 return;
19755 }
19756 }
19757 }
19758 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
19759 }
19760
vldr(Condition cond,DataType dt,SRegister rd,Location * location)19761 void Assembler::vldr(Condition cond,
19762 DataType dt,
19763 SRegister rd,
19764 Location* location) {
19765 VIXL_ASSERT(AllowAssembler());
19766 CheckIT(cond);
19767 Location::Offset offset =
19768 location->IsBound()
19769 ? location->GetLocation() -
19770 AlignDown(GetCursorOffset() + GetArchitectureStatePCOffset(), 4)
19771 : 0;
19772 if (IsUsingT32()) {
19773 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
19774 if (dt.IsNoneOr(Untyped32) &&
19775 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
19776 ((offset & 0x3) == 0)) ||
19777 !location->IsBound())) {
19778 static class EmitOp : public Location::EmitOperator {
19779 public:
19780 EmitOp() : Location::EmitOperator(T32) {}
19781 virtual uint32_t Encode(uint32_t instr,
19782 Location::Offset program_counter,
19783 const Location* loc) const VIXL_OVERRIDE {
19784 program_counter += kT32PcDelta;
19785 Location::Offset off =
19786 loc->GetLocation() - AlignDown(program_counter, 4);
19787 VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0));
19788 int32_t target = off >> 2;
19789 uint32_t U = (target >= 0);
19790 target = abs(target) | (U << 8);
19791 return instr | (target & 0xff) | ((target & 0x100) << 15);
19792 }
19793 } immop;
19794 EmitT32_32(Link(0xed1f0a00U | rd.Encode(22, 12),
19795 location,
19796 immop,
19797 &kT32DataInfo));
19798 AdvanceIT();
19799 return;
19800 }
19801 } else {
19802 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
19803 if (dt.IsNoneOr(Untyped32) &&
19804 ((location->IsBound() && (offset >= -1020) && (offset <= 1020) &&
19805 ((offset & 0x3) == 0)) ||
19806 !location->IsBound()) &&
19807 cond.IsNotNever()) {
19808 static class EmitOp : public Location::EmitOperator {
19809 public:
19810 EmitOp() : Location::EmitOperator(A32) {}
19811 virtual uint32_t Encode(uint32_t instr,
19812 Location::Offset program_counter,
19813 const Location* loc) const VIXL_OVERRIDE {
19814 program_counter += kA32PcDelta;
19815 Location::Offset off =
19816 loc->GetLocation() - AlignDown(program_counter, 4);
19817 VIXL_ASSERT((off >= -1020) && (off <= 1020) && ((off & 0x3) == 0));
19818 int32_t target = off >> 2;
19819 uint32_t U = (target >= 0);
19820 target = abs(target) | (U << 8);
19821 return instr | (target & 0xff) | ((target & 0x100) << 15);
19822 }
19823 } immop;
19824 EmitA32(
19825 Link(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12),
19826 location,
19827 immop,
19828 &kA32DataInfo));
19829 return;
19830 }
19831 }
19832 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, location);
19833 }
19834
vldr_info(Condition cond,DataType dt,SRegister rd,Location * location,const struct ReferenceInfo ** info)19835 bool Assembler::vldr_info(Condition cond,
19836 DataType dt,
19837 SRegister rd,
19838 Location* location,
19839 const struct ReferenceInfo** info) {
19840 VIXL_ASSERT(!location->IsBound());
19841 USE(location);
19842 USE(rd);
19843 if (IsUsingT32()) {
19844 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
19845 if (dt.IsNoneOr(Untyped32)) {
19846 *info = &kT32DataInfo;
19847 return true;
19848 }
19849 } else {
19850 // VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
19851 if (dt.IsNoneOr(Untyped32) && cond.IsNotNever()) {
19852 *info = &kA32DataInfo;
19853 return true;
19854 }
19855 }
19856 return false;
19857 }
19858
vldr(Condition cond,DataType dt,SRegister rd,const MemOperand & operand)19859 void Assembler::vldr(Condition cond,
19860 DataType dt,
19861 SRegister rd,
19862 const MemOperand& operand) {
19863 VIXL_ASSERT(AllowAssembler());
19864 CheckIT(cond);
19865 if (operand.IsImmediate()) {
19866 Register rn = operand.GetBaseRegister();
19867 int32_t offset = operand.GetOffsetImmediate();
19868 if (IsUsingT32()) {
19869 // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; T2
19870 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
19871 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset()) {
19872 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19873 uint32_t offset_ = abs(offset) >> 2;
19874 EmitT32_32(0xed1f0a00U | rd.Encode(22, 12) | offset_ | (sign << 23));
19875 AdvanceIT();
19876 return;
19877 }
19878 // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
19879 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
19880 ((offset % 4) == 0) && operand.IsOffset() &&
19881 ((rn.GetCode() & 0xf) != 0xf)) {
19882 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19883 uint32_t offset_ = abs(offset) >> 2;
19884 EmitT32_32(0xed100a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
19885 offset_ | (sign << 23));
19886 AdvanceIT();
19887 return;
19888 }
19889 } else {
19890 // VLDR{<c>}{<q>}{.32} <Sd>, [PC, #<_plusminus_><imm>] ; A2
19891 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
19892 ((offset % 4) == 0) && rn.Is(pc) && operand.IsOffset() &&
19893 cond.IsNotNever()) {
19894 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19895 uint32_t offset_ = abs(offset) >> 2;
19896 EmitA32(0x0d1f0a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19897 offset_ | (sign << 23));
19898 return;
19899 }
19900 // VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
19901 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
19902 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever() &&
19903 ((rn.GetCode() & 0xf) != 0xf)) {
19904 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
19905 uint32_t offset_ = abs(offset) >> 2;
19906 EmitA32(0x0d100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
19907 (rn.GetCode() << 16) | offset_ | (sign << 23));
19908 return;
19909 }
19910 }
19911 }
19912 Delegate(kVldr, &Assembler::vldr, cond, dt, rd, operand);
19913 }
19914
vmax(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)19915 void Assembler::vmax(
19916 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
19917 VIXL_ASSERT(AllowAssembler());
19918 CheckIT(cond);
19919 Dt_U_size_1 encoded_dt(dt);
19920 if (IsUsingT32()) {
19921 // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
19922 if (dt.Is(F32)) {
19923 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19924 EmitT32_32(0xef000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19925 rm.Encode(5, 0));
19926 AdvanceIT();
19927 return;
19928 }
19929 }
19930 // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
19931 if (encoded_dt.IsValid()) {
19932 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19933 EmitT32_32(0xef000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19934 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
19935 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19936 AdvanceIT();
19937 return;
19938 }
19939 }
19940 } else {
19941 // VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
19942 if (dt.Is(F32)) {
19943 if (cond.Is(al)) {
19944 EmitA32(0xf2000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19945 rm.Encode(5, 0));
19946 return;
19947 }
19948 }
19949 // VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
19950 if (encoded_dt.IsValid()) {
19951 if (cond.Is(al)) {
19952 EmitA32(0xf2000600U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19953 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
19954 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19955 return;
19956 }
19957 }
19958 }
19959 Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
19960 }
19961
vmax(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)19962 void Assembler::vmax(
19963 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
19964 VIXL_ASSERT(AllowAssembler());
19965 CheckIT(cond);
19966 Dt_U_size_1 encoded_dt(dt);
19967 if (IsUsingT32()) {
19968 // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
19969 if (dt.Is(F32)) {
19970 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19971 EmitT32_32(0xef000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19972 rm.Encode(5, 0));
19973 AdvanceIT();
19974 return;
19975 }
19976 }
19977 // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
19978 if (encoded_dt.IsValid()) {
19979 if (cond.Is(al) || AllowStronglyDiscouraged()) {
19980 EmitT32_32(0xef000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
19981 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
19982 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
19983 AdvanceIT();
19984 return;
19985 }
19986 }
19987 } else {
19988 // VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
19989 if (dt.Is(F32)) {
19990 if (cond.Is(al)) {
19991 EmitA32(0xf2000f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
19992 rm.Encode(5, 0));
19993 return;
19994 }
19995 }
19996 // VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
19997 if (encoded_dt.IsValid()) {
19998 if (cond.Is(al)) {
19999 EmitA32(0xf2000640U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20000 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20001 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20002 return;
20003 }
20004 }
20005 }
20006 Delegate(kVmax, &Assembler::vmax, cond, dt, rd, rn, rm);
20007 }
20008
vmaxnm(DataType dt,DRegister rd,DRegister rn,DRegister rm)20009 void Assembler::vmaxnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20010 VIXL_ASSERT(AllowAssembler());
20011 CheckIT(al);
20012 if (IsUsingT32()) {
20013 // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
20014 if (OutsideITBlock() && dt.Is(F32)) {
20015 EmitT32_32(0xff000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20016 rm.Encode(5, 0));
20017 AdvanceIT();
20018 return;
20019 }
20020 // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
20021 if (OutsideITBlock() && dt.Is(F64)) {
20022 EmitT32_32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20023 rm.Encode(5, 0));
20024 AdvanceIT();
20025 return;
20026 }
20027 } else {
20028 // VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
20029 if (dt.Is(F32)) {
20030 EmitA32(0xf3000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20031 rm.Encode(5, 0));
20032 return;
20033 }
20034 // VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
20035 if (dt.Is(F64)) {
20036 EmitA32(0xfe800b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20037 rm.Encode(5, 0));
20038 return;
20039 }
20040 }
20041 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
20042 }
20043
vmaxnm(DataType dt,QRegister rd,QRegister rn,QRegister rm)20044 void Assembler::vmaxnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20045 VIXL_ASSERT(AllowAssembler());
20046 CheckIT(al);
20047 if (IsUsingT32()) {
20048 // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
20049 if (OutsideITBlock() && dt.Is(F32)) {
20050 EmitT32_32(0xff000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20051 rm.Encode(5, 0));
20052 AdvanceIT();
20053 return;
20054 }
20055 } else {
20056 // VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
20057 if (dt.Is(F32)) {
20058 EmitA32(0xf3000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20059 rm.Encode(5, 0));
20060 return;
20061 }
20062 }
20063 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
20064 }
20065
vmaxnm(DataType dt,SRegister rd,SRegister rn,SRegister rm)20066 void Assembler::vmaxnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20067 VIXL_ASSERT(AllowAssembler());
20068 CheckIT(al);
20069 if (IsUsingT32()) {
20070 // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
20071 if (OutsideITBlock() && dt.Is(F32)) {
20072 EmitT32_32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20073 rm.Encode(5, 0));
20074 AdvanceIT();
20075 return;
20076 }
20077 } else {
20078 // VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
20079 if (dt.Is(F32)) {
20080 EmitA32(0xfe800a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20081 rm.Encode(5, 0));
20082 return;
20083 }
20084 }
20085 Delegate(kVmaxnm, &Assembler::vmaxnm, dt, rd, rn, rm);
20086 }
20087
vmin(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)20088 void Assembler::vmin(
20089 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20090 VIXL_ASSERT(AllowAssembler());
20091 CheckIT(cond);
20092 Dt_U_size_1 encoded_dt(dt);
20093 if (IsUsingT32()) {
20094 // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
20095 if (dt.Is(F32)) {
20096 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20097 EmitT32_32(0xef200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20098 rm.Encode(5, 0));
20099 AdvanceIT();
20100 return;
20101 }
20102 }
20103 // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
20104 if (encoded_dt.IsValid()) {
20105 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20106 EmitT32_32(0xef000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20107 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20108 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20109 AdvanceIT();
20110 return;
20111 }
20112 }
20113 } else {
20114 // VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
20115 if (dt.Is(F32)) {
20116 if (cond.Is(al)) {
20117 EmitA32(0xf2200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20118 rm.Encode(5, 0));
20119 return;
20120 }
20121 }
20122 // VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
20123 if (encoded_dt.IsValid()) {
20124 if (cond.Is(al)) {
20125 EmitA32(0xf2000610U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20126 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20127 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20128 return;
20129 }
20130 }
20131 }
20132 Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
20133 }
20134
vmin(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)20135 void Assembler::vmin(
20136 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20137 VIXL_ASSERT(AllowAssembler());
20138 CheckIT(cond);
20139 Dt_U_size_1 encoded_dt(dt);
20140 if (IsUsingT32()) {
20141 // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
20142 if (dt.Is(F32)) {
20143 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20144 EmitT32_32(0xef200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20145 rm.Encode(5, 0));
20146 AdvanceIT();
20147 return;
20148 }
20149 }
20150 // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
20151 if (encoded_dt.IsValid()) {
20152 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20153 EmitT32_32(0xef000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20154 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
20155 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20156 AdvanceIT();
20157 return;
20158 }
20159 }
20160 } else {
20161 // VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
20162 if (dt.Is(F32)) {
20163 if (cond.Is(al)) {
20164 EmitA32(0xf2200f40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20165 rm.Encode(5, 0));
20166 return;
20167 }
20168 }
20169 // VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
20170 if (encoded_dt.IsValid()) {
20171 if (cond.Is(al)) {
20172 EmitA32(0xf2000650U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
20173 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
20174 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20175 return;
20176 }
20177 }
20178 }
20179 Delegate(kVmin, &Assembler::vmin, cond, dt, rd, rn, rm);
20180 }
20181
vminnm(DataType dt,DRegister rd,DRegister rn,DRegister rm)20182 void Assembler::vminnm(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20183 VIXL_ASSERT(AllowAssembler());
20184 CheckIT(al);
20185 if (IsUsingT32()) {
20186 // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
20187 if (OutsideITBlock() && dt.Is(F32)) {
20188 EmitT32_32(0xff200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20189 rm.Encode(5, 0));
20190 AdvanceIT();
20191 return;
20192 }
20193 // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
20194 if (OutsideITBlock() && dt.Is(F64)) {
20195 EmitT32_32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20196 rm.Encode(5, 0));
20197 AdvanceIT();
20198 return;
20199 }
20200 } else {
20201 // VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
20202 if (dt.Is(F32)) {
20203 EmitA32(0xf3200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20204 rm.Encode(5, 0));
20205 return;
20206 }
20207 // VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
20208 if (dt.Is(F64)) {
20209 EmitA32(0xfe800b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20210 rm.Encode(5, 0));
20211 return;
20212 }
20213 }
20214 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
20215 }
20216
vminnm(DataType dt,QRegister rd,QRegister rn,QRegister rm)20217 void Assembler::vminnm(DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20218 VIXL_ASSERT(AllowAssembler());
20219 CheckIT(al);
20220 if (IsUsingT32()) {
20221 // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
20222 if (OutsideITBlock() && dt.Is(F32)) {
20223 EmitT32_32(0xff200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20224 rm.Encode(5, 0));
20225 AdvanceIT();
20226 return;
20227 }
20228 } else {
20229 // VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
20230 if (dt.Is(F32)) {
20231 EmitA32(0xf3200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20232 rm.Encode(5, 0));
20233 return;
20234 }
20235 }
20236 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
20237 }
20238
vminnm(DataType dt,SRegister rd,SRegister rn,SRegister rm)20239 void Assembler::vminnm(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20240 VIXL_ASSERT(AllowAssembler());
20241 CheckIT(al);
20242 if (IsUsingT32()) {
20243 // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
20244 if (OutsideITBlock() && dt.Is(F32)) {
20245 EmitT32_32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20246 rm.Encode(5, 0));
20247 AdvanceIT();
20248 return;
20249 }
20250 } else {
20251 // VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
20252 if (dt.Is(F32)) {
20253 EmitA32(0xfe800a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20254 rm.Encode(5, 0));
20255 return;
20256 }
20257 }
20258 Delegate(kVminnm, &Assembler::vminnm, dt, rd, rn, rm);
20259 }
20260
vmla(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)20261 void Assembler::vmla(
20262 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
20263 VIXL_ASSERT(AllowAssembler());
20264 CheckIT(cond);
20265 Dt_size_9 encoded_dt(dt);
20266 if (IsUsingT32()) {
20267 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
20268 if (encoded_dt.IsValid() &&
20269 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20270 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20271 (rm.GetLane() <= 1)))) {
20272 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20273 EmitT32_32(0xef800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
20274 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20275 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20276 AdvanceIT();
20277 return;
20278 }
20279 }
20280 } else {
20281 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
20282 if (encoded_dt.IsValid() &&
20283 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20284 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20285 (rm.GetLane() <= 1)))) {
20286 if (cond.Is(al)) {
20287 EmitA32(0xf2800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
20288 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20289 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20290 return;
20291 }
20292 }
20293 }
20294 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
20295 }
20296
vmla(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)20297 void Assembler::vmla(
20298 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
20299 VIXL_ASSERT(AllowAssembler());
20300 CheckIT(cond);
20301 Dt_size_9 encoded_dt(dt);
20302 if (IsUsingT32()) {
20303 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
20304 if (encoded_dt.IsValid() &&
20305 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20306 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20307 (rm.GetLane() <= 1)))) {
20308 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20309 EmitT32_32(0xff800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
20310 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20311 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20312 AdvanceIT();
20313 return;
20314 }
20315 }
20316 } else {
20317 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
20318 if (encoded_dt.IsValid() &&
20319 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20320 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20321 (rm.GetLane() <= 1)))) {
20322 if (cond.Is(al)) {
20323 EmitA32(0xf3800040U | (encoded_dt.GetTypeEncodingValue() << 8) |
20324 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20325 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20326 return;
20327 }
20328 }
20329 }
20330 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
20331 }
20332
vmla(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)20333 void Assembler::vmla(
20334 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20335 VIXL_ASSERT(AllowAssembler());
20336 CheckIT(cond);
20337 Dt_size_10 encoded_dt(dt);
20338 if (IsUsingT32()) {
20339 // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
20340 if (dt.Is(F32)) {
20341 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20342 EmitT32_32(0xef000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20343 rm.Encode(5, 0));
20344 AdvanceIT();
20345 return;
20346 }
20347 }
20348 // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
20349 if (dt.Is(F64)) {
20350 EmitT32_32(0xee000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20351 rm.Encode(5, 0));
20352 AdvanceIT();
20353 return;
20354 }
20355 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
20356 if (encoded_dt.IsValid()) {
20357 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20358 EmitT32_32(0xef000900U | (encoded_dt.GetEncodingValue() << 20) |
20359 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20360 AdvanceIT();
20361 return;
20362 }
20363 }
20364 } else {
20365 // VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
20366 if (dt.Is(F32)) {
20367 if (cond.Is(al)) {
20368 EmitA32(0xf2000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20369 rm.Encode(5, 0));
20370 return;
20371 }
20372 }
20373 // VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
20374 if (dt.Is(F64) && cond.IsNotNever()) {
20375 EmitA32(0x0e000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20376 rn.Encode(7, 16) | rm.Encode(5, 0));
20377 return;
20378 }
20379 // VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
20380 if (encoded_dt.IsValid()) {
20381 if (cond.Is(al)) {
20382 EmitA32(0xf2000900U | (encoded_dt.GetEncodingValue() << 20) |
20383 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20384 return;
20385 }
20386 }
20387 }
20388 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
20389 }
20390
vmla(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)20391 void Assembler::vmla(
20392 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20393 VIXL_ASSERT(AllowAssembler());
20394 CheckIT(cond);
20395 Dt_size_10 encoded_dt(dt);
20396 if (IsUsingT32()) {
20397 // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
20398 if (dt.Is(F32)) {
20399 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20400 EmitT32_32(0xef000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20401 rm.Encode(5, 0));
20402 AdvanceIT();
20403 return;
20404 }
20405 }
20406 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
20407 if (encoded_dt.IsValid()) {
20408 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20409 EmitT32_32(0xef000940U | (encoded_dt.GetEncodingValue() << 20) |
20410 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20411 AdvanceIT();
20412 return;
20413 }
20414 }
20415 } else {
20416 // VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
20417 if (dt.Is(F32)) {
20418 if (cond.Is(al)) {
20419 EmitA32(0xf2000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20420 rm.Encode(5, 0));
20421 return;
20422 }
20423 }
20424 // VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
20425 if (encoded_dt.IsValid()) {
20426 if (cond.Is(al)) {
20427 EmitA32(0xf2000940U | (encoded_dt.GetEncodingValue() << 20) |
20428 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20429 return;
20430 }
20431 }
20432 }
20433 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
20434 }
20435
vmla(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)20436 void Assembler::vmla(
20437 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20438 VIXL_ASSERT(AllowAssembler());
20439 CheckIT(cond);
20440 if (IsUsingT32()) {
20441 // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
20442 if (dt.Is(F32)) {
20443 EmitT32_32(0xee000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20444 rm.Encode(5, 0));
20445 AdvanceIT();
20446 return;
20447 }
20448 } else {
20449 // VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
20450 if (dt.Is(F32) && cond.IsNotNever()) {
20451 EmitA32(0x0e000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20452 rn.Encode(7, 16) | rm.Encode(5, 0));
20453 return;
20454 }
20455 }
20456 Delegate(kVmla, &Assembler::vmla, cond, dt, rd, rn, rm);
20457 }
20458
vmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegisterLane rm)20459 void Assembler::vmlal(
20460 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
20461 VIXL_ASSERT(AllowAssembler());
20462 CheckIT(cond);
20463 Dt_size_11 encoded_dt(dt);
20464 if (IsUsingT32()) {
20465 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
20466 if (encoded_dt.IsValid() &&
20467 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20468 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20469 (rm.GetLane() <= 1)))) {
20470 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20471 EmitT32_32(0xef800240U | (encoded_dt.GetTypeEncodingValue() << 28) |
20472 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20473 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20474 AdvanceIT();
20475 return;
20476 }
20477 }
20478 } else {
20479 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
20480 if (encoded_dt.IsValid() &&
20481 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20482 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20483 (rm.GetLane() <= 1)))) {
20484 if (cond.Is(al)) {
20485 EmitA32(0xf2800240U | (encoded_dt.GetTypeEncodingValue() << 24) |
20486 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20487 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20488 return;
20489 }
20490 }
20491 }
20492 Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
20493 }
20494
vmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)20495 void Assembler::vmlal(
20496 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
20497 VIXL_ASSERT(AllowAssembler());
20498 CheckIT(cond);
20499 Dt_size_12 encoded_dt(dt);
20500 if (IsUsingT32()) {
20501 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
20502 if (encoded_dt.IsValid()) {
20503 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20504 EmitT32_32(0xef800800U | (encoded_dt.GetTypeEncodingValue() << 28) |
20505 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20506 rn.Encode(7, 16) | rm.Encode(5, 0));
20507 AdvanceIT();
20508 return;
20509 }
20510 }
20511 } else {
20512 // VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
20513 if (encoded_dt.IsValid()) {
20514 if (cond.Is(al)) {
20515 EmitA32(0xf2800800U | (encoded_dt.GetTypeEncodingValue() << 24) |
20516 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20517 rn.Encode(7, 16) | rm.Encode(5, 0));
20518 return;
20519 }
20520 }
20521 }
20522 Delegate(kVmlal, &Assembler::vmlal, cond, dt, rd, rn, rm);
20523 }
20524
vmls(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)20525 void Assembler::vmls(
20526 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
20527 VIXL_ASSERT(AllowAssembler());
20528 CheckIT(cond);
20529 Dt_size_9 encoded_dt(dt);
20530 if (IsUsingT32()) {
20531 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1
20532 if (encoded_dt.IsValid() &&
20533 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20534 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20535 (rm.GetLane() <= 1)))) {
20536 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20537 EmitT32_32(0xef800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
20538 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20539 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20540 AdvanceIT();
20541 return;
20542 }
20543 }
20544 } else {
20545 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1
20546 if (encoded_dt.IsValid() &&
20547 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20548 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20549 (rm.GetLane() <= 1)))) {
20550 if (cond.Is(al)) {
20551 EmitA32(0xf2800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
20552 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20553 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20554 return;
20555 }
20556 }
20557 }
20558 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
20559 }
20560
vmls(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)20561 void Assembler::vmls(
20562 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
20563 VIXL_ASSERT(AllowAssembler());
20564 CheckIT(cond);
20565 Dt_size_9 encoded_dt(dt);
20566 if (IsUsingT32()) {
20567 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1
20568 if (encoded_dt.IsValid() &&
20569 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20570 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20571 (rm.GetLane() <= 1)))) {
20572 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20573 EmitT32_32(0xff800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
20574 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20575 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20576 AdvanceIT();
20577 return;
20578 }
20579 }
20580 } else {
20581 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1
20582 if (encoded_dt.IsValid() &&
20583 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20584 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20585 (rm.GetLane() <= 1)))) {
20586 if (cond.Is(al)) {
20587 EmitA32(0xf3800440U | (encoded_dt.GetTypeEncodingValue() << 8) |
20588 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20589 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20590 return;
20591 }
20592 }
20593 }
20594 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
20595 }
20596
vmls(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)20597 void Assembler::vmls(
20598 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
20599 VIXL_ASSERT(AllowAssembler());
20600 CheckIT(cond);
20601 Dt_size_10 encoded_dt(dt);
20602 if (IsUsingT32()) {
20603 // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
20604 if (dt.Is(F32)) {
20605 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20606 EmitT32_32(0xef200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20607 rm.Encode(5, 0));
20608 AdvanceIT();
20609 return;
20610 }
20611 }
20612 // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
20613 if (dt.Is(F64)) {
20614 EmitT32_32(0xee000b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20615 rm.Encode(5, 0));
20616 AdvanceIT();
20617 return;
20618 }
20619 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1
20620 if (encoded_dt.IsValid()) {
20621 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20622 EmitT32_32(0xff000900U | (encoded_dt.GetEncodingValue() << 20) |
20623 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20624 AdvanceIT();
20625 return;
20626 }
20627 }
20628 } else {
20629 // VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
20630 if (dt.Is(F32)) {
20631 if (cond.Is(al)) {
20632 EmitA32(0xf2200d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20633 rm.Encode(5, 0));
20634 return;
20635 }
20636 }
20637 // VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
20638 if (dt.Is(F64) && cond.IsNotNever()) {
20639 EmitA32(0x0e000b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20640 rn.Encode(7, 16) | rm.Encode(5, 0));
20641 return;
20642 }
20643 // VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
20644 if (encoded_dt.IsValid()) {
20645 if (cond.Is(al)) {
20646 EmitA32(0xf3000900U | (encoded_dt.GetEncodingValue() << 20) |
20647 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20648 return;
20649 }
20650 }
20651 }
20652 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
20653 }
20654
vmls(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)20655 void Assembler::vmls(
20656 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
20657 VIXL_ASSERT(AllowAssembler());
20658 CheckIT(cond);
20659 Dt_size_10 encoded_dt(dt);
20660 if (IsUsingT32()) {
20661 // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
20662 if (dt.Is(F32)) {
20663 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20664 EmitT32_32(0xef200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20665 rm.Encode(5, 0));
20666 AdvanceIT();
20667 return;
20668 }
20669 }
20670 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1
20671 if (encoded_dt.IsValid()) {
20672 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20673 EmitT32_32(0xff000940U | (encoded_dt.GetEncodingValue() << 20) |
20674 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20675 AdvanceIT();
20676 return;
20677 }
20678 }
20679 } else {
20680 // VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
20681 if (dt.Is(F32)) {
20682 if (cond.Is(al)) {
20683 EmitA32(0xf2200d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20684 rm.Encode(5, 0));
20685 return;
20686 }
20687 }
20688 // VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
20689 if (encoded_dt.IsValid()) {
20690 if (cond.Is(al)) {
20691 EmitA32(0xf3000940U | (encoded_dt.GetEncodingValue() << 20) |
20692 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
20693 return;
20694 }
20695 }
20696 }
20697 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
20698 }
20699
vmls(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)20700 void Assembler::vmls(
20701 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
20702 VIXL_ASSERT(AllowAssembler());
20703 CheckIT(cond);
20704 if (IsUsingT32()) {
20705 // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
20706 if (dt.Is(F32)) {
20707 EmitT32_32(0xee000a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
20708 rm.Encode(5, 0));
20709 AdvanceIT();
20710 return;
20711 }
20712 } else {
20713 // VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
20714 if (dt.Is(F32) && cond.IsNotNever()) {
20715 EmitA32(0x0e000a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
20716 rn.Encode(7, 16) | rm.Encode(5, 0));
20717 return;
20718 }
20719 }
20720 Delegate(kVmls, &Assembler::vmls, cond, dt, rd, rn, rm);
20721 }
20722
vmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegisterLane rm)20723 void Assembler::vmlsl(
20724 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
20725 VIXL_ASSERT(AllowAssembler());
20726 CheckIT(cond);
20727 Dt_size_11 encoded_dt(dt);
20728 if (IsUsingT32()) {
20729 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1
20730 if (encoded_dt.IsValid() &&
20731 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20732 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20733 (rm.GetLane() <= 1)))) {
20734 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20735 EmitT32_32(0xef800640U | (encoded_dt.GetTypeEncodingValue() << 28) |
20736 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20737 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20738 AdvanceIT();
20739 return;
20740 }
20741 }
20742 } else {
20743 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1
20744 if (encoded_dt.IsValid() &&
20745 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
20746 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
20747 (rm.GetLane() <= 1)))) {
20748 if (cond.Is(al)) {
20749 EmitA32(0xf2800640U | (encoded_dt.GetTypeEncodingValue() << 24) |
20750 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20751 rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
20752 return;
20753 }
20754 }
20755 }
20756 Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
20757 }
20758
vmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)20759 void Assembler::vmlsl(
20760 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
20761 VIXL_ASSERT(AllowAssembler());
20762 CheckIT(cond);
20763 Dt_size_12 encoded_dt(dt);
20764 if (IsUsingT32()) {
20765 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1
20766 if (encoded_dt.IsValid()) {
20767 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20768 EmitT32_32(0xef800a00U | (encoded_dt.GetTypeEncodingValue() << 28) |
20769 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20770 rn.Encode(7, 16) | rm.Encode(5, 0));
20771 AdvanceIT();
20772 return;
20773 }
20774 }
20775 } else {
20776 // VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
20777 if (encoded_dt.IsValid()) {
20778 if (cond.Is(al)) {
20779 EmitA32(0xf2800a00U | (encoded_dt.GetTypeEncodingValue() << 24) |
20780 (encoded_dt.GetEncodingValue() << 20) | rd.Encode(22, 12) |
20781 rn.Encode(7, 16) | rm.Encode(5, 0));
20782 return;
20783 }
20784 }
20785 }
20786 Delegate(kVmlsl, &Assembler::vmlsl, cond, dt, rd, rn, rm);
20787 }
20788
vmov(Condition cond,Register rt,SRegister rn)20789 void Assembler::vmov(Condition cond, Register rt, SRegister rn) {
20790 VIXL_ASSERT(AllowAssembler());
20791 CheckIT(cond);
20792 if (IsUsingT32()) {
20793 // VMOV{<c>}{<q>} <Rt>, <Sn> ; T1
20794 if ((!rt.IsPC() || AllowUnpredictable())) {
20795 EmitT32_32(0xee100a10U | (rt.GetCode() << 12) | rn.Encode(7, 16));
20796 AdvanceIT();
20797 return;
20798 }
20799 } else {
20800 // VMOV{<c>}{<q>} <Rt>, <Sn> ; A1
20801 if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
20802 EmitA32(0x0e100a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
20803 rn.Encode(7, 16));
20804 return;
20805 }
20806 }
20807 Delegate(kVmov, &Assembler::vmov, cond, rt, rn);
20808 }
20809
vmov(Condition cond,SRegister rn,Register rt)20810 void Assembler::vmov(Condition cond, SRegister rn, Register rt) {
20811 VIXL_ASSERT(AllowAssembler());
20812 CheckIT(cond);
20813 if (IsUsingT32()) {
20814 // VMOV{<c>}{<q>} <Sn>, <Rt> ; T1
20815 if ((!rt.IsPC() || AllowUnpredictable())) {
20816 EmitT32_32(0xee000a10U | rn.Encode(7, 16) | (rt.GetCode() << 12));
20817 AdvanceIT();
20818 return;
20819 }
20820 } else {
20821 // VMOV{<c>}{<q>} <Sn>, <Rt> ; A1
20822 if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
20823 EmitA32(0x0e000a10U | (cond.GetCondition() << 28) | rn.Encode(7, 16) |
20824 (rt.GetCode() << 12));
20825 return;
20826 }
20827 }
20828 Delegate(kVmov, &Assembler::vmov, cond, rn, rt);
20829 }
20830
vmov(Condition cond,Register rt,Register rt2,DRegister rm)20831 void Assembler::vmov(Condition cond, Register rt, Register rt2, DRegister rm) {
20832 VIXL_ASSERT(AllowAssembler());
20833 CheckIT(cond);
20834 if (IsUsingT32()) {
20835 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1
20836 if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20837 EmitT32_32(0xec500b10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
20838 rm.Encode(5, 0));
20839 AdvanceIT();
20840 return;
20841 }
20842 } else {
20843 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1
20844 if (cond.IsNotNever() &&
20845 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20846 EmitA32(0x0c500b10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
20847 (rt2.GetCode() << 16) | rm.Encode(5, 0));
20848 return;
20849 }
20850 }
20851 Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm);
20852 }
20853
vmov(Condition cond,DRegister rm,Register rt,Register rt2)20854 void Assembler::vmov(Condition cond, DRegister rm, Register rt, Register rt2) {
20855 VIXL_ASSERT(AllowAssembler());
20856 CheckIT(cond);
20857 if (IsUsingT32()) {
20858 // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1
20859 if (((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20860 EmitT32_32(0xec400b10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
20861 (rt2.GetCode() << 16));
20862 AdvanceIT();
20863 return;
20864 }
20865 } else {
20866 // VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1
20867 if (cond.IsNotNever() &&
20868 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20869 EmitA32(0x0c400b10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
20870 (rt.GetCode() << 12) | (rt2.GetCode() << 16));
20871 return;
20872 }
20873 }
20874 Delegate(kVmov, &Assembler::vmov, cond, rm, rt, rt2);
20875 }
20876
vmov(Condition cond,Register rt,Register rt2,SRegister rm,SRegister rm1)20877 void Assembler::vmov(
20878 Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) {
20879 VIXL_ASSERT(AllowAssembler());
20880 CheckIT(cond);
20881 if (IsUsingT32()) {
20882 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1
20883 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
20884 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20885 EmitT32_32(0xec500a10U | (rt.GetCode() << 12) | (rt2.GetCode() << 16) |
20886 rm.Encode(5, 0));
20887 AdvanceIT();
20888 return;
20889 }
20890 } else {
20891 // VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1
20892 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
20893 cond.IsNotNever() &&
20894 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20895 EmitA32(0x0c500a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
20896 (rt2.GetCode() << 16) | rm.Encode(5, 0));
20897 return;
20898 }
20899 }
20900 Delegate(kVmov, &Assembler::vmov, cond, rt, rt2, rm, rm1);
20901 }
20902
vmov(Condition cond,SRegister rm,SRegister rm1,Register rt,Register rt2)20903 void Assembler::vmov(
20904 Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) {
20905 VIXL_ASSERT(AllowAssembler());
20906 CheckIT(cond);
20907 if (IsUsingT32()) {
20908 // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1
20909 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
20910 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20911 EmitT32_32(0xec400a10U | rm.Encode(5, 0) | (rt.GetCode() << 12) |
20912 (rt2.GetCode() << 16));
20913 AdvanceIT();
20914 return;
20915 }
20916 } else {
20917 // VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1
20918 if ((((rm.GetCode() + 1) % kNumberOfSRegisters) == rm1.GetCode()) &&
20919 cond.IsNotNever() &&
20920 ((!rt.IsPC() && !rt2.IsPC()) || AllowUnpredictable())) {
20921 EmitA32(0x0c400a10U | (cond.GetCondition() << 28) | rm.Encode(5, 0) |
20922 (rt.GetCode() << 12) | (rt2.GetCode() << 16));
20923 return;
20924 }
20925 }
20926 Delegate(kVmov, &Assembler::vmov, cond, rm, rm1, rt, rt2);
20927 }
20928
vmov(Condition cond,DataType dt,DRegisterLane rd,Register rt)20929 void Assembler::vmov(Condition cond,
20930 DataType dt,
20931 DRegisterLane rd,
20932 Register rt) {
20933 VIXL_ASSERT(AllowAssembler());
20934 CheckIT(cond);
20935 Dt_opc1_opc2_1 encoded_dt(dt, rd);
20936 if (IsUsingT32()) {
20937 // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1
20938 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
20939 EmitT32_32(0xee000b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
20940 ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
20941 rd.Encode(7, 16) | (rt.GetCode() << 12));
20942 AdvanceIT();
20943 return;
20944 }
20945 } else {
20946 // VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1
20947 if (encoded_dt.IsValid() && cond.IsNotNever() &&
20948 (!rt.IsPC() || AllowUnpredictable())) {
20949 EmitA32(0x0e000b10U | (cond.GetCondition() << 28) |
20950 ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
20951 ((encoded_dt.GetEncodingValue() & 0xc) << 19) | rd.Encode(7, 16) |
20952 (rt.GetCode() << 12));
20953 return;
20954 }
20955 }
20956 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, rt);
20957 }
20958
vmov(Condition cond,DataType dt,DRegister rd,const DOperand & operand)20959 void Assembler::vmov(Condition cond,
20960 DataType dt,
20961 DRegister rd,
20962 const DOperand& operand) {
20963 VIXL_ASSERT(AllowAssembler());
20964 CheckIT(cond);
20965 if (operand.IsImmediate()) {
20966 ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
20967 if (IsUsingT32()) {
20968 // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
20969 if (encoded_dt.IsValid()) {
20970 if (cond.Is(al) || AllowStronglyDiscouraged()) {
20971 EmitT32_32(
20972 0xef800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
20973 ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
20974 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20975 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20976 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
20977 AdvanceIT();
20978 return;
20979 }
20980 }
20981 } else {
20982 // VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
20983 if (encoded_dt.IsValid()) {
20984 if (cond.Is(al)) {
20985 EmitA32(0xf2800010U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
20986 ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
20987 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
20988 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
20989 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
20990 return;
20991 }
20992 }
20993 }
20994 }
20995 if (operand.IsImmediate()) {
20996 ImmediateVFP vfp(operand.GetNeonImmediate());
20997 if (IsUsingT32()) {
20998 // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2
20999 if (dt.Is(F64) && vfp.IsValid()) {
21000 EmitT32_32(0xeeb00b00U | rd.Encode(22, 12) |
21001 (vfp.GetEncodingValue() & 0xf) |
21002 ((vfp.GetEncodingValue() & 0xf0) << 12));
21003 AdvanceIT();
21004 return;
21005 }
21006 } else {
21007 // VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2
21008 if (dt.Is(F64) && vfp.IsValid() && cond.IsNotNever()) {
21009 EmitA32(0x0eb00b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21010 (vfp.GetEncodingValue() & 0xf) |
21011 ((vfp.GetEncodingValue() & 0xf0) << 12));
21012 return;
21013 }
21014 }
21015 }
21016 if (operand.IsRegister()) {
21017 DRegister rm = operand.GetRegister();
21018 if (IsUsingT32()) {
21019 // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
21020 if (dt.Is(F64)) {
21021 EmitT32_32(0xeeb00b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
21022 AdvanceIT();
21023 return;
21024 }
21025 // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
21026 if (!dt.Is(F64)) {
21027 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21028 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
21029 rm.Encode(5, 0));
21030 AdvanceIT();
21031 return;
21032 }
21033 }
21034 } else {
21035 // VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
21036 if (dt.Is(F64) && cond.IsNotNever()) {
21037 EmitA32(0x0eb00b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21038 rm.Encode(5, 0));
21039 return;
21040 }
21041 // VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
21042 if (!dt.Is(F64)) {
21043 if (cond.Is(al)) {
21044 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
21045 rm.Encode(5, 0));
21046 return;
21047 }
21048 }
21049 }
21050 }
21051 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
21052 }
21053
vmov(Condition cond,DataType dt,QRegister rd,const QOperand & operand)21054 void Assembler::vmov(Condition cond,
21055 DataType dt,
21056 QRegister rd,
21057 const QOperand& operand) {
21058 VIXL_ASSERT(AllowAssembler());
21059 CheckIT(cond);
21060 if (operand.IsImmediate()) {
21061 ImmediateVmov encoded_dt(dt, operand.GetNeonImmediate());
21062 if (IsUsingT32()) {
21063 // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
21064 if (encoded_dt.IsValid()) {
21065 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21066 EmitT32_32(
21067 0xef800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
21068 ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
21069 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
21070 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21071 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
21072 AdvanceIT();
21073 return;
21074 }
21075 }
21076 } else {
21077 // VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
21078 if (encoded_dt.IsValid()) {
21079 if (cond.Is(al)) {
21080 EmitA32(0xf2800050U | ((encoded_dt.GetEncodingValue() & 0xf) << 8) |
21081 ((encoded_dt.GetEncodingValue() & 0x10) << 1) |
21082 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
21083 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21084 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
21085 return;
21086 }
21087 }
21088 }
21089 }
21090 if (operand.IsRegister()) {
21091 QRegister rm = operand.GetRegister();
21092 if (IsUsingT32()) {
21093 // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
21094 if (!dt.Is(F64)) {
21095 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21096 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
21097 rm.Encode(5, 0));
21098 AdvanceIT();
21099 return;
21100 }
21101 }
21102 } else {
21103 // VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
21104 if (!dt.Is(F64)) {
21105 if (cond.Is(al)) {
21106 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
21107 rm.Encode(5, 0));
21108 return;
21109 }
21110 }
21111 }
21112 }
21113 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
21114 }
21115
vmov(Condition cond,DataType dt,SRegister rd,const SOperand & operand)21116 void Assembler::vmov(Condition cond,
21117 DataType dt,
21118 SRegister rd,
21119 const SOperand& operand) {
21120 VIXL_ASSERT(AllowAssembler());
21121 CheckIT(cond);
21122 if (operand.IsImmediate()) {
21123 ImmediateVFP vfp(operand.GetNeonImmediate());
21124 if (IsUsingT32()) {
21125 // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2
21126 if (dt.Is(F32) && vfp.IsValid()) {
21127 EmitT32_32(0xeeb00a00U | rd.Encode(22, 12) |
21128 (vfp.GetEncodingValue() & 0xf) |
21129 ((vfp.GetEncodingValue() & 0xf0) << 12));
21130 AdvanceIT();
21131 return;
21132 }
21133 } else {
21134 // VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2
21135 if (dt.Is(F32) && vfp.IsValid() && cond.IsNotNever()) {
21136 EmitA32(0x0eb00a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21137 (vfp.GetEncodingValue() & 0xf) |
21138 ((vfp.GetEncodingValue() & 0xf0) << 12));
21139 return;
21140 }
21141 }
21142 }
21143 if (operand.IsRegister()) {
21144 SRegister rm = operand.GetRegister();
21145 if (IsUsingT32()) {
21146 // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
21147 if (dt.Is(F32)) {
21148 EmitT32_32(0xeeb00a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
21149 AdvanceIT();
21150 return;
21151 }
21152 } else {
21153 // VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
21154 if (dt.Is(F32) && cond.IsNotNever()) {
21155 EmitA32(0x0eb00a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21156 rm.Encode(5, 0));
21157 return;
21158 }
21159 }
21160 }
21161 Delegate(kVmov, &Assembler::vmov, cond, dt, rd, operand);
21162 }
21163
vmov(Condition cond,DataType dt,Register rt,DRegisterLane rn)21164 void Assembler::vmov(Condition cond,
21165 DataType dt,
21166 Register rt,
21167 DRegisterLane rn) {
21168 VIXL_ASSERT(AllowAssembler());
21169 CheckIT(cond);
21170 Dt_U_opc1_opc2_1 encoded_dt(dt, rn);
21171 if (IsUsingT32()) {
21172 // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1
21173 if (encoded_dt.IsValid() && (!rt.IsPC() || AllowUnpredictable())) {
21174 EmitT32_32(0xee100b10U | ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
21175 ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
21176 ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
21177 (rt.GetCode() << 12) | rn.Encode(7, 16));
21178 AdvanceIT();
21179 return;
21180 }
21181 } else {
21182 // VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1
21183 if (encoded_dt.IsValid() && cond.IsNotNever() &&
21184 (!rt.IsPC() || AllowUnpredictable())) {
21185 EmitA32(0x0e100b10U | (cond.GetCondition() << 28) |
21186 ((encoded_dt.GetEncodingValue() & 0x3) << 5) |
21187 ((encoded_dt.GetEncodingValue() & 0xc) << 19) |
21188 ((encoded_dt.GetEncodingValue() & 0x10) << 19) |
21189 (rt.GetCode() << 12) | rn.Encode(7, 16));
21190 return;
21191 }
21192 }
21193 Delegate(kVmov, &Assembler::vmov, cond, dt, rt, rn);
21194 }
21195
vmovl(Condition cond,DataType dt,QRegister rd,DRegister rm)21196 void Assembler::vmovl(Condition cond, DataType dt, QRegister rd, DRegister rm) {
21197 VIXL_ASSERT(AllowAssembler());
21198 CheckIT(cond);
21199 Dt_U_imm3H_1 encoded_dt(dt);
21200 if (IsUsingT32()) {
21201 // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1
21202 if (encoded_dt.IsValid()) {
21203 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21204 EmitT32_32(0xef800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21205 ((encoded_dt.GetEncodingValue() & 0x8) << 25) |
21206 rd.Encode(22, 12) | rm.Encode(5, 0));
21207 AdvanceIT();
21208 return;
21209 }
21210 }
21211 } else {
21212 // VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
21213 if (encoded_dt.IsValid()) {
21214 if (cond.Is(al)) {
21215 EmitA32(0xf2800a10U | ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
21216 ((encoded_dt.GetEncodingValue() & 0x8) << 21) |
21217 rd.Encode(22, 12) | rm.Encode(5, 0));
21218 return;
21219 }
21220 }
21221 }
21222 Delegate(kVmovl, &Assembler::vmovl, cond, dt, rd, rm);
21223 }
21224
vmovn(Condition cond,DataType dt,DRegister rd,QRegister rm)21225 void Assembler::vmovn(Condition cond, DataType dt, DRegister rd, QRegister rm) {
21226 VIXL_ASSERT(AllowAssembler());
21227 CheckIT(cond);
21228 Dt_size_3 encoded_dt(dt);
21229 if (IsUsingT32()) {
21230 // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
21231 if (encoded_dt.IsValid()) {
21232 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21233 EmitT32_32(0xffb20200U | (encoded_dt.GetEncodingValue() << 18) |
21234 rd.Encode(22, 12) | rm.Encode(5, 0));
21235 AdvanceIT();
21236 return;
21237 }
21238 }
21239 } else {
21240 // VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
21241 if (encoded_dt.IsValid()) {
21242 if (cond.Is(al)) {
21243 EmitA32(0xf3b20200U | (encoded_dt.GetEncodingValue() << 18) |
21244 rd.Encode(22, 12) | rm.Encode(5, 0));
21245 return;
21246 }
21247 }
21248 }
21249 Delegate(kVmovn, &Assembler::vmovn, cond, dt, rd, rm);
21250 }
21251
vmrs(Condition cond,RegisterOrAPSR_nzcv rt,SpecialFPRegister spec_reg)21252 void Assembler::vmrs(Condition cond,
21253 RegisterOrAPSR_nzcv rt,
21254 SpecialFPRegister spec_reg) {
21255 VIXL_ASSERT(AllowAssembler());
21256 CheckIT(cond);
21257 if (IsUsingT32()) {
21258 // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1
21259 EmitT32_32(0xeef00a10U | (rt.GetCode() << 12) | (spec_reg.GetReg() << 16));
21260 AdvanceIT();
21261 return;
21262 } else {
21263 // VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1
21264 if (cond.IsNotNever()) {
21265 EmitA32(0x0ef00a10U | (cond.GetCondition() << 28) | (rt.GetCode() << 12) |
21266 (spec_reg.GetReg() << 16));
21267 return;
21268 }
21269 }
21270 Delegate(kVmrs, &Assembler::vmrs, cond, rt, spec_reg);
21271 }
21272
vmsr(Condition cond,SpecialFPRegister spec_reg,Register rt)21273 void Assembler::vmsr(Condition cond, SpecialFPRegister spec_reg, Register rt) {
21274 VIXL_ASSERT(AllowAssembler());
21275 CheckIT(cond);
21276 if (IsUsingT32()) {
21277 // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1
21278 if ((!rt.IsPC() || AllowUnpredictable())) {
21279 EmitT32_32(0xeee00a10U | (spec_reg.GetReg() << 16) |
21280 (rt.GetCode() << 12));
21281 AdvanceIT();
21282 return;
21283 }
21284 } else {
21285 // VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1
21286 if (cond.IsNotNever() && (!rt.IsPC() || AllowUnpredictable())) {
21287 EmitA32(0x0ee00a10U | (cond.GetCondition() << 28) |
21288 (spec_reg.GetReg() << 16) | (rt.GetCode() << 12));
21289 return;
21290 }
21291 }
21292 Delegate(kVmsr, &Assembler::vmsr, cond, spec_reg, rt);
21293 }
21294
vmul(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister dm,unsigned index)21295 void Assembler::vmul(Condition cond,
21296 DataType dt,
21297 DRegister rd,
21298 DRegister rn,
21299 DRegister dm,
21300 unsigned index) {
21301 VIXL_ASSERT(AllowAssembler());
21302 CheckIT(cond);
21303 Dt_F_size_3 encoded_dt(dt);
21304 if (IsUsingT32()) {
21305 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1
21306 if (encoded_dt.IsValid() &&
21307 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21308 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
21309 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21310 uint32_t shift = 4;
21311 if (dt.Is(I16)) {
21312 shift = 3;
21313 }
21314 uint32_t mvm = dm.GetCode() | index << shift;
21315 EmitT32_32(0xef800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21316 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
21317 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21318 ((mvm & 0x10) << 1));
21319 AdvanceIT();
21320 return;
21321 }
21322 }
21323 } else {
21324 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1
21325 if (encoded_dt.IsValid() &&
21326 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21327 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
21328 if (cond.Is(al)) {
21329 uint32_t shift = 4;
21330 if (dt.Is(I16)) {
21331 shift = 3;
21332 }
21333 uint32_t mvm = dm.GetCode() | index << shift;
21334 EmitA32(0xf2800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21335 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
21336 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21337 ((mvm & 0x10) << 1));
21338 return;
21339 }
21340 }
21341 }
21342 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
21343 }
21344
vmul(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegister dm,unsigned index)21345 void Assembler::vmul(Condition cond,
21346 DataType dt,
21347 QRegister rd,
21348 QRegister rn,
21349 DRegister dm,
21350 unsigned index) {
21351 VIXL_ASSERT(AllowAssembler());
21352 CheckIT(cond);
21353 Dt_F_size_3 encoded_dt(dt);
21354 if (IsUsingT32()) {
21355 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1
21356 if (encoded_dt.IsValid() &&
21357 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21358 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
21359 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21360 uint32_t shift = 4;
21361 if (dt.Is(I16)) {
21362 shift = 3;
21363 }
21364 uint32_t mvm = dm.GetCode() | index << shift;
21365 EmitT32_32(0xff800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21366 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
21367 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21368 ((mvm & 0x10) << 1));
21369 AdvanceIT();
21370 return;
21371 }
21372 }
21373 } else {
21374 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1
21375 if (encoded_dt.IsValid() &&
21376 ((dt.Is(I16) && (index <= 3) && (dm.GetCode() <= 7)) ||
21377 (!dt.Is(I16) && (index <= 1) && (dm.GetCode() <= 15)))) {
21378 if (cond.Is(al)) {
21379 uint32_t shift = 4;
21380 if (dt.Is(I16)) {
21381 shift = 3;
21382 }
21383 uint32_t mvm = dm.GetCode() | index << shift;
21384 EmitA32(0xf3800840U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21385 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
21386 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21387 ((mvm & 0x10) << 1));
21388 return;
21389 }
21390 }
21391 }
21392 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, dm, index);
21393 }
21394
vmul(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21395 void Assembler::vmul(
21396 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21397 VIXL_ASSERT(AllowAssembler());
21398 CheckIT(cond);
21399 Dt_op_size_1 encoded_dt(dt);
21400 if (IsUsingT32()) {
21401 // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
21402 if (dt.Is(F32)) {
21403 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21404 EmitT32_32(0xff000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21405 rm.Encode(5, 0));
21406 AdvanceIT();
21407 return;
21408 }
21409 }
21410 // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
21411 if (dt.Is(F64)) {
21412 EmitT32_32(0xee200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21413 rm.Encode(5, 0));
21414 AdvanceIT();
21415 return;
21416 }
21417 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
21418 if (encoded_dt.IsValid()) {
21419 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21420 EmitT32_32(0xef000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21421 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21422 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21423 AdvanceIT();
21424 return;
21425 }
21426 }
21427 } else {
21428 // VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
21429 if (dt.Is(F32)) {
21430 if (cond.Is(al)) {
21431 EmitA32(0xf3000d10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21432 rm.Encode(5, 0));
21433 return;
21434 }
21435 }
21436 // VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
21437 if (dt.Is(F64) && cond.IsNotNever()) {
21438 EmitA32(0x0e200b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21439 rn.Encode(7, 16) | rm.Encode(5, 0));
21440 return;
21441 }
21442 // VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
21443 if (encoded_dt.IsValid()) {
21444 if (cond.Is(al)) {
21445 EmitA32(0xf2000910U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21446 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21447 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21448 return;
21449 }
21450 }
21451 }
21452 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
21453 }
21454
vmul(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)21455 void Assembler::vmul(
21456 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
21457 VIXL_ASSERT(AllowAssembler());
21458 CheckIT(cond);
21459 Dt_op_size_1 encoded_dt(dt);
21460 if (IsUsingT32()) {
21461 // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
21462 if (dt.Is(F32)) {
21463 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21464 EmitT32_32(0xff000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21465 rm.Encode(5, 0));
21466 AdvanceIT();
21467 return;
21468 }
21469 }
21470 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
21471 if (encoded_dt.IsValid()) {
21472 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21473 EmitT32_32(0xef000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21474 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21475 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21476 AdvanceIT();
21477 return;
21478 }
21479 }
21480 } else {
21481 // VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
21482 if (dt.Is(F32)) {
21483 if (cond.Is(al)) {
21484 EmitA32(0xf3000d50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21485 rm.Encode(5, 0));
21486 return;
21487 }
21488 }
21489 // VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
21490 if (encoded_dt.IsValid()) {
21491 if (cond.Is(al)) {
21492 EmitA32(0xf2000950U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21493 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21494 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21495 return;
21496 }
21497 }
21498 }
21499 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
21500 }
21501
vmul(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)21502 void Assembler::vmul(
21503 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
21504 VIXL_ASSERT(AllowAssembler());
21505 CheckIT(cond);
21506 if (IsUsingT32()) {
21507 // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
21508 if (dt.Is(F32)) {
21509 EmitT32_32(0xee200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21510 rm.Encode(5, 0));
21511 AdvanceIT();
21512 return;
21513 }
21514 } else {
21515 // VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
21516 if (dt.Is(F32) && cond.IsNotNever()) {
21517 EmitA32(0x0e200a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21518 rn.Encode(7, 16) | rm.Encode(5, 0));
21519 return;
21520 }
21521 }
21522 Delegate(kVmul, &Assembler::vmul, cond, dt, rd, rn, rm);
21523 }
21524
vmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister dm,unsigned index)21525 void Assembler::vmull(Condition cond,
21526 DataType dt,
21527 QRegister rd,
21528 DRegister rn,
21529 DRegister dm,
21530 unsigned index) {
21531 VIXL_ASSERT(AllowAssembler());
21532 CheckIT(cond);
21533 Dt_U_size_2 encoded_dt(dt);
21534 if (IsUsingT32()) {
21535 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1
21536 if (encoded_dt.IsValid() &&
21537 (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
21538 (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) &&
21539 (dm.GetCode() <= 15)))) {
21540 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21541 uint32_t shift = 4;
21542 if (dt.Is(S16) || dt.Is(U16)) {
21543 shift = 3;
21544 }
21545 uint32_t mvm = dm.GetCode() | index << shift;
21546 EmitT32_32(0xef800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21547 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21548 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21549 ((mvm & 0x10) << 1));
21550 AdvanceIT();
21551 return;
21552 }
21553 }
21554 } else {
21555 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1
21556 if (encoded_dt.IsValid() &&
21557 (((dt.Is(S16) || dt.Is(U16)) && (index <= 3) && (dm.GetCode() <= 7)) ||
21558 (!dt.Is(S16) && !dt.Is(U16) && (index <= 1) &&
21559 (dm.GetCode() <= 15)))) {
21560 if (cond.Is(al)) {
21561 uint32_t shift = 4;
21562 if (dt.Is(S16) || dt.Is(U16)) {
21563 shift = 3;
21564 }
21565 uint32_t mvm = dm.GetCode() | index << shift;
21566 EmitA32(0xf2800a40U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21567 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21568 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
21569 ((mvm & 0x10) << 1));
21570 return;
21571 }
21572 }
21573 }
21574 Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, dm, index);
21575 }
21576
vmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)21577 void Assembler::vmull(
21578 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
21579 VIXL_ASSERT(AllowAssembler());
21580 CheckIT(cond);
21581 Dt_op_U_size_1 encoded_dt(dt);
21582 if (IsUsingT32()) {
21583 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
21584 if (encoded_dt.IsValid()) {
21585 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21586 EmitT32_32(0xef800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21587 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
21588 ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
21589 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21590 AdvanceIT();
21591 return;
21592 }
21593 }
21594 } else {
21595 // VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
21596 if (encoded_dt.IsValid()) {
21597 if (cond.Is(al)) {
21598 EmitA32(0xf2800c00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
21599 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
21600 ((encoded_dt.GetEncodingValue() & 0x8) << 6) |
21601 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
21602 return;
21603 }
21604 }
21605 }
21606 Delegate(kVmull, &Assembler::vmull, cond, dt, rd, rn, rm);
21607 }
21608
vmvn(Condition cond,DataType dt,DRegister rd,const DOperand & operand)21609 void Assembler::vmvn(Condition cond,
21610 DataType dt,
21611 DRegister rd,
21612 const DOperand& operand) {
21613 VIXL_ASSERT(AllowAssembler());
21614 CheckIT(cond);
21615 if (operand.IsImmediate()) {
21616 ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
21617 if (IsUsingT32()) {
21618 // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1
21619 if (encoded_dt.IsValid()) {
21620 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21621 EmitT32_32(0xef800030U | (encoded_dt.GetEncodingValue() << 8) |
21622 rd.Encode(22, 12) |
21623 (encoded_dt.GetEncodedImmediate() & 0xf) |
21624 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21625 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
21626 AdvanceIT();
21627 return;
21628 }
21629 }
21630 } else {
21631 // VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
21632 if (encoded_dt.IsValid()) {
21633 if (cond.Is(al)) {
21634 EmitA32(0xf2800030U | (encoded_dt.GetEncodingValue() << 8) |
21635 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
21636 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21637 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
21638 return;
21639 }
21640 }
21641 }
21642 }
21643 if (operand.IsRegister()) {
21644 DRegister rm = operand.GetRegister();
21645 USE(dt);
21646 if (IsUsingT32()) {
21647 // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
21648 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21649 EmitT32_32(0xffb00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
21650 AdvanceIT();
21651 return;
21652 }
21653 } else {
21654 // VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
21655 if (cond.Is(al)) {
21656 EmitA32(0xf3b00580U | rd.Encode(22, 12) | rm.Encode(5, 0));
21657 return;
21658 }
21659 }
21660 }
21661 Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
21662 }
21663
vmvn(Condition cond,DataType dt,QRegister rd,const QOperand & operand)21664 void Assembler::vmvn(Condition cond,
21665 DataType dt,
21666 QRegister rd,
21667 const QOperand& operand) {
21668 VIXL_ASSERT(AllowAssembler());
21669 CheckIT(cond);
21670 if (operand.IsImmediate()) {
21671 ImmediateVmvn encoded_dt(dt, operand.GetNeonImmediate());
21672 if (IsUsingT32()) {
21673 // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1
21674 if (encoded_dt.IsValid()) {
21675 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21676 EmitT32_32(0xef800070U | (encoded_dt.GetEncodingValue() << 8) |
21677 rd.Encode(22, 12) |
21678 (encoded_dt.GetEncodedImmediate() & 0xf) |
21679 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21680 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
21681 AdvanceIT();
21682 return;
21683 }
21684 }
21685 } else {
21686 // VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
21687 if (encoded_dt.IsValid()) {
21688 if (cond.Is(al)) {
21689 EmitA32(0xf2800070U | (encoded_dt.GetEncodingValue() << 8) |
21690 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
21691 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21692 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
21693 return;
21694 }
21695 }
21696 }
21697 }
21698 if (operand.IsRegister()) {
21699 QRegister rm = operand.GetRegister();
21700 USE(dt);
21701 if (IsUsingT32()) {
21702 // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
21703 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21704 EmitT32_32(0xffb005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
21705 AdvanceIT();
21706 return;
21707 }
21708 } else {
21709 // VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
21710 if (cond.Is(al)) {
21711 EmitA32(0xf3b005c0U | rd.Encode(22, 12) | rm.Encode(5, 0));
21712 return;
21713 }
21714 }
21715 }
21716 Delegate(kVmvn, &Assembler::vmvn, cond, dt, rd, operand);
21717 }
21718
vneg(Condition cond,DataType dt,DRegister rd,DRegister rm)21719 void Assembler::vneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
21720 VIXL_ASSERT(AllowAssembler());
21721 CheckIT(cond);
21722 Dt_F_size_1 encoded_dt(dt);
21723 if (IsUsingT32()) {
21724 // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
21725 if (encoded_dt.IsValid()) {
21726 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21727 EmitT32_32(0xffb10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21728 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
21729 rd.Encode(22, 12) | rm.Encode(5, 0));
21730 AdvanceIT();
21731 return;
21732 }
21733 }
21734 // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
21735 if (dt.Is(F64)) {
21736 EmitT32_32(0xeeb10b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
21737 AdvanceIT();
21738 return;
21739 }
21740 } else {
21741 // VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
21742 if (encoded_dt.IsValid()) {
21743 if (cond.Is(al)) {
21744 EmitA32(0xf3b10380U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21745 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
21746 rd.Encode(22, 12) | rm.Encode(5, 0));
21747 return;
21748 }
21749 }
21750 // VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
21751 if (dt.Is(F64) && cond.IsNotNever()) {
21752 EmitA32(0x0eb10b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21753 rm.Encode(5, 0));
21754 return;
21755 }
21756 }
21757 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
21758 }
21759
vneg(Condition cond,DataType dt,QRegister rd,QRegister rm)21760 void Assembler::vneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
21761 VIXL_ASSERT(AllowAssembler());
21762 CheckIT(cond);
21763 Dt_F_size_1 encoded_dt(dt);
21764 if (IsUsingT32()) {
21765 // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
21766 if (encoded_dt.IsValid()) {
21767 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21768 EmitT32_32(0xffb103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21769 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
21770 rd.Encode(22, 12) | rm.Encode(5, 0));
21771 AdvanceIT();
21772 return;
21773 }
21774 }
21775 } else {
21776 // VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
21777 if (encoded_dt.IsValid()) {
21778 if (cond.Is(al)) {
21779 EmitA32(0xf3b103c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
21780 ((encoded_dt.GetEncodingValue() & 0x4) << 8) |
21781 rd.Encode(22, 12) | rm.Encode(5, 0));
21782 return;
21783 }
21784 }
21785 }
21786 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
21787 }
21788
vneg(Condition cond,DataType dt,SRegister rd,SRegister rm)21789 void Assembler::vneg(Condition cond, DataType dt, SRegister rd, SRegister rm) {
21790 VIXL_ASSERT(AllowAssembler());
21791 CheckIT(cond);
21792 if (IsUsingT32()) {
21793 // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
21794 if (dt.Is(F32)) {
21795 EmitT32_32(0xeeb10a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
21796 AdvanceIT();
21797 return;
21798 }
21799 } else {
21800 // VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
21801 if (dt.Is(F32) && cond.IsNotNever()) {
21802 EmitA32(0x0eb10a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21803 rm.Encode(5, 0));
21804 return;
21805 }
21806 }
21807 Delegate(kVneg, &Assembler::vneg, cond, dt, rd, rm);
21808 }
21809
vnmla(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)21810 void Assembler::vnmla(
21811 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
21812 VIXL_ASSERT(AllowAssembler());
21813 CheckIT(cond);
21814 if (IsUsingT32()) {
21815 // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
21816 if (dt.Is(F32)) {
21817 EmitT32_32(0xee100a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21818 rm.Encode(5, 0));
21819 AdvanceIT();
21820 return;
21821 }
21822 } else {
21823 // VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
21824 if (dt.Is(F32) && cond.IsNotNever()) {
21825 EmitA32(0x0e100a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21826 rn.Encode(7, 16) | rm.Encode(5, 0));
21827 return;
21828 }
21829 }
21830 Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
21831 }
21832
vnmla(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21833 void Assembler::vnmla(
21834 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21835 VIXL_ASSERT(AllowAssembler());
21836 CheckIT(cond);
21837 if (IsUsingT32()) {
21838 // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
21839 if (dt.Is(F64)) {
21840 EmitT32_32(0xee100b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21841 rm.Encode(5, 0));
21842 AdvanceIT();
21843 return;
21844 }
21845 } else {
21846 // VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
21847 if (dt.Is(F64) && cond.IsNotNever()) {
21848 EmitA32(0x0e100b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21849 rn.Encode(7, 16) | rm.Encode(5, 0));
21850 return;
21851 }
21852 }
21853 Delegate(kVnmla, &Assembler::vnmla, cond, dt, rd, rn, rm);
21854 }
21855
vnmls(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)21856 void Assembler::vnmls(
21857 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
21858 VIXL_ASSERT(AllowAssembler());
21859 CheckIT(cond);
21860 if (IsUsingT32()) {
21861 // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
21862 if (dt.Is(F32)) {
21863 EmitT32_32(0xee100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21864 rm.Encode(5, 0));
21865 AdvanceIT();
21866 return;
21867 }
21868 } else {
21869 // VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
21870 if (dt.Is(F32) && cond.IsNotNever()) {
21871 EmitA32(0x0e100a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21872 rn.Encode(7, 16) | rm.Encode(5, 0));
21873 return;
21874 }
21875 }
21876 Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
21877 }
21878
vnmls(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21879 void Assembler::vnmls(
21880 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21881 VIXL_ASSERT(AllowAssembler());
21882 CheckIT(cond);
21883 if (IsUsingT32()) {
21884 // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
21885 if (dt.Is(F64)) {
21886 EmitT32_32(0xee100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21887 rm.Encode(5, 0));
21888 AdvanceIT();
21889 return;
21890 }
21891 } else {
21892 // VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
21893 if (dt.Is(F64) && cond.IsNotNever()) {
21894 EmitA32(0x0e100b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21895 rn.Encode(7, 16) | rm.Encode(5, 0));
21896 return;
21897 }
21898 }
21899 Delegate(kVnmls, &Assembler::vnmls, cond, dt, rd, rn, rm);
21900 }
21901
vnmul(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)21902 void Assembler::vnmul(
21903 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
21904 VIXL_ASSERT(AllowAssembler());
21905 CheckIT(cond);
21906 if (IsUsingT32()) {
21907 // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
21908 if (dt.Is(F32)) {
21909 EmitT32_32(0xee200a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21910 rm.Encode(5, 0));
21911 AdvanceIT();
21912 return;
21913 }
21914 } else {
21915 // VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
21916 if (dt.Is(F32) && cond.IsNotNever()) {
21917 EmitA32(0x0e200a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21918 rn.Encode(7, 16) | rm.Encode(5, 0));
21919 return;
21920 }
21921 }
21922 Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
21923 }
21924
vnmul(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)21925 void Assembler::vnmul(
21926 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
21927 VIXL_ASSERT(AllowAssembler());
21928 CheckIT(cond);
21929 if (IsUsingT32()) {
21930 // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
21931 if (dt.Is(F64)) {
21932 EmitT32_32(0xee200b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21933 rm.Encode(5, 0));
21934 AdvanceIT();
21935 return;
21936 }
21937 } else {
21938 // VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
21939 if (dt.Is(F64) && cond.IsNotNever()) {
21940 EmitA32(0x0e200b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
21941 rn.Encode(7, 16) | rm.Encode(5, 0));
21942 return;
21943 }
21944 }
21945 Delegate(kVnmul, &Assembler::vnmul, cond, dt, rd, rn, rm);
21946 }
21947
vorn(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)21948 void Assembler::vorn(Condition cond,
21949 DataType dt,
21950 DRegister rd,
21951 DRegister rn,
21952 const DOperand& operand) {
21953 VIXL_ASSERT(AllowAssembler());
21954 CheckIT(cond);
21955 if (operand.IsImmediate()) {
21956 ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
21957 if (IsUsingT32()) {
21958 // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
21959 if (encoded_dt.IsValid() && rd.Is(rn)) {
21960 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21961 EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
21962 rd.Encode(22, 12) |
21963 (encoded_dt.GetEncodedImmediate() & 0xf) |
21964 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21965 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
21966 AdvanceIT();
21967 return;
21968 }
21969 }
21970 } else {
21971 // VORN{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
21972 if (encoded_dt.IsValid() && rd.Is(rn)) {
21973 if (cond.Is(al)) {
21974 EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
21975 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
21976 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
21977 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
21978 return;
21979 }
21980 }
21981 }
21982 }
21983 if (operand.IsRegister()) {
21984 DRegister rm = operand.GetRegister();
21985 USE(dt);
21986 if (IsUsingT32()) {
21987 // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
21988 if (cond.Is(al) || AllowStronglyDiscouraged()) {
21989 EmitT32_32(0xef300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21990 rm.Encode(5, 0));
21991 AdvanceIT();
21992 return;
21993 }
21994 } else {
21995 // VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
21996 if (cond.Is(al)) {
21997 EmitA32(0xf2300110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
21998 rm.Encode(5, 0));
21999 return;
22000 }
22001 }
22002 }
22003 Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
22004 }
22005
vorn(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)22006 void Assembler::vorn(Condition cond,
22007 DataType dt,
22008 QRegister rd,
22009 QRegister rn,
22010 const QOperand& operand) {
22011 VIXL_ASSERT(AllowAssembler());
22012 CheckIT(cond);
22013 if (operand.IsImmediate()) {
22014 ImmediateVorn encoded_dt(dt, operand.GetNeonImmediate());
22015 if (IsUsingT32()) {
22016 // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
22017 if (encoded_dt.IsValid() && rd.Is(rn)) {
22018 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22019 EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
22020 rd.Encode(22, 12) |
22021 (encoded_dt.GetEncodedImmediate() & 0xf) |
22022 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
22023 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
22024 AdvanceIT();
22025 return;
22026 }
22027 }
22028 } else {
22029 // VORN{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
22030 if (encoded_dt.IsValid() && rd.Is(rn)) {
22031 if (cond.Is(al)) {
22032 EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
22033 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
22034 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
22035 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
22036 return;
22037 }
22038 }
22039 }
22040 }
22041 if (operand.IsRegister()) {
22042 QRegister rm = operand.GetRegister();
22043 USE(dt);
22044 if (IsUsingT32()) {
22045 // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
22046 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22047 EmitT32_32(0xef300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22048 rm.Encode(5, 0));
22049 AdvanceIT();
22050 return;
22051 }
22052 } else {
22053 // VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
22054 if (cond.Is(al)) {
22055 EmitA32(0xf2300150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22056 rm.Encode(5, 0));
22057 return;
22058 }
22059 }
22060 }
22061 Delegate(kVorn, &Assembler::vorn, cond, dt, rd, rn, operand);
22062 }
22063
vorr(Condition cond,DataType dt,DRegister rd,DRegister rn,const DOperand & operand)22064 void Assembler::vorr(Condition cond,
22065 DataType dt,
22066 DRegister rd,
22067 DRegister rn,
22068 const DOperand& operand) {
22069 VIXL_ASSERT(AllowAssembler());
22070 CheckIT(cond);
22071 if (operand.IsRegister()) {
22072 DRegister rm = operand.GetRegister();
22073 USE(dt);
22074 if (IsUsingT32()) {
22075 // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
22076 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22077 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22078 rm.Encode(5, 0));
22079 AdvanceIT();
22080 return;
22081 }
22082 } else {
22083 // VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
22084 if (cond.Is(al)) {
22085 EmitA32(0xf2200110U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22086 rm.Encode(5, 0));
22087 return;
22088 }
22089 }
22090 }
22091 if (operand.IsImmediate()) {
22092 ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
22093 if (IsUsingT32()) {
22094 // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1
22095 if (encoded_dt.IsValid() && rd.Is(rn)) {
22096 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22097 EmitT32_32(0xef800010U | (encoded_dt.GetEncodingValue() << 8) |
22098 rd.Encode(22, 12) |
22099 (encoded_dt.GetEncodedImmediate() & 0xf) |
22100 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
22101 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
22102 AdvanceIT();
22103 return;
22104 }
22105 }
22106 } else {
22107 // VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1
22108 if (encoded_dt.IsValid() && rd.Is(rn)) {
22109 if (cond.Is(al)) {
22110 EmitA32(0xf2800010U | (encoded_dt.GetEncodingValue() << 8) |
22111 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
22112 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
22113 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
22114 return;
22115 }
22116 }
22117 }
22118 }
22119 Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
22120 }
22121
vorr(Condition cond,DataType dt,QRegister rd,QRegister rn,const QOperand & operand)22122 void Assembler::vorr(Condition cond,
22123 DataType dt,
22124 QRegister rd,
22125 QRegister rn,
22126 const QOperand& operand) {
22127 VIXL_ASSERT(AllowAssembler());
22128 CheckIT(cond);
22129 if (operand.IsRegister()) {
22130 QRegister rm = operand.GetRegister();
22131 USE(dt);
22132 if (IsUsingT32()) {
22133 // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
22134 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22135 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22136 rm.Encode(5, 0));
22137 AdvanceIT();
22138 return;
22139 }
22140 } else {
22141 // VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
22142 if (cond.Is(al)) {
22143 EmitA32(0xf2200150U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22144 rm.Encode(5, 0));
22145 return;
22146 }
22147 }
22148 }
22149 if (operand.IsImmediate()) {
22150 ImmediateVorr encoded_dt(dt, operand.GetNeonImmediate());
22151 if (IsUsingT32()) {
22152 // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1
22153 if (encoded_dt.IsValid() && rd.Is(rn)) {
22154 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22155 EmitT32_32(0xef800050U | (encoded_dt.GetEncodingValue() << 8) |
22156 rd.Encode(22, 12) |
22157 (encoded_dt.GetEncodedImmediate() & 0xf) |
22158 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
22159 ((encoded_dt.GetEncodedImmediate() & 0x80) << 21));
22160 AdvanceIT();
22161 return;
22162 }
22163 }
22164 } else {
22165 // VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1
22166 if (encoded_dt.IsValid() && rd.Is(rn)) {
22167 if (cond.Is(al)) {
22168 EmitA32(0xf2800050U | (encoded_dt.GetEncodingValue() << 8) |
22169 rd.Encode(22, 12) | (encoded_dt.GetEncodedImmediate() & 0xf) |
22170 ((encoded_dt.GetEncodedImmediate() & 0x70) << 12) |
22171 ((encoded_dt.GetEncodedImmediate() & 0x80) << 17));
22172 return;
22173 }
22174 }
22175 }
22176 }
22177 Delegate(kVorr, &Assembler::vorr, cond, dt, rd, rn, operand);
22178 }
22179
vpadal(Condition cond,DataType dt,DRegister rd,DRegister rm)22180 void Assembler::vpadal(Condition cond,
22181 DataType dt,
22182 DRegister rd,
22183 DRegister rm) {
22184 VIXL_ASSERT(AllowAssembler());
22185 CheckIT(cond);
22186 Dt_op_size_2 encoded_dt(dt);
22187 if (IsUsingT32()) {
22188 // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22189 if (encoded_dt.IsValid()) {
22190 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22191 EmitT32_32(0xffb00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22192 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22193 rd.Encode(22, 12) | rm.Encode(5, 0));
22194 AdvanceIT();
22195 return;
22196 }
22197 }
22198 } else {
22199 // VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22200 if (encoded_dt.IsValid()) {
22201 if (cond.Is(al)) {
22202 EmitA32(0xf3b00600U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22203 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22204 rd.Encode(22, 12) | rm.Encode(5, 0));
22205 return;
22206 }
22207 }
22208 }
22209 Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
22210 }
22211
vpadal(Condition cond,DataType dt,QRegister rd,QRegister rm)22212 void Assembler::vpadal(Condition cond,
22213 DataType dt,
22214 QRegister rd,
22215 QRegister rm) {
22216 VIXL_ASSERT(AllowAssembler());
22217 CheckIT(cond);
22218 Dt_op_size_2 encoded_dt(dt);
22219 if (IsUsingT32()) {
22220 // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22221 if (encoded_dt.IsValid()) {
22222 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22223 EmitT32_32(0xffb00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22224 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22225 rd.Encode(22, 12) | rm.Encode(5, 0));
22226 AdvanceIT();
22227 return;
22228 }
22229 }
22230 } else {
22231 // VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22232 if (encoded_dt.IsValid()) {
22233 if (cond.Is(al)) {
22234 EmitA32(0xf3b00640U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22235 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22236 rd.Encode(22, 12) | rm.Encode(5, 0));
22237 return;
22238 }
22239 }
22240 }
22241 Delegate(kVpadal, &Assembler::vpadal, cond, dt, rd, rm);
22242 }
22243
vpadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22244 void Assembler::vpadd(
22245 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22246 VIXL_ASSERT(AllowAssembler());
22247 CheckIT(cond);
22248 Dt_size_4 encoded_dt(dt);
22249 if (IsUsingT32()) {
22250 // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
22251 if (dt.Is(F32)) {
22252 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22253 EmitT32_32(0xff000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22254 rm.Encode(5, 0));
22255 AdvanceIT();
22256 return;
22257 }
22258 }
22259 // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22260 if (encoded_dt.IsValid()) {
22261 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22262 EmitT32_32(0xef000b10U | (encoded_dt.GetEncodingValue() << 20) |
22263 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22264 AdvanceIT();
22265 return;
22266 }
22267 }
22268 } else {
22269 // VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
22270 if (dt.Is(F32)) {
22271 if (cond.Is(al)) {
22272 EmitA32(0xf3000d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22273 rm.Encode(5, 0));
22274 return;
22275 }
22276 }
22277 // VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22278 if (encoded_dt.IsValid()) {
22279 if (cond.Is(al)) {
22280 EmitA32(0xf2000b10U | (encoded_dt.GetEncodingValue() << 20) |
22281 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22282 return;
22283 }
22284 }
22285 }
22286 Delegate(kVpadd, &Assembler::vpadd, cond, dt, rd, rn, rm);
22287 }
22288
vpaddl(Condition cond,DataType dt,DRegister rd,DRegister rm)22289 void Assembler::vpaddl(Condition cond,
22290 DataType dt,
22291 DRegister rd,
22292 DRegister rm) {
22293 VIXL_ASSERT(AllowAssembler());
22294 CheckIT(cond);
22295 Dt_op_size_2 encoded_dt(dt);
22296 if (IsUsingT32()) {
22297 // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22298 if (encoded_dt.IsValid()) {
22299 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22300 EmitT32_32(0xffb00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22301 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22302 rd.Encode(22, 12) | rm.Encode(5, 0));
22303 AdvanceIT();
22304 return;
22305 }
22306 }
22307 } else {
22308 // VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22309 if (encoded_dt.IsValid()) {
22310 if (cond.Is(al)) {
22311 EmitA32(0xf3b00200U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22312 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22313 rd.Encode(22, 12) | rm.Encode(5, 0));
22314 return;
22315 }
22316 }
22317 }
22318 Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
22319 }
22320
vpaddl(Condition cond,DataType dt,QRegister rd,QRegister rm)22321 void Assembler::vpaddl(Condition cond,
22322 DataType dt,
22323 QRegister rd,
22324 QRegister rm) {
22325 VIXL_ASSERT(AllowAssembler());
22326 CheckIT(cond);
22327 Dt_op_size_2 encoded_dt(dt);
22328 if (IsUsingT32()) {
22329 // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22330 if (encoded_dt.IsValid()) {
22331 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22332 EmitT32_32(0xffb00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22333 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22334 rd.Encode(22, 12) | rm.Encode(5, 0));
22335 AdvanceIT();
22336 return;
22337 }
22338 }
22339 } else {
22340 // VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22341 if (encoded_dt.IsValid()) {
22342 if (cond.Is(al)) {
22343 EmitA32(0xf3b00240U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
22344 ((encoded_dt.GetEncodingValue() & 0x4) << 5) |
22345 rd.Encode(22, 12) | rm.Encode(5, 0));
22346 return;
22347 }
22348 }
22349 }
22350 Delegate(kVpaddl, &Assembler::vpaddl, cond, dt, rd, rm);
22351 }
22352
vpmax(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22353 void Assembler::vpmax(
22354 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22355 VIXL_ASSERT(AllowAssembler());
22356 CheckIT(cond);
22357 Dt_U_size_1 encoded_dt(dt);
22358 if (IsUsingT32()) {
22359 // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
22360 if (dt.Is(F32)) {
22361 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22362 EmitT32_32(0xff000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22363 rm.Encode(5, 0));
22364 AdvanceIT();
22365 return;
22366 }
22367 }
22368 // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22369 if (encoded_dt.IsValid()) {
22370 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22371 EmitT32_32(0xef000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22372 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22373 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22374 AdvanceIT();
22375 return;
22376 }
22377 }
22378 } else {
22379 // VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
22380 if (dt.Is(F32)) {
22381 if (cond.Is(al)) {
22382 EmitA32(0xf3000f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22383 rm.Encode(5, 0));
22384 return;
22385 }
22386 }
22387 // VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22388 if (encoded_dt.IsValid()) {
22389 if (cond.Is(al)) {
22390 EmitA32(0xf2000a00U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22391 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22392 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22393 return;
22394 }
22395 }
22396 }
22397 Delegate(kVpmax, &Assembler::vpmax, cond, dt, rd, rn, rm);
22398 }
22399
vpmin(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22400 void Assembler::vpmin(
22401 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22402 VIXL_ASSERT(AllowAssembler());
22403 CheckIT(cond);
22404 Dt_U_size_1 encoded_dt(dt);
22405 if (IsUsingT32()) {
22406 // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
22407 if (dt.Is(F32)) {
22408 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22409 EmitT32_32(0xff200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22410 rm.Encode(5, 0));
22411 AdvanceIT();
22412 return;
22413 }
22414 }
22415 // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22416 if (encoded_dt.IsValid()) {
22417 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22418 EmitT32_32(0xef000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22419 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22420 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22421 AdvanceIT();
22422 return;
22423 }
22424 }
22425 } else {
22426 // VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
22427 if (dt.Is(F32)) {
22428 if (cond.Is(al)) {
22429 EmitA32(0xf3200f00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
22430 rm.Encode(5, 0));
22431 return;
22432 }
22433 }
22434 // VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22435 if (encoded_dt.IsValid()) {
22436 if (cond.Is(al)) {
22437 EmitA32(0xf2000a10U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22438 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22439 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22440 return;
22441 }
22442 }
22443 }
22444 Delegate(kVpmin, &Assembler::vpmin, cond, dt, rd, rn, rm);
22445 }
22446
vpop(Condition cond,DataType dt,DRegisterList dreglist)22447 void Assembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) {
22448 VIXL_ASSERT(AllowAssembler());
22449 CheckIT(cond);
22450 USE(dt);
22451 if (IsUsingT32()) {
22452 // VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1
22453 if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
22454 const DRegister& dreg = dreglist.GetFirstDRegister();
22455 unsigned len = dreglist.GetLength() * 2;
22456 EmitT32_32(0xecbd0b00U | dreg.Encode(22, 12) | (len & 0xff));
22457 AdvanceIT();
22458 return;
22459 }
22460 } else {
22461 // VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1
22462 if (cond.IsNotNever() &&
22463 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
22464 const DRegister& dreg = dreglist.GetFirstDRegister();
22465 unsigned len = dreglist.GetLength() * 2;
22466 EmitA32(0x0cbd0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
22467 (len & 0xff));
22468 return;
22469 }
22470 }
22471 Delegate(kVpop, &Assembler::vpop, cond, dt, dreglist);
22472 }
22473
vpop(Condition cond,DataType dt,SRegisterList sreglist)22474 void Assembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) {
22475 VIXL_ASSERT(AllowAssembler());
22476 CheckIT(cond);
22477 USE(dt);
22478 if (IsUsingT32()) {
22479 // VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2
22480 const SRegister& sreg = sreglist.GetFirstSRegister();
22481 unsigned len = sreglist.GetLength();
22482 EmitT32_32(0xecbd0a00U | sreg.Encode(22, 12) | (len & 0xff));
22483 AdvanceIT();
22484 return;
22485 } else {
22486 // VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2
22487 if (cond.IsNotNever()) {
22488 const SRegister& sreg = sreglist.GetFirstSRegister();
22489 unsigned len = sreglist.GetLength();
22490 EmitA32(0x0cbd0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
22491 (len & 0xff));
22492 return;
22493 }
22494 }
22495 Delegate(kVpop, &Assembler::vpop, cond, dt, sreglist);
22496 }
22497
vpush(Condition cond,DataType dt,DRegisterList dreglist)22498 void Assembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) {
22499 VIXL_ASSERT(AllowAssembler());
22500 CheckIT(cond);
22501 USE(dt);
22502 if (IsUsingT32()) {
22503 // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1
22504 if (((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
22505 const DRegister& dreg = dreglist.GetFirstDRegister();
22506 unsigned len = dreglist.GetLength() * 2;
22507 EmitT32_32(0xed2d0b00U | dreg.Encode(22, 12) | (len & 0xff));
22508 AdvanceIT();
22509 return;
22510 }
22511 } else {
22512 // VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1
22513 if (cond.IsNotNever() &&
22514 ((dreglist.GetLength() <= 16) || AllowUnpredictable())) {
22515 const DRegister& dreg = dreglist.GetFirstDRegister();
22516 unsigned len = dreglist.GetLength() * 2;
22517 EmitA32(0x0d2d0b00U | (cond.GetCondition() << 28) | dreg.Encode(22, 12) |
22518 (len & 0xff));
22519 return;
22520 }
22521 }
22522 Delegate(kVpush, &Assembler::vpush, cond, dt, dreglist);
22523 }
22524
vpush(Condition cond,DataType dt,SRegisterList sreglist)22525 void Assembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) {
22526 VIXL_ASSERT(AllowAssembler());
22527 CheckIT(cond);
22528 USE(dt);
22529 if (IsUsingT32()) {
22530 // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2
22531 const SRegister& sreg = sreglist.GetFirstSRegister();
22532 unsigned len = sreglist.GetLength();
22533 EmitT32_32(0xed2d0a00U | sreg.Encode(22, 12) | (len & 0xff));
22534 AdvanceIT();
22535 return;
22536 } else {
22537 // VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2
22538 if (cond.IsNotNever()) {
22539 const SRegister& sreg = sreglist.GetFirstSRegister();
22540 unsigned len = sreglist.GetLength();
22541 EmitA32(0x0d2d0a00U | (cond.GetCondition() << 28) | sreg.Encode(22, 12) |
22542 (len & 0xff));
22543 return;
22544 }
22545 }
22546 Delegate(kVpush, &Assembler::vpush, cond, dt, sreglist);
22547 }
22548
vqabs(Condition cond,DataType dt,DRegister rd,DRegister rm)22549 void Assembler::vqabs(Condition cond, DataType dt, DRegister rd, DRegister rm) {
22550 VIXL_ASSERT(AllowAssembler());
22551 CheckIT(cond);
22552 Dt_size_5 encoded_dt(dt);
22553 if (IsUsingT32()) {
22554 // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
22555 if (encoded_dt.IsValid()) {
22556 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22557 EmitT32_32(0xffb00700U | (encoded_dt.GetEncodingValue() << 18) |
22558 rd.Encode(22, 12) | rm.Encode(5, 0));
22559 AdvanceIT();
22560 return;
22561 }
22562 }
22563 } else {
22564 // VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
22565 if (encoded_dt.IsValid()) {
22566 if (cond.Is(al)) {
22567 EmitA32(0xf3b00700U | (encoded_dt.GetEncodingValue() << 18) |
22568 rd.Encode(22, 12) | rm.Encode(5, 0));
22569 return;
22570 }
22571 }
22572 }
22573 Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
22574 }
22575
vqabs(Condition cond,DataType dt,QRegister rd,QRegister rm)22576 void Assembler::vqabs(Condition cond, DataType dt, QRegister rd, QRegister rm) {
22577 VIXL_ASSERT(AllowAssembler());
22578 CheckIT(cond);
22579 Dt_size_5 encoded_dt(dt);
22580 if (IsUsingT32()) {
22581 // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
22582 if (encoded_dt.IsValid()) {
22583 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22584 EmitT32_32(0xffb00740U | (encoded_dt.GetEncodingValue() << 18) |
22585 rd.Encode(22, 12) | rm.Encode(5, 0));
22586 AdvanceIT();
22587 return;
22588 }
22589 }
22590 } else {
22591 // VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
22592 if (encoded_dt.IsValid()) {
22593 if (cond.Is(al)) {
22594 EmitA32(0xf3b00740U | (encoded_dt.GetEncodingValue() << 18) |
22595 rd.Encode(22, 12) | rm.Encode(5, 0));
22596 return;
22597 }
22598 }
22599 }
22600 Delegate(kVqabs, &Assembler::vqabs, cond, dt, rd, rm);
22601 }
22602
vqadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22603 void Assembler::vqadd(
22604 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22605 VIXL_ASSERT(AllowAssembler());
22606 CheckIT(cond);
22607 Dt_U_size_3 encoded_dt(dt);
22608 if (IsUsingT32()) {
22609 // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22610 if (encoded_dt.IsValid()) {
22611 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22612 EmitT32_32(0xef000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22613 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22614 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22615 AdvanceIT();
22616 return;
22617 }
22618 }
22619 } else {
22620 // VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22621 if (encoded_dt.IsValid()) {
22622 if (cond.Is(al)) {
22623 EmitA32(0xf2000010U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22624 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22625 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22626 return;
22627 }
22628 }
22629 }
22630 Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
22631 }
22632
vqadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)22633 void Assembler::vqadd(
22634 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22635 VIXL_ASSERT(AllowAssembler());
22636 CheckIT(cond);
22637 Dt_U_size_3 encoded_dt(dt);
22638 if (IsUsingT32()) {
22639 // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22640 if (encoded_dt.IsValid()) {
22641 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22642 EmitT32_32(0xef000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22643 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
22644 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22645 AdvanceIT();
22646 return;
22647 }
22648 }
22649 } else {
22650 // VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22651 if (encoded_dt.IsValid()) {
22652 if (cond.Is(al)) {
22653 EmitA32(0xf2000050U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
22654 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
22655 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22656 return;
22657 }
22658 }
22659 }
22660 Delegate(kVqadd, &Assembler::vqadd, cond, dt, rd, rn, rm);
22661 }
22662
vqdmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)22663 void Assembler::vqdmlal(
22664 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
22665 VIXL_ASSERT(AllowAssembler());
22666 CheckIT(cond);
22667 Dt_size_13 encoded_dt(dt);
22668 if (IsUsingT32()) {
22669 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
22670 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22671 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22672 EmitT32_32(0xef800900U | (encoded_dt.GetEncodingValue() << 20) |
22673 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22674 AdvanceIT();
22675 return;
22676 }
22677 }
22678 } else {
22679 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
22680 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22681 if (cond.Is(al)) {
22682 EmitA32(0xf2800900U | (encoded_dt.GetEncodingValue() << 20) |
22683 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22684 return;
22685 }
22686 }
22687 }
22688 Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, rm);
22689 }
22690
vqdmlal(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister dm,unsigned index)22691 void Assembler::vqdmlal(Condition cond,
22692 DataType dt,
22693 QRegister rd,
22694 DRegister rn,
22695 DRegister dm,
22696 unsigned index) {
22697 VIXL_ASSERT(AllowAssembler());
22698 CheckIT(cond);
22699 Dt_size_13 encoded_dt(dt);
22700 if (IsUsingT32()) {
22701 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
22702 if (encoded_dt.IsValid() &&
22703 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
22704 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
22705 (dt.Is(S16) || dt.Is(S32))) {
22706 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22707 uint32_t shift = 4;
22708 if (dt.Is(S16)) {
22709 shift = 3;
22710 }
22711 uint32_t mvm = dm.GetCode() | index << shift;
22712 EmitT32_32(0xef800340U | (encoded_dt.GetEncodingValue() << 20) |
22713 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
22714 ((mvm & 0x10) << 1));
22715 AdvanceIT();
22716 return;
22717 }
22718 }
22719 } else {
22720 // VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
22721 if (encoded_dt.IsValid() &&
22722 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
22723 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
22724 (dt.Is(S16) || dt.Is(S32))) {
22725 if (cond.Is(al)) {
22726 uint32_t shift = 4;
22727 if (dt.Is(S16)) {
22728 shift = 3;
22729 }
22730 uint32_t mvm = dm.GetCode() | index << shift;
22731 EmitA32(0xf2800340U | (encoded_dt.GetEncodingValue() << 20) |
22732 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
22733 ((mvm & 0x10) << 1));
22734 return;
22735 }
22736 }
22737 }
22738 Delegate(kVqdmlal, &Assembler::vqdmlal, cond, dt, rd, rn, dm, index);
22739 }
22740
vqdmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)22741 void Assembler::vqdmlsl(
22742 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
22743 VIXL_ASSERT(AllowAssembler());
22744 CheckIT(cond);
22745 Dt_size_13 encoded_dt(dt);
22746 if (IsUsingT32()) {
22747 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
22748 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22749 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22750 EmitT32_32(0xef800b00U | (encoded_dt.GetEncodingValue() << 20) |
22751 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22752 AdvanceIT();
22753 return;
22754 }
22755 }
22756 } else {
22757 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
22758 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22759 if (cond.Is(al)) {
22760 EmitA32(0xf2800b00U | (encoded_dt.GetEncodingValue() << 20) |
22761 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22762 return;
22763 }
22764 }
22765 }
22766 Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, rm);
22767 }
22768
vqdmlsl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister dm,unsigned index)22769 void Assembler::vqdmlsl(Condition cond,
22770 DataType dt,
22771 QRegister rd,
22772 DRegister rn,
22773 DRegister dm,
22774 unsigned index) {
22775 VIXL_ASSERT(AllowAssembler());
22776 CheckIT(cond);
22777 Dt_size_13 encoded_dt(dt);
22778 if (IsUsingT32()) {
22779 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2
22780 if (encoded_dt.IsValid() &&
22781 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
22782 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
22783 (dt.Is(S16) || dt.Is(S32))) {
22784 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22785 uint32_t shift = 4;
22786 if (dt.Is(S16)) {
22787 shift = 3;
22788 }
22789 uint32_t mvm = dm.GetCode() | index << shift;
22790 EmitT32_32(0xef800740U | (encoded_dt.GetEncodingValue() << 20) |
22791 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
22792 ((mvm & 0x10) << 1));
22793 AdvanceIT();
22794 return;
22795 }
22796 }
22797 } else {
22798 // VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2
22799 if (encoded_dt.IsValid() &&
22800 ((dt.Is(S16) && (index <= 3) && (dm.GetCode() <= 7)) ||
22801 (!dt.Is(S16) && (index <= 1) && (dm.GetCode() <= 15))) &&
22802 (dt.Is(S16) || dt.Is(S32))) {
22803 if (cond.Is(al)) {
22804 uint32_t shift = 4;
22805 if (dt.Is(S16)) {
22806 shift = 3;
22807 }
22808 uint32_t mvm = dm.GetCode() | index << shift;
22809 EmitA32(0xf2800740U | (encoded_dt.GetEncodingValue() << 20) |
22810 rd.Encode(22, 12) | rn.Encode(7, 16) | (mvm & 0xf) |
22811 ((mvm & 0x10) << 1));
22812 return;
22813 }
22814 }
22815 }
22816 Delegate(kVqdmlsl, &Assembler::vqdmlsl, cond, dt, rd, rn, dm, index);
22817 }
22818
vqdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)22819 void Assembler::vqdmulh(
22820 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
22821 VIXL_ASSERT(AllowAssembler());
22822 CheckIT(cond);
22823 Dt_size_13 encoded_dt(dt);
22824 if (IsUsingT32()) {
22825 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
22826 if (encoded_dt.IsValid()) {
22827 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22828 EmitT32_32(0xef000b00U | (encoded_dt.GetEncodingValue() << 20) |
22829 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22830 AdvanceIT();
22831 return;
22832 }
22833 }
22834 } else {
22835 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
22836 if (encoded_dt.IsValid()) {
22837 if (cond.Is(al)) {
22838 EmitA32(0xf2000b00U | (encoded_dt.GetEncodingValue() << 20) |
22839 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22840 return;
22841 }
22842 }
22843 }
22844 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
22845 }
22846
vqdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)22847 void Assembler::vqdmulh(
22848 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
22849 VIXL_ASSERT(AllowAssembler());
22850 CheckIT(cond);
22851 Dt_size_13 encoded_dt(dt);
22852 if (IsUsingT32()) {
22853 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
22854 if (encoded_dt.IsValid()) {
22855 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22856 EmitT32_32(0xef000b40U | (encoded_dt.GetEncodingValue() << 20) |
22857 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22858 AdvanceIT();
22859 return;
22860 }
22861 }
22862 } else {
22863 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
22864 if (encoded_dt.IsValid()) {
22865 if (cond.Is(al)) {
22866 EmitA32(0xf2000b40U | (encoded_dt.GetEncodingValue() << 20) |
22867 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22868 return;
22869 }
22870 }
22871 }
22872 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
22873 }
22874
vqdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)22875 void Assembler::vqdmulh(
22876 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
22877 VIXL_ASSERT(AllowAssembler());
22878 CheckIT(cond);
22879 Dt_size_13 encoded_dt(dt);
22880 if (IsUsingT32()) {
22881 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
22882 if (encoded_dt.IsValid() &&
22883 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22884 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22885 (rm.GetLane() <= 1))) &&
22886 (dt.Is(S16) || dt.Is(S32))) {
22887 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22888 EmitT32_32(0xef800c40U | (encoded_dt.GetEncodingValue() << 20) |
22889 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
22890 AdvanceIT();
22891 return;
22892 }
22893 }
22894 } else {
22895 // VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
22896 if (encoded_dt.IsValid() &&
22897 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22898 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22899 (rm.GetLane() <= 1))) &&
22900 (dt.Is(S16) || dt.Is(S32))) {
22901 if (cond.Is(al)) {
22902 EmitA32(0xf2800c40U | (encoded_dt.GetEncodingValue() << 20) |
22903 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
22904 return;
22905 }
22906 }
22907 }
22908 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
22909 }
22910
vqdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)22911 void Assembler::vqdmulh(
22912 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
22913 VIXL_ASSERT(AllowAssembler());
22914 CheckIT(cond);
22915 Dt_size_13 encoded_dt(dt);
22916 if (IsUsingT32()) {
22917 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
22918 if (encoded_dt.IsValid() &&
22919 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22920 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22921 (rm.GetLane() <= 1))) &&
22922 (dt.Is(S16) || dt.Is(S32))) {
22923 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22924 EmitT32_32(0xff800c40U | (encoded_dt.GetEncodingValue() << 20) |
22925 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
22926 AdvanceIT();
22927 return;
22928 }
22929 }
22930 } else {
22931 // VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
22932 if (encoded_dt.IsValid() &&
22933 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22934 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22935 (rm.GetLane() <= 1))) &&
22936 (dt.Is(S16) || dt.Is(S32))) {
22937 if (cond.Is(al)) {
22938 EmitA32(0xf3800c40U | (encoded_dt.GetEncodingValue() << 20) |
22939 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
22940 return;
22941 }
22942 }
22943 }
22944 Delegate(kVqdmulh, &Assembler::vqdmulh, cond, dt, rd, rn, rm);
22945 }
22946
vqdmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)22947 void Assembler::vqdmull(
22948 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
22949 VIXL_ASSERT(AllowAssembler());
22950 CheckIT(cond);
22951 Dt_size_13 encoded_dt(dt);
22952 if (IsUsingT32()) {
22953 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
22954 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22955 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22956 EmitT32_32(0xef800d00U | (encoded_dt.GetEncodingValue() << 20) |
22957 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22958 AdvanceIT();
22959 return;
22960 }
22961 }
22962 } else {
22963 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
22964 if (encoded_dt.IsValid() && (dt.Is(S16) || dt.Is(S32))) {
22965 if (cond.Is(al)) {
22966 EmitA32(0xf2800d00U | (encoded_dt.GetEncodingValue() << 20) |
22967 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
22968 return;
22969 }
22970 }
22971 }
22972 Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
22973 }
22974
vqdmull(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegisterLane rm)22975 void Assembler::vqdmull(
22976 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
22977 VIXL_ASSERT(AllowAssembler());
22978 CheckIT(cond);
22979 Dt_size_13 encoded_dt(dt);
22980 if (IsUsingT32()) {
22981 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2
22982 if (encoded_dt.IsValid() &&
22983 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22984 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22985 (rm.GetLane() <= 1))) &&
22986 (dt.Is(S16) || dt.Is(S32))) {
22987 if (cond.Is(al) || AllowStronglyDiscouraged()) {
22988 EmitT32_32(0xef800b40U | (encoded_dt.GetEncodingValue() << 20) |
22989 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
22990 AdvanceIT();
22991 return;
22992 }
22993 }
22994 } else {
22995 // VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2
22996 if (encoded_dt.IsValid() &&
22997 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
22998 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
22999 (rm.GetLane() <= 1))) &&
23000 (dt.Is(S16) || dt.Is(S32))) {
23001 if (cond.Is(al)) {
23002 EmitA32(0xf2800b40U | (encoded_dt.GetEncodingValue() << 20) |
23003 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
23004 return;
23005 }
23006 }
23007 }
23008 Delegate(kVqdmull, &Assembler::vqdmull, cond, dt, rd, rn, rm);
23009 }
23010
vqmovn(Condition cond,DataType dt,DRegister rd,QRegister rm)23011 void Assembler::vqmovn(Condition cond,
23012 DataType dt,
23013 DRegister rd,
23014 QRegister rm) {
23015 VIXL_ASSERT(AllowAssembler());
23016 CheckIT(cond);
23017 Dt_op_size_3 encoded_dt(dt);
23018 if (IsUsingT32()) {
23019 // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
23020 if (encoded_dt.IsValid()) {
23021 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23022 EmitT32_32(0xffb20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23023 ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
23024 rd.Encode(22, 12) | rm.Encode(5, 0));
23025 AdvanceIT();
23026 return;
23027 }
23028 }
23029 } else {
23030 // VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
23031 if (encoded_dt.IsValid()) {
23032 if (cond.Is(al)) {
23033 EmitA32(0xf3b20280U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23034 ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
23035 rd.Encode(22, 12) | rm.Encode(5, 0));
23036 return;
23037 }
23038 }
23039 }
23040 Delegate(kVqmovn, &Assembler::vqmovn, cond, dt, rd, rm);
23041 }
23042
vqmovun(Condition cond,DataType dt,DRegister rd,QRegister rm)23043 void Assembler::vqmovun(Condition cond,
23044 DataType dt,
23045 DRegister rd,
23046 QRegister rm) {
23047 VIXL_ASSERT(AllowAssembler());
23048 CheckIT(cond);
23049 Dt_size_14 encoded_dt(dt);
23050 if (IsUsingT32()) {
23051 // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1
23052 if (encoded_dt.IsValid()) {
23053 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23054 EmitT32_32(0xffb20240U | (encoded_dt.GetEncodingValue() << 18) |
23055 rd.Encode(22, 12) | rm.Encode(5, 0));
23056 AdvanceIT();
23057 return;
23058 }
23059 }
23060 } else {
23061 // VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
23062 if (encoded_dt.IsValid()) {
23063 if (cond.Is(al)) {
23064 EmitA32(0xf3b20240U | (encoded_dt.GetEncodingValue() << 18) |
23065 rd.Encode(22, 12) | rm.Encode(5, 0));
23066 return;
23067 }
23068 }
23069 }
23070 Delegate(kVqmovun, &Assembler::vqmovun, cond, dt, rd, rm);
23071 }
23072
vqneg(Condition cond,DataType dt,DRegister rd,DRegister rm)23073 void Assembler::vqneg(Condition cond, DataType dt, DRegister rd, DRegister rm) {
23074 VIXL_ASSERT(AllowAssembler());
23075 CheckIT(cond);
23076 Dt_size_5 encoded_dt(dt);
23077 if (IsUsingT32()) {
23078 // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
23079 if (encoded_dt.IsValid()) {
23080 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23081 EmitT32_32(0xffb00780U | (encoded_dt.GetEncodingValue() << 18) |
23082 rd.Encode(22, 12) | rm.Encode(5, 0));
23083 AdvanceIT();
23084 return;
23085 }
23086 }
23087 } else {
23088 // VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
23089 if (encoded_dt.IsValid()) {
23090 if (cond.Is(al)) {
23091 EmitA32(0xf3b00780U | (encoded_dt.GetEncodingValue() << 18) |
23092 rd.Encode(22, 12) | rm.Encode(5, 0));
23093 return;
23094 }
23095 }
23096 }
23097 Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
23098 }
23099
vqneg(Condition cond,DataType dt,QRegister rd,QRegister rm)23100 void Assembler::vqneg(Condition cond, DataType dt, QRegister rd, QRegister rm) {
23101 VIXL_ASSERT(AllowAssembler());
23102 CheckIT(cond);
23103 Dt_size_5 encoded_dt(dt);
23104 if (IsUsingT32()) {
23105 // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
23106 if (encoded_dt.IsValid()) {
23107 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23108 EmitT32_32(0xffb007c0U | (encoded_dt.GetEncodingValue() << 18) |
23109 rd.Encode(22, 12) | rm.Encode(5, 0));
23110 AdvanceIT();
23111 return;
23112 }
23113 }
23114 } else {
23115 // VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
23116 if (encoded_dt.IsValid()) {
23117 if (cond.Is(al)) {
23118 EmitA32(0xf3b007c0U | (encoded_dt.GetEncodingValue() << 18) |
23119 rd.Encode(22, 12) | rm.Encode(5, 0));
23120 return;
23121 }
23122 }
23123 }
23124 Delegate(kVqneg, &Assembler::vqneg, cond, dt, rd, rm);
23125 }
23126
vqrdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)23127 void Assembler::vqrdmulh(
23128 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23129 VIXL_ASSERT(AllowAssembler());
23130 CheckIT(cond);
23131 Dt_size_13 encoded_dt(dt);
23132 if (IsUsingT32()) {
23133 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
23134 if (encoded_dt.IsValid()) {
23135 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23136 EmitT32_32(0xff000b00U | (encoded_dt.GetEncodingValue() << 20) |
23137 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23138 AdvanceIT();
23139 return;
23140 }
23141 }
23142 } else {
23143 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
23144 if (encoded_dt.IsValid()) {
23145 if (cond.Is(al)) {
23146 EmitA32(0xf3000b00U | (encoded_dt.GetEncodingValue() << 20) |
23147 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23148 return;
23149 }
23150 }
23151 }
23152 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
23153 }
23154
vqrdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)23155 void Assembler::vqrdmulh(
23156 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
23157 VIXL_ASSERT(AllowAssembler());
23158 CheckIT(cond);
23159 Dt_size_13 encoded_dt(dt);
23160 if (IsUsingT32()) {
23161 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
23162 if (encoded_dt.IsValid()) {
23163 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23164 EmitT32_32(0xff000b40U | (encoded_dt.GetEncodingValue() << 20) |
23165 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23166 AdvanceIT();
23167 return;
23168 }
23169 }
23170 } else {
23171 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
23172 if (encoded_dt.IsValid()) {
23173 if (cond.Is(al)) {
23174 EmitA32(0xf3000b40U | (encoded_dt.GetEncodingValue() << 20) |
23175 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23176 return;
23177 }
23178 }
23179 }
23180 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
23181 }
23182
vqrdmulh(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegisterLane rm)23183 void Assembler::vqrdmulh(
23184 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
23185 VIXL_ASSERT(AllowAssembler());
23186 CheckIT(cond);
23187 Dt_size_13 encoded_dt(dt);
23188 if (IsUsingT32()) {
23189 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2
23190 if (encoded_dt.IsValid() &&
23191 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
23192 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
23193 (rm.GetLane() <= 1))) &&
23194 (dt.Is(S16) || dt.Is(S32))) {
23195 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23196 EmitT32_32(0xef800d40U | (encoded_dt.GetEncodingValue() << 20) |
23197 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
23198 AdvanceIT();
23199 return;
23200 }
23201 }
23202 } else {
23203 // VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
23204 if (encoded_dt.IsValid() &&
23205 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
23206 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
23207 (rm.GetLane() <= 1))) &&
23208 (dt.Is(S16) || dt.Is(S32))) {
23209 if (cond.Is(al)) {
23210 EmitA32(0xf2800d40U | (encoded_dt.GetEncodingValue() << 20) |
23211 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
23212 return;
23213 }
23214 }
23215 }
23216 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
23217 }
23218
vqrdmulh(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegisterLane rm)23219 void Assembler::vqrdmulh(
23220 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
23221 VIXL_ASSERT(AllowAssembler());
23222 CheckIT(cond);
23223 Dt_size_13 encoded_dt(dt);
23224 if (IsUsingT32()) {
23225 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2
23226 if (encoded_dt.IsValid() &&
23227 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
23228 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
23229 (rm.GetLane() <= 1))) &&
23230 (dt.Is(S16) || dt.Is(S32))) {
23231 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23232 EmitT32_32(0xff800d40U | (encoded_dt.GetEncodingValue() << 20) |
23233 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
23234 AdvanceIT();
23235 return;
23236 }
23237 }
23238 } else {
23239 // VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
23240 if (encoded_dt.IsValid() &&
23241 (((dt.GetSize() == 16) && (rm.GetCode() <= 7) && (rm.GetLane() <= 3)) ||
23242 ((dt.GetSize() == 32) && (rm.GetCode() <= 15) &&
23243 (rm.GetLane() <= 1))) &&
23244 (dt.Is(S16) || dt.Is(S32))) {
23245 if (cond.Is(al)) {
23246 EmitA32(0xf3800d40U | (encoded_dt.GetEncodingValue() << 20) |
23247 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.EncodeX(dt, 5, 0));
23248 return;
23249 }
23250 }
23251 }
23252 Delegate(kVqrdmulh, &Assembler::vqrdmulh, cond, dt, rd, rn, rm);
23253 }
23254
vqrshl(Condition cond,DataType dt,DRegister rd,DRegister rm,DRegister rn)23255 void Assembler::vqrshl(
23256 Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
23257 VIXL_ASSERT(AllowAssembler());
23258 CheckIT(cond);
23259 Dt_U_size_3 encoded_dt(dt);
23260 if (IsUsingT32()) {
23261 // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
23262 if (encoded_dt.IsValid()) {
23263 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23264 EmitT32_32(0xef000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23265 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23266 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23267 AdvanceIT();
23268 return;
23269 }
23270 }
23271 } else {
23272 // VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
23273 if (encoded_dt.IsValid()) {
23274 if (cond.Is(al)) {
23275 EmitA32(0xf2000510U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23276 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23277 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23278 return;
23279 }
23280 }
23281 }
23282 Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
23283 }
23284
vqrshl(Condition cond,DataType dt,QRegister rd,QRegister rm,QRegister rn)23285 void Assembler::vqrshl(
23286 Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
23287 VIXL_ASSERT(AllowAssembler());
23288 CheckIT(cond);
23289 Dt_U_size_3 encoded_dt(dt);
23290 if (IsUsingT32()) {
23291 // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
23292 if (encoded_dt.IsValid()) {
23293 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23294 EmitT32_32(0xef000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23295 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23296 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23297 AdvanceIT();
23298 return;
23299 }
23300 }
23301 } else {
23302 // VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
23303 if (encoded_dt.IsValid()) {
23304 if (cond.Is(al)) {
23305 EmitA32(0xf2000550U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23306 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23307 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23308 return;
23309 }
23310 }
23311 }
23312 Delegate(kVqrshl, &Assembler::vqrshl, cond, dt, rd, rm, rn);
23313 }
23314
vqrshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)23315 void Assembler::vqrshrn(Condition cond,
23316 DataType dt,
23317 DRegister rd,
23318 QRegister rm,
23319 const QOperand& operand) {
23320 VIXL_ASSERT(AllowAssembler());
23321 CheckIT(cond);
23322 if (operand.IsImmediate()) {
23323 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23324 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23325 Dt_op_size_3 encoded_dt(dt);
23326 Dt_imm6_1 encoded_dt_2(dt);
23327 if (IsUsingT32()) {
23328 // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23329 if (encoded_dt.IsValid() && (imm == 0)) {
23330 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23331 EmitT32_32(0xffb20280U |
23332 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23333 ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
23334 rd.Encode(22, 12) | rm.Encode(5, 0));
23335 AdvanceIT();
23336 return;
23337 }
23338 }
23339 // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
23340 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23341 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23342 uint32_t imm6 = dt.GetSize() / 2 - imm;
23343 EmitT32_32(0xef800950U |
23344 (encoded_dt_2.GetTypeEncodingValue() << 28) |
23345 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
23346 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23347 AdvanceIT();
23348 return;
23349 }
23350 }
23351 } else {
23352 // VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23353 if (encoded_dt.IsValid() && (imm == 0)) {
23354 if (cond.Is(al)) {
23355 EmitA32(0xf3b20280U |
23356 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23357 ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
23358 rd.Encode(22, 12) | rm.Encode(5, 0));
23359 return;
23360 }
23361 }
23362 // VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
23363 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23364 if (cond.Is(al)) {
23365 uint32_t imm6 = dt.GetSize() / 2 - imm;
23366 EmitA32(0xf2800950U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
23367 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
23368 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23369 return;
23370 }
23371 }
23372 }
23373 }
23374 }
23375 Delegate(kVqrshrn, &Assembler::vqrshrn, cond, dt, rd, rm, operand);
23376 }
23377
vqrshrun(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)23378 void Assembler::vqrshrun(Condition cond,
23379 DataType dt,
23380 DRegister rd,
23381 QRegister rm,
23382 const QOperand& operand) {
23383 VIXL_ASSERT(AllowAssembler());
23384 CheckIT(cond);
23385 if (operand.IsImmediate()) {
23386 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23387 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23388 Dt_imm6_2 encoded_dt(dt);
23389 Dt_size_14 encoded_dt_2(dt);
23390 if (IsUsingT32()) {
23391 // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
23392 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23393 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23394 uint32_t imm6 = dt.GetSize() / 2 - imm;
23395 EmitT32_32(0xff800850U | (encoded_dt.GetTypeEncodingValue() << 28) |
23396 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23397 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23398 AdvanceIT();
23399 return;
23400 }
23401 }
23402 // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23403 if (encoded_dt_2.IsValid() && (imm == 0)) {
23404 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23405 EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
23406 rd.Encode(22, 12) | rm.Encode(5, 0));
23407 AdvanceIT();
23408 return;
23409 }
23410 }
23411 } else {
23412 // VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
23413 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23414 if (cond.Is(al)) {
23415 uint32_t imm6 = dt.GetSize() / 2 - imm;
23416 EmitA32(0xf3800850U | (encoded_dt.GetTypeEncodingValue() << 24) |
23417 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23418 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23419 return;
23420 }
23421 }
23422 // VQRSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23423 if (encoded_dt_2.IsValid() && (imm == 0)) {
23424 if (cond.Is(al)) {
23425 EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
23426 rd.Encode(22, 12) | rm.Encode(5, 0));
23427 return;
23428 }
23429 }
23430 }
23431 }
23432 }
23433 Delegate(kVqrshrun, &Assembler::vqrshrun, cond, dt, rd, rm, operand);
23434 }
23435
vqshl(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)23436 void Assembler::vqshl(Condition cond,
23437 DataType dt,
23438 DRegister rd,
23439 DRegister rm,
23440 const DOperand& operand) {
23441 VIXL_ASSERT(AllowAssembler());
23442 CheckIT(cond);
23443 if (operand.IsRegister()) {
23444 DRegister rn = operand.GetRegister();
23445 Dt_U_size_3 encoded_dt(dt);
23446 if (IsUsingT32()) {
23447 // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
23448 if (encoded_dt.IsValid()) {
23449 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23450 EmitT32_32(0xef000410U |
23451 ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23452 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23453 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23454 AdvanceIT();
23455 return;
23456 }
23457 }
23458 } else {
23459 // VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
23460 if (encoded_dt.IsValid()) {
23461 if (cond.Is(al)) {
23462 EmitA32(0xf2000410U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23463 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23464 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23465 return;
23466 }
23467 }
23468 }
23469 }
23470 if (operand.IsImmediate()) {
23471 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23472 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23473 Dt_L_imm6_1 encoded_dt(dt);
23474 if (IsUsingT32()) {
23475 // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23476 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23477 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23478 uint32_t imm6 = imm;
23479 EmitT32_32(0xef800710U | (encoded_dt.GetTypeEncodingValue() << 28) |
23480 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23481 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23482 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23483 AdvanceIT();
23484 return;
23485 }
23486 }
23487 } else {
23488 // VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23489 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23490 if (cond.Is(al)) {
23491 uint32_t imm6 = imm;
23492 EmitA32(0xf2800710U | (encoded_dt.GetTypeEncodingValue() << 24) |
23493 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23494 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23495 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23496 return;
23497 }
23498 }
23499 }
23500 }
23501 }
23502 Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
23503 }
23504
vqshl(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)23505 void Assembler::vqshl(Condition cond,
23506 DataType dt,
23507 QRegister rd,
23508 QRegister rm,
23509 const QOperand& operand) {
23510 VIXL_ASSERT(AllowAssembler());
23511 CheckIT(cond);
23512 if (operand.IsRegister()) {
23513 QRegister rn = operand.GetRegister();
23514 Dt_U_size_3 encoded_dt(dt);
23515 if (IsUsingT32()) {
23516 // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
23517 if (encoded_dt.IsValid()) {
23518 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23519 EmitT32_32(0xef000450U |
23520 ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23521 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23522 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23523 AdvanceIT();
23524 return;
23525 }
23526 }
23527 } else {
23528 // VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
23529 if (encoded_dt.IsValid()) {
23530 if (cond.Is(al)) {
23531 EmitA32(0xf2000450U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23532 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23533 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
23534 return;
23535 }
23536 }
23537 }
23538 }
23539 if (operand.IsImmediate()) {
23540 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23541 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23542 Dt_L_imm6_1 encoded_dt(dt);
23543 if (IsUsingT32()) {
23544 // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23545 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23546 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23547 uint32_t imm6 = imm;
23548 EmitT32_32(0xef800750U | (encoded_dt.GetTypeEncodingValue() << 28) |
23549 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23550 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23551 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23552 AdvanceIT();
23553 return;
23554 }
23555 }
23556 } else {
23557 // VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23558 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23559 if (cond.Is(al)) {
23560 uint32_t imm6 = imm;
23561 EmitA32(0xf2800750U | (encoded_dt.GetTypeEncodingValue() << 24) |
23562 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23563 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23564 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23565 return;
23566 }
23567 }
23568 }
23569 }
23570 }
23571 Delegate(kVqshl, &Assembler::vqshl, cond, dt, rd, rm, operand);
23572 }
23573
vqshlu(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)23574 void Assembler::vqshlu(Condition cond,
23575 DataType dt,
23576 DRegister rd,
23577 DRegister rm,
23578 const DOperand& operand) {
23579 VIXL_ASSERT(AllowAssembler());
23580 CheckIT(cond);
23581 if (operand.IsImmediate()) {
23582 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23583 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23584 Dt_L_imm6_2 encoded_dt(dt);
23585 if (IsUsingT32()) {
23586 // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
23587 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23588 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23589 uint32_t imm6 = imm;
23590 EmitT32_32(0xef800610U | (encoded_dt.GetTypeEncodingValue() << 28) |
23591 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23592 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23593 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23594 AdvanceIT();
23595 return;
23596 }
23597 }
23598 } else {
23599 // VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
23600 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23601 if (cond.Is(al)) {
23602 uint32_t imm6 = imm;
23603 EmitA32(0xf2800610U | (encoded_dt.GetTypeEncodingValue() << 24) |
23604 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23605 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23606 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23607 return;
23608 }
23609 }
23610 }
23611 }
23612 }
23613 Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
23614 }
23615
vqshlu(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)23616 void Assembler::vqshlu(Condition cond,
23617 DataType dt,
23618 QRegister rd,
23619 QRegister rm,
23620 const QOperand& operand) {
23621 VIXL_ASSERT(AllowAssembler());
23622 CheckIT(cond);
23623 if (operand.IsImmediate()) {
23624 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23625 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23626 Dt_L_imm6_2 encoded_dt(dt);
23627 if (IsUsingT32()) {
23628 // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
23629 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23630 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23631 uint32_t imm6 = imm;
23632 EmitT32_32(0xef800650U | (encoded_dt.GetTypeEncodingValue() << 28) |
23633 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23634 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23635 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23636 AdvanceIT();
23637 return;
23638 }
23639 }
23640 } else {
23641 // VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
23642 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
23643 if (cond.Is(al)) {
23644 uint32_t imm6 = imm;
23645 EmitA32(0xf2800650U | (encoded_dt.GetTypeEncodingValue() << 24) |
23646 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23647 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
23648 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23649 return;
23650 }
23651 }
23652 }
23653 }
23654 }
23655 Delegate(kVqshlu, &Assembler::vqshlu, cond, dt, rd, rm, operand);
23656 }
23657
vqshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)23658 void Assembler::vqshrn(Condition cond,
23659 DataType dt,
23660 DRegister rd,
23661 QRegister rm,
23662 const QOperand& operand) {
23663 VIXL_ASSERT(AllowAssembler());
23664 CheckIT(cond);
23665 if (operand.IsImmediate()) {
23666 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23667 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23668 Dt_op_size_3 encoded_dt(dt);
23669 Dt_imm6_1 encoded_dt_2(dt);
23670 if (IsUsingT32()) {
23671 // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23672 if (encoded_dt.IsValid() && (imm == 0)) {
23673 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23674 EmitT32_32(0xffb20280U |
23675 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23676 ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
23677 rd.Encode(22, 12) | rm.Encode(5, 0));
23678 AdvanceIT();
23679 return;
23680 }
23681 }
23682 // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
23683 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23684 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23685 uint32_t imm6 = dt.GetSize() / 2 - imm;
23686 EmitT32_32(0xef800910U |
23687 (encoded_dt_2.GetTypeEncodingValue() << 28) |
23688 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
23689 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23690 AdvanceIT();
23691 return;
23692 }
23693 }
23694 } else {
23695 // VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23696 if (encoded_dt.IsValid() && (imm == 0)) {
23697 if (cond.Is(al)) {
23698 EmitA32(0xf3b20280U |
23699 ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23700 ((encoded_dt.GetEncodingValue() & 0xc) << 4) |
23701 rd.Encode(22, 12) | rm.Encode(5, 0));
23702 return;
23703 }
23704 }
23705 // VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
23706 if (encoded_dt_2.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23707 if (cond.Is(al)) {
23708 uint32_t imm6 = dt.GetSize() / 2 - imm;
23709 EmitA32(0xf2800910U | (encoded_dt_2.GetTypeEncodingValue() << 24) |
23710 ((encoded_dt_2.GetEncodingValue() & 0x7) << 19) |
23711 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23712 return;
23713 }
23714 }
23715 }
23716 }
23717 }
23718 Delegate(kVqshrn, &Assembler::vqshrn, cond, dt, rd, rm, operand);
23719 }
23720
vqshrun(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)23721 void Assembler::vqshrun(Condition cond,
23722 DataType dt,
23723 DRegister rd,
23724 QRegister rm,
23725 const QOperand& operand) {
23726 VIXL_ASSERT(AllowAssembler());
23727 CheckIT(cond);
23728 if (operand.IsImmediate()) {
23729 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
23730 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
23731 Dt_imm6_2 encoded_dt(dt);
23732 Dt_size_14 encoded_dt_2(dt);
23733 if (IsUsingT32()) {
23734 // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1
23735 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23736 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23737 uint32_t imm6 = dt.GetSize() / 2 - imm;
23738 EmitT32_32(0xff800810U | (encoded_dt.GetTypeEncodingValue() << 28) |
23739 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23740 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23741 AdvanceIT();
23742 return;
23743 }
23744 }
23745 // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
23746 if (encoded_dt_2.IsValid() && (imm == 0)) {
23747 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23748 EmitT32_32(0xffb20240U | (encoded_dt_2.GetEncodingValue() << 18) |
23749 rd.Encode(22, 12) | rm.Encode(5, 0));
23750 AdvanceIT();
23751 return;
23752 }
23753 }
23754 } else {
23755 // VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1
23756 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
23757 if (cond.Is(al)) {
23758 uint32_t imm6 = dt.GetSize() / 2 - imm;
23759 EmitA32(0xf3800810U | (encoded_dt.GetTypeEncodingValue() << 24) |
23760 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
23761 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
23762 return;
23763 }
23764 }
23765 // VQSHRUN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
23766 if (encoded_dt_2.IsValid() && (imm == 0)) {
23767 if (cond.Is(al)) {
23768 EmitA32(0xf3b20240U | (encoded_dt_2.GetEncodingValue() << 18) |
23769 rd.Encode(22, 12) | rm.Encode(5, 0));
23770 return;
23771 }
23772 }
23773 }
23774 }
23775 }
23776 Delegate(kVqshrun, &Assembler::vqshrun, cond, dt, rd, rm, operand);
23777 }
23778
vqsub(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)23779 void Assembler::vqsub(
23780 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23781 VIXL_ASSERT(AllowAssembler());
23782 CheckIT(cond);
23783 Dt_U_size_3 encoded_dt(dt);
23784 if (IsUsingT32()) {
23785 // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
23786 if (encoded_dt.IsValid()) {
23787 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23788 EmitT32_32(0xef000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23789 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23790 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23791 AdvanceIT();
23792 return;
23793 }
23794 }
23795 } else {
23796 // VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
23797 if (encoded_dt.IsValid()) {
23798 if (cond.Is(al)) {
23799 EmitA32(0xf2000210U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23800 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23801 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23802 return;
23803 }
23804 }
23805 }
23806 Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
23807 }
23808
vqsub(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)23809 void Assembler::vqsub(
23810 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
23811 VIXL_ASSERT(AllowAssembler());
23812 CheckIT(cond);
23813 Dt_U_size_3 encoded_dt(dt);
23814 if (IsUsingT32()) {
23815 // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
23816 if (encoded_dt.IsValid()) {
23817 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23818 EmitT32_32(0xef000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23819 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
23820 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23821 AdvanceIT();
23822 return;
23823 }
23824 }
23825 } else {
23826 // VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
23827 if (encoded_dt.IsValid()) {
23828 if (cond.Is(al)) {
23829 EmitA32(0xf2000250U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
23830 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
23831 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23832 return;
23833 }
23834 }
23835 }
23836 Delegate(kVqsub, &Assembler::vqsub, cond, dt, rd, rn, rm);
23837 }
23838
vraddhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)23839 void Assembler::vraddhn(
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 // VRADDHN{<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(0xff800400U | (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 // VRADDHN{<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(0xf3800400U | (encoded_dt.GetEncodingValue() << 20) |
23859 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
23860 return;
23861 }
23862 }
23863 }
23864 Delegate(kVraddhn, &Assembler::vraddhn, cond, dt, rd, rn, rm);
23865 }
23866
vrecpe(Condition cond,DataType dt,DRegister rd,DRegister rm)23867 void Assembler::vrecpe(Condition cond,
23868 DataType dt,
23869 DRegister rd,
23870 DRegister rm) {
23871 VIXL_ASSERT(AllowAssembler());
23872 CheckIT(cond);
23873 Dt_F_size_4 encoded_dt(dt);
23874 if (IsUsingT32()) {
23875 // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
23876 if (encoded_dt.IsValid()) {
23877 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23878 EmitT32_32(0xffb30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23879 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23880 rd.Encode(22, 12) | rm.Encode(5, 0));
23881 AdvanceIT();
23882 return;
23883 }
23884 }
23885 } else {
23886 // VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
23887 if (encoded_dt.IsValid()) {
23888 if (cond.Is(al)) {
23889 EmitA32(0xf3b30400U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23890 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23891 rd.Encode(22, 12) | rm.Encode(5, 0));
23892 return;
23893 }
23894 }
23895 }
23896 Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
23897 }
23898
vrecpe(Condition cond,DataType dt,QRegister rd,QRegister rm)23899 void Assembler::vrecpe(Condition cond,
23900 DataType dt,
23901 QRegister rd,
23902 QRegister rm) {
23903 VIXL_ASSERT(AllowAssembler());
23904 CheckIT(cond);
23905 Dt_F_size_4 encoded_dt(dt);
23906 if (IsUsingT32()) {
23907 // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
23908 if (encoded_dt.IsValid()) {
23909 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23910 EmitT32_32(0xffb30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23911 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23912 rd.Encode(22, 12) | rm.Encode(5, 0));
23913 AdvanceIT();
23914 return;
23915 }
23916 }
23917 } else {
23918 // VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
23919 if (encoded_dt.IsValid()) {
23920 if (cond.Is(al)) {
23921 EmitA32(0xf3b30440U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
23922 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
23923 rd.Encode(22, 12) | rm.Encode(5, 0));
23924 return;
23925 }
23926 }
23927 }
23928 Delegate(kVrecpe, &Assembler::vrecpe, cond, dt, rd, rm);
23929 }
23930
vrecps(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)23931 void Assembler::vrecps(
23932 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
23933 VIXL_ASSERT(AllowAssembler());
23934 CheckIT(cond);
23935 if (IsUsingT32()) {
23936 // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
23937 if (dt.Is(F32)) {
23938 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23939 EmitT32_32(0xef000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23940 rm.Encode(5, 0));
23941 AdvanceIT();
23942 return;
23943 }
23944 }
23945 } else {
23946 // VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
23947 if (dt.Is(F32)) {
23948 if (cond.Is(al)) {
23949 EmitA32(0xf2000f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23950 rm.Encode(5, 0));
23951 return;
23952 }
23953 }
23954 }
23955 Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
23956 }
23957
vrecps(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)23958 void Assembler::vrecps(
23959 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
23960 VIXL_ASSERT(AllowAssembler());
23961 CheckIT(cond);
23962 if (IsUsingT32()) {
23963 // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
23964 if (dt.Is(F32)) {
23965 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23966 EmitT32_32(0xef000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23967 rm.Encode(5, 0));
23968 AdvanceIT();
23969 return;
23970 }
23971 }
23972 } else {
23973 // VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
23974 if (dt.Is(F32)) {
23975 if (cond.Is(al)) {
23976 EmitA32(0xf2000f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
23977 rm.Encode(5, 0));
23978 return;
23979 }
23980 }
23981 }
23982 Delegate(kVrecps, &Assembler::vrecps, cond, dt, rd, rn, rm);
23983 }
23984
vrev16(Condition cond,DataType dt,DRegister rd,DRegister rm)23985 void Assembler::vrev16(Condition cond,
23986 DataType dt,
23987 DRegister rd,
23988 DRegister rm) {
23989 VIXL_ASSERT(AllowAssembler());
23990 CheckIT(cond);
23991 Dt_size_1 encoded_dt(dt);
23992 if (IsUsingT32()) {
23993 // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
23994 if (encoded_dt.IsValid()) {
23995 if (cond.Is(al) || AllowStronglyDiscouraged()) {
23996 EmitT32_32(0xffb00100U | (encoded_dt.GetEncodingValue() << 18) |
23997 rd.Encode(22, 12) | rm.Encode(5, 0));
23998 AdvanceIT();
23999 return;
24000 }
24001 }
24002 } else {
24003 // VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
24004 if (encoded_dt.IsValid()) {
24005 if (cond.Is(al)) {
24006 EmitA32(0xf3b00100U | (encoded_dt.GetEncodingValue() << 18) |
24007 rd.Encode(22, 12) | rm.Encode(5, 0));
24008 return;
24009 }
24010 }
24011 }
24012 Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
24013 }
24014
vrev16(Condition cond,DataType dt,QRegister rd,QRegister rm)24015 void Assembler::vrev16(Condition cond,
24016 DataType dt,
24017 QRegister rd,
24018 QRegister rm) {
24019 VIXL_ASSERT(AllowAssembler());
24020 CheckIT(cond);
24021 Dt_size_1 encoded_dt(dt);
24022 if (IsUsingT32()) {
24023 // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
24024 if (encoded_dt.IsValid()) {
24025 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24026 EmitT32_32(0xffb00140U | (encoded_dt.GetEncodingValue() << 18) |
24027 rd.Encode(22, 12) | rm.Encode(5, 0));
24028 AdvanceIT();
24029 return;
24030 }
24031 }
24032 } else {
24033 // VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
24034 if (encoded_dt.IsValid()) {
24035 if (cond.Is(al)) {
24036 EmitA32(0xf3b00140U | (encoded_dt.GetEncodingValue() << 18) |
24037 rd.Encode(22, 12) | rm.Encode(5, 0));
24038 return;
24039 }
24040 }
24041 }
24042 Delegate(kVrev16, &Assembler::vrev16, cond, dt, rd, rm);
24043 }
24044
vrev32(Condition cond,DataType dt,DRegister rd,DRegister rm)24045 void Assembler::vrev32(Condition cond,
24046 DataType dt,
24047 DRegister rd,
24048 DRegister rm) {
24049 VIXL_ASSERT(AllowAssembler());
24050 CheckIT(cond);
24051 Dt_size_15 encoded_dt(dt);
24052 if (IsUsingT32()) {
24053 // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
24054 if (encoded_dt.IsValid()) {
24055 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24056 EmitT32_32(0xffb00080U | (encoded_dt.GetEncodingValue() << 18) |
24057 rd.Encode(22, 12) | rm.Encode(5, 0));
24058 AdvanceIT();
24059 return;
24060 }
24061 }
24062 } else {
24063 // VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
24064 if (encoded_dt.IsValid()) {
24065 if (cond.Is(al)) {
24066 EmitA32(0xf3b00080U | (encoded_dt.GetEncodingValue() << 18) |
24067 rd.Encode(22, 12) | rm.Encode(5, 0));
24068 return;
24069 }
24070 }
24071 }
24072 Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
24073 }
24074
vrev32(Condition cond,DataType dt,QRegister rd,QRegister rm)24075 void Assembler::vrev32(Condition cond,
24076 DataType dt,
24077 QRegister rd,
24078 QRegister rm) {
24079 VIXL_ASSERT(AllowAssembler());
24080 CheckIT(cond);
24081 Dt_size_15 encoded_dt(dt);
24082 if (IsUsingT32()) {
24083 // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
24084 if (encoded_dt.IsValid()) {
24085 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24086 EmitT32_32(0xffb000c0U | (encoded_dt.GetEncodingValue() << 18) |
24087 rd.Encode(22, 12) | rm.Encode(5, 0));
24088 AdvanceIT();
24089 return;
24090 }
24091 }
24092 } else {
24093 // VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
24094 if (encoded_dt.IsValid()) {
24095 if (cond.Is(al)) {
24096 EmitA32(0xf3b000c0U | (encoded_dt.GetEncodingValue() << 18) |
24097 rd.Encode(22, 12) | rm.Encode(5, 0));
24098 return;
24099 }
24100 }
24101 }
24102 Delegate(kVrev32, &Assembler::vrev32, cond, dt, rd, rm);
24103 }
24104
vrev64(Condition cond,DataType dt,DRegister rd,DRegister rm)24105 void Assembler::vrev64(Condition cond,
24106 DataType dt,
24107 DRegister rd,
24108 DRegister rm) {
24109 VIXL_ASSERT(AllowAssembler());
24110 CheckIT(cond);
24111 Dt_size_7 encoded_dt(dt);
24112 if (IsUsingT32()) {
24113 // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
24114 if (encoded_dt.IsValid()) {
24115 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24116 EmitT32_32(0xffb00000U | (encoded_dt.GetEncodingValue() << 18) |
24117 rd.Encode(22, 12) | rm.Encode(5, 0));
24118 AdvanceIT();
24119 return;
24120 }
24121 }
24122 } else {
24123 // VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
24124 if (encoded_dt.IsValid()) {
24125 if (cond.Is(al)) {
24126 EmitA32(0xf3b00000U | (encoded_dt.GetEncodingValue() << 18) |
24127 rd.Encode(22, 12) | rm.Encode(5, 0));
24128 return;
24129 }
24130 }
24131 }
24132 Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
24133 }
24134
vrev64(Condition cond,DataType dt,QRegister rd,QRegister rm)24135 void Assembler::vrev64(Condition cond,
24136 DataType dt,
24137 QRegister rd,
24138 QRegister rm) {
24139 VIXL_ASSERT(AllowAssembler());
24140 CheckIT(cond);
24141 Dt_size_7 encoded_dt(dt);
24142 if (IsUsingT32()) {
24143 // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
24144 if (encoded_dt.IsValid()) {
24145 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24146 EmitT32_32(0xffb00040U | (encoded_dt.GetEncodingValue() << 18) |
24147 rd.Encode(22, 12) | rm.Encode(5, 0));
24148 AdvanceIT();
24149 return;
24150 }
24151 }
24152 } else {
24153 // VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
24154 if (encoded_dt.IsValid()) {
24155 if (cond.Is(al)) {
24156 EmitA32(0xf3b00040U | (encoded_dt.GetEncodingValue() << 18) |
24157 rd.Encode(22, 12) | rm.Encode(5, 0));
24158 return;
24159 }
24160 }
24161 }
24162 Delegate(kVrev64, &Assembler::vrev64, cond, dt, rd, rm);
24163 }
24164
vrhadd(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)24165 void Assembler::vrhadd(
24166 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
24167 VIXL_ASSERT(AllowAssembler());
24168 CheckIT(cond);
24169 Dt_U_size_1 encoded_dt(dt);
24170 if (IsUsingT32()) {
24171 // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
24172 if (encoded_dt.IsValid()) {
24173 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24174 EmitT32_32(0xef000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24175 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24176 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
24177 AdvanceIT();
24178 return;
24179 }
24180 }
24181 } else {
24182 // VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
24183 if (encoded_dt.IsValid()) {
24184 if (cond.Is(al)) {
24185 EmitA32(0xf2000100U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24186 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24187 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
24188 return;
24189 }
24190 }
24191 }
24192 Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
24193 }
24194
vrhadd(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)24195 void Assembler::vrhadd(
24196 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
24197 VIXL_ASSERT(AllowAssembler());
24198 CheckIT(cond);
24199 Dt_U_size_1 encoded_dt(dt);
24200 if (IsUsingT32()) {
24201 // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
24202 if (encoded_dt.IsValid()) {
24203 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24204 EmitT32_32(0xef000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24205 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24206 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
24207 AdvanceIT();
24208 return;
24209 }
24210 }
24211 } else {
24212 // VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
24213 if (encoded_dt.IsValid()) {
24214 if (cond.Is(al)) {
24215 EmitA32(0xf2000140U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24216 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24217 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
24218 return;
24219 }
24220 }
24221 }
24222 Delegate(kVrhadd, &Assembler::vrhadd, cond, dt, rd, rn, rm);
24223 }
24224
vrinta(DataType dt,DRegister rd,DRegister rm)24225 void Assembler::vrinta(DataType dt, DRegister rd, DRegister rm) {
24226 VIXL_ASSERT(AllowAssembler());
24227 CheckIT(al);
24228 Dt_size_16 encoded_dt(dt);
24229 if (IsUsingT32()) {
24230 // VRINTA{<q>}.<dt> <Dd>, <Dm> ; T1
24231 if (encoded_dt.IsValid()) {
24232 EmitT32_32(0xffb20500U | (encoded_dt.GetEncodingValue() << 18) |
24233 rd.Encode(22, 12) | rm.Encode(5, 0));
24234 AdvanceIT();
24235 return;
24236 }
24237 // VRINTA{<q>}.F64 <Dd>, <Dm> ; T1
24238 if (dt.Is(F64)) {
24239 EmitT32_32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24240 AdvanceIT();
24241 return;
24242 }
24243 } else {
24244 // VRINTA{<q>}.<dt> <Dd>, <Dm> ; A1
24245 if (encoded_dt.IsValid()) {
24246 EmitA32(0xf3b20500U | (encoded_dt.GetEncodingValue() << 18) |
24247 rd.Encode(22, 12) | rm.Encode(5, 0));
24248 return;
24249 }
24250 // VRINTA{<q>}.F64 <Dd>, <Dm> ; A1
24251 if (dt.Is(F64)) {
24252 EmitA32(0xfeb80b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24253 return;
24254 }
24255 }
24256 Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm);
24257 }
24258
vrinta(DataType dt,QRegister rd,QRegister rm)24259 void Assembler::vrinta(DataType dt, QRegister rd, QRegister rm) {
24260 VIXL_ASSERT(AllowAssembler());
24261 CheckIT(al);
24262 Dt_size_16 encoded_dt(dt);
24263 if (IsUsingT32()) {
24264 // VRINTA{<q>}.<dt> <Qd>, <Qm> ; T1
24265 if (encoded_dt.IsValid()) {
24266 EmitT32_32(0xffb20540U | (encoded_dt.GetEncodingValue() << 18) |
24267 rd.Encode(22, 12) | rm.Encode(5, 0));
24268 AdvanceIT();
24269 return;
24270 }
24271 } else {
24272 // VRINTA{<q>}.<dt> <Qd>, <Qm> ; A1
24273 if (encoded_dt.IsValid()) {
24274 EmitA32(0xf3b20540U | (encoded_dt.GetEncodingValue() << 18) |
24275 rd.Encode(22, 12) | rm.Encode(5, 0));
24276 return;
24277 }
24278 }
24279 Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm);
24280 }
24281
vrinta(DataType dt,SRegister rd,SRegister rm)24282 void Assembler::vrinta(DataType dt, SRegister rd, SRegister rm) {
24283 VIXL_ASSERT(AllowAssembler());
24284 CheckIT(al);
24285 if (IsUsingT32()) {
24286 // VRINTA{<q>}.F32 <Sd>, <Sm> ; T1
24287 if (dt.Is(F32)) {
24288 EmitT32_32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24289 AdvanceIT();
24290 return;
24291 }
24292 } else {
24293 // VRINTA{<q>}.F32 <Sd>, <Sm> ; A1
24294 if (dt.Is(F32)) {
24295 EmitA32(0xfeb80a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24296 return;
24297 }
24298 }
24299 Delegate(kVrinta, &Assembler::vrinta, dt, rd, rm);
24300 }
24301
vrintm(DataType dt,DRegister rd,DRegister rm)24302 void Assembler::vrintm(DataType dt, DRegister rd, DRegister rm) {
24303 VIXL_ASSERT(AllowAssembler());
24304 CheckIT(al);
24305 Dt_size_16 encoded_dt(dt);
24306 if (IsUsingT32()) {
24307 // VRINTM{<q>}.<dt> <Dd>, <Dm> ; T1
24308 if (encoded_dt.IsValid()) {
24309 EmitT32_32(0xffb20680U | (encoded_dt.GetEncodingValue() << 18) |
24310 rd.Encode(22, 12) | rm.Encode(5, 0));
24311 AdvanceIT();
24312 return;
24313 }
24314 // VRINTM{<q>}.F64 <Dd>, <Dm> ; T1
24315 if (dt.Is(F64)) {
24316 EmitT32_32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24317 AdvanceIT();
24318 return;
24319 }
24320 } else {
24321 // VRINTM{<q>}.<dt> <Dd>, <Dm> ; A1
24322 if (encoded_dt.IsValid()) {
24323 EmitA32(0xf3b20680U | (encoded_dt.GetEncodingValue() << 18) |
24324 rd.Encode(22, 12) | rm.Encode(5, 0));
24325 return;
24326 }
24327 // VRINTM{<q>}.F64 <Dd>, <Dm> ; A1
24328 if (dt.Is(F64)) {
24329 EmitA32(0xfebb0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24330 return;
24331 }
24332 }
24333 Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm);
24334 }
24335
vrintm(DataType dt,QRegister rd,QRegister rm)24336 void Assembler::vrintm(DataType dt, QRegister rd, QRegister rm) {
24337 VIXL_ASSERT(AllowAssembler());
24338 CheckIT(al);
24339 Dt_size_16 encoded_dt(dt);
24340 if (IsUsingT32()) {
24341 // VRINTM{<q>}.<dt> <Qd>, <Qm> ; T1
24342 if (encoded_dt.IsValid()) {
24343 EmitT32_32(0xffb206c0U | (encoded_dt.GetEncodingValue() << 18) |
24344 rd.Encode(22, 12) | rm.Encode(5, 0));
24345 AdvanceIT();
24346 return;
24347 }
24348 } else {
24349 // VRINTM{<q>}.<dt> <Qd>, <Qm> ; A1
24350 if (encoded_dt.IsValid()) {
24351 EmitA32(0xf3b206c0U | (encoded_dt.GetEncodingValue() << 18) |
24352 rd.Encode(22, 12) | rm.Encode(5, 0));
24353 return;
24354 }
24355 }
24356 Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm);
24357 }
24358
vrintm(DataType dt,SRegister rd,SRegister rm)24359 void Assembler::vrintm(DataType dt, SRegister rd, SRegister rm) {
24360 VIXL_ASSERT(AllowAssembler());
24361 CheckIT(al);
24362 if (IsUsingT32()) {
24363 // VRINTM{<q>}.F32 <Sd>, <Sm> ; T1
24364 if (dt.Is(F32)) {
24365 EmitT32_32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24366 AdvanceIT();
24367 return;
24368 }
24369 } else {
24370 // VRINTM{<q>}.F32 <Sd>, <Sm> ; A1
24371 if (dt.Is(F32)) {
24372 EmitA32(0xfebb0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24373 return;
24374 }
24375 }
24376 Delegate(kVrintm, &Assembler::vrintm, dt, rd, rm);
24377 }
24378
vrintn(DataType dt,DRegister rd,DRegister rm)24379 void Assembler::vrintn(DataType dt, DRegister rd, DRegister rm) {
24380 VIXL_ASSERT(AllowAssembler());
24381 CheckIT(al);
24382 Dt_size_16 encoded_dt(dt);
24383 if (IsUsingT32()) {
24384 // VRINTN{<q>}.<dt> <Dd>, <Dm> ; T1
24385 if (encoded_dt.IsValid()) {
24386 EmitT32_32(0xffb20400U | (encoded_dt.GetEncodingValue() << 18) |
24387 rd.Encode(22, 12) | rm.Encode(5, 0));
24388 AdvanceIT();
24389 return;
24390 }
24391 // VRINTN{<q>}.F64 <Dd>, <Dm> ; T1
24392 if (dt.Is(F64)) {
24393 EmitT32_32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24394 AdvanceIT();
24395 return;
24396 }
24397 } else {
24398 // VRINTN{<q>}.<dt> <Dd>, <Dm> ; A1
24399 if (encoded_dt.IsValid()) {
24400 EmitA32(0xf3b20400U | (encoded_dt.GetEncodingValue() << 18) |
24401 rd.Encode(22, 12) | rm.Encode(5, 0));
24402 return;
24403 }
24404 // VRINTN{<q>}.F64 <Dd>, <Dm> ; A1
24405 if (dt.Is(F64)) {
24406 EmitA32(0xfeb90b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24407 return;
24408 }
24409 }
24410 Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm);
24411 }
24412
vrintn(DataType dt,QRegister rd,QRegister rm)24413 void Assembler::vrintn(DataType dt, QRegister rd, QRegister rm) {
24414 VIXL_ASSERT(AllowAssembler());
24415 CheckIT(al);
24416 Dt_size_16 encoded_dt(dt);
24417 if (IsUsingT32()) {
24418 // VRINTN{<q>}.<dt> <Qd>, <Qm> ; T1
24419 if (encoded_dt.IsValid()) {
24420 EmitT32_32(0xffb20440U | (encoded_dt.GetEncodingValue() << 18) |
24421 rd.Encode(22, 12) | rm.Encode(5, 0));
24422 AdvanceIT();
24423 return;
24424 }
24425 } else {
24426 // VRINTN{<q>}.<dt> <Qd>, <Qm> ; A1
24427 if (encoded_dt.IsValid()) {
24428 EmitA32(0xf3b20440U | (encoded_dt.GetEncodingValue() << 18) |
24429 rd.Encode(22, 12) | rm.Encode(5, 0));
24430 return;
24431 }
24432 }
24433 Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm);
24434 }
24435
vrintn(DataType dt,SRegister rd,SRegister rm)24436 void Assembler::vrintn(DataType dt, SRegister rd, SRegister rm) {
24437 VIXL_ASSERT(AllowAssembler());
24438 CheckIT(al);
24439 if (IsUsingT32()) {
24440 // VRINTN{<q>}.F32 <Sd>, <Sm> ; T1
24441 if (dt.Is(F32)) {
24442 EmitT32_32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24443 AdvanceIT();
24444 return;
24445 }
24446 } else {
24447 // VRINTN{<q>}.F32 <Sd>, <Sm> ; A1
24448 if (dt.Is(F32)) {
24449 EmitA32(0xfeb90a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24450 return;
24451 }
24452 }
24453 Delegate(kVrintn, &Assembler::vrintn, dt, rd, rm);
24454 }
24455
vrintp(DataType dt,DRegister rd,DRegister rm)24456 void Assembler::vrintp(DataType dt, DRegister rd, DRegister rm) {
24457 VIXL_ASSERT(AllowAssembler());
24458 CheckIT(al);
24459 Dt_size_16 encoded_dt(dt);
24460 if (IsUsingT32()) {
24461 // VRINTP{<q>}.<dt> <Dd>, <Dm> ; T1
24462 if (encoded_dt.IsValid()) {
24463 EmitT32_32(0xffb20780U | (encoded_dt.GetEncodingValue() << 18) |
24464 rd.Encode(22, 12) | rm.Encode(5, 0));
24465 AdvanceIT();
24466 return;
24467 }
24468 // VRINTP{<q>}.F64 <Dd>, <Dm> ; T1
24469 if (dt.Is(F64)) {
24470 EmitT32_32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24471 AdvanceIT();
24472 return;
24473 }
24474 } else {
24475 // VRINTP{<q>}.<dt> <Dd>, <Dm> ; A1
24476 if (encoded_dt.IsValid()) {
24477 EmitA32(0xf3b20780U | (encoded_dt.GetEncodingValue() << 18) |
24478 rd.Encode(22, 12) | rm.Encode(5, 0));
24479 return;
24480 }
24481 // VRINTP{<q>}.F64 <Dd>, <Dm> ; A1
24482 if (dt.Is(F64)) {
24483 EmitA32(0xfeba0b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24484 return;
24485 }
24486 }
24487 Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm);
24488 }
24489
vrintp(DataType dt,QRegister rd,QRegister rm)24490 void Assembler::vrintp(DataType dt, QRegister rd, QRegister rm) {
24491 VIXL_ASSERT(AllowAssembler());
24492 CheckIT(al);
24493 Dt_size_16 encoded_dt(dt);
24494 if (IsUsingT32()) {
24495 // VRINTP{<q>}.<dt> <Qd>, <Qm> ; T1
24496 if (encoded_dt.IsValid()) {
24497 EmitT32_32(0xffb207c0U | (encoded_dt.GetEncodingValue() << 18) |
24498 rd.Encode(22, 12) | rm.Encode(5, 0));
24499 AdvanceIT();
24500 return;
24501 }
24502 } else {
24503 // VRINTP{<q>}.<dt> <Qd>, <Qm> ; A1
24504 if (encoded_dt.IsValid()) {
24505 EmitA32(0xf3b207c0U | (encoded_dt.GetEncodingValue() << 18) |
24506 rd.Encode(22, 12) | rm.Encode(5, 0));
24507 return;
24508 }
24509 }
24510 Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm);
24511 }
24512
vrintp(DataType dt,SRegister rd,SRegister rm)24513 void Assembler::vrintp(DataType dt, SRegister rd, SRegister rm) {
24514 VIXL_ASSERT(AllowAssembler());
24515 CheckIT(al);
24516 if (IsUsingT32()) {
24517 // VRINTP{<q>}.F32 <Sd>, <Sm> ; T1
24518 if (dt.Is(F32)) {
24519 EmitT32_32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24520 AdvanceIT();
24521 return;
24522 }
24523 } else {
24524 // VRINTP{<q>}.F32 <Sd>, <Sm> ; A1
24525 if (dt.Is(F32)) {
24526 EmitA32(0xfeba0a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24527 return;
24528 }
24529 }
24530 Delegate(kVrintp, &Assembler::vrintp, dt, rd, rm);
24531 }
24532
vrintr(Condition cond,DataType dt,SRegister rd,SRegister rm)24533 void Assembler::vrintr(Condition cond,
24534 DataType dt,
24535 SRegister rd,
24536 SRegister rm) {
24537 VIXL_ASSERT(AllowAssembler());
24538 CheckIT(cond);
24539 if (IsUsingT32()) {
24540 // VRINTR{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
24541 if (dt.Is(F32)) {
24542 EmitT32_32(0xeeb60a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24543 AdvanceIT();
24544 return;
24545 }
24546 } else {
24547 // VRINTR{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
24548 if (dt.Is(F32) && cond.IsNotNever()) {
24549 EmitA32(0x0eb60a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24550 rm.Encode(5, 0));
24551 return;
24552 }
24553 }
24554 Delegate(kVrintr, &Assembler::vrintr, cond, dt, rd, rm);
24555 }
24556
vrintr(Condition cond,DataType dt,DRegister rd,DRegister rm)24557 void Assembler::vrintr(Condition cond,
24558 DataType dt,
24559 DRegister rd,
24560 DRegister rm) {
24561 VIXL_ASSERT(AllowAssembler());
24562 CheckIT(cond);
24563 if (IsUsingT32()) {
24564 // VRINTR{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
24565 if (dt.Is(F64)) {
24566 EmitT32_32(0xeeb60b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24567 AdvanceIT();
24568 return;
24569 }
24570 } else {
24571 // VRINTR{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
24572 if (dt.Is(F64) && cond.IsNotNever()) {
24573 EmitA32(0x0eb60b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24574 rm.Encode(5, 0));
24575 return;
24576 }
24577 }
24578 Delegate(kVrintr, &Assembler::vrintr, cond, dt, rd, rm);
24579 }
24580
vrintx(Condition cond,DataType dt,DRegister rd,DRegister rm)24581 void Assembler::vrintx(Condition cond,
24582 DataType dt,
24583 DRegister rd,
24584 DRegister rm) {
24585 VIXL_ASSERT(AllowAssembler());
24586 CheckIT(cond);
24587 Dt_size_16 encoded_dt(dt);
24588 if (IsUsingT32()) {
24589 // VRINTX{<q>}.<dt> <Dd>, <Dm> ; T1
24590 if (encoded_dt.IsValid()) {
24591 EmitT32_32(0xffb20480U | (encoded_dt.GetEncodingValue() << 18) |
24592 rd.Encode(22, 12) | rm.Encode(5, 0));
24593 AdvanceIT();
24594 return;
24595 }
24596 // VRINTX{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
24597 if (dt.Is(F64)) {
24598 EmitT32_32(0xeeb70b40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24599 AdvanceIT();
24600 return;
24601 }
24602 } else {
24603 // VRINTX{<q>}.<dt> <Dd>, <Dm> ; A1
24604 if (encoded_dt.IsValid()) {
24605 EmitA32(0xf3b20480U | (encoded_dt.GetEncodingValue() << 18) |
24606 rd.Encode(22, 12) | rm.Encode(5, 0));
24607 return;
24608 }
24609 // VRINTX{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
24610 if (dt.Is(F64) && cond.IsNotNever()) {
24611 EmitA32(0x0eb70b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24612 rm.Encode(5, 0));
24613 return;
24614 }
24615 }
24616 Delegate(kVrintx, &Assembler::vrintx, cond, dt, rd, rm);
24617 }
24618
vrintx(DataType dt,QRegister rd,QRegister rm)24619 void Assembler::vrintx(DataType dt, QRegister rd, QRegister rm) {
24620 VIXL_ASSERT(AllowAssembler());
24621 CheckIT(al);
24622 Dt_size_16 encoded_dt(dt);
24623 if (IsUsingT32()) {
24624 // VRINTX{<q>}.<dt> <Qd>, <Qm> ; T1
24625 if (encoded_dt.IsValid()) {
24626 EmitT32_32(0xffb204c0U | (encoded_dt.GetEncodingValue() << 18) |
24627 rd.Encode(22, 12) | rm.Encode(5, 0));
24628 AdvanceIT();
24629 return;
24630 }
24631 } else {
24632 // VRINTX{<q>}.<dt> <Qd>, <Qm> ; A1
24633 if (encoded_dt.IsValid()) {
24634 EmitA32(0xf3b204c0U | (encoded_dt.GetEncodingValue() << 18) |
24635 rd.Encode(22, 12) | rm.Encode(5, 0));
24636 return;
24637 }
24638 }
24639 Delegate(kVrintx, &Assembler::vrintx, dt, rd, rm);
24640 }
24641
vrintx(Condition cond,DataType dt,SRegister rd,SRegister rm)24642 void Assembler::vrintx(Condition cond,
24643 DataType dt,
24644 SRegister rd,
24645 SRegister rm) {
24646 VIXL_ASSERT(AllowAssembler());
24647 CheckIT(cond);
24648 if (IsUsingT32()) {
24649 // VRINTX{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
24650 if (dt.Is(F32)) {
24651 EmitT32_32(0xeeb70a40U | rd.Encode(22, 12) | rm.Encode(5, 0));
24652 AdvanceIT();
24653 return;
24654 }
24655 } else {
24656 // VRINTX{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
24657 if (dt.Is(F32) && cond.IsNotNever()) {
24658 EmitA32(0x0eb70a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24659 rm.Encode(5, 0));
24660 return;
24661 }
24662 }
24663 Delegate(kVrintx, &Assembler::vrintx, cond, dt, rd, rm);
24664 }
24665
vrintz(Condition cond,DataType dt,DRegister rd,DRegister rm)24666 void Assembler::vrintz(Condition cond,
24667 DataType dt,
24668 DRegister rd,
24669 DRegister rm) {
24670 VIXL_ASSERT(AllowAssembler());
24671 CheckIT(cond);
24672 Dt_size_16 encoded_dt(dt);
24673 if (IsUsingT32()) {
24674 // VRINTZ{<q>}.<dt> <Dd>, <Dm> ; T1
24675 if (encoded_dt.IsValid()) {
24676 EmitT32_32(0xffb20580U | (encoded_dt.GetEncodingValue() << 18) |
24677 rd.Encode(22, 12) | rm.Encode(5, 0));
24678 AdvanceIT();
24679 return;
24680 }
24681 // VRINTZ{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
24682 if (dt.Is(F64)) {
24683 EmitT32_32(0xeeb60bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
24684 AdvanceIT();
24685 return;
24686 }
24687 } else {
24688 // VRINTZ{<q>}.<dt> <Dd>, <Dm> ; A1
24689 if (encoded_dt.IsValid()) {
24690 EmitA32(0xf3b20580U | (encoded_dt.GetEncodingValue() << 18) |
24691 rd.Encode(22, 12) | rm.Encode(5, 0));
24692 return;
24693 }
24694 // VRINTZ{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
24695 if (dt.Is(F64) && cond.IsNotNever()) {
24696 EmitA32(0x0eb60bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24697 rm.Encode(5, 0));
24698 return;
24699 }
24700 }
24701 Delegate(kVrintz, &Assembler::vrintz, cond, dt, rd, rm);
24702 }
24703
vrintz(DataType dt,QRegister rd,QRegister rm)24704 void Assembler::vrintz(DataType dt, QRegister rd, QRegister rm) {
24705 VIXL_ASSERT(AllowAssembler());
24706 CheckIT(al);
24707 Dt_size_16 encoded_dt(dt);
24708 if (IsUsingT32()) {
24709 // VRINTZ{<q>}.<dt> <Qd>, <Qm> ; T1
24710 if (encoded_dt.IsValid()) {
24711 EmitT32_32(0xffb205c0U | (encoded_dt.GetEncodingValue() << 18) |
24712 rd.Encode(22, 12) | rm.Encode(5, 0));
24713 AdvanceIT();
24714 return;
24715 }
24716 } else {
24717 // VRINTZ{<q>}.<dt> <Qd>, <Qm> ; A1
24718 if (encoded_dt.IsValid()) {
24719 EmitA32(0xf3b205c0U | (encoded_dt.GetEncodingValue() << 18) |
24720 rd.Encode(22, 12) | rm.Encode(5, 0));
24721 return;
24722 }
24723 }
24724 Delegate(kVrintz, &Assembler::vrintz, dt, rd, rm);
24725 }
24726
vrintz(Condition cond,DataType dt,SRegister rd,SRegister rm)24727 void Assembler::vrintz(Condition cond,
24728 DataType dt,
24729 SRegister rd,
24730 SRegister rm) {
24731 VIXL_ASSERT(AllowAssembler());
24732 CheckIT(cond);
24733 if (IsUsingT32()) {
24734 // VRINTZ{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
24735 if (dt.Is(F32)) {
24736 EmitT32_32(0xeeb60ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
24737 AdvanceIT();
24738 return;
24739 }
24740 } else {
24741 // VRINTZ{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
24742 if (dt.Is(F32) && cond.IsNotNever()) {
24743 EmitA32(0x0eb60ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
24744 rm.Encode(5, 0));
24745 return;
24746 }
24747 }
24748 Delegate(kVrintz, &Assembler::vrintz, cond, dt, rd, rm);
24749 }
24750
vrshl(Condition cond,DataType dt,DRegister rd,DRegister rm,DRegister rn)24751 void Assembler::vrshl(
24752 Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
24753 VIXL_ASSERT(AllowAssembler());
24754 CheckIT(cond);
24755 Dt_U_size_3 encoded_dt(dt);
24756 if (IsUsingT32()) {
24757 // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
24758 if (encoded_dt.IsValid()) {
24759 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24760 EmitT32_32(0xef000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24761 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24762 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24763 AdvanceIT();
24764 return;
24765 }
24766 }
24767 } else {
24768 // VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
24769 if (encoded_dt.IsValid()) {
24770 if (cond.Is(al)) {
24771 EmitA32(0xf2000500U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24772 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24773 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24774 return;
24775 }
24776 }
24777 }
24778 Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
24779 }
24780
vrshl(Condition cond,DataType dt,QRegister rd,QRegister rm,QRegister rn)24781 void Assembler::vrshl(
24782 Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
24783 VIXL_ASSERT(AllowAssembler());
24784 CheckIT(cond);
24785 Dt_U_size_3 encoded_dt(dt);
24786 if (IsUsingT32()) {
24787 // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
24788 if (encoded_dt.IsValid()) {
24789 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24790 EmitT32_32(0xef000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24791 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
24792 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24793 AdvanceIT();
24794 return;
24795 }
24796 }
24797 } else {
24798 // VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
24799 if (encoded_dt.IsValid()) {
24800 if (cond.Is(al)) {
24801 EmitA32(0xf2000540U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
24802 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
24803 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
24804 return;
24805 }
24806 }
24807 }
24808 Delegate(kVrshl, &Assembler::vrshl, cond, dt, rd, rm, rn);
24809 }
24810
vrshr(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)24811 void Assembler::vrshr(Condition cond,
24812 DataType dt,
24813 DRegister rd,
24814 DRegister rm,
24815 const DOperand& operand) {
24816 VIXL_ASSERT(AllowAssembler());
24817 CheckIT(cond);
24818 if (operand.IsImmediate()) {
24819 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24820 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24821 Dt_L_imm6_1 encoded_dt(dt);
24822 if (IsUsingT32()) {
24823 // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
24824 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24825 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24826 uint32_t imm6 = dt.GetSize() - imm;
24827 EmitT32_32(0xef800210U | (encoded_dt.GetTypeEncodingValue() << 28) |
24828 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24829 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24830 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24831 AdvanceIT();
24832 return;
24833 }
24834 }
24835 // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
24836 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24837 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24838 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24839 rm.Encode(5, 0));
24840 AdvanceIT();
24841 return;
24842 }
24843 }
24844 } else {
24845 // VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
24846 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24847 if (cond.Is(al)) {
24848 uint32_t imm6 = dt.GetSize() - imm;
24849 EmitA32(0xf2800210U | (encoded_dt.GetTypeEncodingValue() << 24) |
24850 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24851 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24852 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24853 return;
24854 }
24855 }
24856 // VRSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
24857 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24858 if (cond.Is(al)) {
24859 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24860 rm.Encode(5, 0));
24861 return;
24862 }
24863 }
24864 }
24865 }
24866 }
24867 Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
24868 }
24869
vrshr(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)24870 void Assembler::vrshr(Condition cond,
24871 DataType dt,
24872 QRegister rd,
24873 QRegister rm,
24874 const QOperand& operand) {
24875 VIXL_ASSERT(AllowAssembler());
24876 CheckIT(cond);
24877 if (operand.IsImmediate()) {
24878 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24879 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24880 Dt_L_imm6_1 encoded_dt(dt);
24881 if (IsUsingT32()) {
24882 // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
24883 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24884 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24885 uint32_t imm6 = dt.GetSize() - imm;
24886 EmitT32_32(0xef800250U | (encoded_dt.GetTypeEncodingValue() << 28) |
24887 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24888 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24889 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24890 AdvanceIT();
24891 return;
24892 }
24893 }
24894 // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
24895 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24896 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24897 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24898 rm.Encode(5, 0));
24899 AdvanceIT();
24900 return;
24901 }
24902 }
24903 } else {
24904 // VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
24905 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
24906 if (cond.Is(al)) {
24907 uint32_t imm6 = dt.GetSize() - imm;
24908 EmitA32(0xf2800250U | (encoded_dt.GetTypeEncodingValue() << 24) |
24909 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24910 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
24911 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24912 return;
24913 }
24914 }
24915 // VRSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
24916 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
24917 if (cond.Is(al)) {
24918 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
24919 rm.Encode(5, 0));
24920 return;
24921 }
24922 }
24923 }
24924 }
24925 }
24926 Delegate(kVrshr, &Assembler::vrshr, cond, dt, rd, rm, operand);
24927 }
24928
vrshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)24929 void Assembler::vrshrn(Condition cond,
24930 DataType dt,
24931 DRegister rd,
24932 QRegister rm,
24933 const QOperand& operand) {
24934 VIXL_ASSERT(AllowAssembler());
24935 CheckIT(cond);
24936 if (operand.IsImmediate()) {
24937 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
24938 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
24939 Dt_imm6_3 encoded_dt(dt);
24940 Dt_size_3 encoded_dt_2(dt);
24941 if (IsUsingT32()) {
24942 // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
24943 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
24944 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24945 uint32_t imm6 = dt.GetSize() / 2 - imm;
24946 EmitT32_32(0xef800850U |
24947 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24948 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24949 AdvanceIT();
24950 return;
24951 }
24952 }
24953 // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
24954 if (encoded_dt_2.IsValid() && (imm == 0)) {
24955 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24956 EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
24957 rd.Encode(22, 12) | rm.Encode(5, 0));
24958 AdvanceIT();
24959 return;
24960 }
24961 }
24962 } else {
24963 // VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
24964 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
24965 if (cond.Is(al)) {
24966 uint32_t imm6 = dt.GetSize() / 2 - imm;
24967 EmitA32(0xf2800850U |
24968 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
24969 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
24970 return;
24971 }
24972 }
24973 // VRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
24974 if (encoded_dt_2.IsValid() && (imm == 0)) {
24975 if (cond.Is(al)) {
24976 EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
24977 rd.Encode(22, 12) | rm.Encode(5, 0));
24978 return;
24979 }
24980 }
24981 }
24982 }
24983 }
24984 Delegate(kVrshrn, &Assembler::vrshrn, cond, dt, rd, rm, operand);
24985 }
24986
vrsqrte(Condition cond,DataType dt,DRegister rd,DRegister rm)24987 void Assembler::vrsqrte(Condition cond,
24988 DataType dt,
24989 DRegister rd,
24990 DRegister rm) {
24991 VIXL_ASSERT(AllowAssembler());
24992 CheckIT(cond);
24993 Dt_F_size_4 encoded_dt(dt);
24994 if (IsUsingT32()) {
24995 // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
24996 if (encoded_dt.IsValid()) {
24997 if (cond.Is(al) || AllowStronglyDiscouraged()) {
24998 EmitT32_32(0xffb30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
24999 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
25000 rd.Encode(22, 12) | rm.Encode(5, 0));
25001 AdvanceIT();
25002 return;
25003 }
25004 }
25005 } else {
25006 // VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
25007 if (encoded_dt.IsValid()) {
25008 if (cond.Is(al)) {
25009 EmitA32(0xf3b30480U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
25010 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
25011 rd.Encode(22, 12) | rm.Encode(5, 0));
25012 return;
25013 }
25014 }
25015 }
25016 Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
25017 }
25018
vrsqrte(Condition cond,DataType dt,QRegister rd,QRegister rm)25019 void Assembler::vrsqrte(Condition cond,
25020 DataType dt,
25021 QRegister rd,
25022 QRegister rm) {
25023 VIXL_ASSERT(AllowAssembler());
25024 CheckIT(cond);
25025 Dt_F_size_4 encoded_dt(dt);
25026 if (IsUsingT32()) {
25027 // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
25028 if (encoded_dt.IsValid()) {
25029 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25030 EmitT32_32(0xffb304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
25031 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
25032 rd.Encode(22, 12) | rm.Encode(5, 0));
25033 AdvanceIT();
25034 return;
25035 }
25036 }
25037 } else {
25038 // VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
25039 if (encoded_dt.IsValid()) {
25040 if (cond.Is(al)) {
25041 EmitA32(0xf3b304c0U | ((encoded_dt.GetEncodingValue() & 0x3) << 18) |
25042 ((encoded_dt.GetEncodingValue() & 0x4) << 6) |
25043 rd.Encode(22, 12) | rm.Encode(5, 0));
25044 return;
25045 }
25046 }
25047 }
25048 Delegate(kVrsqrte, &Assembler::vrsqrte, cond, dt, rd, rm);
25049 }
25050
vrsqrts(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)25051 void Assembler::vrsqrts(
25052 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25053 VIXL_ASSERT(AllowAssembler());
25054 CheckIT(cond);
25055 if (IsUsingT32()) {
25056 // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
25057 if (dt.Is(F32)) {
25058 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25059 EmitT32_32(0xef200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25060 rm.Encode(5, 0));
25061 AdvanceIT();
25062 return;
25063 }
25064 }
25065 } else {
25066 // VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
25067 if (dt.Is(F32)) {
25068 if (cond.Is(al)) {
25069 EmitA32(0xf2200f10U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25070 rm.Encode(5, 0));
25071 return;
25072 }
25073 }
25074 }
25075 Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
25076 }
25077
vrsqrts(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)25078 void Assembler::vrsqrts(
25079 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
25080 VIXL_ASSERT(AllowAssembler());
25081 CheckIT(cond);
25082 if (IsUsingT32()) {
25083 // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
25084 if (dt.Is(F32)) {
25085 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25086 EmitT32_32(0xef200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25087 rm.Encode(5, 0));
25088 AdvanceIT();
25089 return;
25090 }
25091 }
25092 } else {
25093 // VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
25094 if (dt.Is(F32)) {
25095 if (cond.Is(al)) {
25096 EmitA32(0xf2200f50U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25097 rm.Encode(5, 0));
25098 return;
25099 }
25100 }
25101 }
25102 Delegate(kVrsqrts, &Assembler::vrsqrts, cond, dt, rd, rn, rm);
25103 }
25104
vrsra(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25105 void Assembler::vrsra(Condition cond,
25106 DataType dt,
25107 DRegister rd,
25108 DRegister rm,
25109 const DOperand& operand) {
25110 VIXL_ASSERT(AllowAssembler());
25111 CheckIT(cond);
25112 if (operand.IsImmediate()) {
25113 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25114 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25115 Dt_L_imm6_1 encoded_dt(dt);
25116 if (IsUsingT32()) {
25117 // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
25118 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25119 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25120 uint32_t imm6 = dt.GetSize() - imm;
25121 EmitT32_32(0xef800310U | (encoded_dt.GetTypeEncodingValue() << 28) |
25122 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25123 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25124 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25125 AdvanceIT();
25126 return;
25127 }
25128 }
25129 } else {
25130 // VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
25131 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25132 if (cond.Is(al)) {
25133 uint32_t imm6 = dt.GetSize() - imm;
25134 EmitA32(0xf2800310U | (encoded_dt.GetTypeEncodingValue() << 24) |
25135 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25136 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25137 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25138 return;
25139 }
25140 }
25141 }
25142 }
25143 }
25144 Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
25145 }
25146
vrsra(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)25147 void Assembler::vrsra(Condition cond,
25148 DataType dt,
25149 QRegister rd,
25150 QRegister rm,
25151 const QOperand& operand) {
25152 VIXL_ASSERT(AllowAssembler());
25153 CheckIT(cond);
25154 if (operand.IsImmediate()) {
25155 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25156 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25157 Dt_L_imm6_1 encoded_dt(dt);
25158 if (IsUsingT32()) {
25159 // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
25160 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25161 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25162 uint32_t imm6 = dt.GetSize() - imm;
25163 EmitT32_32(0xef800350U | (encoded_dt.GetTypeEncodingValue() << 28) |
25164 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25165 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25166 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25167 AdvanceIT();
25168 return;
25169 }
25170 }
25171 } else {
25172 // VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
25173 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25174 if (cond.Is(al)) {
25175 uint32_t imm6 = dt.GetSize() - imm;
25176 EmitA32(0xf2800350U | (encoded_dt.GetTypeEncodingValue() << 24) |
25177 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25178 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25179 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25180 return;
25181 }
25182 }
25183 }
25184 }
25185 }
25186 Delegate(kVrsra, &Assembler::vrsra, cond, dt, rd, rm, operand);
25187 }
25188
vrsubhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)25189 void Assembler::vrsubhn(
25190 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
25191 VIXL_ASSERT(AllowAssembler());
25192 CheckIT(cond);
25193 Dt_size_3 encoded_dt(dt);
25194 if (IsUsingT32()) {
25195 // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
25196 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
25197 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25198 EmitT32_32(0xff800600U | (encoded_dt.GetEncodingValue() << 20) |
25199 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25200 AdvanceIT();
25201 return;
25202 }
25203 }
25204 } else {
25205 // VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
25206 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
25207 if (cond.Is(al)) {
25208 EmitA32(0xf3800600U | (encoded_dt.GetEncodingValue() << 20) |
25209 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
25210 return;
25211 }
25212 }
25213 }
25214 Delegate(kVrsubhn, &Assembler::vrsubhn, cond, dt, rd, rn, rm);
25215 }
25216
vseleq(DataType dt,DRegister rd,DRegister rn,DRegister rm)25217 void Assembler::vseleq(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25218 VIXL_ASSERT(AllowAssembler());
25219 CheckIT(al);
25220 if (IsUsingT32()) {
25221 // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1
25222 if (OutsideITBlock() && dt.Is(F64)) {
25223 EmitT32_32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25224 rm.Encode(5, 0));
25225 AdvanceIT();
25226 return;
25227 }
25228 } else {
25229 // VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1
25230 if (dt.Is(F64)) {
25231 EmitA32(0xfe000b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25232 rm.Encode(5, 0));
25233 return;
25234 }
25235 }
25236 Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
25237 }
25238
vseleq(DataType dt,SRegister rd,SRegister rn,SRegister rm)25239 void Assembler::vseleq(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
25240 VIXL_ASSERT(AllowAssembler());
25241 CheckIT(al);
25242 if (IsUsingT32()) {
25243 // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1
25244 if (OutsideITBlock() && dt.Is(F32)) {
25245 EmitT32_32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25246 rm.Encode(5, 0));
25247 AdvanceIT();
25248 return;
25249 }
25250 } else {
25251 // VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1
25252 if (dt.Is(F32)) {
25253 EmitA32(0xfe000a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25254 rm.Encode(5, 0));
25255 return;
25256 }
25257 }
25258 Delegate(kVseleq, &Assembler::vseleq, dt, rd, rn, rm);
25259 }
25260
vselge(DataType dt,DRegister rd,DRegister rn,DRegister rm)25261 void Assembler::vselge(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25262 VIXL_ASSERT(AllowAssembler());
25263 CheckIT(al);
25264 if (IsUsingT32()) {
25265 // VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1
25266 if (OutsideITBlock() && dt.Is(F64)) {
25267 EmitT32_32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25268 rm.Encode(5, 0));
25269 AdvanceIT();
25270 return;
25271 }
25272 } else {
25273 // VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1
25274 if (dt.Is(F64)) {
25275 EmitA32(0xfe200b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25276 rm.Encode(5, 0));
25277 return;
25278 }
25279 }
25280 Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
25281 }
25282
vselge(DataType dt,SRegister rd,SRegister rn,SRegister rm)25283 void Assembler::vselge(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
25284 VIXL_ASSERT(AllowAssembler());
25285 CheckIT(al);
25286 if (IsUsingT32()) {
25287 // VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1
25288 if (OutsideITBlock() && dt.Is(F32)) {
25289 EmitT32_32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25290 rm.Encode(5, 0));
25291 AdvanceIT();
25292 return;
25293 }
25294 } else {
25295 // VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1
25296 if (dt.Is(F32)) {
25297 EmitA32(0xfe200a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25298 rm.Encode(5, 0));
25299 return;
25300 }
25301 }
25302 Delegate(kVselge, &Assembler::vselge, dt, rd, rn, rm);
25303 }
25304
vselgt(DataType dt,DRegister rd,DRegister rn,DRegister rm)25305 void Assembler::vselgt(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25306 VIXL_ASSERT(AllowAssembler());
25307 CheckIT(al);
25308 if (IsUsingT32()) {
25309 // VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1
25310 if (OutsideITBlock() && dt.Is(F64)) {
25311 EmitT32_32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25312 rm.Encode(5, 0));
25313 AdvanceIT();
25314 return;
25315 }
25316 } else {
25317 // VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1
25318 if (dt.Is(F64)) {
25319 EmitA32(0xfe300b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25320 rm.Encode(5, 0));
25321 return;
25322 }
25323 }
25324 Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
25325 }
25326
vselgt(DataType dt,SRegister rd,SRegister rn,SRegister rm)25327 void Assembler::vselgt(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
25328 VIXL_ASSERT(AllowAssembler());
25329 CheckIT(al);
25330 if (IsUsingT32()) {
25331 // VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1
25332 if (OutsideITBlock() && dt.Is(F32)) {
25333 EmitT32_32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25334 rm.Encode(5, 0));
25335 AdvanceIT();
25336 return;
25337 }
25338 } else {
25339 // VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1
25340 if (dt.Is(F32)) {
25341 EmitA32(0xfe300a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25342 rm.Encode(5, 0));
25343 return;
25344 }
25345 }
25346 Delegate(kVselgt, &Assembler::vselgt, dt, rd, rn, rm);
25347 }
25348
vselvs(DataType dt,DRegister rd,DRegister rn,DRegister rm)25349 void Assembler::vselvs(DataType dt, DRegister rd, DRegister rn, DRegister rm) {
25350 VIXL_ASSERT(AllowAssembler());
25351 CheckIT(al);
25352 if (IsUsingT32()) {
25353 // VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1
25354 if (OutsideITBlock() && dt.Is(F64)) {
25355 EmitT32_32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25356 rm.Encode(5, 0));
25357 AdvanceIT();
25358 return;
25359 }
25360 } else {
25361 // VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1
25362 if (dt.Is(F64)) {
25363 EmitA32(0xfe100b00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25364 rm.Encode(5, 0));
25365 return;
25366 }
25367 }
25368 Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
25369 }
25370
vselvs(DataType dt,SRegister rd,SRegister rn,SRegister rm)25371 void Assembler::vselvs(DataType dt, SRegister rd, SRegister rn, SRegister rm) {
25372 VIXL_ASSERT(AllowAssembler());
25373 CheckIT(al);
25374 if (IsUsingT32()) {
25375 // VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1
25376 if (OutsideITBlock() && dt.Is(F32)) {
25377 EmitT32_32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25378 rm.Encode(5, 0));
25379 AdvanceIT();
25380 return;
25381 }
25382 } else {
25383 // VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1
25384 if (dt.Is(F32)) {
25385 EmitA32(0xfe100a00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
25386 rm.Encode(5, 0));
25387 return;
25388 }
25389 }
25390 Delegate(kVselvs, &Assembler::vselvs, dt, rd, rn, rm);
25391 }
25392
vshl(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25393 void Assembler::vshl(Condition cond,
25394 DataType dt,
25395 DRegister rd,
25396 DRegister rm,
25397 const DOperand& operand) {
25398 VIXL_ASSERT(AllowAssembler());
25399 CheckIT(cond);
25400 if (operand.IsImmediate()) {
25401 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25402 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25403 Dt_L_imm6_3 encoded_dt(dt);
25404 if (IsUsingT32()) {
25405 // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1
25406 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25407 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25408 uint32_t imm6 = imm;
25409 EmitT32_32(0xef800510U |
25410 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25411 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25412 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25413 AdvanceIT();
25414 return;
25415 }
25416 }
25417 } else {
25418 // VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1
25419 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25420 if (cond.Is(al)) {
25421 uint32_t imm6 = imm;
25422 EmitA32(0xf2800510U |
25423 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25424 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25425 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25426 return;
25427 }
25428 }
25429 }
25430 }
25431 }
25432 if (operand.IsRegister()) {
25433 DRegister rn = operand.GetRegister();
25434 Dt_U_size_3 encoded_dt(dt);
25435 if (IsUsingT32()) {
25436 // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
25437 if (encoded_dt.IsValid()) {
25438 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25439 EmitT32_32(0xef000400U |
25440 ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25441 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
25442 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
25443 AdvanceIT();
25444 return;
25445 }
25446 }
25447 } else {
25448 // VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
25449 if (encoded_dt.IsValid()) {
25450 if (cond.Is(al)) {
25451 EmitA32(0xf2000400U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25452 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
25453 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
25454 return;
25455 }
25456 }
25457 }
25458 }
25459 Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
25460 }
25461
vshl(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)25462 void Assembler::vshl(Condition cond,
25463 DataType dt,
25464 QRegister rd,
25465 QRegister rm,
25466 const QOperand& operand) {
25467 VIXL_ASSERT(AllowAssembler());
25468 CheckIT(cond);
25469 if (operand.IsImmediate()) {
25470 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25471 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25472 Dt_L_imm6_3 encoded_dt(dt);
25473 if (IsUsingT32()) {
25474 // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1
25475 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25476 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25477 uint32_t imm6 = imm;
25478 EmitT32_32(0xef800550U |
25479 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25480 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25481 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25482 AdvanceIT();
25483 return;
25484 }
25485 }
25486 } else {
25487 // VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1
25488 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25489 if (cond.Is(al)) {
25490 uint32_t imm6 = imm;
25491 EmitA32(0xf2800550U |
25492 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25493 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25494 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25495 return;
25496 }
25497 }
25498 }
25499 }
25500 }
25501 if (operand.IsRegister()) {
25502 QRegister rn = operand.GetRegister();
25503 Dt_U_size_3 encoded_dt(dt);
25504 if (IsUsingT32()) {
25505 // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
25506 if (encoded_dt.IsValid()) {
25507 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25508 EmitT32_32(0xef000440U |
25509 ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25510 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
25511 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
25512 AdvanceIT();
25513 return;
25514 }
25515 }
25516 } else {
25517 // VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
25518 if (encoded_dt.IsValid()) {
25519 if (cond.Is(al)) {
25520 EmitA32(0xf2000440U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
25521 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
25522 rd.Encode(22, 12) | rm.Encode(5, 0) | rn.Encode(7, 16));
25523 return;
25524 }
25525 }
25526 }
25527 }
25528 Delegate(kVshl, &Assembler::vshl, cond, dt, rd, rm, operand);
25529 }
25530
vshll(Condition cond,DataType dt,QRegister rd,DRegister rm,const DOperand & operand)25531 void Assembler::vshll(Condition cond,
25532 DataType dt,
25533 QRegister rd,
25534 DRegister rm,
25535 const DOperand& operand) {
25536 VIXL_ASSERT(AllowAssembler());
25537 CheckIT(cond);
25538 if (operand.IsImmediate()) {
25539 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25540 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25541 Dt_imm6_4 encoded_dt(dt);
25542 Dt_size_17 encoded_dt_2(dt);
25543 if (IsUsingT32()) {
25544 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1
25545 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
25546 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25547 uint32_t imm6 = dt.GetSize() + imm;
25548 EmitT32_32(0xef800a10U | (encoded_dt.GetTypeEncodingValue() << 28) |
25549 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25550 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25551 AdvanceIT();
25552 return;
25553 }
25554 }
25555 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2
25556 if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
25557 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25558 EmitT32_32(0xffb20300U | (encoded_dt_2.GetEncodingValue() << 18) |
25559 rd.Encode(22, 12) | rm.Encode(5, 0));
25560 AdvanceIT();
25561 return;
25562 }
25563 }
25564 } else {
25565 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1
25566 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() - 1)) {
25567 if (cond.Is(al)) {
25568 uint32_t imm6 = dt.GetSize() + imm;
25569 EmitA32(0xf2800a10U | (encoded_dt.GetTypeEncodingValue() << 24) |
25570 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25571 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25572 return;
25573 }
25574 }
25575 // VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2
25576 if (encoded_dt_2.IsValid() && (imm == dt.GetSize())) {
25577 if (cond.Is(al)) {
25578 EmitA32(0xf3b20300U | (encoded_dt_2.GetEncodingValue() << 18) |
25579 rd.Encode(22, 12) | rm.Encode(5, 0));
25580 return;
25581 }
25582 }
25583 }
25584 }
25585 }
25586 Delegate(kVshll, &Assembler::vshll, cond, dt, rd, rm, operand);
25587 }
25588
vshr(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25589 void Assembler::vshr(Condition cond,
25590 DataType dt,
25591 DRegister rd,
25592 DRegister rm,
25593 const DOperand& operand) {
25594 VIXL_ASSERT(AllowAssembler());
25595 CheckIT(cond);
25596 if (operand.IsImmediate()) {
25597 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25598 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25599 Dt_L_imm6_1 encoded_dt(dt);
25600 if (IsUsingT32()) {
25601 // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
25602 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25603 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25604 uint32_t imm6 = dt.GetSize() - imm;
25605 EmitT32_32(0xef800010U | (encoded_dt.GetTypeEncodingValue() << 28) |
25606 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25607 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25608 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25609 AdvanceIT();
25610 return;
25611 }
25612 }
25613 // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; T1
25614 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
25615 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25616 EmitT32_32(0xef200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
25617 rm.Encode(5, 0));
25618 AdvanceIT();
25619 return;
25620 }
25621 }
25622 } else {
25623 // VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
25624 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25625 if (cond.Is(al)) {
25626 uint32_t imm6 = dt.GetSize() - imm;
25627 EmitA32(0xf2800010U | (encoded_dt.GetTypeEncodingValue() << 24) |
25628 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25629 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25630 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25631 return;
25632 }
25633 }
25634 // VSHR{<c>}{<q>}.<dt> <Dd>, <Dm>, #0 ; A1
25635 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
25636 if (cond.Is(al)) {
25637 EmitA32(0xf2200110U | rd.Encode(22, 12) | rm.Encode(7, 16) |
25638 rm.Encode(5, 0));
25639 return;
25640 }
25641 }
25642 }
25643 }
25644 }
25645 Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
25646 }
25647
vshr(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)25648 void Assembler::vshr(Condition cond,
25649 DataType dt,
25650 QRegister rd,
25651 QRegister rm,
25652 const QOperand& operand) {
25653 VIXL_ASSERT(AllowAssembler());
25654 CheckIT(cond);
25655 if (operand.IsImmediate()) {
25656 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25657 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25658 Dt_L_imm6_1 encoded_dt(dt);
25659 if (IsUsingT32()) {
25660 // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
25661 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25662 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25663 uint32_t imm6 = dt.GetSize() - imm;
25664 EmitT32_32(0xef800050U | (encoded_dt.GetTypeEncodingValue() << 28) |
25665 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25666 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25667 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25668 AdvanceIT();
25669 return;
25670 }
25671 }
25672 // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; T1
25673 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
25674 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25675 EmitT32_32(0xef200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
25676 rm.Encode(5, 0));
25677 AdvanceIT();
25678 return;
25679 }
25680 }
25681 } else {
25682 // VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
25683 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25684 if (cond.Is(al)) {
25685 uint32_t imm6 = dt.GetSize() - imm;
25686 EmitA32(0xf2800050U | (encoded_dt.GetTypeEncodingValue() << 24) |
25687 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25688 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25689 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25690 return;
25691 }
25692 }
25693 // VSHR{<c>}{<q>}.<dt> <Qd>, <Qm>, #0 ; A1
25694 if ((dt.Is(kDataTypeS) || dt.Is(kDataTypeU)) && (imm == 0)) {
25695 if (cond.Is(al)) {
25696 EmitA32(0xf2200150U | rd.Encode(22, 12) | rm.Encode(7, 16) |
25697 rm.Encode(5, 0));
25698 return;
25699 }
25700 }
25701 }
25702 }
25703 }
25704 Delegate(kVshr, &Assembler::vshr, cond, dt, rd, rm, operand);
25705 }
25706
vshrn(Condition cond,DataType dt,DRegister rd,QRegister rm,const QOperand & operand)25707 void Assembler::vshrn(Condition cond,
25708 DataType dt,
25709 DRegister rd,
25710 QRegister rm,
25711 const QOperand& operand) {
25712 VIXL_ASSERT(AllowAssembler());
25713 CheckIT(cond);
25714 if (operand.IsImmediate()) {
25715 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25716 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25717 Dt_imm6_3 encoded_dt(dt);
25718 Dt_size_3 encoded_dt_2(dt);
25719 if (IsUsingT32()) {
25720 // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1
25721 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
25722 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25723 uint32_t imm6 = dt.GetSize() / 2 - imm;
25724 EmitT32_32(0xef800810U |
25725 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25726 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25727 AdvanceIT();
25728 return;
25729 }
25730 }
25731 // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; T1
25732 if (encoded_dt_2.IsValid() && (imm == 0)) {
25733 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25734 EmitT32_32(0xffb20200U | (encoded_dt_2.GetEncodingValue() << 18) |
25735 rd.Encode(22, 12) | rm.Encode(5, 0));
25736 AdvanceIT();
25737 return;
25738 }
25739 }
25740 } else {
25741 // VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1
25742 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize() / 2)) {
25743 if (cond.Is(al)) {
25744 uint32_t imm6 = dt.GetSize() / 2 - imm;
25745 EmitA32(0xf2800810U |
25746 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25747 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25748 return;
25749 }
25750 }
25751 // VSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0 ; A1
25752 if (encoded_dt_2.IsValid() && (imm == 0)) {
25753 if (cond.Is(al)) {
25754 EmitA32(0xf3b20200U | (encoded_dt_2.GetEncodingValue() << 18) |
25755 rd.Encode(22, 12) | rm.Encode(5, 0));
25756 return;
25757 }
25758 }
25759 }
25760 }
25761 }
25762 Delegate(kVshrn, &Assembler::vshrn, cond, dt, rd, rm, operand);
25763 }
25764
vsli(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25765 void Assembler::vsli(Condition cond,
25766 DataType dt,
25767 DRegister rd,
25768 DRegister rm,
25769 const DOperand& operand) {
25770 VIXL_ASSERT(AllowAssembler());
25771 CheckIT(cond);
25772 if (operand.IsImmediate()) {
25773 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25774 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25775 Dt_L_imm6_4 encoded_dt(dt);
25776 if (IsUsingT32()) {
25777 // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
25778 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25779 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25780 uint32_t imm6 = imm;
25781 EmitT32_32(0xff800510U |
25782 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25783 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25784 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25785 AdvanceIT();
25786 return;
25787 }
25788 }
25789 } else {
25790 // VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
25791 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25792 if (cond.Is(al)) {
25793 uint32_t imm6 = imm;
25794 EmitA32(0xf3800510U |
25795 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25796 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25797 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25798 return;
25799 }
25800 }
25801 }
25802 }
25803 }
25804 Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
25805 }
25806
vsli(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)25807 void Assembler::vsli(Condition cond,
25808 DataType dt,
25809 QRegister rd,
25810 QRegister rm,
25811 const QOperand& operand) {
25812 VIXL_ASSERT(AllowAssembler());
25813 CheckIT(cond);
25814 if (operand.IsImmediate()) {
25815 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25816 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25817 Dt_L_imm6_4 encoded_dt(dt);
25818 if (IsUsingT32()) {
25819 // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
25820 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25821 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25822 uint32_t imm6 = imm;
25823 EmitT32_32(0xff800550U |
25824 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25825 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25826 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25827 AdvanceIT();
25828 return;
25829 }
25830 }
25831 } else {
25832 // VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
25833 if (encoded_dt.IsValid() && (imm <= dt.GetSize() - 1)) {
25834 if (cond.Is(al)) {
25835 uint32_t imm6 = imm;
25836 EmitA32(0xf3800550U |
25837 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25838 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25839 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25840 return;
25841 }
25842 }
25843 }
25844 }
25845 }
25846 Delegate(kVsli, &Assembler::vsli, cond, dt, rd, rm, operand);
25847 }
25848
vsqrt(Condition cond,DataType dt,SRegister rd,SRegister rm)25849 void Assembler::vsqrt(Condition cond, DataType dt, SRegister rd, SRegister rm) {
25850 VIXL_ASSERT(AllowAssembler());
25851 CheckIT(cond);
25852 if (IsUsingT32()) {
25853 // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
25854 if (dt.Is(F32)) {
25855 EmitT32_32(0xeeb10ac0U | rd.Encode(22, 12) | rm.Encode(5, 0));
25856 AdvanceIT();
25857 return;
25858 }
25859 } else {
25860 // VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
25861 if (dt.Is(F32) && cond.IsNotNever()) {
25862 EmitA32(0x0eb10ac0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25863 rm.Encode(5, 0));
25864 return;
25865 }
25866 }
25867 Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
25868 }
25869
vsqrt(Condition cond,DataType dt,DRegister rd,DRegister rm)25870 void Assembler::vsqrt(Condition cond, DataType dt, DRegister rd, DRegister rm) {
25871 VIXL_ASSERT(AllowAssembler());
25872 CheckIT(cond);
25873 if (IsUsingT32()) {
25874 // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
25875 if (dt.Is(F64)) {
25876 EmitT32_32(0xeeb10bc0U | rd.Encode(22, 12) | rm.Encode(5, 0));
25877 AdvanceIT();
25878 return;
25879 }
25880 } else {
25881 // VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
25882 if (dt.Is(F64) && cond.IsNotNever()) {
25883 EmitA32(0x0eb10bc0U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
25884 rm.Encode(5, 0));
25885 return;
25886 }
25887 }
25888 Delegate(kVsqrt, &Assembler::vsqrt, cond, dt, rd, rm);
25889 }
25890
vsra(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25891 void Assembler::vsra(Condition cond,
25892 DataType dt,
25893 DRegister rd,
25894 DRegister rm,
25895 const DOperand& operand) {
25896 VIXL_ASSERT(AllowAssembler());
25897 CheckIT(cond);
25898 if (operand.IsImmediate()) {
25899 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25900 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25901 Dt_L_imm6_1 encoded_dt(dt);
25902 if (IsUsingT32()) {
25903 // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1
25904 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25905 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25906 uint32_t imm6 = dt.GetSize() - imm;
25907 EmitT32_32(0xef800110U | (encoded_dt.GetTypeEncodingValue() << 28) |
25908 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25909 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25910 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25911 AdvanceIT();
25912 return;
25913 }
25914 }
25915 } else {
25916 // VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1
25917 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25918 if (cond.Is(al)) {
25919 uint32_t imm6 = dt.GetSize() - imm;
25920 EmitA32(0xf2800110U | (encoded_dt.GetTypeEncodingValue() << 24) |
25921 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25922 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25923 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25924 return;
25925 }
25926 }
25927 }
25928 }
25929 }
25930 Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
25931 }
25932
vsra(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)25933 void Assembler::vsra(Condition cond,
25934 DataType dt,
25935 QRegister rd,
25936 QRegister rm,
25937 const QOperand& operand) {
25938 VIXL_ASSERT(AllowAssembler());
25939 CheckIT(cond);
25940 if (operand.IsImmediate()) {
25941 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25942 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25943 Dt_L_imm6_1 encoded_dt(dt);
25944 if (IsUsingT32()) {
25945 // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1
25946 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25947 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25948 uint32_t imm6 = dt.GetSize() - imm;
25949 EmitT32_32(0xef800150U | (encoded_dt.GetTypeEncodingValue() << 28) |
25950 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25951 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25952 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25953 AdvanceIT();
25954 return;
25955 }
25956 }
25957 } else {
25958 // VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1
25959 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25960 if (cond.Is(al)) {
25961 uint32_t imm6 = dt.GetSize() - imm;
25962 EmitA32(0xf2800150U | (encoded_dt.GetTypeEncodingValue() << 24) |
25963 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25964 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25965 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25966 return;
25967 }
25968 }
25969 }
25970 }
25971 }
25972 Delegate(kVsra, &Assembler::vsra, cond, dt, rd, rm, operand);
25973 }
25974
vsri(Condition cond,DataType dt,DRegister rd,DRegister rm,const DOperand & operand)25975 void Assembler::vsri(Condition cond,
25976 DataType dt,
25977 DRegister rd,
25978 DRegister rm,
25979 const DOperand& operand) {
25980 VIXL_ASSERT(AllowAssembler());
25981 CheckIT(cond);
25982 if (operand.IsImmediate()) {
25983 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
25984 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
25985 Dt_L_imm6_4 encoded_dt(dt);
25986 if (IsUsingT32()) {
25987 // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1
25988 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
25989 if (cond.Is(al) || AllowStronglyDiscouraged()) {
25990 uint32_t imm6 = dt.GetSize() - imm;
25991 EmitT32_32(0xff800410U |
25992 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
25993 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
25994 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
25995 AdvanceIT();
25996 return;
25997 }
25998 }
25999 } else {
26000 // VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
26001 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
26002 if (cond.Is(al)) {
26003 uint32_t imm6 = dt.GetSize() - imm;
26004 EmitA32(0xf3800410U |
26005 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
26006 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
26007 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
26008 return;
26009 }
26010 }
26011 }
26012 }
26013 }
26014 Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
26015 }
26016
vsri(Condition cond,DataType dt,QRegister rd,QRegister rm,const QOperand & operand)26017 void Assembler::vsri(Condition cond,
26018 DataType dt,
26019 QRegister rd,
26020 QRegister rm,
26021 const QOperand& operand) {
26022 VIXL_ASSERT(AllowAssembler());
26023 CheckIT(cond);
26024 if (operand.IsImmediate()) {
26025 if (operand.GetNeonImmediate().CanConvert<uint32_t>()) {
26026 uint32_t imm = operand.GetNeonImmediate().GetImmediate<uint32_t>();
26027 Dt_L_imm6_4 encoded_dt(dt);
26028 if (IsUsingT32()) {
26029 // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1
26030 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
26031 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26032 uint32_t imm6 = dt.GetSize() - imm;
26033 EmitT32_32(0xff800450U |
26034 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
26035 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
26036 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
26037 AdvanceIT();
26038 return;
26039 }
26040 }
26041 } else {
26042 // VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
26043 if (encoded_dt.IsValid() && (imm >= 1) && (imm <= dt.GetSize())) {
26044 if (cond.Is(al)) {
26045 uint32_t imm6 = dt.GetSize() - imm;
26046 EmitA32(0xf3800450U |
26047 ((encoded_dt.GetEncodingValue() & 0x7) << 19) |
26048 ((encoded_dt.GetEncodingValue() & 0x8) << 4) |
26049 rd.Encode(22, 12) | rm.Encode(5, 0) | (imm6 << 16));
26050 return;
26051 }
26052 }
26053 }
26054 }
26055 }
26056 Delegate(kVsri, &Assembler::vsri, cond, dt, rd, rm, operand);
26057 }
26058
vst1(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)26059 void Assembler::vst1(Condition cond,
26060 DataType dt,
26061 const NeonRegisterList& nreglist,
26062 const AlignedMemOperand& operand) {
26063 VIXL_ASSERT(AllowAssembler());
26064 CheckIT(cond);
26065 if (operand.IsImmediateZero()) {
26066 Register rn = operand.GetBaseRegister();
26067 Alignment align = operand.GetAlignment();
26068 Dt_size_6 encoded_dt(dt);
26069 Dt_size_7 encoded_dt_2(dt);
26070 Align_align_5 encoded_align_1(align, nreglist);
26071 Align_index_align_1 encoded_align_2(align, nreglist, dt);
26072 if (IsUsingT32()) {
26073 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26074 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26075 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26076 operand.IsOffset() && encoded_align_1.IsValid() &&
26077 (!rn.IsPC() || AllowUnpredictable())) {
26078 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26079 const DRegister& first = nreglist.GetFirstDRegister();
26080 uint32_t len_encoding;
26081 switch (nreglist.GetLength()) {
26082 default:
26083 VIXL_UNREACHABLE_OR_FALLTHROUGH();
26084 case 1:
26085 len_encoding = 0x7;
26086 break;
26087 case 2:
26088 len_encoding = 0xa;
26089 break;
26090 case 3:
26091 len_encoding = 0x6;
26092 break;
26093 case 4:
26094 len_encoding = 0x2;
26095 break;
26096 }
26097 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
26098 (encoded_align_1.GetEncodingValue() << 4) |
26099 first.Encode(22, 12) | (len_encoding << 8) |
26100 (rn.GetCode() << 16));
26101 AdvanceIT();
26102 return;
26103 }
26104 }
26105 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26106 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26107 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26108 operand.IsPostIndex() && encoded_align_1.IsValid() &&
26109 (!rn.IsPC() || AllowUnpredictable())) {
26110 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26111 const DRegister& first = nreglist.GetFirstDRegister();
26112 uint32_t len_encoding;
26113 switch (nreglist.GetLength()) {
26114 default:
26115 VIXL_UNREACHABLE_OR_FALLTHROUGH();
26116 case 1:
26117 len_encoding = 0x7;
26118 break;
26119 case 2:
26120 len_encoding = 0xa;
26121 break;
26122 case 3:
26123 len_encoding = 0x6;
26124 break;
26125 case 4:
26126 len_encoding = 0x2;
26127 break;
26128 }
26129 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
26130 (encoded_align_1.GetEncodingValue() << 4) |
26131 first.Encode(22, 12) | (len_encoding << 8) |
26132 (rn.GetCode() << 16));
26133 AdvanceIT();
26134 return;
26135 }
26136 }
26137 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26138 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26139 (nreglist.GetLength() == 1) && operand.IsOffset() &&
26140 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
26141 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26142 const DRegister& first = nreglist.GetFirstDRegister();
26143 EmitT32_32(0xf980000fU | (encoded_dt_2.GetEncodingValue() << 10) |
26144 (encoded_align_2.GetEncodingValue() << 4) |
26145 first.Encode(22, 12) | (rn.GetCode() << 16));
26146 AdvanceIT();
26147 return;
26148 }
26149 }
26150 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26151 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26152 (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
26153 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
26154 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26155 const DRegister& first = nreglist.GetFirstDRegister();
26156 EmitT32_32(0xf980000dU | (encoded_dt_2.GetEncodingValue() << 10) |
26157 (encoded_align_2.GetEncodingValue() << 4) |
26158 first.Encode(22, 12) | (rn.GetCode() << 16));
26159 AdvanceIT();
26160 return;
26161 }
26162 }
26163 } else {
26164 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26165 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26166 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26167 operand.IsOffset() && encoded_align_1.IsValid() &&
26168 (!rn.IsPC() || AllowUnpredictable())) {
26169 if (cond.Is(al)) {
26170 const DRegister& first = nreglist.GetFirstDRegister();
26171 uint32_t len_encoding;
26172 switch (nreglist.GetLength()) {
26173 default:
26174 VIXL_UNREACHABLE_OR_FALLTHROUGH();
26175 case 1:
26176 len_encoding = 0x7;
26177 break;
26178 case 2:
26179 len_encoding = 0xa;
26180 break;
26181 case 3:
26182 len_encoding = 0x6;
26183 break;
26184 case 4:
26185 len_encoding = 0x2;
26186 break;
26187 }
26188 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
26189 (encoded_align_1.GetEncodingValue() << 4) |
26190 first.Encode(22, 12) | (len_encoding << 8) |
26191 (rn.GetCode() << 16));
26192 return;
26193 }
26194 }
26195 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26196 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26197 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26198 operand.IsPostIndex() && encoded_align_1.IsValid() &&
26199 (!rn.IsPC() || AllowUnpredictable())) {
26200 if (cond.Is(al)) {
26201 const DRegister& first = nreglist.GetFirstDRegister();
26202 uint32_t len_encoding;
26203 switch (nreglist.GetLength()) {
26204 default:
26205 VIXL_UNREACHABLE_OR_FALLTHROUGH();
26206 case 1:
26207 len_encoding = 0x7;
26208 break;
26209 case 2:
26210 len_encoding = 0xa;
26211 break;
26212 case 3:
26213 len_encoding = 0x6;
26214 break;
26215 case 4:
26216 len_encoding = 0x2;
26217 break;
26218 }
26219 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
26220 (encoded_align_1.GetEncodingValue() << 4) |
26221 first.Encode(22, 12) | (len_encoding << 8) |
26222 (rn.GetCode() << 16));
26223 return;
26224 }
26225 }
26226 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26227 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26228 (nreglist.GetLength() == 1) && operand.IsOffset() &&
26229 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
26230 if (cond.Is(al)) {
26231 const DRegister& first = nreglist.GetFirstDRegister();
26232 EmitA32(0xf480000fU | (encoded_dt_2.GetEncodingValue() << 10) |
26233 (encoded_align_2.GetEncodingValue() << 4) |
26234 first.Encode(22, 12) | (rn.GetCode() << 16));
26235 return;
26236 }
26237 }
26238 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26239 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26240 (nreglist.GetLength() == 1) && operand.IsPostIndex() &&
26241 encoded_align_2.IsValid() && (!rn.IsPC() || AllowUnpredictable())) {
26242 if (cond.Is(al)) {
26243 const DRegister& first = nreglist.GetFirstDRegister();
26244 EmitA32(0xf480000dU | (encoded_dt_2.GetEncodingValue() << 10) |
26245 (encoded_align_2.GetEncodingValue() << 4) |
26246 first.Encode(22, 12) | (rn.GetCode() << 16));
26247 return;
26248 }
26249 }
26250 }
26251 }
26252 if (operand.IsPlainRegister()) {
26253 Register rn = operand.GetBaseRegister();
26254 Alignment align = operand.GetAlignment();
26255 Register rm = operand.GetOffsetRegister();
26256 Dt_size_6 encoded_dt(dt);
26257 Dt_size_7 encoded_dt_2(dt);
26258 Align_align_5 encoded_align_1(align, nreglist);
26259 Align_index_align_1 encoded_align_2(align, nreglist, dt);
26260 if (IsUsingT32()) {
26261 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26262 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26263 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26264 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26265 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26266 const DRegister& first = nreglist.GetFirstDRegister();
26267 uint32_t len_encoding;
26268 switch (nreglist.GetLength()) {
26269 default:
26270 VIXL_UNREACHABLE_OR_FALLTHROUGH();
26271 case 1:
26272 len_encoding = 0x7;
26273 break;
26274 case 2:
26275 len_encoding = 0xa;
26276 break;
26277 case 3:
26278 len_encoding = 0x6;
26279 break;
26280 case 4:
26281 len_encoding = 0x2;
26282 break;
26283 }
26284 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
26285 (encoded_align_1.GetEncodingValue() << 4) |
26286 first.Encode(22, 12) | (len_encoding << 8) |
26287 (rn.GetCode() << 16) | rm.GetCode());
26288 AdvanceIT();
26289 return;
26290 }
26291 }
26292 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26293 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26294 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
26295 (!rn.IsPC() || AllowUnpredictable())) {
26296 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26297 const DRegister& first = nreglist.GetFirstDRegister();
26298 EmitT32_32(0xf9800000U | (encoded_dt_2.GetEncodingValue() << 10) |
26299 (encoded_align_2.GetEncodingValue() << 4) |
26300 first.Encode(22, 12) | (rn.GetCode() << 16) |
26301 rm.GetCode());
26302 AdvanceIT();
26303 return;
26304 }
26305 }
26306 } else {
26307 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
26308 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26309 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4) &&
26310 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26311 if (cond.Is(al)) {
26312 const DRegister& first = nreglist.GetFirstDRegister();
26313 uint32_t len_encoding;
26314 switch (nreglist.GetLength()) {
26315 default:
26316 VIXL_UNREACHABLE_OR_FALLTHROUGH();
26317 case 1:
26318 len_encoding = 0x7;
26319 break;
26320 case 2:
26321 len_encoding = 0xa;
26322 break;
26323 case 3:
26324 len_encoding = 0x6;
26325 break;
26326 case 4:
26327 len_encoding = 0x2;
26328 break;
26329 }
26330 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
26331 (encoded_align_1.GetEncodingValue() << 4) |
26332 first.Encode(22, 12) | (len_encoding << 8) |
26333 (rn.GetCode() << 16) | rm.GetCode());
26334 return;
26335 }
26336 }
26337 // VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
26338 if (encoded_dt_2.IsValid() && nreglist.IsTransferOneLane() &&
26339 (nreglist.GetLength() == 1) && !rm.IsPC() && !rm.IsSP() &&
26340 (!rn.IsPC() || AllowUnpredictable())) {
26341 if (cond.Is(al)) {
26342 const DRegister& first = nreglist.GetFirstDRegister();
26343 EmitA32(0xf4800000U | (encoded_dt_2.GetEncodingValue() << 10) |
26344 (encoded_align_2.GetEncodingValue() << 4) |
26345 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
26346 return;
26347 }
26348 }
26349 }
26350 }
26351 Delegate(kVst1, &Assembler::vst1, cond, dt, nreglist, operand);
26352 }
26353
vst2(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)26354 void Assembler::vst2(Condition cond,
26355 DataType dt,
26356 const NeonRegisterList& nreglist,
26357 const AlignedMemOperand& operand) {
26358 VIXL_ASSERT(AllowAssembler());
26359 CheckIT(cond);
26360 if (operand.IsImmediateZero()) {
26361 Register rn = operand.GetBaseRegister();
26362 Alignment align = operand.GetAlignment();
26363 Dt_size_7 encoded_dt(dt);
26364 Align_align_2 encoded_align_1(align, nreglist);
26365 Align_index_align_2 encoded_align_2(align, nreglist, dt);
26366 if (IsUsingT32()) {
26367 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26368 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26369 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26370 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26371 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26372 operand.IsOffset() && encoded_align_1.IsValid() &&
26373 (!rn.IsPC() || AllowUnpredictable())) {
26374 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26375 const DRegister& first = nreglist.GetFirstDRegister();
26376 uint32_t len_encoding;
26377 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26378 len_encoding = 0x8;
26379 }
26380 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26381 len_encoding = 0x9;
26382 }
26383 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26384 len_encoding = 0x3;
26385 }
26386 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
26387 (encoded_align_1.GetEncodingValue() << 4) |
26388 first.Encode(22, 12) | (len_encoding << 8) |
26389 (rn.GetCode() << 16));
26390 AdvanceIT();
26391 return;
26392 }
26393 }
26394 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26395 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26396 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26397 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26398 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26399 operand.IsPostIndex() && encoded_align_1.IsValid() &&
26400 (!rn.IsPC() || AllowUnpredictable())) {
26401 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26402 const DRegister& first = nreglist.GetFirstDRegister();
26403 uint32_t len_encoding;
26404 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26405 len_encoding = 0x8;
26406 }
26407 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26408 len_encoding = 0x9;
26409 }
26410 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26411 len_encoding = 0x3;
26412 }
26413 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
26414 (encoded_align_1.GetEncodingValue() << 4) |
26415 first.Encode(22, 12) | (len_encoding << 8) |
26416 (rn.GetCode() << 16));
26417 AdvanceIT();
26418 return;
26419 }
26420 }
26421 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26422 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26423 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26424 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26425 operand.IsOffset() && encoded_align_2.IsValid() &&
26426 (!rn.IsPC() || AllowUnpredictable())) {
26427 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26428 const DRegister& first = nreglist.GetFirstDRegister();
26429 EmitT32_32(0xf980010fU | (encoded_dt.GetEncodingValue() << 10) |
26430 (encoded_align_2.GetEncodingValue() << 4) |
26431 first.Encode(22, 12) | (rn.GetCode() << 16));
26432 AdvanceIT();
26433 return;
26434 }
26435 }
26436 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26437 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26438 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26439 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26440 operand.IsPostIndex() && encoded_align_2.IsValid() &&
26441 (!rn.IsPC() || AllowUnpredictable())) {
26442 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26443 const DRegister& first = nreglist.GetFirstDRegister();
26444 EmitT32_32(0xf980010dU | (encoded_dt.GetEncodingValue() << 10) |
26445 (encoded_align_2.GetEncodingValue() << 4) |
26446 first.Encode(22, 12) | (rn.GetCode() << 16));
26447 AdvanceIT();
26448 return;
26449 }
26450 }
26451 } else {
26452 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26453 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26454 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26455 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26456 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26457 operand.IsOffset() && encoded_align_1.IsValid() &&
26458 (!rn.IsPC() || AllowUnpredictable())) {
26459 if (cond.Is(al)) {
26460 const DRegister& first = nreglist.GetFirstDRegister();
26461 uint32_t len_encoding;
26462 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26463 len_encoding = 0x8;
26464 }
26465 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26466 len_encoding = 0x9;
26467 }
26468 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26469 len_encoding = 0x3;
26470 }
26471 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
26472 (encoded_align_1.GetEncodingValue() << 4) |
26473 first.Encode(22, 12) | (len_encoding << 8) |
26474 (rn.GetCode() << 16));
26475 return;
26476 }
26477 }
26478 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26479 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26480 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26481 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26482 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26483 operand.IsPostIndex() && encoded_align_1.IsValid() &&
26484 (!rn.IsPC() || AllowUnpredictable())) {
26485 if (cond.Is(al)) {
26486 const DRegister& first = nreglist.GetFirstDRegister();
26487 uint32_t len_encoding;
26488 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26489 len_encoding = 0x8;
26490 }
26491 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26492 len_encoding = 0x9;
26493 }
26494 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26495 len_encoding = 0x3;
26496 }
26497 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
26498 (encoded_align_1.GetEncodingValue() << 4) |
26499 first.Encode(22, 12) | (len_encoding << 8) |
26500 (rn.GetCode() << 16));
26501 return;
26502 }
26503 }
26504 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26505 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26506 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26507 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26508 operand.IsOffset() && encoded_align_2.IsValid() &&
26509 (!rn.IsPC() || AllowUnpredictable())) {
26510 if (cond.Is(al)) {
26511 const DRegister& first = nreglist.GetFirstDRegister();
26512 EmitA32(0xf480010fU | (encoded_dt.GetEncodingValue() << 10) |
26513 (encoded_align_2.GetEncodingValue() << 4) |
26514 first.Encode(22, 12) | (rn.GetCode() << 16));
26515 return;
26516 }
26517 }
26518 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26519 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26520 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26521 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26522 operand.IsPostIndex() && encoded_align_2.IsValid() &&
26523 (!rn.IsPC() || AllowUnpredictable())) {
26524 if (cond.Is(al)) {
26525 const DRegister& first = nreglist.GetFirstDRegister();
26526 EmitA32(0xf480010dU | (encoded_dt.GetEncodingValue() << 10) |
26527 (encoded_align_2.GetEncodingValue() << 4) |
26528 first.Encode(22, 12) | (rn.GetCode() << 16));
26529 return;
26530 }
26531 }
26532 }
26533 }
26534 if (operand.IsPlainRegister()) {
26535 Register rn = operand.GetBaseRegister();
26536 Alignment align = operand.GetAlignment();
26537 Register rm = operand.GetOffsetRegister();
26538 Dt_size_7 encoded_dt(dt);
26539 Align_align_2 encoded_align_1(align, nreglist);
26540 Align_index_align_2 encoded_align_2(align, nreglist, dt);
26541 if (IsUsingT32()) {
26542 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26543 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26544 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26545 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26546 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26547 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26548 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26549 const DRegister& first = nreglist.GetFirstDRegister();
26550 uint32_t len_encoding;
26551 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26552 len_encoding = 0x8;
26553 }
26554 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26555 len_encoding = 0x9;
26556 }
26557 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26558 len_encoding = 0x3;
26559 }
26560 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
26561 (encoded_align_1.GetEncodingValue() << 4) |
26562 first.Encode(22, 12) | (len_encoding << 8) |
26563 (rn.GetCode() << 16) | rm.GetCode());
26564 AdvanceIT();
26565 return;
26566 }
26567 }
26568 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26569 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26570 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26571 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26572 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26573 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26574 const DRegister& first = nreglist.GetFirstDRegister();
26575 EmitT32_32(0xf9800100U | (encoded_dt.GetEncodingValue() << 10) |
26576 (encoded_align_2.GetEncodingValue() << 4) |
26577 first.Encode(22, 12) | (rn.GetCode() << 16) |
26578 rm.GetCode());
26579 AdvanceIT();
26580 return;
26581 }
26582 }
26583 } else {
26584 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
26585 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26586 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26587 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) ||
26588 (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4))) &&
26589 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26590 if (cond.Is(al)) {
26591 const DRegister& first = nreglist.GetFirstDRegister();
26592 uint32_t len_encoding;
26593 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) {
26594 len_encoding = 0x8;
26595 }
26596 if (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2)) {
26597 len_encoding = 0x9;
26598 }
26599 if (nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) {
26600 len_encoding = 0x3;
26601 }
26602 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
26603 (encoded_align_1.GetEncodingValue() << 4) |
26604 first.Encode(22, 12) | (len_encoding << 8) |
26605 (rn.GetCode() << 16) | rm.GetCode());
26606 return;
26607 }
26608 }
26609 // VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
26610 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26611 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 2)) ||
26612 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 2))) &&
26613 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26614 if (cond.Is(al)) {
26615 const DRegister& first = nreglist.GetFirstDRegister();
26616 EmitA32(0xf4800100U | (encoded_dt.GetEncodingValue() << 10) |
26617 (encoded_align_2.GetEncodingValue() << 4) |
26618 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
26619 return;
26620 }
26621 }
26622 }
26623 }
26624 Delegate(kVst2, &Assembler::vst2, cond, dt, nreglist, operand);
26625 }
26626
vst3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)26627 void Assembler::vst3(Condition cond,
26628 DataType dt,
26629 const NeonRegisterList& nreglist,
26630 const AlignedMemOperand& operand) {
26631 VIXL_ASSERT(AllowAssembler());
26632 CheckIT(cond);
26633 if (operand.IsImmediateZero()) {
26634 Register rn = operand.GetBaseRegister();
26635 Alignment align = operand.GetAlignment();
26636 Dt_size_7 encoded_dt(dt);
26637 Align_align_3 encoded_align_1(align);
26638 if (IsUsingT32()) {
26639 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26640 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26641 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26642 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26643 operand.IsOffset() && encoded_align_1.IsValid() &&
26644 (!rn.IsPC() || AllowUnpredictable())) {
26645 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26646 const DRegister& first = nreglist.GetFirstDRegister();
26647 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26648 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
26649 (encoded_align_1.GetEncodingValue() << 4) |
26650 first.Encode(22, 12) | (len_encoding << 8) |
26651 (rn.GetCode() << 16));
26652 AdvanceIT();
26653 return;
26654 }
26655 }
26656 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26657 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26658 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26659 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26660 operand.IsPostIndex() && encoded_align_1.IsValid() &&
26661 (!rn.IsPC() || AllowUnpredictable())) {
26662 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26663 const DRegister& first = nreglist.GetFirstDRegister();
26664 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26665 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
26666 (encoded_align_1.GetEncodingValue() << 4) |
26667 first.Encode(22, 12) | (len_encoding << 8) |
26668 (rn.GetCode() << 16));
26669 AdvanceIT();
26670 return;
26671 }
26672 }
26673 } else {
26674 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26675 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26676 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26677 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26678 operand.IsOffset() && encoded_align_1.IsValid() &&
26679 (!rn.IsPC() || AllowUnpredictable())) {
26680 if (cond.Is(al)) {
26681 const DRegister& first = nreglist.GetFirstDRegister();
26682 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26683 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
26684 (encoded_align_1.GetEncodingValue() << 4) |
26685 first.Encode(22, 12) | (len_encoding << 8) |
26686 (rn.GetCode() << 16));
26687 return;
26688 }
26689 }
26690 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26691 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26692 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26693 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26694 operand.IsPostIndex() && encoded_align_1.IsValid() &&
26695 (!rn.IsPC() || AllowUnpredictable())) {
26696 if (cond.Is(al)) {
26697 const DRegister& first = nreglist.GetFirstDRegister();
26698 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26699 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
26700 (encoded_align_1.GetEncodingValue() << 4) |
26701 first.Encode(22, 12) | (len_encoding << 8) |
26702 (rn.GetCode() << 16));
26703 return;
26704 }
26705 }
26706 }
26707 }
26708 if (operand.IsPlainRegister()) {
26709 Register rn = operand.GetBaseRegister();
26710 Alignment align = operand.GetAlignment();
26711 Register rm = operand.GetOffsetRegister();
26712 Dt_size_7 encoded_dt(dt);
26713 Align_align_3 encoded_align_1(align);
26714 if (IsUsingT32()) {
26715 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
26716 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26717 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26718 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26719 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26720 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26721 const DRegister& first = nreglist.GetFirstDRegister();
26722 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26723 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
26724 (encoded_align_1.GetEncodingValue() << 4) |
26725 first.Encode(22, 12) | (len_encoding << 8) |
26726 (rn.GetCode() << 16) | rm.GetCode());
26727 AdvanceIT();
26728 return;
26729 }
26730 }
26731 } else {
26732 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
26733 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26734 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26735 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26736 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
26737 if (cond.Is(al)) {
26738 const DRegister& first = nreglist.GetFirstDRegister();
26739 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x4 : 0x5;
26740 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
26741 (encoded_align_1.GetEncodingValue() << 4) |
26742 first.Encode(22, 12) | (len_encoding << 8) |
26743 (rn.GetCode() << 16) | rm.GetCode());
26744 return;
26745 }
26746 }
26747 }
26748 }
26749 Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
26750 }
26751
vst3(Condition cond,DataType dt,const NeonRegisterList & nreglist,const MemOperand & operand)26752 void Assembler::vst3(Condition cond,
26753 DataType dt,
26754 const NeonRegisterList& nreglist,
26755 const MemOperand& operand) {
26756 VIXL_ASSERT(AllowAssembler());
26757 CheckIT(cond);
26758 if (operand.IsImmediateZero()) {
26759 Register rn = operand.GetBaseRegister();
26760 Dt_size_7 encoded_dt(dt);
26761 Index_1 encoded_align_1(nreglist, dt);
26762 if (IsUsingT32()) {
26763 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
26764 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26765 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26766 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26767 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
26768 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26769 const DRegister& first = nreglist.GetFirstDRegister();
26770 EmitT32_32(0xf980020fU | (encoded_dt.GetEncodingValue() << 10) |
26771 (encoded_align_1.GetEncodingValue() << 4) |
26772 first.Encode(22, 12) | (rn.GetCode() << 16));
26773 AdvanceIT();
26774 return;
26775 }
26776 }
26777 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1
26778 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26779 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26780 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26781 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
26782 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26783 const DRegister& first = nreglist.GetFirstDRegister();
26784 EmitT32_32(0xf980020dU | (encoded_dt.GetEncodingValue() << 10) |
26785 (encoded_align_1.GetEncodingValue() << 4) |
26786 first.Encode(22, 12) | (rn.GetCode() << 16));
26787 AdvanceIT();
26788 return;
26789 }
26790 }
26791 } else {
26792 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
26793 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26794 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26795 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26796 operand.IsOffset() && (!rn.IsPC() || AllowUnpredictable())) {
26797 if (cond.Is(al)) {
26798 const DRegister& first = nreglist.GetFirstDRegister();
26799 EmitA32(0xf480020fU | (encoded_dt.GetEncodingValue() << 10) |
26800 (encoded_align_1.GetEncodingValue() << 4) |
26801 first.Encode(22, 12) | (rn.GetCode() << 16));
26802 return;
26803 }
26804 }
26805 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
26806 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26807 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26808 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26809 operand.IsPostIndex() && (!rn.IsPC() || AllowUnpredictable())) {
26810 if (cond.Is(al)) {
26811 const DRegister& first = nreglist.GetFirstDRegister();
26812 EmitA32(0xf480020dU | (encoded_dt.GetEncodingValue() << 10) |
26813 (encoded_align_1.GetEncodingValue() << 4) |
26814 first.Encode(22, 12) | (rn.GetCode() << 16));
26815 return;
26816 }
26817 }
26818 }
26819 }
26820 if (operand.IsPlainRegister()) {
26821 Register rn = operand.GetBaseRegister();
26822 Sign sign = operand.GetSign();
26823 Register rm = operand.GetOffsetRegister();
26824 Dt_size_7 encoded_dt(dt);
26825 Index_1 encoded_align_1(nreglist, dt);
26826 if (IsUsingT32()) {
26827 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1
26828 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26829 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26830 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26831 sign.IsPlus() && operand.IsPostIndex() &&
26832 (!rn.IsPC() || AllowUnpredictable())) {
26833 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26834 const DRegister& first = nreglist.GetFirstDRegister();
26835 EmitT32_32(0xf9800200U | (encoded_dt.GetEncodingValue() << 10) |
26836 (encoded_align_1.GetEncodingValue() << 4) |
26837 first.Encode(22, 12) | (rn.GetCode() << 16) |
26838 rm.GetCode());
26839 AdvanceIT();
26840 return;
26841 }
26842 }
26843 } else {
26844 // VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
26845 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26846 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 3)) ||
26847 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 3))) &&
26848 sign.IsPlus() && operand.IsPostIndex() &&
26849 (!rn.IsPC() || AllowUnpredictable())) {
26850 if (cond.Is(al)) {
26851 const DRegister& first = nreglist.GetFirstDRegister();
26852 EmitA32(0xf4800200U | (encoded_dt.GetEncodingValue() << 10) |
26853 (encoded_align_1.GetEncodingValue() << 4) |
26854 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
26855 return;
26856 }
26857 }
26858 }
26859 }
26860 Delegate(kVst3, &Assembler::vst3, cond, dt, nreglist, operand);
26861 }
26862
vst4(Condition cond,DataType dt,const NeonRegisterList & nreglist,const AlignedMemOperand & operand)26863 void Assembler::vst4(Condition cond,
26864 DataType dt,
26865 const NeonRegisterList& nreglist,
26866 const AlignedMemOperand& operand) {
26867 VIXL_ASSERT(AllowAssembler());
26868 CheckIT(cond);
26869 if (operand.IsImmediateZero()) {
26870 Register rn = operand.GetBaseRegister();
26871 Alignment align = operand.GetAlignment();
26872 Dt_size_7 encoded_dt(dt);
26873 Align_align_4 encoded_align_1(align);
26874 Align_index_align_3 encoded_align_2(align, nreglist, dt);
26875 if (IsUsingT32()) {
26876 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26877 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26878 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26879 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26880 operand.IsOffset() && encoded_align_1.IsValid() &&
26881 (!rn.IsPC() || AllowUnpredictable())) {
26882 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26883 const DRegister& first = nreglist.GetFirstDRegister();
26884 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
26885 EmitT32_32(0xf900000fU | (encoded_dt.GetEncodingValue() << 6) |
26886 (encoded_align_1.GetEncodingValue() << 4) |
26887 first.Encode(22, 12) | (len_encoding << 8) |
26888 (rn.GetCode() << 16));
26889 AdvanceIT();
26890 return;
26891 }
26892 }
26893 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26894 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26895 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26896 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26897 operand.IsPostIndex() && encoded_align_1.IsValid() &&
26898 (!rn.IsPC() || AllowUnpredictable())) {
26899 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26900 const DRegister& first = nreglist.GetFirstDRegister();
26901 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
26902 EmitT32_32(0xf900000dU | (encoded_dt.GetEncodingValue() << 6) |
26903 (encoded_align_1.GetEncodingValue() << 4) |
26904 first.Encode(22, 12) | (len_encoding << 8) |
26905 (rn.GetCode() << 16));
26906 AdvanceIT();
26907 return;
26908 }
26909 }
26910 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1
26911 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26912 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26913 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26914 operand.IsOffset() && encoded_align_2.IsValid() &&
26915 (!rn.IsPC() || AllowUnpredictable())) {
26916 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26917 const DRegister& first = nreglist.GetFirstDRegister();
26918 EmitT32_32(0xf980030fU | (encoded_dt.GetEncodingValue() << 10) |
26919 (encoded_align_2.GetEncodingValue() << 4) |
26920 first.Encode(22, 12) | (rn.GetCode() << 16));
26921 AdvanceIT();
26922 return;
26923 }
26924 }
26925 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1
26926 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26927 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26928 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26929 operand.IsPostIndex() && encoded_align_2.IsValid() &&
26930 (!rn.IsPC() || AllowUnpredictable())) {
26931 if (cond.Is(al) || AllowStronglyDiscouraged()) {
26932 const DRegister& first = nreglist.GetFirstDRegister();
26933 EmitT32_32(0xf980030dU | (encoded_dt.GetEncodingValue() << 10) |
26934 (encoded_align_2.GetEncodingValue() << 4) |
26935 first.Encode(22, 12) | (rn.GetCode() << 16));
26936 AdvanceIT();
26937 return;
26938 }
26939 }
26940 } else {
26941 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26942 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26943 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26944 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26945 operand.IsOffset() && encoded_align_1.IsValid() &&
26946 (!rn.IsPC() || AllowUnpredictable())) {
26947 if (cond.Is(al)) {
26948 const DRegister& first = nreglist.GetFirstDRegister();
26949 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
26950 EmitA32(0xf400000fU | (encoded_dt.GetEncodingValue() << 6) |
26951 (encoded_align_1.GetEncodingValue() << 4) |
26952 first.Encode(22, 12) | (len_encoding << 8) |
26953 (rn.GetCode() << 16));
26954 return;
26955 }
26956 }
26957 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26958 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
26959 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26960 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26961 operand.IsPostIndex() && encoded_align_1.IsValid() &&
26962 (!rn.IsPC() || AllowUnpredictable())) {
26963 if (cond.Is(al)) {
26964 const DRegister& first = nreglist.GetFirstDRegister();
26965 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
26966 EmitA32(0xf400000dU | (encoded_dt.GetEncodingValue() << 6) |
26967 (encoded_align_1.GetEncodingValue() << 4) |
26968 first.Encode(22, 12) | (len_encoding << 8) |
26969 (rn.GetCode() << 16));
26970 return;
26971 }
26972 }
26973 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
26974 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26975 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26976 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26977 operand.IsOffset() && encoded_align_2.IsValid() &&
26978 (!rn.IsPC() || AllowUnpredictable())) {
26979 if (cond.Is(al)) {
26980 const DRegister& first = nreglist.GetFirstDRegister();
26981 EmitA32(0xf480030fU | (encoded_dt.GetEncodingValue() << 10) |
26982 (encoded_align_2.GetEncodingValue() << 4) |
26983 first.Encode(22, 12) | (rn.GetCode() << 16));
26984 return;
26985 }
26986 }
26987 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1
26988 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
26989 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
26990 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
26991 operand.IsPostIndex() && encoded_align_2.IsValid() &&
26992 (!rn.IsPC() || AllowUnpredictable())) {
26993 if (cond.Is(al)) {
26994 const DRegister& first = nreglist.GetFirstDRegister();
26995 EmitA32(0xf480030dU | (encoded_dt.GetEncodingValue() << 10) |
26996 (encoded_align_2.GetEncodingValue() << 4) |
26997 first.Encode(22, 12) | (rn.GetCode() << 16));
26998 return;
26999 }
27000 }
27001 }
27002 }
27003 if (operand.IsPlainRegister()) {
27004 Register rn = operand.GetBaseRegister();
27005 Alignment align = operand.GetAlignment();
27006 Register rm = operand.GetOffsetRegister();
27007 Dt_size_7 encoded_dt(dt);
27008 Align_align_4 encoded_align_1(align);
27009 Align_index_align_3 encoded_align_2(align, nreglist, dt);
27010 if (IsUsingT32()) {
27011 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
27012 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
27013 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
27014 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
27015 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
27016 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27017 const DRegister& first = nreglist.GetFirstDRegister();
27018 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
27019 EmitT32_32(0xf9000000U | (encoded_dt.GetEncodingValue() << 6) |
27020 (encoded_align_1.GetEncodingValue() << 4) |
27021 first.Encode(22, 12) | (len_encoding << 8) |
27022 (rn.GetCode() << 16) | rm.GetCode());
27023 AdvanceIT();
27024 return;
27025 }
27026 }
27027 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1
27028 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
27029 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
27030 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
27031 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
27032 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27033 const DRegister& first = nreglist.GetFirstDRegister();
27034 EmitT32_32(0xf9800300U | (encoded_dt.GetEncodingValue() << 10) |
27035 (encoded_align_2.GetEncodingValue() << 4) |
27036 first.Encode(22, 12) | (rn.GetCode() << 16) |
27037 rm.GetCode());
27038 AdvanceIT();
27039 return;
27040 }
27041 }
27042 } else {
27043 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
27044 if (encoded_dt.IsValid() && nreglist.IsTransferMultipleLanes() &&
27045 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
27046 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
27047 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
27048 if (cond.Is(al)) {
27049 const DRegister& first = nreglist.GetFirstDRegister();
27050 uint32_t len_encoding = nreglist.IsSingleSpaced() ? 0x0 : 0x1;
27051 EmitA32(0xf4000000U | (encoded_dt.GetEncodingValue() << 6) |
27052 (encoded_align_1.GetEncodingValue() << 4) |
27053 first.Encode(22, 12) | (len_encoding << 8) |
27054 (rn.GetCode() << 16) | rm.GetCode());
27055 return;
27056 }
27057 }
27058 // VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1
27059 if (encoded_dt.IsValid() && nreglist.IsTransferOneLane() &&
27060 ((nreglist.IsSingleSpaced() && (nreglist.GetLength() == 4)) ||
27061 (nreglist.IsDoubleSpaced() && (nreglist.GetLength() == 4))) &&
27062 !rm.IsPC() && !rm.IsSP() && (!rn.IsPC() || AllowUnpredictable())) {
27063 if (cond.Is(al)) {
27064 const DRegister& first = nreglist.GetFirstDRegister();
27065 EmitA32(0xf4800300U | (encoded_dt.GetEncodingValue() << 10) |
27066 (encoded_align_2.GetEncodingValue() << 4) |
27067 first.Encode(22, 12) | (rn.GetCode() << 16) | rm.GetCode());
27068 return;
27069 }
27070 }
27071 }
27072 }
27073 Delegate(kVst4, &Assembler::vst4, cond, dt, nreglist, operand);
27074 }
27075
vstm(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)27076 void Assembler::vstm(Condition cond,
27077 DataType dt,
27078 Register rn,
27079 WriteBack write_back,
27080 DRegisterList dreglist) {
27081 VIXL_ASSERT(AllowAssembler());
27082 CheckIT(cond);
27083 USE(dt);
27084 if (IsUsingT32()) {
27085 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
27086 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
27087 AllowUnpredictable())) {
27088 const DRegister& dreg = dreglist.GetFirstDRegister();
27089 unsigned len = dreglist.GetLength() * 2;
27090 EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
27091 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
27092 (len & 0xff));
27093 AdvanceIT();
27094 return;
27095 }
27096 } else {
27097 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
27098 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
27099 (!rn.IsPC() || !write_back.DoesWriteBack())) ||
27100 AllowUnpredictable())) {
27101 const DRegister& dreg = dreglist.GetFirstDRegister();
27102 unsigned len = dreglist.GetLength() * 2;
27103 EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27104 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
27105 (len & 0xff));
27106 return;
27107 }
27108 }
27109 Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, dreglist);
27110 }
27111
vstm(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)27112 void Assembler::vstm(Condition cond,
27113 DataType dt,
27114 Register rn,
27115 WriteBack write_back,
27116 SRegisterList sreglist) {
27117 VIXL_ASSERT(AllowAssembler());
27118 CheckIT(cond);
27119 USE(dt);
27120 if (IsUsingT32()) {
27121 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
27122 if ((!rn.IsPC() || AllowUnpredictable())) {
27123 const SRegister& sreg = sreglist.GetFirstSRegister();
27124 unsigned len = sreglist.GetLength();
27125 EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
27126 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
27127 (len & 0xff));
27128 AdvanceIT();
27129 return;
27130 }
27131 } else {
27132 // VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
27133 if (cond.IsNotNever() &&
27134 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
27135 const SRegister& sreg = sreglist.GetFirstSRegister();
27136 unsigned len = sreglist.GetLength();
27137 EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27138 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
27139 (len & 0xff));
27140 return;
27141 }
27142 }
27143 Delegate(kVstm, &Assembler::vstm, cond, dt, rn, write_back, sreglist);
27144 }
27145
vstmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)27146 void Assembler::vstmdb(Condition cond,
27147 DataType dt,
27148 Register rn,
27149 WriteBack write_back,
27150 DRegisterList dreglist) {
27151 VIXL_ASSERT(AllowAssembler());
27152 CheckIT(cond);
27153 USE(dt);
27154 if (IsUsingT32()) {
27155 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
27156 if (write_back.DoesWriteBack() &&
27157 (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
27158 AllowUnpredictable())) {
27159 const DRegister& dreg = dreglist.GetFirstDRegister();
27160 unsigned len = dreglist.GetLength() * 2;
27161 EmitT32_32(0xed200b00U | (rn.GetCode() << 16) | dreg.Encode(22, 12) |
27162 (len & 0xff));
27163 AdvanceIT();
27164 return;
27165 }
27166 } else {
27167 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
27168 if (write_back.DoesWriteBack() && cond.IsNotNever() &&
27169 (((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
27170 AllowUnpredictable())) {
27171 const DRegister& dreg = dreglist.GetFirstDRegister();
27172 unsigned len = dreglist.GetLength() * 2;
27173 EmitA32(0x0d200b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27174 dreg.Encode(22, 12) | (len & 0xff));
27175 return;
27176 }
27177 }
27178 Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, dreglist);
27179 }
27180
vstmdb(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)27181 void Assembler::vstmdb(Condition cond,
27182 DataType dt,
27183 Register rn,
27184 WriteBack write_back,
27185 SRegisterList sreglist) {
27186 VIXL_ASSERT(AllowAssembler());
27187 CheckIT(cond);
27188 USE(dt);
27189 if (IsUsingT32()) {
27190 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
27191 if (write_back.DoesWriteBack() && (!rn.IsPC() || AllowUnpredictable())) {
27192 const SRegister& sreg = sreglist.GetFirstSRegister();
27193 unsigned len = sreglist.GetLength();
27194 EmitT32_32(0xed200a00U | (rn.GetCode() << 16) | sreg.Encode(22, 12) |
27195 (len & 0xff));
27196 AdvanceIT();
27197 return;
27198 }
27199 } else {
27200 // VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
27201 if (write_back.DoesWriteBack() && cond.IsNotNever() &&
27202 (!rn.IsPC() || AllowUnpredictable())) {
27203 const SRegister& sreg = sreglist.GetFirstSRegister();
27204 unsigned len = sreglist.GetLength();
27205 EmitA32(0x0d200a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27206 sreg.Encode(22, 12) | (len & 0xff));
27207 return;
27208 }
27209 }
27210 Delegate(kVstmdb, &Assembler::vstmdb, cond, dt, rn, write_back, sreglist);
27211 }
27212
vstmia(Condition cond,DataType dt,Register rn,WriteBack write_back,DRegisterList dreglist)27213 void Assembler::vstmia(Condition cond,
27214 DataType dt,
27215 Register rn,
27216 WriteBack write_back,
27217 DRegisterList dreglist) {
27218 VIXL_ASSERT(AllowAssembler());
27219 CheckIT(cond);
27220 USE(dt);
27221 if (IsUsingT32()) {
27222 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
27223 if ((((dreglist.GetLength() <= 16) && !rn.IsPC()) ||
27224 AllowUnpredictable())) {
27225 const DRegister& dreg = dreglist.GetFirstDRegister();
27226 unsigned len = dreglist.GetLength() * 2;
27227 EmitT32_32(0xec800b00U | (rn.GetCode() << 16) |
27228 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
27229 (len & 0xff));
27230 AdvanceIT();
27231 return;
27232 }
27233 } else {
27234 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
27235 if (cond.IsNotNever() && (((dreglist.GetLength() <= 16) &&
27236 (!rn.IsPC() || !write_back.DoesWriteBack())) ||
27237 AllowUnpredictable())) {
27238 const DRegister& dreg = dreglist.GetFirstDRegister();
27239 unsigned len = dreglist.GetLength() * 2;
27240 EmitA32(0x0c800b00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27241 (write_back.GetWriteBackUint32() << 21) | dreg.Encode(22, 12) |
27242 (len & 0xff));
27243 return;
27244 }
27245 }
27246 Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, dreglist);
27247 }
27248
vstmia(Condition cond,DataType dt,Register rn,WriteBack write_back,SRegisterList sreglist)27249 void Assembler::vstmia(Condition cond,
27250 DataType dt,
27251 Register rn,
27252 WriteBack write_back,
27253 SRegisterList sreglist) {
27254 VIXL_ASSERT(AllowAssembler());
27255 CheckIT(cond);
27256 USE(dt);
27257 if (IsUsingT32()) {
27258 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
27259 if ((!rn.IsPC() || AllowUnpredictable())) {
27260 const SRegister& sreg = sreglist.GetFirstSRegister();
27261 unsigned len = sreglist.GetLength();
27262 EmitT32_32(0xec800a00U | (rn.GetCode() << 16) |
27263 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
27264 (len & 0xff));
27265 AdvanceIT();
27266 return;
27267 }
27268 } else {
27269 // VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
27270 if (cond.IsNotNever() &&
27271 ((!rn.IsPC() || !write_back.DoesWriteBack()) || AllowUnpredictable())) {
27272 const SRegister& sreg = sreglist.GetFirstSRegister();
27273 unsigned len = sreglist.GetLength();
27274 EmitA32(0x0c800a00U | (cond.GetCondition() << 28) | (rn.GetCode() << 16) |
27275 (write_back.GetWriteBackUint32() << 21) | sreg.Encode(22, 12) |
27276 (len & 0xff));
27277 return;
27278 }
27279 }
27280 Delegate(kVstmia, &Assembler::vstmia, cond, dt, rn, write_back, sreglist);
27281 }
27282
vstr(Condition cond,DataType dt,DRegister rd,const MemOperand & operand)27283 void Assembler::vstr(Condition cond,
27284 DataType dt,
27285 DRegister rd,
27286 const MemOperand& operand) {
27287 VIXL_ASSERT(AllowAssembler());
27288 CheckIT(cond);
27289 if (operand.IsImmediate()) {
27290 Register rn = operand.GetBaseRegister();
27291 int32_t offset = operand.GetOffsetImmediate();
27292 if (IsUsingT32()) {
27293 // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
27294 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
27295 ((offset % 4) == 0) && operand.IsOffset() &&
27296 (!rn.IsPC() || AllowUnpredictable())) {
27297 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
27298 uint32_t offset_ = abs(offset) >> 2;
27299 EmitT32_32(0xed000b00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
27300 offset_ | (sign << 23));
27301 AdvanceIT();
27302 return;
27303 }
27304 } else {
27305 // VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
27306 if (dt.IsNoneOr(Untyped64) && (offset >= -1020) && (offset <= 1020) &&
27307 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
27308 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
27309 uint32_t offset_ = abs(offset) >> 2;
27310 EmitA32(0x0d000b00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
27311 (rn.GetCode() << 16) | offset_ | (sign << 23));
27312 return;
27313 }
27314 }
27315 }
27316 Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
27317 }
27318
vstr(Condition cond,DataType dt,SRegister rd,const MemOperand & operand)27319 void Assembler::vstr(Condition cond,
27320 DataType dt,
27321 SRegister rd,
27322 const MemOperand& operand) {
27323 VIXL_ASSERT(AllowAssembler());
27324 CheckIT(cond);
27325 if (operand.IsImmediate()) {
27326 Register rn = operand.GetBaseRegister();
27327 int32_t offset = operand.GetOffsetImmediate();
27328 if (IsUsingT32()) {
27329 // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
27330 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
27331 ((offset % 4) == 0) && operand.IsOffset() &&
27332 (!rn.IsPC() || AllowUnpredictable())) {
27333 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
27334 uint32_t offset_ = abs(offset) >> 2;
27335 EmitT32_32(0xed000a00U | rd.Encode(22, 12) | (rn.GetCode() << 16) |
27336 offset_ | (sign << 23));
27337 AdvanceIT();
27338 return;
27339 }
27340 } else {
27341 // VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
27342 if (dt.IsNoneOr(Untyped32) && (offset >= -1020) && (offset <= 1020) &&
27343 ((offset % 4) == 0) && operand.IsOffset() && cond.IsNotNever()) {
27344 uint32_t sign = operand.GetSign().IsPlus() ? 1 : 0;
27345 uint32_t offset_ = abs(offset) >> 2;
27346 EmitA32(0x0d000a00U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
27347 (rn.GetCode() << 16) | offset_ | (sign << 23));
27348 return;
27349 }
27350 }
27351 }
27352 Delegate(kVstr, &Assembler::vstr, cond, dt, rd, operand);
27353 }
27354
vsub(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)27355 void Assembler::vsub(
27356 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
27357 VIXL_ASSERT(AllowAssembler());
27358 CheckIT(cond);
27359 Dt_size_2 encoded_dt(dt);
27360 if (IsUsingT32()) {
27361 // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
27362 if (dt.Is(F32)) {
27363 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27364 EmitT32_32(0xef200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27365 rm.Encode(5, 0));
27366 AdvanceIT();
27367 return;
27368 }
27369 }
27370 // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
27371 if (dt.Is(F64)) {
27372 EmitT32_32(0xee300b40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27373 rm.Encode(5, 0));
27374 AdvanceIT();
27375 return;
27376 }
27377 // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
27378 if (encoded_dt.IsValid()) {
27379 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27380 EmitT32_32(0xff000800U | (encoded_dt.GetEncodingValue() << 20) |
27381 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27382 AdvanceIT();
27383 return;
27384 }
27385 }
27386 } else {
27387 // VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
27388 if (dt.Is(F32)) {
27389 if (cond.Is(al)) {
27390 EmitA32(0xf2200d00U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27391 rm.Encode(5, 0));
27392 return;
27393 }
27394 }
27395 // VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
27396 if (dt.Is(F64) && cond.IsNotNever()) {
27397 EmitA32(0x0e300b40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
27398 rn.Encode(7, 16) | rm.Encode(5, 0));
27399 return;
27400 }
27401 // VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
27402 if (encoded_dt.IsValid()) {
27403 if (cond.Is(al)) {
27404 EmitA32(0xf3000800U | (encoded_dt.GetEncodingValue() << 20) |
27405 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27406 return;
27407 }
27408 }
27409 }
27410 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
27411 }
27412
vsub(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)27413 void Assembler::vsub(
27414 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
27415 VIXL_ASSERT(AllowAssembler());
27416 CheckIT(cond);
27417 Dt_size_2 encoded_dt(dt);
27418 if (IsUsingT32()) {
27419 // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
27420 if (dt.Is(F32)) {
27421 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27422 EmitT32_32(0xef200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27423 rm.Encode(5, 0));
27424 AdvanceIT();
27425 return;
27426 }
27427 }
27428 // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
27429 if (encoded_dt.IsValid()) {
27430 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27431 EmitT32_32(0xff000840U | (encoded_dt.GetEncodingValue() << 20) |
27432 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27433 AdvanceIT();
27434 return;
27435 }
27436 }
27437 } else {
27438 // VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
27439 if (dt.Is(F32)) {
27440 if (cond.Is(al)) {
27441 EmitA32(0xf2200d40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27442 rm.Encode(5, 0));
27443 return;
27444 }
27445 }
27446 // VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
27447 if (encoded_dt.IsValid()) {
27448 if (cond.Is(al)) {
27449 EmitA32(0xf3000840U | (encoded_dt.GetEncodingValue() << 20) |
27450 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27451 return;
27452 }
27453 }
27454 }
27455 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
27456 }
27457
vsub(Condition cond,DataType dt,SRegister rd,SRegister rn,SRegister rm)27458 void Assembler::vsub(
27459 Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
27460 VIXL_ASSERT(AllowAssembler());
27461 CheckIT(cond);
27462 if (IsUsingT32()) {
27463 // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
27464 if (dt.Is(F32)) {
27465 EmitT32_32(0xee300a40U | rd.Encode(22, 12) | rn.Encode(7, 16) |
27466 rm.Encode(5, 0));
27467 AdvanceIT();
27468 return;
27469 }
27470 } else {
27471 // VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
27472 if (dt.Is(F32) && cond.IsNotNever()) {
27473 EmitA32(0x0e300a40U | (cond.GetCondition() << 28) | rd.Encode(22, 12) |
27474 rn.Encode(7, 16) | rm.Encode(5, 0));
27475 return;
27476 }
27477 }
27478 Delegate(kVsub, &Assembler::vsub, cond, dt, rd, rn, rm);
27479 }
27480
vsubhn(Condition cond,DataType dt,DRegister rd,QRegister rn,QRegister rm)27481 void Assembler::vsubhn(
27482 Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
27483 VIXL_ASSERT(AllowAssembler());
27484 CheckIT(cond);
27485 Dt_size_3 encoded_dt(dt);
27486 if (IsUsingT32()) {
27487 // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1
27488 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
27489 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27490 EmitT32_32(0xef800600U | (encoded_dt.GetEncodingValue() << 20) |
27491 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27492 AdvanceIT();
27493 return;
27494 }
27495 }
27496 } else {
27497 // VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
27498 if (encoded_dt.IsValid() && (dt.Is(I16) || dt.Is(I32) || dt.Is(I64))) {
27499 if (cond.Is(al)) {
27500 EmitA32(0xf2800600U | (encoded_dt.GetEncodingValue() << 20) |
27501 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27502 return;
27503 }
27504 }
27505 }
27506 Delegate(kVsubhn, &Assembler::vsubhn, cond, dt, rd, rn, rm);
27507 }
27508
vsubl(Condition cond,DataType dt,QRegister rd,DRegister rn,DRegister rm)27509 void Assembler::vsubl(
27510 Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
27511 VIXL_ASSERT(AllowAssembler());
27512 CheckIT(cond);
27513 Dt_U_size_1 encoded_dt(dt);
27514 if (IsUsingT32()) {
27515 // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
27516 if (encoded_dt.IsValid()) {
27517 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27518 EmitT32_32(0xef800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
27519 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
27520 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27521 AdvanceIT();
27522 return;
27523 }
27524 }
27525 } else {
27526 // VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
27527 if (encoded_dt.IsValid()) {
27528 if (cond.Is(al)) {
27529 EmitA32(0xf2800200U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
27530 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
27531 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27532 return;
27533 }
27534 }
27535 }
27536 Delegate(kVsubl, &Assembler::vsubl, cond, dt, rd, rn, rm);
27537 }
27538
vsubw(Condition cond,DataType dt,QRegister rd,QRegister rn,DRegister rm)27539 void Assembler::vsubw(
27540 Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
27541 VIXL_ASSERT(AllowAssembler());
27542 CheckIT(cond);
27543 Dt_U_size_1 encoded_dt(dt);
27544 if (IsUsingT32()) {
27545 // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1
27546 if (encoded_dt.IsValid()) {
27547 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27548 EmitT32_32(0xef800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
27549 ((encoded_dt.GetEncodingValue() & 0x4) << 26) |
27550 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27551 AdvanceIT();
27552 return;
27553 }
27554 }
27555 } else {
27556 // VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
27557 if (encoded_dt.IsValid()) {
27558 if (cond.Is(al)) {
27559 EmitA32(0xf2800300U | ((encoded_dt.GetEncodingValue() & 0x3) << 20) |
27560 ((encoded_dt.GetEncodingValue() & 0x4) << 22) |
27561 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27562 return;
27563 }
27564 }
27565 }
27566 Delegate(kVsubw, &Assembler::vsubw, cond, dt, rd, rn, rm);
27567 }
27568
vswp(Condition cond,DataType dt,DRegister rd,DRegister rm)27569 void Assembler::vswp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
27570 VIXL_ASSERT(AllowAssembler());
27571 CheckIT(cond);
27572 USE(dt);
27573 if (IsUsingT32()) {
27574 // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
27575 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27576 EmitT32_32(0xffb20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
27577 AdvanceIT();
27578 return;
27579 }
27580 } else {
27581 // VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
27582 if (cond.Is(al)) {
27583 EmitA32(0xf3b20000U | rd.Encode(22, 12) | rm.Encode(5, 0));
27584 return;
27585 }
27586 }
27587 Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
27588 }
27589
vswp(Condition cond,DataType dt,QRegister rd,QRegister rm)27590 void Assembler::vswp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
27591 VIXL_ASSERT(AllowAssembler());
27592 CheckIT(cond);
27593 USE(dt);
27594 if (IsUsingT32()) {
27595 // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
27596 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27597 EmitT32_32(0xffb20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
27598 AdvanceIT();
27599 return;
27600 }
27601 } else {
27602 // VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
27603 if (cond.Is(al)) {
27604 EmitA32(0xf3b20040U | rd.Encode(22, 12) | rm.Encode(5, 0));
27605 return;
27606 }
27607 }
27608 Delegate(kVswp, &Assembler::vswp, cond, dt, rd, rm);
27609 }
27610
vtbl(Condition cond,DataType dt,DRegister rd,const NeonRegisterList & nreglist,DRegister rm)27611 void Assembler::vtbl(Condition cond,
27612 DataType dt,
27613 DRegister rd,
27614 const NeonRegisterList& nreglist,
27615 DRegister rm) {
27616 VIXL_ASSERT(AllowAssembler());
27617 CheckIT(cond);
27618 if (IsUsingT32()) {
27619 // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
27620 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
27621 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
27622 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27623 const DRegister& first = nreglist.GetFirstDRegister();
27624 uint32_t len_encoding = nreglist.GetLength() - 1;
27625 EmitT32_32(0xffb00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
27626 (len_encoding << 8) | rm.Encode(5, 0));
27627 AdvanceIT();
27628 return;
27629 }
27630 }
27631 } else {
27632 // VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
27633 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
27634 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
27635 if (cond.Is(al)) {
27636 const DRegister& first = nreglist.GetFirstDRegister();
27637 uint32_t len_encoding = nreglist.GetLength() - 1;
27638 EmitA32(0xf3b00800U | rd.Encode(22, 12) | first.Encode(7, 16) |
27639 (len_encoding << 8) | rm.Encode(5, 0));
27640 return;
27641 }
27642 }
27643 }
27644 Delegate(kVtbl, &Assembler::vtbl, cond, dt, rd, nreglist, rm);
27645 }
27646
vtbx(Condition cond,DataType dt,DRegister rd,const NeonRegisterList & nreglist,DRegister rm)27647 void Assembler::vtbx(Condition cond,
27648 DataType dt,
27649 DRegister rd,
27650 const NeonRegisterList& nreglist,
27651 DRegister rm) {
27652 VIXL_ASSERT(AllowAssembler());
27653 CheckIT(cond);
27654 if (IsUsingT32()) {
27655 // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1
27656 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
27657 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
27658 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27659 const DRegister& first = nreglist.GetFirstDRegister();
27660 uint32_t len_encoding = nreglist.GetLength() - 1;
27661 EmitT32_32(0xffb00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
27662 (len_encoding << 8) | rm.Encode(5, 0));
27663 AdvanceIT();
27664 return;
27665 }
27666 }
27667 } else {
27668 // VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
27669 if (dt.Is(Untyped8) && nreglist.IsTransferMultipleLanes() &&
27670 (nreglist.IsSingleSpaced()) && (nreglist.GetLength() <= 4)) {
27671 if (cond.Is(al)) {
27672 const DRegister& first = nreglist.GetFirstDRegister();
27673 uint32_t len_encoding = nreglist.GetLength() - 1;
27674 EmitA32(0xf3b00840U | rd.Encode(22, 12) | first.Encode(7, 16) |
27675 (len_encoding << 8) | rm.Encode(5, 0));
27676 return;
27677 }
27678 }
27679 }
27680 Delegate(kVtbx, &Assembler::vtbx, cond, dt, rd, nreglist, rm);
27681 }
27682
vtrn(Condition cond,DataType dt,DRegister rd,DRegister rm)27683 void Assembler::vtrn(Condition cond, DataType dt, DRegister rd, DRegister rm) {
27684 VIXL_ASSERT(AllowAssembler());
27685 CheckIT(cond);
27686 Dt_size_7 encoded_dt(dt);
27687 if (IsUsingT32()) {
27688 // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
27689 if (encoded_dt.IsValid()) {
27690 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27691 EmitT32_32(0xffb20080U | (encoded_dt.GetEncodingValue() << 18) |
27692 rd.Encode(22, 12) | rm.Encode(5, 0));
27693 AdvanceIT();
27694 return;
27695 }
27696 }
27697 } else {
27698 // VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
27699 if (encoded_dt.IsValid()) {
27700 if (cond.Is(al)) {
27701 EmitA32(0xf3b20080U | (encoded_dt.GetEncodingValue() << 18) |
27702 rd.Encode(22, 12) | rm.Encode(5, 0));
27703 return;
27704 }
27705 }
27706 }
27707 Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
27708 }
27709
vtrn(Condition cond,DataType dt,QRegister rd,QRegister rm)27710 void Assembler::vtrn(Condition cond, DataType dt, QRegister rd, QRegister rm) {
27711 VIXL_ASSERT(AllowAssembler());
27712 CheckIT(cond);
27713 Dt_size_7 encoded_dt(dt);
27714 if (IsUsingT32()) {
27715 // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
27716 if (encoded_dt.IsValid()) {
27717 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27718 EmitT32_32(0xffb200c0U | (encoded_dt.GetEncodingValue() << 18) |
27719 rd.Encode(22, 12) | rm.Encode(5, 0));
27720 AdvanceIT();
27721 return;
27722 }
27723 }
27724 } else {
27725 // VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
27726 if (encoded_dt.IsValid()) {
27727 if (cond.Is(al)) {
27728 EmitA32(0xf3b200c0U | (encoded_dt.GetEncodingValue() << 18) |
27729 rd.Encode(22, 12) | rm.Encode(5, 0));
27730 return;
27731 }
27732 }
27733 }
27734 Delegate(kVtrn, &Assembler::vtrn, cond, dt, rd, rm);
27735 }
27736
vtst(Condition cond,DataType dt,DRegister rd,DRegister rn,DRegister rm)27737 void Assembler::vtst(
27738 Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
27739 VIXL_ASSERT(AllowAssembler());
27740 CheckIT(cond);
27741 Dt_size_7 encoded_dt(dt);
27742 if (IsUsingT32()) {
27743 // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
27744 if (encoded_dt.IsValid()) {
27745 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27746 EmitT32_32(0xef000810U | (encoded_dt.GetEncodingValue() << 20) |
27747 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27748 AdvanceIT();
27749 return;
27750 }
27751 }
27752 } else {
27753 // VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
27754 if (encoded_dt.IsValid()) {
27755 if (cond.Is(al)) {
27756 EmitA32(0xf2000810U | (encoded_dt.GetEncodingValue() << 20) |
27757 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27758 return;
27759 }
27760 }
27761 }
27762 Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
27763 }
27764
vtst(Condition cond,DataType dt,QRegister rd,QRegister rn,QRegister rm)27765 void Assembler::vtst(
27766 Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
27767 VIXL_ASSERT(AllowAssembler());
27768 CheckIT(cond);
27769 Dt_size_7 encoded_dt(dt);
27770 if (IsUsingT32()) {
27771 // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
27772 if (encoded_dt.IsValid()) {
27773 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27774 EmitT32_32(0xef000850U | (encoded_dt.GetEncodingValue() << 20) |
27775 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27776 AdvanceIT();
27777 return;
27778 }
27779 }
27780 } else {
27781 // VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
27782 if (encoded_dt.IsValid()) {
27783 if (cond.Is(al)) {
27784 EmitA32(0xf2000850U | (encoded_dt.GetEncodingValue() << 20) |
27785 rd.Encode(22, 12) | rn.Encode(7, 16) | rm.Encode(5, 0));
27786 return;
27787 }
27788 }
27789 }
27790 Delegate(kVtst, &Assembler::vtst, cond, dt, rd, rn, rm);
27791 }
27792
vuzp(Condition cond,DataType dt,DRegister rd,DRegister rm)27793 void Assembler::vuzp(Condition cond, DataType dt, DRegister rd, DRegister rm) {
27794 VIXL_ASSERT(AllowAssembler());
27795 CheckIT(cond);
27796 Dt_size_15 encoded_dt(dt);
27797 if (IsUsingT32()) {
27798 // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
27799 if (encoded_dt.IsValid()) {
27800 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27801 EmitT32_32(0xffb20100U | (encoded_dt.GetEncodingValue() << 18) |
27802 rd.Encode(22, 12) | rm.Encode(5, 0));
27803 AdvanceIT();
27804 return;
27805 }
27806 }
27807 // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
27808 if (dt.Is(Untyped32)) {
27809 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27810 EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
27811 AdvanceIT();
27812 return;
27813 }
27814 }
27815 } else {
27816 // VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
27817 if (encoded_dt.IsValid()) {
27818 if (cond.Is(al)) {
27819 EmitA32(0xf3b20100U | (encoded_dt.GetEncodingValue() << 18) |
27820 rd.Encode(22, 12) | rm.Encode(5, 0));
27821 return;
27822 }
27823 }
27824 // VUZP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
27825 if (dt.Is(Untyped32)) {
27826 if (cond.Is(al)) {
27827 EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
27828 return;
27829 }
27830 }
27831 }
27832 Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
27833 }
27834
vuzp(Condition cond,DataType dt,QRegister rd,QRegister rm)27835 void Assembler::vuzp(Condition cond, DataType dt, QRegister rd, QRegister rm) {
27836 VIXL_ASSERT(AllowAssembler());
27837 CheckIT(cond);
27838 Dt_size_7 encoded_dt(dt);
27839 if (IsUsingT32()) {
27840 // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
27841 if (encoded_dt.IsValid()) {
27842 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27843 EmitT32_32(0xffb20140U | (encoded_dt.GetEncodingValue() << 18) |
27844 rd.Encode(22, 12) | rm.Encode(5, 0));
27845 AdvanceIT();
27846 return;
27847 }
27848 }
27849 } else {
27850 // VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
27851 if (encoded_dt.IsValid()) {
27852 if (cond.Is(al)) {
27853 EmitA32(0xf3b20140U | (encoded_dt.GetEncodingValue() << 18) |
27854 rd.Encode(22, 12) | rm.Encode(5, 0));
27855 return;
27856 }
27857 }
27858 }
27859 Delegate(kVuzp, &Assembler::vuzp, cond, dt, rd, rm);
27860 }
27861
vzip(Condition cond,DataType dt,DRegister rd,DRegister rm)27862 void Assembler::vzip(Condition cond, DataType dt, DRegister rd, DRegister rm) {
27863 VIXL_ASSERT(AllowAssembler());
27864 CheckIT(cond);
27865 Dt_size_15 encoded_dt(dt);
27866 if (IsUsingT32()) {
27867 // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
27868 if (encoded_dt.IsValid()) {
27869 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27870 EmitT32_32(0xffb20180U | (encoded_dt.GetEncodingValue() << 18) |
27871 rd.Encode(22, 12) | rm.Encode(5, 0));
27872 AdvanceIT();
27873 return;
27874 }
27875 }
27876 // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; T1
27877 if (dt.Is(Untyped32)) {
27878 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27879 EmitT32_32(0xffba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
27880 AdvanceIT();
27881 return;
27882 }
27883 }
27884 } else {
27885 // VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
27886 if (encoded_dt.IsValid()) {
27887 if (cond.Is(al)) {
27888 EmitA32(0xf3b20180U | (encoded_dt.GetEncodingValue() << 18) |
27889 rd.Encode(22, 12) | rm.Encode(5, 0));
27890 return;
27891 }
27892 }
27893 // VZIP{<c>}{<q>}.32 <Dd>, <Dm> ; A1
27894 if (dt.Is(Untyped32)) {
27895 if (cond.Is(al)) {
27896 EmitA32(0xf3ba0080U | rd.Encode(22, 12) | rm.Encode(5, 0));
27897 return;
27898 }
27899 }
27900 }
27901 Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
27902 }
27903
vzip(Condition cond,DataType dt,QRegister rd,QRegister rm)27904 void Assembler::vzip(Condition cond, DataType dt, QRegister rd, QRegister rm) {
27905 VIXL_ASSERT(AllowAssembler());
27906 CheckIT(cond);
27907 Dt_size_7 encoded_dt(dt);
27908 if (IsUsingT32()) {
27909 // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
27910 if (encoded_dt.IsValid()) {
27911 if (cond.Is(al) || AllowStronglyDiscouraged()) {
27912 EmitT32_32(0xffb201c0U | (encoded_dt.GetEncodingValue() << 18) |
27913 rd.Encode(22, 12) | rm.Encode(5, 0));
27914 AdvanceIT();
27915 return;
27916 }
27917 }
27918 } else {
27919 // VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
27920 if (encoded_dt.IsValid()) {
27921 if (cond.Is(al)) {
27922 EmitA32(0xf3b201c0U | (encoded_dt.GetEncodingValue() << 18) |
27923 rd.Encode(22, 12) | rm.Encode(5, 0));
27924 return;
27925 }
27926 }
27927 }
27928 Delegate(kVzip, &Assembler::vzip, cond, dt, rd, rm);
27929 }
27930
yield(Condition cond,EncodingSize size)27931 void Assembler::yield(Condition cond, EncodingSize size) {
27932 VIXL_ASSERT(AllowAssembler());
27933 CheckIT(cond);
27934 if (IsUsingT32()) {
27935 // YIELD{<c>}{<q>} ; T1
27936 if (!size.IsWide()) {
27937 EmitT32_16(0xbf10);
27938 AdvanceIT();
27939 return;
27940 }
27941 // YIELD{<c>}.W ; T2
27942 if (!size.IsNarrow()) {
27943 EmitT32_32(0xf3af8001U);
27944 AdvanceIT();
27945 return;
27946 }
27947 } else {
27948 // YIELD{<c>}{<q>} ; A1
27949 if (cond.IsNotNever()) {
27950 EmitA32(0x0320f001U | (cond.GetCondition() << 28));
27951 return;
27952 }
27953 }
27954 Delegate(kYield, &Assembler::yield, cond, size);
27955 }
27956 // End of generated code.
27957
27958 } // namespace aarch32
27959 } // namespace vixl
27960