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}