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