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