1use core::ops::{Add, Deref, Mul};
2
3use derive_more::derive::{Deref, DerefMut};
4
5use crate::{
6 core::{
7 arch_traits::{Arch, ArchTraits},
8 operand::*,
9 types::TypeId,
10 },
11 define_abstract_reg, define_final_reg, define_operand_cast, define_reg_traits,
12};
13
14define_reg_traits!(X86Rip, RegGroup::X86Rip, 0, TypeId::Void);
15define_reg_traits!(X86GpbLo, RegGroup::Gp, 1, TypeId::Int8);
16define_reg_traits!(X86GpbHi, RegGroup::Gp, 1, TypeId::Int8);
17define_reg_traits!(X86Gpw, RegGroup::Gp, 2, TypeId::Int16);
18define_reg_traits!(X86Gpd, RegGroup::Gp, 4, TypeId::Int32);
19define_reg_traits!(X86Gpq, RegGroup::Gp, 8, TypeId::Int64);
20define_reg_traits!(X86Xmm, RegGroup::Vec, 16, TypeId::Int32x4);
21define_reg_traits!(X86Ymm, RegGroup::Vec, 32, TypeId::Int32x8);
22define_reg_traits!(X86Zmm, RegGroup::Vec, 64, TypeId::Int32x16);
23define_reg_traits!(X86KReg, RegGroup::X86K, 0, TypeId::Void);
24define_reg_traits!(X86Mm, RegGroup::X86MM, 8, TypeId::Mmx64);
25define_reg_traits!(X86SReg, RegGroup::X86SReg, 2, TypeId::Void);
26define_reg_traits!(X86CReg, RegGroup::X86CReg, 0, TypeId::Void);
27define_reg_traits!(X86DReg, RegGroup::X86DReg, 0, TypeId::Void);
28define_reg_traits!(X86St, RegGroup::X86St, 10, TypeId::Float80);
29define_reg_traits!(X86Bnd, RegGroup::X86Bnd, 16, TypeId::Void);
30define_reg_traits!(X86Tmm, RegGroup::X86Tmm, 0, TypeId::Void);
31
32#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
33pub struct Reg(pub BaseReg);
34
35define_abstract_reg!(Reg, BaseReg);
36
37impl Reg {
38 pub const fn signature_of(typ: RegType) -> OperandSignature {
39 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
40 }
41
42 pub fn is_gpb(&self) -> bool {
43 self.size() == 1
44 }
45
46 pub fn is_gpb_lo(&self) -> bool {
47 self.has_base_signature(X86GpbLo::SIGNATURE)
48 }
49
50 pub fn is_gpb_hi(&self) -> bool {
51 self.has_base_signature(X86GpbHi::SIGNATURE)
52 }
53
54 pub fn is_gpw(&self) -> bool {
55 self.has_base_signature(X86Gpw::SIGNATURE)
56 }
57
58 pub fn is_gpd(&self) -> bool {
59 self.has_base_signature(X86Gpd::SIGNATURE)
60 }
61
62 pub fn is_gpq(&self) -> bool {
63 self.has_base_signature(X86Gpq::SIGNATURE)
64 }
65
66 pub fn is_gp32(&self) -> bool {
67 self.has_base_signature(X86Gpd::SIGNATURE)
68 }
69
70 pub fn is_gp64(&self) -> bool {
71 self.has_base_signature(X86Gpq::SIGNATURE)
72 }
73
74 pub fn is_xmm(&self) -> bool {
75 self.has_base_signature(X86Xmm::SIGNATURE)
76 }
77
78 pub fn is_ymm(&self) -> bool {
79 self.has_base_signature(X86Ymm::SIGNATURE)
80 }
81
82 pub fn is_zmm(&self) -> bool {
83 self.has_base_signature(X86Zmm::SIGNATURE)
84 }
85
86 pub fn is_vec128(&self) -> bool {
87 self.has_base_signature(X86Xmm::SIGNATURE)
88 }
89
90 pub fn is_vec256(&self) -> bool {
91 self.has_base_signature(X86Ymm::SIGNATURE)
92 }
93
94 pub fn is_vec512(&self) -> bool {
95 self.has_base_signature(X86Zmm::SIGNATURE)
96 }
97
98 pub fn is_mm(&self) -> bool {
99 self.has_base_signature(X86Mm::SIGNATURE)
100 }
101
102 pub fn is_k_reg(&self) -> bool {
103 self.has_base_signature(X86KReg::SIGNATURE)
104 }
105
106 pub fn is_s_reg(&self) -> bool {
107 self.has_base_signature(X86SReg::SIGNATURE)
108 }
109
110 pub fn is_c_reg(&self) -> bool {
111 self.has_base_signature(X86CReg::SIGNATURE)
112 }
113
114 pub fn is_d_reg(&self) -> bool {
115 self.has_base_signature(X86DReg::SIGNATURE)
116 }
117
118 pub fn is_st(&self) -> bool {
119 self.has_base_signature(X86St::SIGNATURE)
120 }
121
122 pub fn is_bnd(&self) -> bool {
123 self.has_base_signature(X86Bnd::SIGNATURE)
124 }
125
126 pub fn is_tmm(&self) -> bool {
127 self.has_base_signature(X86Tmm::SIGNATURE)
128 }
129
130 pub fn is_rip(&self) -> bool {
131 self.has_base_signature(X86Rip::SIGNATURE)
132 }
133
134 pub fn set_reg_t<T: RegTraits>(&mut self, rid: u32) {
135 self.set_signature(T::SIGNATURE.into());
136 self.set_id(rid);
137 }
138
139 pub fn set_type_and_id(&mut self, typ: RegType, id: u32) {
140 self.set_signature(Self::signature_of(typ));
141 self.set_id(id);
142 }
143
144 pub fn group_of(typ: RegType) -> RegGroup {
145 ArchTraits::by_arch(Arch::X86).reg_type_to_group(typ)
146 }
147
148 pub const fn type_id_of(typ: RegType) -> TypeId {
149 ArchTraits::by_arch(Arch::X86).reg_type_to_type_id(typ)
150 }
151
152 pub const fn group_of_t<T: RegTraits>() -> RegGroup {
153 T::GROUP
154 }
155
156 pub const fn type_id_of_t<T: RegTraits>() -> TypeId {
157 T::TYPE_ID
158 }
159
160 pub const fn signature_of_vec_by_type(typ: TypeId) -> OperandSignature {
161 let typ = typ as u32;
162
163 if typ <= TypeId::VEC128_END {
164 OperandSignature::new(X86Xmm::SIGNATURE)
165 } else if typ <= TypeId::VEC256_END {
166 OperandSignature::new(X86Ymm::SIGNATURE)
167 } else {
168 OperandSignature::new(X86Zmm::SIGNATURE)
169 }
170 }
171
172 pub const fn signature_of_vec_by_size(size: u32) -> OperandSignature {
173 if size <= 16 {
174 OperandSignature::new(X86Xmm::SIGNATURE)
175 } else if size <= 32 {
176 OperandSignature::new(X86Ymm::SIGNATURE)
177 } else {
178 OperandSignature::new(X86Zmm::SIGNATURE)
179 }
180 }
181
182 pub fn operand_is_gpb(op: &Operand) -> bool {
183 op.signature.subset(
184 OperandSignature::OP_TYPE_MASK
185 | OperandSignature::REG_GROUP_MASK
186 | OperandSignature::SIZE_MASK,
187 ) == (OperandSignature::from_op_type(OperandType::Reg)
188 | OperandSignature::from_reg_group(RegGroup::Gp)
189 | OperandSignature::from_size(1))
190 }
191
192 pub fn operand_is_gpb_lo(op: &Operand) -> bool {
193 op.as_::<Self>().is_gpb_lo()
194 }
195 pub fn operand_is_gpb_hi(op: &Operand) -> bool {
196 op.as_::<Self>().is_gpb_hi()
197 }
198 pub fn operand_is_gpw(op: &Operand) -> bool {
199 op.as_::<Self>().is_gpw()
200 }
201 pub fn operand_is_gpd(op: &Operand) -> bool {
202 op.as_::<Self>().is_gpd()
203 }
204 pub fn operand_is_gpq(op: &Operand) -> bool {
205 op.as_::<Self>().is_gpq()
206 }
207 pub fn operand_is_xmm(op: &Operand) -> bool {
208 op.as_::<Self>().is_xmm()
209 }
210 pub fn operand_is_ymm(op: &Operand) -> bool {
211 op.as_::<Self>().is_ymm()
212 }
213 pub fn operand_is_zmm(op: &Operand) -> bool {
214 op.as_::<Self>().is_zmm()
215 }
216 pub fn operand_is_mm(op: &Operand) -> bool {
217 op.as_::<Self>().is_mm()
218 }
219 pub fn operand_is_k_reg(op: &Operand) -> bool {
220 op.as_::<Self>().is_k_reg()
221 }
222 pub fn operand_is_s_reg(op: &Operand) -> bool {
223 op.as_::<Self>().is_s_reg()
224 }
225 pub fn operand_is_c_reg(op: &Operand) -> bool {
226 op.as_::<Self>().is_c_reg()
227 }
228 pub fn operand_is_d_reg(op: &Operand) -> bool {
229 op.as_::<Self>().is_d_reg()
230 }
231 pub fn operand_is_st(op: &Operand) -> bool {
232 op.as_::<Self>().is_st()
233 }
234 pub fn operand_is_bnd(op: &Operand) -> bool {
235 op.as_::<Self>().is_bnd()
236 }
237 pub fn operand_is_tmm(op: &Operand) -> bool {
238 op.as_::<Self>().is_tmm()
239 }
240 pub fn operand_is_rip(op: &Operand) -> bool {
241 op.as_::<Self>().is_rip()
242 }
243
244 pub fn operand_is_gpb_with_id(op: &Operand, rid: u32) -> bool {
245 (Self::operand_is_gpb(op) as u32 & (op.id() == rid) as u32) != 0
246 }
247 pub fn operand_is_gpb_lo_with_id(op: &Operand, rid: u32) -> bool {
248 (Self::operand_is_gpb_lo(op) as u32 & (op.id() == rid) as u32) != 0
249 }
250 pub fn operand_is_gpb_hi_with_id(op: &Operand, rid: u32) -> bool {
251 (Self::operand_is_gpb_hi(op) as u32 & (op.id() == rid) as u32) != 0
252 }
253 pub fn operand_is_gpw_with_id(op: &Operand, rid: u32) -> bool {
254 (Self::operand_is_gpw(op) as u32 & (op.id() == rid) as u32) != 0
255 }
256 pub fn operand_is_gpd_with_id(op: &Operand, rid: u32) -> bool {
257 (Self::operand_is_gpd(op) as u32 & (op.id() == rid) as u32) != 0
258 }
259 pub fn operand_is_gpq_with_id(op: &Operand, rid: u32) -> bool {
260 (Self::operand_is_gpq(op) as u32 & (op.id() == rid) as u32) != 0
261 }
262 pub fn operand_is_xmm_with_id(op: &Operand, rid: u32) -> bool {
263 (Self::operand_is_xmm(op) as u32 & (op.id() == rid) as u32) != 0
264 }
265 pub fn operand_is_ymm_with_id(op: &Operand, rid: u32) -> bool {
266 (Self::operand_is_ymm(op) as u32 & (op.id() == rid) as u32) != 0
267 }
268 pub fn operand_is_zmm_with_id(op: &Operand, rid: u32) -> bool {
269 (Self::operand_is_zmm(op) as u32 & (op.id() == rid) as u32) != 0
270 }
271 pub fn operand_is_mm_with_id(op: &Operand, rid: u32) -> bool {
272 (Self::operand_is_mm(op) as u32 & (op.id() == rid) as u32) != 0
273 }
274 pub fn operand_is_k_reg_with_id(op: &Operand, rid: u32) -> bool {
275 (Self::operand_is_k_reg(op) as u32 & (op.id() == rid) as u32) != 0
276 }
277 pub fn operand_is_s_reg_with_id(op: &Operand, rid: u32) -> bool {
278 (Self::operand_is_s_reg(op) as u32 & (op.id() == rid) as u32) != 0
279 }
280 pub fn operand_is_c_reg_with_id(op: &Operand, rid: u32) -> bool {
281 (Self::operand_is_c_reg(op) as u32 & (op.id() == rid) as u32) != 0
282 }
283 pub fn operand_is_d_reg_with_id(op: &Operand, rid: u32) -> bool {
284 (Self::operand_is_d_reg(op) as u32 & (op.id() == rid) as u32) != 0
285 }
286 pub fn operand_is_st_with_id(op: &Operand, rid: u32) -> bool {
287 (Self::operand_is_st(op) as u32 & (op.id() == rid) as u32) != 0
288 }
289 pub fn operand_is_bnd_with_id(op: &Operand, rid: u32) -> bool {
290 (Self::operand_is_bnd(op) as u32 & (op.id() == rid) as u32) != 0
291 }
292 pub fn operand_is_tmm_with_id(op: &Operand, rid: u32) -> bool {
293 (Self::operand_is_tmm(op) as u32 & (op.id() == rid) as u32) != 0
294 }
295 pub fn operand_is_rip_with_id(op: &Operand, rid: u32) -> bool {
296 (Self::operand_is_rip(op) as u32 & (op.id() == rid) as u32) != 0
297 }
298
299 pub const SIGNATURE: u32 = BaseReg::SIGNATURE;
300}
301
302#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
303pub struct Gp(pub Reg);
304
305define_abstract_reg!(Gp, Reg);
306
307impl Gp {
308 pub const fn signature_of(typ: RegType) -> OperandSignature {
309 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
310 }
311
312 pub const AX: u32 = 0;
313 pub const CX: u32 = 1;
314 pub const DX: u32 = 2;
315 pub const BX: u32 = 3;
316 pub const SP: u32 = 4;
317 pub const BP: u32 = 5;
318 pub const SI: u32 = 6;
319 pub const DI: u32 = 7;
320 pub const R8: u32 = 8;
321 pub const R9: u32 = 9;
322 pub const R10: u32 = 10;
323 pub const R11: u32 = 11;
324 pub const R12: u32 = 12;
325 pub const R13: u32 = 13;
326 pub const R14: u32 = 14;
327 pub const R15: u32 = 15;
328
329 pub const SIGNATURE: u32 = Reg::SIGNATURE;
330}
331
332#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
333pub struct Vec(pub Reg);
334
335define_abstract_reg!(Vec, Reg);
336
337impl Vec {
338 pub const fn signature_of(typ: RegType) -> OperandSignature {
339 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
340 }
341
342 pub const SIGNATURE: u32 = Reg::SIGNATURE;
343}
344
345#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
346pub struct SReg(pub Reg);
347
348impl SReg {
349 pub const fn signature_of(typ: RegType) -> OperandSignature {
350 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
351 }
352
353 pub const ES: u32 = 1;
354 pub const CS: u32 = 2;
355 pub const SS: u32 = 3;
356 pub const DS: u32 = 4;
357 pub const FS: u32 = 5;
358 pub const GS: u32 = 6;
359}
360
361define_final_reg!(SReg, Reg, X86SReg);
362
363#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
364pub struct Gpb(pub Gp);
365
366define_abstract_reg!(Gpb, Gp);
367
368impl Gpb {
369 pub const fn signature_of(typ: RegType) -> OperandSignature {
370 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
371 }
372
373 pub const SIGNATURE: u32 = Gp::SIGNATURE;
374}
375
376#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
377pub struct GpbLo(pub Gpb);
378
379impl GpbLo {
380 pub const fn signature_of(typ: RegType) -> OperandSignature {
381 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
382 }
383}
384
385define_final_reg!(GpbLo, Gpb, X86GpbLo);
386
387#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
388pub struct GpbHi(pub Gpb);
389
390impl GpbHi {
391 pub const fn signature_of(typ: RegType) -> OperandSignature {
392 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
393 }
394}
395
396define_final_reg!(GpbHi, Gpb, X86GpbHi);
397
398#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
399pub struct Gpw(pub Gp);
400
401impl Gpw {
402 pub const fn signature_of(typ: RegType) -> OperandSignature {
403 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
404 }
405}
406
407define_final_reg!(Gpw, Gp, X86Gpw);
408
409#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
410pub struct Gpd(pub Gp);
411
412impl Gpd {
413 pub const fn signature_of(typ: RegType) -> OperandSignature {
414 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
415 }
416}
417
418define_final_reg!(Gpd, Gp, X86Gpd);
419
420#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
421pub struct Gpq(pub Gp);
422
423impl Gpq {
424 pub const fn signature_of(typ: RegType) -> OperandSignature {
425 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
426 }
427}
428
429define_final_reg!(Gpq, Gp, X86Gpq);
430
431#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
432pub struct Xmm(pub Vec);
433
434impl Xmm {
435 pub const fn signature_of(typ: RegType) -> OperandSignature {
436 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
437 }
438
439 pub fn half(&self) -> Xmm {
440 Xmm::from_id(self.id())
441 }
442}
443
444define_final_reg!(Xmm, Vec, X86Xmm);
445
446#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
447pub struct Ymm(pub Vec);
448
449impl Ymm {
450 pub const fn signature_of(typ: RegType) -> OperandSignature {
451 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
452 }
453
454 pub fn half(&self) -> Xmm {
455 Xmm::from_id(self.id())
456 }
457}
458
459define_final_reg!(Ymm, Vec, X86Ymm);
460
461#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
462pub struct Zmm(pub Vec);
463
464impl Zmm {
465 pub const fn signature_of(typ: RegType) -> OperandSignature {
466 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
467 }
468
469 pub fn half(&self) -> Ymm {
470 Ymm::from_id(self.id())
471 }
472}
473
474define_final_reg!(Zmm, Vec, X86Zmm);
475
476#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
477pub struct Mm(pub Reg);
478
479impl Mm {
480 pub const fn signature_of(typ: RegType) -> OperandSignature {
481 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
482 }
483}
484
485define_final_reg!(Mm, Reg, X86Mm);
486
487#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
488pub struct KReg(pub Reg);
489
490impl KReg {
491 pub const fn signature_of(typ: RegType) -> OperandSignature {
492 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
493 }
494}
495
496define_final_reg!(KReg, Reg, X86KReg);
497
498#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
499pub struct CReg(pub Reg);
500
501impl CReg {
502 pub const fn signature_of(typ: RegType) -> OperandSignature {
503 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
504 }
505}
506
507define_final_reg!(CReg, Reg, X86CReg);
508
509#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
510pub struct DReg(pub Reg);
511
512impl DReg {
513 pub const fn signature_of(typ: RegType) -> OperandSignature {
514 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
515 }
516}
517
518define_final_reg!(DReg, Reg, X86DReg);
519
520#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
521pub struct St(pub Reg);
522
523impl St {
524 pub const fn signature_of(typ: RegType) -> OperandSignature {
525 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
526 }
527}
528
529define_final_reg!(St, Reg, X86St);
530
531#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
532pub struct Bnd(pub Reg);
533
534impl Bnd {
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!(Bnd, Reg, X86Bnd);
541
542#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
543pub struct Tmm(pub Reg);
544
545impl Tmm {
546 pub const fn signature_of(typ: RegType) -> OperandSignature {
547 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
548 }
549}
550
551define_final_reg!(Tmm, Reg, X86Tmm);
552
553#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
554pub struct Rip(pub Reg);
555
556impl Rip {
557 pub const fn signature_of(typ: RegType) -> OperandSignature {
558 ArchTraits::by_arch(Arch::X86).reg_type_to_signature(typ)
559 }
560}
561
562define_final_reg!(Rip, Reg, X86Rip);
563
564impl Gp {
565 pub fn r8(&self) -> GpbLo {
566 GpbLo::from_id(self.id())
567 }
568
569 pub fn r8lo(&self) -> GpbLo {
570 GpbLo::from_id(self.id())
571 }
572
573 pub fn r8hi(&self) -> GpbHi {
574 GpbHi::from_id(self.id())
575 }
576
577 pub fn r16(&self) -> Gpw {
578 Gpw::from_id(self.id())
579 }
580
581 pub fn r32(&self) -> Gpd {
582 Gpd::from_id(self.id())
583 }
584
585 pub fn r64(&self) -> Gpq {
586 Gpq::from_id(self.id())
587 }
588}
589impl Vec {
590 pub fn xmm(&self) -> Xmm {
591 Xmm::from_id(self.id())
592 }
593
594 pub fn ymm(&self) -> Ymm {
595 Ymm::from_id(self.id())
596 }
597
598 pub fn zmm(&self) -> Zmm {
599 Zmm::from_id(self.id())
600 }
601
602 pub fn v128(&self) -> Xmm {
603 Xmm::from_id(self.id())
604 }
605
606 pub fn v256(&self) -> Ymm {
607 Ymm::from_id(self.id())
608 }
609
610 pub fn v512(&self) -> Zmm {
611 Zmm::from_id(self.id())
612 }
613}
614
615pub mod regs {
616 use super::*;
617 pub const fn gpb(id: u32) -> GpbLo {
618 GpbLo::from_id(id)
619 }
620
621 pub const fn gpb_lo(id: u32) -> GpbLo {
622 GpbLo::from_id(id)
623 }
624
625 pub const fn gpb_hi(id: u32) -> GpbHi {
626 GpbHi::from_id(id)
627 }
628
629 pub const fn gpw(id: u32) -> Gpw {
630 Gpw::from_id(id)
631 }
632
633 pub const fn gpd(id: u32) -> Gpd {
634 Gpd::from_id(id)
635 }
636
637 pub const fn gpq(id: u32) -> Gpq {
638 Gpq::from_id(id)
639 }
640
641 pub const fn xmm(id: u32) -> Xmm {
642 Xmm::from_id(id)
643 }
644
645 pub const fn ymm(id: u32) -> Ymm {
646 Ymm::from_id(id)
647 }
648
649 pub const fn zmm(id: u32) -> Zmm {
650 Zmm::from_id(id)
651 }
652
653 pub const fn mm(id: u32) -> Mm {
654 Mm::from_id(id)
655 }
656
657 pub const fn k(id: u32) -> KReg {
658 KReg::from_id(id)
659 }
660
661 pub const fn cr(id: u32) -> CReg {
662 CReg::from_id(id)
663 }
664
665 pub const fn dr(id: u32) -> DReg {
666 DReg::from_id(id)
667 }
668
669 pub const fn st(id: u32) -> St {
670 St::from_id(id)
671 }
672
673 pub const fn bnd(id: u32) -> Bnd {
674 Bnd::from_id(id)
675 }
676
677 pub const fn tmm(id: u32) -> Tmm {
678 Tmm::from_id(id)
679 }
680
681 pub const fn rip() -> Rip {
682 Rip::from_id(0x120)
683 }
684
685 pub const fn sreg(id: u32) -> SReg {
686 SReg::from_id(id)
687 }
688
689 pub const AL: GpbLo = gpb_lo(Gp::AX);
690 pub const CL: GpbLo = gpb_lo(Gp::CX);
691 pub const DL: GpbLo = gpb_lo(Gp::DX);
692 pub const BL: GpbLo = gpb_lo(Gp::BX);
693 pub const SPL: GpbLo = gpb_lo(Gp::SP);
694 pub const BPL: GpbLo = gpb_lo(Gp::BP);
695 pub const SIL: GpbLo = gpb_lo(Gp::SI);
696 pub const DIL: GpbLo = gpb_lo(Gp::DI);
697 pub const R8B: GpbLo = gpb_lo(Gp::R8);
698 pub const R9B: GpbLo = gpb_lo(Gp::R9);
699 pub const R10B: GpbLo = gpb_lo(Gp::R10);
700 pub const R11B: GpbLo = gpb_lo(Gp::R11);
701 pub const R12B: GpbLo = gpb_lo(Gp::R12);
702 pub const R13B: GpbLo = gpb_lo(Gp::R13);
703 pub const R14B: GpbLo = gpb_lo(Gp::R14);
704 pub const R15B: GpbLo = gpb_lo(Gp::R15);
705
706 pub const AH: GpbHi = gpb_hi(Gp::AX);
707 pub const CH: GpbHi = gpb_hi(Gp::CX);
708 pub const DH: GpbHi = gpb_hi(Gp::DX);
709 pub const BH: GpbHi = gpb_hi(Gp::BX);
710
711 pub const AX: Gpw = gpw(Gp::AX);
712 pub const CX: Gpw = gpw(Gp::CX);
713 pub const DX: Gpw = gpw(Gp::DX);
714 pub const BX: Gpw = gpw(Gp::BX);
715 pub const SP: Gpw = gpw(Gp::SP);
716 pub const BP: Gpw = gpw(Gp::BP);
717 pub const SI: Gpw = gpw(Gp::SI);
718 pub const DI: Gpw = gpw(Gp::DI);
719 pub const R8W: Gpw = gpw(Gp::R8);
720 pub const R9W: Gpw = gpw(Gp::R9);
721 pub const R10W: Gpw = gpw(Gp::R10);
722 pub const R11W: Gpw = gpw(Gp::R11);
723 pub const R12W: Gpw = gpw(Gp::R12);
724 pub const R13W: Gpw = gpw(Gp::R13);
725 pub const R14W: Gpw = gpw(Gp::R14);
726 pub const R15W: Gpw = gpw(Gp::R15);
727
728 pub const EAX: Gpd = gpd(Gp::AX);
729 pub const ECX: Gpd = gpd(Gp::CX);
730 pub const EDX: Gpd = gpd(Gp::DX);
731 pub const EBX: Gpd = gpd(Gp::BX);
732 pub const ESP: Gpd = gpd(Gp::SP);
733 pub const EBP: Gpd = gpd(Gp::BP);
734 pub const ESI: Gpd = gpd(Gp::SI);
735 pub const EDI: Gpd = gpd(Gp::DI);
736 pub const R8D: Gpd = gpd(Gp::R8);
737 pub const R9D: Gpd = gpd(Gp::R9);
738 pub const R10D: Gpd = gpd(Gp::R10);
739 pub const R11D: Gpd = gpd(Gp::R11);
740 pub const R12D: Gpd = gpd(Gp::R12);
741 pub const R13D: Gpd = gpd(Gp::R13);
742 pub const R14D: Gpd = gpd(Gp::R14);
743 pub const R15D: Gpd = gpd(Gp::R15);
744
745 pub const RAX: Gpq = gpq(Gp::AX);
746 pub const RCX: Gpq = gpq(Gp::CX);
747 pub const RDX: Gpq = gpq(Gp::DX);
748 pub const RBX: Gpq = gpq(Gp::BX);
749 pub const RSP: Gpq = gpq(Gp::SP);
750 pub const RBP: Gpq = gpq(Gp::BP);
751 pub const RSI: Gpq = gpq(Gp::SI);
752 pub const RDI: Gpq = gpq(Gp::DI);
753 pub const R8: Gpq = gpq(Gp::R8);
754 pub const R9: Gpq = gpq(Gp::R9);
755 pub const R10: Gpq = gpq(Gp::R10);
756 pub const R11: Gpq = gpq(Gp::R11);
757 pub const R12: Gpq = gpq(Gp::R12);
758 pub const R13: Gpq = gpq(Gp::R13);
759 pub const R14: Gpq = gpq(Gp::R14);
760 pub const R15: Gpq = gpq(Gp::R15);
761
762 pub const XMM0: Xmm = xmm(0);
763 pub const XMM1: Xmm = xmm(1);
764 pub const XMM2: Xmm = xmm(2);
765 pub const XMM3: Xmm = xmm(3);
766 pub const XMM4: Xmm = xmm(4);
767 pub const XMM5: Xmm = xmm(5);
768 pub const XMM6: Xmm = xmm(6);
769 pub const XMM7: Xmm = xmm(7);
770 pub const XMM8: Xmm = xmm(8);
771 pub const XMM9: Xmm = xmm(9);
772 pub const XMM10: Xmm = xmm(10);
773 pub const XMM11: Xmm = xmm(11);
774 pub const XMM12: Xmm = xmm(12);
775 pub const XMM13: Xmm = xmm(13);
776 pub const XMM14: Xmm = xmm(14);
777 pub const XMM15: Xmm = xmm(15);
778 pub const XMM16: Xmm = xmm(16);
779 pub const XMM17: Xmm = xmm(17);
780 pub const XMM18: Xmm = xmm(18);
781 pub const XMM19: Xmm = xmm(19);
782 pub const XMM20: Xmm = xmm(20);
783 pub const XMM21: Xmm = xmm(21);
784 pub const XMM22: Xmm = xmm(22);
785 pub const XMM23: Xmm = xmm(23);
786 pub const XMM24: Xmm = xmm(24);
787 pub const XMM25: Xmm = xmm(25);
788 pub const XMM26: Xmm = xmm(26);
789 pub const XMM27: Xmm = xmm(27);
790 pub const XMM28: Xmm = xmm(28);
791 pub const XMM29: Xmm = xmm(29);
792 pub const XMM30: Xmm = xmm(30);
793 pub const XMM31: Xmm = xmm(31);
794
795 pub const YMM0: Ymm = ymm(0);
796 pub const YMM1: Ymm = ymm(1);
797 pub const YMM2: Ymm = ymm(2);
798 pub const YMM3: Ymm = ymm(3);
799 pub const YMM4: Ymm = ymm(4);
800 pub const YMM5: Ymm = ymm(5);
801 pub const YMM6: Ymm = ymm(6);
802 pub const YMM7: Ymm = ymm(7);
803 pub const YMM8: Ymm = ymm(8);
804 pub const YMM9: Ymm = ymm(9);
805 pub const YMM10: Ymm = ymm(10);
806 pub const YMM11: Ymm = ymm(11);
807 pub const YMM12: Ymm = ymm(12);
808 pub const YMM13: Ymm = ymm(13);
809 pub const YMM14: Ymm = ymm(14);
810 pub const YMM15: Ymm = ymm(15);
811 pub const YMM16: Ymm = ymm(16);
812 pub const YMM17: Ymm = ymm(17);
813 pub const YMM18: Ymm = ymm(18);
814 pub const YMM19: Ymm = ymm(19);
815 pub const YMM20: Ymm = ymm(20);
816 pub const YMM21: Ymm = ymm(21);
817 pub const YMM22: Ymm = ymm(22);
818 pub const YMM23: Ymm = ymm(23);
819 pub const YMM24: Ymm = ymm(24);
820 pub const YMM25: Ymm = ymm(25);
821 pub const YMM26: Ymm = ymm(26);
822 pub const YMM27: Ymm = ymm(27);
823 pub const YMM28: Ymm = ymm(28);
824 pub const YMM29: Ymm = ymm(29);
825 pub const YMM30: Ymm = ymm(30);
826 pub const YMM31: Ymm = ymm(31);
827
828 pub const ZMM0: Zmm = zmm(0);
829 pub const ZMM1: Zmm = zmm(1);
830 pub const ZMM2: Zmm = zmm(2);
831 pub const ZMM3: Zmm = zmm(3);
832 pub const ZMM4: Zmm = zmm(4);
833 pub const ZMM5: Zmm = zmm(5);
834 pub const ZMM6: Zmm = zmm(6);
835 pub const ZMM7: Zmm = zmm(7);
836 pub const ZMM8: Zmm = zmm(8);
837 pub const ZMM9: Zmm = zmm(9);
838 pub const ZMM10: Zmm = zmm(10);
839 pub const ZMM11: Zmm = zmm(11);
840 pub const ZMM12: Zmm = zmm(12);
841 pub const ZMM13: Zmm = zmm(13);
842 pub const ZMM14: Zmm = zmm(14);
843 pub const ZMM15: Zmm = zmm(15);
844 pub const ZMM16: Zmm = zmm(16);
845 pub const ZMM17: Zmm = zmm(17);
846 pub const ZMM18: Zmm = zmm(18);
847 pub const ZMM19: Zmm = zmm(19);
848 pub const ZMM20: Zmm = zmm(20);
849 pub const ZMM21: Zmm = zmm(21);
850 pub const ZMM22: Zmm = zmm(22);
851 pub const ZMM23: Zmm = zmm(23);
852 pub const ZMM24: Zmm = zmm(24);
853 pub const ZMM25: Zmm = zmm(25);
854 pub const ZMM26: Zmm = zmm(26);
855 pub const ZMM27: Zmm = zmm(27);
856 pub const ZMM28: Zmm = zmm(28);
857 pub const ZMM29: Zmm = zmm(29);
858 pub const ZMM30: Zmm = zmm(30);
859 pub const ZMM31: Zmm = zmm(31);
860
861 pub const MM0: Mm = mm(0);
862 pub const MM1: Mm = mm(1);
863 pub const MM2: Mm = mm(2);
864 pub const MM3: Mm = mm(3);
865 pub const MM4: Mm = mm(4);
866 pub const MM5: Mm = mm(5);
867 pub const MM6: Mm = mm(6);
868 pub const MM7: Mm = mm(7);
869
870 pub const K0: KReg = k(0);
871 pub const K1: KReg = k(1);
872 pub const K2: KReg = k(2);
873 pub const K3: KReg = k(3);
874 pub const K4: KReg = k(4);
875 pub const K5: KReg = k(5);
876 pub const K6: KReg = k(6);
877 pub const K7: KReg = k(7);
878
879 pub const CR0: CReg = cr(0);
880 pub const CR2: CReg = cr(2);
881 pub const CR3: CReg = cr(3);
882 pub const CR4: CReg = cr(4);
883 pub const CR8: CReg = cr(8);
884
885 pub const DR0: DReg = dr(0);
886 pub const DR1: DReg = dr(1);
887 pub const DR2: DReg = dr(2);
888 pub const DR3: DReg = dr(3);
889 pub const DR6: DReg = dr(6);
890 pub const DR7: DReg = dr(7);
891
892 pub const ST0: St = st(0);
893 pub const ST1: St = st(1);
894 pub const ST2: St = st(2);
895 pub const ST3: St = st(3);
896 pub const ST4: St = st(4);
897 pub const ST5: St = st(5);
898 pub const ST6: St = st(6);
899 pub const ST7: St = st(7);
900
901 pub const BND0: Bnd = bnd(0);
902 pub const BND1: Bnd = bnd(1);
903 pub const BND2: Bnd = bnd(2);
904 pub const BND3: Bnd = bnd(3);
905
906 pub const TMM0: Tmm = tmm(0);
907 pub const TMM1: Tmm = tmm(1);
908 pub const TMM2: Tmm = tmm(2);
909 pub const TMM3: Tmm = tmm(3);
910 pub const TMM4: Tmm = tmm(4);
911 pub const TMM5: Tmm = tmm(5);
912 pub const TMM6: Tmm = tmm(6);
913 pub const TMM7: Tmm = tmm(7);
914
915 pub const RIP: Rip = rip();
916
917 pub const ES: SReg = sreg(SReg::ES);
918 pub const CS: SReg = sreg(SReg::CS);
919 pub const SS: SReg = sreg(SReg::SS);
920 pub const DS: SReg = sreg(SReg::DS);
921 pub const FS: SReg = sreg(SReg::FS);
922 pub const GS: SReg = sreg(SReg::GS);
923}
924pub use regs::*;
925
926#[derive(Deref, DerefMut, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
927pub struct Mem(pub BaseMem);
928
929define_operand_cast!(Mem, BaseMem);
930
931#[derive(Clone, Copy, PartialEq, Eq)]
932#[repr(u32)]
933pub enum AddrType {
934 Default = 0,
935 Abs = 1,
936 Rel = 2,
937}
938
939#[derive(Clone, Copy, PartialEq, Eq)]
940#[repr(u32)]
941pub enum Broadcast {
942 None = 0,
943 B1To2 = 1,
944 B1To4 = 2,
945 B1To8 = 3,
946 B1To16 = 4,
947 B1To32 = 5,
948 B1To64 = 6,
949}
950type Signature = OperandSignature;
951
952impl Mem {
953 pub const SIGNATURE_MEM_ADDR_TYPE_SHIFT: u32 = 14;
954 pub const SIGNATURE_MEM_ADDR_TYPE_MASK: u32 = 0x03 << Self::SIGNATURE_MEM_ADDR_TYPE_SHIFT;
955
956 pub const SIGNATURE_MEM_SHIFT_VALUE_SHIFT: u32 = 16;
957 pub const SIGNATURE_MEM_SHIFT_VALUE_MASK: u32 = 0x03 << Self::SIGNATURE_MEM_SHIFT_VALUE_SHIFT;
958
959 pub const SIGNATURE_MEM_SEGMENT_SHIFT: u32 = 18;
960 pub const SIGNATURE_MEM_SEGMENT_MASK: u32 = 0x07 << Self::SIGNATURE_MEM_SEGMENT_SHIFT;
961
962 pub const SIGNATURE_MEM_BROADCAST_SHIFT: u32 = 21;
963 pub const SIGNATURE_MEM_BROADCAST_MASK: u32 = 0x7 << Self::SIGNATURE_MEM_BROADCAST_SHIFT;
964
965 pub const fn new() -> Self {
966 Self(BaseMem::new())
967 }
968
969 pub fn base_reg(&self) -> Reg {
970 Reg::from_type_and_id(self.base_type(), self.base_id())
971 }
972
973 pub fn index_reg(&self) -> Reg {
974 Reg::from_type_and_id(self.index_type(), self.index_id())
975 }
976
977 pub fn set_index(&mut self, index: &BaseReg, shift: u32) {
978 self.0.set_index(index);
979 self.set_shift(shift);
980 }
981
982 pub fn has_size(&self) -> bool {
983 self.0.signature.has_field::<{ Signature::SIZE_MASK }>()
984 }
985
986 pub fn has_size_of(&self, s: u32) -> bool {
987 self.size() == s
988 }
989
990 pub fn size(&self) -> u32 {
991 self.0.signature.get_field::<{ Signature::SIZE_MASK }>()
992 }
993
994 pub fn set_size(&mut self, size: u32) {
995 self.0.signature.set_field::<{ Signature::SIZE_MASK }>(size);
996 }
997
998 pub fn addr_type(&self) -> AddrType {
999 unsafe {
1000 core::mem::transmute(
1001 self.0
1002 .signature
1003 .get_field::<{ Self::SIGNATURE_MEM_ADDR_TYPE_MASK }>(),
1004 )
1005 }
1006 }
1007
1008 pub fn set_addr_type(&mut self, addr_type: AddrType) {
1009 self.0
1010 .signature
1011 .set_field::<{ Self::SIGNATURE_MEM_ADDR_TYPE_MASK }>(addr_type as u32);
1012 }
1013
1014 pub fn reset_addr_type(&mut self) {
1015 self.set_addr_type(AddrType::Default);
1016 }
1017
1018 pub fn is_abs(&self) -> bool {
1019 self.addr_type() == AddrType::Abs
1020 }
1021
1022 pub fn set_abs(&mut self) {
1023 self.set_addr_type(AddrType::Abs);
1024 }
1025
1026 pub fn is_rel(&self) -> bool {
1027 self.addr_type() == AddrType::Rel
1028 }
1029
1030 pub fn set_rel(&mut self) {
1031 self.set_addr_type(AddrType::Rel);
1032 }
1033
1034 pub fn has_segment(&self) -> bool {
1035 self.0
1036 .signature
1037 .has_field::<{ Self::SIGNATURE_MEM_SEGMENT_MASK }>()
1038 }
1039
1040 pub fn segment(&self) -> SReg {
1041 SReg::from_id(self.segment_id())
1042 }
1043
1044 pub fn segment_id(&self) -> u32 {
1045 self.0
1046 .signature
1047 .get_field::<{ Self::SIGNATURE_MEM_SEGMENT_MASK }>()
1048 }
1049
1050 pub fn set_segment(&mut self, seg: SReg) {
1051 self.set_segment_id(seg.id());
1052 }
1053
1054 pub fn set_segment_id(&mut self, r_id: u32) {
1055 self.0
1056 .signature
1057 .set_field::<{ Self::SIGNATURE_MEM_SEGMENT_MASK }>(r_id);
1058 }
1059
1060 pub fn reset_segment(&mut self) {
1061 self.set_segment_id(0);
1062 }
1063
1064 pub fn has_shift(&self) -> bool {
1065 self.0
1066 .signature
1067 .has_field::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>()
1068 }
1069
1070 pub fn shift(&self) -> u32 {
1071 self.0
1072 .signature
1073 .get_field::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>()
1074 }
1075
1076 pub fn set_shift(&mut self, shift: u32) {
1077 self.0
1078 .signature
1079 .set_field::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift);
1080 }
1081
1082 pub fn reset_shift(&mut self) {
1083 self.set_shift(0);
1084 }
1085
1086 pub fn has_broadcast(&self) -> bool {
1087 self.0
1088 .signature
1089 .has_field::<{ Self::SIGNATURE_MEM_BROADCAST_MASK }>()
1090 }
1091
1092 pub fn get_broadcast(&self) -> Broadcast {
1093 unsafe {
1094 core::mem::transmute(
1095 self.0
1096 .signature
1097 .get_field::<{ Self::SIGNATURE_MEM_BROADCAST_MASK }>(),
1098 )
1099 }
1100 }
1101
1102 pub fn set_broadcast(&mut self, b: Broadcast) {
1103 self.0
1104 .signature
1105 .set_field::<{ Self::SIGNATURE_MEM_BROADCAST_MASK }>(b as u32);
1106 }
1107
1108 pub fn reset_broadcast(&mut self) {
1109 self.set_broadcast(Broadcast::None);
1110 }
1111
1112 pub fn _1to1(&self) -> Self {
1113 self.clone_broadcasted(Broadcast::None)
1114 }
1115
1116 pub fn _1to2(&self) -> Self {
1117 self.clone_broadcasted(Broadcast::B1To2)
1118 }
1119
1120 pub fn _1to4(&self) -> Self {
1121 self.clone_broadcasted(Broadcast::B1To4)
1122 }
1123
1124 pub fn _1to8(&self) -> Self {
1125 self.clone_broadcasted(Broadcast::B1To8)
1126 }
1127
1128 pub fn _1to16(&self) -> Self {
1129 self.clone_broadcasted(Broadcast::B1To16)
1130 }
1131
1132 pub fn _1to32(&self) -> Self {
1133 self.clone_broadcasted(Broadcast::B1To32)
1134 }
1135
1136 pub fn _1to64(&self) -> Self {
1137 self.clone_broadcasted(Broadcast::B1To64)
1138 }
1139
1140 pub fn base_and_index_types(&self) -> u32 {
1141 self.signature
1142 .get_field::<{ OperandSignature::MEM_BASE_INDEX_MASK }>()
1143 }
1144
1145 pub fn clone_broadcasted(&self, bcst: Broadcast) -> Self {
1146 Self(BaseMem::from_base_and_index_disp(
1147 OperandSignature::new(
1148 self.0.signature.bits() & !Self::SIGNATURE_MEM_BROADCAST_MASK as u32,
1149 ) | OperandSignature::new((bcst as u32) << Self::SIGNATURE_MEM_BROADCAST_SHIFT),
1150 self.0.base_id(),
1151 self.0.data[0],
1152 self.0.data[1] as _,
1153 ))
1154 }
1155
1156 pub fn from_signature_base_and_index_id_disp(
1157 signature: OperandSignature,
1158 base_id: u32,
1159 index_id: u32,
1160 offset: i32,
1161 ) -> Self {
1162 Self(BaseMem::from_base_and_index_disp(
1163 signature, base_id, index_id, offset,
1164 ))
1165 }
1166
1167 pub fn from_sym_and_index_shift_disp(
1168 base: &Sym,
1169 index: &BaseReg,
1170 shift: u32,
1171 off: i32,
1172 size: u32,
1173 signature: OperandSignature,
1174 ) -> Self {
1175 Self(BaseMem::from_base_and_index_disp(
1176 Signature::from_op_type(OperandType::Mem)
1177 | Signature::from_mem_base_type(RegType::SymTag)
1178 | Signature::from_mem_index_type(index.typ())
1179 | Signature::from_value::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift)
1180 | Signature::from_size(size)
1181 | signature,
1182 base.id(),
1183 index.id(),
1184 off,
1185 ))
1186 }
1187 pub fn from_label_and_index_shift_disp(
1188 base: &Label,
1189 index: &BaseReg,
1190 shift: u32,
1191 off: i32,
1192 size: u32,
1193 signature: OperandSignature,
1194 ) -> Self {
1195 Self(BaseMem::from_base_and_index_disp(
1196 Signature::from_op_type(OperandType::Mem)
1197 | Signature::from_mem_base_type(RegType::LabelTag)
1198 | Signature::from_mem_index_type(index.typ())
1199 | Signature::from_value::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift)
1200 | Signature::from_size(size)
1201 | signature,
1202 base.id(),
1203 index.id(),
1204 off,
1205 ))
1206 }
1207
1208 pub fn from_label_and_disp(
1209 base: &Label,
1210 off: i32,
1211 size: u32,
1212 signature: OperandSignature,
1213 ) -> Self {
1214 Self(BaseMem::from_base_and_index_disp(
1215 Signature::from_op_type(OperandType::Mem)
1216 | Signature::from_mem_base_type(RegType::LabelTag)
1217 | Signature::from_size(size)
1218 | signature,
1219 base.id(),
1220 0,
1221 off,
1222 ))
1223 }
1224
1225 pub fn from_sym_and_disp(base: &Sym, off: i32, size: u32, signature: OperandSignature) -> Self {
1226 Self(BaseMem::from_base_and_index_disp(
1227 Signature::from_op_type(OperandType::Mem)
1228 | Signature::from_mem_base_type(RegType::SymTag)
1229 | Signature::from_size(size)
1230 | signature,
1231 base.id(),
1232 0,
1233 off,
1234 ))
1235 }
1236
1237 pub fn from_base_and_disp(
1238 base: &BaseReg,
1239 off: i32,
1240 size: u32,
1241 signature: OperandSignature,
1242 ) -> Self {
1243 Self(BaseMem::from_base_and_index_disp(
1244 Signature::from_op_type(OperandType::Mem)
1245 | Signature::from_mem_base_type(base.typ())
1246 | Signature::from_size(size)
1247 | signature,
1248 base.id(),
1249 0,
1250 off,
1251 ))
1252 }
1253
1254 pub fn from_base_and_index_shift_disp(
1255 base: &BaseReg,
1256 index: &BaseReg,
1257 shift: u32,
1258 off: i32,
1259 size: u32,
1260 signature: OperandSignature,
1261 ) -> Self {
1262 Self(BaseMem::from_base_and_index_disp(
1263 Signature::from_op_type(OperandType::Mem)
1264 | Signature::from_mem_base_type(base.typ())
1265 | Signature::from_mem_index_type(index.typ())
1266 | Signature::from_value::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift)
1267 | Signature::from_size(size)
1268 | signature,
1269 base.id(),
1270 index.id(),
1271 off,
1272 ))
1273 }
1274
1275 pub fn from_u64_and_index_shift_disp(
1276 base: u64,
1277 index: &BaseReg,
1278 shift: u32,
1279 size: u32,
1280 signature: OperandSignature,
1281 ) -> Self {
1282 Self(BaseMem::from_base_and_index_disp(
1283 Signature::from_op_type(OperandType::Mem)
1284 | Signature::from_mem_index_type(index.typ())
1285 | Signature::from_value::<{ Self::SIGNATURE_MEM_SHIFT_VALUE_MASK }>(shift)
1286 | Signature::from_size(size)
1287 | signature,
1288 (base >> 32) as u32,
1289 index.id(),
1290 (base & 0xFFFFFFF) as _,
1291 ))
1292 }
1293
1294 pub fn from_u64(base: u64, size: u32, signature: OperandSignature) -> Self {
1295 Self(BaseMem::from_base_and_index_disp(
1296 Signature::from_op_type(OperandType::Mem) | Signature::from_size(size) | signature,
1297 (base >> 32) as u32,
1298 0,
1299 (base & 0xFFFFFFF) as _,
1300 ))
1301 }
1302}
1303
1304impl Add<i32> for Gpq {
1305 type Output = Mem;
1306 fn add(self, rhs: i32) -> Self::Output {
1307 ptr(self, rhs, 0)
1308 }
1309}
1310
1311impl Mul<i32> for Gpq {
1312 type Output = Mem;
1313
1314 fn mul(self, rhs: i32) -> Self::Output {
1315 let shift = match rhs {
1316 0 | 1 => 0,
1317 2 => 1,
1318 4 => 2,
1319 8 => 3,
1320 16 => 4,
1321 _ => todo!(),
1322 };
1323 ptr_index(RAX, self, shift, 0, 0)
1324 }
1325}
1326
1327impl<T: Deref<Target = Gp>> Mul<T> for Mem {
1328 type Output = Mem;
1329
1330 fn mul(self, rhs: T) -> Self::Output {
1331 let mut this = self;
1332 let reg = rhs.deref();
1333 this.set_index_id(reg.id());
1334 this.set_index_type(reg.typ());
1335
1336 this
1337 }
1338}
1339
1340impl Add<i32> for Label {
1341 type Output = Mem;
1342
1343 fn add(self, rhs: i32) -> Self::Output {
1344 label_ptr(self, rhs, 0)
1345 }
1346}
1347
1348impl Add<Mem> for Gpq {
1349 type Output = Mem;
1350
1351 fn add(self, mut rhs: Mem) -> Self::Output {
1352 rhs.set_base(&self);
1353 rhs
1354 }
1355}
1356
1357impl Add<i32> for Mem {
1358 type Output = Mem;
1359
1360 fn add(self, rhs: i32) -> Self::Output {
1361 let mut this = self;
1362 this.add_offset(rhs as _);
1363 this
1364 }
1365}
1366
1367macro_rules! mem_ptr {
1368 ($name: ident, $size: literal) => {
1369 paste::paste! {
1370 pub fn $name(base: impl Deref<Target = Gp>, offset: i32) -> Mem {
1371 Mem::from_base_and_disp(base.deref(), offset, $size, 0.into())
1372 }
1373
1374 pub fn [<$name _index>](base: impl Deref<Target = Gp>, index: impl Deref<Target = Gp>, shift: u32, offset: i32) -> Mem {
1375 Mem::from_base_and_index_shift_disp(base.deref(), index.deref(), shift, offset, $size, 0.into())
1376 }
1377
1378 pub fn [<$name _label>](base: Label, offset: i32) -> Mem {
1379 Mem::from_label_and_disp(&base, offset, $size, 0.into())
1380 }
1381
1382 pub fn [<$name _label_index>](base: Label, index: impl Deref<Target = Gp>, shift: u32, offset: i32) -> Mem {
1383 Mem::from_label_and_index_shift_disp(&base, index.deref(), shift, offset, $size, 0.into())
1384 }
1385
1386 pub fn [<$name _sym>](base: Sym, offset: i32) -> Mem {
1387 Mem::from_sym_and_disp(&base, offset, $size, 0.into())
1388 }
1389
1390 pub fn [<$name _sym_index>](base: Sym, index: impl Deref<Target = Gp>, shift: u32, offset: i32) -> Mem {
1391 Mem::from_sym_and_index_shift_disp(&base, index.deref(), shift, offset, $size, 0.into())
1392 }
1393
1394
1395 pub fn [<$name _rip>](offset: i32) -> Mem {
1396 Mem::from_base_and_disp(&RIP, offset, $size, 0.into())
1397 }
1398
1399 pub fn [<$name _u64>](base: u64) -> Mem {
1400 Mem::from_u64(base, $size, 0.into())
1401 }
1402
1403 pub fn [<$name _u64_index>](base: u64, index: impl Deref<Target = Gp>, shift: u32) -> Mem {
1404 Mem::from_u64_and_index_shift_disp(base, index.deref(), shift, $size, 0.into())
1405 }
1406
1407 pub fn [<$name _u64_abs>](base: u64) -> Mem {
1408 Mem::from_u64(base, $size, OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Abs as _))
1409 }
1410
1411 pub fn [<$name _u64_index_abs>](base: u64, index: impl Deref<Target = Gp>, shift: u32) -> Mem {
1412 Mem::from_u64_and_index_shift_disp(base, index.deref(), shift, $size, OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Abs as _))
1413 }
1414
1415 pub fn [<$name _u64_rel>](base: u64) -> Mem {
1416 Mem::from_u64(base, $size, OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Rel as _))
1417 }
1418
1419 pub fn [<$name _u64_index_rel>](base: u64, index: impl Deref<Target = Gp>, shift: u32) -> Mem {
1420 Mem::from_u64_and_index_shift_disp(base, index.deref(), shift, $size, OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Rel as _))
1421 }
1422 }
1423 }
1424}
1425mem_ptr!(ptr8, 1);
1426mem_ptr!(ptr16, 2);
1427mem_ptr!(ptr32, 4);
1428mem_ptr!(ptr48, 6);
1429mem_ptr!(ptr64, 8);
1430mem_ptr!(ptr80, 10);
1431mem_ptr!(ptr128, 16);
1432mem_ptr!(ptr256, 32);
1433mem_ptr!(ptr512, 64);
1434
1435mem_ptr!(byte_ptr, 1);
1436mem_ptr!(word_ptr, 2);
1437mem_ptr!(dword_ptr, 4);
1438mem_ptr!(fword_ptr, 6);
1439mem_ptr!(qword_ptr, 8);
1440mem_ptr!(tbyte_ptr, 10);
1441mem_ptr!(tword_ptr, 10);
1442mem_ptr!(oword_ptr, 16);
1443mem_ptr!(dqword_ptr, 16);
1444mem_ptr!(qqword_ptr, 32);
1445mem_ptr!(xmmword_ptr, 16);
1446mem_ptr!(ymmword_ptr, 32);
1447mem_ptr!(zmmword_ptr, 64);
1448
1449pub fn ptr(base: impl Deref<Target = Gp>, offset: i32, size: u32) -> Mem {
1450 Mem::from_base_and_disp(base.deref(), offset, size, 0.into())
1451}
1452
1453pub fn ptr_index(
1454 base: impl Deref<Target = Gp>,
1455 index: impl Deref<Target = Gp>,
1456 shift: u32,
1457 offset: i32,
1458 size: u32,
1459) -> Mem {
1460 Mem::from_base_and_index_shift_disp(base.deref(), index.deref(), shift, offset, size, 0.into())
1461}
1462
1463pub fn label_ptr(base: Label, offset: i32, size: u32) -> Mem {
1464 Mem::from_label_and_disp(&base, offset, size, 0.into())
1465}
1466pub fn label_ptr_index(
1467 base: Label,
1468 index: impl Deref<Target = Gp>,
1469 shift: u32,
1470 offset: i32,
1471 size: u32,
1472) -> Mem {
1473 Mem::from_label_and_index_shift_disp(&base, index.deref(), shift, offset, size, 0.into())
1474}
1475
1476pub fn sym_ptr(base: Sym, offset: i32, size: u32) -> Mem {
1477 Mem::from_sym_and_disp(&base, offset, size, 0.into())
1478}
1479pub fn sym_ptr_index(
1480 base: Sym,
1481 index: impl Deref<Target = Gp>,
1482 shift: u32,
1483 offset: i32,
1484 size: u32,
1485) -> Mem {
1486 Mem::from_sym_and_index_shift_disp(&base, index.deref(), shift, offset, size, 0.into())
1487}
1488
1489pub fn rip_rel(offset: i32, size: u32) -> Mem {
1490 Mem::from_base_and_disp(&RIP, offset, size, 0.into())
1491}
1492
1493pub fn u64_ptr(base: u64, size: u32) -> Mem {
1494 Mem::from_u64(base, size, 0.into())
1495}
1496
1497pub fn u64_ptr_index(base: u64, index: impl Deref<Target = Gp>, shift: u32, size: u32) -> Mem {
1498 Mem::from_u64_and_index_shift_disp(base, index.deref(), shift, size, 0.into())
1499}
1500
1501pub fn u64_ptr_abs(base: u64, size: u32) -> Mem {
1502 Mem::from_u64(
1503 base,
1504 size,
1505 OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Abs as _),
1506 )
1507}
1508
1509pub fn u64_ptr_index_abs(base: u64, index: impl Deref<Target = Gp>, shift: u32, size: u32) -> Mem {
1510 Mem::from_u64_and_index_shift_disp(
1511 base,
1512 index.deref(),
1513 shift,
1514 size,
1515 OperandSignature::from_value::<{ Mem::SIGNATURE_MEM_ADDR_TYPE_MASK }>(AddrType::Abs as _),
1516 )
1517}