1use core::ops::{BitAnd, BitOr, BitXor, Deref, DerefMut};
16use num_traits::{FromPrimitive, ToPrimitive};
17
18use super::{globals::INVALID_ID, support::bitmask_from_bool, types::TypeId};
19#[macro_export]
20macro_rules! define_operand_cast {
21 ($t: ty, $base: ty) => {
22 impl OperandCast for $t {
23 fn as_operand(&self) -> &Operand {
24 (**self).as_operand()
25 }
26
27 fn from_operand(op: &Operand) -> Self {
28 Self(<$base>::from_operand(op))
29 }
30 }
31 };
32}
33
34#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
36#[repr(u32)]
37pub enum OperandType {
38 None = 0,
40 Reg = 1,
42 Mem = 2,
44 RegList = 3,
46 Imm = 4,
48 Label = 5,
50 Sym = 6,
52}
53
54impl core::convert::TryFrom<u32> for OperandType {
55 type Error = ();
56
57 fn try_from(value: u32) -> Result<Self, Self::Error> {
58 match value {
59 0 => Ok(Self::None),
60 1 => Ok(Self::Reg),
61 2 => Ok(Self::Mem),
62 3 => Ok(Self::RegList),
63 4 => Ok(Self::Imm),
64 5 => Ok(Self::Label),
65 6 => Ok(Self::Sym),
66 _ => Err(()),
67 }
68 }
69}
70
71pub type RegMask = u32;
75
76#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
80#[repr(u32)]
81pub enum RegType {
82 None,
84
85 LabelTag,
87 SymTag,
89 PC,
91
92 Gp8Lo,
94
95 Gp8Hi,
97
98 Gp16,
100
101 Gp32,
103
104 Gp64,
106
107 Vec8,
109
110 Vec16,
112
113 Vec32,
115
116 Vec64,
118
119 Vec128,
121
122 Vec256,
124
125 Vec512,
127
128 VecNLen,
130
131 Mask,
133
134 Extra,
136
137 X86SReg,
138 X86CReg,
139 X86DReg,
140 X86St,
141 X86Bnd,
142 X86Tmm,
143 MaxValue = 31,
144}
145
146impl core::convert::TryFrom<u32> for RegType {
147 type Error = ();
148
149 fn try_from(value: u32) -> Result<Self, Self::Error> {
150 match value {
151 0 => Ok(Self::None),
152 1 => Ok(Self::LabelTag),
153 2 => Ok(Self::SymTag),
154 3 => Ok(Self::PC),
155 4 => Ok(Self::Gp8Lo),
156 5 => Ok(Self::Gp8Hi),
157 6 => Ok(Self::Gp16),
158 7 => Ok(Self::Gp32),
159 8 => Ok(Self::Gp64),
160 9 => Ok(Self::Vec8),
161 10 => Ok(Self::Vec16),
162 11 => Ok(Self::Vec32),
163 12 => Ok(Self::Vec64),
164 13 => Ok(Self::Vec128),
165 14 => Ok(Self::Vec256),
166 15 => Ok(Self::Vec512),
167 16 => Ok(Self::VecNLen),
168 17 => Ok(Self::Mask),
169 18 => Ok(Self::Extra),
170 19 => Ok(Self::X86SReg),
171 20 => Ok(Self::X86CReg),
172 21 => Ok(Self::X86DReg),
173 22 => Ok(Self::X86St),
174 23 => Ok(Self::X86Bnd),
175 24 => Ok(Self::X86Tmm),
176 31 => Ok(Self::MaxValue),
177 _ => Err(()),
178 }
179 }
180}
181
182#[allow(non_upper_case_globals)]
183impl RegType {
184 pub const X86Mm: Self = Self::Extra;
185 pub const X86Rip: Self = Self::PC;
186 pub const X86GpbLo: Self = Self::Gp8Lo;
187 pub const X86GpbHi: Self = Self::Gp8Hi;
188 pub const X86Gpw: Self = Self::Gp16;
189 pub const X86Gpd: Self = Self::Gp32;
190 pub const X86Gpq: Self = Self::Gp64;
191 pub const X86Xmm: Self = Self::Vec128;
192 pub const X86Ymm: Self = Self::Vec256;
193 pub const X86Zmm: Self = Self::Vec512;
194 pub const X86KReg: Self = Self::Mask;
195
196 pub const RISCVPC: Self = Self::PC;
197 pub const RISCV64Gp: Self = Self::Gp64;
198 pub const RISCV32Gp: Self = Self::Gp32;
199 pub const RISCVFp: Self = Self::Vec64;
200 pub const RISCVVec: Self = Self::VecNLen;
201}
202
203#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
204#[repr(u32)]
205pub enum RegGroup {
206 Gp = 0,
207 Vec,
208 Mask,
209 ExtraVirt3,
210 PC,
211 X86SReg,
212 X86CReg,
213 X86DReg,
214 X86St,
215 X86Bnd,
216 X86Tmm,
217}
218
219impl core::convert::TryFrom<u32> for RegGroup {
220 type Error = ();
221
222 fn try_from(value: u32) -> Result<Self, Self::Error> {
223 match value {
224 0 => Ok(Self::Gp),
225 1 => Ok(Self::Vec),
226 2 => Ok(Self::Mask),
227 3 => Ok(Self::ExtraVirt3),
228 4 => Ok(Self::PC),
229 5 => Ok(Self::X86SReg),
230 6 => Ok(Self::X86CReg),
231 7 => Ok(Self::X86DReg),
232 8 => Ok(Self::X86St),
233 9 => Ok(Self::X86Bnd),
234 10 => Ok(Self::X86Tmm),
235 _ => Err(()),
236 }
237 }
238}
239
240impl RegGroup {
241 pub const X86K: Self = Self::Mask;
242 pub const X86MM: Self = Self::ExtraVirt3;
243}
244
245#[allow(non_upper_case_globals)]
246impl RegGroup {
247 pub const X86Rip: Self = Self::PC;
248}
249
250#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
251pub struct OperandSignature {
252 pub bits: u32,
253}
254
255impl BitOr for OperandSignature {
256 type Output = Self;
257
258 fn bitor(self, rhs: Self) -> Self::Output {
259 Self {
260 bits: self.bits | rhs.bits,
261 }
262 }
263}
264
265impl BitAnd for OperandSignature {
266 type Output = Self;
267
268 fn bitand(self, rhs: Self) -> Self::Output {
269 Self {
270 bits: self.bits & rhs.bits,
271 }
272 }
273}
274
275impl BitXor for OperandSignature {
276 type Output = Self;
277
278 fn bitxor(self, rhs: Self) -> Self::Output {
279 Self {
280 bits: self.bits ^ rhs.bits,
281 }
282 }
283}
284
285impl From<u32> for OperandSignature {
286 fn from(value: u32) -> Self {
287 Self { bits: value }
288 }
289}
290
291impl OperandSignature {
292 pub const OP_TYPE_SHIFT: u32 = 0;
294 pub const OP_TYPE_MASK: u32 = 0x07u32 << Self::OP_TYPE_SHIFT;
296
297 pub const REG_TYPE_SHIFT: u32 = 3;
299 pub const REG_TYPE_MASK: u32 = 0x1Fu32 << Self::REG_TYPE_SHIFT;
301
302 pub const REG_GROUP_SHIFT: u32 = 8;
304 pub const REG_GROUP_MASK: u32 = 0x0Fu32 << Self::REG_GROUP_SHIFT;
306
307 pub const MEM_BASE_TYPE_SHIFT: u32 = 3;
309 pub const MEM_BASE_TYPE_MASK: u32 = 0x1Fu32 << Self::MEM_BASE_TYPE_SHIFT;
311
312 pub const MEM_INDEX_TYPE_SHIFT: u32 = 8;
314 pub const MEM_INDEX_TYPE_MASK: u32 = 0x1Fu32 << Self::MEM_INDEX_TYPE_SHIFT;
316
317 pub const MEM_BASE_INDEX_SHIFT: u32 = 3;
319 pub const MEM_BASE_INDEX_MASK: u32 = 0x3FFu32 << Self::MEM_BASE_INDEX_SHIFT;
321
322 pub const MEM_REG_HOME_SHIFT: u32 = 13;
323 pub const MEM_REG_HOME_FLAG: u32 = 0x01 << Self::MEM_REG_HOME_SHIFT;
324
325 pub const PREDICATE_SHIFT: u32 = 20;
327 pub const PREDICATE_MASK: u32 = 0x0Fu32 << Self::PREDICATE_SHIFT;
329
330 pub const SIZE_SHIFT: u32 = 24;
332 pub const SIZE_MASK: u32 = 0xFFu32 << Self::SIZE_SHIFT;
334
335 pub const fn new(bits: u32) -> Self {
336 Self { bits }
337 }
338
339 pub const fn subset(&self, mask: u32) -> Self {
340 Self {
341 bits: self.bits & mask,
342 }
343 }
344}
345
346impl OperandSignature {
347 pub fn reset(&mut self) {
348 self.bits = 0;
349 }
350
351 pub const fn bits(&self) -> u32 {
352 self.bits
353 }
354
355 pub fn set_bits(&mut self, bits: u32) {
356 self.bits = bits;
357 }
358
359 pub const fn has_field<const K_FIELD_MASK: u32>(&self) -> bool {
360 (self.bits & K_FIELD_MASK) != 0
361 }
362
363 pub const fn has_value<const K_FIELD_MASK: u32>(&self, value: u32) -> bool {
364 (self.bits & K_FIELD_MASK) != value << K_FIELD_MASK.trailing_zeros()
365 }
366
367 pub const fn from_bits(bits: u32) -> Self {
368 OperandSignature { bits }
369 }
370
371 pub const fn from_value<const K_FIELD_MASK: u32>(value: u32) -> Self {
372 OperandSignature {
373 bits: value << K_FIELD_MASK.trailing_zeros(),
374 }
375 }
376
377 pub const fn from_op_type(op_type: OperandType) -> Self {
378 OperandSignature {
379 bits: (op_type as u32) << Self::OP_TYPE_SHIFT,
380 }
381 }
382
383 pub const fn from_reg_type(reg_type: RegType) -> Self {
384 OperandSignature {
385 bits: (reg_type as u32) << Self::REG_TYPE_SHIFT,
386 }
387 }
388
389 pub const fn from_reg_group(reg_group: RegGroup) -> Self {
390 OperandSignature {
391 bits: (reg_group as u32) << Self::REG_GROUP_SHIFT,
392 }
393 }
394
395 pub const fn from_mem_base_type(base_type: RegType) -> Self {
396 OperandSignature {
397 bits: (base_type as u32) << Self::MEM_BASE_TYPE_SHIFT,
398 }
399 }
400
401 pub const fn from_mem_index_type(index_type: RegType) -> Self {
402 OperandSignature {
403 bits: (index_type as u32) << Self::MEM_INDEX_TYPE_SHIFT,
404 }
405 }
406
407 pub const fn from_predicate(predicate: u32) -> Self {
408 OperandSignature {
409 bits: predicate << Self::PREDICATE_SHIFT,
410 }
411 }
412
413 pub const fn from_size(size: u32) -> Self {
414 OperandSignature {
415 bits: size << Self::SIZE_SHIFT,
416 }
417 }
418
419 pub fn set_field<const K_FIELD_MASK: u32>(&mut self, value: u32) {
420 self.bits = (self.bits & !K_FIELD_MASK) | (value << K_FIELD_MASK.trailing_zeros());
421 }
422
423 pub const fn get_field<const K_FIELD_MASK: u32>(&self) -> u32 {
424 (self.bits >> K_FIELD_MASK.trailing_zeros())
425 & (K_FIELD_MASK >> K_FIELD_MASK.trailing_zeros())
426 }
427
428 pub const fn is_valid(&self) -> bool {
429 self.bits != 0
430 }
431
432 pub fn op_type(&self) -> OperandType {
433 OperandType::try_from(self.get_field::<{ Self::OP_TYPE_MASK }>()).unwrap()
434 }
435
436 pub fn reg_type(&self) -> RegType {
437 RegType::try_from(self.get_field::<{ Self::REG_TYPE_MASK }>()).unwrap()
438 }
439
440 pub fn reg_group(&self) -> RegGroup {
441 RegGroup::try_from(self.get_field::<{ Self::REG_GROUP_MASK }>()).unwrap()
442 }
443
444 pub fn mem_base_type(&self) -> RegType {
445 RegType::try_from(self.get_field::<{ Self::MEM_BASE_TYPE_MASK }>()).unwrap()
446 }
447
448 pub fn mem_index_type(&self) -> RegType {
449 RegType::try_from(self.get_field::<{ Self::MEM_INDEX_TYPE_MASK }>()).unwrap()
450 }
451
452 pub fn predicate(&self) -> u32 {
453 self.get_field::<{ Self::PREDICATE_MASK }>()
454 }
455
456 pub fn size(&self) -> u32 {
457 self.get_field::<{ Self::SIZE_MASK }>()
458 }
459
460 pub fn set_op_type(&mut self, op_type: OperandType) {
461 self.set_field::<{ Self::OP_TYPE_MASK }>(op_type as _);
462 }
463
464 pub fn set_reg_type(&mut self, reg_type: RegType) {
465 self.set_field::<{ Self::REG_TYPE_MASK }>(reg_type as _);
466 }
467
468 pub fn set_reg_group(&mut self, reg_group: RegGroup) {
469 self.set_field::<{ Self::REG_GROUP_MASK }>(reg_group as _);
470 }
471
472 pub fn set_mem_base_type(&mut self, base_type: RegType) {
473 self.set_field::<{ Self::MEM_BASE_TYPE_MASK }>(base_type as _);
474 }
475
476 pub fn set_mem_index_type(&mut self, index_type: RegType) {
477 self.set_field::<{ Self::MEM_INDEX_TYPE_MASK }>(index_type as _);
478 }
479
480 pub fn set_predicate(&mut self, predicate: u32) {
481 self.set_field::<{ Self::PREDICATE_MASK }>(predicate);
482 }
483
484 pub fn set_size(&mut self, size: u32) {
485 self.set_field::<{ Self::SIZE_MASK }>(size);
486 }
487}
488
489pub const DATA_MEM_INDEX_ID: usize = 0;
490pub const DATA_MEM_OFFSET_LO: usize = 1;
491pub const DATA_IMM_VALUE_LO: usize = if cfg!(target_endian = "little") { 0 } else { 1 };
492pub const DATA_IMM_VALUE_HI: usize = if DATA_IMM_VALUE_LO == 0 { 1 } else { 0 };
493
494pub const VIRT_ID_MIN: u32 = 400;
495pub const VIRT_ID_MAX: u32 = u32::MAX - 1;
496pub const VIRT_ID_COUNT: u32 = VIRT_ID_MAX - VIRT_ID_MIN + 1;
497
498#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
504pub struct Operand {
505 pub signature: OperandSignature,
506 pub base_id: u32,
507 pub data: [u32; 2],
508}
509
510pub const fn is_virt_id(id: u32) -> bool {
511 id - VIRT_ID_MIN < VIRT_ID_COUNT
512}
513
514pub const fn index_to_virt_id(id: u32) -> u32 {
515 id + VIRT_ID_MIN
516}
517
518pub const fn virt_id_to_index(id: u32) -> u32 {
519 id - VIRT_ID_MIN
520}
521
522impl Default for Operand {
523 fn default() -> Self {
524 Self::new()
525 }
526}
527
528impl Operand {
529 pub const fn new() -> Self {
530 Self {
531 base_id: INVALID_ID,
532 signature: OperandSignature::new(0),
533 data: [0; 2],
534 }
535 }
536
537 pub const fn make_reg(sig: OperandSignature, id: u32) -> Self {
538 Self {
539 base_id: id,
540 signature: sig,
541 data: [0; 2],
542 }
543 }
544
545 pub fn reset(&mut self) {
546 self.signature.reset();
547 self.base_id = 0;
548 self.data = [0; 2]
549 }
550
551 pub fn has_signature(&self, other: OperandSignature) -> bool {
552 self.signature == other
553 }
554
555 pub const fn signature(&self) -> OperandSignature {
556 self.signature
557 }
558
559 pub fn set_signature(&mut self, sig: OperandSignature) {
560 self.signature = sig;
561 }
562
563 pub fn set_id(&mut self, id: u32) {
564 self.base_id = id;
565 }
566
567 pub fn op_type(&self) -> OperandType {
568 self.signature.op_type()
569 }
570
571 pub const fn is_none(&self) -> bool {
572 self.signature.bits == 0
573 }
574
575 pub fn is_reg(&self) -> bool {
576 self.op_type() == OperandType::Reg
577 }
578
579 pub fn is_reg_list(&self) -> bool {
580 self.op_type() == OperandType::RegList
581 }
582
583 pub fn is_mem(&self) -> bool {
584 self.op_type() == OperandType::Mem
585 }
586
587 pub fn is_imm(&self) -> bool {
588 self.op_type() == OperandType::Imm
589 }
590
591 pub fn is_label(&self) -> bool {
592 self.op_type() == OperandType::Label
593 }
594
595 pub fn is_sym(&self) -> bool {
596 self.op_type() == OperandType::Sym
597 }
598
599 pub fn is_phys_reg(&self) -> bool {
600 self.is_reg() && self.base_id < 0xff
601 }
602
603 pub fn is_virt_reg(&self) -> bool {
604 self.is_reg() && self.base_id > 0xff
605 }
606
607 pub const fn id(&self) -> u32 {
608 self.base_id
609 }
610
611 pub fn is_reg_type_of(&self, typ: RegType) -> bool {
612 self.signature
613 .subset(OperandSignature::OP_TYPE_MASK | OperandSignature::REG_TYPE_MASK)
614 == OperandSignature::from_reg_type(typ)
615 | OperandSignature::from_op_type(OperandType::Reg)
616 }
617
618 pub fn is_reg_group_of(&self, group: RegGroup) -> bool {
619 self.signature
620 .subset(OperandSignature::OP_TYPE_MASK | OperandSignature::REG_GROUP_MASK)
621 == OperandSignature::from_reg_group(group)
622 | OperandSignature::from_op_type(OperandType::Reg)
623 }
624
625 pub fn is_gp(&self) -> bool {
626 self.is_reg_group_of(RegGroup::Gp)
627 }
628
629 pub fn is_gp32(&self) -> bool {
630 self.is_reg_type_of(RegType::Gp32)
631 }
632
633 pub fn is_gp64(&self) -> bool {
634 self.is_reg_type_of(RegType::Gp64)
635 }
636
637 pub fn is_vec(&self) -> bool {
638 self.is_reg_group_of(RegGroup::Vec)
639 }
640
641 pub fn is_vec8(&self) -> bool {
642 self.is_reg_type_of(RegType::Vec8)
643 }
644
645 pub fn is_vec16(&self) -> bool {
646 self.is_reg_type_of(RegType::Vec16)
647 }
648
649 pub fn is_vec32(&self) -> bool {
650 self.is_reg_type_of(RegType::Vec32)
651 }
652
653 pub fn is_vec64(&self) -> bool {
654 self.is_reg_type_of(RegType::Vec64)
655 }
656
657 pub fn is_vec128(&self) -> bool {
658 self.is_reg_type_of(RegType::Vec128)
659 }
660
661 pub fn is_vec256(&self) -> bool {
662 self.is_reg_type_of(RegType::Vec256)
663 }
664
665 pub fn is_vec512(&self) -> bool {
666 self.is_reg_type_of(RegType::Vec512)
667 }
668
669 pub fn is_mask(&self) -> bool {
670 self.is_reg_group_of(RegGroup::Mask)
671 }
672
673 pub fn is_reg_list_of(&self, typ: RegType) -> bool {
674 self.signature
675 .subset(OperandSignature::OP_TYPE_MASK | OperandSignature::REG_TYPE_MASK)
676 == OperandSignature::from_reg_type(typ)
677 }
678
679 pub fn is_reg_or_mem(&self) -> bool {
680 self.op_type() >= OperandType::Reg && self.op_type() <= OperandType::Mem
681 }
682
683 pub fn is_reg_or_reg_list_or_mem(&self) -> bool {
684 self.op_type() >= OperandType::RegList && self.op_type() <= OperandType::RegList
685 }
686
687 pub fn x86_rm_size(&self) -> u32 {
688 self.signature.size()
689 }
690}
691
692#[derive(Clone, Copy, PartialEq, Eq, Hash)]
693pub struct Label(pub Operand);
694
695impl Deref for Label {
696 type Target = Operand;
697
698 fn deref(&self) -> &Self::Target {
699 &self.0
700 }
701}
702
703impl DerefMut for Label {
704 fn deref_mut(&mut self) -> &mut Self::Target {
705 &mut self.0
706 }
707}
708
709impl core::fmt::Debug for Label {
710 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
711 write!(f, "label{}", self.id())
712 }
713}
714
715impl PartialOrd for Label {
716 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
717 Some(self.cmp(other))
718 }
719}
720
721impl Ord for Label {
722 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
723 self.id().cmp(&other.id())
724 }
725}
726
727define_operand_cast!(Label, Operand);
728
729impl Default for Label {
730 fn default() -> Self {
731 Self::new()
732 }
733}
734
735impl Label {
736 pub const fn new() -> Self {
737 Self(Operand {
738 signature: OperandSignature::from_op_type(OperandType::Label),
739 base_id: INVALID_ID,
740 data: [0; 2],
741 })
742 }
743
744 pub const fn from_id(id: u32) -> Self {
745 Self(Operand {
746 signature: OperandSignature::from_op_type(OperandType::Label),
747 base_id: id,
748 data: [0; 2],
749 })
750 }
751
752 pub const fn is_valid(&self) -> bool {
753 self.0.base_id != INVALID_ID
754 }
755
756 pub fn set_id(&mut self, id: u32) {
757 self.base_id = id;
758 }
759}
760
761#[derive(Clone, Copy, PartialEq, Eq, Hash)]
762pub struct Sym(pub Operand);
763
764impl Deref for Sym {
765 type Target = Operand;
766
767 fn deref(&self) -> &Self::Target {
768 &self.0
769 }
770}
771
772impl DerefMut for Sym {
773 fn deref_mut(&mut self) -> &mut Self::Target {
774 &mut self.0
775 }
776}
777
778impl core::fmt::Debug for Sym {
779 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
780 write!(f, "sym{}", self.id())
781 }
782}
783
784impl PartialOrd for Sym {
785 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
786 Some(self.cmp(other))
787 }
788}
789
790impl Ord for Sym {
791 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
792 self.id().cmp(&other.id())
793 }
794}
795
796define_operand_cast!(Sym, Operand);
797
798impl Default for Sym {
799 fn default() -> Self {
800 Self::new()
801 }
802}
803
804impl Sym {
805 pub const fn new() -> Self {
806 Self(Operand {
807 signature: OperandSignature::from_op_type(OperandType::Sym),
808 base_id: INVALID_ID,
809 data: [0; 2],
810 })
811 }
812
813 pub const fn from_id(id: u32) -> Self {
814 Self(Operand {
815 signature: OperandSignature::from_op_type(OperandType::Sym),
816 base_id: id,
817 data: [0; 2],
818 })
819 }
820
821 pub const fn is_valid(&self) -> bool {
822 self.0.base_id != INVALID_ID
823 }
824
825 pub fn set_id(&mut self, id: u32) {
826 self.base_id = id;
827 }
828}
829
830#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
831pub struct BaseReg(pub Operand);
832
833impl Deref for BaseReg {
834 type Target = Operand;
835
836 fn deref(&self) -> &Self::Target {
837 &self.0
838 }
839}
840
841impl DerefMut for BaseReg {
842 fn deref_mut(&mut self) -> &mut Self::Target {
843 &mut self.0
844 }
845}
846
847pub const REG_SIGNATURE: OperandSignature = OperandSignature::from_op_type(OperandType::Reg);
848pub const REG_TYPE_NONE: u32 = RegType::None as u32;
849pub const REG_BASE_SIGNATURE_MASK: u32 = OperandSignature::OP_TYPE_MASK
850 | OperandSignature::REG_TYPE_MASK
851 | OperandSignature::REG_GROUP_MASK
852 | OperandSignature::SIZE_MASK;
853
854impl Default for BaseReg {
855 fn default() -> Self {
856 Self::new()
857 }
858}
859
860impl BaseReg {
861 pub const SIGNATURE: u32 = REG_BASE_SIGNATURE_MASK;
862
863 pub const fn new() -> Self {
864 Self(Operand {
865 signature: OperandSignature::from_op_type(OperandType::Reg),
866 base_id: 0xff,
867 data: [0; 2],
868 })
869 }
870
871 pub const fn from_signature_and_id(signature: OperandSignature, id: u32) -> Self {
872 Self(Operand {
873 signature,
874 base_id: id,
875 data: [0; 2],
876 })
877 }
878
879 pub const fn base_signature(&self) -> OperandSignature {
880 OperandSignature {
881 bits: self.0.signature.bits & REG_BASE_SIGNATURE_MASK,
882 }
883 }
884
885 pub fn has_base_signature(&self, signature: impl Into<OperandSignature>) -> bool {
886 self.base_signature().bits == signature.into().bits
887 }
888
889 pub fn is_valid(&self) -> bool {
890 self.signature().is_valid() && self.base_id != 0xff
891 }
892
893 pub fn is_phys_reg(&self) -> bool {
894 self.base_id < 0xff
895 }
896
897 pub fn is_virt_reg(&self) -> bool {
898 self.base_id > 0xff
899 }
900
901 pub fn is_type(&self, typ: RegType) -> bool {
902 self.signature.subset(OperandSignature::REG_TYPE_MASK)
903 == OperandSignature::from_reg_type(typ)
904 }
905
906 pub fn is_group(&self, group: RegGroup) -> bool {
907 self.signature.subset(OperandSignature::REG_GROUP_MASK)
908 == OperandSignature::from_reg_group(group)
909 }
910
911 pub fn is_gp(&self) -> bool {
912 self.is_group(RegGroup::Gp)
913 }
914
915 pub fn is_vec(&self) -> bool {
916 self.is_group(RegGroup::Vec)
917 }
918
919 pub fn is_mask(&self) -> bool {
920 self.is_group(RegGroup::Mask)
921 }
922
923 pub fn operand_is_gp(op: &Operand) -> bool {
924 op.signature()
925 .subset(OperandSignature::OP_TYPE_MASK | OperandSignature::REG_GROUP_MASK)
926 == (OperandSignature::from_op_type(OperandType::Reg)
927 | OperandSignature::from_reg_group(RegGroup::Gp))
928 }
929
930 pub fn operand_is_vec(op: &Operand) -> bool {
931 op.signature()
932 .subset(OperandSignature::OP_TYPE_MASK | OperandSignature::REG_GROUP_MASK)
933 == (OperandSignature::from_op_type(OperandType::Reg)
934 | OperandSignature::from_reg_group(RegGroup::Vec))
935 }
936
937 pub fn operand_is_gp_with_id(op: &Operand, id: u32) -> bool {
938 Self::operand_is_gp(op) && op.id() == id
939 }
940
941 pub fn is_vec_with_id(op: &Operand, id: u32) -> bool {
942 Self::operand_is_vec(op) && op.id() == id
943 }
944
945 pub fn is_reg_of_type(&self, typ: RegType) -> bool {
946 self.is_type(typ)
947 }
948
949 pub fn is_reg_of_type_and_id(&self, typ: RegType, id: u32) -> bool {
950 self.is_type(typ) && self.base_id == id
951 }
952
953 pub fn typ(&self) -> RegType {
954 self.signature.reg_type()
955 }
956
957 pub fn reg_type(&self) -> RegType {
958 self.signature.reg_type()
959 }
960
961 pub fn group(&self) -> RegGroup {
962 self.signature.reg_group()
963 }
964
965 pub fn has_size(&self) -> bool {
966 self.signature
967 .has_field::<{ OperandSignature::SIZE_MASK }>()
968 }
969
970 pub fn size(&self) -> u32 {
971 self.signature.size()
972 }
973
974 pub fn predicate(&self) -> u32 {
975 self.signature.predicate()
976 }
977
978 pub fn set_predicate(&mut self, predicate: u32) {
979 self.signature
980 .set_field::<{ OperandSignature::PREDICATE_MASK }>(predicate);
981 }
982
983 pub fn reset_predicate(&mut self) {
984 self.set_predicate(0);
985 }
986}
987
988pub trait RegTraits {
989 const VALID: u32 = 1;
990 const TYPE: RegType;
991 const GROUP: RegGroup;
992 const SIZE: u32;
993 const TYPE_ID: TypeId;
994
995 const SIGNATURE: u32 = OperandSignature::from_op_type(OperandType::Reg).bits
996 | OperandSignature::from_reg_type(Self::TYPE).bits
997 | OperandSignature::from_reg_group(Self::GROUP).bits
998 | OperandSignature::from_size(Self::SIZE).bits;
999}
1000
1001#[macro_export]
1002macro_rules! define_abstract_reg {
1003 ($reg: ty, $base: ty) => {
1004 impl Default for $reg {
1005 fn default() -> Self {
1006 Self::new()
1007 }
1008 }
1009
1010 impl $reg {
1011 pub const fn new() -> Self {
1012 Self(<$base>::from_signature_and_id(
1013 OperandSignature {
1014 bits: <$base>::SIGNATURE,
1015 },
1016 0xff,
1017 ))
1018 }
1019
1020 pub const fn from_signature_and_id(signature: OperandSignature, id: u32) -> Self {
1021 Self(<$base>::from_signature_and_id(signature, id))
1022 }
1023
1024 pub const fn from_type_and_id(typ: RegType, id: u32) -> Self {
1025 Self::from_signature_and_id(Self::signature_of(typ), id)
1026 }
1027 }
1028
1029 define_operand_cast!($reg, $base);
1030 };
1031}
1032
1033#[macro_export]
1034macro_rules! define_final_reg {
1035 ($reg: ty, $base: ty, $traits: ty) => {
1036 define_abstract_reg!($reg, $base);
1037 impl $reg {
1038 pub const THIS_TYPE: RegType = <$traits>::TYPE;
1039 pub const THIS_GROUP: RegGroup = <$traits>::GROUP;
1040 pub const THIS_SIZE: u32 = <$traits>::SIZE;
1041 pub const SIGNATURE: u32 = <$traits>::SIGNATURE;
1042
1043 pub const fn from_id(id: u32) -> Self {
1044 Self(<$base>::from_signature_and_id(
1045 OperandSignature::new(Self::SIGNATURE),
1046 id,
1047 ))
1048 }
1049 }
1050 };
1051}
1052
1053#[macro_export]
1054macro_rules! define_reg_traits {
1055 ($reg_type: ident, $group: path, $size: expr, $type_id: path) => {
1056 pub struct $reg_type;
1057
1058 impl RegTraits for $reg_type {
1059 const TYPE: RegType = RegType::$reg_type;
1060 const GROUP: RegGroup = $group;
1061 const SIZE: u32 = $size;
1062 const TYPE_ID: TypeId = $type_id;
1063 }
1064 };
1065}
1066
1067pub trait OperandCast {
1070 fn as_operand(&self) -> &Operand;
1071 fn from_operand(op: &Operand) -> Self;
1072}
1073
1074impl OperandCast for Operand {
1075 fn as_operand(&self) -> &Operand {
1076 self
1077 }
1078
1079 fn from_operand(op: &Operand) -> Self {
1080 *op
1081 }
1082}
1083
1084define_operand_cast!(BaseReg, Operand);
1085
1086impl Operand {
1087 pub fn as_<T>(&self) -> T
1088 where
1089 T: OperandCast,
1090 {
1091 T::from_operand(self)
1092 }
1093}
1094
1095#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
1096pub struct BaseMem(pub Operand);
1097
1098impl Deref for BaseMem {
1099 type Target = Operand;
1100
1101 fn deref(&self) -> &Self::Target {
1102 &self.0
1103 }
1104}
1105
1106impl DerefMut for BaseMem {
1107 fn deref_mut(&mut self) -> &mut Self::Target {
1108 &mut self.0
1109 }
1110}
1111
1112define_operand_cast!(BaseMem, Operand);
1113
1114impl Default for BaseMem {
1115 fn default() -> Self {
1116 Self::new()
1117 }
1118}
1119
1120impl BaseMem {
1121 pub fn from_base_disp(base_reg: impl AsRef<BaseReg>, offset: i32) -> Self {
1122 let base = base_reg.as_ref();
1123 Self(Operand {
1124 signature: OperandSignature::from_op_type(OperandType::Mem)
1125 | OperandSignature::from_mem_base_type(base.typ()),
1126 base_id: base.id(),
1127 data: [0, offset as _],
1128 })
1129 }
1130
1131 pub fn from_base_and_index_disp(
1132 u0: OperandSignature,
1133 base_id: u32,
1134 index_id: u32,
1135 offset: i32,
1136 ) -> Self {
1137 Self(Operand {
1138 signature: u0,
1139 base_id,
1140 data: [index_id, offset as _],
1141 })
1142 }
1143
1144 pub fn reset(&mut self) {
1145 self.signature = OperandSignature::from_op_type(OperandType::Mem);
1146 self.base_id = 0;
1147 self.data = [0; 2]
1148 }
1149
1150 pub const fn new() -> Self {
1151 Self(Operand {
1152 signature: OperandSignature::from_op_type(OperandType::Mem),
1153 base_id: 0,
1154 data: [0; 2],
1155 })
1156 }
1157
1158 pub fn is_reg_home(&self) -> bool {
1159 self.signature
1160 .has_field::<{ OperandSignature::MEM_REG_HOME_FLAG }>()
1161 }
1162
1163 pub fn set_reg_home(&mut self) {
1164 self.signature.bits |= OperandSignature::MEM_REG_HOME_FLAG;
1165 }
1166
1167 pub fn clear_reg_home(&mut self) {
1168 self.signature.bits &= !OperandSignature::MEM_REG_HOME_FLAG;
1169 }
1170
1171 pub fn has_base(&self) -> bool {
1172 self.signature.bits & OperandSignature::MEM_BASE_TYPE_MASK != 0
1173 }
1174
1175 pub fn has_index(&self) -> bool {
1176 self.signature.bits & OperandSignature::MEM_INDEX_TYPE_MASK != 0
1177 }
1178
1179 pub fn has_base_or_index(&self) -> bool {
1180 self.has_base() || self.has_index()
1181 }
1182
1183 pub fn has_base_and_index(&self) -> bool {
1184 self.has_base() && self.has_index()
1185 }
1186
1187 pub fn has_base_label(&self) -> bool {
1188 self.signature.subset(OperandSignature::MEM_BASE_TYPE_MASK)
1189 == OperandSignature::from_reg_type(RegType::LabelTag)
1190 }
1191
1192 pub fn has_base_sym(&self) -> bool {
1193 self.signature.subset(OperandSignature::MEM_BASE_TYPE_MASK)
1194 == OperandSignature::from_reg_type(RegType::SymTag)
1195 }
1196
1197 pub fn has_base_reg(&self) -> bool {
1198 self.signature.subset(OperandSignature::MEM_BASE_TYPE_MASK)
1199 > OperandSignature::from_reg_type(RegType::SymTag)
1200 }
1201
1202 pub fn has_index_reg(&self) -> bool {
1203 self.signature.subset(OperandSignature::MEM_INDEX_TYPE_MASK)
1204 > OperandSignature::from_reg_type(RegType::SymTag)
1205 }
1206
1207 pub fn base_type(&self) -> RegType {
1208 self.signature.mem_base_type()
1209 }
1210
1211 pub fn index_type(&self) -> RegType {
1212 self.signature.mem_index_type()
1213 }
1214
1215 pub fn base_id(&self) -> u32 {
1216 self.base_id
1217 }
1218
1219 pub fn index_id(&self) -> u32 {
1220 self.data[DATA_MEM_INDEX_ID]
1221 }
1222
1223 pub fn set_base_type(&mut self, base_type: RegType) {
1224 self.signature.set_mem_base_type(base_type);
1225 }
1226
1227 pub fn set_index_type(&mut self, index_type: RegType) {
1228 self.signature.set_mem_index_type(index_type);
1229 }
1230
1231 pub fn set_base_id(&mut self, id: u32) {
1232 self.base_id = id;
1233 }
1234
1235 pub fn set_index_id(&mut self, id: u32) {
1236 self.data[DATA_MEM_INDEX_ID] = id;
1237 }
1238
1239 pub fn set_base(&mut self, base: &BaseReg) {
1240 let base_reg = base;
1241 self.set_base_type(base_reg.typ());
1242 self.set_base_id(base_reg.id());
1243 }
1244
1245 pub fn set_index(&mut self, index: &BaseReg) {
1246 let index_reg = index;
1247 self.set_index_type(index_reg.typ());
1248 self.set_index_id(index_reg.id());
1249 }
1250 pub fn reset_base(&mut self) {
1251 self.signature.bits &= !OperandSignature::MEM_BASE_TYPE_MASK;
1252 self.base_id = 0;
1253 }
1254
1255 pub fn reset_index(&mut self) {
1256 self.signature.bits &= !OperandSignature::MEM_INDEX_TYPE_MASK;
1257 self.data[DATA_MEM_INDEX_ID] = 0;
1258 }
1259
1260 pub fn is_offset_64bit(&self) -> bool {
1261 self.base_type() == RegType::None
1263 }
1264
1265 pub fn has_offset(&self) -> bool {
1266 (self.data[DATA_MEM_OFFSET_LO] | (self.base_id & bitmask_from_bool(self.is_offset_64bit())))
1267 != 0
1268 }
1269
1270 pub fn offset(&self) -> i64 {
1271 if self.is_offset_64bit() {
1272 (self.data[DATA_MEM_OFFSET_LO] as u64 | (self.base_id as u64) << 32) as i64
1273 } else {
1274 self.data[DATA_MEM_OFFSET_LO] as i32 as i64
1275 }
1276 }
1277 pub fn offset_lo32(&self) -> i32 {
1278 self.data[DATA_MEM_OFFSET_LO] as i32
1279 }
1280
1281 pub fn offset_hi32(&self) -> i32 {
1282 if self.is_offset_64bit() {
1283 self.base_id as i32
1284 } else {
1285 0
1286 }
1287 }
1288 pub fn set_offset(&mut self, offset: i64) {
1289 let lo = (offset as u64 & 0xFFFFFFFF) as u32;
1290 let hi = (offset as u64 >> 32) as u32;
1291 let hi_msk = bitmask_from_bool(self.is_offset_64bit());
1292
1293 self.data[DATA_MEM_OFFSET_LO] = lo;
1294 self.base_id = (hi & hi_msk) | (self.base_id & !hi_msk);
1295 }
1296 pub fn set_offset_lo32(&mut self, offset: i32) {
1297 self.data[DATA_MEM_OFFSET_LO] = offset as u32;
1298 }
1299
1300 pub fn add_offset(&mut self, offset: i64) {
1301 if self.is_offset_64bit() {
1302 self.set_offset(self.offset() + offset);
1303 } else {
1304 self.set_offset_lo32(self.offset_lo32() + offset as i32);
1305 }
1306 }
1307
1308 pub fn add_offset_lo32(&mut self, offset: i32) {
1309 self.set_offset_lo32(self.offset_lo32() + offset);
1310 }
1311
1312 pub fn reset_offset(&mut self) {
1313 self.set_offset(0);
1314 }
1315
1316 pub fn reset_offset_lo32(&mut self) {
1317 self.set_offset_lo32(0);
1318 }
1319}
1320#[derive(Clone, Copy, PartialEq, Eq)]
1321pub enum ImmType {
1322 Int = 0,
1323 Double = 1,
1324}
1325
1326#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
1327pub struct Imm(pub Operand);
1328
1329impl Deref for Imm {
1330 type Target = Operand;
1331
1332 fn deref(&self) -> &Self::Target {
1333 &self.0
1334 }
1335}
1336
1337impl DerefMut for Imm {
1338 fn deref_mut(&mut self) -> &mut Self::Target {
1339 &mut self.0
1340 }
1341}
1342
1343define_operand_cast!(Imm, Operand);
1344
1345impl Default for Imm {
1346 fn default() -> Self {
1347 Self::new()
1348 }
1349}
1350
1351impl Imm {
1352 pub const fn new() -> Self {
1353 Self(Operand {
1354 signature: OperandSignature::from_op_type(OperandType::Imm),
1355 base_id: 0,
1356 data: [0; 2],
1357 })
1358 }
1359 pub fn from_value<T: Into<i64>>(val: T, predicate: u32) -> Self {
1370 let value = val.into();
1371 Self(Operand {
1372 signature: OperandSignature::from_op_type(OperandType::Imm)
1373 | OperandSignature::from_predicate(predicate),
1374 base_id: 0,
1375 data: [value as u32, (value >> 32) as u32],
1376 })
1377 }
1378
1379 pub fn from_float(val: f32, predicate: u32) -> Self {
1380 let mut imm = Self::new();
1381 imm.set_value_float(val);
1382 imm.set_predicate(predicate);
1383 imm
1384 }
1385
1386 pub fn from_double(val: f64, predicate: u32) -> Self {
1387 let mut imm = Self::new();
1388 imm.set_value_float(val);
1389 imm.set_predicate(predicate);
1390 imm
1391 }
1392
1393 pub fn typ(&self) -> ImmType {
1394 if self
1395 .signature()
1396 .get_field::<{ OperandSignature::PREDICATE_MASK }>()
1397 == 0
1398 {
1399 ImmType::Int
1400 } else {
1401 ImmType::Double
1402 }
1403 }
1404
1405 pub fn set_type(&mut self, typ: ImmType) {
1406 self.signature
1407 .set_field::<{ OperandSignature::PREDICATE_MASK }>(typ as u32);
1408 }
1409
1410 pub fn reset_type(&mut self) {
1411 self.set_type(ImmType::Int);
1412 }
1413
1414 pub fn predicate(&self) -> u32 {
1415 self.signature()
1416 .get_field::<{ OperandSignature::PREDICATE_MASK }>()
1417 }
1418
1419 pub fn set_predicate(&mut self, predicate: u32) {
1420 self.signature
1421 .set_field::<{ OperandSignature::PREDICATE_MASK }>(predicate);
1422 }
1423
1424 pub fn reset_predicate(&mut self) {
1425 self.set_predicate(0);
1426 }
1427
1428 pub fn value(&self) -> i64 {
1429 (((self.data[DATA_IMM_VALUE_HI] as u64) << 32) | (self.data[DATA_IMM_VALUE_LO] as u64))
1430 as i64
1431 }
1432
1433 pub fn value_f32(&self) -> f32 {
1434 f32::from_bits(self.data[DATA_IMM_VALUE_LO])
1435 }
1436
1437 pub fn value_f64(&self) -> f64 {
1438 f64::from_bits(
1439 ((self.data[DATA_IMM_VALUE_HI] as u64) << 32) | (self.data[DATA_IMM_VALUE_LO] as u64),
1440 )
1441 }
1442
1443 pub fn is_int(&self) -> bool {
1444 self.typ() == ImmType::Int
1445 }
1446
1447 pub fn is_double(&self) -> bool {
1448 self.typ() == ImmType::Double
1449 }
1450
1451 pub fn is_int8(&self) -> bool {
1452 self.is_int() && (-128..=127).contains(&self.value())
1453 }
1454
1455 pub fn is_uint8(&self) -> bool {
1456 self.is_int() && (0..=255).contains(&self.value())
1457 }
1458
1459 pub fn is_int16(&self) -> bool {
1460 self.is_int() && (-32768..=32767).contains(&self.value())
1461 }
1462
1463 pub fn is_uint16(&self) -> bool {
1464 self.is_int() && (0..=65535).contains(&self.value())
1465 }
1466
1467 pub fn is_int32(&self) -> bool {
1468 self.is_int() && (-2147483648..=2147483647).contains(&self.value())
1469 }
1470
1471 pub fn is_uint32(&self) -> bool {
1472 self.is_int() && self.data[DATA_IMM_VALUE_HI] == 0
1473 }
1474
1475 pub fn value_as<T: FromPrimitive>(&self) -> T {
1476 T::from_i64(self.value()).unwrap()
1477 }
1478
1479 pub fn int32_lo(&self) -> i32 {
1480 self.data[DATA_IMM_VALUE_LO] as i32
1481 }
1482
1483 pub fn int32_hi(&self) -> i32 {
1484 self.data[DATA_IMM_VALUE_HI] as i32
1485 }
1486
1487 pub fn uint32_lo(&self) -> u32 {
1488 self.data[DATA_IMM_VALUE_LO]
1489 }
1490
1491 pub fn uint32_hi(&self) -> u32 {
1492 self.data[DATA_IMM_VALUE_HI]
1493 }
1494
1495 pub fn set_value<T: ToPrimitive>(&mut self, val: T) {
1496 let value = val.to_i64().unwrap();
1497 self.data[DATA_IMM_VALUE_LO] = value as u32;
1498 self.data[DATA_IMM_VALUE_HI] = (value >> 32) as u32;
1499 self.set_type(ImmType::Int);
1500 }
1501 pub fn set_value_float<T: Into<f64>>(&mut self, val: T) {
1502 let value = f64::to_bits(val.into());
1503 self.data[DATA_IMM_VALUE_LO] = value as u32;
1504 self.data[DATA_IMM_VALUE_HI] = (value >> 32) as u32;
1505 self.set_type(ImmType::Double);
1506 }
1507
1508 pub fn sign_extend_8_bits(&mut self) {
1509 self.set_value(self.value_as::<i8>() as i64);
1510 }
1511
1512 pub fn sign_extend_16_bits(&mut self) {
1513 self.set_value(self.value_as::<i16>() as i64);
1514 }
1515
1516 pub fn sign_extend_32_bits(&mut self) {
1517 self.set_value(self.value_as::<i32>() as i64);
1518 }
1519
1520 pub fn zero_extend_8_bits(&mut self) {
1521 self.set_value(self.value_as::<u8>() as u64);
1522 }
1523
1524 pub fn zero_extend_16_bits(&mut self) {
1525 self.set_value(self.value_as::<u16>() as u64);
1526 }
1527
1528 pub fn zero_extend_32_bits(&mut self) {
1529 self.data[DATA_IMM_VALUE_HI] = 0;
1530 }
1531}
1532
1533pub fn imm<T: Into<i64>>(val: T) -> Imm {
1534 Imm::from_value(val, 0)
1535}
1536
1537use core::fmt;
1541
1542impl fmt::Display for OperandType {
1543 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1544 match self {
1545 OperandType::None => write!(f, "None"),
1546 OperandType::Reg => write!(f, "Reg"),
1547 OperandType::Mem => write!(f, "Mem"),
1548 OperandType::RegList => write!(f, "RegList"),
1549 OperandType::Imm => write!(f, "Imm"),
1550 OperandType::Label => write!(f, "Label"),
1551 OperandType::Sym => write!(f, "Sym"),
1552 }
1553 }
1554}
1555
1556impl fmt::Display for RegType {
1557 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1558 match self {
1559 RegType::None => write!(f, "None"),
1560 RegType::LabelTag => write!(f, "LabelTag"),
1561 RegType::SymTag => write!(f, "SymTag"),
1562 RegType::PC => write!(f, "PC"),
1563 RegType::Gp8Lo => write!(f, "Gp8Lo"),
1564 RegType::Gp8Hi => write!(f, "Gp8Hi"),
1565 RegType::Gp16 => write!(f, "Gp16"),
1566 RegType::Gp32 => write!(f, "Gp32"),
1567 RegType::Gp64 => write!(f, "Gp64"),
1568 RegType::Vec8 => write!(f, "Vec8"),
1569 RegType::Vec16 => write!(f, "Vec16"),
1570 RegType::Vec32 => write!(f, "Vec32"),
1571 RegType::Vec64 => write!(f, "Vec64"),
1572 RegType::Vec128 => write!(f, "Vec128"),
1573 RegType::Vec256 => write!(f, "Vec256"),
1574 RegType::Vec512 => write!(f, "Vec512"),
1575 RegType::VecNLen => write!(f, "VecNLen"),
1576 RegType::Mask => write!(f, "Mask"),
1577 RegType::Extra => write!(f, "Extra"),
1578 RegType::X86SReg => write!(f, "X86SReg"),
1579 RegType::X86CReg => write!(f, "X86CReg"),
1580 RegType::X86DReg => write!(f, "X86DReg"),
1581 RegType::X86St => write!(f, "X86St"),
1582 RegType::X86Bnd => write!(f, "X86Bnd"),
1583 RegType::X86Tmm => write!(f, "X86Tmm"),
1584 RegType::MaxValue => write!(f, "MaxValue"),
1585 }
1586 }
1587}
1588
1589impl fmt::Display for RegGroup {
1590 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1591 match self {
1592 RegGroup::Gp => write!(f, "Gp"),
1593 RegGroup::Vec => write!(f, "Vec"),
1594 RegGroup::Mask => write!(f, "Mask"),
1595 RegGroup::ExtraVirt3 => write!(f, "ExtraVirt3"),
1596 RegGroup::PC => write!(f, "PC"),
1597 RegGroup::X86SReg => write!(f, "sreg"),
1598 RegGroup::X86CReg => write!(f, "creg"),
1599 RegGroup::X86DReg => write!(f, "dreg"),
1600 RegGroup::X86St => write!(f, "st"),
1601 RegGroup::X86Bnd => write!(f, "bnd"),
1602 RegGroup::X86Tmm => write!(f, "tmm"),
1603 }
1604 }
1605}
1606
1607impl fmt::Display for Operand {
1608 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1609 match self.op_type() {
1610 OperandType::None => write!(f, "None"),
1611 OperandType::Reg => {
1612 let reg = self.as_::<BaseReg>();
1614 write!(f, "{}", reg)
1615 }
1616 OperandType::Mem => {
1617 let mem = self.as_::<BaseMem>();
1618 write!(f, "{}", mem)
1619 }
1620 OperandType::RegList => write!(f, "RegList"),
1621 OperandType::Imm => {
1622 let imm = self.as_::<Imm>();
1623 write!(f, "{}", imm)
1624 }
1625 OperandType::Label => {
1626 let label = self.as_::<Label>();
1627 write!(f, "{}", label)
1628 }
1629 OperandType::Sym => {
1630 let sym = self.as_::<Sym>();
1631 write!(f, "{}", sym)
1632 }
1633 }
1634 }
1635}
1636
1637impl fmt::Display for Label {
1638 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1639 if self.is_valid() {
1640 write!(f, "label{}", self.id())
1641 } else {
1642 write!(f, "label_invalid")
1643 }
1644 }
1645}
1646
1647impl fmt::Display for Sym {
1648 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1649 if self.is_valid() {
1650 write!(f, "sym{}", self.id())
1651 } else {
1652 write!(f, "sym_invalid")
1653 }
1654 }
1655}
1656
1657impl fmt::Display for BaseReg {
1658 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1659 if !self.is_valid() {
1660 return write!(f, "reg_invalid");
1661 }
1662
1663 match self.typ() {
1665 RegType::Gp8Lo => write!(f, "gp8lo{}", self.id()),
1666 RegType::Gp8Hi => write!(f, "gp8hi{}", self.id()),
1667 RegType::Gp16 => write!(f, "gp16{}", self.id()),
1668 RegType::Gp32 => write!(f, "gp32{}", self.id()),
1669 RegType::Gp64 => write!(f, "gp64{}", self.id()),
1670 RegType::Vec8 => write!(f, "vec8{}", self.id()),
1671 RegType::Vec16 => write!(f, "vec16{}", self.id()),
1672 RegType::Vec32 => write!(f, "vec32{}", self.id()),
1673 RegType::Vec64 => write!(f, "vec64{}", self.id()),
1674 RegType::Vec128 => write!(f, "vec128{}", self.id()),
1675 RegType::Vec256 => write!(f, "vec256{}", self.id()),
1676 RegType::Vec512 => write!(f, "vec512{}", self.id()),
1677 RegType::VecNLen => write!(f, "vecnlen{}", self.id()),
1678 RegType::Mask => write!(f, "mask{}", self.id()),
1679 RegType::X86SReg => write!(f, "sreg{}", self.id()),
1680 RegType::X86CReg => write!(f, "creg{}", self.id()),
1681 RegType::X86DReg => write!(f, "dreg{}", self.id()),
1682 RegType::X86St => write!(f, "st{}", self.id()),
1683 RegType::X86Bnd => write!(f, "bnd{}", self.id()),
1684 RegType::X86Tmm => write!(f, "tmm{}", self.id()),
1685 RegType::PC => write!(f, "pc{}", self.id()),
1686 RegType::Extra => write!(f, "extra{}", self.id()),
1687 RegType::MaxValue => write!(f, "maxvalue"),
1688 RegType::None | RegType::LabelTag | RegType::SymTag => {
1689 write!(f, "reg{}", self.id())
1690 }
1691 }
1692 }
1693}
1694
1695impl fmt::Display for BaseMem {
1696 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1697 use alloc::format;
1698 let mut parts = alloc::vec::Vec::new();
1699
1700 if self.has_base() {
1702 if self.has_base_label() {
1703 parts.push(format!("label{}", self.base_id()));
1704 } else if self.has_base_sym() {
1705 parts.push(format!("sym{}", self.base_id()));
1706 } else if self.has_base_reg() {
1707 let base_reg = BaseReg::from_signature_and_id(
1709 OperandSignature::from_reg_type(self.base_type()),
1710 self.base_id(),
1711 );
1712 parts.push(format!("{}", base_reg));
1713 }
1714 }
1715
1716 if self.has_index() && self.has_index_reg() {
1718 let index_reg = BaseReg::from_signature_and_id(
1719 OperandSignature::from_reg_type(self.index_type()),
1720 self.index_id(),
1721 );
1722 parts.push(format!("{}", index_reg));
1723 }
1724
1725 if self.has_offset() {
1727 let offset = self.offset();
1728 if offset >= 0 {
1729 parts.push(format!("+{}", offset));
1730 } else {
1731 parts.push(format!("{}", offset));
1732 }
1733 }
1734
1735 if parts.is_empty() {
1736 write!(f, "mem[0]")
1737 } else {
1738 write!(f, "mem[{}]", parts.join(" + "))
1739 }
1740 }
1741}
1742
1743impl fmt::Display for Imm {
1744 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1745 match self.typ() {
1746 ImmType::Int => write!(f, "{}", self.value()),
1747 ImmType::Double => write!(f, "{}", self.value_f64()),
1748 }
1749 }
1750}