1use derive_more::derive::{BitAnd, BitOr, BitXor, Deref, DerefMut, TryFrom};
2use num_traits::{FromPrimitive, ToPrimitive};
3
4use super::{globals::INVALID_ID, support::bitmask_from_bool, types::TypeId};
5#[macro_export]
6macro_rules! define_operand_cast {
7    ($t: ty, $base: ty) => {
8        impl OperandCast for $t {
9            fn as_operand(&self) -> &Operand {
10                (**self).as_operand()
11            }
12
13            fn from_operand(op: &Operand) -> Self {
14                Self(<$base>::from_operand(op))
15            }
16        }
17    };
18}
19
20#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, derive_more::TryFrom, Debug)]
22#[repr(u32)]
23#[try_from(repr)]
24pub enum OperandType {
25    None = 0,
27    Reg = 1,
29    Mem = 2,
31    RegList = 3,
33    Imm = 4,
35    Label = 5,
37    Sym,
39}
40
41pub type RegMask = u32;
45
46#[derive(TryFrom, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
50#[repr(u32)]
51#[try_from(repr)]
52pub enum RegType {
53    None,
55
56    LabelTag,
58    SymTag,
60    PC,
62
63    Gp8Lo,
65
66    Gp8Hi,
68
69    Gp16,
71
72    Gp32,
74
75    Gp64,
77
78    Vec8,
80
81    Vec16,
83
84    Vec32,
86
87    Vec64,
89
90    Vec128,
92
93    Vec256,
95
96    Vec512,
98
99    VecNLen,
101
102    Mask,
104
105    Extra,
107
108    X86SReg,
109    X86CReg,
110    X86DReg,
111    X86St,
112    X86Bnd,
113    X86Tmm,
114    MaxValue = 31,
115}
116
117#[allow(non_upper_case_globals)]
118impl RegType {
119    pub const X86Mm: Self = Self::Extra;
120    pub const X86Rip: Self = Self::PC;
121    pub const X86GpbLo: Self = Self::Gp8Lo;
122    pub const X86GpbHi: Self = Self::Gp8Hi;
123    pub const X86Gpw: Self = Self::Gp16;
124    pub const X86Gpd: Self = Self::Gp32;
125    pub const X86Gpq: Self = Self::Gp64;
126    pub const X86Xmm: Self = Self::Vec128;
127    pub const X86Ymm: Self = Self::Vec256;
128    pub const X86Zmm: Self = Self::Vec512;
129    pub const X86KReg: Self = Self::Mask;
130
131    pub const RISCVPC: Self = Self::PC;
132    pub const RISCV64Gp: Self = Self::Gp64;
133    pub const RISCV32Gp: Self = Self::Gp32;
134    pub const RISCVFp: Self = Self::Vec64;
135    pub const RISCVVec: Self = Self::VecNLen;
136}
137
138#[derive(TryFrom, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
139#[repr(u32)]
140#[try_from(repr)]
141pub enum RegGroup {
142    Gp = 0,
143    Vec,
144    Mask,
145    ExtraVirt3,
146    PC,
147    X86SReg,
148    X86CReg,
149    X86DReg,
150    X86St,
151    X86Bnd,
152    X86Tmm,
153}
154
155impl RegGroup {
156    pub const X86K: Self = Self::Mask;
157    pub const X86MM: Self = Self::ExtraVirt3;
158}
159
160#[allow(non_upper_case_globals)]
161impl RegGroup {
162    pub const X86Rip: Self = Self::PC;
163}
164
165#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, BitOr, BitAnd, BitXor)]
166pub struct OperandSignature {
167    pub bits: u32,
168}
169
170impl From<u32> for OperandSignature {
171    fn from(value: u32) -> Self {
172        Self { bits: value }
173    }
174}
175
176impl OperandSignature {
177    pub const OP_TYPE_SHIFT: u32 = 0;
179    pub const OP_TYPE_MASK: u32 = 0x07u32 << Self::OP_TYPE_SHIFT;
181
182    pub const REG_TYPE_SHIFT: u32 = 3;
184    pub const REG_TYPE_MASK: u32 = 0x1Fu32 << Self::REG_TYPE_SHIFT;
186
187    pub const REG_GROUP_SHIFT: u32 = 8;
189    pub const REG_GROUP_MASK: u32 = 0x0Fu32 << Self::REG_GROUP_SHIFT;
191
192    pub const MEM_BASE_TYPE_SHIFT: u32 = 3;
194    pub const MEM_BASE_TYPE_MASK: u32 = 0x1Fu32 << Self::MEM_BASE_TYPE_SHIFT;
196
197    pub const MEM_INDEX_TYPE_SHIFT: u32 = 8;
199    pub const MEM_INDEX_TYPE_MASK: u32 = 0x1Fu32 << Self::MEM_INDEX_TYPE_SHIFT;
201
202    pub const MEM_BASE_INDEX_SHIFT: u32 = 3;
204    pub const MEM_BASE_INDEX_MASK: u32 = 0x3FFu32 << Self::MEM_BASE_INDEX_SHIFT;
206
207    pub const MEM_REG_HOME_SHIFT: u32 = 13;
208    pub const MEM_REG_HOME_FLAG: u32 = 0x01 << Self::MEM_REG_HOME_SHIFT;
209
210    pub const PREDICATE_SHIFT: u32 = 20;
212    pub const PREDICATE_MASK: u32 = 0x0Fu32 << Self::PREDICATE_SHIFT;
214
215    pub const SIZE_SHIFT: u32 = 24;
217    pub const SIZE_MASK: u32 = 0xFFu32 << Self::SIZE_SHIFT;
219
220    pub const fn new(bits: u32) -> Self {
221        Self { bits }
222    }
223
224    pub const fn subset(&self, mask: u32) -> Self {
225        Self {
226            bits: self.bits & mask,
227        }
228    }
229}
230
231impl OperandSignature {
232    pub fn reset(&mut self) -> () {
233        self.bits = 0;
234    }
235
236    pub const fn bits(&self) -> u32 {
237        self.bits
238    }
239
240    pub fn set_bits(&mut self, bits: u32) -> () {
241        self.bits = bits;
242    }
243
244    pub const fn has_field<const K_FIELD_MASK: u32>(&self) -> bool {
245        (self.bits & K_FIELD_MASK) != 0
246    }
247
248    pub const fn has_value<const K_FIELD_MASK: u32>(&self, value: u32) -> bool {
249        (self.bits & K_FIELD_MASK) != value << K_FIELD_MASK.trailing_zeros()
250    }
251
252    pub const fn from_bits(bits: u32) -> Self {
253        OperandSignature { bits }
254    }
255
256    pub const fn from_value<const K_FIELD_MASK: u32>(value: u32) -> Self {
257        OperandSignature {
258            bits: value << K_FIELD_MASK.trailing_zeros(),
259        }
260    }
261
262    pub const fn from_op_type(op_type: OperandType) -> Self {
263        OperandSignature {
264            bits: (op_type as u32) << Self::OP_TYPE_SHIFT,
265        }
266    }
267
268    pub const fn from_reg_type(reg_type: RegType) -> Self {
269        OperandSignature {
270            bits: (reg_type as u32) << Self::REG_TYPE_SHIFT,
271        }
272    }
273
274    pub const fn from_reg_group(reg_group: RegGroup) -> Self {
275        OperandSignature {
276            bits: (reg_group as u32) << Self::REG_GROUP_SHIFT,
277        }
278    }
279
280    pub const fn from_mem_base_type(base_type: RegType) -> Self {
281        OperandSignature {
282            bits: (base_type as u32) << Self::MEM_BASE_TYPE_SHIFT,
283        }
284    }
285
286    pub const fn from_mem_index_type(index_type: RegType) -> Self {
287        OperandSignature {
288            bits: (index_type as u32) << Self::MEM_INDEX_TYPE_SHIFT,
289        }
290    }
291
292    pub const fn from_predicate(predicate: u32) -> Self {
293        OperandSignature {
294            bits: predicate << Self::PREDICATE_SHIFT,
295        }
296    }
297
298    pub const fn from_size(size: u32) -> Self {
299        OperandSignature {
300            bits: size << Self::SIZE_SHIFT,
301        }
302    }
303
304    pub fn set_field<const K_FIELD_MASK: u32>(&mut self, value: u32) -> () {
305        self.bits = (self.bits & !K_FIELD_MASK) | (value << K_FIELD_MASK.trailing_zeros());
306    }
307
308    pub const fn get_field<const K_FIELD_MASK: u32>(&self) -> u32 {
309        (self.bits >> K_FIELD_MASK.trailing_zeros())
310            & (K_FIELD_MASK >> K_FIELD_MASK.trailing_zeros())
311    }
312
313    pub const fn is_valid(&self) -> bool {
314        self.bits != 0
315    }
316
317    pub fn op_type(&self) -> OperandType {
318        OperandType::try_from(self.get_field::<{ Self::OP_TYPE_MASK }>()).unwrap()
319    }
320
321    pub fn reg_type(&self) -> RegType {
322        RegType::try_from(self.get_field::<{ Self::REG_TYPE_MASK }>()).unwrap()
323    }
324
325    pub fn reg_group(&self) -> RegGroup {
326        RegGroup::try_from(self.get_field::<{ Self::REG_GROUP_MASK }>()).unwrap()
327    }
328
329    pub fn mem_base_type(&self) -> RegType {
330        RegType::try_from(self.get_field::<{ Self::MEM_BASE_TYPE_MASK }>()).unwrap()
331    }
332
333    pub fn mem_index_type(&self) -> RegType {
334        RegType::try_from(self.get_field::<{ Self::MEM_INDEX_TYPE_MASK }>()).unwrap()
335    }
336
337    pub fn predicate(&self) -> u32 {
338        self.get_field::<{ Self::PREDICATE_MASK }>()
339    }
340
341    pub fn size(&self) -> u32 {
342        self.get_field::<{ Self::SIZE_MASK }>()
343    }
344
345    pub fn set_op_type(&mut self, op_type: OperandType) {
346        self.set_field::<{ Self::OP_TYPE_MASK }>(op_type as _);
347    }
348
349    pub fn set_reg_type(&mut self, reg_type: RegType) {
350        self.set_field::<{ Self::REG_TYPE_MASK }>(reg_type as _);
351    }
352
353    pub fn set_reg_group(&mut self, reg_group: RegGroup) {
354        self.set_field::<{ Self::REG_GROUP_MASK }>(reg_group as _);
355    }
356
357    pub fn set_mem_base_type(&mut self, base_type: RegType) {
358        self.set_field::<{ Self::MEM_BASE_TYPE_MASK }>(base_type as _);
359    }
360
361    pub fn set_mem_index_type(&mut self, index_type: RegType) {
362        self.set_field::<{ Self::MEM_INDEX_TYPE_MASK }>(index_type as _);
363    }
364
365    pub fn set_predicate(&mut self, predicate: u32) {
366        self.set_field::<{ Self::PREDICATE_MASK }>(predicate);
367    }
368
369    pub fn set_size(&mut self, size: u32) {
370        self.set_field::<{ Self::SIZE_MASK }>(size);
371    }
372}
373
374pub const DATA_MEM_INDEX_ID: usize = 0;
375pub const DATA_MEM_OFFSET_LO: usize = 1;
376pub const DATA_IMM_VALUE_LO: usize = if cfg!(target_endian = "little") { 0 } else { 1 };
377pub const DATA_IMM_VALUE_HI: usize = if DATA_IMM_VALUE_LO == 0 { 1 } else { 0 };
378
379pub const VIRT_ID_MIN: u32 = 400;
380pub const VIRT_ID_MAX: u32 = u32::MAX - 1;
381pub const VIRT_ID_COUNT: u32 = VIRT_ID_MAX - VIRT_ID_MIN + 1;
382
383#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
389pub struct Operand {
390    pub signature: OperandSignature,
391    pub base_id: u32,
392    pub data: [u32; 2],
393}
394
395pub const fn is_virt_id(id: u32) -> bool {
396    id - VIRT_ID_MIN < VIRT_ID_COUNT
397}
398
399pub const fn index_to_virt_id(id: u32) -> u32 {
400    id + VIRT_ID_MIN
401}
402
403pub const fn virt_id_to_index(id: u32) -> u32 {
404    id - VIRT_ID_MIN
405}
406
407impl Operand {
408    pub const fn new() -> Self {
409        Self {
410            base_id: INVALID_ID,
411            signature: OperandSignature::new(0),
412            data: [0; 2],
413        }
414    }
415
416    pub const fn make_reg(sig: OperandSignature, id: u32) -> Self {
417        Self {
418            base_id: id,
419            signature: sig,
420            data: [0; 2],
421        }
422    }
423
424    pub fn reset(&mut self) {
425        self.signature.reset();
426        self.base_id = 0;
427        self.data = [0; 2]
428    }
429
430    pub fn has_signature(&self, other: OperandSignature) -> bool {
431        self.signature == other
432    }
433
434    pub const fn signature(&self) -> OperandSignature {
435        self.signature
436    }
437
438    pub fn set_signature(&mut self, sig: OperandSignature) {
439        self.signature = sig;
440    }
441
442    pub fn set_id(&mut self, id: u32) {
443        self.base_id = id;
444    }
445
446    pub fn op_type(&self) -> OperandType {
447        self.signature.op_type()
448    }
449
450    pub const fn is_none(&self) -> bool {
451        self.signature.bits == 0
452    }
453
454    pub fn is_reg(&self) -> bool {
455        self.op_type() == OperandType::Reg
456    }
457
458    pub fn is_reg_list(&self) -> bool {
459        self.op_type() == OperandType::RegList
460    }
461
462    pub fn is_mem(&self) -> bool {
463        self.op_type() == OperandType::Mem
464    }
465
466    pub fn is_imm(&self) -> bool {
467        self.op_type() == OperandType::Imm
468    }
469
470    pub fn is_label(&self) -> bool {
471        self.op_type() == OperandType::Label
472    }
473
474    pub fn is_sym(&self) -> bool {
475        self.op_type() == OperandType::Sym
476    }
477
478    pub fn is_phys_reg(&self) -> bool {
479        self.is_reg() && self.base_id < 0xff
480    }
481
482    pub fn is_virt_reg(&self) -> bool {
483        self.is_reg() && self.base_id > 0xff
484    }
485
486    pub const fn id(&self) -> u32 {
487        self.base_id
488    }
489
490    pub fn is_reg_type_of(&self, typ: RegType) -> bool {
491        self.signature
492            .subset(OperandSignature::OP_TYPE_MASK | OperandSignature::REG_TYPE_MASK)
493            == OperandSignature::from_reg_type(typ)
494                | OperandSignature::from_op_type(OperandType::Reg)
495    }
496
497    pub fn is_reg_group_of(&self, group: RegGroup) -> bool {
498        self.signature
499            .subset(OperandSignature::OP_TYPE_MASK | OperandSignature::REG_GROUP_MASK)
500            == OperandSignature::from_reg_group(group)
501                | OperandSignature::from_op_type(OperandType::Reg)
502    }
503
504    pub fn is_gp(&self) -> bool {
505        self.is_reg_group_of(RegGroup::Gp)
506    }
507
508    pub fn is_gp32(&self) -> bool {
509        self.is_reg_type_of(RegType::Gp32)
510    }
511
512    pub fn is_gp64(&self) -> bool {
513        self.is_reg_type_of(RegType::Gp64)
514    }
515
516    pub fn is_vec(&self) -> bool {
517        self.is_reg_group_of(RegGroup::Vec)
518    }
519
520    pub fn is_vec8(&self) -> bool {
521        self.is_reg_type_of(RegType::Vec8)
522    }
523
524    pub fn is_vec16(&self) -> bool {
525        self.is_reg_type_of(RegType::Vec16)
526    }
527
528    pub fn is_vec32(&self) -> bool {
529        self.is_reg_type_of(RegType::Vec32)
530    }
531
532    pub fn is_vec64(&self) -> bool {
533        self.is_reg_type_of(RegType::Vec64)
534    }
535
536    pub fn is_vec128(&self) -> bool {
537        self.is_reg_type_of(RegType::Vec128)
538    }
539
540    pub fn is_vec256(&self) -> bool {
541        self.is_reg_type_of(RegType::Vec256)
542    }
543
544    pub fn is_vec512(&self) -> bool {
545        self.is_reg_type_of(RegType::Vec512)
546    }
547
548    pub fn is_mask(&self) -> bool {
549        self.is_reg_group_of(RegGroup::Mask)
550    }
551
552    pub fn is_reg_list_of(&self, typ: RegType) -> bool {
553        self.signature
554            .subset(OperandSignature::OP_TYPE_MASK | OperandSignature::REG_TYPE_MASK)
555            == OperandSignature::from_reg_type(typ)
556    }
557
558    pub fn is_reg_or_mem(&self) -> bool {
559        self.op_type() >= OperandType::Reg && self.op_type() <= OperandType::Mem
560    }
561
562    pub fn is_reg_or_reg_list_or_mem(&self) -> bool {
563        self.op_type() >= OperandType::RegList && self.op_type() <= OperandType::RegList
564    }
565
566    pub fn x86_rm_size(&self) -> u32 {
567        self.signature.size()
568    }
569}
570
571#[derive(Deref, DerefMut, Clone, Copy, PartialEq, Eq, Hash)]
572pub struct Label(pub Operand);
573
574impl core::fmt::Debug for Label {
575    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
576        write!(f, "label{}", self.id())
577    }
578}
579
580impl PartialOrd for Label {
581    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
582        self.id().partial_cmp(&other.id())
583    }
584}
585
586impl Ord for Label {
587    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
588        self.id().cmp(&other.id())
589    }
590}
591
592define_operand_cast!(Label, Operand);
593
594impl Label {
595    pub const fn new() -> Self {
596        Self(Operand {
597            signature: OperandSignature::from_op_type(OperandType::Label),
598            base_id: INVALID_ID,
599            data: [0; 2],
600        })
601    }
602
603    pub const fn from_id(id: u32) -> Self {
604        Self(Operand {
605            signature: OperandSignature::from_op_type(OperandType::Label),
606            base_id: id,
607            data: [0; 2],
608        })
609    }
610
611    pub const fn is_valid(&self) -> bool {
612        self.0.base_id != INVALID_ID
613    }
614
615    pub fn set_id(&mut self, id: u32) {
616        self.base_id = id;
617    }
618}
619
620#[derive(Deref, DerefMut, Clone, Copy, PartialEq, Eq, Hash)]
621pub struct Sym(pub Operand);
622
623impl core::fmt::Debug for Sym {
624    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
625        write!(f, "sym{}",self.id())
626    }
627}
628
629impl PartialOrd for Sym {
630    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
631        self.id().partial_cmp(&other.id())
632    }
633}
634
635impl Ord for Sym {
636    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
637        self.id().cmp(&other.id())
638    }
639}
640
641define_operand_cast!(Sym, Operand);
642
643impl Sym {
644    pub const fn new() -> Self {
645        Self(Operand {
646            signature: OperandSignature::from_op_type(OperandType::Sym),
647            base_id: INVALID_ID,
648            data: [0; 2],
649        })
650    }
651
652    pub const fn from_id(id: u32) -> Self {
653        Self(Operand {
654            signature: OperandSignature::from_op_type(OperandType::Label),
655            base_id: id,
656            data: [0; 2],
657        })
658    }
659
660    pub const fn is_valid(&self) -> bool {
661        self.0.base_id != INVALID_ID
662    }
663
664    pub fn set_id(&mut self, id: u32) {
665        self.base_id = id;
666    }
667}
668
669#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
670pub struct BaseReg(pub Operand);
671
672pub const REG_SIGNATURE: OperandSignature = OperandSignature::from_op_type(OperandType::Reg);
673pub const REG_TYPE_NONE: u32 = RegType::None as u32;
674pub const REG_BASE_SIGNATURE_MASK: u32 = OperandSignature::OP_TYPE_MASK
675    | OperandSignature::REG_TYPE_MASK
676    | OperandSignature::REG_GROUP_MASK
677    | OperandSignature::SIZE_MASK;
678
679impl BaseReg {
680    pub const SIGNATURE: u32 = REG_BASE_SIGNATURE_MASK;
681
682    pub const fn new() -> Self {
683        Self(Operand {
684            signature: OperandSignature::from_op_type(OperandType::Reg),
685            base_id: 0xff,
686            data: [0; 2],
687        })
688    }
689
690    pub const fn from_signature_and_id(signature: OperandSignature, id: u32) -> Self {
691        Self(Operand {
692            signature,
693            base_id: id,
694            data: [0; 2],
695        })
696    }
697
698    pub const fn base_signature(&self) -> OperandSignature {
699        OperandSignature {
700            bits: self.0.signature.bits & REG_BASE_SIGNATURE_MASK,
701        }
702    }
703
704    pub fn has_base_signature(&self, signature: impl Into<OperandSignature>) -> bool {
705        self.base_signature().bits == signature.into().bits
706    }
707
708    pub fn is_valid(&self) -> bool {
709        self.signature().is_valid() && self.base_id != 0xff
710    }
711
712    pub fn is_phys_reg(&self) -> bool {
713        self.base_id < 0xff
714    }
715
716    pub fn is_virt_reg(&self) -> bool {
717        self.base_id > 0xff
718    }
719
720    pub fn is_type(&self, typ: RegType) -> bool {
721        self.signature.subset(OperandSignature::REG_TYPE_MASK)
722            == OperandSignature::from_reg_type(typ)
723    }
724
725    pub fn is_group(&self, group: RegGroup) -> bool {
726        self.signature.subset(OperandSignature::REG_GROUP_MASK)
727            == OperandSignature::from_reg_group(group)
728    }
729
730    pub fn is_gp(&self) -> bool {
731        self.is_group(RegGroup::Gp)
732    }
733
734    pub fn is_vec(&self) -> bool {
735        self.is_group(RegGroup::Vec)
736    }
737
738    pub fn is_mask(&self) -> bool {
739        self.is_group(RegGroup::Mask)
740    }
741
742    pub fn operand_is_gp(op: &Operand) -> bool {
743        op.signature()
744            .subset(OperandSignature::OP_TYPE_MASK | OperandSignature::REG_GROUP_MASK)
745            == (OperandSignature::from_op_type(OperandType::Reg)
746                | OperandSignature::from_reg_group(RegGroup::Gp))
747    }
748
749    pub fn operand_is_vec(op: &Operand) -> bool {
750        op.signature()
751            .subset(OperandSignature::OP_TYPE_MASK | OperandSignature::REG_GROUP_MASK)
752            == (OperandSignature::from_op_type(OperandType::Reg)
753                | OperandSignature::from_reg_group(RegGroup::Vec))
754    }
755
756    pub fn operand_is_gp_with_id(op: &Operand, id: u32) -> bool {
757        Self::operand_is_gp(op) && op.id() == id
758    }
759
760    pub fn is_vec_with_id(op: &Operand, id: u32) -> bool {
761        Self::operand_is_vec(op) && op.id() == id
762    }
763
764    pub fn is_reg_of_type(&self, typ: RegType) -> bool {
765        self.is_type(typ)
766    }
767
768    pub fn is_reg_of_type_and_id(&self, typ: RegType, id: u32) -> bool {
769        self.is_type(typ) && self.base_id == id
770    }
771
772    pub fn typ(&self) -> RegType {
773        self.signature.reg_type()
774    }
775
776    pub fn group(&self) -> RegGroup {
777        self.signature.reg_group()
778    }
779
780    pub fn has_size(&self) -> bool {
781        self.signature
782            .has_field::<{ OperandSignature::SIZE_MASK }>()
783    }
784
785    pub fn size(&self) -> u32 {
786        self.signature.size()
787    }
788
789    pub fn predicate(&self) -> u32 {
790        self.signature.predicate()
791    }
792
793    pub fn set_predicate(&mut self, predicate: u32) {
794        self.signature
795            .set_field::<{ OperandSignature::PREDICATE_MASK }>(predicate);
796    }
797
798    pub fn reset_predicate(&mut self) {
799        self.set_predicate(0);
800    }
801}
802
803pub trait RegTraits {
804    const VALID: u32 = 1;
805    const TYPE: RegType;
806    const GROUP: RegGroup;
807    const SIZE: u32;
808    const TYPE_ID: TypeId;
809
810    const SIGNATURE: u32 = OperandSignature::from_op_type(OperandType::Reg).bits
811        | OperandSignature::from_reg_type(Self::TYPE).bits
812        | OperandSignature::from_reg_group(Self::GROUP).bits
813        | OperandSignature::from_size(Self::SIZE).bits;
814}
815
816#[macro_export]
817macro_rules! define_abstract_reg {
818    ($reg: ty, $base: ty) => {
819        impl $reg {
820            pub const fn new() -> Self {
821                Self(<$base>::from_signature_and_id(
822                    OperandSignature {
823                        bits: <$base>::SIGNATURE,
824                    },
825                    0xff,
826                ))
827            }
828
829            pub const fn from_signature_and_id(signature: OperandSignature, id: u32) -> Self {
830                Self(<$base>::from_signature_and_id(signature, id))
831            }
832
833            pub const fn from_type_and_id(typ: RegType, id: u32) -> Self {
834                Self::from_signature_and_id(Self::signature_of(typ), id)
835            }
836        }
837
838        define_operand_cast!($reg, $base);
839    };
840}
841
842#[macro_export]
843macro_rules! define_final_reg {
844    ($reg: ty, $base: ty, $traits: ty) => {
845        define_abstract_reg!($reg, $base);
846        impl $reg {
847            pub const THIS_TYPE: RegType = <$traits>::TYPE;
848            pub const THIS_GROUP: RegGroup = <$traits>::GROUP;
849            pub const THIS_SIZE: u32 = <$traits>::SIZE;
850            pub const SIGNATURE: u32 = <$traits>::SIGNATURE;
851
852            pub const fn from_id(id: u32) -> Self {
853                Self(<$base>::from_signature_and_id(
854                    OperandSignature::new(Self::SIGNATURE),
855                    id,
856                ))
857            }
858        }
859    };
860}
861
862#[macro_export]
863macro_rules! define_reg_traits {
864    ($reg_type: ident, $group: path, $size: expr, $type_id: path) => {
865        pub struct $reg_type;
866
867        impl RegTraits for $reg_type {
868            const TYPE: RegType = RegType::$reg_type;
869            const GROUP: RegGroup = $group;
870            const SIZE: u32 = $size;
871            const TYPE_ID: TypeId = $type_id;
872        }
873    };
874}
875
876pub trait OperandCast {
879    fn as_operand(&self) -> &Operand;
880    fn from_operand(op: &Operand) -> Self;
881}
882
883impl OperandCast for Operand {
884    fn as_operand(&self) -> &Operand {
885        self
886    }
887
888    fn from_operand(op: &Operand) -> Self {
889        *op
890    }
891}
892
893define_operand_cast!(BaseReg, Operand);
894
895impl Operand {
896    pub fn as_<T>(&self) -> T
897    where
898        T: OperandCast,
899    {
900        T::from_operand(self)
901    }
902}
903
904#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
905pub struct BaseMem(pub Operand);
906
907define_operand_cast!(BaseMem, Operand);
908
909impl BaseMem {
910    pub fn from_base_disp(base_reg: impl AsRef<BaseReg>, offset: i32) -> Self {
911        let base = base_reg.as_ref();
912        Self(Operand {
913            signature: OperandSignature::from_op_type(OperandType::Mem)
914                | OperandSignature::from_mem_base_type(base.typ()),
915            base_id: base.id(),
916            data: [0, offset as _],
917        })
918    }
919
920    pub fn from_base_and_index_disp(
921        u0: OperandSignature,
922        base_id: u32,
923        index_id: u32,
924        offset: i32,
925    ) -> Self {
926        Self(Operand {
927            signature: u0,
928            base_id,
929            data: [index_id, offset as _],
930        })
931    }
932
933    pub fn reset(&mut self) {
934        self.signature = OperandSignature::from_op_type(OperandType::Mem);
935        self.base_id = 0;
936        self.data = [0; 2]
937    }
938
939    pub const fn new() -> Self {
940        Self(Operand {
941            signature: OperandSignature::from_op_type(OperandType::Mem),
942            base_id: 0,
943            data: [0; 2],
944        })
945    }
946
947    pub fn is_reg_home(&self) -> bool {
948        self.signature
949            .has_field::<{ OperandSignature::MEM_REG_HOME_FLAG }>()
950    }
951
952    pub fn set_reg_home(&mut self) {
953        self.signature.bits |= OperandSignature::MEM_REG_HOME_FLAG;
954    }
955
956    pub fn clear_reg_home(&mut self) {
957        self.signature.bits &= !OperandSignature::MEM_REG_HOME_FLAG;
958    }
959
960    pub fn has_base(&self) -> bool {
961        self.signature.bits & OperandSignature::MEM_BASE_TYPE_MASK != 0
962    }
963
964    pub fn has_index(&self) -> bool {
965        self.signature.bits & OperandSignature::MEM_INDEX_TYPE_MASK != 0
966    }
967
968    pub fn has_base_or_index(&self) -> bool {
969        self.has_base() || self.has_index()
970    }
971
972    pub fn has_base_and_index(&self) -> bool {
973        self.has_base() && self.has_index()
974    }
975
976    pub fn has_base_label(&self) -> bool {
977        self.signature.subset(OperandSignature::MEM_BASE_TYPE_MASK)
978            == OperandSignature::from_reg_type(RegType::LabelTag)
979    }
980
981    pub fn has_base_sym(&self) -> bool {
982        self.signature.subset(OperandSignature::MEM_BASE_TYPE_MASK)
983            == OperandSignature::from_reg_type(RegType::SymTag)
984    }
985
986    pub fn has_base_reg(&self) -> bool {
987        self.signature.subset(OperandSignature::MEM_BASE_TYPE_MASK)
988            > OperandSignature::from_reg_type(RegType::SymTag)
989    }
990
991    pub fn has_index_reg(&self) -> bool {
992        self.signature.subset(OperandSignature::MEM_INDEX_TYPE_MASK)
993            > OperandSignature::from_reg_type(RegType::SymTag)
994    }
995
996    pub fn base_type(&self) -> RegType {
997        self.signature.mem_base_type()
998    }
999
1000    pub fn index_type(&self) -> RegType {
1001        self.signature.mem_index_type()
1002    }
1003
1004    pub fn base_id(&self) -> u32 {
1005        self.base_id
1006    }
1007
1008    pub fn index_id(&self) -> u32 {
1009        self.data[DATA_MEM_INDEX_ID]
1010    }
1011
1012    pub fn set_base_type(&mut self, base_type: RegType) {
1013        self.signature.set_mem_base_type(base_type);
1014    }
1015
1016    pub fn set_index_type(&mut self, index_type: RegType) {
1017        self.signature.set_mem_index_type(index_type);
1018    }
1019
1020    pub fn set_base_id(&mut self, id: u32) {
1021        self.base_id = id;
1022    }
1023
1024    pub fn set_index_id(&mut self, id: u32) {
1025        self.data[DATA_MEM_INDEX_ID] = id;
1026    }
1027
1028    pub fn set_base(&mut self, base: &BaseReg) {
1029        let base_reg = base;
1030        self.set_base_type(base_reg.typ());
1031        self.set_base_id(base_reg.id());
1032    }
1033
1034    pub fn set_index(&mut self, index: &BaseReg) {
1035        let index_reg = index;
1036        self.set_index_type(index_reg.typ());
1037        self.set_index_id(index_reg.id());
1038    }
1039    pub fn reset_base(&mut self) {
1040        self.signature.bits &= !OperandSignature::MEM_BASE_TYPE_MASK;
1041        self.base_id = 0;
1042    }
1043
1044    pub fn reset_index(&mut self) {
1045        self.signature.bits &= !OperandSignature::MEM_INDEX_TYPE_MASK;
1046        self.data[DATA_MEM_INDEX_ID] = 0;
1047    }
1048
1049    pub fn is_offset_64bit(&self) -> bool {
1050        self.base_type() == RegType::None
1052    }
1053
1054    pub fn has_offset(&self) -> bool {
1055        (self.data[DATA_MEM_OFFSET_LO] | (self.base_id & bitmask_from_bool(self.is_offset_64bit())))
1056            != 0
1057    }
1058
1059    pub fn offset(&self) -> i64 {
1060        if self.is_offset_64bit() {
1061            (self.data[DATA_MEM_OFFSET_LO] as u64 | (self.base_id as u64) << 32) as i64
1062        } else {
1063            self.data[DATA_MEM_OFFSET_LO] as i32 as i64
1064        }
1065    }
1066    pub fn offset_lo32(&self) -> i32 {
1067        self.data[DATA_MEM_OFFSET_LO] as i32
1068    }
1069
1070    pub fn offset_hi32(&self) -> i32 {
1071        if self.is_offset_64bit() {
1072            self.base_id as i32
1073        } else {
1074            0
1075        }
1076    }
1077    pub fn set_offset(&mut self, offset: i64) {
1078        let lo = (offset as u64 & 0xFFFFFFFF) as u32;
1079        let hi = (offset as u64 >> 32) as u32;
1080        let hi_msk = bitmask_from_bool(self.is_offset_64bit());
1081
1082        self.data[DATA_MEM_OFFSET_LO] = lo;
1083        self.base_id = (hi & hi_msk) | (self.base_id & !hi_msk);
1084    }
1085    pub fn set_offset_lo32(&mut self, offset: i32) {
1086        self.data[DATA_MEM_OFFSET_LO] = offset as u32;
1087    }
1088
1089    pub fn add_offset(&mut self, offset: i64) {
1090        if self.is_offset_64bit() {
1091            self.set_offset(self.offset() + offset);
1092        } else {
1093            self.set_offset_lo32(self.offset_lo32() + offset as i32);
1094        }
1095    }
1096
1097    pub fn add_offset_lo32(&mut self, offset: i32) {
1098        self.set_offset_lo32(self.offset_lo32() + offset);
1099    }
1100
1101    pub fn reset_offset(&mut self) {
1102        self.set_offset(0);
1103    }
1104
1105    pub fn reset_offset_lo32(&mut self) {
1106        self.set_offset_lo32(0);
1107    }
1108}
1109#[derive(Clone, Copy, PartialEq, Eq)]
1110pub enum ImmType {
1111    Int = 0,
1112    Double = 1,
1113}
1114
1115#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
1116pub struct Imm(pub Operand);
1117
1118define_operand_cast!(Imm, Operand);
1119
1120impl Imm {
1121    pub const fn new() -> Self {
1122        Self(Operand {
1123            signature: OperandSignature::from_op_type(OperandType::Imm),
1124            base_id: 0,
1125            data: [0; 2],
1126        })
1127    }
1128    pub fn from_value<T: Into<i64>>(val: T, predicate: u32) -> Self {
1139        let value = val.into();
1140        Self(Operand {
1141            signature: OperandSignature::from_op_type(OperandType::Imm)
1142                | OperandSignature::from_predicate(predicate),
1143            base_id: 0,
1144            data: [value as u32, (value >> 32) as u32],
1145        })
1146    }
1147
1148    pub fn from_float(val: f32, predicate: u32) -> Self {
1149        let mut imm = Self::new();
1150        imm.set_value_float(val);
1151        imm.set_predicate(predicate);
1152        imm
1153    }
1154
1155    pub fn from_double(val: f64, predicate: u32) -> Self {
1156        let mut imm = Self::new();
1157        imm.set_value_float(val);
1158        imm.set_predicate(predicate);
1159        imm
1160    }
1161
1162    pub fn typ(&self) -> ImmType {
1163        if self
1164            .signature()
1165            .get_field::<{ OperandSignature::PREDICATE_MASK }>()
1166            == 0
1167        {
1168            ImmType::Int
1169        } else {
1170            ImmType::Double
1171        }
1172    }
1173
1174    pub fn set_type(&mut self, typ: ImmType) {
1175        self.signature
1176            .set_field::<{ OperandSignature::PREDICATE_MASK }>(typ as u32);
1177    }
1178
1179    pub fn reset_type(&mut self) {
1180        self.set_type(ImmType::Int);
1181    }
1182
1183    pub fn predicate(&self) -> u32 {
1184        self.signature()
1185            .get_field::<{ OperandSignature::PREDICATE_MASK }>()
1186    }
1187
1188    pub fn set_predicate(&mut self, predicate: u32) {
1189        self.signature
1190            .set_field::<{ OperandSignature::PREDICATE_MASK }>(predicate);
1191    }
1192
1193    pub fn reset_predicate(&mut self) {
1194        self.set_predicate(0);
1195    }
1196
1197    pub fn value(&self) -> i64 {
1198        (((self.data[DATA_IMM_VALUE_HI] as u64) << 32) | (self.data[DATA_IMM_VALUE_LO] as u64))
1199            as i64
1200    }
1201
1202    pub fn is_int(&self) -> bool {
1203        self.typ() == ImmType::Int
1204    }
1205
1206    pub fn is_double(&self) -> bool {
1207        self.typ() == ImmType::Double
1208    }
1209
1210    pub fn is_int8(&self) -> bool {
1211        self.is_int() && (-128..=127).contains(&self.value())
1212    }
1213
1214    pub fn is_uint8(&self) -> bool {
1215        self.is_int() && (0..=255).contains(&self.value())
1216    }
1217
1218    pub fn is_int16(&self) -> bool {
1219        self.is_int() && (-32768..=32767).contains(&self.value())
1220    }
1221
1222    pub fn is_uint16(&self) -> bool {
1223        self.is_int() && (0..=65535).contains(&self.value())
1224    }
1225
1226    pub fn is_int32(&self) -> bool {
1227        self.is_int() && (-2147483648..=2147483647).contains(&self.value())
1228    }
1229
1230    pub fn is_uint32(&self) -> bool {
1231        self.is_int() && self.data[DATA_IMM_VALUE_HI] == 0
1232    }
1233
1234    pub fn value_as<T: FromPrimitive>(&self) -> T {
1235        T::from_i64(self.value()).unwrap()
1236    }
1237
1238    pub fn int32_lo(&self) -> i32 {
1239        self.data[DATA_IMM_VALUE_LO] as i32
1240    }
1241
1242    pub fn int32_hi(&self) -> i32 {
1243        self.data[DATA_IMM_VALUE_HI] as i32
1244    }
1245
1246    pub fn uint32_lo(&self) -> u32 {
1247        self.data[DATA_IMM_VALUE_LO]
1248    }
1249
1250    pub fn uint32_hi(&self) -> u32 {
1251        self.data[DATA_IMM_VALUE_HI]
1252    }
1253
1254    pub fn set_value<T: ToPrimitive>(&mut self, val: T) {
1255        let value = val.to_i64().unwrap();
1256        self.data[DATA_IMM_VALUE_LO] = value as u32;
1257        self.data[DATA_IMM_VALUE_HI] = (value >> 32) as u32;
1258        self.set_type(ImmType::Int);
1259    }
1260    pub fn set_value_float<T: Into<f64>>(&mut self, val: T) {
1261        let value = f64::to_bits(val.into());
1262        self.data[DATA_IMM_VALUE_LO] = value as u32;
1263        self.data[DATA_IMM_VALUE_HI] = (value >> 32) as u32;
1264        self.set_type(ImmType::Double);
1265    }
1266
1267    pub fn clone(&self) -> Self {
1268        *self
1269    }
1270
1271    pub fn sign_extend_8_bits(&mut self) {
1272        self.set_value(self.value_as::<i8>() as i64);
1273    }
1274
1275    pub fn sign_extend_16_bits(&mut self) {
1276        self.set_value(self.value_as::<i16>() as i64);
1277    }
1278
1279    pub fn sign_extend_32_bits(&mut self) {
1280        self.set_value(self.value_as::<i32>() as i64);
1281    }
1282
1283    pub fn zero_extend_8_bits(&mut self) {
1284        self.set_value(self.value_as::<u8>() as u64);
1285    }
1286
1287    pub fn zero_extend_16_bits(&mut self) {
1288        self.set_value(self.value_as::<u16>() as u64);
1289    }
1290
1291    pub fn zero_extend_32_bits(&mut self) {
1292        self.data[DATA_IMM_VALUE_HI] = 0;
1293    }
1294}
1295
1296pub fn imm<T: Into<i64>>(val: T) -> Imm {
1297    Imm::from_value(val, 0)
1298}