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