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