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