Skip to main content

asmkit/core/
operand.rs

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