Skip to main content

asmkit/aarch64/
operands.rs

1//! AArch64 operands definition.
2use crate::{
3    core::{operand::*, types::TypeId},
4    define_abstract_reg, define_operand_cast,
5};
6
7use core::fmt;
8
9macro_rules! impl_deref_for_wrapper {
10    ($wrapper:ty, $target:ty) => {
11        impl core::ops::Deref for $wrapper {
12            type Target = $target;
13
14            fn deref(&self) -> &Self::Target {
15                &self.0
16            }
17        }
18
19        impl core::ops::DerefMut for $wrapper {
20            fn deref_mut(&mut self) -> &mut Self::Target {
21                &mut self.0
22            }
23        }
24    };
25}
26
27pub struct A64Gpw;
28impl RegTraits for A64Gpw {
29    const TYPE: RegType = RegType::Gp32;
30    const GROUP: RegGroup = RegGroup::Gp;
31    const SIZE: u32 = 4;
32    const TYPE_ID: TypeId = TypeId::Int32;
33}
34
35pub struct A64Gpx;
36impl RegTraits for A64Gpx {
37    const TYPE: RegType = RegType::Gp64;
38    const GROUP: RegGroup = RegGroup::Gp;
39    const SIZE: u32 = 8;
40    const TYPE_ID: TypeId = TypeId::Int64;
41}
42
43pub struct A64VecB;
44impl RegTraits for A64VecB {
45    const TYPE: RegType = RegType::Vec8;
46    const GROUP: RegGroup = RegGroup::Vec;
47    const SIZE: u32 = 1;
48    const TYPE_ID: TypeId = TypeId::Int8;
49}
50
51pub struct A64VecH;
52impl RegTraits for A64VecH {
53    const TYPE: RegType = RegType::Vec16;
54    const GROUP: RegGroup = RegGroup::Vec;
55    const SIZE: u32 = 2;
56    const TYPE_ID: TypeId = TypeId::Int16;
57}
58
59pub struct A64VecS;
60impl RegTraits for A64VecS {
61    const TYPE: RegType = RegType::Vec32;
62    const GROUP: RegGroup = RegGroup::Vec;
63    const SIZE: u32 = 4;
64    const TYPE_ID: TypeId = TypeId::Int32;
65}
66
67pub struct A64VecD;
68impl RegTraits for A64VecD {
69    const TYPE: RegType = RegType::Vec64;
70    const GROUP: RegGroup = RegGroup::Vec;
71    const SIZE: u32 = 8;
72    const TYPE_ID: TypeId = TypeId::Int64;
73}
74
75pub struct A64VecQ;
76impl RegTraits for A64VecQ {
77    const TYPE: RegType = RegType::Vec128;
78    const GROUP: RegGroup = RegGroup::Vec;
79    const SIZE: u32 = 16;
80    const TYPE_ID: TypeId = TypeId::Int32x4;
81}
82
83#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
84pub struct Reg(pub BaseReg);
85
86impl_deref_for_wrapper!(Reg, BaseReg);
87
88define_abstract_reg!(Reg, BaseReg);
89
90impl Reg {
91    pub const fn signature_of(typ: RegType) -> OperandSignature {
92        match typ {
93            RegType::Gp32 => OperandSignature::new(A64Gpw::SIGNATURE),
94            RegType::Gp64 => OperandSignature::new(A64Gpx::SIGNATURE),
95            RegType::Vec8 => OperandSignature::new(A64VecB::SIGNATURE),
96            RegType::Vec16 => OperandSignature::new(A64VecH::SIGNATURE),
97            RegType::Vec32 => OperandSignature::new(A64VecS::SIGNATURE),
98            RegType::Vec64 => OperandSignature::new(A64VecD::SIGNATURE),
99            RegType::Vec128 => OperandSignature::new(A64VecQ::SIGNATURE),
100            _ => OperandSignature::new(0),
101        }
102    }
103
104    pub fn is_gp(&self) -> bool {
105        self.is_group(RegGroup::Gp)
106    }
107
108    pub fn is_gp32(&self) -> bool {
109        self.has_base_signature(A64Gpw::SIGNATURE)
110    }
111
112    pub fn is_gp64(&self) -> bool {
113        self.has_base_signature(A64Gpx::SIGNATURE)
114    }
115
116    pub fn is_vec(&self) -> bool {
117        self.is_group(RegGroup::Vec)
118    }
119
120    pub fn is_vec8(&self) -> bool {
121        self.has_base_signature(A64VecB::SIGNATURE)
122    }
123
124    pub fn is_vec16(&self) -> bool {
125        self.has_base_signature(A64VecH::SIGNATURE)
126    }
127
128    pub fn is_vec32(&self) -> bool {
129        self.has_base_signature(A64VecS::SIGNATURE)
130    }
131
132    pub fn is_vec64(&self) -> bool {
133        self.has_base_signature(A64VecD::SIGNATURE)
134    }
135
136    pub fn is_vec128(&self) -> bool {
137        self.has_base_signature(A64VecQ::SIGNATURE)
138    }
139
140    pub fn set_reg_t<T: RegTraits>(&mut self, rid: u32) {
141        self.set_signature(T::SIGNATURE.into());
142        self.set_id(rid);
143    }
144
145    pub fn set_type_and_id(&mut self, typ: RegType, id: u32) {
146        self.set_signature(Self::signature_of(typ));
147        self.set_id(id);
148    }
149
150    pub const fn group_of_t<T: RegTraits>() -> RegGroup {
151        T::GROUP
152    }
153
154    pub const fn type_id_of_t<T: RegTraits>() -> TypeId {
155        T::TYPE_ID
156    }
157
158    pub fn is_sp(&self) -> bool {
159        self.is_gp() && self.0.0.id() == Gp::ID_SP
160    }
161
162    pub fn is_zr(&self) -> bool {
163        self.is_gp() && self.0.0.id() == Gp::ID_ZR
164    }
165
166    pub const SIGNATURE: u32 = BaseReg::SIGNATURE;
167}
168
169#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
170pub struct Gp(pub Reg);
171
172impl_deref_for_wrapper!(Gp, Reg);
173
174define_abstract_reg!(Gp, Reg);
175
176impl Gp {
177    pub const ID_OS: u32 = 18;
178    pub const ID_FP: u32 = 29;
179    pub const ID_LR: u32 = 30;
180    pub const ID_SP: u32 = 31;
181    pub const ID_ZR: u32 = 63;
182
183    pub const fn signature_of(typ: RegType) -> OperandSignature {
184        Reg::signature_of(typ)
185    }
186
187    pub const fn make_r32(reg_id: u32) -> Self {
188        Self(Reg::from_signature_and_id(
189            OperandSignature::new(A64Gpw::SIGNATURE),
190            reg_id,
191        ))
192    }
193
194    pub const fn make_r64(reg_id: u32) -> Self {
195        Self(Reg::from_signature_and_id(
196            OperandSignature::new(A64Gpx::SIGNATURE),
197            reg_id,
198        ))
199    }
200
201    pub const fn make_w(reg_id: u32) -> Self {
202        Self::make_r32(reg_id)
203    }
204
205    pub const fn make_x(reg_id: u32) -> Self {
206        Self::make_r64(reg_id)
207    }
208
209    pub fn is_zr(&self) -> bool {
210        self.id() == Self::ID_ZR
211    }
212
213    pub fn is_sp(&self) -> bool {
214        self.id() == Self::ID_SP
215    }
216
217    pub fn r32(&self) -> Self {
218        Self::make_r32(self.id())
219    }
220
221    pub fn r64(&self) -> Self {
222        Self::make_r64(self.id())
223    }
224
225    pub fn w(&self) -> Self {
226        self.r32()
227    }
228
229    pub fn x(&self) -> Self {
230        self.r64()
231    }
232
233    pub const SIGNATURE: u32 = Reg::SIGNATURE;
234}
235
236#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
237#[repr(u32)]
238pub enum VecElementType {
239    None = 0,
240    B = 1,
241    H = 2,
242    S = 3,
243    D = 4,
244    B4 = 5,
245    H2 = 6,
246}
247
248#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
249pub struct Vec(pub Reg);
250
251impl_deref_for_wrapper!(Vec, Reg);
252
253define_abstract_reg!(Vec, Reg);
254
255impl Vec {
256    pub const SIGNATURE_REG_ELEMENT_TYPE_SHIFT: u32 = 12;
257    pub const SIGNATURE_REG_ELEMENT_TYPE_MASK: u32 = 0x07 << Self::SIGNATURE_REG_ELEMENT_TYPE_SHIFT;
258
259    pub const SIGNATURE_REG_ELEMENT_FLAG_SHIFT: u32 = 15;
260    pub const SIGNATURE_REG_ELEMENT_FLAG_MASK: u32 = 0x01 << Self::SIGNATURE_REG_ELEMENT_FLAG_SHIFT;
261
262    pub const SIGNATURE_REG_ELEMENT_INDEX_SHIFT: u32 = 16;
263    pub const SIGNATURE_REG_ELEMENT_INDEX_MASK: u32 =
264        0x0F << Self::SIGNATURE_REG_ELEMENT_INDEX_SHIFT;
265
266    pub const SIGNATURE_ELEMENT_B: u32 =
267        (VecElementType::B as u32) << Self::SIGNATURE_REG_ELEMENT_TYPE_SHIFT;
268    pub const SIGNATURE_ELEMENT_H: u32 =
269        (VecElementType::H as u32) << Self::SIGNATURE_REG_ELEMENT_TYPE_SHIFT;
270    pub const SIGNATURE_ELEMENT_S: u32 =
271        (VecElementType::S as u32) << Self::SIGNATURE_REG_ELEMENT_TYPE_SHIFT;
272    pub const SIGNATURE_ELEMENT_D: u32 =
273        (VecElementType::D as u32) << Self::SIGNATURE_REG_ELEMENT_TYPE_SHIFT;
274    pub const SIGNATURE_ELEMENT_B4: u32 =
275        (VecElementType::B4 as u32) << Self::SIGNATURE_REG_ELEMENT_TYPE_SHIFT;
276    pub const SIGNATURE_ELEMENT_H2: u32 =
277        (VecElementType::H2 as u32) << Self::SIGNATURE_REG_ELEMENT_TYPE_SHIFT;
278
279    const fn make_element_access_signature(
280        element_type: VecElementType,
281        element_index: u32,
282    ) -> OperandSignature {
283        OperandSignature::new(
284            A64VecQ::SIGNATURE
285                | Self::SIGNATURE_REG_ELEMENT_FLAG_MASK
286                | ((element_type as u32) << Self::SIGNATURE_REG_ELEMENT_TYPE_SHIFT)
287                | (element_index << Self::SIGNATURE_REG_ELEMENT_INDEX_SHIFT),
288        )
289    }
290
291    pub const fn signature_of(typ: RegType) -> OperandSignature {
292        Reg::signature_of(typ)
293    }
294
295    pub const fn make_v8(reg_id: u32) -> Self {
296        Self(Reg::from_signature_and_id(
297            OperandSignature::new(A64VecB::SIGNATURE),
298            reg_id,
299        ))
300    }
301
302    pub const fn make_v16(reg_id: u32) -> Self {
303        Self(Reg::from_signature_and_id(
304            OperandSignature::new(A64VecH::SIGNATURE),
305            reg_id,
306        ))
307    }
308
309    pub const fn make_v32(reg_id: u32) -> Self {
310        Self(Reg::from_signature_and_id(
311            OperandSignature::new(A64VecS::SIGNATURE),
312            reg_id,
313        ))
314    }
315
316    pub const fn make_v64(reg_id: u32) -> Self {
317        Self(Reg::from_signature_and_id(
318            OperandSignature::new(A64VecD::SIGNATURE),
319            reg_id,
320        ))
321    }
322
323    pub const fn make_v128(reg_id: u32) -> Self {
324        Self(Reg::from_signature_and_id(
325            OperandSignature::new(A64VecQ::SIGNATURE),
326            reg_id,
327        ))
328    }
329
330    pub const fn make_b(reg_id: u32) -> Self {
331        Self::make_v8(reg_id)
332    }
333
334    pub const fn make_h(reg_id: u32) -> Self {
335        Self::make_v16(reg_id)
336    }
337
338    pub const fn make_s(reg_id: u32) -> Self {
339        Self::make_v32(reg_id)
340    }
341
342    pub const fn make_d(reg_id: u32) -> Self {
343        Self::make_v64(reg_id)
344    }
345
346    pub const fn make_q(reg_id: u32) -> Self {
347        Self::make_v128(reg_id)
348    }
349
350    pub const fn make_v32_with_element_type(element_type: VecElementType, reg_id: u32) -> Self {
351        Self(Reg::from_signature_and_id(
352            OperandSignature::new(
353                A64VecS::SIGNATURE
354                    | ((element_type as u32) << Self::SIGNATURE_REG_ELEMENT_TYPE_SHIFT),
355            ),
356            reg_id,
357        ))
358    }
359
360    pub const fn make_v64_with_element_type(element_type: VecElementType, reg_id: u32) -> Self {
361        Self(Reg::from_signature_and_id(
362            OperandSignature::new(
363                A64VecD::SIGNATURE
364                    | ((element_type as u32) << Self::SIGNATURE_REG_ELEMENT_TYPE_SHIFT),
365            ),
366            reg_id,
367        ))
368    }
369
370    pub const fn make_v128_with_element_type(element_type: VecElementType, reg_id: u32) -> Self {
371        Self(Reg::from_signature_and_id(
372            OperandSignature::new(
373                A64VecQ::SIGNATURE
374                    | ((element_type as u32) << Self::SIGNATURE_REG_ELEMENT_TYPE_SHIFT),
375            ),
376            reg_id,
377        ))
378    }
379
380    pub const fn make_v128_with_element_index(
381        element_type: VecElementType,
382        element_index: u32,
383        reg_id: u32,
384    ) -> Self {
385        Self(Reg::from_signature_and_id(
386            Self::make_element_access_signature(element_type, element_index),
387            reg_id,
388        ))
389    }
390
391    pub fn has_element_type_or_index(&self) -> bool {
392        self.0
393			.0
394			.0
395			.signature
396			.has_field::<{ Self::SIGNATURE_REG_ELEMENT_TYPE_MASK | Self::SIGNATURE_REG_ELEMENT_FLAG_MASK }>()
397    }
398
399    pub fn is_vec_b8(&self) -> bool {
400        self.0
401            .0
402            .0
403            .signature
404            .subset(REG_BASE_SIGNATURE_MASK | Self::SIGNATURE_REG_ELEMENT_TYPE_MASK)
405            == OperandSignature::new(A64VecD::SIGNATURE | Self::SIGNATURE_ELEMENT_B)
406    }
407
408    pub fn is_vec_h4(&self) -> bool {
409        self.0
410            .0
411            .0
412            .signature
413            .subset(REG_BASE_SIGNATURE_MASK | Self::SIGNATURE_REG_ELEMENT_TYPE_MASK)
414            == OperandSignature::new(A64VecD::SIGNATURE | Self::SIGNATURE_ELEMENT_H)
415    }
416
417    pub fn is_vec_s2(&self) -> bool {
418        self.0
419            .0
420            .0
421            .signature
422            .subset(REG_BASE_SIGNATURE_MASK | Self::SIGNATURE_REG_ELEMENT_TYPE_MASK)
423            == OperandSignature::new(A64VecD::SIGNATURE | Self::SIGNATURE_ELEMENT_S)
424    }
425
426    pub fn is_vec_d1(&self) -> bool {
427        self.0
428            .0
429            .0
430            .signature
431            .subset(REG_BASE_SIGNATURE_MASK | Self::SIGNATURE_REG_ELEMENT_TYPE_MASK)
432            == OperandSignature::new(A64VecD::SIGNATURE)
433    }
434
435    pub fn is_vec_b16(&self) -> bool {
436        self.0
437            .0
438            .0
439            .signature
440            .subset(REG_BASE_SIGNATURE_MASK | Self::SIGNATURE_REG_ELEMENT_TYPE_MASK)
441            == OperandSignature::new(A64VecQ::SIGNATURE | Self::SIGNATURE_ELEMENT_B)
442    }
443
444    pub fn is_vec_h8(&self) -> bool {
445        self.0
446            .0
447            .0
448            .signature
449            .subset(REG_BASE_SIGNATURE_MASK | Self::SIGNATURE_REG_ELEMENT_TYPE_MASK)
450            == OperandSignature::new(A64VecQ::SIGNATURE | Self::SIGNATURE_ELEMENT_H)
451    }
452
453    pub fn is_vec_s4(&self) -> bool {
454        self.0
455            .0
456            .0
457            .signature
458            .subset(REG_BASE_SIGNATURE_MASK | Self::SIGNATURE_REG_ELEMENT_TYPE_MASK)
459            == OperandSignature::new(A64VecQ::SIGNATURE | Self::SIGNATURE_ELEMENT_S)
460    }
461
462    pub fn is_vec_d2(&self) -> bool {
463        self.0
464            .0
465            .0
466            .signature
467            .subset(REG_BASE_SIGNATURE_MASK | Self::SIGNATURE_REG_ELEMENT_TYPE_MASK)
468            == OperandSignature::new(A64VecQ::SIGNATURE | Self::SIGNATURE_ELEMENT_D)
469    }
470
471    pub fn is_vec_b4x4(&self) -> bool {
472        self.0
473            .0
474            .0
475            .signature
476            .subset(REG_BASE_SIGNATURE_MASK | Self::SIGNATURE_REG_ELEMENT_TYPE_MASK)
477            == OperandSignature::new(A64VecQ::SIGNATURE | Self::SIGNATURE_ELEMENT_B4)
478    }
479
480    pub fn is_vec_h2x4(&self) -> bool {
481        self.0
482            .0
483            .0
484            .signature
485            .subset(REG_BASE_SIGNATURE_MASK | Self::SIGNATURE_REG_ELEMENT_TYPE_MASK)
486            == OperandSignature::new(A64VecQ::SIGNATURE | Self::SIGNATURE_ELEMENT_H2)
487    }
488
489    pub fn v8(&self) -> Self {
490        Self::make_v8(self.id())
491    }
492
493    pub fn v16(&self) -> Self {
494        Self::make_v16(self.id())
495    }
496
497    pub fn v32(&self) -> Self {
498        Self::make_v32(self.id())
499    }
500
501    pub fn v64(&self) -> Self {
502        Self::make_v64(self.id())
503    }
504
505    pub fn v128(&self) -> Self {
506        Self::make_v128(self.id())
507    }
508
509    pub fn b(&self) -> Self {
510        self.v8()
511    }
512
513    pub fn h(&self) -> Self {
514        self.v16()
515    }
516
517    pub fn s(&self) -> Self {
518        self.v32()
519    }
520
521    pub fn d(&self) -> Self {
522        self.v64()
523    }
524
525    pub fn q(&self) -> Self {
526        self.v128()
527    }
528
529    pub fn b_at(&self, element_index: u32) -> Self {
530        Self::make_v128_with_element_index(VecElementType::B, element_index, self.id())
531    }
532
533    pub fn h_at(&self, element_index: u32) -> Self {
534        Self::make_v128_with_element_index(VecElementType::H, element_index, self.id())
535    }
536
537    pub fn s_at(&self, element_index: u32) -> Self {
538        Self::make_v128_with_element_index(VecElementType::S, element_index, self.id())
539    }
540
541    pub fn d_at(&self, element_index: u32) -> Self {
542        Self::make_v128_with_element_index(VecElementType::D, element_index, self.id())
543    }
544
545    pub fn h2_at(&self, element_index: u32) -> Self {
546        Self::make_v128_with_element_index(VecElementType::H2, element_index, self.id())
547    }
548
549    pub fn b4_at(&self, element_index: u32) -> Self {
550        Self::make_v128_with_element_index(VecElementType::B4, element_index, self.id())
551    }
552
553    pub fn b8(&self) -> Self {
554        Self::make_v64_with_element_type(VecElementType::B, self.id())
555    }
556
557    pub fn b16(&self) -> Self {
558        Self::make_v128_with_element_type(VecElementType::B, self.id())
559    }
560
561    pub fn h2(&self) -> Self {
562        Self::make_v32_with_element_type(VecElementType::H, self.id())
563    }
564
565    pub fn h4(&self) -> Self {
566        Self::make_v64_with_element_type(VecElementType::H, self.id())
567    }
568
569    pub fn h8(&self) -> Self {
570        Self::make_v128_with_element_type(VecElementType::H, self.id())
571    }
572
573    pub fn s2(&self) -> Self {
574        Self::make_v64_with_element_type(VecElementType::S, self.id())
575    }
576
577    pub fn s4(&self) -> Self {
578        Self::make_v128_with_element_type(VecElementType::S, self.id())
579    }
580
581    pub fn d2(&self) -> Self {
582        Self::make_v128_with_element_type(VecElementType::D, self.id())
583    }
584
585    pub fn has_element_type(&self) -> bool {
586        self.0
587            .0
588            .0
589            .signature
590            .has_field::<{ Self::SIGNATURE_REG_ELEMENT_TYPE_MASK }>()
591    }
592
593    pub fn element_type(&self) -> VecElementType {
594        match self
595            .0
596            .0
597            .0
598            .signature
599            .get_field::<{ Self::SIGNATURE_REG_ELEMENT_TYPE_MASK }>()
600        {
601            1 => VecElementType::B,
602            2 => VecElementType::H,
603            3 => VecElementType::S,
604            4 => VecElementType::D,
605            5 => VecElementType::B4,
606            6 => VecElementType::H2,
607            _ => VecElementType::None,
608        }
609    }
610
611    pub fn set_element_type(&mut self, element_type: VecElementType) {
612        self.0
613            .0
614            .0
615            .signature
616            .set_field::<{ Self::SIGNATURE_REG_ELEMENT_TYPE_MASK }>(element_type as u32);
617    }
618
619    pub fn reset_element_type(&mut self) {
620        self.0
621            .0
622            .0
623            .signature
624            .set_field::<{ Self::SIGNATURE_REG_ELEMENT_TYPE_MASK }>(0);
625    }
626
627    pub fn has_element_index(&self) -> bool {
628        self.0
629            .0
630            .0
631            .signature
632            .has_field::<{ Self::SIGNATURE_REG_ELEMENT_FLAG_MASK }>()
633    }
634
635    pub fn element_index(&self) -> u32 {
636        self.0
637            .0
638            .0
639            .signature
640            .get_field::<{ Self::SIGNATURE_REG_ELEMENT_INDEX_MASK }>()
641    }
642
643    pub fn set_element_index(&mut self, element_index: u32) {
644        self.0.0.0.signature.bits |= Self::SIGNATURE_REG_ELEMENT_FLAG_MASK;
645        self.0
646            .0
647            .0
648            .signature
649            .set_field::<{ Self::SIGNATURE_REG_ELEMENT_INDEX_MASK }>(element_index);
650    }
651
652    pub fn reset_element_index(&mut self) {
653        self.0.0.0.signature.bits &=
654            !(Self::SIGNATURE_REG_ELEMENT_FLAG_MASK | Self::SIGNATURE_REG_ELEMENT_INDEX_MASK);
655    }
656
657    pub fn at(&self, element_index: u32) -> Self {
658        Self(Reg::from_signature_and_id(
659            OperandSignature::new(
660                (self.0.0.0.signature.bits & !Self::SIGNATURE_REG_ELEMENT_INDEX_MASK)
661                    | (element_index << Self::SIGNATURE_REG_ELEMENT_INDEX_SHIFT)
662                    | Self::SIGNATURE_REG_ELEMENT_FLAG_MASK,
663            ),
664            self.id(),
665        ))
666    }
667
668    pub const SIGNATURE: u32 = Reg::SIGNATURE;
669}
670
671#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
672#[repr(u32)]
673pub enum ShiftOp {
674    LSL = 0,
675    LSR = 1,
676    ASR = 2,
677    ROR = 3,
678    RRX = 4,
679    MSL = 5,
680    UXTB = 6,
681    UXTH = 7,
682    UXTW = 8,
683    UXTX = 9,
684    SXTB = 10,
685    SXTH = 11,
686    SXTW = 12,
687    SXTX = 13,
688}
689
690#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
691pub struct Shift {
692    op: ShiftOp,
693    value: u32,
694}
695
696impl Shift {
697    pub const fn new(op: ShiftOp, value: u32) -> Self {
698        Self { op, value }
699    }
700
701    pub const fn op(&self) -> ShiftOp {
702        self.op
703    }
704
705    pub const fn value(&self) -> u32 {
706        self.value
707    }
708}
709
710impl From<u32> for Shift {
711    fn from(value: u32) -> Self {
712        Self::new(ShiftOp::LSL, value)
713    }
714}
715
716#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
717#[repr(u32)]
718pub enum OffsetMode {
719    Fixed = 0,
720    PreIndex = 1,
721    PostIndex = 2,
722}
723
724#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
725pub struct Mem(pub BaseMem);
726
727impl_deref_for_wrapper!(Mem, BaseMem);
728
729define_operand_cast!(Mem, BaseMem);
730
731type Signature = OperandSignature;
732
733impl Default for Mem {
734    fn default() -> Self {
735        Self::new()
736    }
737}
738
739impl Mem {
740    pub const SIGNATURE_MEM_SHIFT_VALUE_SHIFT: u32 = 14;
741    pub const SIGNATURE_MEM_SHIFT_VALUE_MASK: u32 = 0x1F << Self::SIGNATURE_MEM_SHIFT_VALUE_SHIFT;
742
743    pub const SIGNATURE_MEM_SHIFT_OP_SHIFT: u32 = 20;
744    pub const SIGNATURE_MEM_SHIFT_OP_MASK: u32 = 0x0F << Self::SIGNATURE_MEM_SHIFT_OP_SHIFT;
745
746    pub const SIGNATURE_MEM_OFFSET_MODE_SHIFT: u32 = 24;
747    pub const SIGNATURE_MEM_OFFSET_MODE_MASK: u32 = 0x03 << Self::SIGNATURE_MEM_OFFSET_MODE_SHIFT;
748
749    pub const fn new() -> Self {
750        Self(BaseMem::new())
751    }
752
753    pub fn from_signature_base_and_index_id_disp(
754        signature: OperandSignature,
755        base_id: u32,
756        index_id: u32,
757        offset: i32,
758    ) -> Self {
759        Self(BaseMem::from_base_and_index_disp(
760            signature, base_id, index_id, offset,
761        ))
762    }
763
764    pub fn from_label_and_disp(base: &Label, off: i32, signature: OperandSignature) -> Self {
765        Self(BaseMem::from_base_and_index_disp(
766            Signature::from_op_type(OperandType::Mem)
767                | Signature::from_mem_base_type(RegType::LabelTag)
768                | signature,
769            base.id(),
770            0,
771            off,
772        ))
773    }
774
775    pub fn from_base_and_disp(base: &Reg, off: i32, signature: OperandSignature) -> Self {
776        Self(BaseMem::from_base_and_index_disp(
777            Signature::from_op_type(OperandType::Mem)
778                | Signature::from_mem_base_type(base.typ())
779                | signature,
780            base.id(),
781            0,
782            off,
783        ))
784    }
785
786    pub fn from_base_and_index(base: &Reg, index: &Reg, signature: OperandSignature) -> Self {
787        Self(BaseMem::from_base_and_index_disp(
788            Signature::from_op_type(OperandType::Mem)
789                | Signature::from_mem_base_type(base.typ())
790                | Signature::from_mem_index_type(index.typ())
791                | signature,
792            base.id(),
793            index.id(),
794            0,
795        ))
796    }
797
798    pub fn from_base_and_index_shift(
799        base: &Reg,
800        index: &Reg,
801        shift: impl Into<Shift>,
802        signature: OperandSignature,
803    ) -> Self {
804        let shift = shift.into();
805        Self(BaseMem::from_base_and_index_disp(
806            Signature::from_op_type(OperandType::Mem)
807                | Signature::from_mem_base_type(base.typ())
808                | Signature::from_mem_index_type(index.typ())
809                | Signature::from_value::<{ Self::SIGNATURE_MEM_SHIFT_OP_MASK }>(shift.op() as u32)
810                | Signature::from_value::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift.value())
811                | signature,
812            base.id(),
813            index.id(),
814            0,
815        ))
816    }
817
818    pub fn from_u64(base: u64, signature: OperandSignature) -> Self {
819        Self(BaseMem::from_base_and_index_disp(
820            Signature::from_op_type(OperandType::Mem) | signature,
821            (base >> 32) as u32,
822            0,
823            (base & 0xFFFF_FFFF) as u32 as i32,
824        ))
825    }
826
827    pub fn clone_adjusted(&self, off: i64) -> Self {
828        let mut result = *self;
829        result.add_offset(off);
830        result
831    }
832
833    pub fn pre(&self) -> Self {
834        let mut result = *self;
835        result.set_offset_mode(OffsetMode::PreIndex);
836        result
837    }
838
839    pub fn pre_offset(&self, off: i64) -> Self {
840        let mut result = *self;
841        result.set_offset_mode(OffsetMode::PreIndex);
842        result.add_offset(off);
843        result
844    }
845
846    pub fn post(&self) -> Self {
847        let mut result = *self;
848        result.set_offset_mode(OffsetMode::PostIndex);
849        result
850    }
851
852    pub fn post_offset(&self, off: i64) -> Self {
853        let mut result = *self;
854        result.set_offset_mode(OffsetMode::PostIndex);
855        result.add_offset(off);
856        result
857    }
858
859    pub fn base_reg(&self) -> Reg {
860        Reg::from_type_and_id(self.base_type(), self.base_id())
861    }
862
863    pub fn index_reg(&self) -> Reg {
864        Reg::from_type_and_id(self.index_type(), self.index_id())
865    }
866
867    pub fn set_index(&mut self, index: Reg, shift: impl Into<Shift>) {
868        self.0.set_index(&index.0);
869        self.set_shift(shift);
870    }
871
872    pub fn offset_mode(&self) -> OffsetMode {
873        match self
874            .0
875            .signature
876            .get_field::<{ Self::SIGNATURE_MEM_OFFSET_MODE_MASK }>()
877        {
878            1 => OffsetMode::PreIndex,
879            2 => OffsetMode::PostIndex,
880            _ => OffsetMode::Fixed,
881        }
882    }
883
884    pub fn set_offset_mode(&mut self, mode: OffsetMode) {
885        self.0
886            .signature
887            .set_field::<{ Self::SIGNATURE_MEM_OFFSET_MODE_MASK }>(mode as u32);
888    }
889
890    pub fn reset_offset_mode(&mut self) {
891        self.set_offset_mode(OffsetMode::Fixed);
892    }
893
894    pub fn is_fixed_offset(&self) -> bool {
895        self.offset_mode() == OffsetMode::Fixed
896    }
897
898    pub fn is_pre_or_post(&self) -> bool {
899        self.offset_mode() != OffsetMode::Fixed
900    }
901
902    pub fn is_pre_index(&self) -> bool {
903        self.offset_mode() == OffsetMode::PreIndex
904    }
905
906    pub fn is_post_index(&self) -> bool {
907        self.offset_mode() == OffsetMode::PostIndex
908    }
909
910    pub fn make_pre_index(&mut self) {
911        self.set_offset_mode(OffsetMode::PreIndex);
912    }
913
914    pub fn make_post_index(&mut self) {
915        self.set_offset_mode(OffsetMode::PostIndex);
916    }
917
918    pub fn shift_op(&self) -> ShiftOp {
919        match self
920            .0
921            .signature
922            .get_field::<{ Self::SIGNATURE_MEM_SHIFT_OP_MASK }>()
923        {
924            1 => ShiftOp::LSR,
925            2 => ShiftOp::ASR,
926            3 => ShiftOp::ROR,
927            4 => ShiftOp::RRX,
928            5 => ShiftOp::MSL,
929            6 => ShiftOp::UXTB,
930            7 => ShiftOp::UXTH,
931            8 => ShiftOp::UXTW,
932            9 => ShiftOp::UXTX,
933            10 => ShiftOp::SXTB,
934            11 => ShiftOp::SXTH,
935            12 => ShiftOp::SXTW,
936            13 => ShiftOp::SXTX,
937            _ => ShiftOp::LSL,
938        }
939    }
940
941    pub fn set_shift_op(&mut self, op: ShiftOp) {
942        self.0
943            .signature
944            .set_field::<{ Self::SIGNATURE_MEM_SHIFT_OP_MASK }>(op as u32);
945    }
946
947    pub fn reset_shift_op(&mut self) {
948        self.set_shift_op(ShiftOp::LSL);
949    }
950
951    pub fn has_shift(&self) -> bool {
952        self.0
953            .signature
954            .has_field::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>()
955    }
956
957    pub fn shift(&self) -> u32 {
958        self.0
959            .signature
960            .get_field::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>()
961    }
962
963    pub fn set_shift(&mut self, shift: impl Into<Shift>) {
964        let shift = shift.into();
965        self.set_shift_op(shift.op());
966        self.0
967            .signature
968            .set_field::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift.value());
969    }
970
971    pub fn reset_shift(&mut self) {
972        self.0
973            .signature
974            .set_field::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(0);
975    }
976}
977
978pub mod regs {
979    use super::*;
980
981    pub const fn w(id: u32) -> Gp {
982        Gp::make_r32(id)
983    }
984
985    pub const fn gp32(id: u32) -> Gp {
986        Gp::make_r32(id)
987    }
988
989    pub const fn x(id: u32) -> Gp {
990        Gp::make_r64(id)
991    }
992
993    pub const fn gp64(id: u32) -> Gp {
994        Gp::make_r64(id)
995    }
996
997    pub const fn b(id: u32) -> Vec {
998        Vec::make_v8(id)
999    }
1000
1001    pub const fn h(id: u32) -> Vec {
1002        Vec::make_v16(id)
1003    }
1004
1005    pub const fn s(id: u32) -> Vec {
1006        Vec::make_v32(id)
1007    }
1008
1009    pub const fn d(id: u32) -> Vec {
1010        Vec::make_v64(id)
1011    }
1012
1013    pub const fn q(id: u32) -> Vec {
1014        Vec::make_v128(id)
1015    }
1016
1017    pub const fn v(id: u32) -> Vec {
1018        Vec::make_v128(id)
1019    }
1020
1021    macro_rules! define_reg_consts {
1022		($ctor:ident, $ty:ty, { $($name:ident = $id:expr),* $(,)? }) => {
1023			$(pub const $name: $ty = $ctor($id);)*
1024		};
1025	}
1026
1027    define_reg_consts!(w, Gp, {
1028        w0 = 0, w1 = 1, w2 = 2, w3 = 3, w4 = 4, w5 = 5, w6 = 6, w7 = 7,
1029        w8 = 8, w9 = 9, w10 = 10, w11 = 11, w12 = 12, w13 = 13, w14 = 14, w15 = 15,
1030        w16 = 16, w17 = 17, w18 = 18, w19 = 19, w20 = 20, w21 = 21, w22 = 22, w23 = 23,
1031        w24 = 24, w25 = 25, w26 = 26, w27 = 27, w28 = 28, w29 = 29, w30 = 30,
1032        wzr = Gp::ID_ZR, wsp = Gp::ID_SP
1033    });
1034
1035    define_reg_consts!(x, Gp, {
1036        x0 = 0, x1 = 1, x2 = 2, x3 = 3, x4 = 4, x5 = 5, x6 = 6, x7 = 7,
1037        x8 = 8, x9 = 9, x10 = 10, x11 = 11, x12 = 12, x13 = 13, x14 = 14, x15 = 15,
1038        x16 = 16, x17 = 17, x18 = 18, x19 = 19, x20 = 20, x21 = 21, x22 = 22, x23 = 23,
1039        x24 = 24, x25 = 25, x26 = 26, x27 = 27, x28 = 28, x29 = 29, x30 = 30,
1040        xzr = Gp::ID_ZR, sp = Gp::ID_SP
1041    });
1042
1043    pub const wos: Gp = w(Gp::ID_OS);
1044    pub const wfp: Gp = w(Gp::ID_FP);
1045    pub const wlr: Gp = w(Gp::ID_LR);
1046    pub const os: Gp = x(Gp::ID_OS);
1047    pub const fp: Gp = x(Gp::ID_FP);
1048    pub const lr: Gp = x(Gp::ID_LR);
1049    pub const zr: Gp = x(Gp::ID_ZR);
1050
1051    define_reg_consts!(b, Vec, {
1052        b0 = 0, b1 = 1, b2 = 2, b3 = 3, b4 = 4, b5 = 5, b6 = 6, b7 = 7,
1053        b8 = 8, b9 = 9, b10 = 10, b11 = 11, b12 = 12, b13 = 13, b14 = 14, b15 = 15,
1054        b16 = 16, b17 = 17, b18 = 18, b19 = 19, b20 = 20, b21 = 21, b22 = 22, b23 = 23,
1055        b24 = 24, b25 = 25, b26 = 26, b27 = 27, b28 = 28, b29 = 29, b30 = 30, b31 = 31
1056    });
1057
1058    define_reg_consts!(h, Vec, {
1059        h0 = 0, h1 = 1, h2 = 2, h3 = 3, h4 = 4, h5 = 5, h6 = 6, h7 = 7,
1060        h8 = 8, h9 = 9, h10 = 10, h11 = 11, h12 = 12, h13 = 13, h14 = 14, h15 = 15,
1061        h16 = 16, h17 = 17, h18 = 18, h19 = 19, h20 = 20, h21 = 21, h22 = 22, h23 = 23,
1062        h24 = 24, h25 = 25, h26 = 26, h27 = 27, h28 = 28, h29 = 29, h30 = 30, h31 = 31
1063    });
1064
1065    define_reg_consts!(s, Vec, {
1066        s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6, s7 = 7,
1067        s8 = 8, s9 = 9, s10 = 10, s11 = 11, s12 = 12, s13 = 13, s14 = 14, s15 = 15,
1068        s16 = 16, s17 = 17, s18 = 18, s19 = 19, s20 = 20, s21 = 21, s22 = 22, s23 = 23,
1069        s24 = 24, s25 = 25, s26 = 26, s27 = 27, s28 = 28, s29 = 29, s30 = 30, s31 = 31
1070    });
1071
1072    define_reg_consts!(d, Vec, {
1073        d0 = 0, d1 = 1, d2 = 2, d3 = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7,
1074        d8 = 8, d9 = 9, d10 = 10, d11 = 11, d12 = 12, d13 = 13, d14 = 14, d15 = 15,
1075        d16 = 16, d17 = 17, d18 = 18, d19 = 19, d20 = 20, d21 = 21, d22 = 22, d23 = 23,
1076        d24 = 24, d25 = 25, d26 = 26, d27 = 27, d28 = 28, d29 = 29, d30 = 30, d31 = 31
1077    });
1078
1079    define_reg_consts!(q, Vec, {
1080        q0 = 0, q1 = 1, q2 = 2, q3 = 3, q4 = 4, q5 = 5, q6 = 6, q7 = 7,
1081        q8 = 8, q9 = 9, q10 = 10, q11 = 11, q12 = 12, q13 = 13, q14 = 14, q15 = 15,
1082        q16 = 16, q17 = 17, q18 = 18, q19 = 19, q20 = 20, q21 = 21, q22 = 22, q23 = 23,
1083        q24 = 24, q25 = 25, q26 = 26, q27 = 27, q28 = 28, q29 = 29, q30 = 30, q31 = 31
1084    });
1085
1086    define_reg_consts!(v, Vec, {
1087        v0 = 0, v1 = 1, v2 = 2, v3 = 3, v4 = 4, v5 = 5, v6 = 6, v7 = 7,
1088        v8 = 8, v9 = 9, v10 = 10, v11 = 11, v12 = 12, v13 = 13, v14 = 14, v15 = 15,
1089        v16 = 16, v17 = 17, v18 = 18, v19 = 19, v20 = 20, v21 = 21, v22 = 22, v23 = 23,
1090        v24 = 24, v25 = 25, v26 = 26, v27 = 27, v28 = 28, v29 = 29, v30 = 30, v31 = 31
1091    });
1092}
1093
1094pub use regs::*;
1095
1096pub const fn lsl(value: u32) -> Shift {
1097    Shift::new(ShiftOp::LSL, value)
1098}
1099
1100pub const fn lsr(value: u32) -> Shift {
1101    Shift::new(ShiftOp::LSR, value)
1102}
1103
1104pub const fn asr(value: u32) -> Shift {
1105    Shift::new(ShiftOp::ASR, value)
1106}
1107
1108pub const fn ror(value: u32) -> Shift {
1109    Shift::new(ShiftOp::ROR, value)
1110}
1111
1112pub const fn rrx() -> Shift {
1113    Shift::new(ShiftOp::RRX, 0)
1114}
1115
1116pub const fn msl(value: u32) -> Shift {
1117    Shift::new(ShiftOp::MSL, value)
1118}
1119
1120pub const fn uxtb(value: u32) -> Shift {
1121    Shift::new(ShiftOp::UXTB, value)
1122}
1123
1124pub const fn uxth(value: u32) -> Shift {
1125    Shift::new(ShiftOp::UXTH, value)
1126}
1127
1128pub const fn uxtw(value: u32) -> Shift {
1129    Shift::new(ShiftOp::UXTW, value)
1130}
1131
1132pub const fn uxtx(value: u32) -> Shift {
1133    Shift::new(ShiftOp::UXTX, value)
1134}
1135
1136pub const fn sxtb(value: u32) -> Shift {
1137    Shift::new(ShiftOp::SXTB, value)
1138}
1139
1140pub const fn sxth(value: u32) -> Shift {
1141    Shift::new(ShiftOp::SXTH, value)
1142}
1143
1144pub const fn sxtw(value: u32) -> Shift {
1145    Shift::new(ShiftOp::SXTW, value)
1146}
1147
1148pub const fn sxtx(value: u32) -> Shift {
1149    Shift::new(ShiftOp::SXTX, value)
1150}
1151
1152pub fn ptr(base: Gp, offset: i32) -> Mem {
1153    Mem::from_base_and_disp(&base.0, offset, OperandSignature::new(0))
1154}
1155
1156pub fn ptr_pre(base: Gp, offset: i32) -> Mem {
1157    Mem::from_base_and_disp(
1158        &base.0,
1159        offset,
1160        OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_OFFSET_MODE_MASK }>(
1161            OffsetMode::PreIndex as u32,
1162        ),
1163    )
1164}
1165
1166pub fn ptr_post(base: Gp, offset: i32) -> Mem {
1167    Mem::from_base_and_disp(
1168        &base.0,
1169        offset,
1170        OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_OFFSET_MODE_MASK }>(
1171            OffsetMode::PostIndex as u32,
1172        ),
1173    )
1174}
1175
1176pub fn ptr_reg(base: Gp, index: Gp) -> Mem {
1177    Mem::from_base_and_index(&base.0, &index.0, OperandSignature::new(0))
1178}
1179
1180pub fn ptr_reg_pre(base: Gp, index: Gp) -> Mem {
1181    Mem::from_base_and_index(
1182        &base.0,
1183        &index.0,
1184        OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_OFFSET_MODE_MASK }>(
1185            OffsetMode::PreIndex as u32,
1186        ),
1187    )
1188}
1189
1190pub fn ptr_reg_post(base: Gp, index: Gp) -> Mem {
1191    Mem::from_base_and_index(
1192        &base.0,
1193        &index.0,
1194        OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_OFFSET_MODE_MASK }>(
1195            OffsetMode::PostIndex as u32,
1196        ),
1197    )
1198}
1199
1200pub fn ptr_shift(base: Gp, index: Gp, shift: impl Into<Shift>) -> Mem {
1201    Mem::from_base_and_index_shift(&base.0, &index.0, shift, OperandSignature::new(0))
1202}
1203
1204pub fn label_ptr(base: Label, offset: i32) -> Mem {
1205    Mem::from_label_and_disp(&base, offset, OperandSignature::new(0))
1206}
1207
1208pub fn abs_ptr(base: u64) -> Mem {
1209    Mem::from_u64(base, OperandSignature::new(0))
1210}
1211
1212impl fmt::Display for Reg {
1213    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1214        if !self.is_valid() {
1215            return write!(f, "reg_invalid");
1216        }
1217
1218        if self.is_gp32() || self.is_gp64() {
1219            write!(f, "{}", Gp::from_type_and_id(self.typ(), self.id()))
1220        } else if self.is_vec() {
1221            write!(f, "{}", Vec::from_type_and_id(self.typ(), self.id()))
1222        } else {
1223            write!(f, "reg{}", self.id())
1224        }
1225    }
1226}
1227
1228impl fmt::Display for Gp {
1229    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1230        if !self.is_valid() {
1231            return write!(f, "gp_invalid");
1232        }
1233
1234        if self.is_gp32() {
1235            match self.id() {
1236                Self::ID_SP => write!(f, "wsp"),
1237                Self::ID_ZR => write!(f, "wzr"),
1238                id => write!(f, "w{}", id),
1239            }
1240        } else {
1241            match self.id() {
1242                Self::ID_SP => write!(f, "sp"),
1243                Self::ID_ZR => write!(f, "xzr"),
1244                id => write!(f, "x{}", id),
1245            }
1246        }
1247    }
1248}
1249
1250impl fmt::Display for Vec {
1251    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1252        if !self.is_valid() {
1253            return write!(f, "vec_invalid");
1254        }
1255
1256        if self.has_element_index() {
1257            let suffix = match self.element_type() {
1258                VecElementType::B => "b",
1259                VecElementType::H => "h",
1260                VecElementType::S => "s",
1261                VecElementType::D => "d",
1262                VecElementType::B4 => "b4",
1263                VecElementType::H2 => "h2",
1264                VecElementType::None => "",
1265            };
1266            if suffix.is_empty() {
1267                write!(f, "v{}[{}]", self.id(), self.element_index())
1268            } else {
1269                write!(f, "v{}.{}[{}]", self.id(), suffix, self.element_index())
1270            }
1271        } else if self.has_element_type() {
1272            let suffix = match (self.typ(), self.element_type()) {
1273                (RegType::Vec32, VecElementType::H) => "2h",
1274                (RegType::Vec64, VecElementType::B) => "8b",
1275                (RegType::Vec64, VecElementType::H) => "4h",
1276                (RegType::Vec64, VecElementType::S) => "2s",
1277                (RegType::Vec64, VecElementType::D) | (RegType::Vec64, VecElementType::None) => {
1278                    "1d"
1279                }
1280                (RegType::Vec128, VecElementType::B) => "16b",
1281                (RegType::Vec128, VecElementType::H) => "8h",
1282                (RegType::Vec128, VecElementType::S) => "4s",
1283                (RegType::Vec128, VecElementType::D) => "2d",
1284                (RegType::Vec128, VecElementType::B4) => "4b",
1285                (RegType::Vec128, VecElementType::H2) => "2h",
1286                _ => "",
1287            };
1288
1289            if suffix.is_empty() {
1290                write!(f, "v{}", self.id())
1291            } else {
1292                write!(f, "v{}.{}", self.id(), suffix)
1293            }
1294        } else {
1295            match self.typ() {
1296                RegType::Vec8 => write!(f, "b{}", self.id()),
1297                RegType::Vec16 => write!(f, "h{}", self.id()),
1298                RegType::Vec32 => write!(f, "s{}", self.id()),
1299                RegType::Vec64 => write!(f, "d{}", self.id()),
1300                RegType::Vec128 => write!(f, "v{}", self.id()),
1301                _ => write!(f, "vec{}", self.id()),
1302            }
1303        }
1304    }
1305}
1306
1307impl fmt::Display for Shift {
1308    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1309        let op = match self.op() {
1310            ShiftOp::LSL => "lsl",
1311            ShiftOp::LSR => "lsr",
1312            ShiftOp::ASR => "asr",
1313            ShiftOp::ROR => "ror",
1314            ShiftOp::RRX => "rrx",
1315            ShiftOp::MSL => "msl",
1316            ShiftOp::UXTB => "uxtb",
1317            ShiftOp::UXTH => "uxth",
1318            ShiftOp::UXTW => "uxtw",
1319            ShiftOp::UXTX => "uxtx",
1320            ShiftOp::SXTB => "sxtb",
1321            ShiftOp::SXTH => "sxth",
1322            ShiftOp::SXTW => "sxtw",
1323            ShiftOp::SXTX => "sxtx",
1324        };
1325
1326        if matches!(self.op(), ShiftOp::RRX) {
1327            write!(f, "{}", op)
1328        } else {
1329            write!(f, "{} #{}", op, self.value())
1330        }
1331    }
1332}
1333
1334impl fmt::Display for OffsetMode {
1335    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1336        match self {
1337            OffsetMode::Fixed => write!(f, "fixed"),
1338            OffsetMode::PreIndex => write!(f, "pre-index"),
1339            OffsetMode::PostIndex => write!(f, "post-index"),
1340        }
1341    }
1342}
1343
1344impl fmt::Display for Mem {
1345    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1346        if !self.has_base() && !self.has_index() {
1347            let addr = ((self.base_id() as u64) << 32) | (self.offset() as u32 as u64);
1348            return write!(f, "[0x{addr:x}]");
1349        }
1350
1351        let has_offset = self.has_offset() && self.offset() != 0;
1352        let has_index = self.has_index() && self.has_index_reg();
1353
1354        match self.offset_mode() {
1355            OffsetMode::PostIndex => {
1356                write!(f, "[")?;
1357                if self.has_base_label() {
1358                    write!(f, "label{}", self.base_id())?;
1359                } else {
1360                    write!(f, "{}", self.base_reg())?;
1361                }
1362                write!(f, "]")?;
1363
1364                if has_index {
1365                    write!(f, ", {}", self.index_reg())?;
1366                    if self.has_shift() {
1367                        write!(f, ", {}", Shift::new(self.shift_op(), self.shift()))?;
1368                    }
1369                } else if has_offset {
1370                    write!(f, ", #{}", self.offset())?;
1371                }
1372
1373                Ok(())
1374            }
1375            OffsetMode::Fixed | OffsetMode::PreIndex => {
1376                write!(f, "[")?;
1377                if self.has_base_label() {
1378                    write!(f, "label{}", self.base_id())?;
1379                } else {
1380                    write!(f, "{}", self.base_reg())?;
1381                }
1382
1383                if has_index {
1384                    write!(f, ", {}", self.index_reg())?;
1385                    if self.has_shift() {
1386                        write!(f, ", {}", Shift::new(self.shift_op(), self.shift()))?;
1387                    }
1388                } else if has_offset {
1389                    write!(f, ", #{}", self.offset())?;
1390                }
1391
1392                write!(f, "]")?;
1393
1394                if self.is_pre_index() {
1395                    write!(f, "!")?;
1396                }
1397
1398                Ok(())
1399            }
1400        }
1401    }
1402}