Rust · 218885 bytes Raw Blame History
1 //! ARM64 instruction encoding.
2 //!
3 //! Converts structured instruction representations into their 4-byte binary encodings.
4 //! Every ARM64 instruction is exactly 32 bits.
5
6 use crate::reg::{Cond, FpReg, GpReg};
7
8 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
9 pub enum AddrExtend {
10 Uxtw,
11 Lsl,
12 Sxtw,
13 Sxtx,
14 }
15
16 impl AddrExtend {
17 fn enc(self) -> u32 {
18 match self {
19 AddrExtend::Uxtw => 0b010,
20 AddrExtend::Lsl => 0b011,
21 AddrExtend::Sxtw => 0b110,
22 AddrExtend::Sxtx => 0b111,
23 }
24 }
25 }
26
27 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
28 pub enum RegShift {
29 Lsl,
30 Lsr,
31 Asr,
32 }
33
34 impl RegShift {
35 fn enc(self) -> u32 {
36 match self {
37 RegShift::Lsl => 0b00,
38 RegShift::Lsr => 0b01,
39 RegShift::Asr => 0b10,
40 }
41 }
42 }
43
44 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
45 pub enum RegExtend {
46 Uxtb,
47 Uxth,
48 Uxtw,
49 Uxtx,
50 Sxtb,
51 Sxth,
52 Sxtw,
53 Sxtx,
54 }
55
56 impl RegExtend {
57 fn enc(self) -> u32 {
58 match self {
59 RegExtend::Uxtb => 0b000,
60 RegExtend::Uxth => 0b001,
61 RegExtend::Uxtw => 0b010,
62 RegExtend::Uxtx => 0b011,
63 RegExtend::Sxtb => 0b100,
64 RegExtend::Sxth => 0b101,
65 RegExtend::Sxtw => 0b110,
66 RegExtend::Sxtx => 0b111,
67 }
68 }
69 }
70
71 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
72 pub enum BarrierOpt {
73 Oshld,
74 Oshst,
75 Osh,
76 Nshld,
77 Nshst,
78 Nsh,
79 Ishld,
80 Ishst,
81 Ish,
82 Ld,
83 St,
84 Sy,
85 }
86
87 impl BarrierOpt {
88 fn enc(self) -> u32 {
89 match self {
90 BarrierOpt::Oshld => 0b0001,
91 BarrierOpt::Oshst => 0b0010,
92 BarrierOpt::Osh => 0b0011,
93 BarrierOpt::Nshld => 0b0101,
94 BarrierOpt::Nshst => 0b0110,
95 BarrierOpt::Nsh => 0b0111,
96 BarrierOpt::Ishld => 0b1001,
97 BarrierOpt::Ishst => 0b1010,
98 BarrierOpt::Ish => 0b1011,
99 BarrierOpt::Ld => 0b1101,
100 BarrierOpt::St => 0b1110,
101 BarrierOpt::Sy => 0b1111,
102 }
103 }
104 }
105
106 /// An ARM64 instruction that can be encoded to its 4-byte binary form.
107 #[derive(Debug, Clone, PartialEq, Eq)]
108 pub enum Inst {
109 // ---- Data processing (register) ----
110 /// ADD Xd, Xn, Xm (sf=true for 64-bit, false for 32-bit)
111 AddReg {
112 rd: GpReg,
113 rn: GpReg,
114 rm: GpReg,
115 sf: bool,
116 },
117 /// ADD Xd, Xn, Xm, <shift> #amount
118 AddShiftReg {
119 rd: GpReg,
120 rn: GpReg,
121 rm: GpReg,
122 shift: RegShift,
123 amount: u8,
124 sf: bool,
125 },
126 /// ADD Xd, Xn, Rm, <extend> {#amount}
127 AddExtReg {
128 rd: GpReg,
129 rn: GpReg,
130 rm: GpReg,
131 extend: RegExtend,
132 amount: u8,
133 sf: bool,
134 },
135 /// SUB Xd, Xn, Xm
136 SubReg {
137 rd: GpReg,
138 rn: GpReg,
139 rm: GpReg,
140 sf: bool,
141 },
142 /// SUB Xd, Xn, Xm, <shift> #amount
143 SubShiftReg {
144 rd: GpReg,
145 rn: GpReg,
146 rm: GpReg,
147 shift: RegShift,
148 amount: u8,
149 sf: bool,
150 },
151 /// SUB Xd, Xn, Rm, <extend> {#amount}
152 SubExtReg {
153 rd: GpReg,
154 rn: GpReg,
155 rm: GpReg,
156 extend: RegExtend,
157 amount: u8,
158 sf: bool,
159 },
160 /// ADDS Xd, Xn, Xm (sets flags)
161 AddsReg {
162 rd: GpReg,
163 rn: GpReg,
164 rm: GpReg,
165 sf: bool,
166 },
167 /// ADDS Xd, Xn, Xm, <shift> #amount (sets flags)
168 AddsShiftReg {
169 rd: GpReg,
170 rn: GpReg,
171 rm: GpReg,
172 shift: RegShift,
173 amount: u8,
174 sf: bool,
175 },
176 /// ADDS Xd, Xn, Rm, <extend> {#amount} (sets flags)
177 AddsExtReg {
178 rd: GpReg,
179 rn: GpReg,
180 rm: GpReg,
181 extend: RegExtend,
182 amount: u8,
183 sf: bool,
184 },
185 /// SUBS Xd, Xn, Xm (sets flags)
186 SubsReg {
187 rd: GpReg,
188 rn: GpReg,
189 rm: GpReg,
190 sf: bool,
191 },
192 /// SUBS Xd, Xn, Xm, <shift> #amount (sets flags)
193 SubsShiftReg {
194 rd: GpReg,
195 rn: GpReg,
196 rm: GpReg,
197 shift: RegShift,
198 amount: u8,
199 sf: bool,
200 },
201 /// SUBS Xd, Xn, Rm, <extend> {#amount} (sets flags)
202 SubsExtReg {
203 rd: GpReg,
204 rn: GpReg,
205 rm: GpReg,
206 extend: RegExtend,
207 amount: u8,
208 sf: bool,
209 },
210 /// MUL Xd, Xn, Xm (alias for MADD Xd, Xn, Xm, XZR)
211 Mul {
212 rd: GpReg,
213 rn: GpReg,
214 rm: GpReg,
215 sf: bool,
216 },
217 /// MADD Xd, Xn, Xm, Xa
218 Madd {
219 rd: GpReg,
220 rn: GpReg,
221 rm: GpReg,
222 ra: GpReg,
223 sf: bool,
224 },
225 /// MSUB Xd, Xn, Xm, Xa
226 Msub {
227 rd: GpReg,
228 rn: GpReg,
229 rm: GpReg,
230 ra: GpReg,
231 sf: bool,
232 },
233 /// UMULL Xd, Wn, Wm
234 Umull { rd: GpReg, rn: GpReg, rm: GpReg },
235 /// SDIV Xd, Xn, Xm
236 Sdiv {
237 rd: GpReg,
238 rn: GpReg,
239 rm: GpReg,
240 sf: bool,
241 },
242 /// UDIV Xd, Xn, Xm
243 Udiv {
244 rd: GpReg,
245 rn: GpReg,
246 rm: GpReg,
247 sf: bool,
248 },
249 /// CSEL Xd, Xn, Xm, cond
250 Csel {
251 rd: GpReg,
252 rn: GpReg,
253 rm: GpReg,
254 cond: Cond,
255 sf: bool,
256 },
257 /// CSINV Xd, Xn, Xm, cond
258 Csinv {
259 rd: GpReg,
260 rn: GpReg,
261 rm: GpReg,
262 cond: Cond,
263 sf: bool,
264 },
265 /// CSNEG Xd, Xn, Xm, cond
266 Csneg {
267 rd: GpReg,
268 rn: GpReg,
269 rm: GpReg,
270 cond: Cond,
271 sf: bool,
272 },
273 /// CCMP Xn, #imm5, #nzcv, cond
274 CcmpImm {
275 rn: GpReg,
276 imm5: u8,
277 nzcv: u8,
278 cond: Cond,
279 sf: bool,
280 },
281 /// CCMN Xn, #imm5, #nzcv, cond
282 CcmnImm {
283 rn: GpReg,
284 imm5: u8,
285 nzcv: u8,
286 cond: Cond,
287 sf: bool,
288 },
289
290 // ---- Logic (register) ----
291 /// AND Xd, Xn, Xm
292 AndReg {
293 rd: GpReg,
294 rn: GpReg,
295 rm: GpReg,
296 sf: bool,
297 },
298 /// ORR Xd, Xn, Xm
299 OrrReg {
300 rd: GpReg,
301 rn: GpReg,
302 rm: GpReg,
303 sf: bool,
304 },
305 /// ORN Xd, Xn, Xm
306 OrnReg {
307 rd: GpReg,
308 rn: GpReg,
309 rm: GpReg,
310 sf: bool,
311 },
312 /// EOR Xd, Xn, Xm
313 EorReg {
314 rd: GpReg,
315 rn: GpReg,
316 rm: GpReg,
317 sf: bool,
318 },
319 /// ANDS Xd, Xn, Xm (sets flags — TST is ANDS with XZR dest)
320 AndsReg {
321 rd: GpReg,
322 rn: GpReg,
323 rm: GpReg,
324 sf: bool,
325 },
326 /// AND Xd, Xn, #imm
327 AndImm {
328 rd: GpReg,
329 rn: GpReg,
330 imm: u64,
331 sf: bool,
332 },
333 /// ORR Xd, Xn, #imm
334 OrrImm {
335 rd: GpReg,
336 rn: GpReg,
337 imm: u64,
338 sf: bool,
339 },
340 /// EOR Xd, Xn, #imm
341 EorImm {
342 rd: GpReg,
343 rn: GpReg,
344 imm: u64,
345 sf: bool,
346 },
347 /// ANDS Xd, Xn, #imm
348 AndsImm {
349 rd: GpReg,
350 rn: GpReg,
351 imm: u64,
352 sf: bool,
353 },
354
355 // ---- Data processing (immediate) ----
356 /// ADD Xd, Xn, #imm12{, LSL #12}
357 AddImm {
358 rd: GpReg,
359 rn: GpReg,
360 imm12: u16,
361 shift: bool,
362 sf: bool,
363 },
364 /// SUB Xd, Xn, #imm12{, LSL #12}
365 SubImm {
366 rd: GpReg,
367 rn: GpReg,
368 imm12: u16,
369 shift: bool,
370 sf: bool,
371 },
372 /// ADDS Xd, Xn, #imm12{, LSL #12}
373 AddsImm {
374 rd: GpReg,
375 rn: GpReg,
376 imm12: u16,
377 shift: bool,
378 sf: bool,
379 },
380 /// SUBS Xd, Xn, #imm12{, LSL #12}
381 SubsImm {
382 rd: GpReg,
383 rn: GpReg,
384 imm12: u16,
385 shift: bool,
386 sf: bool,
387 },
388
389 // ---- Move (wide immediate) ----
390 /// MOVZ Xd, #imm16{, LSL #shift} (shift = 0, 16, 32, 48)
391 Movz {
392 rd: GpReg,
393 imm16: u16,
394 shift: u8,
395 sf: bool,
396 },
397 /// MOVK Xd, #imm16{, LSL #shift} (keep other bits)
398 Movk {
399 rd: GpReg,
400 imm16: u16,
401 shift: u8,
402 sf: bool,
403 },
404 /// MOVN Xd, #imm16{, LSL #shift} (move NOT)
405 Movn {
406 rd: GpReg,
407 imm16: u16,
408 shift: u8,
409 sf: bool,
410 },
411
412 // ---- Shifts (aliases for UBFM/SBFM/EXTR) ----
413 /// LSL Xd, Xn, #amount (alias for UBFM)
414 LslImm {
415 rd: GpReg,
416 rn: GpReg,
417 amount: u8,
418 sf: bool,
419 },
420 /// LSR Xd, Xn, #amount (alias for UBFM)
421 LsrImm {
422 rd: GpReg,
423 rn: GpReg,
424 amount: u8,
425 sf: bool,
426 },
427 /// ASR Xd, Xn, #amount (alias for SBFM)
428 AsrImm {
429 rd: GpReg,
430 rn: GpReg,
431 amount: u8,
432 sf: bool,
433 },
434 /// UBFIZ Xd, Xn, #lsb, #width (alias for UBFM)
435 Ubfiz {
436 rd: GpReg,
437 rn: GpReg,
438 lsb: u8,
439 width: u8,
440 sf: bool,
441 },
442 /// BFI Xd, Xn, #lsb, #width (alias for BFM)
443 Bfi {
444 rd: GpReg,
445 rn: GpReg,
446 lsb: u8,
447 width: u8,
448 sf: bool,
449 },
450 /// BFXIL Xd, Xn, #lsb, #width (alias for BFM)
451 Bfxil {
452 rd: GpReg,
453 rn: GpReg,
454 lsb: u8,
455 width: u8,
456 sf: bool,
457 },
458
459 // ---- Branches ----
460 /// B #offset (unconditional, PC-relative, offset in bytes, must be aligned)
461 B { offset: i32 },
462 /// BL #offset (branch and link / call)
463 Bl { offset: i32 },
464 /// B.cond #offset (conditional branch)
465 BCond { cond: Cond, offset: i32 },
466 /// CBZ Xt, #offset
467 Cbz { rt: GpReg, offset: i32, sf: bool },
468 /// CBNZ Xt, #offset
469 Cbnz { rt: GpReg, offset: i32, sf: bool },
470 /// TBZ Xt, #bit, #offset
471 Tbz {
472 rt: GpReg,
473 bit: u8,
474 offset: i32,
475 sf: bool,
476 },
477 /// TBNZ Xt, #bit, #offset
478 Tbnz {
479 rt: GpReg,
480 bit: u8,
481 offset: i32,
482 sf: bool,
483 },
484 /// RET {Xn}
485 Ret { rn: GpReg },
486 /// BR Xn (indirect branch)
487 Br { rn: GpReg },
488 /// BLR Xn (indirect call)
489 Blr { rn: GpReg },
490 /// CSINC Xd, Xn, Xm, cond
491 Csinc {
492 rd: GpReg,
493 rn: GpReg,
494 rm: GpReg,
495 cond: Cond,
496 sf: bool,
497 },
498
499 // ---- Address generation ----
500 /// ADR Xd, #imm (PC-relative, ±1MB range)
501 Adr { rd: GpReg, imm: i32 },
502 /// ADRP Xd, #imm (page-relative, 4KB pages, ±4GB range)
503 Adrp { rd: GpReg, imm: i32 },
504
505 // ---- Load/Store (unsigned offset) ----
506 /// LDR Xt, [Xn, #offset] (64-bit, offset is byte offset, must be 8-byte aligned)
507 LdrImm64 { rt: GpReg, rn: GpReg, offset: u16 },
508 /// LDR Wt, [Xn, #offset] (32-bit, 4-byte aligned)
509 LdrImm32 { rt: GpReg, rn: GpReg, offset: u16 },
510 /// STR Xt, [Xn, #offset] (64-bit)
511 StrImm64 { rt: GpReg, rn: GpReg, offset: u16 },
512 /// STR Wt, [Xn, #offset] (32-bit)
513 StrImm32 { rt: GpReg, rn: GpReg, offset: u16 },
514 /// LDUR Xt, [Xn, #offset] (64-bit signed unscaled offset)
515 Ldur64 { rt: GpReg, rn: GpReg, offset: i16 },
516 /// LDUR Wt, [Xn, #offset] (32-bit signed unscaled offset)
517 Ldur32 { rt: GpReg, rn: GpReg, offset: i16 },
518 /// STUR Xt, [Xn, #offset] (64-bit signed unscaled offset)
519 Stur64 { rt: GpReg, rn: GpReg, offset: i16 },
520 /// STUR Wt, [Xn, #offset] (32-bit signed unscaled offset)
521 Stur32 { rt: GpReg, rn: GpReg, offset: i16 },
522 /// LDR Xt, [Xn, Rm{, extend}]
523 LdrReg64 {
524 rt: GpReg,
525 rn: GpReg,
526 rm: GpReg,
527 extend: AddrExtend,
528 shift: bool,
529 },
530 /// LDR Wt, [Xn, Rm{, extend}]
531 LdrReg32 {
532 rt: GpReg,
533 rn: GpReg,
534 rm: GpReg,
535 extend: AddrExtend,
536 shift: bool,
537 },
538 /// STR Xt, [Xn, Rm{, extend}]
539 StrReg64 {
540 rt: GpReg,
541 rn: GpReg,
542 rm: GpReg,
543 extend: AddrExtend,
544 shift: bool,
545 },
546 /// STR Wt, [Xn, Rm{, extend}]
547 StrReg32 {
548 rt: GpReg,
549 rn: GpReg,
550 rm: GpReg,
551 extend: AddrExtend,
552 shift: bool,
553 },
554 /// LDRB Wt, [Xn, #offset] (byte load, zero-extend)
555 Ldrb { rt: GpReg, rn: GpReg, offset: u16 },
556 /// LDRSB Wt, [Xn, #offset] (byte load, sign-extend to 32)
557 Ldrsb32 { rt: GpReg, rn: GpReg, offset: u16 },
558 /// LDRSB Xt, [Xn, #offset] (byte load, sign-extend to 64)
559 Ldrsb64 { rt: GpReg, rn: GpReg, offset: u16 },
560 /// LDRH Wt, [Xn, #offset] (halfword load, zero-extend)
561 Ldrh { rt: GpReg, rn: GpReg, offset: u16 },
562 /// LDRSH Wt, [Xn, #offset] (halfword load, sign-extend to 32)
563 Ldrsh32 { rt: GpReg, rn: GpReg, offset: u16 },
564 /// LDRSH Xt, [Xn, #offset] (halfword load, sign-extend to 64)
565 Ldrsh64 { rt: GpReg, rn: GpReg, offset: u16 },
566 /// STRB Wt, [Xn, #offset]
567 Strb { rt: GpReg, rn: GpReg, offset: u16 },
568 /// STRH Wt, [Xn, #offset]
569 Strh { rt: GpReg, rn: GpReg, offset: u16 },
570 /// LDRSW Xt, [Xn, #offset] (32-bit load, sign-extend to 64)
571 Ldrsw { rt: GpReg, rn: GpReg, offset: u16 },
572 /// LDRB Wt, [Xn, Rm{, extend}]
573 LdrbReg {
574 rt: GpReg,
575 rn: GpReg,
576 rm: GpReg,
577 extend: AddrExtend,
578 shift: bool,
579 },
580 /// LDRSB Wt, [Xn, Rm{, extend}]
581 LdrsbReg32 {
582 rt: GpReg,
583 rn: GpReg,
584 rm: GpReg,
585 extend: AddrExtend,
586 shift: bool,
587 },
588 /// LDRSB Xt, [Xn, Rm{, extend}]
589 LdrsbReg64 {
590 rt: GpReg,
591 rn: GpReg,
592 rm: GpReg,
593 extend: AddrExtend,
594 shift: bool,
595 },
596 /// LDRH Wt, [Xn, Rm{, extend}]
597 LdrhReg {
598 rt: GpReg,
599 rn: GpReg,
600 rm: GpReg,
601 extend: AddrExtend,
602 shift: bool,
603 },
604 /// LDRSH Wt, [Xn, Rm{, extend}]
605 LdrshReg32 {
606 rt: GpReg,
607 rn: GpReg,
608 rm: GpReg,
609 extend: AddrExtend,
610 shift: bool,
611 },
612 /// LDRSH Xt, [Xn, Rm{, extend}]
613 LdrshReg64 {
614 rt: GpReg,
615 rn: GpReg,
616 rm: GpReg,
617 extend: AddrExtend,
618 shift: bool,
619 },
620 /// STRB Wt, [Xn, Rm{, extend}]
621 StrbReg {
622 rt: GpReg,
623 rn: GpReg,
624 rm: GpReg,
625 extend: AddrExtend,
626 shift: bool,
627 },
628 /// STRH Wt, [Xn, Rm{, extend}]
629 StrhReg {
630 rt: GpReg,
631 rn: GpReg,
632 rm: GpReg,
633 extend: AddrExtend,
634 shift: bool,
635 },
636 /// LDRSW Xt, [Xn, Rm{, extend}]
637 LdrswReg {
638 rt: GpReg,
639 rn: GpReg,
640 rm: GpReg,
641 extend: AddrExtend,
642 shift: bool,
643 },
644
645 /// LDR Dt, [Xn, #offset]
646 LdrFpImm64 { rt: FpReg, rn: GpReg, offset: u16 },
647 /// LDR St, [Xn, #offset]
648 LdrFpImm32 { rt: FpReg, rn: GpReg, offset: u16 },
649 /// LDR Ht, [Xn, #offset]
650 LdrFpImm16 { rt: FpReg, rn: GpReg, offset: u16 },
651 /// LDR Bt, [Xn, #offset]
652 LdrFpImm8 { rt: FpReg, rn: GpReg, offset: u16 },
653 /// LDR Qt, [Xn, #offset]
654 LdrFpImm128 { rt: FpReg, rn: GpReg, offset: u16 },
655 /// STR Dt, [Xn, #offset]
656 StrFpImm64 { rt: FpReg, rn: GpReg, offset: u16 },
657 /// STR St, [Xn, #offset]
658 StrFpImm32 { rt: FpReg, rn: GpReg, offset: u16 },
659 /// STR Ht, [Xn, #offset]
660 StrFpImm16 { rt: FpReg, rn: GpReg, offset: u16 },
661 /// STR Bt, [Xn, #offset]
662 StrFpImm8 { rt: FpReg, rn: GpReg, offset: u16 },
663 /// STR Qt, [Xn, #offset]
664 StrFpImm128 { rt: FpReg, rn: GpReg, offset: u16 },
665 /// LDUR Dt, [Xn, #offset]
666 LdurFp64 { rt: FpReg, rn: GpReg, offset: i16 },
667 /// LDUR St, [Xn, #offset]
668 LdurFp32 { rt: FpReg, rn: GpReg, offset: i16 },
669 /// LDUR Ht, [Xn, #offset]
670 LdurFp16 { rt: FpReg, rn: GpReg, offset: i16 },
671 /// LDUR Bt, [Xn, #offset]
672 LdurFp8 { rt: FpReg, rn: GpReg, offset: i16 },
673 /// LDUR Qt, [Xn, #offset]
674 LdurFp128 { rt: FpReg, rn: GpReg, offset: i16 },
675 /// STUR Dt, [Xn, #offset]
676 SturFp64 { rt: FpReg, rn: GpReg, offset: i16 },
677 /// STUR St, [Xn, #offset]
678 SturFp32 { rt: FpReg, rn: GpReg, offset: i16 },
679 /// STUR Ht, [Xn, #offset]
680 SturFp16 { rt: FpReg, rn: GpReg, offset: i16 },
681 /// STUR Bt, [Xn, #offset]
682 SturFp8 { rt: FpReg, rn: GpReg, offset: i16 },
683 /// STUR Qt, [Xn, #offset]
684 SturFp128 { rt: FpReg, rn: GpReg, offset: i16 },
685 /// LDR Dt, [Xn, Rm{, extend}]
686 LdrFpReg64 {
687 rt: FpReg,
688 rn: GpReg,
689 rm: GpReg,
690 extend: AddrExtend,
691 shift: bool,
692 },
693 /// LDR St, [Xn, Rm{, extend}]
694 LdrFpReg32 {
695 rt: FpReg,
696 rn: GpReg,
697 rm: GpReg,
698 extend: AddrExtend,
699 shift: bool,
700 },
701 /// LDR Qt, [Xn, Rm{, extend}]
702 LdrFpReg128 {
703 rt: FpReg,
704 rn: GpReg,
705 rm: GpReg,
706 extend: AddrExtend,
707 shift: bool,
708 },
709 /// STR Dt, [Xn, Rm{, extend}]
710 StrFpReg64 {
711 rt: FpReg,
712 rn: GpReg,
713 rm: GpReg,
714 extend: AddrExtend,
715 shift: bool,
716 },
717 /// STR St, [Xn, Rm{, extend}]
718 StrFpReg32 {
719 rt: FpReg,
720 rn: GpReg,
721 rm: GpReg,
722 extend: AddrExtend,
723 shift: bool,
724 },
725 /// STR Qt, [Xn, Rm{, extend}]
726 StrFpReg128 {
727 rt: FpReg,
728 rn: GpReg,
729 rm: GpReg,
730 extend: AddrExtend,
731 shift: bool,
732 },
733
734 /// LDR Xt, label
735 LdrLit64 { rt: GpReg, offset: i32 },
736 /// LDR Wt, label
737 LdrLit32 { rt: GpReg, offset: i32 },
738 /// LDRSW Xt, label
739 LdrswLit { rt: GpReg, offset: i32 },
740 /// LDR Dt, label
741 LdrFpLit64 { rt: FpReg, offset: i32 },
742 /// LDR St, label
743 LdrFpLit32 { rt: FpReg, offset: i32 },
744 /// LDR Qt, label
745 LdrFpLit128 { rt: FpReg, offset: i32 },
746
747 // ---- Load/Store (pre-index) ----
748 /// LDR Wt, [Xn, #offset]! (pre-index, 32-bit)
749 LdrPre32 { rt: GpReg, rn: GpReg, offset: i16 },
750 /// STR Wt, [Xn, #offset]! (pre-index, 32-bit)
751 StrPre32 { rt: GpReg, rn: GpReg, offset: i16 },
752 /// LDRB Wt, [Xn, #offset]! (pre-index, byte)
753 LdrbPre { rt: GpReg, rn: GpReg, offset: i16 },
754 /// LDRSB Wt, [Xn, #offset]! (pre-index, byte)
755 LdrsbPre32 { rt: GpReg, rn: GpReg, offset: i16 },
756 /// LDRSB Xt, [Xn, #offset]! (pre-index, byte)
757 LdrsbPre64 { rt: GpReg, rn: GpReg, offset: i16 },
758 /// STRB Wt, [Xn, #offset]! (pre-index, byte)
759 StrbPre { rt: GpReg, rn: GpReg, offset: i16 },
760 /// LDRH Wt, [Xn, #offset]! (pre-index, halfword)
761 LdrhPre { rt: GpReg, rn: GpReg, offset: i16 },
762 /// LDRSH Wt, [Xn, #offset]! (pre-index, halfword)
763 LdrshPre32 { rt: GpReg, rn: GpReg, offset: i16 },
764 /// LDRSH Xt, [Xn, #offset]! (pre-index, halfword)
765 LdrshPre64 { rt: GpReg, rn: GpReg, offset: i16 },
766 /// STRH Wt, [Xn, #offset]! (pre-index, halfword)
767 StrhPre { rt: GpReg, rn: GpReg, offset: i16 },
768 /// LDR Xt, [Xn, #offset]! (pre-index, 64-bit)
769 LdrPre64 { rt: GpReg, rn: GpReg, offset: i16 },
770 /// STR Xt, [Xn, #offset]! (pre-index, 64-bit)
771 StrPre64 { rt: GpReg, rn: GpReg, offset: i16 },
772 /// LDR Dt, [Xn, #offset]! (pre-index, double)
773 LdrFpPre64 { rt: FpReg, rn: GpReg, offset: i16 },
774 /// STR Dt, [Xn, #offset]! (pre-index, double)
775 StrFpPre64 { rt: FpReg, rn: GpReg, offset: i16 },
776 /// LDR St, [Xn, #offset]! (pre-index, single)
777 LdrFpPre32 { rt: FpReg, rn: GpReg, offset: i16 },
778 /// STR St, [Xn, #offset]! (pre-index, single)
779 StrFpPre32 { rt: FpReg, rn: GpReg, offset: i16 },
780 /// LDR Qt, [Xn, #offset]! (pre-index, vector)
781 LdrFpPre128 { rt: FpReg, rn: GpReg, offset: i16 },
782 /// STR Qt, [Xn, #offset]! (pre-index, vector)
783 StrFpPre128 { rt: FpReg, rn: GpReg, offset: i16 },
784
785 // ---- Load/Store (post-index) ----
786 /// LDR Wt, [Xn], #offset (post-index, 32-bit)
787 LdrPost32 { rt: GpReg, rn: GpReg, offset: i16 },
788 /// STR Wt, [Xn], #offset (post-index, 32-bit)
789 StrPost32 { rt: GpReg, rn: GpReg, offset: i16 },
790 /// LDRB Wt, [Xn], #offset (post-index, byte)
791 LdrbPost { rt: GpReg, rn: GpReg, offset: i16 },
792 /// LDRSB Wt, [Xn], #offset (post-index, byte)
793 LdrsbPost32 { rt: GpReg, rn: GpReg, offset: i16 },
794 /// LDRSB Xt, [Xn], #offset (post-index, byte)
795 LdrsbPost64 { rt: GpReg, rn: GpReg, offset: i16 },
796 /// STRB Wt, [Xn], #offset (post-index, byte)
797 StrbPost { rt: GpReg, rn: GpReg, offset: i16 },
798 /// LDRH Wt, [Xn], #offset (post-index, halfword)
799 LdrhPost { rt: GpReg, rn: GpReg, offset: i16 },
800 /// LDRSH Wt, [Xn], #offset (post-index, halfword)
801 LdrshPost32 { rt: GpReg, rn: GpReg, offset: i16 },
802 /// LDRSH Xt, [Xn], #offset (post-index, halfword)
803 LdrshPost64 { rt: GpReg, rn: GpReg, offset: i16 },
804 /// STRH Wt, [Xn], #offset (post-index, halfword)
805 StrhPost { rt: GpReg, rn: GpReg, offset: i16 },
806 /// LDR Xt, [Xn], #offset (post-index, 64-bit)
807 LdrPost64 { rt: GpReg, rn: GpReg, offset: i16 },
808 /// STR Xt, [Xn], #offset (post-index, 64-bit)
809 StrPost64 { rt: GpReg, rn: GpReg, offset: i16 },
810 /// LDR Dt, [Xn], #offset (post-index, double)
811 LdrFpPost64 { rt: FpReg, rn: GpReg, offset: i16 },
812 /// STR Dt, [Xn], #offset (post-index, double)
813 StrFpPost64 { rt: FpReg, rn: GpReg, offset: i16 },
814 /// LDR St, [Xn], #offset (post-index, single)
815 LdrFpPost32 { rt: FpReg, rn: GpReg, offset: i16 },
816 /// STR St, [Xn], #offset (post-index, single)
817 StrFpPost32 { rt: FpReg, rn: GpReg, offset: i16 },
818 /// LDR Qt, [Xn], #offset (post-index, vector)
819 LdrFpPost128 { rt: FpReg, rn: GpReg, offset: i16 },
820 /// STR Qt, [Xn], #offset (post-index, vector)
821 StrFpPost128 { rt: FpReg, rn: GpReg, offset: i16 },
822
823 // ---- Atomic memory operations ----
824 /// LDAPRB Wt, [Xn]
825 Ldaprb { rt: GpReg, rn: GpReg },
826 /// LDAPRH Wt, [Xn]
827 Ldaprh { rt: GpReg, rn: GpReg },
828 /// LDAPR Wt, [Xn]
829 Ldapr32 { rt: GpReg, rn: GpReg },
830 /// LDAPR Xt, [Xn]
831 Ldapr64 { rt: GpReg, rn: GpReg },
832 /// STLRB Wt, [Xn]
833 Stlrb { rt: GpReg, rn: GpReg },
834 /// STLRH Wt, [Xn]
835 Stlrh { rt: GpReg, rn: GpReg },
836 /// STLR Wt, [Xn]
837 Stlr32 { rt: GpReg, rn: GpReg },
838 /// STLR Xt, [Xn]
839 Stlr64 { rt: GpReg, rn: GpReg },
840 /// LDADDALB Ws, Wt, [Xn]
841 Ldaddalb { rs: GpReg, rt: GpReg, rn: GpReg },
842 /// LDADDALH Ws, Wt, [Xn]
843 Ldaddalh { rs: GpReg, rt: GpReg, rn: GpReg },
844 /// LDADDAL Ws, Wt, [Xn]
845 Ldaddal32 { rs: GpReg, rt: GpReg, rn: GpReg },
846 /// LDADDAL Xs, Xt, [Xn]
847 Ldaddal64 { rs: GpReg, rt: GpReg, rn: GpReg },
848 /// LDUMAXALB Ws, Wt, [Xn]
849 Ldumaxalb { rs: GpReg, rt: GpReg, rn: GpReg },
850 /// LDUMAXALH Ws, Wt, [Xn]
851 Ldumaxalh { rs: GpReg, rt: GpReg, rn: GpReg },
852 /// LDUMAXAL Ws, Wt, [Xn]
853 Ldumaxal32 { rs: GpReg, rt: GpReg, rn: GpReg },
854 /// LDUMAXAL Xs, Xt, [Xn]
855 Ldumaxal64 { rs: GpReg, rt: GpReg, rn: GpReg },
856 /// LDSMAXALB Ws, Wt, [Xn]
857 Ldsmaxalb { rs: GpReg, rt: GpReg, rn: GpReg },
858 /// LDSMAXALH Ws, Wt, [Xn]
859 Ldsmaxalh { rs: GpReg, rt: GpReg, rn: GpReg },
860 /// LDSMAXAL Ws, Wt, [Xn]
861 Ldsmaxal32 { rs: GpReg, rt: GpReg, rn: GpReg },
862 /// LDSMAXAL Xs, Xt, [Xn]
863 Ldsmaxal64 { rs: GpReg, rt: GpReg, rn: GpReg },
864 /// LDUMINALB Ws, Wt, [Xn]
865 Lduminalb { rs: GpReg, rt: GpReg, rn: GpReg },
866 /// LDUMINALH Ws, Wt, [Xn]
867 Lduminalh { rs: GpReg, rt: GpReg, rn: GpReg },
868 /// LDUMINAL Ws, Wt, [Xn]
869 Lduminal32 { rs: GpReg, rt: GpReg, rn: GpReg },
870 /// LDUMINAL Xs, Xt, [Xn]
871 Lduminal64 { rs: GpReg, rt: GpReg, rn: GpReg },
872 /// LDSMINALB Ws, Wt, [Xn]
873 Ldsminalb { rs: GpReg, rt: GpReg, rn: GpReg },
874 /// LDSMINALH Ws, Wt, [Xn]
875 Ldsminalh { rs: GpReg, rt: GpReg, rn: GpReg },
876 /// LDSMINAL Ws, Wt, [Xn]
877 Ldsminal32 { rs: GpReg, rt: GpReg, rn: GpReg },
878 /// LDSMINAL Xs, Xt, [Xn]
879 Ldsminal64 { rs: GpReg, rt: GpReg, rn: GpReg },
880 /// LDCLRALB Ws, Wt, [Xn]
881 Ldclralb { rs: GpReg, rt: GpReg, rn: GpReg },
882 /// LDCLRALH Ws, Wt, [Xn]
883 Ldclralh { rs: GpReg, rt: GpReg, rn: GpReg },
884 /// LDCLRAL Ws, Wt, [Xn]
885 Ldclral32 { rs: GpReg, rt: GpReg, rn: GpReg },
886 /// LDCLRAL Xs, Xt, [Xn]
887 Ldclral64 { rs: GpReg, rt: GpReg, rn: GpReg },
888 /// LDEORALB Ws, Wt, [Xn]
889 Ldeoralb { rs: GpReg, rt: GpReg, rn: GpReg },
890 /// LDEORALH Ws, Wt, [Xn]
891 Ldeoralh { rs: GpReg, rt: GpReg, rn: GpReg },
892 /// LDEORAL Ws, Wt, [Xn]
893 Ldeoral32 { rs: GpReg, rt: GpReg, rn: GpReg },
894 /// LDEORAL Xs, Xt, [Xn]
895 Ldeoral64 { rs: GpReg, rt: GpReg, rn: GpReg },
896 /// LDSETALB Ws, Wt, [Xn]
897 Ldsetalb { rs: GpReg, rt: GpReg, rn: GpReg },
898 /// LDSETALH Ws, Wt, [Xn]
899 Ldsetalh { rs: GpReg, rt: GpReg, rn: GpReg },
900 /// LDSETAL Ws, Wt, [Xn]
901 Ldsetal32 { rs: GpReg, rt: GpReg, rn: GpReg },
902 /// LDSETAL Xs, Xt, [Xn]
903 Ldsetal64 { rs: GpReg, rt: GpReg, rn: GpReg },
904 /// SWPAL Ws, Wt, [Xn]
905 Swpal32 { rs: GpReg, rt: GpReg, rn: GpReg },
906 /// SWPAL Xs, Xt, [Xn]
907 Swpal64 { rs: GpReg, rt: GpReg, rn: GpReg },
908 /// SWPALB Ws, Wt, [Xn]
909 Swpalb { rs: GpReg, rt: GpReg, rn: GpReg },
910 /// SWPALH Ws, Wt, [Xn]
911 Swpalh { rs: GpReg, rt: GpReg, rn: GpReg },
912 /// CASALB Ws, Wt, [Xn]
913 Casalb { rs: GpReg, rt: GpReg, rn: GpReg },
914 /// CASALH Ws, Wt, [Xn]
915 Casalh { rs: GpReg, rt: GpReg, rn: GpReg },
916 /// CASAL Ws, Wt, [Xn]
917 Casal32 { rs: GpReg, rt: GpReg, rn: GpReg },
918 /// CASAL Xs, Xt, [Xn]
919 Casal64 { rs: GpReg, rt: GpReg, rn: GpReg },
920
921 // ---- Load/Store pair ----
922 /// STP Wt1, Wt2, [Xn, #offset] (signed offset, 32-bit)
923 StpOff32 {
924 rt1: GpReg,
925 rt2: GpReg,
926 rn: GpReg,
927 offset: i16,
928 },
929 /// STP Xt1, Xt2, [Xn, #offset] (signed offset, 64-bit)
930 StpOff64 {
931 rt1: GpReg,
932 rt2: GpReg,
933 rn: GpReg,
934 offset: i16,
935 },
936 /// LDP Wt1, Wt2, [Xn, #offset] (signed offset, 32-bit)
937 LdpOff32 {
938 rt1: GpReg,
939 rt2: GpReg,
940 rn: GpReg,
941 offset: i16,
942 },
943 /// LDP Xt1, Xt2, [Xn, #offset] (signed offset, 64-bit)
944 LdpOff64 {
945 rt1: GpReg,
946 rt2: GpReg,
947 rn: GpReg,
948 offset: i16,
949 },
950 /// STP Wt1, Wt2, [Xn, #offset]! (pre-index, 32-bit)
951 StpPre32 {
952 rt1: GpReg,
953 rt2: GpReg,
954 rn: GpReg,
955 offset: i16,
956 },
957 /// STP Xt1, Xt2, [Xn, #offset]! (pre-index, 64-bit)
958 StpPre64 {
959 rt1: GpReg,
960 rt2: GpReg,
961 rn: GpReg,
962 offset: i16,
963 },
964 /// STP Wt1, Wt2, [Xn], #offset (post-index, 32-bit)
965 StpPost32 {
966 rt1: GpReg,
967 rt2: GpReg,
968 rn: GpReg,
969 offset: i16,
970 },
971 /// STP Xt1, Xt2, [Xn], #offset (post-index, 64-bit)
972 StpPost64 {
973 rt1: GpReg,
974 rt2: GpReg,
975 rn: GpReg,
976 offset: i16,
977 },
978 /// LDP Wt1, Wt2, [Xn, #offset]! (pre-index, 32-bit)
979 LdpPre32 {
980 rt1: GpReg,
981 rt2: GpReg,
982 rn: GpReg,
983 offset: i16,
984 },
985 /// LDP Xt1, Xt2, [Xn, #offset]! (pre-index, 64-bit)
986 LdpPre64 {
987 rt1: GpReg,
988 rt2: GpReg,
989 rn: GpReg,
990 offset: i16,
991 },
992 /// LDP Wt1, Wt2, [Xn], #offset (post-index, 32-bit)
993 LdpPost32 {
994 rt1: GpReg,
995 rt2: GpReg,
996 rn: GpReg,
997 offset: i16,
998 },
999 /// LDP Xt1, Xt2, [Xn], #offset (post-index, 64-bit)
1000 LdpPost64 {
1001 rt1: GpReg,
1002 rt2: GpReg,
1003 rn: GpReg,
1004 offset: i16,
1005 },
1006 /// STP Dt1, Dt2, [Xn, #offset] (signed offset, double)
1007 StpFpOff64 {
1008 rt1: FpReg,
1009 rt2: FpReg,
1010 rn: GpReg,
1011 offset: i16,
1012 },
1013 /// LDP Dt1, Dt2, [Xn, #offset] (signed offset, double)
1014 LdpFpOff64 {
1015 rt1: FpReg,
1016 rt2: FpReg,
1017 rn: GpReg,
1018 offset: i16,
1019 },
1020 /// STP Dt1, Dt2, [Xn, #offset]! (pre-index, double)
1021 StpFpPre64 {
1022 rt1: FpReg,
1023 rt2: FpReg,
1024 rn: GpReg,
1025 offset: i16,
1026 },
1027 /// STP Dt1, Dt2, [Xn], #offset (post-index, double)
1028 StpFpPost64 {
1029 rt1: FpReg,
1030 rt2: FpReg,
1031 rn: GpReg,
1032 offset: i16,
1033 },
1034 /// LDP Dt1, Dt2, [Xn, #offset]! (pre-index, double)
1035 LdpFpPre64 {
1036 rt1: FpReg,
1037 rt2: FpReg,
1038 rn: GpReg,
1039 offset: i16,
1040 },
1041 /// LDP Dt1, Dt2, [Xn], #offset (post-index, double)
1042 LdpFpPost64 {
1043 rt1: FpReg,
1044 rt2: FpReg,
1045 rn: GpReg,
1046 offset: i16,
1047 },
1048 /// STP St1, St2, [Xn, #offset] (signed offset, single)
1049 StpFpOff32 {
1050 rt1: FpReg,
1051 rt2: FpReg,
1052 rn: GpReg,
1053 offset: i16,
1054 },
1055 /// LDP St1, St2, [Xn, #offset] (signed offset, single)
1056 LdpFpOff32 {
1057 rt1: FpReg,
1058 rt2: FpReg,
1059 rn: GpReg,
1060 offset: i16,
1061 },
1062 /// STP St1, St2, [Xn, #offset]! (pre-index, single)
1063 StpFpPre32 {
1064 rt1: FpReg,
1065 rt2: FpReg,
1066 rn: GpReg,
1067 offset: i16,
1068 },
1069 /// STP St1, St2, [Xn], #offset (post-index, single)
1070 StpFpPost32 {
1071 rt1: FpReg,
1072 rt2: FpReg,
1073 rn: GpReg,
1074 offset: i16,
1075 },
1076 /// LDP St1, St2, [Xn, #offset]! (pre-index, single)
1077 LdpFpPre32 {
1078 rt1: FpReg,
1079 rt2: FpReg,
1080 rn: GpReg,
1081 offset: i16,
1082 },
1083 /// LDP St1, St2, [Xn], #offset (post-index, single)
1084 LdpFpPost32 {
1085 rt1: FpReg,
1086 rt2: FpReg,
1087 rn: GpReg,
1088 offset: i16,
1089 },
1090 /// STP Qt1, Qt2, [Xn, #offset] (signed offset, 128-bit)
1091 StpFpOff128 {
1092 rt1: FpReg,
1093 rt2: FpReg,
1094 rn: GpReg,
1095 offset: i16,
1096 },
1097 /// LDP Qt1, Qt2, [Xn, #offset] (signed offset, 128-bit)
1098 LdpFpOff128 {
1099 rt1: FpReg,
1100 rt2: FpReg,
1101 rn: GpReg,
1102 offset: i16,
1103 },
1104 /// STP Qt1, Qt2, [Xn, #offset]! (pre-index, 128-bit)
1105 StpFpPre128 {
1106 rt1: FpReg,
1107 rt2: FpReg,
1108 rn: GpReg,
1109 offset: i16,
1110 },
1111 /// STP Qt1, Qt2, [Xn], #offset (post-index, 128-bit)
1112 StpFpPost128 {
1113 rt1: FpReg,
1114 rt2: FpReg,
1115 rn: GpReg,
1116 offset: i16,
1117 },
1118 /// LDP Qt1, Qt2, [Xn, #offset]! (pre-index, 128-bit)
1119 LdpFpPre128 {
1120 rt1: FpReg,
1121 rt2: FpReg,
1122 rn: GpReg,
1123 offset: i16,
1124 },
1125 /// LDP Qt1, Qt2, [Xn], #offset (post-index, 128-bit)
1126 LdpFpPost128 {
1127 rt1: FpReg,
1128 rt2: FpReg,
1129 rn: GpReg,
1130 offset: i16,
1131 },
1132
1133 // ---- Floating point arithmetic ----
1134 /// FADD Dd, Dn, Dm (double)
1135 FaddD { rd: FpReg, rn: FpReg, rm: FpReg },
1136 /// FSUB Dd, Dn, Dm (double)
1137 FsubD { rd: FpReg, rn: FpReg, rm: FpReg },
1138 /// FMUL Dd, Dn, Dm (double)
1139 FmulD { rd: FpReg, rn: FpReg, rm: FpReg },
1140 /// FDIV Dd, Dn, Dm (double)
1141 FdivD { rd: FpReg, rn: FpReg, rm: FpReg },
1142 /// FADD Sd, Sn, Sm (single)
1143 FaddS { rd: FpReg, rn: FpReg, rm: FpReg },
1144 /// FADD.2D Vd, Vn, Vm
1145 FaddV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1146 /// FADD.4S Vd, Vn, Vm
1147 FaddV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1148 /// FADDP.2D Vd, Vn, Vm
1149 FaddpV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1150 /// FADDP.4S Vd, Vn, Vm
1151 FaddpV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1152 /// FMAXP.2D Vd, Vn, Vm
1153 FmaxpV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1154 /// FMAXP.4S Vd, Vn, Vm
1155 FmaxpV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1156 /// FMINP.2D Vd, Vn, Vm
1157 FminpV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1158 /// FMINP.4S Vd, Vn, Vm
1159 FminpV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1160 /// FMAXNMP.4S Vd, Vn, Vm
1161 FmaxnmpV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1162 /// FMINNMP.4S Vd, Vn, Vm
1163 FminnmpV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1164 /// FADDP.2S Sd, Vn
1165 FaddpV2S { rd: FpReg, rn: FpReg },
1166 /// FADDP.2D Dd, Vn
1167 FaddpV2DScalar { rd: FpReg, rn: FpReg },
1168 /// FMAXP.2D Dd, Vn
1169 FmaxpV2DScalar { rd: FpReg, rn: FpReg },
1170 /// FMINP.2D Dd, Vn
1171 FminpV2DScalar { rd: FpReg, rn: FpReg },
1172 /// FMAXNMP.2D Dd, Vn
1173 FmaxnmpV2DScalar { rd: FpReg, rn: FpReg },
1174 /// FMINNMP.2D Dd, Vn
1175 FminnmpV2DScalar { rd: FpReg, rn: FpReg },
1176 /// FMLA.4S Vd, Vn, Vm
1177 FmlaV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1178 /// FMLA.2D Vd, Vn, Vm
1179 FmlaV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1180 /// FMLS.4S Vd, Vn, Vm
1181 FmlsV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1182 /// FMLS.2D Vd, Vn, Vm
1183 FmlsV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1184 /// ADD.4S Vd, Vn, Vm
1185 AddV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1186 /// ADDP.2D Vd, Vn, Vm
1187 AddpV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1188 /// ADDP.16B Vd, Vn, Vm
1189 AddpV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1190 /// ADDP.8H Vd, Vn, Vm
1191 AddpV8H { rd: FpReg, rn: FpReg, rm: FpReg },
1192 /// ADDP.4S Vd, Vn, Vm
1193 AddpV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1194 /// SMAXP.16B Vd, Vn, Vm
1195 SmaxpV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1196 /// SMAXP.8H Vd, Vn, Vm
1197 SmaxpV8H { rd: FpReg, rn: FpReg, rm: FpReg },
1198 /// SMAXP.4S Vd, Vn, Vm
1199 SmaxpV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1200 /// SMINP.16B Vd, Vn, Vm
1201 SminpV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1202 /// SMINP.8H Vd, Vn, Vm
1203 SminpV8H { rd: FpReg, rn: FpReg, rm: FpReg },
1204 /// SMINP.4S Vd, Vn, Vm
1205 SminpV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1206 /// FMAX.2D Vd, Vn, Vm
1207 FmaxV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1208 /// FMAX.4S Vd, Vn, Vm
1209 FmaxV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1210 /// FMIN.2D Vd, Vn, Vm
1211 FminV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1212 /// FMIN.4S Vd, Vn, Vm
1213 FminV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1214 /// FMAXNM.2D Vd, Vn, Vm
1215 FmaxnmV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1216 /// FMAXNM.4S Vd, Vn, Vm
1217 FmaxnmV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1218 /// FMAXNMP.2D Vd, Vn, Vm
1219 FmaxnmpV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1220 /// FMINNM.2D Vd, Vn, Vm
1221 FminnmV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1222 /// FMINNM.4S Vd, Vn, Vm
1223 FminnmV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1224 /// FMINNMP.2D Vd, Vn, Vm
1225 FminnmpV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1226 /// SMAX.4S Vd, Vn, Vm
1227 SmaxV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1228 /// SMIN.4S Vd, Vn, Vm
1229 SminV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1230 /// UMAX.4S Vd, Vn, Vm
1231 UmaxV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1232 /// UMAXP.16B Vd, Vn, Vm
1233 UmaxpV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1234 /// UMAXP.8H Vd, Vn, Vm
1235 UmaxpV8H { rd: FpReg, rn: FpReg, rm: FpReg },
1236 /// UMIN.4S Vd, Vn, Vm
1237 UminV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1238 /// UMINP.16B Vd, Vn, Vm
1239 UminpV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1240 /// UMINP.8H Vd, Vn, Vm
1241 UminpV8H { rd: FpReg, rn: FpReg, rm: FpReg },
1242 /// UMAXP.4S Vd, Vn, Vm
1243 UmaxpV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1244 /// UMINP.4S Vd, Vn, Vm
1245 UminpV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1246 /// ADDV.16B Bd, Vn
1247 AddvV16B { rd: FpReg, rn: FpReg },
1248 /// ADDV.8H Hd, Vn
1249 AddvV8H { rd: FpReg, rn: FpReg },
1250 /// ADDV.4S Sd, Vn
1251 AddvV4S { rd: FpReg, rn: FpReg },
1252 /// UMAXV.16B Bd, Vn
1253 UmaxvV16B { rd: FpReg, rn: FpReg },
1254 /// UMAXV.8H Hd, Vn
1255 UmaxvV8H { rd: FpReg, rn: FpReg },
1256 /// UMAXV.4S Sd, Vn
1257 UmaxvV4S { rd: FpReg, rn: FpReg },
1258 /// SMAXV.16B Bd, Vn
1259 SmaxvV16B { rd: FpReg, rn: FpReg },
1260 /// SMAXV.8H Hd, Vn
1261 SmaxvV8H { rd: FpReg, rn: FpReg },
1262 /// SMAXV.4S Sd, Vn
1263 SmaxvV4S { rd: FpReg, rn: FpReg },
1264 /// UMINV.16B Bd, Vn
1265 UminvV16B { rd: FpReg, rn: FpReg },
1266 /// UMINV.8H Hd, Vn
1267 UminvV8H { rd: FpReg, rn: FpReg },
1268 /// UMINV.4S Sd, Vn
1269 UminvV4S { rd: FpReg, rn: FpReg },
1270 /// SMINV.16B Bd, Vn
1271 SminvV16B { rd: FpReg, rn: FpReg },
1272 /// SMINV.8H Hd, Vn
1273 SminvV8H { rd: FpReg, rn: FpReg },
1274 /// SMINV.4S Sd, Vn
1275 SminvV4S { rd: FpReg, rn: FpReg },
1276 /// FMAXV.4S Sd, Vn
1277 FmaxvV4S { rd: FpReg, rn: FpReg },
1278 /// FMINV.4S Sd, Vn
1279 FminvV4S { rd: FpReg, rn: FpReg },
1280 /// FMAXNMV.4S Sd, Vn
1281 FmaxnmvV4S { rd: FpReg, rn: FpReg },
1282 /// FMINNMV.4S Sd, Vn
1283 FminnmvV4S { rd: FpReg, rn: FpReg },
1284 /// FSUB.2D Vd, Vn, Vm
1285 FsubV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1286 /// FSUB.4S Vd, Vn, Vm
1287 FsubV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1288 /// SUB.4S Vd, Vn, Vm
1289 SubV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1290 /// FSUB Sd, Sn, Sm (single)
1291 FsubS { rd: FpReg, rn: FpReg, rm: FpReg },
1292 /// FMUL.2D Vd, Vn, Vm
1293 FmulV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1294 /// FMUL.4S Vd, Vn, Vm
1295 FmulV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1296 /// FMUL Sd, Sn, Sm (single)
1297 FmulS { rd: FpReg, rn: FpReg, rm: FpReg },
1298 /// FDIV.2D Vd, Vn, Vm
1299 FdivV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1300 /// FABD.2D Vd, Vn, Vm
1301 FabdV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1302 /// FDIV.4S Vd, Vn, Vm
1303 FdivV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1304 /// FABS.4S Vd, Vn
1305 FabsV4S { rd: FpReg, rn: FpReg },
1306 /// FABS.2D Vd, Vn
1307 FabsV2D { rd: FpReg, rn: FpReg },
1308 /// FNEG.4S Vd, Vn
1309 FnegV4S { rd: FpReg, rn: FpReg },
1310 /// FNEG.2D Vd, Vn
1311 FnegV2D { rd: FpReg, rn: FpReg },
1312 /// FSQRT.4S Vd, Vn
1313 FsqrtV4S { rd: FpReg, rn: FpReg },
1314 /// FSQRT.2D Vd, Vn
1315 FsqrtV2D { rd: FpReg, rn: FpReg },
1316 /// SCVTF.4S Vd, Vn
1317 ScvtfV4S { rd: FpReg, rn: FpReg },
1318 /// SCVTF.2D Vd, Vn
1319 ScvtfV2D { rd: FpReg, rn: FpReg },
1320 /// UCVTF.4S Vd, Vn
1321 UcvtfV4S { rd: FpReg, rn: FpReg },
1322 /// UCVTF.2D Vd, Vn
1323 UcvtfV2D { rd: FpReg, rn: FpReg },
1324 /// FCVTZS.4S Vd, Vn
1325 FcvtzsV4S { rd: FpReg, rn: FpReg },
1326 /// FCVTZS.2D Vd, Vn
1327 FcvtzsV2D { rd: FpReg, rn: FpReg },
1328 /// FCVTZU.4S Vd, Vn
1329 FcvtzuV4S { rd: FpReg, rn: FpReg },
1330 /// FCVTZU.2D Vd, Vn
1331 FcvtzuV2D { rd: FpReg, rn: FpReg },
1332 /// FRECPE.4S Vd, Vn
1333 FrecpeV4S { rd: FpReg, rn: FpReg },
1334 /// FRECPE.2D Vd, Vn
1335 FrecpeV2D { rd: FpReg, rn: FpReg },
1336 /// FRECPS.4S Vd, Vn, Vm
1337 FrecpsV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1338 /// FRECPS.2D Vd, Vn, Vm
1339 FrecpsV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1340 /// FRSQRTE.4S Vd, Vn
1341 FrsqrteV4S { rd: FpReg, rn: FpReg },
1342 /// FRSQRTE.2D Vd, Vn
1343 FrsqrteV2D { rd: FpReg, rn: FpReg },
1344 /// FRSQRTS.4S Vd, Vn, Vm
1345 FrsqrtsV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1346 /// FRSQRTS.2D Vd, Vn, Vm
1347 FrsqrtsV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1348 /// FRINTN.4S Vd, Vn
1349 FrintnV4S { rd: FpReg, rn: FpReg },
1350 /// FRINTN.2D Vd, Vn
1351 FrintnV2D { rd: FpReg, rn: FpReg },
1352 /// FRINTM.4S Vd, Vn
1353 FrintmV4S { rd: FpReg, rn: FpReg },
1354 /// FRINTM.2D Vd, Vn
1355 FrintmV2D { rd: FpReg, rn: FpReg },
1356 /// FRINTP.4S Vd, Vn
1357 FrintpV4S { rd: FpReg, rn: FpReg },
1358 /// FRINTP.2D Vd, Vn
1359 FrintpV2D { rd: FpReg, rn: FpReg },
1360 /// FRINTZ.4S Vd, Vn
1361 FrintzV4S { rd: FpReg, rn: FpReg },
1362 /// FRINTZ.2D Vd, Vn
1363 FrintzV2D { rd: FpReg, rn: FpReg },
1364 /// FRINTA.4S Vd, Vn
1365 FrintaV4S { rd: FpReg, rn: FpReg },
1366 /// FRINTA.2D Vd, Vn
1367 FrintaV2D { rd: FpReg, rn: FpReg },
1368 /// FRINTI.4S Vd, Vn
1369 FrintiV4S { rd: FpReg, rn: FpReg },
1370 /// FRINTI.2D Vd, Vn
1371 FrintiV2D { rd: FpReg, rn: FpReg },
1372 /// FDIV Sd, Sn, Sm (single)
1373 FdivS { rd: FpReg, rn: FpReg, rm: FpReg },
1374 /// FMOV Dd, Dn
1375 FmovRegD { rd: FpReg, rn: FpReg },
1376 /// FMOV Sd, Sn
1377 FmovRegS { rd: FpReg, rn: FpReg },
1378 /// MOV.8B Vd, Vn
1379 MovV8B { rd: FpReg, rn: FpReg },
1380 /// MOV.16B Vd, Vn
1381 MovV16B { rd: FpReg, rn: FpReg },
1382 /// MOV.4S Vd, Vn
1383 MovV4S { rd: FpReg, rn: FpReg },
1384 /// MOV.2D Vd, Vn
1385 MovV2D { rd: FpReg, rn: FpReg },
1386 /// DUP.16B Vd, Vn[index]
1387 DupV16B { rd: FpReg, rn: FpReg, index: u8 },
1388 /// DUP.8H Vd, Vn[index]
1389 DupV8H { rd: FpReg, rn: FpReg, index: u8 },
1390 /// DUP.4S Vd, Vn[index]
1391 DupV4S { rd: FpReg, rn: FpReg, index: u8 },
1392 /// DUP.2D Vd, Vn[index]
1393 DupV2D { rd: FpReg, rn: FpReg, index: u8 },
1394 /// AND.16B Vd, Vn, Vm
1395 AndV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1396 /// BIC.16B Vd, Vn, Vm
1397 BicV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1398 /// ORR.16B Vd, Vn, Vm
1399 OrrV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1400 /// EOR.16B Vd, Vn, Vm
1401 EorV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1402 /// BIF.16B Vd, Vn, Vm
1403 BifV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1404 /// BIT.16B Vd, Vn, Vm
1405 BitV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1406 /// BSL.16B Vd, Vn, Vm
1407 BslV16B { rd: FpReg, rn: FpReg, rm: FpReg },
1408 /// CMEQ.4S Vd, Vn, Vm
1409 CmeqV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1410 /// FCMEQ.4S Vd, Vn, Vm
1411 FcmeqV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1412 /// FCMEQ.2D Vd, Vn, Vm
1413 FcmeqV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1414 /// CMHS.4S Vd, Vn, Vm
1415 CmhsV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1416 /// CMHI.4S Vd, Vn, Vm
1417 CmhiV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1418 /// CMGE.4S Vd, Vn, Vm
1419 CmgeV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1420 /// FCMGE.4S Vd, Vn, Vm
1421 FcmgeV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1422 /// FCMGE.2D Vd, Vn, Vm
1423 FcmgeV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1424 /// FCMGE.2D Vd, Vn, #0.0
1425 FcmgeZeroV2D { rd: FpReg, rn: FpReg },
1426 /// CMGT.4S Vd, Vn, Vm
1427 CmgtV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1428 /// FCMGT.4S Vd, Vn, Vm
1429 FcmgtV4S { rd: FpReg, rn: FpReg, rm: FpReg },
1430 /// FCMGT.2D Vd, Vn, Vm
1431 FcmgtV2D { rd: FpReg, rn: FpReg, rm: FpReg },
1432 /// FCMGT.2D Vd, Vn, #0.0
1433 FcmgtZeroV2D { rd: FpReg, rn: FpReg },
1434 /// FCMLE.2D Vd, Vn, #0.0
1435 FcmleZeroV2D { rd: FpReg, rn: FpReg },
1436 /// FCMLT.2D Vd, Vn, #0.0
1437 FcmltZeroV2D { rd: FpReg, rn: FpReg },
1438 /// EXT.16B Vd, Vn, Vm, #index
1439 ExtV16B {
1440 rd: FpReg,
1441 rn: FpReg,
1442 rm: FpReg,
1443 index: u8,
1444 },
1445 /// REV64.4S Vd, Vn
1446 Rev64V4S { rd: FpReg, rn: FpReg },
1447 /// ZIP1.4S Vd, Vn, Vm
1448 Zip1V4S { rd: FpReg, rn: FpReg, rm: FpReg },
1449 /// ZIP1.2D Vd, Vn, Vm
1450 Zip1V2D { rd: FpReg, rn: FpReg, rm: FpReg },
1451 /// ZIP2.4S Vd, Vn, Vm
1452 Zip2V4S { rd: FpReg, rn: FpReg, rm: FpReg },
1453 /// ZIP2.2D Vd, Vn, Vm
1454 Zip2V2D { rd: FpReg, rn: FpReg, rm: FpReg },
1455 /// UZP1.4S Vd, Vn, Vm
1456 Uzp1V4S { rd: FpReg, rn: FpReg, rm: FpReg },
1457 /// UZP1.2D Vd, Vn, Vm
1458 Uzp1V2D { rd: FpReg, rn: FpReg, rm: FpReg },
1459 /// UZP2.4S Vd, Vn, Vm
1460 Uzp2V4S { rd: FpReg, rn: FpReg, rm: FpReg },
1461 /// UZP2.2D Vd, Vn, Vm
1462 Uzp2V2D { rd: FpReg, rn: FpReg, rm: FpReg },
1463 /// TRN1.4S Vd, Vn, Vm
1464 Trn1V4S { rd: FpReg, rn: FpReg, rm: FpReg },
1465 /// TRN1.2D Vd, Vn, Vm
1466 Trn1V2D { rd: FpReg, rn: FpReg, rm: FpReg },
1467 /// TRN2.4S Vd, Vn, Vm
1468 Trn2V4S { rd: FpReg, rn: FpReg, rm: FpReg },
1469 /// TRN2.2D Vd, Vn, Vm
1470 Trn2V2D { rd: FpReg, rn: FpReg, rm: FpReg },
1471 /// TBL.16B Vd, { Vn... }, Vm
1472 TblV16B {
1473 rd: FpReg,
1474 table: FpReg,
1475 table_len: u8,
1476 index: FpReg,
1477 },
1478 /// TBX.16B Vd, { Vn... }, Vm
1479 TbxV16B {
1480 rd: FpReg,
1481 table: FpReg,
1482 table_len: u8,
1483 index: FpReg,
1484 },
1485 /// MOV Sd, Vn[index]
1486 MovFromLaneS { rd: FpReg, rn: FpReg, index: u8 },
1487 /// MOV Dd, Vn[index]
1488 MovFromLaneD { rd: FpReg, rn: FpReg, index: u8 },
1489 /// MOV.S Wd, Vn[index]
1490 MovFromLaneGpS { rd: GpReg, rn: FpReg, index: u8 },
1491 /// MOV.D Xd, Vn[index]
1492 MovFromLaneGpD { rd: GpReg, rn: FpReg, index: u8 },
1493 /// UMOV.H Wd, Vn[index]
1494 UmovFromLaneH { rd: GpReg, rn: FpReg, index: u8 },
1495 /// UMOV.B Wd, Vn[index]
1496 UmovFromLaneB { rd: GpReg, rn: FpReg, index: u8 },
1497 /// SMOV.H Wd, Vn[index]
1498 SmovFromLaneH { rd: GpReg, rn: FpReg, index: u8 },
1499 /// SMOV.B Wd, Vn[index]
1500 SmovFromLaneB { rd: GpReg, rn: FpReg, index: u8 },
1501 /// MOV.S Vd[index], Vn[index]
1502 MovLaneS {
1503 rd: FpReg,
1504 rd_index: u8,
1505 rn: FpReg,
1506 rn_index: u8,
1507 },
1508 /// MOV.D Vd[index], Vn[index]
1509 MovLaneD {
1510 rd: FpReg,
1511 rd_index: u8,
1512 rn: FpReg,
1513 rn_index: u8,
1514 },
1515 /// MOV.H Vd[index], Vn[index]
1516 MovLaneH {
1517 rd: FpReg,
1518 rd_index: u8,
1519 rn: FpReg,
1520 rn_index: u8,
1521 },
1522 /// MOV.B Vd[index], Vn[index]
1523 MovLaneB {
1524 rd: FpReg,
1525 rd_index: u8,
1526 rn: FpReg,
1527 rn_index: u8,
1528 },
1529 /// MOV.S Vd[index], Wn
1530 MovLaneFromGpS { rd: FpReg, rd_index: u8, rn: GpReg },
1531 /// MOV.D Vd[index], Xn
1532 MovLaneFromGpD { rd: FpReg, rd_index: u8, rn: GpReg },
1533 /// MOV.H Vd[index], Wn
1534 MovLaneFromGpH { rd: FpReg, rd_index: u8, rn: GpReg },
1535 /// MOV.B Vd[index], Wn
1536 MovLaneFromGpB { rd: FpReg, rd_index: u8, rn: GpReg },
1537 /// LD1.B { Vt }[index], [Xn]
1538 Ld1LaneB { rt: FpReg, index: u8, rn: GpReg },
1539 /// LD1.H { Vt }[index], [Xn]
1540 Ld1LaneH { rt: FpReg, index: u8, rn: GpReg },
1541 /// LD1.S { Vt }[index], [Xn]
1542 Ld1LaneS { rt: FpReg, index: u8, rn: GpReg },
1543 /// LD1.D { Vt }[index], [Xn]
1544 Ld1LaneD { rt: FpReg, index: u8, rn: GpReg },
1545 /// FNEG Dd, Dn
1546 FnegD { rd: FpReg, rn: FpReg },
1547 /// FNEG Sd, Sn
1548 FnegS { rd: FpReg, rn: FpReg },
1549 /// FABS Dd, Dn
1550 FabsD { rd: FpReg, rn: FpReg },
1551 /// FABS Sd, Sn
1552 FabsS { rd: FpReg, rn: FpReg },
1553 /// FSQRT Dd, Dn
1554 FsqrtD { rd: FpReg, rn: FpReg },
1555 /// FSQRT Sd, Sn
1556 FsqrtS { rd: FpReg, rn: FpReg },
1557 /// FCMP Dn, Dm
1558 FcmpD { rn: FpReg, rm: FpReg },
1559 /// FCMP Sn, Sm
1560 FcmpS { rn: FpReg, rm: FpReg },
1561 /// FMOV Dd, #imm
1562 FmovImmD { rd: FpReg, imm8: u8 },
1563 /// FMOV Sd, #imm
1564 FmovImmS { rd: FpReg, imm8: u8 },
1565 /// FCSEL Dd, Dn, Dm, cond
1566 FcselD {
1567 rd: FpReg,
1568 rn: FpReg,
1569 rm: FpReg,
1570 cond: Cond,
1571 },
1572 /// FCSEL Sd, Sn, Sm, cond
1573 FcselS {
1574 rd: FpReg,
1575 rn: FpReg,
1576 rm: FpReg,
1577 cond: Cond,
1578 },
1579 /// FMADD Dd, Dn, Dm, Da (Dd = Da + Dn*Dm)
1580 FmaddD {
1581 rd: FpReg,
1582 rn: FpReg,
1583 rm: FpReg,
1584 ra: FpReg,
1585 },
1586 /// FMADD Sd, Sn, Sm, Sa
1587 FmaddS {
1588 rd: FpReg,
1589 rn: FpReg,
1590 rm: FpReg,
1591 ra: FpReg,
1592 },
1593
1594 // ---- FP / integer conversion ----
1595 /// FCVTZS Xd, Dn (double -> signed 64-bit int, truncate toward zero)
1596 FcvtzsD { rd: GpReg, rn: FpReg },
1597 /// SCVTF Dd, Xn (signed 64-bit int -> double)
1598 ScvtfD { rd: FpReg, rn: GpReg },
1599 /// FMOV Dd, Xn (move bits GP -> FP, no conversion)
1600 FmovToD { rd: FpReg, rn: GpReg },
1601 /// FMOV Sd, Wn (move bits GP -> FP, no conversion)
1602 FmovToS { rd: FpReg, rn: GpReg },
1603 /// FMOV Xd, Dn (move bits FP -> GP, no conversion)
1604 FmovFromD { rd: GpReg, rn: FpReg },
1605 /// FMOV Wd, Sn (move bits FP -> GP, no conversion)
1606 FmovFromS { rd: GpReg, rn: FpReg },
1607
1608 // ---- System ----
1609 /// SVC #imm16
1610 Svc { imm16: u16 },
1611 /// NOP
1612 Nop,
1613 /// YIELD
1614 Yield,
1615 /// WFE
1616 Wfe,
1617 /// WFI
1618 Wfi,
1619 /// SEV
1620 Sev,
1621 /// SEVL
1622 Sevl,
1623 /// DMB <option>
1624 Dmb { option: BarrierOpt },
1625 /// DSB <option>
1626 Dsb { option: BarrierOpt },
1627 /// ISB {<option>}
1628 Isb { option: BarrierOpt },
1629 /// BRK #imm16
1630 Brk { imm16: u16 },
1631 }
1632
1633 impl Inst {
1634 /// Encode this instruction into its 32-bit binary representation.
1635 pub fn encode(&self) -> u32 {
1636 match self {
1637 // ---- Data processing (register) ----
1638 Inst::AddReg { rd, rn, rm, sf } => dp_reg(*sf, 0b00, 0b01011, 0b00, *rm, 0, *rn, *rd),
1639 Inst::AddShiftReg {
1640 rd,
1641 rn,
1642 rm,
1643 shift,
1644 amount,
1645 sf,
1646 } => dp_reg(
1647 *sf,
1648 0b00,
1649 0b01011,
1650 shift.enc(),
1651 *rm,
1652 *amount as u32,
1653 *rn,
1654 *rd,
1655 ),
1656 Inst::AddExtReg {
1657 rd,
1658 rn,
1659 rm,
1660 extend,
1661 amount,
1662 sf,
1663 } => dp_ext(*sf, 0b00, *rm, *extend, *amount, *rn, *rd),
1664 Inst::SubReg { rd, rn, rm, sf } => dp_reg(*sf, 0b10, 0b01011, 0b00, *rm, 0, *rn, *rd),
1665 Inst::SubShiftReg {
1666 rd,
1667 rn,
1668 rm,
1669 shift,
1670 amount,
1671 sf,
1672 } => dp_reg(
1673 *sf,
1674 0b10,
1675 0b01011,
1676 shift.enc(),
1677 *rm,
1678 *amount as u32,
1679 *rn,
1680 *rd,
1681 ),
1682 Inst::SubExtReg {
1683 rd,
1684 rn,
1685 rm,
1686 extend,
1687 amount,
1688 sf,
1689 } => dp_ext(*sf, 0b10, *rm, *extend, *amount, *rn, *rd),
1690 Inst::AddsReg { rd, rn, rm, sf } => dp_reg(*sf, 0b01, 0b01011, 0b00, *rm, 0, *rn, *rd),
1691 Inst::AddsShiftReg {
1692 rd,
1693 rn,
1694 rm,
1695 shift,
1696 amount,
1697 sf,
1698 } => dp_reg(
1699 *sf,
1700 0b01,
1701 0b01011,
1702 shift.enc(),
1703 *rm,
1704 *amount as u32,
1705 *rn,
1706 *rd,
1707 ),
1708 Inst::AddsExtReg {
1709 rd,
1710 rn,
1711 rm,
1712 extend,
1713 amount,
1714 sf,
1715 } => dp_ext(*sf, 0b01, *rm, *extend, *amount, *rn, *rd),
1716 Inst::SubsReg { rd, rn, rm, sf } => dp_reg(*sf, 0b11, 0b01011, 0b00, *rm, 0, *rn, *rd),
1717 Inst::SubsShiftReg {
1718 rd,
1719 rn,
1720 rm,
1721 shift,
1722 amount,
1723 sf,
1724 } => dp_reg(
1725 *sf,
1726 0b11,
1727 0b01011,
1728 shift.enc(),
1729 *rm,
1730 *amount as u32,
1731 *rn,
1732 *rd,
1733 ),
1734 Inst::SubsExtReg {
1735 rd,
1736 rn,
1737 rm,
1738 extend,
1739 amount,
1740 sf,
1741 } => dp_ext(*sf, 0b11, *rm, *extend, *amount, *rn, *rd),
1742
1743 // MUL: alias for MADD Xd, Xn, Xm, XZR
1744 // sf|00|11011|000|Rm|0|Ra(11111)|Rn|Rd
1745 Inst::Mul { rd, rn, rm, sf } => {
1746 let s = (*sf as u32) << 31;
1747 s | (0b00_11011_000 << 21)
1748 | (rm.enc() << 16)
1749 | (0b0_11111 << 10)
1750 | (rn.enc() << 5)
1751 | rd.enc()
1752 }
1753 // MADD: sf|00|11011|000|Rm|0|Ra|Rn|Rd
1754 Inst::Madd { rd, rn, rm, ra, sf } => {
1755 let s = (*sf as u32) << 31;
1756 s | (0b00_11011_000 << 21)
1757 | (rm.enc() << 16)
1758 | (ra.enc() << 10)
1759 | (rn.enc() << 5)
1760 | rd.enc()
1761 }
1762 Inst::Msub { rd, rn, rm, ra, sf } => {
1763 let s = (*sf as u32) << 31;
1764 s | (0b00_11011_000 << 21)
1765 | (rm.enc() << 16)
1766 | (1 << 15)
1767 | (ra.enc() << 10)
1768 | (rn.enc() << 5)
1769 | rd.enc()
1770 }
1771 Inst::Umull { rd, rn, rm } => {
1772 0x9BA0_0000 | (rm.enc() << 16) | (0b1_1111 << 10) | (rn.enc() << 5) | rd.enc()
1773 }
1774 // SDIV: sf|0|0|11010110|Rm|00001|1|Rn|Rd
1775 Inst::Sdiv { rd, rn, rm, sf } => {
1776 let s = (*sf as u32) << 31;
1777 s | (0b0_0_11010110 << 21)
1778 | (rm.enc() << 16)
1779 | (0b000011 << 10)
1780 | (rn.enc() << 5)
1781 | rd.enc()
1782 }
1783 // UDIV: sf|0|0|11010110|Rm|00001|0|Rn|Rd
1784 Inst::Udiv { rd, rn, rm, sf } => {
1785 let s = (*sf as u32) << 31;
1786 s | (0b0_0_11010110 << 21)
1787 | (rm.enc() << 16)
1788 | (0b000010 << 10)
1789 | (rn.enc() << 5)
1790 | rd.enc()
1791 }
1792
1793 // ---- Logic (register) ----
1794 Inst::AndReg { rd, rn, rm, sf } => logic_reg(*sf, 0b00, false, *rm, *rn, *rd),
1795 Inst::OrrReg { rd, rn, rm, sf } => logic_reg(*sf, 0b01, false, *rm, *rn, *rd),
1796 Inst::OrnReg { rd, rn, rm, sf } => logic_reg(*sf, 0b01, true, *rm, *rn, *rd),
1797 Inst::EorReg { rd, rn, rm, sf } => logic_reg(*sf, 0b10, false, *rm, *rn, *rd),
1798 Inst::AndsReg { rd, rn, rm, sf } => logic_reg(*sf, 0b11, false, *rm, *rn, *rd),
1799 Inst::AndImm { rd, rn, imm, sf } => logical_imm(*sf, 0b00, *imm, *rn, *rd),
1800 Inst::OrrImm { rd, rn, imm, sf } => logical_imm(*sf, 0b01, *imm, *rn, *rd),
1801 Inst::EorImm { rd, rn, imm, sf } => logical_imm(*sf, 0b10, *imm, *rn, *rd),
1802 Inst::AndsImm { rd, rn, imm, sf } => logical_imm(*sf, 0b11, *imm, *rn, *rd),
1803
1804 // ---- Data processing (immediate) ----
1805 Inst::AddImm {
1806 rd,
1807 rn,
1808 imm12,
1809 shift,
1810 sf,
1811 } => dp_imm(*sf, 0b00, *imm12, *shift, *rn, *rd),
1812 Inst::SubImm {
1813 rd,
1814 rn,
1815 imm12,
1816 shift,
1817 sf,
1818 } => dp_imm(*sf, 0b10, *imm12, *shift, *rn, *rd),
1819 Inst::AddsImm {
1820 rd,
1821 rn,
1822 imm12,
1823 shift,
1824 sf,
1825 } => dp_imm(*sf, 0b01, *imm12, *shift, *rn, *rd),
1826 Inst::SubsImm {
1827 rd,
1828 rn,
1829 imm12,
1830 shift,
1831 sf,
1832 } => dp_imm(*sf, 0b11, *imm12, *shift, *rn, *rd),
1833
1834 // ---- Move (wide immediate) ----
1835 Inst::Movz {
1836 rd,
1837 imm16,
1838 shift,
1839 sf,
1840 } => mov_wide(*sf, 0b10, *imm16, *shift, *rd),
1841 Inst::Movk {
1842 rd,
1843 imm16,
1844 shift,
1845 sf,
1846 } => mov_wide(*sf, 0b11, *imm16, *shift, *rd),
1847 Inst::Movn {
1848 rd,
1849 imm16,
1850 shift,
1851 sf,
1852 } => mov_wide(*sf, 0b00, *imm16, *shift, *rd),
1853
1854 // ---- Shifts (bitfield aliases) ----
1855 Inst::LslImm { rd, rn, amount, sf } => {
1856 let bits = if *sf { 64u8 } else { 32u8 };
1857 let immr = bits.wrapping_sub(*amount) & (bits - 1);
1858 let imms = bits - 1 - *amount;
1859 bitfield(*sf, 0b10, immr, imms, *rn, *rd)
1860 }
1861 Inst::LsrImm { rd, rn, amount, sf } => {
1862 let imms = if *sf { 63u8 } else { 31u8 };
1863 bitfield(*sf, 0b10, *amount, imms, *rn, *rd)
1864 }
1865 Inst::AsrImm { rd, rn, amount, sf } => {
1866 let imms = if *sf { 63u8 } else { 31u8 };
1867 bitfield(*sf, 0b00, *amount, imms, *rn, *rd)
1868 }
1869 Inst::Ubfiz {
1870 rd,
1871 rn,
1872 lsb,
1873 width,
1874 sf,
1875 } => {
1876 let bits = if *sf { 64u8 } else { 32u8 };
1877 let immr = bits.wrapping_sub(*lsb) & (bits - 1);
1878 bitfield(*sf, 0b10, immr, width.wrapping_sub(1), *rn, *rd)
1879 }
1880 Inst::Bfi {
1881 rd,
1882 rn,
1883 lsb,
1884 width,
1885 sf,
1886 } => {
1887 let bits = if *sf { 64u8 } else { 32u8 };
1888 let immr = bits.wrapping_sub(*lsb) & (bits - 1);
1889 bitfield(*sf, 0b01, immr, width.wrapping_sub(1), *rn, *rd)
1890 }
1891 Inst::Bfxil {
1892 rd,
1893 rn,
1894 lsb,
1895 width,
1896 sf,
1897 } => bitfield(
1898 *sf,
1899 0b01,
1900 *lsb,
1901 lsb.wrapping_add(*width).wrapping_sub(1),
1902 *rn,
1903 *rd,
1904 ),
1905
1906 // ---- Branches ----
1907 Inst::B { offset } => {
1908 let imm26 = ((*offset >> 2) as u32) & 0x03FF_FFFF;
1909 (0b000101 << 26) | imm26
1910 }
1911 Inst::Bl { offset } => {
1912 let imm26 = ((*offset >> 2) as u32) & 0x03FF_FFFF;
1913 (0b100101 << 26) | imm26
1914 }
1915 Inst::BCond { cond, offset } => {
1916 let imm19 = ((*offset >> 2) as u32) & 0x7FFFF;
1917 (0b01010100 << 24) | (imm19 << 5) | cond.enc()
1918 }
1919 Inst::Cbz { rt, offset, sf } => {
1920 let s = (*sf as u32) << 31;
1921 let imm19 = ((*offset >> 2) as u32) & 0x7FFFF;
1922 s | (0b011010_0 << 24) | (imm19 << 5) | rt.enc()
1923 }
1924 Inst::Cbnz { rt, offset, sf } => {
1925 let s = (*sf as u32) << 31;
1926 let imm19 = ((*offset >> 2) as u32) & 0x7FFFF;
1927 s | (0b011010_1 << 24) | (imm19 << 5) | rt.enc()
1928 }
1929 Inst::Tbz {
1930 rt,
1931 bit,
1932 offset,
1933 sf: _,
1934 } => {
1935 let b5 = ((*bit >> 5) as u32) & 0x1;
1936 let b40 = (*bit as u32) & 0x1F;
1937 let imm14 = ((*offset >> 2) as u32) & 0x3FFF;
1938 (b5 << 31) | (0b011011 << 25) | (b40 << 19) | (imm14 << 5) | rt.enc()
1939 }
1940 Inst::Tbnz {
1941 rt,
1942 bit,
1943 offset,
1944 sf: _,
1945 } => {
1946 let b5 = ((*bit >> 5) as u32) & 0x1;
1947 let b40 = (*bit as u32) & 0x1F;
1948 let imm14 = ((*offset >> 2) as u32) & 0x3FFF;
1949 (b5 << 31) | (0b011011 << 25) | (1 << 24) | (b40 << 19) | (imm14 << 5) | rt.enc()
1950 }
1951 Inst::Ret { rn } => 0xD65F0000 | (rn.enc() << 5),
1952 Inst::Br { rn } => 0xD61F0000 | (rn.enc() << 5),
1953 Inst::Blr { rn } => 0xD63F0000 | (rn.enc() << 5),
1954 Inst::Csel {
1955 rd,
1956 rn,
1957 rm,
1958 cond,
1959 sf,
1960 } => csel(*sf, 0b00, *rm, *cond, *rn, *rd),
1961 Inst::Csinc {
1962 rd,
1963 rn,
1964 rm,
1965 cond,
1966 sf,
1967 } => csel(*sf, 0b01, *rm, *cond, *rn, *rd),
1968 Inst::Csinv {
1969 rd,
1970 rn,
1971 rm,
1972 cond,
1973 sf,
1974 } => csel(*sf, 0b10, *rm, *cond, *rn, *rd),
1975 Inst::Csneg {
1976 rd,
1977 rn,
1978 rm,
1979 cond,
1980 sf,
1981 } => csel(*sf, 0b11, *rm, *cond, *rn, *rd),
1982 Inst::CcmpImm {
1983 rn,
1984 imm5,
1985 nzcv,
1986 cond,
1987 sf,
1988 } => ccmp_imm(*sf, true, *rn, *imm5, *nzcv, *cond),
1989 Inst::CcmnImm {
1990 rn,
1991 imm5,
1992 nzcv,
1993 cond,
1994 sf,
1995 } => ccmp_imm(*sf, false, *rn, *imm5, *nzcv, *cond),
1996
1997 // ---- Address generation ----
1998 Inst::Adr { rd, imm } => {
1999 let immlo = (*imm as u32) & 0x3;
2000 let immhi = ((*imm as u32) >> 2) & 0x7FFFF;
2001 (immlo << 29) | (0b10000 << 24) | (immhi << 5) | rd.enc()
2002 }
2003 Inst::Adrp { rd, imm } => {
2004 let page = (*imm >> 12) as u32;
2005 let immlo = page & 0x3;
2006 let immhi = (page >> 2) & 0x7FFFF;
2007 (1 << 31) | (immlo << 29) | (0b10000 << 24) | (immhi << 5) | rd.enc()
2008 }
2009
2010 // ---- Load/Store (unsigned offset) ----
2011 Inst::LdrImm64 { rt, rn, offset } => {
2012 let uoff = (*offset / 8) as u32;
2013 (0b11_111_0_01_01 << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
2014 }
2015 Inst::LdrImm32 { rt, rn, offset } => {
2016 let uoff = (*offset / 4) as u32;
2017 (0b10_111_0_01_01 << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
2018 }
2019 Inst::StrImm64 { rt, rn, offset } => {
2020 let uoff = (*offset / 8) as u32;
2021 (0b11_111_0_01_00 << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
2022 }
2023 Inst::StrImm32 { rt, rn, offset } => {
2024 let uoff = (*offset / 4) as u32;
2025 (0b10_111_0_01_00 << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
2026 }
2027 Inst::Ldur64 { rt, rn, offset } => ldst_idx(0b11, 0b01, *offset, 0b00, *rn, *rt),
2028 Inst::Ldur32 { rt, rn, offset } => ldst_idx(0b10, 0b01, *offset, 0b00, *rn, *rt),
2029 Inst::Stur64 { rt, rn, offset } => ldst_idx(0b11, 0b00, *offset, 0b00, *rn, *rt),
2030 Inst::Stur32 { rt, rn, offset } => ldst_idx(0b10, 0b00, *offset, 0b00, *rn, *rt),
2031 Inst::LdrReg64 {
2032 rt,
2033 rn,
2034 rm,
2035 extend,
2036 shift,
2037 } => ldst_reg(0b11, 0b01, *rm, *extend, *shift, *rn, *rt),
2038 Inst::LdrReg32 {
2039 rt,
2040 rn,
2041 rm,
2042 extend,
2043 shift,
2044 } => ldst_reg(0b10, 0b01, *rm, *extend, *shift, *rn, *rt),
2045 Inst::StrReg64 {
2046 rt,
2047 rn,
2048 rm,
2049 extend,
2050 shift,
2051 } => ldst_reg(0b11, 0b00, *rm, *extend, *shift, *rn, *rt),
2052 Inst::StrReg32 {
2053 rt,
2054 rn,
2055 rm,
2056 extend,
2057 shift,
2058 } => ldst_reg(0b10, 0b00, *rm, *extend, *shift, *rn, *rt),
2059 Inst::Ldrb { rt, rn, offset } => {
2060 let uoff = *offset as u32;
2061 (0b00_111_0_01_01 << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
2062 }
2063 Inst::Ldrsb32 { rt, rn, offset } => {
2064 let uoff = *offset as u32;
2065 (0b111_001 << 24) | (0b11 << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
2066 }
2067 Inst::Ldrsb64 { rt, rn, offset } => {
2068 let uoff = *offset as u32;
2069 (0b111_001 << 24) | (0b10 << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
2070 }
2071 Inst::Ldrh { rt, rn, offset } => {
2072 let uoff = (*offset / 2) as u32;
2073 (0b01_111_0_01_01 << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
2074 }
2075 Inst::Ldrsh32 { rt, rn, offset } => {
2076 let uoff = (*offset / 2) as u32;
2077 (0b01 << 30)
2078 | (0b111_001 << 24)
2079 | (0b11 << 22)
2080 | (uoff << 10)
2081 | (rn.enc() << 5)
2082 | rt.enc()
2083 }
2084 Inst::Ldrsh64 { rt, rn, offset } => {
2085 let uoff = (*offset / 2) as u32;
2086 (0b01 << 30)
2087 | (0b111_001 << 24)
2088 | (0b10 << 22)
2089 | (uoff << 10)
2090 | (rn.enc() << 5)
2091 | rt.enc()
2092 }
2093 Inst::Strb { rt, rn, offset } => {
2094 let uoff = *offset as u32;
2095 (0b00_111_0_01_00 << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
2096 }
2097 Inst::Strh { rt, rn, offset } => {
2098 let uoff = (*offset / 2) as u32;
2099 (0b01_111_0_01_00 << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
2100 }
2101 Inst::Ldrsw { rt, rn, offset } => {
2102 let uoff = (*offset / 4) as u32;
2103 (0b10_111_0_01_10 << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
2104 }
2105 Inst::LdrbReg {
2106 rt,
2107 rn,
2108 rm,
2109 extend,
2110 shift,
2111 } => ldst_reg(0b00, 0b01, *rm, *extend, *shift, *rn, *rt),
2112 Inst::LdrsbReg32 {
2113 rt,
2114 rn,
2115 rm,
2116 extend,
2117 shift,
2118 } => ldst_reg(0b00, 0b11, *rm, *extend, *shift, *rn, *rt),
2119 Inst::LdrsbReg64 {
2120 rt,
2121 rn,
2122 rm,
2123 extend,
2124 shift,
2125 } => ldst_reg(0b00, 0b10, *rm, *extend, *shift, *rn, *rt),
2126 Inst::LdrhReg {
2127 rt,
2128 rn,
2129 rm,
2130 extend,
2131 shift,
2132 } => ldst_reg(0b01, 0b01, *rm, *extend, *shift, *rn, *rt),
2133 Inst::LdrshReg32 {
2134 rt,
2135 rn,
2136 rm,
2137 extend,
2138 shift,
2139 } => ldst_reg(0b01, 0b11, *rm, *extend, *shift, *rn, *rt),
2140 Inst::LdrshReg64 {
2141 rt,
2142 rn,
2143 rm,
2144 extend,
2145 shift,
2146 } => ldst_reg(0b01, 0b10, *rm, *extend, *shift, *rn, *rt),
2147 Inst::StrbReg {
2148 rt,
2149 rn,
2150 rm,
2151 extend,
2152 shift,
2153 } => ldst_reg(0b00, 0b00, *rm, *extend, *shift, *rn, *rt),
2154 Inst::StrhReg {
2155 rt,
2156 rn,
2157 rm,
2158 extend,
2159 shift,
2160 } => ldst_reg(0b01, 0b00, *rm, *extend, *shift, *rn, *rt),
2161 Inst::LdrswReg {
2162 rt,
2163 rn,
2164 rm,
2165 extend,
2166 shift,
2167 } => ldst_reg(0b10, 0b10, *rm, *extend, *shift, *rn, *rt),
2168
2169 Inst::LdrFpImm64 { rt, rn, offset } => ldst_uimm_fp(0b11, 0b01, 3, *offset, *rn, *rt),
2170 Inst::LdrFpImm32 { rt, rn, offset } => ldst_uimm_fp(0b10, 0b01, 2, *offset, *rn, *rt),
2171 Inst::LdrFpImm16 { rt, rn, offset } => ldst_uimm_fp(0b01, 0b01, 1, *offset, *rn, *rt),
2172 Inst::LdrFpImm8 { rt, rn, offset } => ldst_uimm_fp(0b00, 0b01, 0, *offset, *rn, *rt),
2173 Inst::LdrFpImm128 { rt, rn, offset } => ldst_uimm_fp(0b00, 0b11, 4, *offset, *rn, *rt),
2174 Inst::StrFpImm64 { rt, rn, offset } => ldst_uimm_fp(0b11, 0b00, 3, *offset, *rn, *rt),
2175 Inst::StrFpImm32 { rt, rn, offset } => ldst_uimm_fp(0b10, 0b00, 2, *offset, *rn, *rt),
2176 Inst::StrFpImm16 { rt, rn, offset } => ldst_uimm_fp(0b01, 0b00, 1, *offset, *rn, *rt),
2177 Inst::StrFpImm8 { rt, rn, offset } => ldst_uimm_fp(0b00, 0b00, 0, *offset, *rn, *rt),
2178 Inst::StrFpImm128 { rt, rn, offset } => ldst_uimm_fp(0b00, 0b10, 4, *offset, *rn, *rt),
2179 Inst::LdurFp64 { rt, rn, offset } => ldst_idx_fp(0b11, 0b01, *offset, 0b00, *rn, *rt),
2180 Inst::LdurFp32 { rt, rn, offset } => ldst_idx_fp(0b10, 0b01, *offset, 0b00, *rn, *rt),
2181 Inst::LdurFp16 { rt, rn, offset } => ldst_idx_fp(0b01, 0b01, *offset, 0b00, *rn, *rt),
2182 Inst::LdurFp8 { rt, rn, offset } => ldst_idx_fp(0b00, 0b01, *offset, 0b00, *rn, *rt),
2183 Inst::LdurFp128 { rt, rn, offset } => ldst_idx_fp(0b00, 0b11, *offset, 0b00, *rn, *rt),
2184 Inst::SturFp64 { rt, rn, offset } => ldst_idx_fp(0b11, 0b00, *offset, 0b00, *rn, *rt),
2185 Inst::SturFp32 { rt, rn, offset } => ldst_idx_fp(0b10, 0b00, *offset, 0b00, *rn, *rt),
2186 Inst::SturFp16 { rt, rn, offset } => ldst_idx_fp(0b01, 0b00, *offset, 0b00, *rn, *rt),
2187 Inst::SturFp8 { rt, rn, offset } => ldst_idx_fp(0b00, 0b00, *offset, 0b00, *rn, *rt),
2188 Inst::SturFp128 { rt, rn, offset } => ldst_idx_fp(0b00, 0b10, *offset, 0b00, *rn, *rt),
2189 Inst::LdrFpReg64 {
2190 rt,
2191 rn,
2192 rm,
2193 extend,
2194 shift,
2195 } => ldst_reg_fp(0b11, 0b01, *rm, *extend, *shift, *rn, *rt),
2196 Inst::LdrFpReg32 {
2197 rt,
2198 rn,
2199 rm,
2200 extend,
2201 shift,
2202 } => ldst_reg_fp(0b10, 0b01, *rm, *extend, *shift, *rn, *rt),
2203 Inst::LdrFpReg128 {
2204 rt,
2205 rn,
2206 rm,
2207 extend,
2208 shift,
2209 } => ldst_reg_fp(0b00, 0b11, *rm, *extend, *shift, *rn, *rt),
2210 Inst::StrFpReg64 {
2211 rt,
2212 rn,
2213 rm,
2214 extend,
2215 shift,
2216 } => ldst_reg_fp(0b11, 0b00, *rm, *extend, *shift, *rn, *rt),
2217 Inst::StrFpReg32 {
2218 rt,
2219 rn,
2220 rm,
2221 extend,
2222 shift,
2223 } => ldst_reg_fp(0b10, 0b00, *rm, *extend, *shift, *rn, *rt),
2224 Inst::StrFpReg128 {
2225 rt,
2226 rn,
2227 rm,
2228 extend,
2229 shift,
2230 } => ldst_reg_fp(0b00, 0b10, *rm, *extend, *shift, *rn, *rt),
2231
2232 Inst::LdrLit64 { rt, offset } => ldr_lit(0b01, *offset, *rt),
2233 Inst::LdrLit32 { rt, offset } => ldr_lit(0b00, *offset, *rt),
2234 Inst::LdrswLit { rt, offset } => ldr_lit(0b10, *offset, *rt),
2235 Inst::LdrFpLit64 { rt, offset } => ldr_lit_fp(0b01, *offset, *rt),
2236 Inst::LdrFpLit32 { rt, offset } => ldr_lit_fp(0b00, *offset, *rt),
2237 Inst::LdrFpLit128 { rt, offset } => ldr_lit_fp(0b10, *offset, *rt),
2238
2239 // ---- Load/Store (pre/post-index) ----
2240 Inst::LdrPre32 { rt, rn, offset } => ldst_idx(0b10, 0b01, *offset, 0b11, *rn, *rt),
2241 Inst::StrPre32 { rt, rn, offset } => ldst_idx(0b10, 0b00, *offset, 0b11, *rn, *rt),
2242 Inst::LdrbPre { rt, rn, offset } => ldst_idx(0b00, 0b01, *offset, 0b11, *rn, *rt),
2243 Inst::LdrsbPre32 { rt, rn, offset } => ldst_idx(0b00, 0b11, *offset, 0b11, *rn, *rt),
2244 Inst::LdrsbPre64 { rt, rn, offset } => ldst_idx(0b00, 0b10, *offset, 0b11, *rn, *rt),
2245 Inst::StrbPre { rt, rn, offset } => ldst_idx(0b00, 0b00, *offset, 0b11, *rn, *rt),
2246 Inst::LdrhPre { rt, rn, offset } => ldst_idx(0b01, 0b01, *offset, 0b11, *rn, *rt),
2247 Inst::LdrshPre32 { rt, rn, offset } => ldst_idx(0b01, 0b11, *offset, 0b11, *rn, *rt),
2248 Inst::LdrshPre64 { rt, rn, offset } => ldst_idx(0b01, 0b10, *offset, 0b11, *rn, *rt),
2249 Inst::StrhPre { rt, rn, offset } => ldst_idx(0b01, 0b00, *offset, 0b11, *rn, *rt),
2250 Inst::LdrPre64 { rt, rn, offset } => ldst_idx(0b11, 0b01, *offset, 0b11, *rn, *rt),
2251 Inst::StrPre64 { rt, rn, offset } => ldst_idx(0b11, 0b00, *offset, 0b11, *rn, *rt),
2252 Inst::LdrPost32 { rt, rn, offset } => ldst_idx(0b10, 0b01, *offset, 0b01, *rn, *rt),
2253 Inst::StrPost32 { rt, rn, offset } => ldst_idx(0b10, 0b00, *offset, 0b01, *rn, *rt),
2254 Inst::LdrbPost { rt, rn, offset } => ldst_idx(0b00, 0b01, *offset, 0b01, *rn, *rt),
2255 Inst::LdrsbPost32 { rt, rn, offset } => ldst_idx(0b00, 0b11, *offset, 0b01, *rn, *rt),
2256 Inst::LdrsbPost64 { rt, rn, offset } => ldst_idx(0b00, 0b10, *offset, 0b01, *rn, *rt),
2257 Inst::StrbPost { rt, rn, offset } => ldst_idx(0b00, 0b00, *offset, 0b01, *rn, *rt),
2258 Inst::LdrhPost { rt, rn, offset } => ldst_idx(0b01, 0b01, *offset, 0b01, *rn, *rt),
2259 Inst::LdrshPost32 { rt, rn, offset } => ldst_idx(0b01, 0b11, *offset, 0b01, *rn, *rt),
2260 Inst::LdrshPost64 { rt, rn, offset } => ldst_idx(0b01, 0b10, *offset, 0b01, *rn, *rt),
2261 Inst::StrhPost { rt, rn, offset } => ldst_idx(0b01, 0b00, *offset, 0b01, *rn, *rt),
2262 Inst::LdrPost64 { rt, rn, offset } => ldst_idx(0b11, 0b01, *offset, 0b01, *rn, *rt),
2263 Inst::StrPost64 { rt, rn, offset } => ldst_idx(0b11, 0b00, *offset, 0b01, *rn, *rt),
2264 Inst::LdrFpPre64 { rt, rn, offset } => ldst_idx_fp(0b11, 0b01, *offset, 0b11, *rn, *rt),
2265 Inst::StrFpPre64 { rt, rn, offset } => ldst_idx_fp(0b11, 0b00, *offset, 0b11, *rn, *rt),
2266 Inst::LdrFpPre32 { rt, rn, offset } => ldst_idx_fp(0b10, 0b01, *offset, 0b11, *rn, *rt),
2267 Inst::StrFpPre32 { rt, rn, offset } => ldst_idx_fp(0b10, 0b00, *offset, 0b11, *rn, *rt),
2268 Inst::LdrFpPre128 { rt, rn, offset } => {
2269 ldst_idx_fp(0b00, 0b11, *offset, 0b11, *rn, *rt)
2270 }
2271 Inst::StrFpPre128 { rt, rn, offset } => {
2272 ldst_idx_fp(0b00, 0b10, *offset, 0b11, *rn, *rt)
2273 }
2274 Inst::LdrFpPost64 { rt, rn, offset } => {
2275 ldst_idx_fp(0b11, 0b01, *offset, 0b01, *rn, *rt)
2276 }
2277 Inst::StrFpPost64 { rt, rn, offset } => {
2278 ldst_idx_fp(0b11, 0b00, *offset, 0b01, *rn, *rt)
2279 }
2280 Inst::LdrFpPost32 { rt, rn, offset } => {
2281 ldst_idx_fp(0b10, 0b01, *offset, 0b01, *rn, *rt)
2282 }
2283 Inst::StrFpPost32 { rt, rn, offset } => {
2284 ldst_idx_fp(0b10, 0b00, *offset, 0b01, *rn, *rt)
2285 }
2286 Inst::LdrFpPost128 { rt, rn, offset } => {
2287 ldst_idx_fp(0b00, 0b11, *offset, 0b01, *rn, *rt)
2288 }
2289 Inst::StrFpPost128 { rt, rn, offset } => {
2290 ldst_idx_fp(0b00, 0b10, *offset, 0b01, *rn, *rt)
2291 }
2292
2293 // ---- Atomic memory operations ----
2294 Inst::Ldaprb { rt, rn } => 0x38BFC000 | (rn.enc() << 5) | rt.enc(),
2295 Inst::Ldaprh { rt, rn } => 0x78BFC000 | (rn.enc() << 5) | rt.enc(),
2296 Inst::Ldapr32 { rt, rn } => 0xB8BFC000 | (rn.enc() << 5) | rt.enc(),
2297 Inst::Ldapr64 { rt, rn } => 0xF8BFC000 | (rn.enc() << 5) | rt.enc(),
2298 Inst::Stlrb { rt, rn } => 0x089FFC00 | (rn.enc() << 5) | rt.enc(),
2299 Inst::Stlrh { rt, rn } => 0x489FFC00 | (rn.enc() << 5) | rt.enc(),
2300 Inst::Stlr32 { rt, rn } => 0x889FFC00 | (rn.enc() << 5) | rt.enc(),
2301 Inst::Stlr64 { rt, rn } => 0xC89FFC00 | (rn.enc() << 5) | rt.enc(),
2302 Inst::Ldaddalb { rs, rt, rn } => {
2303 0x38E00000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2304 }
2305 Inst::Ldaddalh { rs, rt, rn } => {
2306 0x78E00000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2307 }
2308 Inst::Ldaddal32 { rs, rt, rn } => {
2309 0xB8E00000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2310 }
2311 Inst::Ldaddal64 { rs, rt, rn } => {
2312 0xF8E00000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2313 }
2314 Inst::Ldumaxalb { rs, rt, rn } => {
2315 0x38E06000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2316 }
2317 Inst::Ldumaxalh { rs, rt, rn } => {
2318 0x78E06000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2319 }
2320 Inst::Ldumaxal32 { rs, rt, rn } => {
2321 0xB8E06000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2322 }
2323 Inst::Ldumaxal64 { rs, rt, rn } => {
2324 0xF8E06000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2325 }
2326 Inst::Ldsmaxalb { rs, rt, rn } => {
2327 0x38E04000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2328 }
2329 Inst::Ldsmaxalh { rs, rt, rn } => {
2330 0x78E04000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2331 }
2332 Inst::Ldsmaxal32 { rs, rt, rn } => {
2333 0xB8E04000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2334 }
2335 Inst::Ldsmaxal64 { rs, rt, rn } => {
2336 0xF8E04000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2337 }
2338 Inst::Lduminalb { rs, rt, rn } => {
2339 0x38E07000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2340 }
2341 Inst::Lduminalh { rs, rt, rn } => {
2342 0x78E07000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2343 }
2344 Inst::Lduminal32 { rs, rt, rn } => {
2345 0xB8E07000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2346 }
2347 Inst::Lduminal64 { rs, rt, rn } => {
2348 0xF8E07000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2349 }
2350 Inst::Ldsminalb { rs, rt, rn } => {
2351 0x38E05000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2352 }
2353 Inst::Ldsminalh { rs, rt, rn } => {
2354 0x78E05000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2355 }
2356 Inst::Ldsminal32 { rs, rt, rn } => {
2357 0xB8E05000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2358 }
2359 Inst::Ldsminal64 { rs, rt, rn } => {
2360 0xF8E05000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2361 }
2362 Inst::Ldclralb { rs, rt, rn } => {
2363 0x38E01000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2364 }
2365 Inst::Ldclralh { rs, rt, rn } => {
2366 0x78E01000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2367 }
2368 Inst::Ldclral32 { rs, rt, rn } => {
2369 0xB8E01000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2370 }
2371 Inst::Ldclral64 { rs, rt, rn } => {
2372 0xF8E01000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2373 }
2374 Inst::Ldeoralb { rs, rt, rn } => {
2375 0x38E02000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2376 }
2377 Inst::Ldeoralh { rs, rt, rn } => {
2378 0x78E02000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2379 }
2380 Inst::Ldeoral32 { rs, rt, rn } => {
2381 0xB8E02000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2382 }
2383 Inst::Ldeoral64 { rs, rt, rn } => {
2384 0xF8E02000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2385 }
2386 Inst::Ldsetalb { rs, rt, rn } => {
2387 0x38E03000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2388 }
2389 Inst::Ldsetalh { rs, rt, rn } => {
2390 0x78E03000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2391 }
2392 Inst::Ldsetal32 { rs, rt, rn } => {
2393 0xB8E03000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2394 }
2395 Inst::Ldsetal64 { rs, rt, rn } => {
2396 0xF8E03000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2397 }
2398 Inst::Swpal32 { rs, rt, rn } => {
2399 0xB8E08000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2400 }
2401 Inst::Swpal64 { rs, rt, rn } => {
2402 0xF8E08000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2403 }
2404 Inst::Swpalb { rs, rt, rn } => {
2405 0x38E08000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2406 }
2407 Inst::Swpalh { rs, rt, rn } => {
2408 0x78E08000 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2409 }
2410 Inst::Casalb { rs, rt, rn } => {
2411 0x08E0FC00 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2412 }
2413 Inst::Casalh { rs, rt, rn } => {
2414 0x48E0FC00 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2415 }
2416 Inst::Casal32 { rs, rt, rn } => {
2417 0x88E0FC00 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2418 }
2419 Inst::Casal64 { rs, rt, rn } => {
2420 0xC8E0FC00 | (rs.enc() << 16) | (rn.enc() << 5) | rt.enc()
2421 }
2422
2423 // ---- Load/Store pair ----
2424 Inst::StpOff32 {
2425 rt1,
2426 rt2,
2427 rn,
2428 offset,
2429 } => ldp_stp(0b00, 0b010, 0, *offset, *rt2, *rn, *rt1),
2430 Inst::StpOff64 {
2431 rt1,
2432 rt2,
2433 rn,
2434 offset,
2435 } => ldp_stp(0b10, 0b010, 0, *offset, *rt2, *rn, *rt1),
2436 Inst::LdpOff32 {
2437 rt1,
2438 rt2,
2439 rn,
2440 offset,
2441 } => ldp_stp(0b00, 0b010, 1, *offset, *rt2, *rn, *rt1),
2442 Inst::LdpOff64 {
2443 rt1,
2444 rt2,
2445 rn,
2446 offset,
2447 } => ldp_stp(0b10, 0b010, 1, *offset, *rt2, *rn, *rt1),
2448 Inst::StpPre32 {
2449 rt1,
2450 rt2,
2451 rn,
2452 offset,
2453 } => ldp_stp(0b00, 0b011, 0, *offset, *rt2, *rn, *rt1),
2454 Inst::StpPre64 {
2455 rt1,
2456 rt2,
2457 rn,
2458 offset,
2459 } => ldp_stp(0b10, 0b011, 0, *offset, *rt2, *rn, *rt1),
2460 Inst::StpPost32 {
2461 rt1,
2462 rt2,
2463 rn,
2464 offset,
2465 } => ldp_stp(0b00, 0b001, 0, *offset, *rt2, *rn, *rt1),
2466 Inst::StpPost64 {
2467 rt1,
2468 rt2,
2469 rn,
2470 offset,
2471 } => ldp_stp(0b10, 0b001, 0, *offset, *rt2, *rn, *rt1),
2472 Inst::LdpPre32 {
2473 rt1,
2474 rt2,
2475 rn,
2476 offset,
2477 } => ldp_stp(0b00, 0b011, 1, *offset, *rt2, *rn, *rt1),
2478 Inst::LdpPre64 {
2479 rt1,
2480 rt2,
2481 rn,
2482 offset,
2483 } => ldp_stp(0b10, 0b011, 1, *offset, *rt2, *rn, *rt1),
2484 Inst::LdpPost32 {
2485 rt1,
2486 rt2,
2487 rn,
2488 offset,
2489 } => ldp_stp(0b00, 0b001, 1, *offset, *rt2, *rn, *rt1),
2490 Inst::LdpPost64 {
2491 rt1,
2492 rt2,
2493 rn,
2494 offset,
2495 } => ldp_stp(0b10, 0b001, 1, *offset, *rt2, *rn, *rt1),
2496 Inst::StpFpOff64 {
2497 rt1,
2498 rt2,
2499 rn,
2500 offset,
2501 } => ldp_stp_fp(0b01, 0b010, 0, *offset, *rt2, *rn, *rt1),
2502 Inst::LdpFpOff64 {
2503 rt1,
2504 rt2,
2505 rn,
2506 offset,
2507 } => ldp_stp_fp(0b01, 0b010, 1, *offset, *rt2, *rn, *rt1),
2508 Inst::StpFpPre64 {
2509 rt1,
2510 rt2,
2511 rn,
2512 offset,
2513 } => ldp_stp_fp(0b01, 0b011, 0, *offset, *rt2, *rn, *rt1),
2514 Inst::StpFpPost64 {
2515 rt1,
2516 rt2,
2517 rn,
2518 offset,
2519 } => ldp_stp_fp(0b01, 0b001, 0, *offset, *rt2, *rn, *rt1),
2520 Inst::LdpFpPre64 {
2521 rt1,
2522 rt2,
2523 rn,
2524 offset,
2525 } => ldp_stp_fp(0b01, 0b011, 1, *offset, *rt2, *rn, *rt1),
2526 Inst::LdpFpPost64 {
2527 rt1,
2528 rt2,
2529 rn,
2530 offset,
2531 } => ldp_stp_fp(0b01, 0b001, 1, *offset, *rt2, *rn, *rt1),
2532 Inst::StpFpOff32 {
2533 rt1,
2534 rt2,
2535 rn,
2536 offset,
2537 } => ldp_stp_fp(0b00, 0b010, 0, *offset, *rt2, *rn, *rt1),
2538 Inst::LdpFpOff32 {
2539 rt1,
2540 rt2,
2541 rn,
2542 offset,
2543 } => ldp_stp_fp(0b00, 0b010, 1, *offset, *rt2, *rn, *rt1),
2544 Inst::StpFpPre32 {
2545 rt1,
2546 rt2,
2547 rn,
2548 offset,
2549 } => ldp_stp_fp(0b00, 0b011, 0, *offset, *rt2, *rn, *rt1),
2550 Inst::StpFpPost32 {
2551 rt1,
2552 rt2,
2553 rn,
2554 offset,
2555 } => ldp_stp_fp(0b00, 0b001, 0, *offset, *rt2, *rn, *rt1),
2556 Inst::LdpFpPre32 {
2557 rt1,
2558 rt2,
2559 rn,
2560 offset,
2561 } => ldp_stp_fp(0b00, 0b011, 1, *offset, *rt2, *rn, *rt1),
2562 Inst::LdpFpPost32 {
2563 rt1,
2564 rt2,
2565 rn,
2566 offset,
2567 } => ldp_stp_fp(0b00, 0b001, 1, *offset, *rt2, *rn, *rt1),
2568 Inst::StpFpOff128 {
2569 rt1,
2570 rt2,
2571 rn,
2572 offset,
2573 } => ldp_stp_fp(0b10, 0b010, 0, *offset, *rt2, *rn, *rt1),
2574 Inst::LdpFpOff128 {
2575 rt1,
2576 rt2,
2577 rn,
2578 offset,
2579 } => ldp_stp_fp(0b10, 0b010, 1, *offset, *rt2, *rn, *rt1),
2580 Inst::StpFpPre128 {
2581 rt1,
2582 rt2,
2583 rn,
2584 offset,
2585 } => ldp_stp_fp(0b10, 0b011, 0, *offset, *rt2, *rn, *rt1),
2586 Inst::StpFpPost128 {
2587 rt1,
2588 rt2,
2589 rn,
2590 offset,
2591 } => ldp_stp_fp(0b10, 0b001, 0, *offset, *rt2, *rn, *rt1),
2592 Inst::LdpFpPre128 {
2593 rt1,
2594 rt2,
2595 rn,
2596 offset,
2597 } => ldp_stp_fp(0b10, 0b011, 1, *offset, *rt2, *rn, *rt1),
2598 Inst::LdpFpPost128 {
2599 rt1,
2600 rt2,
2601 rn,
2602 offset,
2603 } => ldp_stp_fp(0b10, 0b001, 1, *offset, *rt2, *rn, *rt1),
2604
2605 // ---- FP arithmetic ----
2606 Inst::FaddD { rd, rn, rm } => fp_arith(0b01, 0b0010, *rm, *rn, *rd),
2607 Inst::FsubD { rd, rn, rm } => fp_arith(0b01, 0b0011, *rm, *rn, *rd),
2608 Inst::FmulD { rd, rn, rm } => fp_arith(0b01, 0b0000, *rm, *rn, *rd),
2609 Inst::FdivD { rd, rn, rm } => fp_arith(0b01, 0b0001, *rm, *rn, *rd),
2610 Inst::FaddS { rd, rn, rm } => fp_arith(0b00, 0b0010, *rm, *rn, *rd),
2611 Inst::FaddV2D { rd, rn, rm } => simd_fp_arith_2d(0x4E60D400, *rm, *rn, *rd),
2612 Inst::FaddV4S { rd, rn, rm } => simd_fp_arith_4s(0x4E20D400, *rm, *rn, *rd),
2613 Inst::FaddpV2D { rd, rn, rm } => simd_fp_arith_2d(0x6E60D400, *rm, *rn, *rd),
2614 Inst::FaddpV4S { rd, rn, rm } => simd_fp_arith_4s(0x6E20D400, *rm, *rn, *rd),
2615 Inst::FmaxpV2D { rd, rn, rm } => simd_fp_arith_2d(0x6E60F400, *rm, *rn, *rd),
2616 Inst::FmaxpV4S { rd, rn, rm } => simd_fp_arith_4s(0x6E20F400, *rm, *rn, *rd),
2617 Inst::FminpV2D { rd, rn, rm } => simd_fp_arith_2d(0x6EE0F400, *rm, *rn, *rd),
2618 Inst::FminpV4S { rd, rn, rm } => simd_fp_arith_4s(0x6EA0F400, *rm, *rn, *rd),
2619 Inst::FmaxnmpV2D { rd, rn, rm } => simd_fp_arith_2d(0x6E60C400, *rm, *rn, *rd),
2620 Inst::FmaxnmpV4S { rd, rn, rm } => simd_fp_arith_4s(0x6E20C400, *rm, *rn, *rd),
2621 Inst::FminnmpV2D { rd, rn, rm } => simd_fp_arith_2d(0x6EE0C400, *rm, *rn, *rd),
2622 Inst::FminnmpV4S { rd, rn, rm } => simd_fp_arith_4s(0x6EA0C400, *rm, *rn, *rd),
2623 Inst::FaddpV2S { rd, rn } => simd_reduce_4s(0x7E30D800, *rn, *rd),
2624 Inst::FaddpV2DScalar { rd, rn } => simd_reduce(0x7E70D800, *rn, *rd),
2625 Inst::FmaxpV2DScalar { rd, rn } => simd_reduce(0x7E70F800, *rn, *rd),
2626 Inst::FminpV2DScalar { rd, rn } => simd_reduce(0x7EF0F800, *rn, *rd),
2627 Inst::FmaxnmpV2DScalar { rd, rn } => simd_reduce(0x7E70C800, *rn, *rd),
2628 Inst::FminnmpV2DScalar { rd, rn } => simd_reduce(0x7EF0C800, *rn, *rd),
2629 Inst::FmlaV4S { rd, rn, rm } => simd_fp_arith_4s(0x4E20CC00, *rm, *rn, *rd),
2630 Inst::FmlaV2D { rd, rn, rm } => simd_fp_arith_2d(0x4E60CC00, *rm, *rn, *rd),
2631 Inst::FmlsV4S { rd, rn, rm } => simd_fp_arith_4s(0x4EA0CC00, *rm, *rn, *rd),
2632 Inst::FmlsV2D { rd, rn, rm } => simd_fp_arith_2d(0x4EE0CC00, *rm, *rn, *rd),
2633 Inst::AddV4S { rd, rn, rm } => simd_binary(0x4EA08400, *rm, *rn, *rd),
2634 Inst::AddpV2D { rd, rn, rm } => simd_binary(0x4EE0BC00, *rm, *rn, *rd),
2635 Inst::AddpV16B { rd, rn, rm } => simd_binary(0x4E20BC00, *rm, *rn, *rd),
2636 Inst::AddpV8H { rd, rn, rm } => simd_binary(0x4E60BC00, *rm, *rn, *rd),
2637 Inst::AddpV4S { rd, rn, rm } => simd_binary(0x4EA0BC00, *rm, *rn, *rd),
2638 Inst::SmaxpV16B { rd, rn, rm } => simd_binary(0x4E20A400, *rm, *rn, *rd),
2639 Inst::SmaxpV8H { rd, rn, rm } => simd_binary(0x4E60A400, *rm, *rn, *rd),
2640 Inst::SmaxpV4S { rd, rn, rm } => simd_binary(0x4EA0A400, *rm, *rn, *rd),
2641 Inst::SminpV16B { rd, rn, rm } => simd_binary(0x4E20AC00, *rm, *rn, *rd),
2642 Inst::SminpV8H { rd, rn, rm } => simd_binary(0x4E60AC00, *rm, *rn, *rd),
2643 Inst::SminpV4S { rd, rn, rm } => simd_binary(0x4EA0AC00, *rm, *rn, *rd),
2644 Inst::FmaxV2D { rd, rn, rm } => simd_fp_arith_2d(0x4E60F400, *rm, *rn, *rd),
2645 Inst::FmaxV4S { rd, rn, rm } => simd_fp_arith_4s(0x4E20F400, *rm, *rn, *rd),
2646 Inst::FminV2D { rd, rn, rm } => simd_fp_arith_2d(0x4EE0F400, *rm, *rn, *rd),
2647 Inst::FminV4S { rd, rn, rm } => simd_fp_arith_4s(0x4EA0F400, *rm, *rn, *rd),
2648 Inst::FmaxnmV2D { rd, rn, rm } => simd_fp_arith_2d(0x4E60C400, *rm, *rn, *rd),
2649 Inst::FmaxnmV4S { rd, rn, rm } => simd_fp_arith_4s(0x4E20C400, *rm, *rn, *rd),
2650 Inst::FminnmV2D { rd, rn, rm } => simd_fp_arith_2d(0x4EE0C400, *rm, *rn, *rd),
2651 Inst::FminnmV4S { rd, rn, rm } => simd_fp_arith_4s(0x4EA0C400, *rm, *rn, *rd),
2652 Inst::SmaxV4S { rd, rn, rm } => simd_binary(0x4EA06400, *rm, *rn, *rd),
2653 Inst::SminV4S { rd, rn, rm } => simd_binary(0x4EA06C00, *rm, *rn, *rd),
2654 Inst::UmaxV4S { rd, rn, rm } => simd_binary(0x6EA06400, *rm, *rn, *rd),
2655 Inst::UmaxpV16B { rd, rn, rm } => simd_binary(0x6E20A400, *rm, *rn, *rd),
2656 Inst::UmaxpV8H { rd, rn, rm } => simd_binary(0x6E60A400, *rm, *rn, *rd),
2657 Inst::UminV4S { rd, rn, rm } => simd_binary(0x6EA06C00, *rm, *rn, *rd),
2658 Inst::UminpV16B { rd, rn, rm } => simd_binary(0x6E20AC00, *rm, *rn, *rd),
2659 Inst::UminpV8H { rd, rn, rm } => simd_binary(0x6E60AC00, *rm, *rn, *rd),
2660 Inst::UmaxpV4S { rd, rn, rm } => simd_binary(0x6EA0A400, *rm, *rn, *rd),
2661 Inst::UminpV4S { rd, rn, rm } => simd_binary(0x6EA0AC00, *rm, *rn, *rd),
2662 Inst::AddvV16B { rd, rn } => simd_reduce(0x4E31B800, *rn, *rd),
2663 Inst::AddvV8H { rd, rn } => simd_reduce(0x4E71B800, *rn, *rd),
2664 Inst::AddvV4S { rd, rn } => simd_reduce_4s(0x4EB1B800, *rn, *rd),
2665 Inst::UmaxvV16B { rd, rn } => simd_reduce(0x6E30A800, *rn, *rd),
2666 Inst::UmaxvV8H { rd, rn } => simd_reduce(0x6E70A800, *rn, *rd),
2667 Inst::UmaxvV4S { rd, rn } => simd_reduce_4s(0x6EB0A800, *rn, *rd),
2668 Inst::SmaxvV16B { rd, rn } => simd_reduce(0x4E30A800, *rn, *rd),
2669 Inst::SmaxvV8H { rd, rn } => simd_reduce(0x4E70A800, *rn, *rd),
2670 Inst::SmaxvV4S { rd, rn } => simd_reduce_4s(0x4EB0A800, *rn, *rd),
2671 Inst::UminvV16B { rd, rn } => simd_reduce(0x6E31A800, *rn, *rd),
2672 Inst::UminvV8H { rd, rn } => simd_reduce(0x6E71A800, *rn, *rd),
2673 Inst::UminvV4S { rd, rn } => simd_reduce_4s(0x6EB1A800, *rn, *rd),
2674 Inst::SminvV16B { rd, rn } => simd_reduce(0x4E31A800, *rn, *rd),
2675 Inst::SminvV8H { rd, rn } => simd_reduce(0x4E71A800, *rn, *rd),
2676 Inst::SminvV4S { rd, rn } => simd_reduce_4s(0x4EB1A800, *rn, *rd),
2677 Inst::FmaxvV4S { rd, rn } => simd_reduce_4s(0x6E30F800, *rn, *rd),
2678 Inst::FminvV4S { rd, rn } => simd_reduce_4s(0x6EB0F800, *rn, *rd),
2679 Inst::FmaxnmvV4S { rd, rn } => simd_reduce_4s(0x6E30C800, *rn, *rd),
2680 Inst::FminnmvV4S { rd, rn } => simd_reduce_4s(0x6EB0C800, *rn, *rd),
2681 Inst::FsubV2D { rd, rn, rm } => simd_fp_arith_2d(0x4EE0D400, *rm, *rn, *rd),
2682 Inst::FsubV4S { rd, rn, rm } => simd_fp_arith_4s(0x4EA0D400, *rm, *rn, *rd),
2683 Inst::SubV4S { rd, rn, rm } => simd_binary(0x6EA08400, *rm, *rn, *rd),
2684 Inst::FsubS { rd, rn, rm } => fp_arith(0b00, 0b0011, *rm, *rn, *rd),
2685 Inst::FmulV2D { rd, rn, rm } => simd_fp_arith_2d(0x6E60DC00, *rm, *rn, *rd),
2686 Inst::FmulV4S { rd, rn, rm } => simd_fp_arith_4s(0x6E20DC00, *rm, *rn, *rd),
2687 Inst::FmulS { rd, rn, rm } => fp_arith(0b00, 0b0000, *rm, *rn, *rd),
2688 Inst::FdivV2D { rd, rn, rm } => simd_fp_arith_2d(0x6E60FC00, *rm, *rn, *rd),
2689 Inst::FabdV2D { rd, rn, rm } => simd_fp_arith_2d(0x6EE0D400, *rm, *rn, *rd),
2690 Inst::FdivV4S { rd, rn, rm } => simd_fp_arith_4s(0x6E20FC00, *rm, *rn, *rd),
2691 Inst::FabsV4S { rd, rn } => simd_unary(0x4EA0F800, *rn, *rd),
2692 Inst::FabsV2D { rd, rn } => simd_unary(0x4EE0F800, *rn, *rd),
2693 Inst::FnegV4S { rd, rn } => simd_unary(0x6EA0F800, *rn, *rd),
2694 Inst::FnegV2D { rd, rn } => simd_unary(0x6EE0F800, *rn, *rd),
2695 Inst::FsqrtV4S { rd, rn } => simd_unary(0x6EA1F800, *rn, *rd),
2696 Inst::FsqrtV2D { rd, rn } => simd_unary(0x6EE1F800, *rn, *rd),
2697 Inst::ScvtfV4S { rd, rn } => simd_unary(0x4E21D800, *rn, *rd),
2698 Inst::ScvtfV2D { rd, rn } => simd_unary(0x4E61D800, *rn, *rd),
2699 Inst::UcvtfV4S { rd, rn } => simd_unary(0x6E21D800, *rn, *rd),
2700 Inst::UcvtfV2D { rd, rn } => simd_unary(0x6E61D800, *rn, *rd),
2701 Inst::FcvtzsV4S { rd, rn } => simd_unary(0x4EA1B800, *rn, *rd),
2702 Inst::FcvtzsV2D { rd, rn } => simd_unary(0x4EE1B800, *rn, *rd),
2703 Inst::FcvtzuV4S { rd, rn } => simd_unary(0x6EA1B800, *rn, *rd),
2704 Inst::FcvtzuV2D { rd, rn } => simd_unary(0x6EE1B800, *rn, *rd),
2705 Inst::FrecpeV4S { rd, rn } => simd_unary(0x4EA1D800, *rn, *rd),
2706 Inst::FrecpeV2D { rd, rn } => simd_unary(0x4EE1D800, *rn, *rd),
2707 Inst::FrecpsV4S { rd, rn, rm } => simd_fp_arith_4s(0x4E20FC00, *rm, *rn, *rd),
2708 Inst::FrecpsV2D { rd, rn, rm } => simd_fp_arith_2d(0x4E60FC00, *rm, *rn, *rd),
2709 Inst::FrsqrteV4S { rd, rn } => simd_unary(0x6EA1D800, *rn, *rd),
2710 Inst::FrsqrteV2D { rd, rn } => simd_unary(0x6EE1D800, *rn, *rd),
2711 Inst::FrsqrtsV4S { rd, rn, rm } => simd_fp_arith_4s(0x4EA0FC00, *rm, *rn, *rd),
2712 Inst::FrsqrtsV2D { rd, rn, rm } => simd_fp_arith_2d(0x4EE0FC00, *rm, *rn, *rd),
2713 Inst::FrintnV4S { rd, rn } => simd_unary(0x4E218800, *rn, *rd),
2714 Inst::FrintnV2D { rd, rn } => simd_unary(0x4E618800, *rn, *rd),
2715 Inst::FrintmV4S { rd, rn } => simd_unary(0x4E219800, *rn, *rd),
2716 Inst::FrintmV2D { rd, rn } => simd_unary(0x4E619800, *rn, *rd),
2717 Inst::FrintpV4S { rd, rn } => simd_unary(0x4EA18800, *rn, *rd),
2718 Inst::FrintpV2D { rd, rn } => simd_unary(0x4EE18800, *rn, *rd),
2719 Inst::FrintzV4S { rd, rn } => simd_unary(0x4EA19800, *rn, *rd),
2720 Inst::FrintzV2D { rd, rn } => simd_unary(0x4EE19800, *rn, *rd),
2721 Inst::FrintaV4S { rd, rn } => simd_unary(0x6E218800, *rn, *rd),
2722 Inst::FrintaV2D { rd, rn } => simd_unary(0x6E618800, *rn, *rd),
2723 Inst::FrintiV4S { rd, rn } => simd_unary(0x6EA19800, *rn, *rd),
2724 Inst::FrintiV2D { rd, rn } => simd_unary(0x6EE19800, *rn, *rd),
2725 Inst::FdivS { rd, rn, rm } => fp_arith(0b00, 0b0001, *rm, *rn, *rd),
2726 Inst::FmovRegD { rd, rn } => fp_mov_reg(0x1E604000, *rn, *rd),
2727 Inst::FmovRegS { rd, rn } => fp_mov_reg(0x1E204000, *rn, *rd),
2728 Inst::MovV8B { rd, rn } => simd_mov_reg(0x0EA01C00, *rn, *rd),
2729 Inst::MovV16B { rd, rn } => simd_mov_reg(0x4EA01C00, *rn, *rd),
2730 Inst::MovV4S { rd, rn } => simd_mov_reg(0x4EA01C00, *rn, *rd),
2731 Inst::MovV2D { rd, rn } => simd_mov_reg(0x4EA01C00, *rn, *rd),
2732 Inst::DupV16B { rd, rn, index } => simd_dup_lane(0, *rn, *index, *rd),
2733 Inst::DupV8H { rd, rn, index } => simd_dup_lane(1, *rn, *index, *rd),
2734 Inst::DupV4S { rd, rn, index } => simd_dup_lane(2, *rn, *index, *rd),
2735 Inst::DupV2D { rd, rn, index } => simd_dup_lane(3, *rn, *index, *rd),
2736 Inst::AndV16B { rd, rn, rm } => simd_binary(0x4E201C00, *rm, *rn, *rd),
2737 Inst::BicV16B { rd, rn, rm } => simd_binary(0x4E601C00, *rm, *rn, *rd),
2738 Inst::OrrV16B { rd, rn, rm } => simd_binary(0x4EA01C00, *rm, *rn, *rd),
2739 Inst::EorV16B { rd, rn, rm } => simd_binary(0x6E201C00, *rm, *rn, *rd),
2740 Inst::BifV16B { rd, rn, rm } => simd_binary(0x6EE01C00, *rm, *rn, *rd),
2741 Inst::BitV16B { rd, rn, rm } => simd_binary(0x6EA01C00, *rm, *rn, *rd),
2742 Inst::BslV16B { rd, rn, rm } => simd_binary(0x6E601C00, *rm, *rn, *rd),
2743 Inst::CmeqV4S { rd, rn, rm } => simd_binary(0x6EA08C00, *rm, *rn, *rd),
2744 Inst::FcmeqV4S { rd, rn, rm } => simd_binary(0x4E20E400, *rm, *rn, *rd),
2745 Inst::FcmeqV2D { rd, rn, rm } => simd_binary(0x4E60E400, *rm, *rn, *rd),
2746 Inst::CmhsV4S { rd, rn, rm } => simd_binary(0x6EA03C00, *rm, *rn, *rd),
2747 Inst::CmhiV4S { rd, rn, rm } => simd_binary(0x6EA03400, *rm, *rn, *rd),
2748 Inst::CmgeV4S { rd, rn, rm } => simd_binary(0x4EA03C00, *rm, *rn, *rd),
2749 Inst::FcmgeV4S { rd, rn, rm } => simd_binary(0x6E20E400, *rm, *rn, *rd),
2750 Inst::FcmgeV2D { rd, rn, rm } => simd_binary(0x6E60E400, *rm, *rn, *rd),
2751 Inst::FcmgeZeroV2D { rd, rn } => simd_unary(0x6EE0C800, *rn, *rd),
2752 Inst::CmgtV4S { rd, rn, rm } => simd_binary(0x4EA03400, *rm, *rn, *rd),
2753 Inst::FcmgtV4S { rd, rn, rm } => simd_binary(0x6EA0E400, *rm, *rn, *rd),
2754 Inst::FcmgtV2D { rd, rn, rm } => simd_binary(0x6EE0E400, *rm, *rn, *rd),
2755 Inst::FcmgtZeroV2D { rd, rn } => simd_unary(0x4EE0C800, *rn, *rd),
2756 Inst::FcmleZeroV2D { rd, rn } => simd_unary(0x6EE0D800, *rn, *rd),
2757 Inst::FcmltZeroV2D { rd, rn } => simd_unary(0x4EE0E800, *rn, *rd),
2758 Inst::ExtV16B { rd, rn, rm, index } => simd_ext_16b(*rm, *rn, *rd, *index),
2759 Inst::Rev64V4S { rd, rn } => simd_unary(0x4EA00800, *rn, *rd),
2760 Inst::Zip1V4S { rd, rn, rm } => simd_binary(0x4E803800, *rm, *rn, *rd),
2761 Inst::Zip1V2D { rd, rn, rm } => simd_binary(0x4EC03800, *rm, *rn, *rd),
2762 Inst::Zip2V4S { rd, rn, rm } => simd_binary(0x4E807800, *rm, *rn, *rd),
2763 Inst::Zip2V2D { rd, rn, rm } => simd_binary(0x4EC07800, *rm, *rn, *rd),
2764 Inst::Uzp1V4S { rd, rn, rm } => simd_binary(0x4E801800, *rm, *rn, *rd),
2765 Inst::Uzp1V2D { rd, rn, rm } => simd_binary(0x4EC01800, *rm, *rn, *rd),
2766 Inst::Uzp2V4S { rd, rn, rm } => simd_binary(0x4E805800, *rm, *rn, *rd),
2767 Inst::Uzp2V2D { rd, rn, rm } => simd_binary(0x4EC05800, *rm, *rn, *rd),
2768 Inst::Trn1V4S { rd, rn, rm } => simd_binary(0x4E802800, *rm, *rn, *rd),
2769 Inst::Trn1V2D { rd, rn, rm } => simd_binary(0x4EC02800, *rm, *rn, *rd),
2770 Inst::Trn2V4S { rd, rn, rm } => simd_binary(0x4E806800, *rm, *rn, *rd),
2771 Inst::Trn2V2D { rd, rn, rm } => simd_binary(0x4EC06800, *rm, *rn, *rd),
2772 Inst::TblV16B {
2773 rd,
2774 table,
2775 table_len,
2776 index,
2777 } => simd_table_lookup(0x4E000000, *index, *table, *table_len, *rd),
2778 Inst::TbxV16B {
2779 rd,
2780 table,
2781 table_len,
2782 index,
2783 } => simd_table_lookup(0x4E001000, *index, *table, *table_len, *rd),
2784 Inst::MovFromLaneS { rd, rn, index } => simd_extract_lane_s(*rn, *index, *rd),
2785 Inst::MovFromLaneD { rd, rn, index } => simd_extract_lane_d(*rn, *index, *rd),
2786 Inst::MovFromLaneGpS { rd, rn, index } => simd_extract_lane_gp(2, *rn, *index, *rd),
2787 Inst::MovFromLaneGpD { rd, rn, index } => simd_extract_lane_gp(3, *rn, *index, *rd),
2788 Inst::UmovFromLaneH { rd, rn, index } => simd_extract_lane_gp(1, *rn, *index, *rd),
2789 Inst::UmovFromLaneB { rd, rn, index } => simd_extract_lane_gp(0, *rn, *index, *rd),
2790 Inst::SmovFromLaneH { rd, rn, index } => {
2791 simd_extract_lane_gp_signed(1, *rn, *index, *rd)
2792 }
2793 Inst::SmovFromLaneB { rd, rn, index } => {
2794 simd_extract_lane_gp_signed(0, *rn, *index, *rd)
2795 }
2796 Inst::MovLaneS {
2797 rd,
2798 rd_index,
2799 rn,
2800 rn_index,
2801 } => simd_insert_lane_s(*rn, *rn_index, *rd, *rd_index),
2802 Inst::MovLaneD {
2803 rd,
2804 rd_index,
2805 rn,
2806 rn_index,
2807 } => simd_insert_lane_d(*rn, *rn_index, *rd, *rd_index),
2808 Inst::MovLaneH {
2809 rd,
2810 rd_index,
2811 rn,
2812 rn_index,
2813 } => simd_insert_lane_h(*rn, *rn_index, *rd, *rd_index),
2814 Inst::MovLaneB {
2815 rd,
2816 rd_index,
2817 rn,
2818 rn_index,
2819 } => simd_insert_lane_b(*rn, *rn_index, *rd, *rd_index),
2820 Inst::MovLaneFromGpS { rd, rd_index, rn } => {
2821 simd_insert_lane_gp(2, *rn, *rd_index, *rd)
2822 }
2823 Inst::MovLaneFromGpD { rd, rd_index, rn } => {
2824 simd_insert_lane_gp(3, *rn, *rd_index, *rd)
2825 }
2826 Inst::MovLaneFromGpH { rd, rd_index, rn } => {
2827 simd_insert_lane_gp(1, *rn, *rd_index, *rd)
2828 }
2829 Inst::MovLaneFromGpB { rd, rd_index, rn } => {
2830 simd_insert_lane_gp(0, *rn, *rd_index, *rd)
2831 }
2832 Inst::Ld1LaneB { rt, index, rn } => simd_load_lane(0, *rn, *index, *rt),
2833 Inst::Ld1LaneH { rt, index, rn } => simd_load_lane(1, *rn, *index, *rt),
2834 Inst::Ld1LaneS { rt, index, rn } => simd_load_lane(2, *rn, *index, *rt),
2835 Inst::Ld1LaneD { rt, index, rn } => simd_load_lane(3, *rn, *index, *rt),
2836
2837 Inst::FnegD { rd, rn } => fp_unary(0b01, 0b0000_10, *rn, *rd),
2838 Inst::FnegS { rd, rn } => fp_unary(0b00, 0b0000_10, *rn, *rd),
2839 Inst::FabsD { rd, rn } => fp_unary(0b01, 0b0000_01, *rn, *rd),
2840 Inst::FabsS { rd, rn } => fp_unary(0b00, 0b0000_01, *rn, *rd),
2841 Inst::FsqrtD { rd, rn } => fp_unary(0b01, 0b0000_11, *rn, *rd),
2842 Inst::FsqrtS { rd, rn } => fp_unary(0b00, 0b0000_11, *rn, *rd),
2843 Inst::FcmpD { rn, rm } => fp_cmp(0b01, *rn, *rm),
2844 Inst::FcmpS { rn, rm } => fp_cmp(0b00, *rn, *rm),
2845 Inst::FmovImmD { rd, imm8 } => fp_imm(0b01, *imm8, *rd),
2846 Inst::FmovImmS { rd, imm8 } => fp_imm(0b00, *imm8, *rd),
2847 Inst::FcselD { rd, rn, rm, cond } => fp_csel(0b01, *rm, *cond, *rn, *rd),
2848 Inst::FcselS { rd, rn, rm, cond } => fp_csel(0b00, *rm, *cond, *rn, *rd),
2849 Inst::FmaddD { rd, rn, rm, ra } => fp_madd(0b01, *rd, *rn, *rm, *ra),
2850 Inst::FmaddS { rd, rn, rm, ra } => fp_madd(0b00, *rd, *rn, *rm, *ra),
2851
2852 // ---- FP / integer conversion ----
2853 Inst::FcvtzsD { rd, rn } => {
2854 (0b1_00_11110_01_1 << 21) | (0b11_000 << 16) | (rn.enc() << 5) | rd.enc()
2855 }
2856 Inst::ScvtfD { rd, rn } => {
2857 (0b1_00_11110_01_1 << 21) | (0b00_010 << 16) | (rn.enc() << 5) | rd.enc()
2858 }
2859 Inst::FmovToD { rd, rn } => {
2860 (0b1_00_11110_01_1 << 21) | (0b00_111 << 16) | (rn.enc() << 5) | rd.enc()
2861 }
2862 Inst::FmovToS { rd, rn } => 0x1E270000 | (rn.enc() << 5) | rd.enc(),
2863 Inst::FmovFromD { rd, rn } => {
2864 (0b1_00_11110_01_1 << 21) | (0b00_110 << 16) | (rn.enc() << 5) | rd.enc()
2865 }
2866 Inst::FmovFromS { rd, rn } => 0x1E260000 | (rn.enc() << 5) | rd.enc(),
2867
2868 // ---- System ----
2869 Inst::Svc { imm16 } => (0b11010100_000 << 21) | ((*imm16 as u32) << 5) | 0b000_01,
2870 Inst::Nop => hint(0),
2871 Inst::Yield => hint(1),
2872 Inst::Wfe => hint(2),
2873 Inst::Wfi => hint(3),
2874 Inst::Sev => hint(4),
2875 Inst::Sevl => hint(5),
2876 Inst::Dmb { option } => barrier(0xD50330BF, *option),
2877 Inst::Dsb { option } => barrier(0xD503309F, *option),
2878 Inst::Isb { option } => barrier(0xD50330DF, *option),
2879 Inst::Brk { imm16 } => (0b11010100_001 << 21) | ((*imm16 as u32) << 5),
2880 }
2881 }
2882 }
2883
2884 // ---- Encoding helpers ----
2885
2886 #[allow(clippy::too_many_arguments)]
2887 fn dp_reg(
2888 sf: bool,
2889 opc: u32,
2890 fixed: u32,
2891 shift: u32,
2892 rm: GpReg,
2893 imm6: u32,
2894 rn: GpReg,
2895 rd: GpReg,
2896 ) -> u32 {
2897 ((sf as u32) << 31)
2898 | (opc << 29)
2899 | (fixed << 24)
2900 | (shift << 22)
2901 | (rm.enc() << 16)
2902 | (imm6 << 10)
2903 | (rn.enc() << 5)
2904 | rd.enc()
2905 }
2906
2907 fn logic_reg(sf: bool, opc: u32, n: bool, rm: GpReg, rn: GpReg, rd: GpReg) -> u32 {
2908 ((sf as u32) << 31)
2909 | (opc << 29)
2910 | (0b01010 << 24)
2911 | ((n as u32) << 21)
2912 | (rm.enc() << 16)
2913 | (rn.enc() << 5)
2914 | rd.enc()
2915 }
2916
2917 fn logical_imm(sf: bool, opc: u32, imm: u64, rn: GpReg, rd: GpReg) -> u32 {
2918 let width = if sf { 64 } else { 32 };
2919 let imm = if sf { imm } else { imm & 0xFFFF_FFFF };
2920 let (n, immr, imms) =
2921 encode_logical_immediate(imm, width).expect("logical immediate validated by parser");
2922 ((sf as u32) << 31)
2923 | (opc << 29)
2924 | (0b100100 << 23)
2925 | ((n as u32) << 22)
2926 | ((immr as u32) << 16)
2927 | ((imms as u32) << 10)
2928 | (rn.enc() << 5)
2929 | rd.enc()
2930 }
2931
2932 fn dp_imm(sf: bool, op: u32, imm12: u16, shift: bool, rn: GpReg, rd: GpReg) -> u32 {
2933 ((sf as u32) << 31)
2934 | (op << 29)
2935 | (0b100010 << 23)
2936 | ((shift as u32) << 22)
2937 | ((imm12 as u32) << 10)
2938 | (rn.enc() << 5)
2939 | rd.enc()
2940 }
2941
2942 fn dp_ext(
2943 sf: bool,
2944 op: u32,
2945 rm: GpReg,
2946 extend: RegExtend,
2947 amount: u8,
2948 rn: GpReg,
2949 rd: GpReg,
2950 ) -> u32 {
2951 ((sf as u32) << 31)
2952 | (op << 29)
2953 | (0b01011 << 24)
2954 | (1 << 21)
2955 | (rm.enc() << 16)
2956 | (extend.enc() << 13)
2957 | ((amount as u32) << 10)
2958 | (rn.enc() << 5)
2959 | rd.enc()
2960 }
2961
2962 fn mov_wide(sf: bool, opc: u32, imm16: u16, shift: u8, rd: GpReg) -> u32 {
2963 let hw = (shift / 16) as u32;
2964 ((sf as u32) << 31)
2965 | (opc << 29)
2966 | (0b100101 << 23)
2967 | (hw << 21)
2968 | ((imm16 as u32) << 5)
2969 | rd.enc()
2970 }
2971
2972 fn bitfield(sf: bool, opc: u32, immr: u8, imms: u8, rn: GpReg, rd: GpReg) -> u32 {
2973 let n = sf as u32;
2974 ((sf as u32) << 31)
2975 | (opc << 29)
2976 | (0b100110 << 23)
2977 | (n << 22)
2978 | ((immr as u32) << 16)
2979 | ((imms as u32) << 10)
2980 | (rn.enc() << 5)
2981 | rd.enc()
2982 }
2983
2984 fn encode_logical_immediate(imm: u64, width: u8) -> Option<(bool, u8, u8)> {
2985 let mask = if width == 64 {
2986 u64::MAX
2987 } else {
2988 (1u64 << width) - 1
2989 };
2990 let imm = imm & mask;
2991 if imm == 0 || imm == mask {
2992 return None;
2993 }
2994
2995 for esize in [2u8, 4, 8, 16, 32, 64] {
2996 if esize > width {
2997 continue;
2998 }
2999 for ones in 1..esize {
3000 let base = if ones == 64 {
3001 u64::MAX
3002 } else {
3003 (1u64 << ones) - 1
3004 };
3005 for rot in 0..esize {
3006 let pattern = rotate_right_with_width(base, rot, esize);
3007 let candidate = replicate_pattern(pattern, esize, width);
3008 if candidate == imm {
3009 let n = esize == 64;
3010 let imms =
3011 (((!(u64::from(esize) - 1)) << 1) | u64::from(ones - 1)) as u8 & 0x3F;
3012 return Some((n, rot, imms));
3013 }
3014 }
3015 }
3016 }
3017 None
3018 }
3019
3020 fn rotate_right_with_width(value: u64, rot: u8, width: u8) -> u64 {
3021 let mask = if width == 64 {
3022 u64::MAX
3023 } else {
3024 (1u64 << width) - 1
3025 };
3026 let value = value & mask;
3027 let rot = rot % width;
3028 if rot == 0 {
3029 value
3030 } else {
3031 ((value >> rot) | (value << (width - rot))) & mask
3032 }
3033 }
3034
3035 fn replicate_pattern(pattern: u64, esize: u8, width: u8) -> u64 {
3036 let mut out = 0u64;
3037 let mut shift = 0u8;
3038 while shift < width {
3039 out |= pattern << shift;
3040 shift += esize;
3041 }
3042 if width == 64 {
3043 out
3044 } else {
3045 out & ((1u64 << width) - 1)
3046 }
3047 }
3048
3049 fn csel(sf: bool, variant: u32, rm: GpReg, cond: Cond, rn: GpReg, rd: GpReg) -> u32 {
3050 ((sf as u32) << 31)
3051 | (((variant >> 1) & 0x1) << 30)
3052 | (0b0011010100 << 21)
3053 | (rm.enc() << 16)
3054 | (cond.enc() << 12)
3055 | ((variant & 0x1) << 10)
3056 | (rn.enc() << 5)
3057 | rd.enc()
3058 }
3059
3060 fn ccmp_imm(sf: bool, is_cmp: bool, rn: GpReg, imm5: u8, nzcv: u8, cond: Cond) -> u32 {
3061 let base = match (sf, is_cmp) {
3062 (false, true) => 0x7A400800,
3063 (false, false) => 0x3A400800,
3064 (true, true) => 0xFA400800,
3065 (true, false) => 0xBA400800,
3066 };
3067 base | (((imm5 as u32) & 0x1F) << 16)
3068 | ((cond.enc() & 0xF) << 12)
3069 | ((rn.enc() & 0x1F) << 5)
3070 | ((nzcv as u32) & 0xF)
3071 }
3072
3073 fn ldst_idx(size: u32, opc: u32, offset: i16, idx: u32, rn: GpReg, rt: GpReg) -> u32 {
3074 let imm9 = (offset as u32) & 0x1FF;
3075 (size << 30)
3076 | (0b111_0_00 << 24)
3077 | (opc << 22)
3078 | (imm9 << 12)
3079 | (idx << 10)
3080 | (rn.enc() << 5)
3081 | rt.enc()
3082 }
3083
3084 fn ldst_uimm_fp(size: u32, opc: u32, scale: u8, offset: u16, rn: GpReg, rt: FpReg) -> u32 {
3085 let uoff = ((offset as u32) >> scale) & 0xFFF;
3086 (size << 30) | (0b111_1_01 << 24) | (opc << 22) | (uoff << 10) | (rn.enc() << 5) | rt.enc()
3087 }
3088
3089 fn ldst_reg(
3090 size: u32,
3091 opc: u32,
3092 rm: GpReg,
3093 extend: AddrExtend,
3094 shift: bool,
3095 rn: GpReg,
3096 rt: GpReg,
3097 ) -> u32 {
3098 (size << 30)
3099 | (0b111 << 27)
3100 | (opc << 22)
3101 | (1 << 21)
3102 | (rm.enc() << 16)
3103 | (extend.enc() << 13)
3104 | ((shift as u32) << 12)
3105 | (0b10 << 10)
3106 | (rn.enc() << 5)
3107 | rt.enc()
3108 }
3109
3110 fn ldst_reg_fp(
3111 size: u32,
3112 opc: u32,
3113 rm: GpReg,
3114 extend: AddrExtend,
3115 shift: bool,
3116 rn: GpReg,
3117 rt: FpReg,
3118 ) -> u32 {
3119 ldst_reg(size, opc, rm, extend, shift, rn, GpReg::new(rt.num())) | (1 << 26)
3120 }
3121
3122 fn ldr_lit(opc: u32, offset: i32, rt: GpReg) -> u32 {
3123 let imm19 = ((offset >> 2) as u32) & 0x7FFFF;
3124 (opc << 30) | (0b011 << 27) | (imm19 << 5) | rt.enc()
3125 }
3126
3127 fn ldr_lit_fp(opc: u32, offset: i32, rt: FpReg) -> u32 {
3128 ldr_lit(opc, offset, GpReg::new(rt.num())) | (1 << 26)
3129 }
3130
3131 fn ldst_idx_fp(size: u32, opc: u32, offset: i16, idx: u32, rn: GpReg, rt: FpReg) -> u32 {
3132 ldst_idx(size, opc, offset, idx, rn, GpReg::new(rt.num())) | (1 << 26)
3133 }
3134
3135 /// Load/store pair.
3136 /// Format: opc(2)|101|mode(3)|L(1)|imm7(7)|Rt2(5)|Rn(5)|Rt1(5)
3137 /// mode: 001=post-index, 010=signed-offset, 011=pre-index
3138 fn ldp_stp(opc: u32, mode: u32, l: u32, offset: i16, rt2: GpReg, rn: GpReg, rt1: GpReg) -> u32 {
3139 let scale = if opc == 0b00 { 2 } else { 3 };
3140 let imm7 = ((offset >> scale) as u32) & 0x7F;
3141 (opc << 30)
3142 | (0b101 << 27)
3143 | (mode << 23)
3144 | (l << 22)
3145 | (imm7 << 15)
3146 | (rt2.enc() << 10)
3147 | (rn.enc() << 5)
3148 | rt1.enc()
3149 }
3150
3151 fn ldp_stp_fp(opc: u32, mode: u32, l: u32, offset: i16, rt2: FpReg, rn: GpReg, rt1: FpReg) -> u32 {
3152 let scale = match opc {
3153 0b00 => 2,
3154 0b01 => 3,
3155 0b10 => 4,
3156 _ => unreachable!("invalid FP pair opc"),
3157 };
3158 let imm7 = ((offset >> scale) as u32) & 0x7F;
3159 (opc << 30)
3160 | (0b101 << 27)
3161 | (1 << 26)
3162 | (mode << 23)
3163 | (l << 22)
3164 | (imm7 << 15)
3165 | (rt2.enc() << 10)
3166 | (rn.enc() << 5)
3167 | rt1.enc()
3168 }
3169
3170 fn hint(imm: u32) -> u32 {
3171 0xD503201F | (imm << 5)
3172 }
3173
3174 fn barrier(base: u32, option: BarrierOpt) -> u32 {
3175 base | (option.enc() << 8)
3176 }
3177
3178 /// FP one-source (FNEG, FABS, FSQRT).
3179 /// Format: 0|00|11110|ftype(2)|1|opcode(6)|10000|Rn(5)|Rd(5)
3180 fn fp_unary(ftype: u32, opcode: u32, rn: FpReg, rd: FpReg) -> u32 {
3181 (0b000_11110 << 24)
3182 | (ftype << 22)
3183 | (1 << 21)
3184 | (opcode << 15)
3185 | (0b10000 << 10)
3186 | (rn.enc() << 5)
3187 | rd.enc()
3188 }
3189
3190 /// FCMP Rn, Rm.
3191 /// Format: 0|00|11110|ftype(2)|1|Rm(5)|00|1000|Rn(5)|00000
3192 fn fp_cmp(ftype: u32, rn: FpReg, rm: FpReg) -> u32 {
3193 (0b000_11110 << 24)
3194 | (ftype << 22)
3195 | (1 << 21)
3196 | (rm.enc() << 16)
3197 | (0b00_1000 << 10)
3198 | (rn.enc() << 5)
3199 }
3200
3201 fn fp_imm(ftype: u32, imm8: u8, rd: FpReg) -> u32 {
3202 (0b000_11110 << 24) | (ftype << 22) | (1 << 21) | ((imm8 as u32) << 13) | (1 << 12) | rd.enc()
3203 }
3204
3205 fn fp_csel(ftype: u32, rm: FpReg, cond: Cond, rn: FpReg, rd: FpReg) -> u32 {
3206 (0b000_11110 << 24)
3207 | (ftype << 22)
3208 | (1 << 21)
3209 | (rm.enc() << 16)
3210 | (cond.enc() << 12)
3211 | (0b11 << 10)
3212 | (rn.enc() << 5)
3213 | rd.enc()
3214 }
3215
3216 /// FMADD Rd, Rn, Rm, Ra.
3217 /// Format: 0|00|11111|ftype(2)|0|Rm(5)|0|Ra(5)|Rn(5)|Rd(5)
3218 fn fp_madd(ftype: u32, rd: FpReg, rn: FpReg, rm: FpReg, ra: FpReg) -> u32 {
3219 (0b000_11111 << 24)
3220 | (ftype << 22)
3221 | (rm.enc() << 16)
3222 | (ra.enc() << 10)
3223 | (rn.enc() << 5)
3224 | rd.enc()
3225 }
3226
3227 /// FP two-source arithmetic (FADD, FSUB, FMUL, FDIV).
3228 fn fp_arith(ftype: u32, opcode: u32, rm: FpReg, rn: FpReg, rd: FpReg) -> u32 {
3229 (0b000_11110 << 24)
3230 | (ftype << 22)
3231 | (1 << 21)
3232 | (rm.enc() << 16)
3233 | (opcode << 12)
3234 | (0b10 << 10)
3235 | (rn.enc() << 5)
3236 | rd.enc()
3237 }
3238
3239 fn simd_fp_arith_4s(base: u32, rm: FpReg, rn: FpReg, rd: FpReg) -> u32 {
3240 base | (rm.enc() << 16) | (rn.enc() << 5) | rd.enc()
3241 }
3242
3243 fn simd_fp_arith_2d(base: u32, rm: FpReg, rn: FpReg, rd: FpReg) -> u32 {
3244 base | (rm.enc() << 16) | (rn.enc() << 5) | rd.enc()
3245 }
3246
3247 fn simd_binary(base: u32, rm: FpReg, rn: FpReg, rd: FpReg) -> u32 {
3248 base | (rm.enc() << 16) | (rn.enc() << 5) | rd.enc()
3249 }
3250
3251 fn simd_unary(base: u32, rn: FpReg, rd: FpReg) -> u32 {
3252 base | (rn.enc() << 5) | rd.enc()
3253 }
3254
3255 fn simd_mov_reg(base: u32, rn: FpReg, rd: FpReg) -> u32 {
3256 base | (rn.enc() << 16) | (rn.enc() << 5) | rd.enc()
3257 }
3258
3259 fn simd_reduce(base: u32, rn: FpReg, rd: FpReg) -> u32 {
3260 base | (rn.enc() << 5) | rd.enc()
3261 }
3262
3263 fn simd_reduce_4s(base: u32, rn: FpReg, rd: FpReg) -> u32 {
3264 simd_reduce(base, rn, rd)
3265 }
3266
3267 fn simd_lane_imm5(size_log2: u8, index: u8) -> u32 {
3268 ((1u32) << size_log2) | ((index as u32) << (size_log2 + 1))
3269 }
3270
3271 fn simd_dup_lane(size_log2: u8, rn: FpReg, index: u8, rd: FpReg) -> u32 {
3272 0x4E000400 | (simd_lane_imm5(size_log2, index) << 16) | (rn.enc() << 5) | rd.enc()
3273 }
3274
3275 fn simd_ext_16b(rm: FpReg, rn: FpReg, rd: FpReg, index: u8) -> u32 {
3276 0x6E000000 | (rm.enc() << 16) | ((index as u32) << 11) | (rn.enc() << 5) | rd.enc()
3277 }
3278
3279 fn simd_table_lookup(base: u32, index: FpReg, table: FpReg, table_len: u8, rd: FpReg) -> u32 {
3280 assert!((1..=4).contains(&table_len), "table length must be 1..=4");
3281 base | (index.enc() << 16) | (((table_len as u32) - 1) << 13) | (table.enc() << 5) | rd.enc()
3282 }
3283
3284 fn fp_mov_reg(base: u32, rn: FpReg, rd: FpReg) -> u32 {
3285 base | (rn.enc() << 5) | rd.enc()
3286 }
3287
3288 fn simd_extract_lane_s(rn: FpReg, index: u8, rd: FpReg) -> u32 {
3289 0x5E040400 | ((index as u32) << 19) | (rn.enc() << 5) | rd.enc()
3290 }
3291
3292 fn simd_extract_lane_d(rn: FpReg, index: u8, rd: FpReg) -> u32 {
3293 0x5E080400 | ((index as u32) << 20) | (rn.enc() << 5) | rd.enc()
3294 }
3295
3296 fn simd_extract_lane_gp(size_log2: u8, rn: FpReg, index: u8, rd: GpReg) -> u32 {
3297 let base = if size_log2 == 3 {
3298 0x4E003C00
3299 } else {
3300 0x0E003C00
3301 };
3302 base | (simd_lane_imm5(size_log2, index) << 16) | (rn.enc() << 5) | rd.enc()
3303 }
3304
3305 fn simd_extract_lane_gp_signed(size_log2: u8, rn: FpReg, index: u8, rd: GpReg) -> u32 {
3306 0x0E002C00 | (simd_lane_imm5(size_log2, index) << 16) | (rn.enc() << 5) | rd.enc()
3307 }
3308
3309 fn simd_insert_lane_s(rn: FpReg, rn_index: u8, rd: FpReg, rd_index: u8) -> u32 {
3310 0x6E040400 | ((rd_index as u32) << 19) | ((rn_index as u32) << 13) | (rn.enc() << 5) | rd.enc()
3311 }
3312
3313 fn simd_insert_lane_d(rn: FpReg, rn_index: u8, rd: FpReg, rd_index: u8) -> u32 {
3314 0x6E080400 | ((rd_index as u32) << 20) | ((rn_index as u32) << 14) | (rn.enc() << 5) | rd.enc()
3315 }
3316
3317 fn simd_insert_lane_h(rn: FpReg, rn_index: u8, rd: FpReg, rd_index: u8) -> u32 {
3318 0x6E020400 | ((rd_index as u32) << 18) | ((rn_index as u32) << 12) | (rn.enc() << 5) | rd.enc()
3319 }
3320
3321 fn simd_insert_lane_b(rn: FpReg, rn_index: u8, rd: FpReg, rd_index: u8) -> u32 {
3322 0x6E010400 | ((rd_index as u32) << 17) | ((rn_index as u32) << 11) | (rn.enc() << 5) | rd.enc()
3323 }
3324
3325 fn simd_insert_lane_gp(size_log2: u8, rn: GpReg, index: u8, rd: FpReg) -> u32 {
3326 0x4E001C00 | (simd_lane_imm5(size_log2, index) << 16) | (rn.enc() << 5) | rd.enc()
3327 }
3328
3329 fn simd_load_lane(size_log2: u8, rn: GpReg, index: u8, rt: FpReg) -> u32 {
3330 let base = match size_log2 {
3331 0 => 0x0D400000,
3332 1 => 0x0D404000,
3333 2 => 0x0D408000,
3334 3 => 0x0D408400,
3335 _ => unreachable!(),
3336 };
3337 let low_bits = if size_log2 == 3 {
3338 0
3339 } else {
3340 (index as u32) & ((1u32 << (3 - size_log2)) - 1)
3341 };
3342 let high_bit = ((index as u32) >> (3 - size_log2)) & 1;
3343 base | (high_bit << 30) | (low_bits << (10 + size_log2)) | (rn.enc() << 5) | rt.enc()
3344 }
3345
3346 #[cfg(test)]
3347 mod tests {
3348 use super::*;
3349 use crate::reg::*;
3350
3351 // ================================================================
3352 // Ground truth: every expected value was extracted from Apple `as`
3353 // by assembling the instruction and reading the 4-byte encoding
3354 // with `otool -t`.
3355 // ================================================================
3356
3357 // ---- Data processing (register) ----
3358
3359 #[test]
3360 fn add_x0_x1_x2() {
3361 assert_eq!(
3362 Inst::AddReg {
3363 rd: X0,
3364 rn: X1,
3365 rm: X2,
3366 sf: true
3367 }
3368 .encode(),
3369 0x8B020020
3370 );
3371 }
3372 #[test]
3373 fn sub_x3_x4_x5() {
3374 assert_eq!(
3375 Inst::SubReg {
3376 rd: X3,
3377 rn: X4,
3378 rm: X5,
3379 sf: true
3380 }
3381 .encode(),
3382 0xCB050083
3383 );
3384 }
3385 #[test]
3386 fn add_w0_w1_w2() {
3387 assert_eq!(
3388 Inst::AddReg {
3389 rd: W0,
3390 rn: W1,
3391 rm: W2,
3392 sf: false
3393 }
3394 .encode(),
3395 0x0B020020
3396 );
3397 }
3398 #[test]
3399 fn sub_w3_w4_w5() {
3400 assert_eq!(
3401 Inst::SubReg {
3402 rd: W3,
3403 rn: W4,
3404 rm: W5,
3405 sf: false
3406 }
3407 .encode(),
3408 0x4B050083
3409 );
3410 }
3411 #[test]
3412 fn add_x0_x1_x2_lsl3() {
3413 assert_eq!(
3414 Inst::AddShiftReg {
3415 rd: X0,
3416 rn: X1,
3417 rm: X2,
3418 shift: RegShift::Lsl,
3419 amount: 3,
3420 sf: true
3421 }
3422 .encode(),
3423 0x8B020C20
3424 );
3425 }
3426 #[test]
3427 fn add_x0_x0_w1_sxtw() {
3428 assert_eq!(
3429 Inst::AddExtReg {
3430 rd: X0,
3431 rn: X0,
3432 rm: W1,
3433 extend: RegExtend::Sxtw,
3434 amount: 0,
3435 sf: true
3436 }
3437 .encode(),
3438 0x8B21C000
3439 );
3440 }
3441 #[test]
3442 fn add_x0_x0_w1_sxtw3() {
3443 assert_eq!(
3444 Inst::AddExtReg {
3445 rd: X0,
3446 rn: X0,
3447 rm: W1,
3448 extend: RegExtend::Sxtw,
3449 amount: 3,
3450 sf: true
3451 }
3452 .encode(),
3453 0x8B21CC00
3454 );
3455 }
3456 #[test]
3457 fn sub_w3_w4_w5_asr7() {
3458 assert_eq!(
3459 Inst::SubShiftReg {
3460 rd: W3,
3461 rn: W4,
3462 rm: W5,
3463 shift: RegShift::Asr,
3464 amount: 7,
3465 sf: false
3466 }
3467 .encode(),
3468 0x4B851C83
3469 );
3470 }
3471 #[test]
3472 fn sub_x2_x3_w4_uxtw2() {
3473 assert_eq!(
3474 Inst::SubExtReg {
3475 rd: X2,
3476 rn: X3,
3477 rm: W4,
3478 extend: RegExtend::Uxtw,
3479 amount: 2,
3480 sf: true
3481 }
3482 .encode(),
3483 0xCB244862
3484 );
3485 }
3486 #[test]
3487 fn subs_w10_w8_w9_uxtb() {
3488 assert_eq!(
3489 Inst::SubsExtReg {
3490 rd: W10,
3491 rn: W8,
3492 rm: W9,
3493 extend: RegExtend::Uxtb,
3494 amount: 0,
3495 sf: false
3496 }
3497 .encode(),
3498 0x6B29010A
3499 );
3500 }
3501 #[test]
3502 fn subs_w11_w12_w13_uxth() {
3503 assert_eq!(
3504 Inst::SubsExtReg {
3505 rd: W11,
3506 rn: W12,
3507 rm: W13,
3508 extend: RegExtend::Uxth,
3509 amount: 0,
3510 sf: false
3511 }
3512 .encode(),
3513 0x6B2D218B
3514 );
3515 }
3516 #[test]
3517 fn subs_x14_x15_w16_sxtb() {
3518 assert_eq!(
3519 Inst::SubsExtReg {
3520 rd: X14,
3521 rn: X15,
3522 rm: W16,
3523 extend: RegExtend::Sxtb,
3524 amount: 0,
3525 sf: true
3526 }
3527 .encode(),
3528 0xEB3081EE
3529 );
3530 }
3531 #[test]
3532 fn subs_x17_x18_w19_sxth1() {
3533 assert_eq!(
3534 Inst::SubsExtReg {
3535 rd: X17,
3536 rn: X18,
3537 rm: W19,
3538 extend: RegExtend::Sxth,
3539 amount: 1,
3540 sf: true
3541 }
3542 .encode(),
3543 0xEB33A651
3544 );
3545 }
3546 #[test]
3547 fn cmp_x6_x7_lsr4() {
3548 assert_eq!(
3549 Inst::SubsShiftReg {
3550 rd: XZR,
3551 rn: X6,
3552 rm: X7,
3553 shift: RegShift::Lsr,
3554 amount: 4,
3555 sf: true
3556 }
3557 .encode(),
3558 0xEB4710DF
3559 );
3560 }
3561 #[test]
3562 fn mul_x6_x7_x8() {
3563 assert_eq!(
3564 Inst::Mul {
3565 rd: X6,
3566 rn: X7,
3567 rm: X8,
3568 sf: true
3569 }
3570 .encode(),
3571 0x9B087CE6
3572 );
3573 }
3574 #[test]
3575 fn madd_w0_w0_w0_w8() {
3576 assert_eq!(
3577 Inst::Madd {
3578 rd: W0,
3579 rn: W0,
3580 rm: W0,
3581 ra: W8,
3582 sf: false
3583 }
3584 .encode(),
3585 0x1B002000
3586 );
3587 }
3588 #[test]
3589 fn umull_x9_w8_w9() {
3590 assert_eq!(
3591 Inst::Umull {
3592 rd: X9,
3593 rn: W8,
3594 rm: W9
3595 }
3596 .encode(),
3597 0x9BA97D09
3598 );
3599 }
3600 #[test]
3601 fn msub_w9_w8_w1_w0() {
3602 assert_eq!(
3603 Inst::Msub {
3604 rd: W9,
3605 rn: W8,
3606 rm: W1,
3607 ra: W0,
3608 sf: false
3609 }
3610 .encode(),
3611 0x1B018109
3612 );
3613 }
3614 #[test]
3615 fn sdiv_x9_x10_x11() {
3616 assert_eq!(
3617 Inst::Sdiv {
3618 rd: X9,
3619 rn: X10,
3620 rm: X11,
3621 sf: true
3622 }
3623 .encode(),
3624 0x9ACB0D49
3625 );
3626 }
3627 #[test]
3628 fn udiv_x12_x13_x14() {
3629 assert_eq!(
3630 Inst::Udiv {
3631 rd: X12,
3632 rn: X13,
3633 rm: X14,
3634 sf: true
3635 }
3636 .encode(),
3637 0x9ACE09AC
3638 );
3639 }
3640
3641 // ---- Logic (register) ----
3642
3643 #[test]
3644 fn and_x0_x1_x2() {
3645 assert_eq!(
3646 Inst::AndReg {
3647 rd: X0,
3648 rn: X1,
3649 rm: X2,
3650 sf: true
3651 }
3652 .encode(),
3653 0x8A020020
3654 );
3655 }
3656 #[test]
3657 fn orr_x0_x1_x2() {
3658 assert_eq!(
3659 Inst::OrrReg {
3660 rd: X0,
3661 rn: X1,
3662 rm: X2,
3663 sf: true
3664 }
3665 .encode(),
3666 0xAA020020
3667 );
3668 }
3669 #[test]
3670 fn orn_x0_xzr_x1() {
3671 assert_eq!(
3672 Inst::OrnReg {
3673 rd: X0,
3674 rn: XZR,
3675 rm: X1,
3676 sf: true
3677 }
3678 .encode(),
3679 0xAA2103E0
3680 );
3681 }
3682 #[test]
3683 fn eor_x0_x1_x2() {
3684 assert_eq!(
3685 Inst::EorReg {
3686 rd: X0,
3687 rn: X1,
3688 rm: X2,
3689 sf: true
3690 }
3691 .encode(),
3692 0xCA020020
3693 );
3694 }
3695 #[test]
3696 fn and_w8_w8_0x7() {
3697 assert_eq!(
3698 Inst::AndImm {
3699 rd: W8,
3700 rn: W8,
3701 imm: 0x7,
3702 sf: false
3703 }
3704 .encode(),
3705 0x12000908
3706 );
3707 }
3708 #[test]
3709 fn and_x9_x9_0xff() {
3710 assert_eq!(
3711 Inst::AndImm {
3712 rd: X9,
3713 rn: X9,
3714 imm: 0xFF,
3715 sf: true
3716 }
3717 .encode(),
3718 0x92401D29
3719 );
3720 }
3721
3722 // ---- Data processing (immediate) ----
3723
3724 #[test]
3725 fn add_x0_x1_42() {
3726 assert_eq!(
3727 Inst::AddImm {
3728 rd: X0,
3729 rn: X1,
3730 imm12: 42,
3731 shift: false,
3732 sf: true
3733 }
3734 .encode(),
3735 0x9100A820
3736 );
3737 }
3738 #[test]
3739 fn sub_x0_x1_42() {
3740 assert_eq!(
3741 Inst::SubImm {
3742 rd: X0,
3743 rn: X1,
3744 imm12: 42,
3745 shift: false,
3746 sf: true
3747 }
3748 .encode(),
3749 0xD100A820
3750 );
3751 }
3752 #[test]
3753 fn add_x0_x1_42_lsl12() {
3754 assert_eq!(
3755 Inst::AddImm {
3756 rd: X0,
3757 rn: X1,
3758 imm12: 42,
3759 shift: true,
3760 sf: true
3761 }
3762 .encode(),
3763 0x9140A820
3764 );
3765 }
3766
3767 // ---- Move (wide immediate) ----
3768
3769 #[test]
3770 fn movz_x0_0x1234() {
3771 assert_eq!(
3772 Inst::Movz {
3773 rd: X0,
3774 imm16: 0x1234,
3775 shift: 0,
3776 sf: true
3777 }
3778 .encode(),
3779 0xD2824680
3780 );
3781 }
3782 #[test]
3783 fn movz_x0_0x5678_lsl16() {
3784 assert_eq!(
3785 Inst::Movz {
3786 rd: X0,
3787 imm16: 0x5678,
3788 shift: 16,
3789 sf: true
3790 }
3791 .encode(),
3792 0xD2AACF00
3793 );
3794 }
3795 #[test]
3796 fn movk_x0_0xabcd_lsl32() {
3797 assert_eq!(
3798 Inst::Movk {
3799 rd: X0,
3800 imm16: 0xABCD,
3801 shift: 32,
3802 sf: true
3803 }
3804 .encode(),
3805 0xF2D579A0
3806 );
3807 }
3808 #[test]
3809 fn movn_x0_0() {
3810 assert_eq!(
3811 Inst::Movn {
3812 rd: X0,
3813 imm16: 0,
3814 shift: 0,
3815 sf: true
3816 }
3817 .encode(),
3818 0x92800000
3819 );
3820 }
3821
3822 // ---- Compare (SUBS/ADDS/ANDS to XZR) ----
3823
3824 #[test]
3825 fn cmp_x0_x1() {
3826 assert_eq!(
3827 Inst::SubsReg {
3828 rd: XZR,
3829 rn: X0,
3830 rm: X1,
3831 sf: true
3832 }
3833 .encode(),
3834 0xEB01001F
3835 );
3836 }
3837 #[test]
3838 fn cmn_x0_x1() {
3839 assert_eq!(
3840 Inst::AddsReg {
3841 rd: XZR,
3842 rn: X0,
3843 rm: X1,
3844 sf: true
3845 }
3846 .encode(),
3847 0xAB01001F
3848 );
3849 }
3850 #[test]
3851 fn tst_x0_x1() {
3852 assert_eq!(
3853 Inst::AndsReg {
3854 rd: XZR,
3855 rn: X0,
3856 rm: X1,
3857 sf: true
3858 }
3859 .encode(),
3860 0xEA01001F
3861 );
3862 }
3863
3864 // ---- Shifts ----
3865
3866 #[test]
3867 fn lsl_x0_x1_3() {
3868 assert_eq!(
3869 Inst::LslImm {
3870 rd: X0,
3871 rn: X1,
3872 amount: 3,
3873 sf: true
3874 }
3875 .encode(),
3876 0xD37DF020
3877 );
3878 }
3879 #[test]
3880 fn lsr_x0_x1_3() {
3881 assert_eq!(
3882 Inst::LsrImm {
3883 rd: X0,
3884 rn: X1,
3885 amount: 3,
3886 sf: true
3887 }
3888 .encode(),
3889 0xD343FC20
3890 );
3891 }
3892 #[test]
3893 fn asr_x0_x1_3() {
3894 assert_eq!(
3895 Inst::AsrImm {
3896 rd: X0,
3897 rn: X1,
3898 amount: 3,
3899 sf: true
3900 }
3901 .encode(),
3902 0x9343FC20
3903 );
3904 }
3905
3906 // W-register shifts (32-bit, different immr/imms field widths)
3907 #[test]
3908 fn lsl_w0_w1_3() {
3909 assert_eq!(
3910 Inst::LslImm {
3911 rd: W0,
3912 rn: W1,
3913 amount: 3,
3914 sf: false
3915 }
3916 .encode(),
3917 0x531D7020
3918 );
3919 }
3920 #[test]
3921 fn lsr_w5_w6_8() {
3922 assert_eq!(
3923 Inst::LsrImm {
3924 rd: W5,
3925 rn: W6,
3926 amount: 8,
3927 sf: false
3928 }
3929 .encode(),
3930 0x53087CC5
3931 );
3932 }
3933 #[test]
3934 fn asr_w5_w6_15() {
3935 assert_eq!(
3936 Inst::AsrImm {
3937 rd: W5,
3938 rn: W6,
3939 amount: 15,
3940 sf: false
3941 }
3942 .encode(),
3943 0x130F7CC5
3944 );
3945 }
3946 #[test]
3947 fn ubfiz_w8_w0_5_3() {
3948 assert_eq!(
3949 Inst::Ubfiz {
3950 rd: W8,
3951 rn: W0,
3952 lsb: 5,
3953 width: 3,
3954 sf: false
3955 }
3956 .encode(),
3957 0x531B0808
3958 );
3959 }
3960 #[test]
3961 fn bfi_w0_w8_5_27() {
3962 assert_eq!(
3963 Inst::Bfi {
3964 rd: W0,
3965 rn: W8,
3966 lsb: 5,
3967 width: 27,
3968 sf: false
3969 }
3970 .encode(),
3971 0x331B6900
3972 );
3973 }
3974 #[test]
3975 fn bfxil_w8_w0_3_5() {
3976 assert_eq!(
3977 Inst::Bfxil {
3978 rd: W8,
3979 rn: W0,
3980 lsb: 3,
3981 width: 5,
3982 sf: false
3983 }
3984 .encode(),
3985 0x33031C08
3986 );
3987 }
3988
3989 // ---- Branches ----
3990
3991 #[test]
3992 fn b_plus4() {
3993 assert_eq!(Inst::B { offset: 4 }.encode(), 0x14000001);
3994 }
3995 #[test]
3996 fn b_minus8() {
3997 assert_eq!(Inst::B { offset: -8 }.encode(), 0x17FFFFFE);
3998 }
3999 #[test]
4000 fn bl_plus16() {
4001 assert_eq!(Inst::Bl { offset: 16 }.encode(), 0x94000004);
4002 }
4003 #[test]
4004 fn b_eq_plus8() {
4005 assert_eq!(
4006 Inst::BCond {
4007 cond: Cond::EQ,
4008 offset: 8
4009 }
4010 .encode(),
4011 0x54000040
4012 );
4013 }
4014 #[test]
4015 fn b_ne_plus12() {
4016 assert_eq!(
4017 Inst::BCond {
4018 cond: Cond::NE,
4019 offset: 12
4020 }
4021 .encode(),
4022 0x54000061
4023 );
4024 }
4025 #[test]
4026 fn b_ge_plus16() {
4027 assert_eq!(
4028 Inst::BCond {
4029 cond: Cond::GE,
4030 offset: 16
4031 }
4032 .encode(),
4033 0x5400008A
4034 );
4035 }
4036 #[test]
4037 fn cbz_x0_plus8() {
4038 assert_eq!(
4039 Inst::Cbz {
4040 rt: X0,
4041 offset: 8,
4042 sf: true
4043 }
4044 .encode(),
4045 0xB4000040
4046 );
4047 }
4048 #[test]
4049 fn cbnz_x1_plus12() {
4050 assert_eq!(
4051 Inst::Cbnz {
4052 rt: X1,
4053 offset: 12,
4054 sf: true
4055 }
4056 .encode(),
4057 0xB5000061
4058 );
4059 }
4060 #[test]
4061 fn tbz_x0_bit5_plus8() {
4062 assert_eq!(
4063 Inst::Tbz {
4064 rt: X0,
4065 bit: 5,
4066 offset: 8,
4067 sf: true
4068 }
4069 .encode(),
4070 0x36280040
4071 );
4072 }
4073 #[test]
4074 fn tbnz_x1_bit33_plus12() {
4075 assert_eq!(
4076 Inst::Tbnz {
4077 rt: X1,
4078 bit: 33,
4079 offset: 12,
4080 sf: true
4081 }
4082 .encode(),
4083 0xB7080061
4084 );
4085 }
4086 #[test]
4087 fn ret_x30() {
4088 assert_eq!(Inst::Ret { rn: X30 }.encode(), 0xD65F03C0);
4089 }
4090 #[test]
4091 fn br_x16() {
4092 assert_eq!(Inst::Br { rn: X16 }.encode(), 0xD61F0200);
4093 }
4094 #[test]
4095 fn blr_x17() {
4096 assert_eq!(Inst::Blr { rn: X17 }.encode(), 0xD63F0220);
4097 }
4098 #[test]
4099 fn csel_w0_w0_w1_gt() {
4100 assert_eq!(
4101 Inst::Csel {
4102 rd: W0,
4103 rn: W0,
4104 rm: W1,
4105 cond: Cond::GT,
4106 sf: false
4107 }
4108 .encode(),
4109 0x1A81C000
4110 );
4111 }
4112 #[test]
4113 fn ccmp_w0_3_4_ne() {
4114 assert_eq!(
4115 Inst::CcmpImm {
4116 rn: W0,
4117 imm5: 3,
4118 nzcv: 4,
4119 cond: Cond::NE,
4120 sf: false
4121 }
4122 .encode(),
4123 0x7A431804
4124 );
4125 }
4126 #[test]
4127 fn ccmp_w1_10_0_lt() {
4128 assert_eq!(
4129 Inst::CcmpImm {
4130 rn: W1,
4131 imm5: 10,
4132 nzcv: 0,
4133 cond: Cond::LT,
4134 sf: false
4135 }
4136 .encode(),
4137 0x7A4AB820
4138 );
4139 }
4140 #[test]
4141 fn ccmp_x2_5_7_eq() {
4142 assert_eq!(
4143 Inst::CcmpImm {
4144 rn: X2,
4145 imm5: 5,
4146 nzcv: 7,
4147 cond: Cond::EQ,
4148 sf: true
4149 }
4150 .encode(),
4151 0xFA450847
4152 );
4153 }
4154 #[test]
4155 fn ccmn_w3_9_1_ge() {
4156 assert_eq!(
4157 Inst::CcmnImm {
4158 rn: W3,
4159 imm5: 9,
4160 nzcv: 1,
4161 cond: Cond::GE,
4162 sf: false
4163 }
4164 .encode(),
4165 0x3A49A861
4166 );
4167 }
4168 #[test]
4169 fn csinc_x2_x3_x3_ne() {
4170 assert_eq!(
4171 Inst::Csinc {
4172 rd: X2,
4173 rn: X3,
4174 rm: X3,
4175 cond: Cond::NE,
4176 sf: true
4177 }
4178 .encode(),
4179 0x9A831462
4180 );
4181 }
4182 #[test]
4183 fn csinv_x2_x3_x4_ne() {
4184 assert_eq!(
4185 Inst::Csinv {
4186 rd: X2,
4187 rn: X3,
4188 rm: X4,
4189 cond: Cond::NE,
4190 sf: true
4191 }
4192 .encode(),
4193 0xDA841062
4194 );
4195 }
4196 #[test]
4197 fn csneg_x5_x6_x7_gt() {
4198 assert_eq!(
4199 Inst::Csneg {
4200 rd: X5,
4201 rn: X6,
4202 rm: X7,
4203 cond: Cond::GT,
4204 sf: true
4205 }
4206 .encode(),
4207 0xDA87C4C5
4208 );
4209 }
4210
4211 // ---- Address generation ----
4212
4213 #[test]
4214 fn adr_x0_8() {
4215 assert_eq!(Inst::Adr { rd: X0, imm: 8 }.encode(), 0x10000040);
4216 }
4217 #[test]
4218 fn adrp_x0_0() {
4219 assert_eq!(Inst::Adrp { rd: X0, imm: 0 }.encode(), 0x90000000);
4220 }
4221
4222 // ---- Load/Store (unsigned offset) ----
4223
4224 #[test]
4225 fn ldr_x0_x1() {
4226 assert_eq!(
4227 Inst::LdrImm64 {
4228 rt: X0,
4229 rn: X1,
4230 offset: 0
4231 }
4232 .encode(),
4233 0xF9400020
4234 );
4235 }
4236 #[test]
4237 fn ldr_x0_x1_8() {
4238 assert_eq!(
4239 Inst::LdrImm64 {
4240 rt: X0,
4241 rn: X1,
4242 offset: 8
4243 }
4244 .encode(),
4245 0xF9400420
4246 );
4247 }
4248 #[test]
4249 fn str_x2_x3_16() {
4250 assert_eq!(
4251 Inst::StrImm64 {
4252 rt: X2,
4253 rn: X3,
4254 offset: 16
4255 }
4256 .encode(),
4257 0xF9000862
4258 );
4259 }
4260 #[test]
4261 fn ldr_w4_x5_4() {
4262 assert_eq!(
4263 Inst::LdrImm32 {
4264 rt: W4,
4265 rn: X5,
4266 offset: 4
4267 }
4268 .encode(),
4269 0xB94004A4
4270 );
4271 }
4272 #[test]
4273 fn str_w6_x7_8() {
4274 assert_eq!(
4275 Inst::StrImm32 {
4276 rt: W6,
4277 rn: X7,
4278 offset: 8
4279 }
4280 .encode(),
4281 0xB90008E6
4282 );
4283 }
4284 #[test]
4285 fn ldur_x9_x29_m8() {
4286 assert_eq!(
4287 Inst::Ldur64 {
4288 rt: X9,
4289 rn: X29,
4290 offset: -8
4291 }
4292 .encode(),
4293 0xF85F83A9
4294 );
4295 }
4296 #[test]
4297 fn stur_w6_x7_m4() {
4298 assert_eq!(
4299 Inst::Stur32 {
4300 rt: W6,
4301 rn: X7,
4302 offset: -4
4303 }
4304 .encode(),
4305 0xB81FC0E6
4306 );
4307 }
4308 #[test]
4309 fn ldr_x0_x1_x2() {
4310 assert_eq!(
4311 Inst::LdrReg64 {
4312 rt: X0,
4313 rn: X1,
4314 rm: X2,
4315 extend: AddrExtend::Lsl,
4316 shift: false
4317 }
4318 .encode(),
4319 0xF8626820
4320 );
4321 }
4322 #[test]
4323 fn ldr_x3_x4_x5_lsl3() {
4324 assert_eq!(
4325 Inst::LdrReg64 {
4326 rt: X3,
4327 rn: X4,
4328 rm: X5,
4329 extend: AddrExtend::Lsl,
4330 shift: true
4331 }
4332 .encode(),
4333 0xF8657883
4334 );
4335 }
4336 #[test]
4337 fn ldr_x6_x7_w8_uxtw3() {
4338 assert_eq!(
4339 Inst::LdrReg64 {
4340 rt: X6,
4341 rn: X7,
4342 rm: W8,
4343 extend: AddrExtend::Uxtw,
4344 shift: true
4345 }
4346 .encode(),
4347 0xF86858E6
4348 );
4349 }
4350 #[test]
4351 fn ldr_x9_x10_x11_sxtx3() {
4352 assert_eq!(
4353 Inst::LdrReg64 {
4354 rt: X9,
4355 rn: X10,
4356 rm: X11,
4357 extend: AddrExtend::Sxtx,
4358 shift: true
4359 }
4360 .encode(),
4361 0xF86BF949
4362 );
4363 }
4364 #[test]
4365 fn str_x12_x13_x14() {
4366 assert_eq!(
4367 Inst::StrReg64 {
4368 rt: X12,
4369 rn: X13,
4370 rm: X14,
4371 extend: AddrExtend::Lsl,
4372 shift: false
4373 }
4374 .encode(),
4375 0xF82E69AC
4376 );
4377 }
4378 #[test]
4379 fn ldrb_w8_x9_1() {
4380 assert_eq!(
4381 Inst::Ldrb {
4382 rt: W8,
4383 rn: X9,
4384 offset: 1
4385 }
4386 .encode(),
4387 0x39400528
4388 );
4389 }
4390 #[test]
4391 fn ldrsb_w0_x1_3() {
4392 assert_eq!(
4393 Inst::Ldrsb32 {
4394 rt: W0,
4395 rn: X1,
4396 offset: 3
4397 }
4398 .encode(),
4399 0x39C00C20
4400 );
4401 }
4402 #[test]
4403 fn ldrsb_x0_x1_3() {
4404 assert_eq!(
4405 Inst::Ldrsb64 {
4406 rt: X0,
4407 rn: X1,
4408 offset: 3
4409 }
4410 .encode(),
4411 0x39800C20
4412 );
4413 }
4414 #[test]
4415 fn ldrb_w9_x1_post_1() {
4416 assert_eq!(
4417 Inst::LdrbPost {
4418 rt: W9,
4419 rn: X1,
4420 offset: 1
4421 }
4422 .encode(),
4423 0x38401429
4424 );
4425 }
4426 #[test]
4427 fn ldrsb_w0_x1_post_1() {
4428 assert_eq!(
4429 Inst::LdrsbPost32 {
4430 rt: W0,
4431 rn: X1,
4432 offset: 1
4433 }
4434 .encode(),
4435 0x38C01420
4436 );
4437 }
4438 #[test]
4439 fn ldrh_w10_x11_2() {
4440 assert_eq!(
4441 Inst::Ldrh {
4442 rt: W10,
4443 rn: X11,
4444 offset: 2
4445 }
4446 .encode(),
4447 0x7940056A
4448 );
4449 }
4450 #[test]
4451 fn ldrsh_w0_x1_4() {
4452 assert_eq!(
4453 Inst::Ldrsh32 {
4454 rt: W0,
4455 rn: X1,
4456 offset: 4
4457 }
4458 .encode(),
4459 0x79C00820
4460 );
4461 }
4462 #[test]
4463 fn ldrsh_x0_x1_4() {
4464 assert_eq!(
4465 Inst::Ldrsh64 {
4466 rt: X0,
4467 rn: X1,
4468 offset: 4
4469 }
4470 .encode(),
4471 0x79800820
4472 );
4473 }
4474 #[test]
4475 fn strb_w9_x8_post_1() {
4476 assert_eq!(
4477 Inst::StrbPost {
4478 rt: W9,
4479 rn: X8,
4480 offset: 1
4481 }
4482 .encode(),
4483 0x38001509
4484 );
4485 }
4486 #[test]
4487 fn strb_w8_x9() {
4488 assert_eq!(
4489 Inst::Strb {
4490 rt: W8,
4491 rn: X9,
4492 offset: 0
4493 }
4494 .encode(),
4495 0x39000128
4496 );
4497 }
4498 #[test]
4499 fn strh_w10_x11_6() {
4500 assert_eq!(
4501 Inst::Strh {
4502 rt: W10,
4503 rn: X11,
4504 offset: 6
4505 }
4506 .encode(),
4507 0x79000D6A
4508 );
4509 }
4510 #[test]
4511 fn ldrh_w3_x4_pre_2() {
4512 assert_eq!(
4513 Inst::LdrhPre {
4514 rt: W3,
4515 rn: X4,
4516 offset: 2
4517 }
4518 .encode(),
4519 0x78402C83
4520 );
4521 }
4522 #[test]
4523 fn ldrsh_w0_x1_pre_2() {
4524 assert_eq!(
4525 Inst::LdrshPre32 {
4526 rt: W0,
4527 rn: X1,
4528 offset: 2
4529 }
4530 .encode(),
4531 0x78C02C20
4532 );
4533 }
4534 #[test]
4535 fn ldrsh_x0_x1_pre_2() {
4536 assert_eq!(
4537 Inst::LdrshPre64 {
4538 rt: X0,
4539 rn: X1,
4540 offset: 2
4541 }
4542 .encode(),
4543 0x78802C20
4544 );
4545 }
4546 #[test]
4547 fn strh_w5_x6_post_2() {
4548 assert_eq!(
4549 Inst::StrhPost {
4550 rt: W5,
4551 rn: X6,
4552 offset: 2
4553 }
4554 .encode(),
4555 0x780024C5
4556 );
4557 }
4558 #[test]
4559 fn ldrsw_x0_x1_4() {
4560 assert_eq!(
4561 Inst::Ldrsw {
4562 rt: X0,
4563 rn: X1,
4564 offset: 4
4565 }
4566 .encode(),
4567 0xB9800420
4568 );
4569 }
4570 #[test]
4571 fn ldrb_w0_x1_x2() {
4572 assert_eq!(
4573 Inst::LdrbReg {
4574 rt: W0,
4575 rn: X1,
4576 rm: X2,
4577 extend: AddrExtend::Lsl,
4578 shift: false
4579 }
4580 .encode(),
4581 0x38626820
4582 );
4583 }
4584 #[test]
4585 fn ldrsb_w0_x1_x2() {
4586 assert_eq!(
4587 Inst::LdrsbReg32 {
4588 rt: W0,
4589 rn: X1,
4590 rm: X2,
4591 extend: AddrExtend::Lsl,
4592 shift: false
4593 }
4594 .encode(),
4595 0x38E26820
4596 );
4597 }
4598 #[test]
4599 fn ldrsb_x0_x1_x2() {
4600 assert_eq!(
4601 Inst::LdrsbReg64 {
4602 rt: X0,
4603 rn: X1,
4604 rm: X2,
4605 extend: AddrExtend::Lsl,
4606 shift: false
4607 }
4608 .encode(),
4609 0x38A26820
4610 );
4611 }
4612 #[test]
4613 fn ldrh_w3_x4_w5_uxtw1() {
4614 assert_eq!(
4615 Inst::LdrhReg {
4616 rt: W3,
4617 rn: X4,
4618 rm: W5,
4619 extend: AddrExtend::Uxtw,
4620 shift: true
4621 }
4622 .encode(),
4623 0x78655883
4624 );
4625 }
4626 #[test]
4627 fn ldrsh_w0_x1_w2_uxtw1() {
4628 assert_eq!(
4629 Inst::LdrshReg32 {
4630 rt: W0,
4631 rn: X1,
4632 rm: W2,
4633 extend: AddrExtend::Uxtw,
4634 shift: true
4635 }
4636 .encode(),
4637 0x78E25820
4638 );
4639 }
4640 #[test]
4641 fn ldrsh_x0_x1_w2_sxtw1() {
4642 assert_eq!(
4643 Inst::LdrshReg64 {
4644 rt: X0,
4645 rn: X1,
4646 rm: W2,
4647 extend: AddrExtend::Sxtw,
4648 shift: true
4649 }
4650 .encode(),
4651 0x78A2D820
4652 );
4653 }
4654 #[test]
4655 fn ldrsw_x6_x7_w8_sxtw2() {
4656 assert_eq!(
4657 Inst::LdrswReg {
4658 rt: X6,
4659 rn: X7,
4660 rm: W8,
4661 extend: AddrExtend::Sxtw,
4662 shift: true
4663 }
4664 .encode(),
4665 0xB8A8D8E6
4666 );
4667 }
4668 #[test]
4669 fn ldaprb_w0_x1() {
4670 assert_eq!(Inst::Ldaprb { rt: W0, rn: X1 }.encode(), 0x38BFC020);
4671 }
4672 #[test]
4673 fn ldaprh_w2_x3() {
4674 assert_eq!(Inst::Ldaprh { rt: W2, rn: X3 }.encode(), 0x78BFC062);
4675 }
4676 #[test]
4677 fn ldapr_w8_x9() {
4678 assert_eq!(Inst::Ldapr32 { rt: W8, rn: X9 }.encode(), 0xB8BFC128);
4679 }
4680 #[test]
4681 fn ldapr_x8_x9() {
4682 assert_eq!(Inst::Ldapr64 { rt: X8, rn: X9 }.encode(), 0xF8BFC128);
4683 }
4684 #[test]
4685 fn stlrb_w4_x5() {
4686 assert_eq!(Inst::Stlrb { rt: W4, rn: X5 }.encode(), 0x089FFCA4);
4687 }
4688 #[test]
4689 fn stlrh_w6_x7() {
4690 assert_eq!(Inst::Stlrh { rt: W6, rn: X7 }.encode(), 0x489FFCE6);
4691 }
4692 #[test]
4693 fn ldaddalb_w0_w1_x2() {
4694 assert_eq!(
4695 Inst::Ldaddalb {
4696 rs: W0,
4697 rt: W1,
4698 rn: X2
4699 }
4700 .encode(),
4701 0x38E00041
4702 );
4703 }
4704 #[test]
4705 fn ldaddalh_w3_w4_x5() {
4706 assert_eq!(
4707 Inst::Ldaddalh {
4708 rs: W3,
4709 rt: W4,
4710 rn: X5
4711 }
4712 .encode(),
4713 0x78E300A4
4714 );
4715 }
4716 #[test]
4717 fn ldumaxalb_w0_w1_x2() {
4718 assert_eq!(
4719 Inst::Ldumaxalb {
4720 rs: W0,
4721 rt: W1,
4722 rn: X2
4723 }
4724 .encode(),
4725 0x38E06041
4726 );
4727 }
4728 #[test]
4729 fn ldumaxalh_w3_w4_x5() {
4730 assert_eq!(
4731 Inst::Ldumaxalh {
4732 rs: W3,
4733 rt: W4,
4734 rn: X5
4735 }
4736 .encode(),
4737 0x78E360A4
4738 );
4739 }
4740 #[test]
4741 fn ldsmaxalb_w18_w19_x20() {
4742 assert_eq!(
4743 Inst::Ldsmaxalb {
4744 rs: W18,
4745 rt: W19,
4746 rn: X20
4747 }
4748 .encode(),
4749 0x38F24293
4750 );
4751 }
4752 #[test]
4753 fn ldsmaxalh_w24_w25_x26() {
4754 assert_eq!(
4755 Inst::Ldsmaxalh {
4756 rs: W24,
4757 rt: W25,
4758 rn: X26
4759 }
4760 .encode(),
4761 0x78F84359
4762 );
4763 }
4764 #[test]
4765 fn lduminalb_w12_w13_x14() {
4766 assert_eq!(
4767 Inst::Lduminalb {
4768 rs: W12,
4769 rt: W13,
4770 rn: X14
4771 }
4772 .encode(),
4773 0x38EC71CD
4774 );
4775 }
4776 #[test]
4777 fn lduminalh_w15_w16_x17() {
4778 assert_eq!(
4779 Inst::Lduminalh {
4780 rs: W15,
4781 rt: W16,
4782 rn: X17
4783 }
4784 .encode(),
4785 0x78EF7230
4786 );
4787 }
4788 #[test]
4789 fn ldsminalb_w21_w22_x23() {
4790 assert_eq!(
4791 Inst::Ldsminalb {
4792 rs: W21,
4793 rt: W22,
4794 rn: X23
4795 }
4796 .encode(),
4797 0x38F552F6
4798 );
4799 }
4800 #[test]
4801 fn ldsminalh_w27_w28_x29() {
4802 assert_eq!(
4803 Inst::Ldsminalh {
4804 rs: W27,
4805 rt: W28,
4806 rn: X29
4807 }
4808 .encode(),
4809 0x78FB53BC
4810 );
4811 }
4812 #[test]
4813 fn ldclralb_w6_w7_x8() {
4814 assert_eq!(
4815 Inst::Ldclralb {
4816 rs: W6,
4817 rt: W7,
4818 rn: X8
4819 }
4820 .encode(),
4821 0x38E61107
4822 );
4823 }
4824 #[test]
4825 fn ldclralh_w15_w16_x17() {
4826 assert_eq!(
4827 Inst::Ldclralh {
4828 rs: W15,
4829 rt: W16,
4830 rn: X17
4831 }
4832 .encode(),
4833 0x78EF1230
4834 );
4835 }
4836 #[test]
4837 fn ldeoralb_w3_w4_x5() {
4838 assert_eq!(
4839 Inst::Ldeoralb {
4840 rs: W3,
4841 rt: W4,
4842 rn: X5
4843 }
4844 .encode(),
4845 0x38E320A4
4846 );
4847 }
4848 #[test]
4849 fn ldeoralh_w12_w13_x14() {
4850 assert_eq!(
4851 Inst::Ldeoralh {
4852 rs: W12,
4853 rt: W13,
4854 rn: X14
4855 }
4856 .encode(),
4857 0x78EC21CD
4858 );
4859 }
4860 #[test]
4861 fn ldsetalb_w0_w1_x2() {
4862 assert_eq!(
4863 Inst::Ldsetalb {
4864 rs: W0,
4865 rt: W1,
4866 rn: X2
4867 }
4868 .encode(),
4869 0x38E03041
4870 );
4871 }
4872 #[test]
4873 fn ldsetalh_w9_w10_x11() {
4874 assert_eq!(
4875 Inst::Ldsetalh {
4876 rs: W9,
4877 rt: W10,
4878 rn: X11
4879 }
4880 .encode(),
4881 0x78E9316A
4882 );
4883 }
4884 #[test]
4885 fn ldumaxal_w6_w7_x8() {
4886 assert_eq!(
4887 Inst::Ldumaxal32 {
4888 rs: W6,
4889 rt: W7,
4890 rn: X8
4891 }
4892 .encode(),
4893 0xB8E66107
4894 );
4895 }
4896 #[test]
4897 fn ldumaxal_x9_x10_x11() {
4898 assert_eq!(
4899 Inst::Ldumaxal64 {
4900 rs: X9,
4901 rt: X10,
4902 rn: X11
4903 }
4904 .encode(),
4905 0xF8E9616A
4906 );
4907 }
4908 #[test]
4909 fn stlr_w10_x11() {
4910 assert_eq!(Inst::Stlr32 { rt: W10, rn: X11 }.encode(), 0x889FFD6A);
4911 }
4912 #[test]
4913 fn stlr_x10_x11() {
4914 assert_eq!(Inst::Stlr64 { rt: X10, rn: X11 }.encode(), 0xC89FFD6A);
4915 }
4916 #[test]
4917 fn ldaddal_w0_w8_x8() {
4918 assert_eq!(
4919 Inst::Ldaddal32 {
4920 rs: W0,
4921 rt: W8,
4922 rn: X8
4923 }
4924 .encode(),
4925 0xB8E00108
4926 );
4927 }
4928 #[test]
4929 fn ldaddal_x0_x8_x8() {
4930 assert_eq!(
4931 Inst::Ldaddal64 {
4932 rs: X0,
4933 rt: X8,
4934 rn: X8
4935 }
4936 .encode(),
4937 0xF8E00108
4938 );
4939 }
4940 #[test]
4941 fn ldsmaxal_w0_w1_x2() {
4942 assert_eq!(
4943 Inst::Ldsmaxal32 {
4944 rs: W0,
4945 rt: W1,
4946 rn: X2
4947 }
4948 .encode(),
4949 0xB8E04041
4950 );
4951 }
4952 #[test]
4953 fn ldsminal_x9_x10_x11() {
4954 assert_eq!(
4955 Inst::Ldsminal64 {
4956 rs: X9,
4957 rt: X10,
4958 rn: X11
4959 }
4960 .encode(),
4961 0xF8E9516A
4962 );
4963 }
4964 #[test]
4965 fn ldclral_w12_w13_x14() {
4966 assert_eq!(
4967 Inst::Ldclral32 {
4968 rs: W12,
4969 rt: W13,
4970 rn: X14
4971 }
4972 .encode(),
4973 0xB8EC11CD
4974 );
4975 }
4976 #[test]
4977 fn ldeoral_x9_x10_x11() {
4978 assert_eq!(
4979 Inst::Ldeoral64 {
4980 rs: X9,
4981 rt: X10,
4982 rn: X11
4983 }
4984 .encode(),
4985 0xF8E9216A
4986 );
4987 }
4988 #[test]
4989 fn ldsetal_w0_w1_x2() {
4990 assert_eq!(
4991 Inst::Ldsetal32 {
4992 rs: W0,
4993 rt: W1,
4994 rn: X2
4995 }
4996 .encode(),
4997 0xB8E03041
4998 );
4999 }
5000 #[test]
5001 fn lduminal_w18_w19_x20() {
5002 assert_eq!(
5003 Inst::Lduminal32 {
5004 rs: W18,
5005 rt: W19,
5006 rn: X20
5007 }
5008 .encode(),
5009 0xB8F27293
5010 );
5011 }
5012 #[test]
5013 fn lduminal_x21_x22_x23() {
5014 assert_eq!(
5015 Inst::Lduminal64 {
5016 rs: X21,
5017 rt: X22,
5018 rn: X23
5019 }
5020 .encode(),
5021 0xF8F572F6
5022 );
5023 }
5024 #[test]
5025 fn swpal_w0_w0_x8() {
5026 assert_eq!(
5027 Inst::Swpal32 {
5028 rs: W0,
5029 rt: W0,
5030 rn: X8
5031 }
5032 .encode(),
5033 0xB8E08100
5034 );
5035 }
5036 #[test]
5037 fn swpal_x1_x2_x3() {
5038 assert_eq!(
5039 Inst::Swpal64 {
5040 rs: X1,
5041 rt: X2,
5042 rn: X3
5043 }
5044 .encode(),
5045 0xF8E18062
5046 );
5047 }
5048 #[test]
5049 fn swpalb_w8_w9_x10() {
5050 assert_eq!(
5051 Inst::Swpalb {
5052 rs: W8,
5053 rt: W9,
5054 rn: X10
5055 }
5056 .encode(),
5057 0x38E88149
5058 );
5059 }
5060 #[test]
5061 fn swpalh_w11_w12_x13() {
5062 assert_eq!(
5063 Inst::Swpalh {
5064 rs: W11,
5065 rt: W12,
5066 rn: X13
5067 }
5068 .encode(),
5069 0x78EB81AC
5070 );
5071 }
5072 #[test]
5073 fn casalb_w6_w7_x8() {
5074 assert_eq!(
5075 Inst::Casalb {
5076 rs: W6,
5077 rt: W7,
5078 rn: X8
5079 }
5080 .encode(),
5081 0x08E6FD07
5082 );
5083 }
5084 #[test]
5085 fn casalh_w9_w10_x11() {
5086 assert_eq!(
5087 Inst::Casalh {
5088 rs: W9,
5089 rt: W10,
5090 rn: X11
5091 }
5092 .encode(),
5093 0x48E9FD6A
5094 );
5095 }
5096 #[test]
5097 fn casal_w4_w5_x6() {
5098 assert_eq!(
5099 Inst::Casal32 {
5100 rs: W4,
5101 rt: W5,
5102 rn: X6
5103 }
5104 .encode(),
5105 0x88E4FCC5
5106 );
5107 }
5108 #[test]
5109 fn casal_x7_x8_x9() {
5110 assert_eq!(
5111 Inst::Casal64 {
5112 rs: X7,
5113 rt: X8,
5114 rn: X9
5115 }
5116 .encode(),
5117 0xC8E7FD28
5118 );
5119 }
5120 #[test]
5121 fn ldr_d0_x1() {
5122 assert_eq!(
5123 Inst::LdrFpImm64 {
5124 rt: D0,
5125 rn: X1,
5126 offset: 0
5127 }
5128 .encode(),
5129 0xFD400020
5130 );
5131 }
5132 #[test]
5133 fn ldr_q0_sp_16() {
5134 assert_eq!(
5135 Inst::LdrFpImm128 {
5136 rt: FpReg::new(0),
5137 rn: SP,
5138 offset: 16
5139 }
5140 .encode(),
5141 0x3DC007E0
5142 );
5143 }
5144 #[test]
5145 fn ldr_h2_sp_14() {
5146 assert_eq!(
5147 Inst::LdrFpImm16 {
5148 rt: FpReg::new(2),
5149 rn: SP,
5150 offset: 14
5151 }
5152 .encode(),
5153 0x7D401FE2
5154 );
5155 }
5156 #[test]
5157 fn ldr_b2_sp_15() {
5158 assert_eq!(
5159 Inst::LdrFpImm8 {
5160 rt: FpReg::new(2),
5161 rn: SP,
5162 offset: 15
5163 }
5164 .encode(),
5165 0x3D403FE2
5166 );
5167 }
5168 #[test]
5169 fn str_q1_sp() {
5170 assert_eq!(
5171 Inst::StrFpImm128 {
5172 rt: FpReg::new(1),
5173 rn: SP,
5174 offset: 0
5175 }
5176 .encode(),
5177 0x3D8003E1
5178 );
5179 }
5180 #[test]
5181 fn str_h2_sp_14() {
5182 assert_eq!(
5183 Inst::StrFpImm16 {
5184 rt: FpReg::new(2),
5185 rn: SP,
5186 offset: 14
5187 }
5188 .encode(),
5189 0x7D001FE2
5190 );
5191 }
5192 #[test]
5193 fn str_b2_sp_15() {
5194 assert_eq!(
5195 Inst::StrFpImm8 {
5196 rt: FpReg::new(2),
5197 rn: SP,
5198 offset: 15
5199 }
5200 .encode(),
5201 0x3D003FE2
5202 );
5203 }
5204 #[test]
5205 fn ldr_q0_lit_16() {
5206 assert_eq!(
5207 Inst::LdrFpLit128 {
5208 rt: FpReg::new(0),
5209 offset: 16
5210 }
5211 .encode(),
5212 0x9C000080
5213 );
5214 }
5215 #[test]
5216 fn ldr_q0_x1_x2() {
5217 assert_eq!(
5218 Inst::LdrFpReg128 {
5219 rt: FpReg::new(0),
5220 rn: X1,
5221 rm: X2,
5222 extend: AddrExtend::Lsl,
5223 shift: false
5224 }
5225 .encode(),
5226 0x3CE26820
5227 );
5228 }
5229 #[test]
5230 fn str_q1_x3_w4_uxtw4() {
5231 assert_eq!(
5232 Inst::StrFpReg128 {
5233 rt: FpReg::new(1),
5234 rn: X3,
5235 rm: W4,
5236 extend: AddrExtend::Uxtw,
5237 shift: true
5238 }
5239 .encode(),
5240 0x3CA45861
5241 );
5242 }
5243 #[test]
5244 fn ldr_q0_sp_post_16() {
5245 assert_eq!(
5246 Inst::LdrFpPost128 {
5247 rt: FpReg::new(0),
5248 rn: SP,
5249 offset: 16
5250 }
5251 .encode(),
5252 0x3CC107E0
5253 );
5254 }
5255 #[test]
5256 fn str_q1_sp_pre_m16() {
5257 assert_eq!(
5258 Inst::StrFpPre128 {
5259 rt: FpReg::new(1),
5260 rn: SP,
5261 offset: -16
5262 }
5263 .encode(),
5264 0x3C9F0FE1
5265 );
5266 }
5267 #[test]
5268 fn str_d2_x3_16() {
5269 assert_eq!(
5270 Inst::StrFpImm64 {
5271 rt: D2,
5272 rn: X3,
5273 offset: 16
5274 }
5275 .encode(),
5276 0xFD000862
5277 );
5278 }
5279 #[test]
5280 fn ldr_s4_x5_x6() {
5281 assert_eq!(
5282 Inst::LdrFpReg32 {
5283 rt: S4,
5284 rn: X5,
5285 rm: X6,
5286 extend: AddrExtend::Lsl,
5287 shift: false
5288 }
5289 .encode(),
5290 0xBC6668A4
5291 );
5292 }
5293 #[test]
5294 fn str_s7_x8_w9_uxtw2() {
5295 assert_eq!(
5296 Inst::StrFpReg32 {
5297 rt: S7,
5298 rn: X8,
5299 rm: W9,
5300 extend: AddrExtend::Uxtw,
5301 shift: true
5302 }
5303 .encode(),
5304 0xBC295907
5305 );
5306 }
5307 #[test]
5308 fn ldr_d10_lit_8() {
5309 assert_eq!(Inst::LdrFpLit64 { rt: D10, offset: 8 }.encode(), 0x5C00004A);
5310 }
5311 #[test]
5312 fn ldr_d0_sp_post_8() {
5313 assert_eq!(
5314 Inst::LdrFpPost64 {
5315 rt: D0,
5316 rn: SP,
5317 offset: 8
5318 }
5319 .encode(),
5320 0xFC4087E0
5321 );
5322 }
5323 #[test]
5324 fn str_d1_sp_pre_m16() {
5325 assert_eq!(
5326 Inst::StrFpPre64 {
5327 rt: D1,
5328 rn: SP,
5329 offset: -16
5330 }
5331 .encode(),
5332 0xFC1F0FE1
5333 );
5334 }
5335 #[test]
5336 fn ldr_s2_sp_post_4() {
5337 assert_eq!(
5338 Inst::LdrFpPost32 {
5339 rt: S2,
5340 rn: SP,
5341 offset: 4
5342 }
5343 .encode(),
5344 0xBC4047E2
5345 );
5346 }
5347 #[test]
5348 fn str_s3_sp_pre_m8() {
5349 assert_eq!(
5350 Inst::StrFpPre32 {
5351 rt: S3,
5352 rn: SP,
5353 offset: -8
5354 }
5355 .encode(),
5356 0xBC1F8FE3
5357 );
5358 }
5359 #[test]
5360 fn ldr_lit64_x0_plus8() {
5361 assert_eq!(Inst::LdrLit64 { rt: X0, offset: 8 }.encode(), 0x58000040);
5362 }
5363 #[test]
5364 fn ldr_lit32_w0_plus12() {
5365 assert_eq!(Inst::LdrLit32 { rt: W0, offset: 12 }.encode(), 0x18000060);
5366 }
5367 #[test]
5368 fn ldrsw_lit_x1_plus8() {
5369 assert_eq!(Inst::LdrswLit { rt: X1, offset: 8 }.encode(), 0x98000041);
5370 }
5371
5372 // ---- Load/Store pair ----
5373
5374 #[test]
5375 fn stp_x29_x30_sp_pre_m16() {
5376 assert_eq!(
5377 Inst::StpPre64 {
5378 rt1: X29,
5379 rt2: X30,
5380 rn: SP,
5381 offset: -16
5382 }
5383 .encode(),
5384 0xA9BF7BFD
5385 );
5386 }
5387 #[test]
5388 fn stp_x29_x30_sp_post_16() {
5389 assert_eq!(
5390 Inst::StpPost64 {
5391 rt1: X29,
5392 rt2: X30,
5393 rn: SP,
5394 offset: 16
5395 }
5396 .encode(),
5397 0xA8817BFD
5398 );
5399 }
5400 #[test]
5401 fn ldp_x29_x30_sp_pre_m16() {
5402 assert_eq!(
5403 Inst::LdpPre64 {
5404 rt1: X29,
5405 rt2: X30,
5406 rn: SP,
5407 offset: -16
5408 }
5409 .encode(),
5410 0xA9FF7BFD
5411 );
5412 }
5413 #[test]
5414 fn ldp_x29_x30_sp_post_16() {
5415 assert_eq!(
5416 Inst::LdpPost64 {
5417 rt1: X29,
5418 rt2: X30,
5419 rn: SP,
5420 offset: 16
5421 }
5422 .encode(),
5423 0xA8C17BFD
5424 );
5425 }
5426 #[test]
5427 fn stp_x19_x20_sp_post_32() {
5428 assert_eq!(
5429 Inst::StpPost64 {
5430 rt1: X19,
5431 rt2: X20,
5432 rn: SP,
5433 offset: 32
5434 }
5435 .encode(),
5436 0xA88253F3
5437 );
5438 }
5439 #[test]
5440 fn ldp_x19_x20_sp_pre_m32() {
5441 assert_eq!(
5442 Inst::LdpPre64 {
5443 rt1: X19,
5444 rt2: X20,
5445 rn: SP,
5446 offset: -32
5447 }
5448 .encode(),
5449 0xA9FE53F3
5450 );
5451 }
5452 #[test]
5453 fn stp_x19_x20_sp_16() {
5454 assert_eq!(
5455 Inst::StpOff64 {
5456 rt1: X19,
5457 rt2: X20,
5458 rn: SP,
5459 offset: 16
5460 }
5461 .encode(),
5462 0xA90153F3
5463 );
5464 }
5465 #[test]
5466 fn ldp_x19_x20_sp_16() {
5467 assert_eq!(
5468 Inst::LdpOff64 {
5469 rt1: X19,
5470 rt2: X20,
5471 rn: SP,
5472 offset: 16
5473 }
5474 .encode(),
5475 0xA94153F3
5476 );
5477 }
5478 #[test]
5479 fn ldp_w9_w8_x8() {
5480 assert_eq!(
5481 Inst::LdpOff32 {
5482 rt1: W9,
5483 rt2: W8,
5484 rn: X8,
5485 offset: 0
5486 }
5487 .encode(),
5488 0x29402109
5489 );
5490 }
5491 #[test]
5492 fn stp_w1_w2_sp_16() {
5493 assert_eq!(
5494 Inst::StpOff32 {
5495 rt1: W1,
5496 rt2: W2,
5497 rn: SP,
5498 offset: 16
5499 }
5500 .encode(),
5501 0x29020BE1
5502 );
5503 }
5504 #[test]
5505 fn ldp_w9_w8_sp_post_8() {
5506 assert_eq!(
5507 Inst::LdpPost32 {
5508 rt1: W9,
5509 rt2: W8,
5510 rn: SP,
5511 offset: 8
5512 }
5513 .encode(),
5514 0x28C123E9
5515 );
5516 }
5517 #[test]
5518 fn ldp_w9_w8_sp_pre_m8() {
5519 assert_eq!(
5520 Inst::LdpPre32 {
5521 rt1: W9,
5522 rt2: W8,
5523 rn: SP,
5524 offset: -8
5525 }
5526 .encode(),
5527 0x29FF23E9
5528 );
5529 }
5530 #[test]
5531 fn ldp_d8_d9_sp_pre_m16() {
5532 assert_eq!(
5533 Inst::LdpFpPre64 {
5534 rt1: D8,
5535 rt2: D9,
5536 rn: SP,
5537 offset: -16
5538 }
5539 .encode(),
5540 0x6DFF27E8
5541 );
5542 }
5543 #[test]
5544 fn stp_d10_d11_sp_post_16() {
5545 assert_eq!(
5546 Inst::StpFpPost64 {
5547 rt1: D10,
5548 rt2: D11,
5549 rn: SP,
5550 offset: 16
5551 }
5552 .encode(),
5553 0x6C812FEA
5554 );
5555 }
5556 #[test]
5557 fn ldp_d12_d13_sp_32() {
5558 assert_eq!(
5559 Inst::LdpFpOff64 {
5560 rt1: D12,
5561 rt2: D13,
5562 rn: SP,
5563 offset: 32
5564 }
5565 .encode(),
5566 0x6D4237EC
5567 );
5568 }
5569 #[test]
5570 fn stp_s0_s1_sp_post_8() {
5571 assert_eq!(
5572 Inst::StpFpPost32 {
5573 rt1: S0,
5574 rt2: S1,
5575 rn: SP,
5576 offset: 8
5577 }
5578 .encode(),
5579 0x2C8107E0
5580 );
5581 }
5582 #[test]
5583 fn ldp_s2_s3_sp_pre_m8() {
5584 assert_eq!(
5585 Inst::LdpFpPre32 {
5586 rt1: S2,
5587 rt2: S3,
5588 rn: SP,
5589 offset: -8
5590 }
5591 .encode(),
5592 0x2DFF0FE2
5593 );
5594 }
5595 #[test]
5596 fn ldp_s4_s5_sp_16() {
5597 assert_eq!(
5598 Inst::LdpFpOff32 {
5599 rt1: S4,
5600 rt2: S5,
5601 rn: SP,
5602 offset: 16
5603 }
5604 .encode(),
5605 0x2D4217E4
5606 );
5607 }
5608 #[test]
5609 fn stp_q0_q1_sp_pre_m32() {
5610 assert_eq!(
5611 Inst::StpFpPre128 {
5612 rt1: FpReg::new(0),
5613 rt2: FpReg::new(1),
5614 rn: SP,
5615 offset: -32
5616 }
5617 .encode(),
5618 0xADBF07E0
5619 );
5620 }
5621 #[test]
5622 fn ldp_q2_q3_sp_post_32() {
5623 assert_eq!(
5624 Inst::LdpFpPost128 {
5625 rt1: FpReg::new(2),
5626 rt2: FpReg::new(3),
5627 rn: SP,
5628 offset: 32
5629 }
5630 .encode(),
5631 0xACC10FE2
5632 );
5633 }
5634 #[test]
5635 fn ldp_q4_q5_sp_64() {
5636 assert_eq!(
5637 Inst::LdpFpOff128 {
5638 rt1: FpReg::new(4),
5639 rt2: FpReg::new(5),
5640 rn: SP,
5641 offset: 64
5642 }
5643 .encode(),
5644 0xAD4217E4
5645 );
5646 }
5647
5648 // ---- Load/Store (pre/post-index) ----
5649
5650 #[test]
5651 fn ldr_w0_x1_post_4() {
5652 assert_eq!(
5653 Inst::LdrPost32 {
5654 rt: W0,
5655 rn: X1,
5656 offset: 4
5657 }
5658 .encode(),
5659 0xB8404420
5660 );
5661 }
5662 #[test]
5663 fn str_w2_x3_pre_m4() {
5664 assert_eq!(
5665 Inst::StrPre32 {
5666 rt: W2,
5667 rn: X3,
5668 offset: -4
5669 }
5670 .encode(),
5671 0xB81FCC62
5672 );
5673 }
5674 #[test]
5675 fn ldr_x0_x1_pre_8() {
5676 assert_eq!(
5677 Inst::LdrPre64 {
5678 rt: X0,
5679 rn: X1,
5680 offset: 8
5681 }
5682 .encode(),
5683 0xF8408C20
5684 );
5685 }
5686 #[test]
5687 fn str_x0_x1_post_8() {
5688 assert_eq!(
5689 Inst::StrPost64 {
5690 rt: X0,
5691 rn: X1,
5692 offset: 8
5693 }
5694 .encode(),
5695 0xF8008420
5696 );
5697 }
5698
5699 // ---- FP arithmetic ----
5700
5701 #[test]
5702 fn fadd_d0_d1_d2() {
5703 assert_eq!(
5704 Inst::FaddD {
5705 rd: D0,
5706 rn: D1,
5707 rm: D2
5708 }
5709 .encode(),
5710 0x1E622820
5711 );
5712 }
5713 #[test]
5714 fn fsub_d3_d4_d5() {
5715 assert_eq!(
5716 Inst::FsubD {
5717 rd: D3,
5718 rn: D4,
5719 rm: D5
5720 }
5721 .encode(),
5722 0x1E653883
5723 );
5724 }
5725 #[test]
5726 fn fmul_d6_d7_d8() {
5727 assert_eq!(
5728 Inst::FmulD {
5729 rd: D6,
5730 rn: D7,
5731 rm: D8
5732 }
5733 .encode(),
5734 0x1E6808E6
5735 );
5736 }
5737 #[test]
5738 fn fdiv_d9_d10_d11() {
5739 assert_eq!(
5740 Inst::FdivD {
5741 rd: D9,
5742 rn: D10,
5743 rm: D11
5744 }
5745 .encode(),
5746 0x1E6B1949
5747 );
5748 }
5749 #[test]
5750 fn fadd_s0_s1_s2() {
5751 assert_eq!(
5752 Inst::FaddS {
5753 rd: S0,
5754 rn: S1,
5755 rm: S2
5756 }
5757 .encode(),
5758 0x1E222820
5759 );
5760 }
5761 #[test]
5762 fn fadd_4s_v0_v0_v1() {
5763 assert_eq!(
5764 Inst::FaddV4S {
5765 rd: FpReg::new(0),
5766 rn: FpReg::new(0),
5767 rm: FpReg::new(1)
5768 }
5769 .encode(),
5770 0x4E21D400
5771 );
5772 }
5773 #[test]
5774 fn fadd_2d_v0_v1_v2() {
5775 assert_eq!(
5776 Inst::FaddV2D {
5777 rd: FpReg::new(0),
5778 rn: FpReg::new(1),
5779 rm: FpReg::new(2)
5780 }
5781 .encode(),
5782 0x4E62D420
5783 );
5784 }
5785 #[test]
5786 fn add_4s_v0_v1_v2() {
5787 assert_eq!(
5788 Inst::AddV4S {
5789 rd: FpReg::new(0),
5790 rn: FpReg::new(1),
5791 rm: FpReg::new(2)
5792 }
5793 .encode(),
5794 0x4EA28420
5795 );
5796 }
5797 #[test]
5798 fn addp_2d_v0_v1_v2() {
5799 assert_eq!(
5800 Inst::AddpV2D {
5801 rd: FpReg::new(0),
5802 rn: FpReg::new(1),
5803 rm: FpReg::new(2)
5804 }
5805 .encode(),
5806 0x4EE2BC20
5807 );
5808 }
5809 #[test]
5810 fn addp_4s_v0_v1_v2() {
5811 assert_eq!(
5812 Inst::AddpV4S {
5813 rd: FpReg::new(0),
5814 rn: FpReg::new(1),
5815 rm: FpReg::new(2)
5816 }
5817 .encode(),
5818 0x4EA2BC20
5819 );
5820 }
5821 #[test]
5822 fn addp_8h_v0_v1_v2() {
5823 assert_eq!(
5824 Inst::AddpV8H {
5825 rd: FpReg::new(0),
5826 rn: FpReg::new(1),
5827 rm: FpReg::new(2)
5828 }
5829 .encode(),
5830 0x4E62BC20
5831 );
5832 }
5833 #[test]
5834 fn addp_16b_v6_v7_v8() {
5835 assert_eq!(
5836 Inst::AddpV16B {
5837 rd: FpReg::new(6),
5838 rn: FpReg::new(7),
5839 rm: FpReg::new(8)
5840 }
5841 .encode(),
5842 0x4E28BCE6
5843 );
5844 }
5845 #[test]
5846 fn fmax_4s_v0_v0_v1() {
5847 assert_eq!(
5848 Inst::FmaxV4S {
5849 rd: FpReg::new(0),
5850 rn: FpReg::new(0),
5851 rm: FpReg::new(1)
5852 }
5853 .encode(),
5854 0x4E21F400
5855 );
5856 }
5857 #[test]
5858 fn fmax_2d_v0_v0_v1() {
5859 assert_eq!(
5860 Inst::FmaxV2D {
5861 rd: FpReg::new(0),
5862 rn: FpReg::new(0),
5863 rm: FpReg::new(1)
5864 }
5865 .encode(),
5866 0x4E61F400
5867 );
5868 }
5869 #[test]
5870 fn fmin_4s_v2_v3_v4() {
5871 assert_eq!(
5872 Inst::FminV4S {
5873 rd: FpReg::new(2),
5874 rn: FpReg::new(3),
5875 rm: FpReg::new(4)
5876 }
5877 .encode(),
5878 0x4EA4F462
5879 );
5880 }
5881 #[test]
5882 fn fmin_2d_v2_v3_v4() {
5883 assert_eq!(
5884 Inst::FminV2D {
5885 rd: FpReg::new(2),
5886 rn: FpReg::new(3),
5887 rm: FpReg::new(4)
5888 }
5889 .encode(),
5890 0x4EE4F462
5891 );
5892 }
5893 #[test]
5894 fn fmaxnm_4s_v0_v1_v2() {
5895 assert_eq!(
5896 Inst::FmaxnmV4S {
5897 rd: FpReg::new(0),
5898 rn: FpReg::new(1),
5899 rm: FpReg::new(2)
5900 }
5901 .encode(),
5902 0x4E22C420
5903 );
5904 }
5905 #[test]
5906 fn fmaxnm_2d_v0_v0_v1() {
5907 assert_eq!(
5908 Inst::FmaxnmV2D {
5909 rd: FpReg::new(0),
5910 rn: FpReg::new(0),
5911 rm: FpReg::new(1)
5912 }
5913 .encode(),
5914 0x4E61C400
5915 );
5916 }
5917 #[test]
5918 fn fminnm_4s_v3_v4_v5() {
5919 assert_eq!(
5920 Inst::FminnmV4S {
5921 rd: FpReg::new(3),
5922 rn: FpReg::new(4),
5923 rm: FpReg::new(5)
5924 }
5925 .encode(),
5926 0x4EA5C483
5927 );
5928 }
5929 #[test]
5930 fn fminnm_2d_v2_v3_v4() {
5931 assert_eq!(
5932 Inst::FminnmV2D {
5933 rd: FpReg::new(2),
5934 rn: FpReg::new(3),
5935 rm: FpReg::new(4)
5936 }
5937 .encode(),
5938 0x4EE4C462
5939 );
5940 }
5941 #[test]
5942 fn smax_4s_v5_v6_v7() {
5943 assert_eq!(
5944 Inst::SmaxV4S {
5945 rd: FpReg::new(5),
5946 rn: FpReg::new(6),
5947 rm: FpReg::new(7)
5948 }
5949 .encode(),
5950 0x4EA764C5
5951 );
5952 }
5953 #[test]
5954 fn smaxp_4s_v6_v7_v8() {
5955 assert_eq!(
5956 Inst::SmaxpV4S {
5957 rd: FpReg::new(6),
5958 rn: FpReg::new(7),
5959 rm: FpReg::new(8)
5960 }
5961 .encode(),
5962 0x4EA8A4E6
5963 );
5964 }
5965 #[test]
5966 fn smaxp_8h_v6_v7_v8() {
5967 assert_eq!(
5968 Inst::SmaxpV8H {
5969 rd: FpReg::new(6),
5970 rn: FpReg::new(7),
5971 rm: FpReg::new(8)
5972 }
5973 .encode(),
5974 0x4E68A4E6
5975 );
5976 }
5977 #[test]
5978 fn smaxp_16b_v6_v7_v8() {
5979 assert_eq!(
5980 Inst::SmaxpV16B {
5981 rd: FpReg::new(6),
5982 rn: FpReg::new(7),
5983 rm: FpReg::new(8)
5984 }
5985 .encode(),
5986 0x4E28A4E6
5987 );
5988 }
5989 #[test]
5990 fn smin_4s_v8_v9_v10() {
5991 assert_eq!(
5992 Inst::SminV4S {
5993 rd: FpReg::new(8),
5994 rn: FpReg::new(9),
5995 rm: FpReg::new(10)
5996 }
5997 .encode(),
5998 0x4EAA6D28
5999 );
6000 }
6001 #[test]
6002 fn sminp_4s_v9_v10_v11() {
6003 assert_eq!(
6004 Inst::SminpV4S {
6005 rd: FpReg::new(9),
6006 rn: FpReg::new(10),
6007 rm: FpReg::new(11)
6008 }
6009 .encode(),
6010 0x4EABAD49
6011 );
6012 }
6013 #[test]
6014 fn sminp_8h_v9_v10_v11() {
6015 assert_eq!(
6016 Inst::SminpV8H {
6017 rd: FpReg::new(9),
6018 rn: FpReg::new(10),
6019 rm: FpReg::new(11)
6020 }
6021 .encode(),
6022 0x4E6BAD49
6023 );
6024 }
6025 #[test]
6026 fn sminp_16b_v9_v10_v11() {
6027 assert_eq!(
6028 Inst::SminpV16B {
6029 rd: FpReg::new(9),
6030 rn: FpReg::new(10),
6031 rm: FpReg::new(11)
6032 }
6033 .encode(),
6034 0x4E2BAD49
6035 );
6036 }
6037 #[test]
6038 fn umax_4s_v0_v0_v1() {
6039 assert_eq!(
6040 Inst::UmaxV4S {
6041 rd: FpReg::new(0),
6042 rn: FpReg::new(0),
6043 rm: FpReg::new(1)
6044 }
6045 .encode(),
6046 0x6EA16400
6047 );
6048 }
6049 #[test]
6050 fn umaxp_4s_v0_v1_v2() {
6051 assert_eq!(
6052 Inst::UmaxpV4S {
6053 rd: FpReg::new(0),
6054 rn: FpReg::new(1),
6055 rm: FpReg::new(2)
6056 }
6057 .encode(),
6058 0x6EA2A420
6059 );
6060 }
6061 #[test]
6062 fn umaxp_8h_v0_v1_v2() {
6063 assert_eq!(
6064 Inst::UmaxpV8H {
6065 rd: FpReg::new(0),
6066 rn: FpReg::new(1),
6067 rm: FpReg::new(2)
6068 }
6069 .encode(),
6070 0x6E62A420
6071 );
6072 }
6073 #[test]
6074 fn umaxp_16b_v0_v1_v2() {
6075 assert_eq!(
6076 Inst::UmaxpV16B {
6077 rd: FpReg::new(0),
6078 rn: FpReg::new(1),
6079 rm: FpReg::new(2)
6080 }
6081 .encode(),
6082 0x6E22A420
6083 );
6084 }
6085 #[test]
6086 fn umin_4s_v2_v3_v4() {
6087 assert_eq!(
6088 Inst::UminV4S {
6089 rd: FpReg::new(2),
6090 rn: FpReg::new(3),
6091 rm: FpReg::new(4)
6092 }
6093 .encode(),
6094 0x6EA46C62
6095 );
6096 }
6097 #[test]
6098 fn uminp_4s_v3_v4_v5() {
6099 assert_eq!(
6100 Inst::UminpV4S {
6101 rd: FpReg::new(3),
6102 rn: FpReg::new(4),
6103 rm: FpReg::new(5)
6104 }
6105 .encode(),
6106 0x6EA5AC83
6107 );
6108 }
6109 #[test]
6110 fn uminp_8h_v3_v4_v5() {
6111 assert_eq!(
6112 Inst::UminpV8H {
6113 rd: FpReg::new(3),
6114 rn: FpReg::new(4),
6115 rm: FpReg::new(5)
6116 }
6117 .encode(),
6118 0x6E65AC83
6119 );
6120 }
6121 #[test]
6122 fn uminp_16b_v3_v4_v5() {
6123 assert_eq!(
6124 Inst::UminpV16B {
6125 rd: FpReg::new(3),
6126 rn: FpReg::new(4),
6127 rm: FpReg::new(5)
6128 }
6129 .encode(),
6130 0x6E25AC83
6131 );
6132 }
6133 #[test]
6134 fn addv_4s_s0_v0() {
6135 assert_eq!(
6136 Inst::AddvV4S {
6137 rd: FpReg::new(0),
6138 rn: FpReg::new(0)
6139 }
6140 .encode(),
6141 0x4EB1B800
6142 );
6143 }
6144 #[test]
6145 fn addv_16b_b0_v0() {
6146 assert_eq!(
6147 Inst::AddvV16B {
6148 rd: FpReg::new(0),
6149 rn: FpReg::new(0)
6150 }
6151 .encode(),
6152 0x4E31B800
6153 );
6154 }
6155 #[test]
6156 fn addv_8h_h0_v0() {
6157 assert_eq!(
6158 Inst::AddvV8H {
6159 rd: FpReg::new(0),
6160 rn: FpReg::new(0)
6161 }
6162 .encode(),
6163 0x4E71B800
6164 );
6165 }
6166 #[test]
6167 fn faddp_4s_v0_v1_v2() {
6168 assert_eq!(
6169 Inst::FaddpV4S {
6170 rd: FpReg::new(0),
6171 rn: FpReg::new(1),
6172 rm: FpReg::new(2)
6173 }
6174 .encode(),
6175 0x6E22D420
6176 );
6177 }
6178 #[test]
6179 fn faddp_2d_v0_v1_v2() {
6180 assert_eq!(
6181 Inst::FaddpV2D {
6182 rd: FpReg::new(0),
6183 rn: FpReg::new(1),
6184 rm: FpReg::new(2)
6185 }
6186 .encode(),
6187 0x6E62D420
6188 );
6189 }
6190 #[test]
6191 fn fmaxp_2d_v3_v4_v5() {
6192 assert_eq!(
6193 Inst::FmaxpV2D {
6194 rd: FpReg::new(3),
6195 rn: FpReg::new(4),
6196 rm: FpReg::new(5)
6197 }
6198 .encode(),
6199 0x6E65F483
6200 );
6201 }
6202 #[test]
6203 fn fmaxp_4s_v0_v1_v2() {
6204 assert_eq!(
6205 Inst::FmaxpV4S {
6206 rd: FpReg::new(0),
6207 rn: FpReg::new(1),
6208 rm: FpReg::new(2)
6209 }
6210 .encode(),
6211 0x6E22F420
6212 );
6213 }
6214 #[test]
6215 fn fminp_2d_v6_v7_v8() {
6216 assert_eq!(
6217 Inst::FminpV2D {
6218 rd: FpReg::new(6),
6219 rn: FpReg::new(7),
6220 rm: FpReg::new(8)
6221 }
6222 .encode(),
6223 0x6EE8F4E6
6224 );
6225 }
6226 #[test]
6227 fn fminp_4s_v3_v4_v5() {
6228 assert_eq!(
6229 Inst::FminpV4S {
6230 rd: FpReg::new(3),
6231 rn: FpReg::new(4),
6232 rm: FpReg::new(5)
6233 }
6234 .encode(),
6235 0x6EA5F483
6236 );
6237 }
6238 #[test]
6239 fn fmaxnmp_4s_v0_v1_v2() {
6240 assert_eq!(
6241 Inst::FmaxnmpV4S {
6242 rd: FpReg::new(0),
6243 rn: FpReg::new(1),
6244 rm: FpReg::new(2)
6245 }
6246 .encode(),
6247 0x6E22C420
6248 );
6249 }
6250 #[test]
6251 fn fmaxnmp_2d_v0_v1_v2() {
6252 assert_eq!(
6253 Inst::FmaxnmpV2D {
6254 rd: FpReg::new(0),
6255 rn: FpReg::new(1),
6256 rm: FpReg::new(2)
6257 }
6258 .encode(),
6259 0x6E62C420
6260 );
6261 }
6262 #[test]
6263 fn fminnmp_4s_v3_v4_v5() {
6264 assert_eq!(
6265 Inst::FminnmpV4S {
6266 rd: FpReg::new(3),
6267 rn: FpReg::new(4),
6268 rm: FpReg::new(5)
6269 }
6270 .encode(),
6271 0x6EA5C483
6272 );
6273 }
6274 #[test]
6275 fn fminnmp_2d_v3_v4_v5() {
6276 assert_eq!(
6277 Inst::FminnmpV2D {
6278 rd: FpReg::new(3),
6279 rn: FpReg::new(4),
6280 rm: FpReg::new(5)
6281 }
6282 .encode(),
6283 0x6EE5C483
6284 );
6285 }
6286 #[test]
6287 fn fmla_4s_v0_v1_v2() {
6288 assert_eq!(
6289 Inst::FmlaV4S {
6290 rd: FpReg::new(0),
6291 rn: FpReg::new(1),
6292 rm: FpReg::new(2)
6293 }
6294 .encode(),
6295 0x4E22CC20
6296 );
6297 }
6298 #[test]
6299 fn fmla_2d_v0_v1_v2() {
6300 assert_eq!(
6301 Inst::FmlaV2D {
6302 rd: FpReg::new(0),
6303 rn: FpReg::new(1),
6304 rm: FpReg::new(2)
6305 }
6306 .encode(),
6307 0x4E62CC20
6308 );
6309 }
6310 #[test]
6311 fn fmls_4s_v3_v4_v5() {
6312 assert_eq!(
6313 Inst::FmlsV4S {
6314 rd: FpReg::new(3),
6315 rn: FpReg::new(4),
6316 rm: FpReg::new(5)
6317 }
6318 .encode(),
6319 0x4EA5CC83
6320 );
6321 }
6322 #[test]
6323 fn fmls_2d_v3_v4_v5() {
6324 assert_eq!(
6325 Inst::FmlsV2D {
6326 rd: FpReg::new(3),
6327 rn: FpReg::new(4),
6328 rm: FpReg::new(5)
6329 }
6330 .encode(),
6331 0x4EE5CC83
6332 );
6333 }
6334 #[test]
6335 fn faddp_2s_s3_v4() {
6336 assert_eq!(
6337 Inst::FaddpV2S {
6338 rd: FpReg::new(3),
6339 rn: FpReg::new(4)
6340 }
6341 .encode(),
6342 0x7E30D883
6343 );
6344 }
6345 #[test]
6346 fn faddp_2d_d0_v0() {
6347 assert_eq!(
6348 Inst::FaddpV2DScalar {
6349 rd: FpReg::new(0),
6350 rn: FpReg::new(0)
6351 }
6352 .encode(),
6353 0x7E70D800
6354 );
6355 }
6356 #[test]
6357 fn fmaxp_2d_d1_v2() {
6358 assert_eq!(
6359 Inst::FmaxpV2DScalar {
6360 rd: FpReg::new(1),
6361 rn: FpReg::new(2)
6362 }
6363 .encode(),
6364 0x7E70F841
6365 );
6366 }
6367 #[test]
6368 fn fminp_2d_d3_v4() {
6369 assert_eq!(
6370 Inst::FminpV2DScalar {
6371 rd: FpReg::new(3),
6372 rn: FpReg::new(4)
6373 }
6374 .encode(),
6375 0x7EF0F883
6376 );
6377 }
6378 #[test]
6379 fn fmaxnmp_2d_d0_v0() {
6380 assert_eq!(
6381 Inst::FmaxnmpV2DScalar {
6382 rd: FpReg::new(0),
6383 rn: FpReg::new(0)
6384 }
6385 .encode(),
6386 0x7E70C800
6387 );
6388 }
6389 #[test]
6390 fn fminnmp_2d_d1_v2() {
6391 assert_eq!(
6392 Inst::FminnmpV2DScalar {
6393 rd: FpReg::new(1),
6394 rn: FpReg::new(2)
6395 }
6396 .encode(),
6397 0x7EF0C841
6398 );
6399 }
6400 #[test]
6401 fn umaxv_4s_s1_v2() {
6402 assert_eq!(
6403 Inst::UmaxvV4S {
6404 rd: FpReg::new(1),
6405 rn: FpReg::new(2)
6406 }
6407 .encode(),
6408 0x6EB0A841
6409 );
6410 }
6411 #[test]
6412 fn umaxv_16b_b0_v0() {
6413 assert_eq!(
6414 Inst::UmaxvV16B {
6415 rd: FpReg::new(0),
6416 rn: FpReg::new(0)
6417 }
6418 .encode(),
6419 0x6E30A800
6420 );
6421 }
6422 #[test]
6423 fn umaxv_8h_h0_v0() {
6424 assert_eq!(
6425 Inst::UmaxvV8H {
6426 rd: FpReg::new(0),
6427 rn: FpReg::new(0)
6428 }
6429 .encode(),
6430 0x6E70A800
6431 );
6432 }
6433 #[test]
6434 fn smaxv_4s_s3_v4() {
6435 assert_eq!(
6436 Inst::SmaxvV4S {
6437 rd: FpReg::new(3),
6438 rn: FpReg::new(4)
6439 }
6440 .encode(),
6441 0x4EB0A883
6442 );
6443 }
6444 #[test]
6445 fn smaxv_16b_b0_v0() {
6446 assert_eq!(
6447 Inst::SmaxvV16B {
6448 rd: FpReg::new(0),
6449 rn: FpReg::new(0)
6450 }
6451 .encode(),
6452 0x4E30A800
6453 );
6454 }
6455 #[test]
6456 fn smaxv_8h_h0_v0() {
6457 assert_eq!(
6458 Inst::SmaxvV8H {
6459 rd: FpReg::new(0),
6460 rn: FpReg::new(0)
6461 }
6462 .encode(),
6463 0x4E70A800
6464 );
6465 }
6466 #[test]
6467 fn uminv_4s_s1_v2() {
6468 assert_eq!(
6469 Inst::UminvV4S {
6470 rd: FpReg::new(1),
6471 rn: FpReg::new(2)
6472 }
6473 .encode(),
6474 0x6EB1A841
6475 );
6476 }
6477 #[test]
6478 fn uminv_16b_b0_v0() {
6479 assert_eq!(
6480 Inst::UminvV16B {
6481 rd: FpReg::new(0),
6482 rn: FpReg::new(0)
6483 }
6484 .encode(),
6485 0x6E31A800
6486 );
6487 }
6488 #[test]
6489 fn uminv_8h_h0_v0() {
6490 assert_eq!(
6491 Inst::UminvV8H {
6492 rd: FpReg::new(0),
6493 rn: FpReg::new(0)
6494 }
6495 .encode(),
6496 0x6E71A800
6497 );
6498 }
6499 #[test]
6500 fn sminv_4s_s3_v4() {
6501 assert_eq!(
6502 Inst::SminvV4S {
6503 rd: FpReg::new(3),
6504 rn: FpReg::new(4)
6505 }
6506 .encode(),
6507 0x4EB1A883
6508 );
6509 }
6510 #[test]
6511 fn sminv_16b_b0_v0() {
6512 assert_eq!(
6513 Inst::SminvV16B {
6514 rd: FpReg::new(0),
6515 rn: FpReg::new(0)
6516 }
6517 .encode(),
6518 0x4E31A800
6519 );
6520 }
6521 #[test]
6522 fn sminv_8h_h0_v0() {
6523 assert_eq!(
6524 Inst::SminvV8H {
6525 rd: FpReg::new(0),
6526 rn: FpReg::new(0)
6527 }
6528 .encode(),
6529 0x4E71A800
6530 );
6531 }
6532 #[test]
6533 fn fmaxv_4s_s1_v2() {
6534 assert_eq!(
6535 Inst::FmaxvV4S {
6536 rd: FpReg::new(1),
6537 rn: FpReg::new(2)
6538 }
6539 .encode(),
6540 0x6E30F841
6541 );
6542 }
6543 #[test]
6544 fn fminv_4s_s3_v4() {
6545 assert_eq!(
6546 Inst::FminvV4S {
6547 rd: FpReg::new(3),
6548 rn: FpReg::new(4)
6549 }
6550 .encode(),
6551 0x6EB0F883
6552 );
6553 }
6554 #[test]
6555 fn fmaxnmv_4s_s1_v2() {
6556 assert_eq!(
6557 Inst::FmaxnmvV4S {
6558 rd: FpReg::new(1),
6559 rn: FpReg::new(2)
6560 }
6561 .encode(),
6562 0x6E30C841
6563 );
6564 }
6565 #[test]
6566 fn fminnmv_4s_s3_v4() {
6567 assert_eq!(
6568 Inst::FminnmvV4S {
6569 rd: FpReg::new(3),
6570 rn: FpReg::new(4)
6571 }
6572 .encode(),
6573 0x6EB0C883
6574 );
6575 }
6576 #[test]
6577 fn fsub_4s_v0_v0_v1() {
6578 assert_eq!(
6579 Inst::FsubV4S {
6580 rd: FpReg::new(0),
6581 rn: FpReg::new(0),
6582 rm: FpReg::new(1)
6583 }
6584 .encode(),
6585 0x4EA1D400
6586 );
6587 }
6588 #[test]
6589 fn fsub_2d_v3_v4_v5() {
6590 assert_eq!(
6591 Inst::FsubV2D {
6592 rd: FpReg::new(3),
6593 rn: FpReg::new(4),
6594 rm: FpReg::new(5)
6595 }
6596 .encode(),
6597 0x4EE5D483
6598 );
6599 }
6600 #[test]
6601 fn sub_4s_v3_v4_v5() {
6602 assert_eq!(
6603 Inst::SubV4S {
6604 rd: FpReg::new(3),
6605 rn: FpReg::new(4),
6606 rm: FpReg::new(5)
6607 }
6608 .encode(),
6609 0x6EA58483
6610 );
6611 }
6612 #[test]
6613 fn fmul_4s_v0_v0_v1() {
6614 assert_eq!(
6615 Inst::FmulV4S {
6616 rd: FpReg::new(0),
6617 rn: FpReg::new(0),
6618 rm: FpReg::new(1)
6619 }
6620 .encode(),
6621 0x6E21DC00
6622 );
6623 }
6624 #[test]
6625 fn fmul_2d_v6_v7_v8() {
6626 assert_eq!(
6627 Inst::FmulV2D {
6628 rd: FpReg::new(6),
6629 rn: FpReg::new(7),
6630 rm: FpReg::new(8)
6631 }
6632 .encode(),
6633 0x6E68DCE6
6634 );
6635 }
6636 #[test]
6637 fn fdiv_4s_v0_v0_v1() {
6638 assert_eq!(
6639 Inst::FdivV4S {
6640 rd: FpReg::new(0),
6641 rn: FpReg::new(0),
6642 rm: FpReg::new(1)
6643 }
6644 .encode(),
6645 0x6E21FC00
6646 );
6647 }
6648 #[test]
6649 fn fdiv_2d_v9_v10_v11() {
6650 assert_eq!(
6651 Inst::FdivV2D {
6652 rd: FpReg::new(9),
6653 rn: FpReg::new(10),
6654 rm: FpReg::new(11)
6655 }
6656 .encode(),
6657 0x6E6BFD49
6658 );
6659 }
6660 #[test]
6661 fn fabd_2d_v0_v1_v2() {
6662 assert_eq!(
6663 Inst::FabdV2D {
6664 rd: FpReg::new(0),
6665 rn: FpReg::new(1),
6666 rm: FpReg::new(2)
6667 }
6668 .encode(),
6669 0x6EE2D420
6670 );
6671 }
6672 #[test]
6673 fn fabs_4s_v0_v0() {
6674 assert_eq!(
6675 Inst::FabsV4S {
6676 rd: FpReg::new(0),
6677 rn: FpReg::new(0)
6678 }
6679 .encode(),
6680 0x4EA0F800
6681 );
6682 }
6683 #[test]
6684 fn fabs_2d_v0_v0() {
6685 assert_eq!(
6686 Inst::FabsV2D {
6687 rd: FpReg::new(0),
6688 rn: FpReg::new(0)
6689 }
6690 .encode(),
6691 0x4EE0F800
6692 );
6693 }
6694 #[test]
6695 fn fneg_4s_v6_v7() {
6696 assert_eq!(
6697 Inst::FnegV4S {
6698 rd: FpReg::new(6),
6699 rn: FpReg::new(7)
6700 }
6701 .encode(),
6702 0x6EA0F8E6
6703 );
6704 }
6705 #[test]
6706 fn fneg_2d_v3_v4() {
6707 assert_eq!(
6708 Inst::FnegV2D {
6709 rd: FpReg::new(3),
6710 rn: FpReg::new(4)
6711 }
6712 .encode(),
6713 0x6EE0F883
6714 );
6715 }
6716 #[test]
6717 fn fsqrt_4s_v1_v2() {
6718 assert_eq!(
6719 Inst::FsqrtV4S {
6720 rd: FpReg::new(1),
6721 rn: FpReg::new(2)
6722 }
6723 .encode(),
6724 0x6EA1F841
6725 );
6726 }
6727 #[test]
6728 fn fsqrt_2d_v1_v2() {
6729 assert_eq!(
6730 Inst::FsqrtV2D {
6731 rd: FpReg::new(1),
6732 rn: FpReg::new(2)
6733 }
6734 .encode(),
6735 0x6EE1F841
6736 );
6737 }
6738 #[test]
6739 fn scvtf_4s_v0_v1() {
6740 assert_eq!(
6741 Inst::ScvtfV4S {
6742 rd: FpReg::new(0),
6743 rn: FpReg::new(1)
6744 }
6745 .encode(),
6746 0x4E21D820
6747 );
6748 }
6749 #[test]
6750 fn scvtf_2d_v0_v0() {
6751 assert_eq!(
6752 Inst::ScvtfV2D {
6753 rd: FpReg::new(0),
6754 rn: FpReg::new(0)
6755 }
6756 .encode(),
6757 0x4E61D800
6758 );
6759 }
6760 #[test]
6761 fn ucvtf_4s_v2_v3() {
6762 assert_eq!(
6763 Inst::UcvtfV4S {
6764 rd: FpReg::new(2),
6765 rn: FpReg::new(3)
6766 }
6767 .encode(),
6768 0x6E21D862
6769 );
6770 }
6771 #[test]
6772 fn ucvtf_2d_v1_v2() {
6773 assert_eq!(
6774 Inst::UcvtfV2D {
6775 rd: FpReg::new(1),
6776 rn: FpReg::new(2)
6777 }
6778 .encode(),
6779 0x6E61D841
6780 );
6781 }
6782 #[test]
6783 fn fcvtzs_4s_v4_v5() {
6784 assert_eq!(
6785 Inst::FcvtzsV4S {
6786 rd: FpReg::new(4),
6787 rn: FpReg::new(5)
6788 }
6789 .encode(),
6790 0x4EA1B8A4
6791 );
6792 }
6793 #[test]
6794 fn fcvtzs_2d_v3_v4() {
6795 assert_eq!(
6796 Inst::FcvtzsV2D {
6797 rd: FpReg::new(3),
6798 rn: FpReg::new(4)
6799 }
6800 .encode(),
6801 0x4EE1B883
6802 );
6803 }
6804 #[test]
6805 fn fcvtzu_4s_v6_v7() {
6806 assert_eq!(
6807 Inst::FcvtzuV4S {
6808 rd: FpReg::new(6),
6809 rn: FpReg::new(7)
6810 }
6811 .encode(),
6812 0x6EA1B8E6
6813 );
6814 }
6815 #[test]
6816 fn fcvtzu_2d_v5_v6() {
6817 assert_eq!(
6818 Inst::FcvtzuV2D {
6819 rd: FpReg::new(5),
6820 rn: FpReg::new(6)
6821 }
6822 .encode(),
6823 0x6EE1B8C5
6824 );
6825 }
6826 #[test]
6827 fn frecpe_4s_v0_v1() {
6828 assert_eq!(
6829 Inst::FrecpeV4S {
6830 rd: FpReg::new(0),
6831 rn: FpReg::new(1)
6832 }
6833 .encode(),
6834 0x4EA1D820
6835 );
6836 }
6837 #[test]
6838 fn frecpe_2d_v0_v0() {
6839 assert_eq!(
6840 Inst::FrecpeV2D {
6841 rd: FpReg::new(0),
6842 rn: FpReg::new(0)
6843 }
6844 .encode(),
6845 0x4EE1D800
6846 );
6847 }
6848 #[test]
6849 fn frecps_4s_v2_v3_v4() {
6850 assert_eq!(
6851 Inst::FrecpsV4S {
6852 rd: FpReg::new(2),
6853 rn: FpReg::new(3),
6854 rm: FpReg::new(4)
6855 }
6856 .encode(),
6857 0x4E24FC62
6858 );
6859 }
6860 #[test]
6861 fn frecps_2d_v1_v2_v3() {
6862 assert_eq!(
6863 Inst::FrecpsV2D {
6864 rd: FpReg::new(1),
6865 rn: FpReg::new(2),
6866 rm: FpReg::new(3)
6867 }
6868 .encode(),
6869 0x4E63FC41
6870 );
6871 }
6872 #[test]
6873 fn frsqrte_4s_v5_v6() {
6874 assert_eq!(
6875 Inst::FrsqrteV4S {
6876 rd: FpReg::new(5),
6877 rn: FpReg::new(6)
6878 }
6879 .encode(),
6880 0x6EA1D8C5
6881 );
6882 }
6883 #[test]
6884 fn frsqrte_2d_v4_v5() {
6885 assert_eq!(
6886 Inst::FrsqrteV2D {
6887 rd: FpReg::new(4),
6888 rn: FpReg::new(5)
6889 }
6890 .encode(),
6891 0x6EE1D8A4
6892 );
6893 }
6894 #[test]
6895 fn frsqrts_4s_v7_v8_v9() {
6896 assert_eq!(
6897 Inst::FrsqrtsV4S {
6898 rd: FpReg::new(7),
6899 rn: FpReg::new(8),
6900 rm: FpReg::new(9)
6901 }
6902 .encode(),
6903 0x4EA9FD07
6904 );
6905 }
6906 #[test]
6907 fn frsqrts_2d_v6_v7_v8() {
6908 assert_eq!(
6909 Inst::FrsqrtsV2D {
6910 rd: FpReg::new(6),
6911 rn: FpReg::new(7),
6912 rm: FpReg::new(8)
6913 }
6914 .encode(),
6915 0x4EE8FCE6
6916 );
6917 }
6918 #[test]
6919 fn frintn_4s_v0_v1() {
6920 assert_eq!(
6921 Inst::FrintnV4S {
6922 rd: FpReg::new(0),
6923 rn: FpReg::new(1)
6924 }
6925 .encode(),
6926 0x4E218820
6927 );
6928 }
6929 #[test]
6930 fn frintm_4s_v2_v3() {
6931 assert_eq!(
6932 Inst::FrintmV4S {
6933 rd: FpReg::new(2),
6934 rn: FpReg::new(3)
6935 }
6936 .encode(),
6937 0x4E219862
6938 );
6939 }
6940 #[test]
6941 fn frintp_4s_v4_v5() {
6942 assert_eq!(
6943 Inst::FrintpV4S {
6944 rd: FpReg::new(4),
6945 rn: FpReg::new(5)
6946 }
6947 .encode(),
6948 0x4EA188A4
6949 );
6950 }
6951 #[test]
6952 fn frintz_4s_v6_v7() {
6953 assert_eq!(
6954 Inst::FrintzV4S {
6955 rd: FpReg::new(6),
6956 rn: FpReg::new(7)
6957 }
6958 .encode(),
6959 0x4EA198E6
6960 );
6961 }
6962 #[test]
6963 fn frinta_4s_v0_v1() {
6964 assert_eq!(
6965 Inst::FrintaV4S {
6966 rd: FpReg::new(0),
6967 rn: FpReg::new(1)
6968 }
6969 .encode(),
6970 0x6E218820
6971 );
6972 }
6973 #[test]
6974 fn frinti_4s_v2_v3() {
6975 assert_eq!(
6976 Inst::FrintiV4S {
6977 rd: FpReg::new(2),
6978 rn: FpReg::new(3)
6979 }
6980 .encode(),
6981 0x6EA19862
6982 );
6983 }
6984 #[test]
6985 fn frintn_2d_v0_v0() {
6986 assert_eq!(
6987 Inst::FrintnV2D {
6988 rd: FpReg::new(0),
6989 rn: FpReg::new(0)
6990 }
6991 .encode(),
6992 0x4E618800
6993 );
6994 }
6995 #[test]
6996 fn frintm_2d_v1_v2() {
6997 assert_eq!(
6998 Inst::FrintmV2D {
6999 rd: FpReg::new(1),
7000 rn: FpReg::new(2)
7001 }
7002 .encode(),
7003 0x4E619841
7004 );
7005 }
7006 #[test]
7007 fn frintp_2d_v3_v4() {
7008 assert_eq!(
7009 Inst::FrintpV2D {
7010 rd: FpReg::new(3),
7011 rn: FpReg::new(4)
7012 }
7013 .encode(),
7014 0x4EE18883
7015 );
7016 }
7017 #[test]
7018 fn frintz_2d_v5_v6() {
7019 assert_eq!(
7020 Inst::FrintzV2D {
7021 rd: FpReg::new(5),
7022 rn: FpReg::new(6)
7023 }
7024 .encode(),
7025 0x4EE198C5
7026 );
7027 }
7028 #[test]
7029 fn frinta_2d_v7_v8() {
7030 assert_eq!(
7031 Inst::FrintaV2D {
7032 rd: FpReg::new(7),
7033 rn: FpReg::new(8)
7034 }
7035 .encode(),
7036 0x6E618907
7037 );
7038 }
7039 #[test]
7040 fn frinti_2d_v9_v10() {
7041 assert_eq!(
7042 Inst::FrintiV2D {
7043 rd: FpReg::new(9),
7044 rn: FpReg::new(10)
7045 }
7046 .encode(),
7047 0x6EE19949
7048 );
7049 }
7050 #[test]
7051 fn mov_16b_v0_v2() {
7052 assert_eq!(
7053 Inst::MovV16B {
7054 rd: FpReg::new(0),
7055 rn: FpReg::new(2)
7056 }
7057 .encode(),
7058 0x4EA21C40
7059 );
7060 }
7061 #[test]
7062 fn mov_8b_v1_v3() {
7063 assert_eq!(
7064 Inst::MovV8B {
7065 rd: FpReg::new(1),
7066 rn: FpReg::new(3)
7067 }
7068 .encode(),
7069 0x0EA31C61
7070 );
7071 }
7072 #[test]
7073 fn mov_4s_v4_v5() {
7074 assert_eq!(
7075 Inst::MovV4S {
7076 rd: FpReg::new(4),
7077 rn: FpReg::new(5)
7078 }
7079 .encode(),
7080 0x4EA51CA4
7081 );
7082 }
7083 #[test]
7084 fn mov_2d_v6_v7() {
7085 assert_eq!(
7086 Inst::MovV2D {
7087 rd: FpReg::new(6),
7088 rn: FpReg::new(7)
7089 }
7090 .encode(),
7091 0x4EA71CE6
7092 );
7093 }
7094 #[test]
7095 fn and_16b_v6_v7_v8() {
7096 assert_eq!(
7097 Inst::AndV16B {
7098 rd: FpReg::new(6),
7099 rn: FpReg::new(7),
7100 rm: FpReg::new(8)
7101 }
7102 .encode(),
7103 0x4E281CE6
7104 );
7105 }
7106 #[test]
7107 fn bic_16b_v5_v6_v7() {
7108 assert_eq!(
7109 Inst::BicV16B {
7110 rd: FpReg::new(5),
7111 rn: FpReg::new(6),
7112 rm: FpReg::new(7)
7113 }
7114 .encode(),
7115 0x4E671CC5
7116 );
7117 }
7118 #[test]
7119 fn bif_16b_v0_v1_v2() {
7120 assert_eq!(
7121 Inst::BifV16B {
7122 rd: FpReg::new(0),
7123 rn: FpReg::new(1),
7124 rm: FpReg::new(2)
7125 }
7126 .encode(),
7127 0x6EE21C20
7128 );
7129 }
7130 #[test]
7131 fn bit_16b_v3_v4_v5() {
7132 assert_eq!(
7133 Inst::BitV16B {
7134 rd: FpReg::new(3),
7135 rn: FpReg::new(4),
7136 rm: FpReg::new(5)
7137 }
7138 .encode(),
7139 0x6EA51C83
7140 );
7141 }
7142 #[test]
7143 fn bsl_16b_v6_v7_v8() {
7144 assert_eq!(
7145 Inst::BslV16B {
7146 rd: FpReg::new(6),
7147 rn: FpReg::new(7),
7148 rm: FpReg::new(8)
7149 }
7150 .encode(),
7151 0x6E681CE6
7152 );
7153 }
7154 #[test]
7155 fn cmeq_4s_v0_v0_v1() {
7156 assert_eq!(
7157 Inst::CmeqV4S {
7158 rd: FpReg::new(0),
7159 rn: FpReg::new(0),
7160 rm: FpReg::new(1)
7161 }
7162 .encode(),
7163 0x6EA18C00
7164 );
7165 }
7166 #[test]
7167 fn fcmeq_4s_v0_v1_v2() {
7168 assert_eq!(
7169 Inst::FcmeqV4S {
7170 rd: FpReg::new(0),
7171 rn: FpReg::new(1),
7172 rm: FpReg::new(2)
7173 }
7174 .encode(),
7175 0x4E22E420
7176 );
7177 }
7178 #[test]
7179 fn fcmeq_2d_v0_v1_v2() {
7180 assert_eq!(
7181 Inst::FcmeqV2D {
7182 rd: FpReg::new(0),
7183 rn: FpReg::new(1),
7184 rm: FpReg::new(2)
7185 }
7186 .encode(),
7187 0x4E62E420
7188 );
7189 }
7190 #[test]
7191 fn cmhs_4s_v0_v0_v1() {
7192 assert_eq!(
7193 Inst::CmhsV4S {
7194 rd: FpReg::new(0),
7195 rn: FpReg::new(0),
7196 rm: FpReg::new(1)
7197 }
7198 .encode(),
7199 0x6EA13C00
7200 );
7201 }
7202 #[test]
7203 fn cmhi_4s_v2_v3_v4() {
7204 assert_eq!(
7205 Inst::CmhiV4S {
7206 rd: FpReg::new(2),
7207 rn: FpReg::new(3),
7208 rm: FpReg::new(4)
7209 }
7210 .encode(),
7211 0x6EA43462
7212 );
7213 }
7214 #[test]
7215 fn cmge_4s_v5_v6_v7() {
7216 assert_eq!(
7217 Inst::CmgeV4S {
7218 rd: FpReg::new(5),
7219 rn: FpReg::new(6),
7220 rm: FpReg::new(7)
7221 }
7222 .encode(),
7223 0x4EA73CC5
7224 );
7225 }
7226 #[test]
7227 fn fcmge_4s_v3_v4_v5() {
7228 assert_eq!(
7229 Inst::FcmgeV4S {
7230 rd: FpReg::new(3),
7231 rn: FpReg::new(4),
7232 rm: FpReg::new(5)
7233 }
7234 .encode(),
7235 0x6E25E483
7236 );
7237 }
7238 #[test]
7239 fn fcmge_2d_v3_v4_v5() {
7240 assert_eq!(
7241 Inst::FcmgeV2D {
7242 rd: FpReg::new(3),
7243 rn: FpReg::new(4),
7244 rm: FpReg::new(5)
7245 }
7246 .encode(),
7247 0x6E65E483
7248 );
7249 }
7250 #[test]
7251 fn fcmge_2d_zero_v0_v0() {
7252 assert_eq!(
7253 Inst::FcmgeZeroV2D {
7254 rd: FpReg::new(0),
7255 rn: FpReg::new(0)
7256 }
7257 .encode(),
7258 0x6EE0C800
7259 );
7260 }
7261 #[test]
7262 fn cmgt_4s_v2_v3_v4() {
7263 assert_eq!(
7264 Inst::CmgtV4S {
7265 rd: FpReg::new(2),
7266 rn: FpReg::new(3),
7267 rm: FpReg::new(4)
7268 }
7269 .encode(),
7270 0x4EA43462
7271 );
7272 }
7273 #[test]
7274 fn fcmgt_4s_v6_v7_v8() {
7275 assert_eq!(
7276 Inst::FcmgtV4S {
7277 rd: FpReg::new(6),
7278 rn: FpReg::new(7),
7279 rm: FpReg::new(8)
7280 }
7281 .encode(),
7282 0x6EA8E4E6
7283 );
7284 }
7285 #[test]
7286 fn fcmgt_2d_v6_v7_v8() {
7287 assert_eq!(
7288 Inst::FcmgtV2D {
7289 rd: FpReg::new(6),
7290 rn: FpReg::new(7),
7291 rm: FpReg::new(8)
7292 }
7293 .encode(),
7294 0x6EE8E4E6
7295 );
7296 }
7297 #[test]
7298 fn fcmgt_2d_zero_v1_v1() {
7299 assert_eq!(
7300 Inst::FcmgtZeroV2D {
7301 rd: FpReg::new(1),
7302 rn: FpReg::new(1)
7303 }
7304 .encode(),
7305 0x4EE0C821
7306 );
7307 }
7308 #[test]
7309 fn fcmle_2d_zero_v2_v2() {
7310 assert_eq!(
7311 Inst::FcmleZeroV2D {
7312 rd: FpReg::new(2),
7313 rn: FpReg::new(2)
7314 }
7315 .encode(),
7316 0x6EE0D842
7317 );
7318 }
7319 #[test]
7320 fn fcmlt_2d_zero_v3_v3() {
7321 assert_eq!(
7322 Inst::FcmltZeroV2D {
7323 rd: FpReg::new(3),
7324 rn: FpReg::new(3)
7325 }
7326 .encode(),
7327 0x4EE0E863
7328 );
7329 }
7330 #[test]
7331 fn orr_16b_v9_v10_v11() {
7332 assert_eq!(
7333 Inst::OrrV16B {
7334 rd: FpReg::new(9),
7335 rn: FpReg::new(10),
7336 rm: FpReg::new(11)
7337 }
7338 .encode(),
7339 0x4EAB1D49
7340 );
7341 }
7342 #[test]
7343 fn eor_16b_v12_v13_v14() {
7344 assert_eq!(
7345 Inst::EorV16B {
7346 rd: FpReg::new(12),
7347 rn: FpReg::new(13),
7348 rm: FpReg::new(14)
7349 }
7350 .encode(),
7351 0x6E2E1DAC
7352 );
7353 }
7354 #[test]
7355 fn ext_16b_v0_v0_v0_8() {
7356 assert_eq!(
7357 Inst::ExtV16B {
7358 rd: FpReg::new(0),
7359 rn: FpReg::new(0),
7360 rm: FpReg::new(0),
7361 index: 8
7362 }
7363 .encode(),
7364 0x6E004000
7365 );
7366 }
7367 #[test]
7368 fn rev64_4s_v1_v2() {
7369 assert_eq!(
7370 Inst::Rev64V4S {
7371 rd: FpReg::new(1),
7372 rn: FpReg::new(2)
7373 }
7374 .encode(),
7375 0x4EA00841
7376 );
7377 }
7378 #[test]
7379 fn zip1_4s_v0_v0_v1() {
7380 assert_eq!(
7381 Inst::Zip1V4S {
7382 rd: FpReg::new(0),
7383 rn: FpReg::new(0),
7384 rm: FpReg::new(1)
7385 }
7386 .encode(),
7387 0x4E813800
7388 );
7389 }
7390 #[test]
7391 fn zip1_2d_v0_v1_v2() {
7392 assert_eq!(
7393 Inst::Zip1V2D {
7394 rd: FpReg::new(0),
7395 rn: FpReg::new(1),
7396 rm: FpReg::new(2)
7397 }
7398 .encode(),
7399 0x4EC23820
7400 );
7401 }
7402 #[test]
7403 fn zip2_4s_v2_v3_v4() {
7404 assert_eq!(
7405 Inst::Zip2V4S {
7406 rd: FpReg::new(2),
7407 rn: FpReg::new(3),
7408 rm: FpReg::new(4)
7409 }
7410 .encode(),
7411 0x4E847862
7412 );
7413 }
7414 #[test]
7415 fn zip2_2d_v3_v4_v5() {
7416 assert_eq!(
7417 Inst::Zip2V2D {
7418 rd: FpReg::new(3),
7419 rn: FpReg::new(4),
7420 rm: FpReg::new(5)
7421 }
7422 .encode(),
7423 0x4EC57883
7424 );
7425 }
7426 #[test]
7427 fn uzp1_4s_v5_v6_v7() {
7428 assert_eq!(
7429 Inst::Uzp1V4S {
7430 rd: FpReg::new(5),
7431 rn: FpReg::new(6),
7432 rm: FpReg::new(7)
7433 }
7434 .encode(),
7435 0x4E8718C5
7436 );
7437 }
7438 #[test]
7439 fn uzp1_2d_v6_v7_v8() {
7440 assert_eq!(
7441 Inst::Uzp1V2D {
7442 rd: FpReg::new(6),
7443 rn: FpReg::new(7),
7444 rm: FpReg::new(8)
7445 }
7446 .encode(),
7447 0x4EC818E6
7448 );
7449 }
7450 #[test]
7451 fn uzp2_4s_v8_v9_v10() {
7452 assert_eq!(
7453 Inst::Uzp2V4S {
7454 rd: FpReg::new(8),
7455 rn: FpReg::new(9),
7456 rm: FpReg::new(10)
7457 }
7458 .encode(),
7459 0x4E8A5928
7460 );
7461 }
7462 #[test]
7463 fn uzp2_2d_v9_v10_v11() {
7464 assert_eq!(
7465 Inst::Uzp2V2D {
7466 rd: FpReg::new(9),
7467 rn: FpReg::new(10),
7468 rm: FpReg::new(11)
7469 }
7470 .encode(),
7471 0x4ECB5949
7472 );
7473 }
7474 #[test]
7475 fn trn1_4s_v11_v12_v13() {
7476 assert_eq!(
7477 Inst::Trn1V4S {
7478 rd: FpReg::new(11),
7479 rn: FpReg::new(12),
7480 rm: FpReg::new(13)
7481 }
7482 .encode(),
7483 0x4E8D298B
7484 );
7485 }
7486 #[test]
7487 fn trn1_2d_v12_v13_v14() {
7488 assert_eq!(
7489 Inst::Trn1V2D {
7490 rd: FpReg::new(12),
7491 rn: FpReg::new(13),
7492 rm: FpReg::new(14)
7493 }
7494 .encode(),
7495 0x4ECE29AC
7496 );
7497 }
7498 #[test]
7499 fn trn2_4s_v3_v4_v5() {
7500 assert_eq!(
7501 Inst::Trn2V4S {
7502 rd: FpReg::new(3),
7503 rn: FpReg::new(4),
7504 rm: FpReg::new(5)
7505 }
7506 .encode(),
7507 0x4E856883
7508 );
7509 }
7510 #[test]
7511 fn trn2_2d_v15_v16_v17() {
7512 assert_eq!(
7513 Inst::Trn2V2D {
7514 rd: FpReg::new(15),
7515 rn: FpReg::new(16),
7516 rm: FpReg::new(17)
7517 }
7518 .encode(),
7519 0x4ED16A0F
7520 );
7521 }
7522 #[test]
7523 fn tbl_16b_v0_v1_v2() {
7524 assert_eq!(
7525 Inst::TblV16B {
7526 rd: FpReg::new(0),
7527 table: FpReg::new(1),
7528 table_len: 1,
7529 index: FpReg::new(2)
7530 }
7531 .encode(),
7532 0x4E020020
7533 );
7534 }
7535 #[test]
7536 fn tbl_16b_v3_v4_v5_v6() {
7537 assert_eq!(
7538 Inst::TblV16B {
7539 rd: FpReg::new(3),
7540 table: FpReg::new(4),
7541 table_len: 2,
7542 index: FpReg::new(6)
7543 }
7544 .encode(),
7545 0x4E062083
7546 );
7547 }
7548 #[test]
7549 fn tbl_16b_v7_v8_v9_v10_v11() {
7550 assert_eq!(
7551 Inst::TblV16B {
7552 rd: FpReg::new(7),
7553 table: FpReg::new(8),
7554 table_len: 3,
7555 index: FpReg::new(11)
7556 }
7557 .encode(),
7558 0x4E0B4107
7559 );
7560 }
7561 #[test]
7562 fn tbl_16b_v12_v13_v14_v15_v16_v17() {
7563 assert_eq!(
7564 Inst::TblV16B {
7565 rd: FpReg::new(12),
7566 table: FpReg::new(13),
7567 table_len: 4,
7568 index: FpReg::new(17)
7569 }
7570 .encode(),
7571 0x4E1161AC
7572 );
7573 }
7574 #[test]
7575 fn tbx_16b_v18_v19_v20() {
7576 assert_eq!(
7577 Inst::TbxV16B {
7578 rd: FpReg::new(18),
7579 table: FpReg::new(19),
7580 table_len: 1,
7581 index: FpReg::new(20)
7582 }
7583 .encode(),
7584 0x4E141272
7585 );
7586 }
7587 #[test]
7588 fn tbx_16b_v21_v22_v23_v24() {
7589 assert_eq!(
7590 Inst::TbxV16B {
7591 rd: FpReg::new(21),
7592 table: FpReg::new(22),
7593 table_len: 2,
7594 index: FpReg::new(24)
7595 }
7596 .encode(),
7597 0x4E1832D5
7598 );
7599 }
7600 #[test]
7601 fn fmov_s1_s2() {
7602 assert_eq!(Inst::FmovRegS { rd: S1, rn: S2 }.encode(), 0x1E204041);
7603 }
7604 #[test]
7605 fn fmov_d1_d2() {
7606 assert_eq!(Inst::FmovRegD { rd: D1, rn: D2 }.encode(), 0x1E604041);
7607 }
7608 #[test]
7609 fn mov_s0_v1_lane2() {
7610 assert_eq!(
7611 Inst::MovFromLaneS {
7612 rd: FpReg::new(0),
7613 rn: FpReg::new(1),
7614 index: 2
7615 }
7616 .encode(),
7617 0x5E140420
7618 );
7619 }
7620 #[test]
7621 fn mov_d3_v4_lane1() {
7622 assert_eq!(
7623 Inst::MovFromLaneD {
7624 rd: FpReg::new(3),
7625 rn: FpReg::new(4),
7626 index: 1
7627 }
7628 .encode(),
7629 0x5E180483
7630 );
7631 }
7632 #[test]
7633 fn mov_s_v5_lane0_from_v6_lane0() {
7634 assert_eq!(
7635 Inst::MovLaneS {
7636 rd: FpReg::new(5),
7637 rd_index: 0,
7638 rn: FpReg::new(6),
7639 rn_index: 0
7640 }
7641 .encode(),
7642 0x6E0404C5
7643 );
7644 }
7645 #[test]
7646 fn mov_d_v7_lane1_from_v8_lane1() {
7647 assert_eq!(
7648 Inst::MovLaneD {
7649 rd: FpReg::new(7),
7650 rd_index: 1,
7651 rn: FpReg::new(8),
7652 rn_index: 1
7653 }
7654 .encode(),
7655 0x6E184507
7656 );
7657 }
7658 #[test]
7659 fn mov_h_v0_lane5_from_v1_lane0() {
7660 assert_eq!(
7661 Inst::MovLaneH {
7662 rd: FpReg::new(0),
7663 rd_index: 5,
7664 rn: FpReg::new(1),
7665 rn_index: 0
7666 }
7667 .encode(),
7668 0x6E160420
7669 );
7670 }
7671 #[test]
7672 fn mov_b_v0_lane7_from_v1_lane0() {
7673 assert_eq!(
7674 Inst::MovLaneB {
7675 rd: FpReg::new(0),
7676 rd_index: 7,
7677 rn: FpReg::new(1),
7678 rn_index: 0
7679 }
7680 .encode(),
7681 0x6E0F0420
7682 );
7683 }
7684 #[test]
7685 fn mov_s_w0_v1_lane2() {
7686 assert_eq!(
7687 Inst::MovFromLaneGpS {
7688 rd: W0,
7689 rn: FpReg::new(1),
7690 index: 2
7691 }
7692 .encode(),
7693 0x0E143C20
7694 );
7695 }
7696 #[test]
7697 fn mov_d_x0_v1_lane1() {
7698 assert_eq!(
7699 Inst::MovFromLaneGpD {
7700 rd: X0,
7701 rn: FpReg::new(1),
7702 index: 1
7703 }
7704 .encode(),
7705 0x4E183C20
7706 );
7707 }
7708 #[test]
7709 fn umov_h_w1_v2_lane5() {
7710 assert_eq!(
7711 Inst::UmovFromLaneH {
7712 rd: W1,
7713 rn: FpReg::new(2),
7714 index: 5
7715 }
7716 .encode(),
7717 0x0E163C41
7718 );
7719 }
7720 #[test]
7721 fn umov_b_w3_v4_lane7() {
7722 assert_eq!(
7723 Inst::UmovFromLaneB {
7724 rd: W3,
7725 rn: FpReg::new(4),
7726 index: 7
7727 }
7728 .encode(),
7729 0x0E0F3C83
7730 );
7731 }
7732 #[test]
7733 fn smov_h_w1_v2_lane3() {
7734 assert_eq!(
7735 Inst::SmovFromLaneH {
7736 rd: W1,
7737 rn: FpReg::new(2),
7738 index: 3
7739 }
7740 .encode(),
7741 0x0E0E2C41
7742 );
7743 }
7744 #[test]
7745 fn smov_b_w0_v0_lane0() {
7746 assert_eq!(
7747 Inst::SmovFromLaneB {
7748 rd: W0,
7749 rn: FpReg::new(0),
7750 index: 0
7751 }
7752 .encode(),
7753 0x0E012C00
7754 );
7755 }
7756 #[test]
7757 fn mov_s_v5_lane1_w6() {
7758 assert_eq!(
7759 Inst::MovLaneFromGpS {
7760 rd: FpReg::new(5),
7761 rd_index: 1,
7762 rn: W6
7763 }
7764 .encode(),
7765 0x4E0C1CC5
7766 );
7767 }
7768 #[test]
7769 fn mov_d_v0_lane1_x1() {
7770 assert_eq!(
7771 Inst::MovLaneFromGpD {
7772 rd: FpReg::new(0),
7773 rd_index: 1,
7774 rn: X1
7775 }
7776 .encode(),
7777 0x4E181C20
7778 );
7779 }
7780 #[test]
7781 fn mov_h_v7_lane5_w8() {
7782 assert_eq!(
7783 Inst::MovLaneFromGpH {
7784 rd: FpReg::new(7),
7785 rd_index: 5,
7786 rn: W8
7787 }
7788 .encode(),
7789 0x4E161D07
7790 );
7791 }
7792 #[test]
7793 fn mov_b_v9_lane7_w10() {
7794 assert_eq!(
7795 Inst::MovLaneFromGpB {
7796 rd: FpReg::new(9),
7797 rd_index: 7,
7798 rn: W10
7799 }
7800 .encode(),
7801 0x4E0F1D49
7802 );
7803 }
7804 #[test]
7805 fn ld1_s_v0_lane1_x8() {
7806 assert_eq!(
7807 Inst::Ld1LaneS {
7808 rt: FpReg::new(0),
7809 index: 1,
7810 rn: X8
7811 }
7812 .encode(),
7813 0x0D409100
7814 );
7815 }
7816 #[test]
7817 fn ld1_d_v2_lane1_x10() {
7818 assert_eq!(
7819 Inst::Ld1LaneD {
7820 rt: FpReg::new(2),
7821 index: 1,
7822 rn: X10
7823 }
7824 .encode(),
7825 0x4D408542
7826 );
7827 }
7828 #[test]
7829 fn ld1_h_v3_lane5_x11() {
7830 assert_eq!(
7831 Inst::Ld1LaneH {
7832 rt: FpReg::new(3),
7833 index: 5,
7834 rn: X11
7835 }
7836 .encode(),
7837 0x4D404963
7838 );
7839 }
7840 #[test]
7841 fn ld1_b_v4_lane7_x12() {
7842 assert_eq!(
7843 Inst::Ld1LaneB {
7844 rt: FpReg::new(4),
7845 index: 7,
7846 rn: X12
7847 }
7848 .encode(),
7849 0x0D401D84
7850 );
7851 }
7852 #[test]
7853 fn dup_16b_v0_v1_lane15() {
7854 assert_eq!(
7855 Inst::DupV16B {
7856 rd: FpReg::new(0),
7857 rn: FpReg::new(1),
7858 index: 15
7859 }
7860 .encode(),
7861 0x4E1F0420
7862 );
7863 }
7864 #[test]
7865 fn dup_8h_v1_v2_lane5() {
7866 assert_eq!(
7867 Inst::DupV8H {
7868 rd: FpReg::new(1),
7869 rn: FpReg::new(2),
7870 index: 5
7871 }
7872 .encode(),
7873 0x4E160441
7874 );
7875 }
7876 #[test]
7877 fn dup_4s_v3_v4_lane2() {
7878 assert_eq!(
7879 Inst::DupV4S {
7880 rd: FpReg::new(3),
7881 rn: FpReg::new(4),
7882 index: 2
7883 }
7884 .encode(),
7885 0x4E140483
7886 );
7887 }
7888 #[test]
7889 fn dup_2d_v5_v6_lane1() {
7890 assert_eq!(
7891 Inst::DupV2D {
7892 rd: FpReg::new(5),
7893 rn: FpReg::new(6),
7894 index: 1
7895 }
7896 .encode(),
7897 0x4E1804C5
7898 );
7899 }
7900 #[test]
7901 fn fsub_s3_s4_s5() {
7902 assert_eq!(
7903 Inst::FsubS {
7904 rd: S3,
7905 rn: S4,
7906 rm: S5
7907 }
7908 .encode(),
7909 0x1E253883
7910 );
7911 }
7912 #[test]
7913 fn fneg_d0_d1() {
7914 assert_eq!(Inst::FnegD { rd: D0, rn: D1 }.encode(), 0x1E614020);
7915 }
7916 #[test]
7917 fn fabs_d0_d1() {
7918 assert_eq!(Inst::FabsD { rd: D0, rn: D1 }.encode(), 0x1E60C020);
7919 }
7920 #[test]
7921 fn fsqrt_d0_d1() {
7922 assert_eq!(Inst::FsqrtD { rd: D0, rn: D1 }.encode(), 0x1E61C020);
7923 }
7924 #[test]
7925 fn fcmp_d0_d1() {
7926 assert_eq!(Inst::FcmpD { rn: D0, rm: D1 }.encode(), 0x1E612000);
7927 }
7928 #[test]
7929 fn fmov_d2_imm_3_5() {
7930 assert_eq!(Inst::FmovImmD { rd: D2, imm8: 12 }.encode(), 0x1E619002);
7931 }
7932 #[test]
7933 fn fmov_d1_imm_10() {
7934 assert_eq!(Inst::FmovImmD { rd: D1, imm8: 36 }.encode(), 0x1E649001);
7935 }
7936 #[test]
7937 fn fmov_d1_imm_neg_1() {
7938 assert_eq!(Inst::FmovImmD { rd: D1, imm8: 240 }.encode(), 0x1E7E1001);
7939 }
7940 #[test]
7941 fn fcsel_d0_d0_d1_mi() {
7942 assert_eq!(
7943 Inst::FcselD {
7944 rd: D0,
7945 rn: D0,
7946 rm: D1,
7947 cond: Cond::MI
7948 }
7949 .encode(),
7950 0x1E614C00
7951 );
7952 }
7953 #[test]
7954 fn fmadd_d0_d1_d2_d3() {
7955 assert_eq!(
7956 Inst::FmaddD {
7957 rd: D0,
7958 rn: D1,
7959 rm: D2,
7960 ra: D3
7961 }
7962 .encode(),
7963 0x1F420C20
7964 );
7965 }
7966
7967 // Single-precision FP unary/compare/fmadd
7968 #[test]
7969 fn fneg_s0_s1() {
7970 assert_eq!(Inst::FnegS { rd: S0, rn: S1 }.encode(), 0x1E214020);
7971 }
7972 #[test]
7973 fn fabs_s0_s1() {
7974 assert_eq!(Inst::FabsS { rd: S0, rn: S1 }.encode(), 0x1E20C020);
7975 }
7976 #[test]
7977 fn fsqrt_s0_s1() {
7978 assert_eq!(Inst::FsqrtS { rd: S0, rn: S1 }.encode(), 0x1E21C020);
7979 }
7980 #[test]
7981 fn fcmp_s0_s1() {
7982 assert_eq!(Inst::FcmpS { rn: S0, rm: S1 }.encode(), 0x1E212000);
7983 }
7984 #[test]
7985 fn fmov_s2_imm_3_5() {
7986 assert_eq!(Inst::FmovImmS { rd: S2, imm8: 12 }.encode(), 0x1E219002);
7987 }
7988 #[test]
7989 fn fcsel_s0_s0_s1_mi() {
7990 assert_eq!(
7991 Inst::FcselS {
7992 rd: S0,
7993 rn: S0,
7994 rm: S1,
7995 cond: Cond::MI
7996 }
7997 .encode(),
7998 0x1E214C00
7999 );
8000 }
8001 #[test]
8002 fn fmadd_s0_s1_s2_s3() {
8003 assert_eq!(
8004 Inst::FmaddS {
8005 rd: S0,
8006 rn: S1,
8007 rm: S2,
8008 ra: S3
8009 }
8010 .encode(),
8011 0x1F020C20
8012 );
8013 }
8014
8015 // ---- FP / integer conversion ----
8016
8017 #[test]
8018 fn fcvtzs_x0_d1() {
8019 assert_eq!(Inst::FcvtzsD { rd: X0, rn: D1 }.encode(), 0x9E780020);
8020 }
8021 #[test]
8022 fn scvtf_d0_x1() {
8023 assert_eq!(Inst::ScvtfD { rd: D0, rn: X1 }.encode(), 0x9E620020);
8024 }
8025 #[test]
8026 fn fmov_d0_x1() {
8027 assert_eq!(Inst::FmovToD { rd: D0, rn: X1 }.encode(), 0x9E670020);
8028 }
8029 #[test]
8030 fn fmov_s0_w0() {
8031 assert_eq!(Inst::FmovToS { rd: S0, rn: W0 }.encode(), 0x1E270000);
8032 }
8033 #[test]
8034 fn fmov_x0_d1() {
8035 assert_eq!(Inst::FmovFromD { rd: X0, rn: D1 }.encode(), 0x9E660020);
8036 }
8037 #[test]
8038 fn fmov_w0_s0() {
8039 assert_eq!(Inst::FmovFromS { rd: W0, rn: S0 }.encode(), 0x1E260000);
8040 }
8041
8042 // ---- System ----
8043
8044 #[test]
8045 fn svc_0x80() {
8046 assert_eq!(Inst::Svc { imm16: 0x80 }.encode(), 0xD4001001);
8047 }
8048 #[test]
8049 fn nop() {
8050 assert_eq!(Inst::Nop.encode(), 0xD503201F);
8051 }
8052 #[test]
8053 fn yield_() {
8054 assert_eq!(Inst::Yield.encode(), 0xD503203F);
8055 }
8056 #[test]
8057 fn wfe_() {
8058 assert_eq!(Inst::Wfe.encode(), 0xD503205F);
8059 }
8060 #[test]
8061 fn wfi_() {
8062 assert_eq!(Inst::Wfi.encode(), 0xD503207F);
8063 }
8064 #[test]
8065 fn sev_() {
8066 assert_eq!(Inst::Sev.encode(), 0xD503209F);
8067 }
8068 #[test]
8069 fn sevl_() {
8070 assert_eq!(Inst::Sevl.encode(), 0xD50320BF);
8071 }
8072 #[test]
8073 fn dmb_ish() {
8074 assert_eq!(
8075 Inst::Dmb {
8076 option: BarrierOpt::Ish
8077 }
8078 .encode(),
8079 0xD5033BBF
8080 );
8081 }
8082 #[test]
8083 fn dsb_ishst() {
8084 assert_eq!(
8085 Inst::Dsb {
8086 option: BarrierOpt::Ishst
8087 }
8088 .encode(),
8089 0xD5033A9F
8090 );
8091 }
8092 #[test]
8093 fn isb_sy() {
8094 assert_eq!(
8095 Inst::Isb {
8096 option: BarrierOpt::Sy
8097 }
8098 .encode(),
8099 0xD5033FDF
8100 );
8101 }
8102 #[test]
8103 fn brk_1() {
8104 assert_eq!(Inst::Brk { imm16: 1 }.encode(), 0xD4200020);
8105 }
8106 }
8107