1use 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}