Skip to main content

asmkit/x86/
operands.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//! X86 operands definition.
13use crate::{
14    core::{
15        arch_traits::{Arch, ArchTraits},
16        operand::*,
17        types::TypeId,
18    },
19    define_abstract_reg, define_final_reg, define_operand_cast, define_reg_traits,
20};
21use core::ops::{Add, Deref, Mul};
22
23macro_rules! impl_deref_for_wrapper {
24    ($wrapper:ty, $target:ty) => {
25        impl core::ops::Deref for $wrapper {
26            type Target = $target;
27
28            fn deref(&self) -> &Self::Target {
29                &self.0
30            }
31        }
32
33        impl core::ops::DerefMut for $wrapper {
34            fn deref_mut(&mut self) -> &mut Self::Target {
35                &mut self.0
36            }
37        }
38    };
39}
40
41define_reg_traits!(X86Rip, RegGroup::X86Rip, 0, TypeId::Void);
42define_reg_traits!(X86GpbLo, RegGroup::Gp, 1, TypeId::Int8);
43define_reg_traits!(X86GpbHi, RegGroup::Gp, 1, TypeId::Int8);
44define_reg_traits!(X86Gpw, RegGroup::Gp, 2, TypeId::Int16);
45define_reg_traits!(X86Gpd, RegGroup::Gp, 4, TypeId::Int32);
46define_reg_traits!(X86Gpq, RegGroup::Gp, 8, TypeId::Int64);
47define_reg_traits!(X86Xmm, RegGroup::Vec, 16, TypeId::Int32x4);
48define_reg_traits!(X86Ymm, RegGroup::Vec, 32, TypeId::Int32x8);
49define_reg_traits!(X86Zmm, RegGroup::Vec, 64, TypeId::Int32x16);
50define_reg_traits!(X86KReg, RegGroup::X86K, 0, TypeId::Void);
51define_reg_traits!(X86Mm, RegGroup::X86MM, 8, TypeId::Mmx64);
52define_reg_traits!(X86SReg, RegGroup::X86SReg, 2, TypeId::Void);
53define_reg_traits!(X86CReg, RegGroup::X86CReg, 0, TypeId::Void);
54define_reg_traits!(X86DReg, RegGroup::X86DReg, 0, TypeId::Void);
55define_reg_traits!(X86St, RegGroup::X86St, 10, TypeId::Float80);
56define_reg_traits!(X86Bnd, RegGroup::X86Bnd, 16, TypeId::Void);
57define_reg_traits!(X86Tmm, RegGroup::X86Tmm, 0, TypeId::Void);
58
59#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
60pub struct Reg(pub BaseReg);
61
62impl_deref_for_wrapper!(Reg, BaseReg);
63
64define_abstract_reg!(Reg, BaseReg);
65
66impl Reg {
67    pub const fn signature_of(typ: RegType) -> OperandSignature {
68        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
69    }
70
71    pub fn is_gpb(&self) -> bool {
72        self.size() == 1
73    }
74
75    pub fn is_gpb_lo(&self) -> bool {
76        self.has_base_signature(X86GpbLo::SIGNATURE)
77    }
78
79    pub fn is_gpb_hi(&self) -> bool {
80        self.has_base_signature(X86GpbHi::SIGNATURE)
81    }
82
83    pub fn is_gpw(&self) -> bool {
84        self.has_base_signature(X86Gpw::SIGNATURE)
85    }
86
87    pub fn is_gpd(&self) -> bool {
88        self.has_base_signature(X86Gpd::SIGNATURE)
89    }
90
91    pub fn is_gpq(&self) -> bool {
92        self.has_base_signature(X86Gpq::SIGNATURE)
93    }
94
95    pub fn is_gp32(&self) -> bool {
96        self.has_base_signature(X86Gpd::SIGNATURE)
97    }
98
99    pub fn is_gp64(&self) -> bool {
100        self.has_base_signature(X86Gpq::SIGNATURE)
101    }
102
103    pub fn is_xmm(&self) -> bool {
104        self.has_base_signature(X86Xmm::SIGNATURE)
105    }
106
107    pub fn is_ymm(&self) -> bool {
108        self.has_base_signature(X86Ymm::SIGNATURE)
109    }
110
111    pub fn is_zmm(&self) -> bool {
112        self.has_base_signature(X86Zmm::SIGNATURE)
113    }
114
115    pub fn is_vec128(&self) -> bool {
116        self.has_base_signature(X86Xmm::SIGNATURE)
117    }
118
119    pub fn is_vec256(&self) -> bool {
120        self.has_base_signature(X86Ymm::SIGNATURE)
121    }
122
123    pub fn is_vec512(&self) -> bool {
124        self.has_base_signature(X86Zmm::SIGNATURE)
125    }
126
127    pub fn is_mm(&self) -> bool {
128        self.has_base_signature(X86Mm::SIGNATURE)
129    }
130
131    pub fn is_k_reg(&self) -> bool {
132        self.has_base_signature(X86KReg::SIGNATURE)
133    }
134
135    pub fn is_s_reg(&self) -> bool {
136        self.has_base_signature(X86SReg::SIGNATURE)
137    }
138
139    pub fn is_c_reg(&self) -> bool {
140        self.has_base_signature(X86CReg::SIGNATURE)
141    }
142
143    pub fn is_d_reg(&self) -> bool {
144        self.has_base_signature(X86DReg::SIGNATURE)
145    }
146
147    pub fn is_st(&self) -> bool {
148        self.has_base_signature(X86St::SIGNATURE)
149    }
150
151    pub fn is_bnd(&self) -> bool {
152        self.has_base_signature(X86Bnd::SIGNATURE)
153    }
154
155    pub fn is_tmm(&self) -> bool {
156        self.has_base_signature(X86Tmm::SIGNATURE)
157    }
158
159    pub fn is_rip(&self) -> bool {
160        self.has_base_signature(X86Rip::SIGNATURE)
161    }
162
163    pub fn set_reg_t<T: RegTraits>(&mut self, rid: u32) {
164        self.set_signature(T::SIGNATURE.into());
165        self.set_id(rid);
166    }
167
168    pub fn set_type_and_id(&mut self, typ: RegType, id: u32) {
169        self.set_signature(Self::signature_of(typ));
170        self.set_id(id);
171    }
172
173    pub fn group_of(typ: RegType) -> RegGroup {
174        ArchTraits::by_arch(Arch::X86).reg_type_to_group(typ)
175    }
176
177    pub const fn type_id_of(typ: RegType) -> TypeId {
178        ArchTraits::by_arch(Arch::X86).reg_type_to_type_id(typ)
179    }
180
181    pub const fn group_of_t<T: RegTraits>() -> RegGroup {
182        T::GROUP
183    }
184
185    pub const fn type_id_of_t<T: RegTraits>() -> TypeId {
186        T::TYPE_ID
187    }
188
189    pub const fn signature_of_vec_by_type(typ: TypeId) -> OperandSignature {
190        let typ = typ as u32;
191
192        if typ <= TypeId::VEC128_END {
193            OperandSignature::new(X86Xmm::SIGNATURE)
194        } else if typ <= TypeId::VEC256_END {
195            OperandSignature::new(X86Ymm::SIGNATURE)
196        } else {
197            OperandSignature::new(X86Zmm::SIGNATURE)
198        }
199    }
200
201    pub const fn signature_of_vec_by_size(size: u32) -> OperandSignature {
202        if size <= 16 {
203            OperandSignature::new(X86Xmm::SIGNATURE)
204        } else if size <= 32 {
205            OperandSignature::new(X86Ymm::SIGNATURE)
206        } else {
207            OperandSignature::new(X86Zmm::SIGNATURE)
208        }
209    }
210
211    pub fn operand_is_gpb(op: &Operand) -> bool {
212        op.signature.subset(
213            OperandSignature::OP_TYPE_MASK
214                | OperandSignature::REG_GROUP_MASK
215                | OperandSignature::SIZE_MASK,
216        ) == (OperandSignature::from_op_type(OperandType::Reg)
217            | OperandSignature::from_reg_group(RegGroup::Gp)
218            | OperandSignature::from_size(1))
219    }
220
221    pub fn operand_is_gpb_lo(op: &Operand) -> bool {
222        op.as_::<Self>().is_gpb_lo()
223    }
224    pub fn operand_is_gpb_hi(op: &Operand) -> bool {
225        op.as_::<Self>().is_gpb_hi()
226    }
227    pub fn operand_is_gpw(op: &Operand) -> bool {
228        op.as_::<Self>().is_gpw()
229    }
230    pub fn operand_is_gpd(op: &Operand) -> bool {
231        op.as_::<Self>().is_gpd()
232    }
233    pub fn operand_is_gpq(op: &Operand) -> bool {
234        op.as_::<Self>().is_gpq()
235    }
236    pub fn operand_is_xmm(op: &Operand) -> bool {
237        op.as_::<Self>().is_xmm()
238    }
239    pub fn operand_is_ymm(op: &Operand) -> bool {
240        op.as_::<Self>().is_ymm()
241    }
242    pub fn operand_is_zmm(op: &Operand) -> bool {
243        op.as_::<Self>().is_zmm()
244    }
245    pub fn operand_is_mm(op: &Operand) -> bool {
246        op.as_::<Self>().is_mm()
247    }
248    pub fn operand_is_k_reg(op: &Operand) -> bool {
249        op.as_::<Self>().is_k_reg()
250    }
251    pub fn operand_is_s_reg(op: &Operand) -> bool {
252        op.as_::<Self>().is_s_reg()
253    }
254    pub fn operand_is_c_reg(op: &Operand) -> bool {
255        op.as_::<Self>().is_c_reg()
256    }
257    pub fn operand_is_d_reg(op: &Operand) -> bool {
258        op.as_::<Self>().is_d_reg()
259    }
260    pub fn operand_is_st(op: &Operand) -> bool {
261        op.as_::<Self>().is_st()
262    }
263    pub fn operand_is_bnd(op: &Operand) -> bool {
264        op.as_::<Self>().is_bnd()
265    }
266    pub fn operand_is_tmm(op: &Operand) -> bool {
267        op.as_::<Self>().is_tmm()
268    }
269    pub fn operand_is_rip(op: &Operand) -> bool {
270        op.as_::<Self>().is_rip()
271    }
272
273    pub fn operand_is_gpb_with_id(op: &Operand, rid: u32) -> bool {
274        (Self::operand_is_gpb(op) as u32 & (op.id() == rid) as u32) != 0
275    }
276    pub fn operand_is_gpb_lo_with_id(op: &Operand, rid: u32) -> bool {
277        (Self::operand_is_gpb_lo(op) as u32 & (op.id() == rid) as u32) != 0
278    }
279    pub fn operand_is_gpb_hi_with_id(op: &Operand, rid: u32) -> bool {
280        (Self::operand_is_gpb_hi(op) as u32 & (op.id() == rid) as u32) != 0
281    }
282    pub fn operand_is_gpw_with_id(op: &Operand, rid: u32) -> bool {
283        (Self::operand_is_gpw(op) as u32 & (op.id() == rid) as u32) != 0
284    }
285    pub fn operand_is_gpd_with_id(op: &Operand, rid: u32) -> bool {
286        (Self::operand_is_gpd(op) as u32 & (op.id() == rid) as u32) != 0
287    }
288    pub fn operand_is_gpq_with_id(op: &Operand, rid: u32) -> bool {
289        (Self::operand_is_gpq(op) as u32 & (op.id() == rid) as u32) != 0
290    }
291    pub fn operand_is_xmm_with_id(op: &Operand, rid: u32) -> bool {
292        (Self::operand_is_xmm(op) as u32 & (op.id() == rid) as u32) != 0
293    }
294    pub fn operand_is_ymm_with_id(op: &Operand, rid: u32) -> bool {
295        (Self::operand_is_ymm(op) as u32 & (op.id() == rid) as u32) != 0
296    }
297    pub fn operand_is_zmm_with_id(op: &Operand, rid: u32) -> bool {
298        (Self::operand_is_zmm(op) as u32 & (op.id() == rid) as u32) != 0
299    }
300    pub fn operand_is_mm_with_id(op: &Operand, rid: u32) -> bool {
301        (Self::operand_is_mm(op) as u32 & (op.id() == rid) as u32) != 0
302    }
303    pub fn operand_is_k_reg_with_id(op: &Operand, rid: u32) -> bool {
304        (Self::operand_is_k_reg(op) as u32 & (op.id() == rid) as u32) != 0
305    }
306    pub fn operand_is_s_reg_with_id(op: &Operand, rid: u32) -> bool {
307        (Self::operand_is_s_reg(op) as u32 & (op.id() == rid) as u32) != 0
308    }
309    pub fn operand_is_c_reg_with_id(op: &Operand, rid: u32) -> bool {
310        (Self::operand_is_c_reg(op) as u32 & (op.id() == rid) as u32) != 0
311    }
312    pub fn operand_is_d_reg_with_id(op: &Operand, rid: u32) -> bool {
313        (Self::operand_is_d_reg(op) as u32 & (op.id() == rid) as u32) != 0
314    }
315    pub fn operand_is_st_with_id(op: &Operand, rid: u32) -> bool {
316        (Self::operand_is_st(op) as u32 & (op.id() == rid) as u32) != 0
317    }
318    pub fn operand_is_bnd_with_id(op: &Operand, rid: u32) -> bool {
319        (Self::operand_is_bnd(op) as u32 & (op.id() == rid) as u32) != 0
320    }
321    pub fn operand_is_tmm_with_id(op: &Operand, rid: u32) -> bool {
322        (Self::operand_is_tmm(op) as u32 & (op.id() == rid) as u32) != 0
323    }
324    pub fn operand_is_rip_with_id(op: &Operand, rid: u32) -> bool {
325        (Self::operand_is_rip(op) as u32 & (op.id() == rid) as u32) != 0
326    }
327
328    pub const SIGNATURE: u32 = BaseReg::SIGNATURE;
329}
330
331#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
332pub struct Gp(pub Reg);
333
334impl_deref_for_wrapper!(Gp, Reg);
335
336define_abstract_reg!(Gp, Reg);
337
338impl Gp {
339    pub const fn signature_of(typ: RegType) -> OperandSignature {
340        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
341    }
342
343    pub const AX: u32 = 0;
344    pub const CX: u32 = 1;
345    pub const DX: u32 = 2;
346    pub const BX: u32 = 3;
347    pub const SP: u32 = 4;
348    pub const BP: u32 = 5;
349    pub const SI: u32 = 6;
350    pub const DI: u32 = 7;
351    pub const R8: u32 = 8;
352    pub const R9: u32 = 9;
353    pub const R10: u32 = 10;
354    pub const R11: u32 = 11;
355    pub const R12: u32 = 12;
356    pub const R13: u32 = 13;
357    pub const R14: u32 = 14;
358    pub const R15: u32 = 15;
359
360    pub const SIGNATURE: u32 = Reg::SIGNATURE;
361}
362
363#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
364pub struct Vec(pub Reg);
365
366impl_deref_for_wrapper!(Vec, Reg);
367
368define_abstract_reg!(Vec, Reg);
369
370impl Vec {
371    pub const fn signature_of(typ: RegType) -> OperandSignature {
372        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
373    }
374
375    pub const SIGNATURE: u32 = Reg::SIGNATURE;
376}
377
378#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
379pub struct SReg(pub Reg);
380
381impl_deref_for_wrapper!(SReg, Reg);
382
383impl SReg {
384    pub const fn signature_of(typ: RegType) -> OperandSignature {
385        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
386    }
387
388    pub const ES: u32 = 1;
389    pub const CS: u32 = 2;
390    pub const SS: u32 = 3;
391    pub const DS: u32 = 4;
392    pub const FS: u32 = 5;
393    pub const GS: u32 = 6;
394}
395
396define_final_reg!(SReg, Reg, X86SReg);
397
398#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
399pub struct Gpb(pub Gp);
400
401impl_deref_for_wrapper!(Gpb, Gp);
402
403define_abstract_reg!(Gpb, Gp);
404
405impl Gpb {
406    pub const fn signature_of(typ: RegType) -> OperandSignature {
407        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
408    }
409
410    pub const SIGNATURE: u32 = Gp::SIGNATURE;
411}
412
413#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
414pub struct GpbLo(pub Gpb);
415
416impl_deref_for_wrapper!(GpbLo, Gpb);
417
418impl GpbLo {
419    pub const fn signature_of(typ: RegType) -> OperandSignature {
420        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
421    }
422}
423
424define_final_reg!(GpbLo, Gpb, X86GpbLo);
425
426#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
427pub struct GpbHi(pub Gpb);
428
429impl_deref_for_wrapper!(GpbHi, Gpb);
430
431impl GpbHi {
432    pub const fn signature_of(typ: RegType) -> OperandSignature {
433        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
434    }
435}
436
437define_final_reg!(GpbHi, Gpb, X86GpbHi);
438
439#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
440pub struct Gpw(pub Gp);
441
442impl_deref_for_wrapper!(Gpw, Gp);
443
444impl Gpw {
445    pub const fn signature_of(typ: RegType) -> OperandSignature {
446        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
447    }
448}
449
450define_final_reg!(Gpw, Gp, X86Gpw);
451
452#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
453pub struct Gpd(pub Gp);
454
455impl_deref_for_wrapper!(Gpd, Gp);
456
457impl Gpd {
458    pub const fn signature_of(typ: RegType) -> OperandSignature {
459        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
460    }
461}
462
463define_final_reg!(Gpd, Gp, X86Gpd);
464
465#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
466pub struct Gpq(pub Gp);
467
468impl_deref_for_wrapper!(Gpq, Gp);
469
470impl Gpq {
471    pub const fn signature_of(typ: RegType) -> OperandSignature {
472        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
473    }
474}
475
476define_final_reg!(Gpq, Gp, X86Gpq);
477
478#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
479pub struct Xmm(pub Vec);
480
481impl_deref_for_wrapper!(Xmm, Vec);
482
483impl Xmm {
484    pub const fn signature_of(typ: RegType) -> OperandSignature {
485        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
486    }
487
488    pub fn half(&self) -> Xmm {
489        Xmm::from_id(self.id())
490    }
491}
492
493define_final_reg!(Xmm, Vec, X86Xmm);
494
495#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
496pub struct Ymm(pub Vec);
497
498impl_deref_for_wrapper!(Ymm, Vec);
499
500impl Ymm {
501    pub const fn signature_of(typ: RegType) -> OperandSignature {
502        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
503    }
504
505    pub fn half(&self) -> Xmm {
506        Xmm::from_id(self.id())
507    }
508}
509
510define_final_reg!(Ymm, Vec, X86Ymm);
511
512#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
513pub struct Zmm(pub Vec);
514
515impl_deref_for_wrapper!(Zmm, Vec);
516
517impl Zmm {
518    pub const fn signature_of(typ: RegType) -> OperandSignature {
519        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
520    }
521
522    pub fn half(&self) -> Ymm {
523        Ymm::from_id(self.id())
524    }
525}
526
527define_final_reg!(Zmm, Vec, X86Zmm);
528
529#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
530pub struct Mm(pub Reg);
531
532impl_deref_for_wrapper!(Mm, Reg);
533
534impl Mm {
535    pub const fn signature_of(typ: RegType) -> OperandSignature {
536        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
537    }
538}
539
540define_final_reg!(Mm, Reg, X86Mm);
541
542#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
543pub struct KReg(pub Reg);
544
545impl_deref_for_wrapper!(KReg, Reg);
546
547impl KReg {
548    pub const fn signature_of(typ: RegType) -> OperandSignature {
549        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
550    }
551}
552
553define_final_reg!(KReg, Reg, X86KReg);
554
555#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
556pub struct CReg(pub Reg);
557
558impl_deref_for_wrapper!(CReg, Reg);
559
560impl CReg {
561    pub const fn signature_of(typ: RegType) -> OperandSignature {
562        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
563    }
564}
565
566define_final_reg!(CReg, Reg, X86CReg);
567
568#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
569pub struct DReg(pub Reg);
570
571impl_deref_for_wrapper!(DReg, Reg);
572
573impl DReg {
574    pub const fn signature_of(typ: RegType) -> OperandSignature {
575        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
576    }
577}
578
579define_final_reg!(DReg, Reg, X86DReg);
580
581#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
582pub struct St(pub Reg);
583
584impl_deref_for_wrapper!(St, Reg);
585
586impl St {
587    pub const fn signature_of(typ: RegType) -> OperandSignature {
588        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
589    }
590}
591
592define_final_reg!(St, Reg, X86St);
593
594#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
595pub struct Bnd(pub Reg);
596
597impl_deref_for_wrapper!(Bnd, Reg);
598
599impl Bnd {
600    pub const fn signature_of(typ: RegType) -> OperandSignature {
601        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
602    }
603}
604
605define_final_reg!(Bnd, Reg, X86Bnd);
606
607#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
608pub struct Tmm(pub Reg);
609
610impl_deref_for_wrapper!(Tmm, Reg);
611
612impl Tmm {
613    pub const fn signature_of(typ: RegType) -> OperandSignature {
614        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
615    }
616}
617
618define_final_reg!(Tmm, Reg, X86Tmm);
619
620#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
621pub struct Rip(pub Reg);
622
623impl_deref_for_wrapper!(Rip, Reg);
624
625impl Rip {
626    pub const fn signature_of(typ: RegType) -> OperandSignature {
627        ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
628    }
629}
630
631define_final_reg!(Rip, Reg, X86Rip);
632
633impl Gp {
634    pub fn r8(&self) -> GpbLo {
635        GpbLo::from_id(self.id())
636    }
637
638    pub fn r8lo(&self) -> GpbLo {
639        GpbLo::from_id(self.id())
640    }
641
642    pub fn r8hi(&self) -> GpbHi {
643        GpbHi::from_id(self.id())
644    }
645
646    pub fn r16(&self) -> Gpw {
647        Gpw::from_id(self.id())
648    }
649
650    pub fn r32(&self) -> Gpd {
651        Gpd::from_id(self.id())
652    }
653
654    pub fn r64(&self) -> Gpq {
655        Gpq::from_id(self.id())
656    }
657}
658impl Vec {
659    pub fn xmm(&self) -> Xmm {
660        Xmm::from_id(self.id())
661    }
662
663    pub fn ymm(&self) -> Ymm {
664        Ymm::from_id(self.id())
665    }
666
667    pub fn zmm(&self) -> Zmm {
668        Zmm::from_id(self.id())
669    }
670
671    pub fn v128(&self) -> Xmm {
672        Xmm::from_id(self.id())
673    }
674
675    pub fn v256(&self) -> Ymm {
676        Ymm::from_id(self.id())
677    }
678
679    pub fn v512(&self) -> Zmm {
680        Zmm::from_id(self.id())
681    }
682}
683
684pub mod regs {
685    use super::*;
686    pub const fn gpb(id: u32) -> GpbLo {
687        GpbLo::from_id(id)
688    }
689
690    pub const fn gpb_lo(id: u32) -> GpbLo {
691        GpbLo::from_id(id)
692    }
693
694    pub const fn gpb_hi(id: u32) -> GpbHi {
695        GpbHi::from_id(id)
696    }
697
698    pub const fn gpw(id: u32) -> Gpw {
699        Gpw::from_id(id)
700    }
701
702    pub const fn gpd(id: u32) -> Gpd {
703        Gpd::from_id(id)
704    }
705
706    pub const fn gpq(id: u32) -> Gpq {
707        Gpq::from_id(id)
708    }
709
710    pub const fn xmm(id: u32) -> Xmm {
711        Xmm::from_id(id)
712    }
713
714    pub const fn ymm(id: u32) -> Ymm {
715        Ymm::from_id(id)
716    }
717
718    pub const fn zmm(id: u32) -> Zmm {
719        Zmm::from_id(id)
720    }
721
722    pub const fn mm(id: u32) -> Mm {
723        Mm::from_id(id)
724    }
725
726    pub const fn k(id: u32) -> KReg {
727        KReg::from_id(id)
728    }
729
730    pub const fn cr(id: u32) -> CReg {
731        CReg::from_id(id)
732    }
733
734    pub const fn dr(id: u32) -> DReg {
735        DReg::from_id(id)
736    }
737
738    pub const fn st(id: u32) -> St {
739        St::from_id(id)
740    }
741
742    pub const fn bnd(id: u32) -> Bnd {
743        Bnd::from_id(id)
744    }
745
746    pub const fn tmm(id: u32) -> Tmm {
747        Tmm::from_id(id)
748    }
749
750    pub const fn rip() -> Rip {
751        Rip::from_id(0x120)
752    }
753
754    pub const fn sreg(id: u32) -> SReg {
755        SReg::from_id(id)
756    }
757
758    pub const AL: GpbLo = gpb_lo(Gp::AX);
759    pub const CL: GpbLo = gpb_lo(Gp::CX);
760    pub const DL: GpbLo = gpb_lo(Gp::DX);
761    pub const BL: GpbLo = gpb_lo(Gp::BX);
762    pub const SPL: GpbLo = gpb_lo(Gp::SP);
763    pub const BPL: GpbLo = gpb_lo(Gp::BP);
764    pub const SIL: GpbLo = gpb_lo(Gp::SI);
765    pub const DIL: GpbLo = gpb_lo(Gp::DI);
766    pub const R8B: GpbLo = gpb_lo(Gp::R8);
767    pub const R9B: GpbLo = gpb_lo(Gp::R9);
768    pub const R10B: GpbLo = gpb_lo(Gp::R10);
769    pub const R11B: GpbLo = gpb_lo(Gp::R11);
770    pub const R12B: GpbLo = gpb_lo(Gp::R12);
771    pub const R13B: GpbLo = gpb_lo(Gp::R13);
772    pub const R14B: GpbLo = gpb_lo(Gp::R14);
773    pub const R15B: GpbLo = gpb_lo(Gp::R15);
774
775    pub const AH: GpbHi = gpb_hi(Gp::AX);
776    pub const CH: GpbHi = gpb_hi(Gp::CX);
777    pub const DH: GpbHi = gpb_hi(Gp::DX);
778    pub const BH: GpbHi = gpb_hi(Gp::BX);
779
780    pub const AX: Gpw = gpw(Gp::AX);
781    pub const CX: Gpw = gpw(Gp::CX);
782    pub const DX: Gpw = gpw(Gp::DX);
783    pub const BX: Gpw = gpw(Gp::BX);
784    pub const SP: Gpw = gpw(Gp::SP);
785    pub const BP: Gpw = gpw(Gp::BP);
786    pub const SI: Gpw = gpw(Gp::SI);
787    pub const DI: Gpw = gpw(Gp::DI);
788    pub const R8W: Gpw = gpw(Gp::R8);
789    pub const R9W: Gpw = gpw(Gp::R9);
790    pub const R10W: Gpw = gpw(Gp::R10);
791    pub const R11W: Gpw = gpw(Gp::R11);
792    pub const R12W: Gpw = gpw(Gp::R12);
793    pub const R13W: Gpw = gpw(Gp::R13);
794    pub const R14W: Gpw = gpw(Gp::R14);
795    pub const R15W: Gpw = gpw(Gp::R15);
796
797    pub const EAX: Gpd = gpd(Gp::AX);
798    pub const ECX: Gpd = gpd(Gp::CX);
799    pub const EDX: Gpd = gpd(Gp::DX);
800    pub const EBX: Gpd = gpd(Gp::BX);
801    pub const ESP: Gpd = gpd(Gp::SP);
802    pub const EBP: Gpd = gpd(Gp::BP);
803    pub const ESI: Gpd = gpd(Gp::SI);
804    pub const EDI: Gpd = gpd(Gp::DI);
805    pub const R8D: Gpd = gpd(Gp::R8);
806    pub const R9D: Gpd = gpd(Gp::R9);
807    pub const R10D: Gpd = gpd(Gp::R10);
808    pub const R11D: Gpd = gpd(Gp::R11);
809    pub const R12D: Gpd = gpd(Gp::R12);
810    pub const R13D: Gpd = gpd(Gp::R13);
811    pub const R14D: Gpd = gpd(Gp::R14);
812    pub const R15D: Gpd = gpd(Gp::R15);
813
814    pub const RAX: Gpq = gpq(Gp::AX);
815    pub const RCX: Gpq = gpq(Gp::CX);
816    pub const RDX: Gpq = gpq(Gp::DX);
817    pub const RBX: Gpq = gpq(Gp::BX);
818    pub const RSP: Gpq = gpq(Gp::SP);
819    pub const RBP: Gpq = gpq(Gp::BP);
820    pub const RSI: Gpq = gpq(Gp::SI);
821    pub const RDI: Gpq = gpq(Gp::DI);
822    pub const R8: Gpq = gpq(Gp::R8);
823    pub const R9: Gpq = gpq(Gp::R9);
824    pub const R10: Gpq = gpq(Gp::R10);
825    pub const R11: Gpq = gpq(Gp::R11);
826    pub const R12: Gpq = gpq(Gp::R12);
827    pub const R13: Gpq = gpq(Gp::R13);
828    pub const R14: Gpq = gpq(Gp::R14);
829    pub const R15: Gpq = gpq(Gp::R15);
830
831    pub const XMM0: Xmm = xmm(0);
832    pub const XMM1: Xmm = xmm(1);
833    pub const XMM2: Xmm = xmm(2);
834    pub const XMM3: Xmm = xmm(3);
835    pub const XMM4: Xmm = xmm(4);
836    pub const XMM5: Xmm = xmm(5);
837    pub const XMM6: Xmm = xmm(6);
838    pub const XMM7: Xmm = xmm(7);
839    pub const XMM8: Xmm = xmm(8);
840    pub const XMM9: Xmm = xmm(9);
841    pub const XMM10: Xmm = xmm(10);
842    pub const XMM11: Xmm = xmm(11);
843    pub const XMM12: Xmm = xmm(12);
844    pub const XMM13: Xmm = xmm(13);
845    pub const XMM14: Xmm = xmm(14);
846    pub const XMM15: Xmm = xmm(15);
847    pub const XMM16: Xmm = xmm(16);
848    pub const XMM17: Xmm = xmm(17);
849    pub const XMM18: Xmm = xmm(18);
850    pub const XMM19: Xmm = xmm(19);
851    pub const XMM20: Xmm = xmm(20);
852    pub const XMM21: Xmm = xmm(21);
853    pub const XMM22: Xmm = xmm(22);
854    pub const XMM23: Xmm = xmm(23);
855    pub const XMM24: Xmm = xmm(24);
856    pub const XMM25: Xmm = xmm(25);
857    pub const XMM26: Xmm = xmm(26);
858    pub const XMM27: Xmm = xmm(27);
859    pub const XMM28: Xmm = xmm(28);
860    pub const XMM29: Xmm = xmm(29);
861    pub const XMM30: Xmm = xmm(30);
862    pub const XMM31: Xmm = xmm(31);
863
864    pub const YMM0: Ymm = ymm(0);
865    pub const YMM1: Ymm = ymm(1);
866    pub const YMM2: Ymm = ymm(2);
867    pub const YMM3: Ymm = ymm(3);
868    pub const YMM4: Ymm = ymm(4);
869    pub const YMM5: Ymm = ymm(5);
870    pub const YMM6: Ymm = ymm(6);
871    pub const YMM7: Ymm = ymm(7);
872    pub const YMM8: Ymm = ymm(8);
873    pub const YMM9: Ymm = ymm(9);
874    pub const YMM10: Ymm = ymm(10);
875    pub const YMM11: Ymm = ymm(11);
876    pub const YMM12: Ymm = ymm(12);
877    pub const YMM13: Ymm = ymm(13);
878    pub const YMM14: Ymm = ymm(14);
879    pub const YMM15: Ymm = ymm(15);
880    pub const YMM16: Ymm = ymm(16);
881    pub const YMM17: Ymm = ymm(17);
882    pub const YMM18: Ymm = ymm(18);
883    pub const YMM19: Ymm = ymm(19);
884    pub const YMM20: Ymm = ymm(20);
885    pub const YMM21: Ymm = ymm(21);
886    pub const YMM22: Ymm = ymm(22);
887    pub const YMM23: Ymm = ymm(23);
888    pub const YMM24: Ymm = ymm(24);
889    pub const YMM25: Ymm = ymm(25);
890    pub const YMM26: Ymm = ymm(26);
891    pub const YMM27: Ymm = ymm(27);
892    pub const YMM28: Ymm = ymm(28);
893    pub const YMM29: Ymm = ymm(29);
894    pub const YMM30: Ymm = ymm(30);
895    pub const YMM31: Ymm = ymm(31);
896
897    pub const ZMM0: Zmm = zmm(0);
898    pub const ZMM1: Zmm = zmm(1);
899    pub const ZMM2: Zmm = zmm(2);
900    pub const ZMM3: Zmm = zmm(3);
901    pub const ZMM4: Zmm = zmm(4);
902    pub const ZMM5: Zmm = zmm(5);
903    pub const ZMM6: Zmm = zmm(6);
904    pub const ZMM7: Zmm = zmm(7);
905    pub const ZMM8: Zmm = zmm(8);
906    pub const ZMM9: Zmm = zmm(9);
907    pub const ZMM10: Zmm = zmm(10);
908    pub const ZMM11: Zmm = zmm(11);
909    pub const ZMM12: Zmm = zmm(12);
910    pub const ZMM13: Zmm = zmm(13);
911    pub const ZMM14: Zmm = zmm(14);
912    pub const ZMM15: Zmm = zmm(15);
913    pub const ZMM16: Zmm = zmm(16);
914    pub const ZMM17: Zmm = zmm(17);
915    pub const ZMM18: Zmm = zmm(18);
916    pub const ZMM19: Zmm = zmm(19);
917    pub const ZMM20: Zmm = zmm(20);
918    pub const ZMM21: Zmm = zmm(21);
919    pub const ZMM22: Zmm = zmm(22);
920    pub const ZMM23: Zmm = zmm(23);
921    pub const ZMM24: Zmm = zmm(24);
922    pub const ZMM25: Zmm = zmm(25);
923    pub const ZMM26: Zmm = zmm(26);
924    pub const ZMM27: Zmm = zmm(27);
925    pub const ZMM28: Zmm = zmm(28);
926    pub const ZMM29: Zmm = zmm(29);
927    pub const ZMM30: Zmm = zmm(30);
928    pub const ZMM31: Zmm = zmm(31);
929
930    pub const MM0: Mm = mm(0);
931    pub const MM1: Mm = mm(1);
932    pub const MM2: Mm = mm(2);
933    pub const MM3: Mm = mm(3);
934    pub const MM4: Mm = mm(4);
935    pub const MM5: Mm = mm(5);
936    pub const MM6: Mm = mm(6);
937    pub const MM7: Mm = mm(7);
938
939    pub const K0: KReg = k(0);
940    pub const K1: KReg = k(1);
941    pub const K2: KReg = k(2);
942    pub const K3: KReg = k(3);
943    pub const K4: KReg = k(4);
944    pub const K5: KReg = k(5);
945    pub const K6: KReg = k(6);
946    pub const K7: KReg = k(7);
947
948    pub const CR0: CReg = cr(0);
949    pub const CR2: CReg = cr(2);
950    pub const CR3: CReg = cr(3);
951    pub const CR4: CReg = cr(4);
952    pub const CR8: CReg = cr(8);
953
954    pub const DR0: DReg = dr(0);
955    pub const DR1: DReg = dr(1);
956    pub const DR2: DReg = dr(2);
957    pub const DR3: DReg = dr(3);
958    pub const DR6: DReg = dr(6);
959    pub const DR7: DReg = dr(7);
960
961    pub const ST0: St = st(0);
962    pub const ST1: St = st(1);
963    pub const ST2: St = st(2);
964    pub const ST3: St = st(3);
965    pub const ST4: St = st(4);
966    pub const ST5: St = st(5);
967    pub const ST6: St = st(6);
968    pub const ST7: St = st(7);
969
970    pub const BND0: Bnd = bnd(0);
971    pub const BND1: Bnd = bnd(1);
972    pub const BND2: Bnd = bnd(2);
973    pub const BND3: Bnd = bnd(3);
974
975    pub const TMM0: Tmm = tmm(0);
976    pub const TMM1: Tmm = tmm(1);
977    pub const TMM2: Tmm = tmm(2);
978    pub const TMM3: Tmm = tmm(3);
979    pub const TMM4: Tmm = tmm(4);
980    pub const TMM5: Tmm = tmm(5);
981    pub const TMM6: Tmm = tmm(6);
982    pub const TMM7: Tmm = tmm(7);
983
984    pub const RIP: Rip = rip();
985
986    pub const ES: SReg = sreg(SReg::ES);
987    pub const CS: SReg = sreg(SReg::CS);
988    pub const SS: SReg = sreg(SReg::SS);
989    pub const DS: SReg = sreg(SReg::DS);
990    pub const FS: SReg = sreg(SReg::FS);
991    pub const GS: SReg = sreg(SReg::GS);
992}
993pub use regs::*;
994
995#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
996pub struct Mem(pub BaseMem);
997
998impl_deref_for_wrapper!(Mem, BaseMem);
999
1000define_operand_cast!(Mem, BaseMem);
1001
1002#[derive(Clone, Copy, PartialEq, Eq)]
1003#[repr(u32)]
1004pub enum AddrType {
1005    Default = 0,
1006    Abs = 1,
1007    Rel = 2,
1008}
1009
1010#[derive(Clone, Copy, PartialEq, Eq)]
1011#[repr(u32)]
1012pub enum Broadcast {
1013    None = 0,
1014    B1To2 = 1,
1015    B1To4 = 2,
1016    B1To8 = 3,
1017    B1To16 = 4,
1018    B1To32 = 5,
1019    B1To64 = 6,
1020}
1021type Signature = OperandSignature;
1022
1023impl Default for Mem {
1024    fn default() -> Self {
1025        Self::new()
1026    }
1027}
1028
1029impl Mem {
1030    pub const SIGNATURE_MEM_ADDR_TYPE_SHIFT: u32 = 14;
1031    pub const SIGNATURE_MEM_ADDR_TYPE_MASK: u32 = 0x03 << Self::SIGNATURE_MEM_ADDR_TYPE_SHIFT;
1032
1033    pub const SIGNATURE_MEM_SHIFT_VALUE_SHIFT: u32 = 16;
1034    pub const SIGNATURE_MEM_SHIFT_VALUE_MASK: u32 = 0x03 << Self::SIGNATURE_MEM_SHIFT_VALUE_SHIFT;
1035
1036    pub const SIGNATURE_MEM_SEGMENT_SHIFT: u32 = 18;
1037    pub const SIGNATURE_MEM_SEGMENT_MASK: u32 = 0x07 << Self::SIGNATURE_MEM_SEGMENT_SHIFT;
1038
1039    pub const SIGNATURE_MEM_BROADCAST_SHIFT: u32 = 21;
1040    pub const SIGNATURE_MEM_BROADCAST_MASK: u32 = 0x7 << Self::SIGNATURE_MEM_BROADCAST_SHIFT;
1041
1042    pub const fn new() -> Self {
1043        Self(BaseMem::new())
1044    }
1045
1046    pub fn base_reg(&self) -> Reg {
1047        Reg::from_type_and_id(self.base_type(), self.base_id())
1048    }
1049
1050    pub fn index_reg(&self) -> Reg {
1051        Reg::from_type_and_id(self.index_type(), self.index_id())
1052    }
1053
1054    pub fn set_index(&mut self, index: &BaseReg, shift: u32) {
1055        self.0.set_index(index);
1056        self.set_shift(shift);
1057    }
1058
1059    pub fn has_size(&self) -> bool {
1060        self.0.signature.has_field::<{ Signature::SIZE_MASK }>()
1061    }
1062
1063    pub fn has_size_of(&self, s: u32) -> bool {
1064        self.size() == s
1065    }
1066
1067    pub fn size(&self) -> u32 {
1068        self.0.signature.get_field::<{ Signature::SIZE_MASK }>()
1069    }
1070
1071    pub fn set_size(&mut self, size: u32) {
1072        self.0.signature.set_field::<{ Signature::SIZE_MASK }>(size);
1073    }
1074
1075    pub fn addr_type(&self) -> AddrType {
1076        unsafe {
1077            core::mem::transmute(
1078                self.0
1079                    .signature
1080                    .get_field::<{ Self::SIGNATURE_MEM_ADDR_TYPE_MASK }>(),
1081            )
1082        }
1083    }
1084
1085    pub fn set_addr_type(&mut self, addr_type: AddrType) {
1086        self.0
1087            .signature
1088            .set_field::<{ Self::SIGNATURE_MEM_ADDR_TYPE_MASK }>(addr_type as u32);
1089    }
1090
1091    pub fn reset_addr_type(&mut self) {
1092        self.set_addr_type(AddrType::Default);
1093    }
1094
1095    pub fn is_abs(&self) -> bool {
1096        self.addr_type() == AddrType::Abs
1097    }
1098
1099    pub fn set_abs(&mut self) {
1100        self.set_addr_type(AddrType::Abs);
1101    }
1102
1103    pub fn is_rel(&self) -> bool {
1104        self.addr_type() == AddrType::Rel
1105    }
1106
1107    pub fn set_rel(&mut self) {
1108        self.set_addr_type(AddrType::Rel);
1109    }
1110
1111    pub fn has_segment(&self) -> bool {
1112        self.0
1113            .signature
1114            .has_field::<{ Self::SIGNATURE_MEM_SEGMENT_MASK }>()
1115    }
1116
1117    pub fn segment(&self) -> SReg {
1118        SReg::from_id(self.segment_id())
1119    }
1120
1121    pub fn segment_id(&self) -> u32 {
1122        self.0
1123            .signature
1124            .get_field::<{ Self::SIGNATURE_MEM_SEGMENT_MASK }>()
1125    }
1126
1127    pub fn set_segment(&mut self, seg: SReg) {
1128        self.set_segment_id(seg.id());
1129    }
1130
1131    pub fn set_segment_id(&mut self, r_id: u32) {
1132        self.0
1133            .signature
1134            .set_field::<{ Self::SIGNATURE_MEM_SEGMENT_MASK }>(r_id);
1135    }
1136
1137    pub fn reset_segment(&mut self) {
1138        self.set_segment_id(0);
1139    }
1140
1141    pub fn has_shift(&self) -> bool {
1142        self.0
1143            .signature
1144            .has_field::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>()
1145    }
1146
1147    pub fn shift(&self) -> u32 {
1148        self.0
1149            .signature
1150            .get_field::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>()
1151    }
1152
1153    pub fn set_shift(&mut self, shift: u32) {
1154        self.0
1155            .signature
1156            .set_field::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift);
1157    }
1158
1159    pub fn reset_shift(&mut self) {
1160        self.set_shift(0);
1161    }
1162
1163    pub fn has_broadcast(&self) -> bool {
1164        self.0
1165            .signature
1166            .has_field::<{ Self::SIGNATURE_MEM_BROADCAST_MASK }>()
1167    }
1168
1169    pub fn get_broadcast(&self) -> Broadcast {
1170        unsafe {
1171            core::mem::transmute(
1172                self.0
1173                    .signature
1174                    .get_field::<{ Self::SIGNATURE_MEM_BROADCAST_MASK }>(),
1175            )
1176        }
1177    }
1178
1179    pub fn set_broadcast(&mut self, b: Broadcast) {
1180        self.0
1181            .signature
1182            .set_field::<{ Self::SIGNATURE_MEM_BROADCAST_MASK }>(b as u32);
1183    }
1184
1185    pub fn reset_broadcast(&mut self) {
1186        self.set_broadcast(Broadcast::None);
1187    }
1188
1189    pub fn _1to1(&self) -> Self {
1190        self.clone_broadcasted(Broadcast::None)
1191    }
1192
1193    pub fn _1to2(&self) -> Self {
1194        self.clone_broadcasted(Broadcast::B1To2)
1195    }
1196
1197    pub fn _1to4(&self) -> Self {
1198        self.clone_broadcasted(Broadcast::B1To4)
1199    }
1200
1201    pub fn _1to8(&self) -> Self {
1202        self.clone_broadcasted(Broadcast::B1To8)
1203    }
1204
1205    pub fn _1to16(&self) -> Self {
1206        self.clone_broadcasted(Broadcast::B1To16)
1207    }
1208
1209    pub fn _1to32(&self) -> Self {
1210        self.clone_broadcasted(Broadcast::B1To32)
1211    }
1212
1213    pub fn _1to64(&self) -> Self {
1214        self.clone_broadcasted(Broadcast::B1To64)
1215    }
1216
1217    pub fn base_and_index_types(&self) -> u32 {
1218        self.signature
1219            .get_field::<{ OperandSignature::MEM_BASE_INDEX_MASK }>()
1220    }
1221
1222    pub fn clone_broadcasted(&self, bcst: Broadcast) -> Self {
1223        Self(BaseMem::from_base_and_index_disp(
1224            OperandSignature::new(self.0.signature.bits() & !Self::SIGNATURE_MEM_BROADCAST_MASK)
1225                | OperandSignature::new((bcst as u32) << Self::SIGNATURE_MEM_BROADCAST_SHIFT),
1226            self.0.base_id(),
1227            self.0.data[0],
1228            self.0.data[1] as _,
1229        ))
1230    }
1231
1232    pub fn from_signature_base_and_index_id_disp(
1233        signature: OperandSignature,
1234        base_id: u32,
1235        index_id: u32,
1236        offset: i32,
1237    ) -> Self {
1238        Self(BaseMem::from_base_and_index_disp(
1239            signature, base_id, index_id, offset,
1240        ))
1241    }
1242
1243    pub fn from_sym_and_index_shift_disp(
1244        base: &Sym,
1245        index: &BaseReg,
1246        shift: u32,
1247        off: i32,
1248        size: u32,
1249        signature: OperandSignature,
1250    ) -> Self {
1251        Self(BaseMem::from_base_and_index_disp(
1252            Signature::from_op_type(OperandType::Mem)
1253                | Signature::from_mem_base_type(RegType::SymTag)
1254                | Signature::from_mem_index_type(index.typ())
1255                | Signature::from_value::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift)
1256                | Signature::from_size(size)
1257                | signature,
1258            base.id(),
1259            index.id(),
1260            off,
1261        ))
1262    }
1263    pub fn from_label_and_index_shift_disp(
1264        base: &Label,
1265        index: &BaseReg,
1266        shift: u32,
1267        off: i32,
1268        size: u32,
1269        signature: OperandSignature,
1270    ) -> Self {
1271        Self(BaseMem::from_base_and_index_disp(
1272            Signature::from_op_type(OperandType::Mem)
1273                | Signature::from_mem_base_type(RegType::LabelTag)
1274                | Signature::from_mem_index_type(index.typ())
1275                | Signature::from_value::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift)
1276                | Signature::from_size(size)
1277                | signature,
1278            base.id(),
1279            index.id(),
1280            off,
1281        ))
1282    }
1283
1284    pub fn from_label_and_disp(
1285        base: &Label,
1286        off: i32,
1287        size: u32,
1288        signature: OperandSignature,
1289    ) -> Self {
1290        Self(BaseMem::from_base_and_index_disp(
1291            Signature::from_op_type(OperandType::Mem)
1292                | Signature::from_mem_base_type(RegType::LabelTag)
1293                | Signature::from_size(size)
1294                | signature,
1295            base.id(),
1296            0,
1297            off,
1298        ))
1299    }
1300
1301    pub fn from_sym_and_disp(base: &Sym, off: i32, size: u32, signature: OperandSignature) -> Self {
1302        Self(BaseMem::from_base_and_index_disp(
1303            Signature::from_op_type(OperandType::Mem)
1304                | Signature::from_mem_base_type(RegType::SymTag)
1305                | Signature::from_size(size)
1306                | signature,
1307            base.id(),
1308            0,
1309            off,
1310        ))
1311    }
1312
1313    pub fn from_base_and_disp(
1314        base: &BaseReg,
1315        off: i32,
1316        size: u32,
1317        signature: OperandSignature,
1318    ) -> Self {
1319        Self(BaseMem::from_base_and_index_disp(
1320            Signature::from_op_type(OperandType::Mem)
1321                | Signature::from_mem_base_type(base.typ())
1322                | Signature::from_size(size)
1323                | signature,
1324            base.id(),
1325            0,
1326            off,
1327        ))
1328    }
1329
1330    pub fn from_base_and_index_shift_disp(
1331        base: &BaseReg,
1332        index: &BaseReg,
1333        shift: u32,
1334        off: i32,
1335        size: u32,
1336        signature: OperandSignature,
1337    ) -> Self {
1338        Self(BaseMem::from_base_and_index_disp(
1339            Signature::from_op_type(OperandType::Mem)
1340                | Signature::from_mem_base_type(base.typ())
1341                | Signature::from_mem_index_type(index.typ())
1342                | Signature::from_value::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift)
1343                | Signature::from_size(size)
1344                | signature,
1345            base.id(),
1346            index.id(),
1347            off,
1348        ))
1349    }
1350
1351    pub fn from_u64_and_index_shift_disp(
1352        base: u64,
1353        index: &BaseReg,
1354        shift: u32,
1355        size: u32,
1356        signature: OperandSignature,
1357    ) -> Self {
1358        Self(BaseMem::from_base_and_index_disp(
1359            Signature::from_op_type(OperandType::Mem)
1360                | Signature::from_mem_index_type(index.typ())
1361                | Signature::from_value::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift)
1362                | Signature::from_size(size)
1363                | signature,
1364            (base >> 32) as u32,
1365            index.id(),
1366            (base & 0xFFFFFFF) as _,
1367        ))
1368    }
1369
1370    pub fn from_u64(base: u64, size: u32, signature: OperandSignature) -> Self {
1371        Self(BaseMem::from_base_and_index_disp(
1372            Signature::from_op_type(OperandType::Mem) | Signature::from_size(size) | signature,
1373            (base >> 32) as u32,
1374            0,
1375            (base & 0xFFFFFFF) as _,
1376        ))
1377    }
1378
1379    pub fn absolute_address(self) -> u64 {
1380        assert!(self.is_abs());
1381        ((self.base_id() as u64) << 32) | (self.data[1] as u64)
1382    }
1383}
1384
1385impl Add<i32> for Gpq {
1386    type Output = Mem;
1387    fn add(self, rhs: i32) -> Self::Output {
1388        ptr(self, rhs, 0)
1389    }
1390}
1391
1392impl Mul<i32> for Gpq {
1393    type Output = Mem;
1394
1395    fn mul(self, rhs: i32) -> Self::Output {
1396        let shift = match rhs {
1397            0 | 1 => 0,
1398            2 => 1,
1399            4 => 2,
1400            8 => 3,
1401            16 => 4,
1402            _ => todo!(),
1403        };
1404        ptr_index(RAX, self, shift, 0, 0)
1405    }
1406}
1407
1408impl<T: Deref<Target = Gp>> Mul<T> for Mem {
1409    type Output = Mem;
1410
1411    fn mul(self, rhs: T) -> Self::Output {
1412        let mut this = self;
1413        let reg = rhs.deref();
1414        this.set_index_id(reg.id());
1415        this.set_index_type(reg.typ());
1416
1417        this
1418    }
1419}
1420
1421impl Add<i32> for Label {
1422    type Output = Mem;
1423
1424    fn add(self, rhs: i32) -> Self::Output {
1425        label_ptr(self, rhs, 0)
1426    }
1427}
1428
1429impl Add<Mem> for Gpq {
1430    type Output = Mem;
1431
1432    fn add(self, mut rhs: Mem) -> Self::Output {
1433        rhs.set_base(&self);
1434        rhs
1435    }
1436}
1437
1438impl Add<i32> for Mem {
1439    type Output = Mem;
1440
1441    fn add(self, rhs: i32) -> Self::Output {
1442        let mut this = self;
1443        this.add_offset(rhs as _);
1444        this
1445    }
1446}
1447
1448macro_rules! mem_ptr {
1449    ($name: ident, $size: literal) => {
1450        paste::paste! {
1451            pub fn $name(base: impl Deref<Target = Gp>, offset: i32) -> Mem {
1452                Mem::from_base_and_disp(base.deref(), offset, $size, 0.into())
1453            }
1454
1455            pub fn [<$name _index>](base: impl Deref<Target = Gp>, index: impl Deref<Target = Gp>, shift: u32, offset: i32) -> Mem {
1456                Mem::from_base_and_index_shift_disp(base.deref(), index.deref(), shift, offset, $size, 0.into())
1457            }
1458
1459            pub fn [<$name _label>](base: Label, offset: i32) -> Mem {
1460                Mem::from_label_and_disp(&base, offset, $size, 0.into())
1461            }
1462
1463            pub fn [<$name _label_index>](base: Label, index: impl Deref<Target = Gp>, shift: u32, offset: i32) -> Mem {
1464                Mem::from_label_and_index_shift_disp(&base, index.deref(), shift, offset, $size, 0.into())
1465            }
1466
1467            pub fn [<$name _sym>](base: Sym, offset: i32) -> Mem {
1468                Mem::from_sym_and_disp(&base, offset, $size, 0.into())
1469            }
1470
1471            pub fn [<$name _sym_index>](base: Sym, index: impl Deref<Target = Gp>, shift: u32, offset: i32) -> Mem {
1472                Mem::from_sym_and_index_shift_disp(&base, index.deref(), shift, offset, $size, 0.into())
1473            }
1474
1475
1476            pub fn [<$name _rip>](offset: i32) -> Mem {
1477                Mem::from_base_and_disp(&RIP, offset, $size, 0.into())
1478            }
1479
1480            pub fn [<$name _u64>](base: u64) -> Mem {
1481                Mem::from_u64(base, $size, 0.into())
1482            }
1483
1484            pub fn [<$name _u64_index>](base: u64, index: impl Deref<Target = Gp>, shift: u32) -> Mem {
1485                Mem::from_u64_and_index_shift_disp(base, index.deref(), shift, $size, 0.into())
1486            }
1487
1488            pub fn [<$name _u64_abs>](base: u64) -> AbsoluteAddress {
1489                AbsoluteAddress(Mem::from_u64(base, $size, OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Abs as _)))
1490            }
1491
1492            pub fn [<$name _u64_index_abs>](base: u64, index: impl Deref<Target = Gp>, shift: u32) -> AbsoluteAddress {
1493                AbsoluteAddress(Mem::from_u64_and_index_shift_disp(base, index.deref(), shift, $size, OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Abs as _)))
1494            }
1495
1496            pub fn [<$name _u64_rel>](base: u64) -> Mem {
1497                Mem::from_u64(base, $size, OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Rel as _))
1498            }
1499
1500            pub fn [<$name _u64_index_rel>](base: u64, index: impl Deref<Target = Gp>, shift: u32) -> Mem {
1501                Mem::from_u64_and_index_shift_disp(base, index.deref(), shift, $size, OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Rel as _))
1502            }
1503        }
1504    }
1505}
1506mem_ptr!(ptr8, 1);
1507mem_ptr!(ptr16, 2);
1508mem_ptr!(ptr32, 4);
1509mem_ptr!(ptr48, 6);
1510mem_ptr!(ptr64, 8);
1511mem_ptr!(ptr80, 10);
1512mem_ptr!(ptr128, 16);
1513mem_ptr!(ptr256, 32);
1514mem_ptr!(ptr512, 64);
1515
1516mem_ptr!(byte_ptr, 1);
1517mem_ptr!(word_ptr, 2);
1518mem_ptr!(dword_ptr, 4);
1519mem_ptr!(fword_ptr, 6);
1520mem_ptr!(qword_ptr, 8);
1521mem_ptr!(tbyte_ptr, 10);
1522mem_ptr!(tword_ptr, 10);
1523mem_ptr!(oword_ptr, 16);
1524mem_ptr!(dqword_ptr, 16);
1525mem_ptr!(qqword_ptr, 32);
1526mem_ptr!(xmmword_ptr, 16);
1527mem_ptr!(ymmword_ptr, 32);
1528mem_ptr!(zmmword_ptr, 64);
1529
1530pub fn ptr(base: impl Deref<Target = Gp>, offset: i32, size: u32) -> Mem {
1531    Mem::from_base_and_disp(base.deref(), offset, size, 0.into())
1532}
1533
1534pub fn ptr_index(
1535    base: impl Deref<Target = Gp>,
1536    index: impl Deref<Target = Gp>,
1537    shift: u32,
1538    offset: i32,
1539    size: u32,
1540) -> Mem {
1541    Mem::from_base_and_index_shift_disp(base.deref(), index.deref(), shift, offset, size, 0.into())
1542}
1543
1544pub fn label_ptr(base: Label, offset: i32, size: u32) -> Mem {
1545    Mem::from_label_and_disp(&base, offset, size, 0.into())
1546}
1547pub fn label_ptr_index(
1548    base: Label,
1549    index: impl Deref<Target = Gp>,
1550    shift: u32,
1551    offset: i32,
1552    size: u32,
1553) -> Mem {
1554    Mem::from_label_and_index_shift_disp(&base, index.deref(), shift, offset, size, 0.into())
1555}
1556
1557pub fn sym_ptr(base: Sym, offset: i32, size: u32) -> Mem {
1558    Mem::from_sym_and_disp(&base, offset, size, 0.into())
1559}
1560pub fn sym_ptr_index(
1561    base: Sym,
1562    index: impl Deref<Target = Gp>,
1563    shift: u32,
1564    offset: i32,
1565    size: u32,
1566) -> Mem {
1567    Mem::from_sym_and_index_shift_disp(&base, index.deref(), shift, offset, size, 0.into())
1568}
1569
1570pub fn rip_rel(offset: i32, size: u32) -> Mem {
1571    Mem::from_base_and_disp(&RIP, offset, size, 0.into())
1572}
1573
1574pub fn u64_ptr(base: u64, size: u32) -> Mem {
1575    Mem::from_u64(base, size, 0.into())
1576}
1577
1578pub fn u64_ptr_index(base: u64, index: impl Deref<Target = Gp>, shift: u32, size: u32) -> Mem {
1579    Mem::from_u64_and_index_shift_disp(base, index.deref(), shift, size, 0.into())
1580}
1581
1582pub fn u64_ptr_abs(base: u64, size: u32) -> Mem {
1583    Mem::from_u64(
1584        base,
1585        size,
1586        OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Abs as _),
1587    )
1588}
1589
1590pub fn u64_ptr_index_abs(base: u64, index: impl Deref<Target = Gp>, shift: u32, size: u32) -> Mem {
1591    Mem::from_u64_and_index_shift_disp(
1592        base,
1593        index.deref(),
1594        shift,
1595        size,
1596        OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Abs as _),
1597    )
1598}
1599
1600// ============================================================================
1601// Display Implementations for X86 Operand Types
1602// ============================================================================
1603use core::fmt;
1604
1605impl fmt::Display for Reg {
1606    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1607        if !self.is_valid() {
1608            return write!(f, "reg_invalid");
1609        }
1610
1611        // Display based on specific register type
1612        if self.is_gpb_lo() {
1613            write!(f, "{}", GpbLo::from_type_and_id(RegType::Gp8Lo, self.id()))
1614        } else if self.is_gpb_hi() {
1615            write!(f, "{}", GpbHi::from_type_and_id(RegType::Gp8Hi, self.id()))
1616        } else if self.is_gpw() {
1617            write!(f, "{}", Gpw::from_type_and_id(RegType::Gp16, self.id()))
1618        } else if self.is_gpd() {
1619            write!(f, "{}", Gpd::from_type_and_id(RegType::Gp32, self.id()))
1620        } else if self.is_gpq() {
1621            write!(f, "{}", Gpq::from_type_and_id(RegType::Gp64, self.id()))
1622        } else if self.is_xmm() {
1623            write!(f, "{}", Xmm::from_type_and_id(RegType::Vec128, self.id()))
1624        } else if self.is_ymm() {
1625            write!(f, "{}", Ymm::from_type_and_id(RegType::Vec256, self.id()))
1626        } else if self.is_zmm() {
1627            write!(f, "{}", Zmm::from_type_and_id(RegType::Vec512, self.id()))
1628        } else if self.is_type(RegType::X86Mm) {
1629            write!(f, "{}", Mm::from_type_and_id(RegType::X86Mm, self.id()))
1630        } else if self.is_type(RegType::X86KReg) {
1631            write!(f, "{}", KReg::from_type_and_id(RegType::X86KReg, self.id()))
1632        } else if self.is_type(RegType::X86SReg) {
1633            write!(f, "{}", SReg::from_type_and_id(RegType::X86SReg, self.id()))
1634        } else if self.is_type(RegType::X86CReg) {
1635            write!(f, "{}", CReg::from_type_and_id(RegType::X86CReg, self.id()))
1636        } else if self.is_type(RegType::X86DReg) {
1637            write!(f, "{}", DReg::from_type_and_id(RegType::X86DReg, self.id()))
1638        } else if self.is_type(RegType::X86St) {
1639            write!(f, "{}", St::from_type_and_id(RegType::X86St, self.id()))
1640        } else if self.is_type(RegType::X86Bnd) {
1641            write!(f, "{}", Bnd::from_type_and_id(RegType::X86Bnd, self.id()))
1642        } else if self.is_type(RegType::X86Tmm) {
1643            write!(f, "{}", Tmm::from_type_and_id(RegType::X86Tmm, self.id()))
1644        } else if self.is_type(RegType::X86Rip) {
1645            write!(f, "{}", Rip::from_type_and_id(RegType::X86Rip, self.id()))
1646        } else {
1647            write!(f, "reg{}", self.id())
1648        }
1649    }
1650}
1651
1652impl fmt::Display for Gp {
1653    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1654        if !self.is_valid() {
1655            return write!(f, "gp_invalid");
1656        }
1657
1658        // Use common x86 register names for physical registers
1659        if self.id() < 16 {
1660            match self.size() {
1661                1 => {
1662                    // 8-bit registers
1663                    if self.id() < 4 {
1664                        // Low 8-bit: AL, CL, DL, BL
1665                        let names = ["al", "cl", "dl", "bl"];
1666                        write!(f, "{}", names[self.id() as usize])
1667                    } else if self.id() < 8 {
1668                        // High 8-bit: AH, CH, DH, BH
1669                        let names = ["ah", "ch", "dh", "bh"];
1670                        write!(f, "{}", names[(self.id() - 4) as usize])
1671                    } else {
1672                        // R8B-R15B
1673                        write!(f, "r{}b", self.id() - 8)
1674                    }
1675                }
1676                2 => {
1677                    // 16-bit registers
1678                    if self.id() < 8 {
1679                        let names = ["ax", "cx", "dx", "bx", "sp", "bp", "si", "di"];
1680                        write!(f, "{}", names[self.id() as usize])
1681                    } else {
1682                        write!(f, "r{}w", self.id() - 8)
1683                    }
1684                }
1685                4 => {
1686                    // 32-bit registers
1687                    if self.id() < 8 {
1688                        let names = ["eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"];
1689                        write!(f, "{}", names[self.id() as usize])
1690                    } else {
1691                        write!(f, "r{}d", self.id() - 8)
1692                    }
1693                }
1694                8 => {
1695                    // 64-bit registers
1696                    if self.id() < 8 {
1697                        let names = ["rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"];
1698                        write!(f, "{}", names[self.id() as usize])
1699                    } else {
1700                        write!(f, "r{}", self.id() - 8)
1701                    }
1702                }
1703                _ => write!(f, "gp{}", self.id()),
1704            }
1705        } else {
1706            write!(f, "gp{}", self.id())
1707        }
1708    }
1709}
1710
1711impl fmt::Display for Vec {
1712    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1713        if !self.is_valid() {
1714            return write!(f, "vec_invalid");
1715        }
1716        write!(f, "vec{}", self.id())
1717    }
1718}
1719
1720impl fmt::Display for SReg {
1721    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1722        if !self.is_valid() {
1723            return write!(f, "sreg_invalid");
1724        }
1725
1726        match self.id() {
1727            SReg::ES => write!(f, "es"),
1728            SReg::CS => write!(f, "cs"),
1729            SReg::SS => write!(f, "ss"),
1730            SReg::DS => write!(f, "ds"),
1731            SReg::FS => write!(f, "fs"),
1732            SReg::GS => write!(f, "gs"),
1733            _ => write!(f, "sreg{}", self.id()),
1734        }
1735    }
1736}
1737
1738impl fmt::Display for Gpb {
1739    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1740        write!(f, "{}", Reg::from_type_and_id(self.typ(), self.id()))
1741    }
1742}
1743
1744impl fmt::Display for GpbLo {
1745    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1746        if !self.is_valid() {
1747            return write!(f, "gpblo_invalid");
1748        }
1749
1750        if self.id() < 4 {
1751            let names = ["al", "cl", "dl", "bl"];
1752            write!(f, "{}", names[self.id() as usize])
1753        } else if self.id() < 8 {
1754            write!(f, "spl")
1755        } else {
1756            write!(f, "r{}b", self.id() - 8)
1757        }
1758    }
1759}
1760
1761impl fmt::Display for GpbHi {
1762    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1763        if !self.is_valid() {
1764            return write!(f, "gpbhi_invalid");
1765        }
1766
1767        let names = ["ah", "ch", "dh", "bh"];
1768        write!(f, "{}", names[self.id() as usize])
1769    }
1770}
1771
1772impl fmt::Display for Gpw {
1773    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1774        if !self.is_valid() {
1775            return write!(f, "gpw_invalid");
1776        }
1777
1778        if self.id() < 8 {
1779            let names = ["ax", "cx", "dx", "bx", "sp", "bp", "si", "di"];
1780            write!(f, "{}", names[self.id() as usize])
1781        } else {
1782            write!(f, "r{}w", self.id() - 8)
1783        }
1784    }
1785}
1786
1787impl fmt::Display for Gpd {
1788    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1789        if !self.is_valid() {
1790            return write!(f, "gpd_invalid");
1791        }
1792
1793        if self.id() < 8 {
1794            let names = ["eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"];
1795            write!(f, "{}", names[self.id() as usize])
1796        } else {
1797            write!(f, "r{}d", self.id() - 8)
1798        }
1799    }
1800}
1801
1802impl fmt::Display for Gpq {
1803    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1804        if !self.is_valid() {
1805            return write!(f, "gpq_invalid");
1806        }
1807
1808        if self.id() < 8 {
1809            let names = ["rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"];
1810            write!(f, "{}", names[self.id() as usize])
1811        } else {
1812            write!(f, "r{}", self.id() - 8)
1813        }
1814    }
1815}
1816
1817impl fmt::Display for Xmm {
1818    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1819        if !self.is_valid() {
1820            return write!(f, "xmm_invalid");
1821        }
1822        write!(f, "xmm{}", self.id())
1823    }
1824}
1825
1826impl fmt::Display for Ymm {
1827    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1828        if !self.is_valid() {
1829            return write!(f, "ymm_invalid");
1830        }
1831        write!(f, "ymm{}", self.id())
1832    }
1833}
1834
1835impl fmt::Display for Zmm {
1836    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1837        if !self.is_valid() {
1838            return write!(f, "zmm_invalid");
1839        }
1840        write!(f, "zmm{}", self.id())
1841    }
1842}
1843
1844impl fmt::Display for Mm {
1845    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1846        if !self.is_valid() {
1847            return write!(f, "mm_invalid");
1848        }
1849        write!(f, "mm{}", self.id())
1850    }
1851}
1852
1853impl fmt::Display for KReg {
1854    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1855        if !self.is_valid() {
1856            return write!(f, "kreg_invalid");
1857        }
1858        write!(f, "k{}", self.id())
1859    }
1860}
1861
1862impl fmt::Display for CReg {
1863    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1864        if !self.is_valid() {
1865            return write!(f, "creg_invalid");
1866        }
1867        write!(f, "cr{}", self.id())
1868    }
1869}
1870
1871impl fmt::Display for DReg {
1872    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1873        if !self.is_valid() {
1874            return write!(f, "dreg_invalid");
1875        }
1876        write!(f, "dr{}", self.id())
1877    }
1878}
1879
1880impl fmt::Display for St {
1881    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1882        if !self.is_valid() {
1883            return write!(f, "st_invalid");
1884        }
1885        write!(f, "st{}", self.id())
1886    }
1887}
1888
1889impl fmt::Display for Bnd {
1890    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1891        if !self.is_valid() {
1892            return write!(f, "bnd_invalid");
1893        }
1894        write!(f, "bnd{}", self.id())
1895    }
1896}
1897
1898impl fmt::Display for Tmm {
1899    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1900        if !self.is_valid() {
1901            return write!(f, "tmm_invalid");
1902        }
1903        write!(f, "tmm{}", self.id())
1904    }
1905}
1906
1907impl fmt::Display for Rip {
1908    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1909        write!(f, "rip")
1910    }
1911}
1912
1913impl fmt::Display for Mem {
1914    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1915        use alloc::format;
1916        use alloc::string::ToString;
1917        let mut output_parts = alloc::vec::Vec::new();
1918
1919        // Segment override
1920        if self.has_segment() {
1921            output_parts.push(format!("{}:", self.segment()));
1922        }
1923
1924        // Base
1925        if self.has_base() {
1926            if self.has_base_label() {
1927                output_parts.push(format!("label{}", self.base_id()));
1928            } else if self.has_base_sym() {
1929                output_parts.push(format!("sym{}", self.base_id()));
1930            } else if self.has_base_reg() {
1931                let base_reg = self.base_reg();
1932                output_parts.push(format!("{}", base_reg));
1933            }
1934        }
1935
1936        // Index with shift
1937        if self.has_index() && self.has_index_reg() {
1938            let index_reg = self.index_reg();
1939            if self.has_shift() {
1940                output_parts.push(format!("{}*{}", index_reg, self.shift()));
1941            } else {
1942                output_parts.push(format!("{}", index_reg));
1943            }
1944        }
1945
1946        // Offset
1947        if self.has_offset() {
1948            let offset = self.offset();
1949            if offset >= 0 {
1950                if !output_parts.is_empty() {
1951                    output_parts.push(format!("+{}", offset));
1952                } else {
1953                    output_parts.push(format!("{}", offset));
1954                }
1955            } else {
1956                output_parts.push(format!("{}", offset));
1957            }
1958        }
1959
1960        // Broadcast
1961        if self.has_broadcast() {
1962            output_parts.push(format!(" {{{}}}", self.get_broadcast() as u32));
1963        }
1964
1965        // Address type
1966        match self.addr_type() {
1967            AddrType::Abs => output_parts.push(" abs".to_string()),
1968            AddrType::Rel => output_parts.push(" rel".to_string()),
1969            AddrType::Default => {}
1970        }
1971
1972        if output_parts.is_empty() {
1973            write!(f, "byte ptr [0]")
1974        } else {
1975            write!(f, "[{}]", output_parts.join(" "))
1976        }
1977    }
1978}
1979
1980impl fmt::Display for Broadcast {
1981    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1982        match self {
1983            Broadcast::None => write!(f, "none"),
1984            Broadcast::B1To2 => write!(f, "1to2"),
1985            Broadcast::B1To4 => write!(f, "1to4"),
1986            Broadcast::B1To8 => write!(f, "1to8"),
1987            Broadcast::B1To16 => write!(f, "1to16"),
1988            Broadcast::B1To32 => write!(f, "1to32"),
1989            Broadcast::B1To64 => write!(f, "1to64"),
1990        }
1991    }
1992}
1993
1994impl fmt::Display for AddrType {
1995    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1996        match self {
1997            AddrType::Default => write!(f, "default"),
1998            AddrType::Abs => write!(f, "abs"),
1999            AddrType::Rel => write!(f, "rel"),
2000        }
2001    }
2002}
2003
2004pub struct AbsoluteAddress(Mem);
2005
2006impl AbsoluteAddress {
2007    pub fn new(addr: u64, size: u32) -> Self {
2008        Self(Mem::from_u64(
2009            addr,
2010            size,
2011            OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(
2012                AddrType::Abs as _,
2013            ),
2014        ))
2015    }
2016
2017    pub fn from_mem(mem: Mem) -> Self {
2018        assert!(mem.is_abs());
2019        Self(mem)
2020    }
2021
2022    pub fn address(&self) -> u64 {
2023        self.0.absolute_address()
2024    }
2025}
2026
2027impl OperandCast for AbsoluteAddress {
2028    fn as_operand(&self) -> &Operand {
2029        self.0.as_operand()
2030    }
2031
2032    fn from_operand(op: &Operand) -> Self {
2033        Self(op.as_::<Mem>())
2034    }
2035}