Skip to main content

closure_ffi_iced_x86/code_asm/
mem.rs

1// SPDX-License-Identifier: MIT
2// Copyright (C) 2018-present iced project and contributors
3
4use crate::code_asm::op_state::{CodeAsmOpState, MemoryOperandSize};
5use crate::code_asm::{AsmRegister16, AsmRegister32, AsmRegister64, AsmRegisterXmm, AsmRegisterYmm, AsmRegisterZmm, CodeLabel};
6use crate::{MemoryOperand, Register};
7use core::ops::{Add, Mul, Sub};
8
9/// A memory operand passed to [`CodeAssembler`] methods.
10///
11/// [`CodeAssembler`]: struct.CodeAssembler.html
12///
13/// The struct name is not part of the public API. Its methods, however, are part of the public API.
14///
15/// You can create a memory operand in many different ways:
16///
17/// ```
18/// use iced_x86::code_asm::*;
19///
20/// // <???> ptr [rax+rdx*4]
21/// let _ = rax + rdx * 4;
22/// // byte ptr [rax]
23/// let _ = byte_ptr(rax);
24/// // <???> ptr gs:[rcx*4+123]
25/// let _ = ptr(rcx * 4 + 123).gs();
26/// // qword bcst [rdx+xmm0*8+123]
27/// let _ = qword_bcst(rdx + xmm0 * 8 + 123);
28/// ```
29#[derive(Debug, Clone, Copy, PartialEq, Eq)]
30pub struct AsmMemoryOperand {
31	base: Register,
32	index: Register,
33	scale: u8,
34	displ: i64,
35	state: CodeAsmOpState,
36}
37
38impl AsmMemoryOperand {
39	// GENERATOR-BEGIN: AsmMemoryOperandPtrMethods
40	// ⚠️This was generated by GENERATOR!🦹‍♂️
41	#[must_use]
42	#[inline]
43	#[rustfmt::skip]
44	pub(crate) fn ptr(mut self) -> Self {
45		self.state.ptr(MemoryOperandSize::None);
46		self
47	}
48
49	#[must_use]
50	#[inline]
51	#[rustfmt::skip]
52	pub(crate) fn byte_ptr(mut self) -> Self {
53		self.state.ptr(MemoryOperandSize::Byte);
54		self
55	}
56
57	#[must_use]
58	#[inline]
59	#[rustfmt::skip]
60	pub(crate) fn word_ptr(mut self) -> Self {
61		self.state.ptr(MemoryOperandSize::Word);
62		self
63	}
64
65	#[must_use]
66	#[inline]
67	#[rustfmt::skip]
68	pub(crate) fn dword_ptr(mut self) -> Self {
69		self.state.ptr(MemoryOperandSize::Dword);
70		self
71	}
72
73	#[must_use]
74	#[inline]
75	#[rustfmt::skip]
76	pub(crate) fn qword_ptr(mut self) -> Self {
77		self.state.ptr(MemoryOperandSize::Qword);
78		self
79	}
80
81	#[must_use]
82	#[inline]
83	#[rustfmt::skip]
84	pub(crate) fn mmword_ptr(mut self) -> Self {
85		self.state.ptr(MemoryOperandSize::Qword);
86		self
87	}
88
89	#[must_use]
90	#[inline]
91	#[rustfmt::skip]
92	pub(crate) fn tbyte_ptr(mut self) -> Self {
93		self.state.ptr(MemoryOperandSize::Tbyte);
94		self
95	}
96
97	#[must_use]
98	#[inline]
99	#[rustfmt::skip]
100	pub(crate) fn tword_ptr(mut self) -> Self {
101		self.state.ptr(MemoryOperandSize::Tbyte);
102		self
103	}
104
105	#[must_use]
106	#[inline]
107	#[rustfmt::skip]
108	pub(crate) fn fword_ptr(mut self) -> Self {
109		self.state.ptr(MemoryOperandSize::Fword);
110		self
111	}
112
113	#[must_use]
114	#[inline]
115	#[rustfmt::skip]
116	pub(crate) fn oword_ptr(mut self) -> Self {
117		self.state.ptr(MemoryOperandSize::Xword);
118		self
119	}
120
121	#[must_use]
122	#[inline]
123	#[rustfmt::skip]
124	pub(crate) fn xmmword_ptr(mut self) -> Self {
125		self.state.ptr(MemoryOperandSize::Xword);
126		self
127	}
128
129	#[must_use]
130	#[inline]
131	#[rustfmt::skip]
132	pub(crate) fn ymmword_ptr(mut self) -> Self {
133		self.state.ptr(MemoryOperandSize::Yword);
134		self
135	}
136
137	#[must_use]
138	#[inline]
139	#[rustfmt::skip]
140	pub(crate) fn zmmword_ptr(mut self) -> Self {
141		self.state.ptr(MemoryOperandSize::Zword);
142		self
143	}
144
145	#[must_use]
146	#[inline]
147	#[rustfmt::skip]
148	pub(crate) fn bcst(mut self) -> Self {
149		self.state.bcst(MemoryOperandSize::None);
150		self
151	}
152
153	#[must_use]
154	#[inline]
155	#[rustfmt::skip]
156	pub(crate) fn word_bcst(mut self) -> Self {
157		self.state.bcst(MemoryOperandSize::Word);
158		self
159	}
160
161	#[must_use]
162	#[inline]
163	#[rustfmt::skip]
164	pub(crate) fn dword_bcst(mut self) -> Self {
165		self.state.bcst(MemoryOperandSize::Dword);
166		self
167	}
168
169	#[must_use]
170	#[inline]
171	#[rustfmt::skip]
172	pub(crate) fn qword_bcst(mut self) -> Self {
173		self.state.bcst(MemoryOperandSize::Qword);
174		self
175	}
176	// GENERATOR-END: AsmMemoryOperandPtrMethods
177
178	/// Adds an `ES` segment override
179	#[must_use]
180	#[inline]
181	pub fn es(mut self) -> Self {
182		self.state.set_es();
183		self
184	}
185
186	/// Adds a `CS` segment override
187	#[must_use]
188	#[inline]
189	pub fn cs(mut self) -> Self {
190		self.state.set_cs();
191		self
192	}
193
194	/// Adds an `SS` segment override
195	#[must_use]
196	#[inline]
197	pub fn ss(mut self) -> Self {
198		self.state.set_ss();
199		self
200	}
201
202	/// Adds a `DS` segment override
203	#[must_use]
204	#[inline]
205	pub fn ds(mut self) -> Self {
206		self.state.set_ds();
207		self
208	}
209
210	/// Adds an `FS` segment override
211	#[must_use]
212	#[inline]
213	pub fn fs(mut self) -> Self {
214		self.state.set_fs();
215		self
216	}
217
218	/// Adds a `GS` segment override
219	#[must_use]
220	#[inline]
221	pub fn gs(mut self) -> Self {
222		self.state.set_gs();
223		self
224	}
225
226	/// Adds a `{k1}` opmask register
227	#[must_use]
228	#[inline]
229	pub fn k1(mut self) -> Self {
230		self.state.set_k1();
231		self
232	}
233
234	/// Adds a `{k2}` opmask register
235	#[must_use]
236	#[inline]
237	pub fn k2(mut self) -> Self {
238		self.state.set_k2();
239		self
240	}
241
242	/// Adds a `{k3}` opmask register
243	#[must_use]
244	#[inline]
245	pub fn k3(mut self) -> Self {
246		self.state.set_k3();
247		self
248	}
249
250	/// Adds a `{k4}` opmask register
251	#[must_use]
252	#[inline]
253	pub fn k4(mut self) -> Self {
254		self.state.set_k4();
255		self
256	}
257
258	/// Adds a `{k5}` opmask register
259	#[must_use]
260	#[inline]
261	pub fn k5(mut self) -> Self {
262		self.state.set_k5();
263		self
264	}
265
266	/// Adds a `{k6}` opmask register
267	#[must_use]
268	#[inline]
269	pub fn k6(mut self) -> Self {
270		self.state.set_k6();
271		self
272	}
273
274	/// Adds a `{k7}` opmask register
275	#[must_use]
276	#[inline]
277	pub fn k7(mut self) -> Self {
278		self.state.set_k7();
279		self
280	}
281
282	#[must_use]
283	#[inline]
284	pub(crate) fn is_displacement_only(&self) -> bool {
285		self.base == Register::None && self.index == Register::None
286	}
287
288	#[must_use]
289	#[inline]
290	pub(crate) fn to_memory_operand(self, bitness: u32) -> MemoryOperand {
291		MemoryOperand {
292			segment_prefix: self.state.segment(),
293			base: self.base,
294			index: self.index,
295			scale: self.scale as u32,
296			displacement: self.displ,
297			displ_size: if self.is_displacement_only() { bitness / 8 } else { (self.displ != 0) as u32 },
298			is_broadcast: self.is_broadcast(),
299		}
300	}
301
302	#[must_use]
303	#[inline]
304	pub(crate) fn is_broadcast(&self) -> bool {
305		self.state.is_broadcast()
306	}
307
308	#[must_use]
309	#[inline]
310	pub(crate) fn size(&self) -> MemoryOperandSize {
311		self.state.size()
312	}
313
314	#[must_use]
315	#[inline]
316	pub(crate) fn index(&self) -> Register {
317		self.index
318	}
319
320	#[must_use]
321	#[inline]
322	pub(crate) fn state(&self) -> CodeAsmOpState {
323		self.state
324	}
325}
326
327impl<R: Into<Register>> From<R> for AsmMemoryOperand {
328	#[inline]
329	fn from(other: R) -> Self {
330		AsmMemoryOperand { base: other.into(), index: Register::None, scale: 1, displ: 0, state: CodeAsmOpState::new() }
331	}
332}
333
334macro_rules! displ_to_mem_op {
335	($($displ_ty:ty)+) => {
336		$(
337			impl From<$displ_ty> for AsmMemoryOperand {
338				#[inline]
339				#[allow(trivial_numeric_casts)]
340				fn from(other: $displ_ty) -> Self {
341					AsmMemoryOperand {
342						base: Register::None,
343						index: Register::None,
344						scale: 1,
345						displ: other as i64,
346						state: CodeAsmOpState::new(),
347					}
348				}
349			}
350		)+
351	};
352}
353displ_to_mem_op!(i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
354
355macro_rules! reg_plus_displ {
356	($reg_ty:ty, $($displ_ty:ty)+) => {
357		$(
358			impl Add<$displ_ty> for $reg_ty {
359				type Output = AsmMemoryOperand;
360				#[inline]
361				#[allow(trivial_numeric_casts)]
362				fn add(self, rhs: $displ_ty) -> Self::Output {
363					AsmMemoryOperand {
364						base: self.into(),
365						index: Register::None,
366						scale: 1,
367						displ: rhs as i64,
368						state: CodeAsmOpState::new(),
369					}
370				}
371			}
372			impl Add<$reg_ty> for $displ_ty {
373				type Output = AsmMemoryOperand;
374				#[inline]
375				#[allow(trivial_numeric_casts)]
376				fn add(self, rhs: $reg_ty) -> Self::Output {
377					AsmMemoryOperand {
378						base: rhs.into(),
379						index: Register::None,
380						scale: 1,
381						displ: self as i64,
382						state: CodeAsmOpState::new(),
383					}
384				}
385			}
386			impl Sub<$displ_ty> for $reg_ty {
387				type Output = AsmMemoryOperand;
388				#[inline]
389				#[allow(trivial_numeric_casts)]
390				fn sub(self, rhs: $displ_ty) -> Self::Output {
391					AsmMemoryOperand {
392						base: self.into(),
393						index: Register::None,
394						scale: 1,
395						displ: (rhs as i64).wrapping_neg(),
396						state: CodeAsmOpState::new(),
397					}
398				}
399			}
400		)+
401	};
402}
403reg_plus_displ!(AsmRegister16, i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
404reg_plus_displ!(AsmRegister32, i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
405reg_plus_displ!(AsmRegister64, i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
406
407macro_rules! reg_mul_scale {
408	($reg_ty:ty, $($scale_ty:ty)+) => {
409		$(
410			impl Mul<$scale_ty> for $reg_ty {
411				type Output = AsmMemoryOperand;
412				#[inline]
413				#[allow(trivial_numeric_casts)]
414				fn mul(self, rhs: $scale_ty) -> Self::Output {
415					AsmMemoryOperand {
416						base: Register::None,
417						index: self.into(),
418						scale: rhs as u8,
419						displ: 0,
420						state: CodeAsmOpState::new(),
421					}
422				}
423			}
424			impl Mul<$reg_ty> for $scale_ty {
425				type Output = AsmMemoryOperand;
426				#[inline]
427				#[allow(trivial_numeric_casts)]
428				fn mul(self, rhs: $reg_ty) -> Self::Output {
429					AsmMemoryOperand {
430						base: Register::None,
431						index: rhs.into(),
432						scale: self as u8,
433						displ: 0,
434						state: CodeAsmOpState::new(),
435					}
436				}
437			}
438		)+
439	};
440}
441reg_mul_scale!(AsmRegister32, i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
442reg_mul_scale!(AsmRegister64, i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
443reg_mul_scale!(AsmRegisterXmm, i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
444reg_mul_scale!(AsmRegisterYmm, i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
445reg_mul_scale!(AsmRegisterZmm, i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
446
447macro_rules! reg_plus_reg {
448	($left_ty:ty, $($right_ty:ty)+) => {
449		$(
450			impl Add<$right_ty> for $left_ty {
451				type Output = AsmMemoryOperand;
452				#[inline]
453				fn add(self, rhs: $right_ty) -> Self::Output {
454					AsmMemoryOperand { base: self.into(), index: rhs.into(), scale: 1, displ: 0, state: CodeAsmOpState::new() }
455				}
456			}
457		)+
458	};
459}
460reg_plus_reg!(AsmRegister16, AsmRegister16);
461reg_plus_reg!(AsmRegister32, AsmRegister32 AsmRegisterXmm AsmRegisterYmm AsmRegisterZmm);
462reg_plus_reg!(AsmRegister64, AsmRegister64 AsmRegisterXmm AsmRegisterYmm AsmRegisterZmm);
463
464// Special case `vec + reg` and treat `vec` as the index register (it can't be the base)
465macro_rules! indexreg_plus_reg {
466	($($left_ty:ty)+, $right_ty:ty) => {
467		$(
468			impl Add<$right_ty> for $left_ty {
469				type Output = AsmMemoryOperand;
470				#[inline]
471				fn add(self, rhs: $right_ty) -> Self::Output {
472					AsmMemoryOperand { base: rhs.into(), index: self.into(), scale: 1, displ: 0, state: CodeAsmOpState::new() }
473				}
474			}
475		)+
476	};
477}
478indexreg_plus_reg!(AsmRegisterXmm AsmRegisterYmm AsmRegisterZmm, AsmRegister32);
479indexreg_plus_reg!(AsmRegisterXmm AsmRegisterYmm AsmRegisterZmm, AsmRegister64);
480
481macro_rules! reg_plus_mem {
482	($($reg_ty:ty)+) => {
483		$(
484			impl Add<AsmMemoryOperand> for $reg_ty {
485				type Output = AsmMemoryOperand;
486				#[inline]
487				fn add(self, mut rhs: AsmMemoryOperand) -> Self::Output {
488					debug_assert_eq!(rhs.base, Register::None);
489					rhs.base = self.into();
490					rhs
491				}
492			}
493
494			impl Add<$reg_ty> for AsmMemoryOperand {
495				type Output = AsmMemoryOperand;
496				#[inline]
497				fn add(mut self, rhs: $reg_ty) -> Self::Output {
498					debug_assert_eq!(self.base, Register::None);
499					self.base = rhs.into();
500					self
501				}
502			}
503		)+
504	};
505}
506reg_plus_mem!(AsmRegister16 AsmRegister32 AsmRegister64);
507
508macro_rules! mem_plus_displ {
509	($($displ_ty:ty)+) => {
510		$(
511			impl Add<$displ_ty> for AsmMemoryOperand {
512				type Output = AsmMemoryOperand;
513				#[inline]
514				#[allow(trivial_numeric_casts)]
515				fn add(mut self, rhs: $displ_ty) -> Self::Output {
516					self.displ = self.displ.wrapping_add(rhs as i64);
517					self
518				}
519			}
520			impl Add<AsmMemoryOperand> for $displ_ty {
521				type Output = AsmMemoryOperand;
522				#[inline]
523				#[allow(trivial_numeric_casts)]
524				fn add(self, mut rhs: AsmMemoryOperand) -> Self::Output {
525					rhs.displ = rhs.displ.wrapping_add(self as i64);
526					rhs
527				}
528			}
529			impl Sub<$displ_ty> for AsmMemoryOperand {
530				type Output = AsmMemoryOperand;
531				#[inline]
532				#[allow(trivial_numeric_casts)]
533				fn sub(mut self, rhs: $displ_ty) -> Self::Output {
534					self.displ = self.displ.wrapping_sub(rhs as i64);
535					self
536				}
537			}
538		)+
539	};
540}
541mem_plus_displ!(i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
542
543impl Add<AsmMemoryOperand> for AsmMemoryOperand {
544	type Output = AsmMemoryOperand;
545	#[inline]
546	fn add(mut self, rhs: AsmMemoryOperand) -> Self::Output {
547		if self.base == Register::None {
548			self.base = rhs.base;
549		} else {
550			debug_assert_eq!(rhs.base, Register::None);
551		}
552		if self.index == Register::None {
553			self.index = rhs.index;
554			self.scale = rhs.scale;
555		} else {
556			debug_assert_eq!(rhs.index, Register::None);
557		}
558		self.displ = self.displ.wrapping_add(rhs.displ);
559		// The remaining fields aren't copied/updated from rhs, eg. segment register, rc, etc.
560		self
561	}
562}
563
564impl From<CodeLabel> for AsmMemoryOperand {
565	#[inline]
566	fn from(other: CodeLabel) -> Self {
567		AsmMemoryOperand { base: Register::RIP, index: Register::None, scale: 1, displ: other.id as i64, state: CodeAsmOpState::new() }
568	}
569}
570
571// GENERATOR-BEGIN: GlobalPtrMethods
572// ⚠️This was generated by GENERATOR!🦹‍♂️
573/// Creates a memory operand with no size hint
574///
575/// # Examples
576///
577/// ```
578/// use iced_x86::code_asm::*;
579///
580/// let _ = ptr(rax);
581/// let _ = ptr(0x1234_5678).fs();
582/// let _ = ptr(rdx * 4 + rcx - 123);
583/// ```
584#[must_use]
585#[inline]
586#[rustfmt::skip]
587pub fn ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
588	mem.into().ptr()
589}
590
591/// Creates a memory operand with a `BYTE PTR` size hint
592///
593/// # Examples
594///
595/// ```
596/// use iced_x86::code_asm::*;
597///
598/// let _ = byte_ptr(rax);
599/// let _ = byte_ptr(0x1234_5678).fs();
600/// let _ = byte_ptr(rdx * 4 + rcx - 123);
601/// ```
602#[must_use]
603#[inline]
604#[rustfmt::skip]
605pub fn byte_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
606	mem.into().byte_ptr()
607}
608
609/// Creates a memory operand with a `WORD PTR` size hint
610///
611/// # Examples
612///
613/// ```
614/// use iced_x86::code_asm::*;
615///
616/// let _ = word_ptr(rax);
617/// let _ = word_ptr(0x1234_5678).fs();
618/// let _ = word_ptr(rdx * 4 + rcx - 123);
619/// ```
620#[must_use]
621#[inline]
622#[rustfmt::skip]
623pub fn word_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
624	mem.into().word_ptr()
625}
626
627/// Creates a memory operand with a `DWORD PTR` size hint
628///
629/// # Examples
630///
631/// ```
632/// use iced_x86::code_asm::*;
633///
634/// let _ = dword_ptr(rax);
635/// let _ = dword_ptr(0x1234_5678).fs();
636/// let _ = dword_ptr(rdx * 4 + rcx - 123);
637/// ```
638#[must_use]
639#[inline]
640#[rustfmt::skip]
641pub fn dword_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
642	mem.into().dword_ptr()
643}
644
645/// Creates a memory operand with a `QWORD PTR` size hint
646///
647/// # Examples
648///
649/// ```
650/// use iced_x86::code_asm::*;
651///
652/// let _ = qword_ptr(rax);
653/// let _ = qword_ptr(0x1234_5678).fs();
654/// let _ = qword_ptr(rdx * 4 + rcx - 123);
655/// ```
656#[must_use]
657#[inline]
658#[rustfmt::skip]
659pub fn qword_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
660	mem.into().qword_ptr()
661}
662
663/// Creates a memory operand with an `MMWORD PTR` size hint
664///
665/// # Examples
666///
667/// ```
668/// use iced_x86::code_asm::*;
669///
670/// let _ = mmword_ptr(rax);
671/// let _ = mmword_ptr(0x1234_5678).fs();
672/// let _ = mmword_ptr(rdx * 4 + rcx - 123);
673/// ```
674#[must_use]
675#[inline]
676#[rustfmt::skip]
677pub fn mmword_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
678	mem.into().mmword_ptr()
679}
680
681/// Creates a memory operand with a `TBYTE PTR` size hint
682///
683/// # Examples
684///
685/// ```
686/// use iced_x86::code_asm::*;
687///
688/// let _ = tbyte_ptr(rax);
689/// let _ = tbyte_ptr(0x1234_5678).fs();
690/// let _ = tbyte_ptr(rdx * 4 + rcx - 123);
691/// ```
692#[must_use]
693#[inline]
694#[rustfmt::skip]
695pub fn tbyte_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
696	mem.into().tbyte_ptr()
697}
698
699/// Creates a memory operand with a `TWORD PTR` size hint
700///
701/// # Examples
702///
703/// ```
704/// use iced_x86::code_asm::*;
705///
706/// let _ = tword_ptr(rax);
707/// let _ = tword_ptr(0x1234_5678).fs();
708/// let _ = tword_ptr(rdx * 4 + rcx - 123);
709/// ```
710#[must_use]
711#[inline]
712#[rustfmt::skip]
713pub fn tword_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
714	mem.into().tword_ptr()
715}
716
717/// Creates a memory operand with an `FWORD PTR` size hint
718///
719/// # Examples
720///
721/// ```
722/// use iced_x86::code_asm::*;
723///
724/// let _ = fword_ptr(rax);
725/// let _ = fword_ptr(0x1234_5678).fs();
726/// let _ = fword_ptr(rdx * 4 + rcx - 123);
727/// ```
728#[must_use]
729#[inline]
730#[rustfmt::skip]
731pub fn fword_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
732	mem.into().fword_ptr()
733}
734
735/// Creates a memory operand with an `OWORD PTR` size hint
736///
737/// # Examples
738///
739/// ```
740/// use iced_x86::code_asm::*;
741///
742/// let _ = oword_ptr(rax);
743/// let _ = oword_ptr(0x1234_5678).fs();
744/// let _ = oword_ptr(rdx * 4 + rcx - 123);
745/// ```
746#[must_use]
747#[inline]
748#[rustfmt::skip]
749pub fn oword_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
750	mem.into().oword_ptr()
751}
752
753/// Creates a memory operand with an `XMMWORD PTR` size hint
754///
755/// # Examples
756///
757/// ```
758/// use iced_x86::code_asm::*;
759///
760/// let _ = xmmword_ptr(rax);
761/// let _ = xmmword_ptr(0x1234_5678).fs();
762/// let _ = xmmword_ptr(rdx * 4 + rcx - 123);
763/// ```
764#[must_use]
765#[inline]
766#[rustfmt::skip]
767pub fn xmmword_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
768	mem.into().xmmword_ptr()
769}
770
771/// Creates a memory operand with a `YMMWORD PTR` size hint
772///
773/// # Examples
774///
775/// ```
776/// use iced_x86::code_asm::*;
777///
778/// let _ = ymmword_ptr(rax);
779/// let _ = ymmword_ptr(0x1234_5678).fs();
780/// let _ = ymmword_ptr(rdx * 4 + rcx - 123);
781/// ```
782#[must_use]
783#[inline]
784#[rustfmt::skip]
785pub fn ymmword_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
786	mem.into().ymmword_ptr()
787}
788
789/// Creates a memory operand with a `ZMMWORD PTR` size hint
790///
791/// # Examples
792///
793/// ```
794/// use iced_x86::code_asm::*;
795///
796/// let _ = zmmword_ptr(rax);
797/// let _ = zmmword_ptr(0x1234_5678).fs();
798/// let _ = zmmword_ptr(rdx * 4 + rcx - 123);
799/// ```
800#[must_use]
801#[inline]
802#[rustfmt::skip]
803pub fn zmmword_ptr<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
804	mem.into().zmmword_ptr()
805}
806
807/// Creates a broadcast memory operand with no size hint
808///
809/// # Examples
810///
811/// ```
812/// use iced_x86::code_asm::*;
813///
814/// let _ = bcst(rax);
815/// let _ = bcst(0x1234_5678).fs();
816/// let _ = bcst(rdx * 4 + rcx - 123);
817/// ```
818#[must_use]
819#[inline]
820#[rustfmt::skip]
821pub fn bcst<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
822	mem.into().bcst()
823}
824
825/// Creates a broadcast memory operand with a `WORD BCST` size hint
826///
827/// # Examples
828///
829/// ```
830/// use iced_x86::code_asm::*;
831///
832/// let _ = word_bcst(rax);
833/// let _ = word_bcst(0x1234_5678).fs();
834/// let _ = word_bcst(rdx * 4 + rcx - 123);
835/// ```
836#[must_use]
837#[inline]
838#[rustfmt::skip]
839pub fn word_bcst<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
840	mem.into().word_bcst()
841}
842
843/// Creates a broadcast memory operand with a `DWORD BCST` size hint
844///
845/// # Examples
846///
847/// ```
848/// use iced_x86::code_asm::*;
849///
850/// let _ = dword_bcst(rax);
851/// let _ = dword_bcst(0x1234_5678).fs();
852/// let _ = dword_bcst(rdx * 4 + rcx - 123);
853/// ```
854#[must_use]
855#[inline]
856#[rustfmt::skip]
857pub fn dword_bcst<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
858	mem.into().dword_bcst()
859}
860
861/// Creates a broadcast memory operand with a `QWORD BCST` size hint
862///
863/// # Examples
864///
865/// ```
866/// use iced_x86::code_asm::*;
867///
868/// let _ = qword_bcst(rax);
869/// let _ = qword_bcst(0x1234_5678).fs();
870/// let _ = qword_bcst(rdx * 4 + rcx - 123);
871/// ```
872#[must_use]
873#[inline]
874#[rustfmt::skip]
875pub fn qword_bcst<M: Into<AsmMemoryOperand>>(mem: M) -> AsmMemoryOperand {
876	mem.into().qword_bcst()
877}
878// GENERATOR-END: GlobalPtrMethods