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