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