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