Skip to main content

asmkit/x86/features/
SSE3.rs

1use crate::x86::assembler::*;
2use crate::x86::operands::*;
3use super::super::opcodes::*;
4use crate::core::emitter::*;
5use crate::core::operand::*;
6
7/// A dummy operand that represents no register. Here just for simplicity.
8const NOREG: Operand = Operand::new();
9
10/// `FISTTP` (FISTTP). 
11/// FISTTP converts the value in ST into a signed integer using truncation (chop) as rounding mode, transfers the result to the destination, and pop ST. FISTTP accepts word, short integer, and long integer destinations.
12///
13///
14/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/FISTTP.html).
15///
16/// Supported operand variants:
17///
18/// ```text
19/// +---+----------+
20/// | # | Operands |
21/// +---+----------+
22/// | 1 | Mem      |
23/// +---+----------+
24/// ```
25pub trait FisttpEmitter<A> {
26    fn fisttp(&mut self, op0: A);
27}
28
29impl<'a> FisttpEmitter<Mem> for Assembler<'a> {
30    fn fisttp(&mut self, op0: Mem) {
31        self.emit(FISTTPM32, op0.as_operand(), &NOREG, &NOREG, &NOREG);
32    }
33}
34
35/// `SSE_ADDSUBPD` (ADDSUBPD). 
36/// Adds odd-numbered double precision floating-point values of the first source operand (second operand) with the corresponding double precision floating-point values from the second source operand (third operand); stores the result in the odd-numbered values of the destination operand (first operand). Subtracts the even-numbered double precision floating-point values from the second source operand from the corresponding double precision floating values in the first source operand; stores the result into the even-numbered values of the destination operand.
37///
38///
39/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/ADDSUBPD.html).
40///
41/// Supported operand variants:
42///
43/// ```text
44/// +---+----------+
45/// | # | Operands |
46/// +---+----------+
47/// | 1 | Xmm, Mem |
48/// | 2 | Xmm, Xmm |
49/// +---+----------+
50/// ```
51pub trait SseAddsubpdEmitter<A, B> {
52    fn sse_addsubpd(&mut self, op0: A, op1: B);
53}
54
55impl<'a> SseAddsubpdEmitter<Xmm, Xmm> for Assembler<'a> {
56    fn sse_addsubpd(&mut self, op0: Xmm, op1: Xmm) {
57        self.emit(SSE_ADDSUBPDRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
58    }
59}
60
61impl<'a> SseAddsubpdEmitter<Xmm, Mem> for Assembler<'a> {
62    fn sse_addsubpd(&mut self, op0: Xmm, op1: Mem) {
63        self.emit(SSE_ADDSUBPDRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
64    }
65}
66
67/// `SSE_ADDSUBPS` (ADDSUBPS). 
68/// Adds odd-numbered single precision floating-point values of the first source operand (second operand) with the corresponding single precision floating-point values from the second source operand (third operand); stores the result in the odd-numbered values of the destination operand (first operand). Subtracts the even-numbered single precision floating-point values from the second source operand from the corresponding single precision floating values in the first source operand; stores the result into the even-numbered values of the destination operand.
69///
70///
71/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/ADDSUBPS.html).
72///
73/// Supported operand variants:
74///
75/// ```text
76/// +---+----------+
77/// | # | Operands |
78/// +---+----------+
79/// | 1 | Xmm, Mem |
80/// | 2 | Xmm, Xmm |
81/// +---+----------+
82/// ```
83pub trait SseAddsubpsEmitter<A, B> {
84    fn sse_addsubps(&mut self, op0: A, op1: B);
85}
86
87impl<'a> SseAddsubpsEmitter<Xmm, Xmm> for Assembler<'a> {
88    fn sse_addsubps(&mut self, op0: Xmm, op1: Xmm) {
89        self.emit(SSE_ADDSUBPSRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
90    }
91}
92
93impl<'a> SseAddsubpsEmitter<Xmm, Mem> for Assembler<'a> {
94    fn sse_addsubps(&mut self, op0: Xmm, op1: Mem) {
95        self.emit(SSE_ADDSUBPSRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
96    }
97}
98
99/// `SSE_HADDPD` (HADDPD). 
100/// Adds the double precision floating-point values in the high and low quadwords of the destination operand and stores the result in the low quadword of the destination operand.
101///
102///
103/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/HADDPD.html).
104///
105/// Supported operand variants:
106///
107/// ```text
108/// +---+----------+
109/// | # | Operands |
110/// +---+----------+
111/// | 1 | Xmm, Mem |
112/// | 2 | Xmm, Xmm |
113/// +---+----------+
114/// ```
115pub trait SseHaddpdEmitter<A, B> {
116    fn sse_haddpd(&mut self, op0: A, op1: B);
117}
118
119impl<'a> SseHaddpdEmitter<Xmm, Xmm> for Assembler<'a> {
120    fn sse_haddpd(&mut self, op0: Xmm, op1: Xmm) {
121        self.emit(SSE_HADDPDRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
122    }
123}
124
125impl<'a> SseHaddpdEmitter<Xmm, Mem> for Assembler<'a> {
126    fn sse_haddpd(&mut self, op0: Xmm, op1: Mem) {
127        self.emit(SSE_HADDPDRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
128    }
129}
130
131/// `SSE_HADDPS` (HADDPS). 
132/// Adds the single precision floating-point values in the first and second dwords of the destination operand and stores the result in the first dword of the destination operand.
133///
134///
135/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/HADDPS.html).
136///
137/// Supported operand variants:
138///
139/// ```text
140/// +---+----------+
141/// | # | Operands |
142/// +---+----------+
143/// | 1 | Xmm, Mem |
144/// | 2 | Xmm, Xmm |
145/// +---+----------+
146/// ```
147pub trait SseHaddpsEmitter<A, B> {
148    fn sse_haddps(&mut self, op0: A, op1: B);
149}
150
151impl<'a> SseHaddpsEmitter<Xmm, Xmm> for Assembler<'a> {
152    fn sse_haddps(&mut self, op0: Xmm, op1: Xmm) {
153        self.emit(SSE_HADDPSRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
154    }
155}
156
157impl<'a> SseHaddpsEmitter<Xmm, Mem> for Assembler<'a> {
158    fn sse_haddps(&mut self, op0: Xmm, op1: Mem) {
159        self.emit(SSE_HADDPSRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
160    }
161}
162
163/// `SSE_HSUBPD` (HSUBPD). 
164/// The HSUBPD instruction subtracts horizontally the packed double precision floating-point numbers of both operands.
165///
166///
167/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/HSUBPD.html).
168///
169/// Supported operand variants:
170///
171/// ```text
172/// +---+----------+
173/// | # | Operands |
174/// +---+----------+
175/// | 1 | Xmm, Mem |
176/// | 2 | Xmm, Xmm |
177/// +---+----------+
178/// ```
179pub trait SseHsubpdEmitter<A, B> {
180    fn sse_hsubpd(&mut self, op0: A, op1: B);
181}
182
183impl<'a> SseHsubpdEmitter<Xmm, Xmm> for Assembler<'a> {
184    fn sse_hsubpd(&mut self, op0: Xmm, op1: Xmm) {
185        self.emit(SSE_HSUBPDRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
186    }
187}
188
189impl<'a> SseHsubpdEmitter<Xmm, Mem> for Assembler<'a> {
190    fn sse_hsubpd(&mut self, op0: Xmm, op1: Mem) {
191        self.emit(SSE_HSUBPDRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
192    }
193}
194
195/// `SSE_HSUBPS` (HSUBPS). 
196/// Subtracts the single precision floating-point value in the second dword of the destination operand from the first dword of the destination operand and stores the result in the first dword of the destination operand.
197///
198///
199/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/HSUBPS.html).
200///
201/// Supported operand variants:
202///
203/// ```text
204/// +---+----------+
205/// | # | Operands |
206/// +---+----------+
207/// | 1 | Xmm, Mem |
208/// | 2 | Xmm, Xmm |
209/// +---+----------+
210/// ```
211pub trait SseHsubpsEmitter<A, B> {
212    fn sse_hsubps(&mut self, op0: A, op1: B);
213}
214
215impl<'a> SseHsubpsEmitter<Xmm, Xmm> for Assembler<'a> {
216    fn sse_hsubps(&mut self, op0: Xmm, op1: Xmm) {
217        self.emit(SSE_HSUBPSRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
218    }
219}
220
221impl<'a> SseHsubpsEmitter<Xmm, Mem> for Assembler<'a> {
222    fn sse_hsubps(&mut self, op0: Xmm, op1: Mem) {
223        self.emit(SSE_HSUBPSRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
224    }
225}
226
227/// `SSE_LDDQU` (LDDQU). 
228/// The instruction is functionally similar to (V)MOVDQU ymm/xmm, m256/m128 for loading from memory. That is: 32/16 bytes of data starting at an address specified by the source memory operand (second operand) are fetched from memory and placed in a destination register (first operand). The source operand need not be aligned on a 32/16-byte boundary. Up to 64/32 bytes may be loaded from memory; this is implementation dependent.
229///
230///
231/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/LDDQU.html).
232///
233/// Supported operand variants:
234///
235/// ```text
236/// +---+----------+
237/// | # | Operands |
238/// +---+----------+
239/// | 1 | Xmm, Mem |
240/// +---+----------+
241/// ```
242pub trait SseLddquEmitter<A, B> {
243    fn sse_lddqu(&mut self, op0: A, op1: B);
244}
245
246impl<'a> SseLddquEmitter<Xmm, Mem> for Assembler<'a> {
247    fn sse_lddqu(&mut self, op0: Xmm, op1: Mem) {
248        self.emit(SSE_LDDQURM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
249    }
250}
251
252/// `SSE_MOVDDUP` (MOVDDUP). 
253/// For 256-bit or higher versions: Duplicates even-indexed double precision floating-point values from the source operand (the second operand) and into adjacent pair and store to the destination operand (the first operand).
254///
255///
256/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/MOVDDUP.html).
257///
258/// Supported operand variants:
259///
260/// ```text
261/// +---+----------+
262/// | # | Operands |
263/// +---+----------+
264/// | 1 | Xmm, Mem |
265/// | 2 | Xmm, Xmm |
266/// +---+----------+
267/// ```
268pub trait SseMovddupEmitter<A, B> {
269    fn sse_movddup(&mut self, op0: A, op1: B);
270}
271
272impl<'a> SseMovddupEmitter<Xmm, Xmm> for Assembler<'a> {
273    fn sse_movddup(&mut self, op0: Xmm, op1: Xmm) {
274        self.emit(SSE_MOVDDUPRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
275    }
276}
277
278impl<'a> SseMovddupEmitter<Xmm, Mem> for Assembler<'a> {
279    fn sse_movddup(&mut self, op0: Xmm, op1: Mem) {
280        self.emit(SSE_MOVDDUPRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
281    }
282}
283
284/// `SSE_MOVSHDUP` (MOVSHDUP). 
285/// Duplicates odd-indexed single precision floating-point values from the source operand (the second operand) to adjacent element pair in the destination operand (the first operand). See Figure 4-3. The source operand is an XMM, YMM or ZMM register or 128, 256 or 512-bit memory location and the destination operand is an XMM, YMM or ZMM register.
286///
287///
288/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/MOVSHDUP.html).
289///
290/// Supported operand variants:
291///
292/// ```text
293/// +---+----------+
294/// | # | Operands |
295/// +---+----------+
296/// | 1 | Xmm, Mem |
297/// | 2 | Xmm, Xmm |
298/// +---+----------+
299/// ```
300pub trait SseMovshdupEmitter<A, B> {
301    fn sse_movshdup(&mut self, op0: A, op1: B);
302}
303
304impl<'a> SseMovshdupEmitter<Xmm, Xmm> for Assembler<'a> {
305    fn sse_movshdup(&mut self, op0: Xmm, op1: Xmm) {
306        self.emit(SSE_MOVSHDUPRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
307    }
308}
309
310impl<'a> SseMovshdupEmitter<Xmm, Mem> for Assembler<'a> {
311    fn sse_movshdup(&mut self, op0: Xmm, op1: Mem) {
312        self.emit(SSE_MOVSHDUPRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
313    }
314}
315
316/// `SSE_MOVSLDUP` (MOVSLDUP). 
317/// Duplicates even-indexed single precision floating-point values from the source operand (the second operand). See Figure 4-4. The source operand is an XMM, YMM or ZMM register or 128, 256 or 512-bit memory location and the destination operand is an XMM, YMM or ZMM register.
318///
319///
320/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/MOVSLDUP.html).
321///
322/// Supported operand variants:
323///
324/// ```text
325/// +---+----------+
326/// | # | Operands |
327/// +---+----------+
328/// | 1 | Xmm, Mem |
329/// | 2 | Xmm, Xmm |
330/// +---+----------+
331/// ```
332pub trait SseMovsldupEmitter<A, B> {
333    fn sse_movsldup(&mut self, op0: A, op1: B);
334}
335
336impl<'a> SseMovsldupEmitter<Xmm, Xmm> for Assembler<'a> {
337    fn sse_movsldup(&mut self, op0: Xmm, op1: Xmm) {
338        self.emit(SSE_MOVSLDUPRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
339    }
340}
341
342impl<'a> SseMovsldupEmitter<Xmm, Mem> for Assembler<'a> {
343    fn sse_movsldup(&mut self, op0: Xmm, op1: Mem) {
344        self.emit(SSE_MOVSLDUPRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
345    }
346}
347
348
349impl<'a> Assembler<'a> {
350    /// `FISTTP` (FISTTP). 
351    /// FISTTP converts the value in ST into a signed integer using truncation (chop) as rounding mode, transfers the result to the destination, and pop ST. FISTTP accepts word, short integer, and long integer destinations.
352    ///
353    ///
354    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/FISTTP.html).
355    ///
356    /// Supported operand variants:
357    ///
358    /// ```text
359    /// +---+----------+
360    /// | # | Operands |
361    /// +---+----------+
362    /// | 1 | Mem      |
363    /// +---+----------+
364    /// ```
365    #[inline]
366    pub fn fisttp<A>(&mut self, op0: A)
367    where Assembler<'a>: FisttpEmitter<A> {
368        <Self as FisttpEmitter<A>>::fisttp(self, op0);
369    }
370    /// `SSE_ADDSUBPD` (ADDSUBPD). 
371    /// Adds odd-numbered double precision floating-point values of the first source operand (second operand) with the corresponding double precision floating-point values from the second source operand (third operand); stores the result in the odd-numbered values of the destination operand (first operand). Subtracts the even-numbered double precision floating-point values from the second source operand from the corresponding double precision floating values in the first source operand; stores the result into the even-numbered values of the destination operand.
372    ///
373    ///
374    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/ADDSUBPD.html).
375    ///
376    /// Supported operand variants:
377    ///
378    /// ```text
379    /// +---+----------+
380    /// | # | Operands |
381    /// +---+----------+
382    /// | 1 | Xmm, Mem |
383    /// | 2 | Xmm, Xmm |
384    /// +---+----------+
385    /// ```
386    #[inline]
387    pub fn sse_addsubpd<A, B>(&mut self, op0: A, op1: B)
388    where Assembler<'a>: SseAddsubpdEmitter<A, B> {
389        <Self as SseAddsubpdEmitter<A, B>>::sse_addsubpd(self, op0, op1);
390    }
391    /// `SSE_ADDSUBPS` (ADDSUBPS). 
392    /// Adds odd-numbered single precision floating-point values of the first source operand (second operand) with the corresponding single precision floating-point values from the second source operand (third operand); stores the result in the odd-numbered values of the destination operand (first operand). Subtracts the even-numbered single precision floating-point values from the second source operand from the corresponding single precision floating values in the first source operand; stores the result into the even-numbered values of the destination operand.
393    ///
394    ///
395    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/ADDSUBPS.html).
396    ///
397    /// Supported operand variants:
398    ///
399    /// ```text
400    /// +---+----------+
401    /// | # | Operands |
402    /// +---+----------+
403    /// | 1 | Xmm, Mem |
404    /// | 2 | Xmm, Xmm |
405    /// +---+----------+
406    /// ```
407    #[inline]
408    pub fn sse_addsubps<A, B>(&mut self, op0: A, op1: B)
409    where Assembler<'a>: SseAddsubpsEmitter<A, B> {
410        <Self as SseAddsubpsEmitter<A, B>>::sse_addsubps(self, op0, op1);
411    }
412    /// `SSE_HADDPD` (HADDPD). 
413    /// Adds the double precision floating-point values in the high and low quadwords of the destination operand and stores the result in the low quadword of the destination operand.
414    ///
415    ///
416    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/HADDPD.html).
417    ///
418    /// Supported operand variants:
419    ///
420    /// ```text
421    /// +---+----------+
422    /// | # | Operands |
423    /// +---+----------+
424    /// | 1 | Xmm, Mem |
425    /// | 2 | Xmm, Xmm |
426    /// +---+----------+
427    /// ```
428    #[inline]
429    pub fn sse_haddpd<A, B>(&mut self, op0: A, op1: B)
430    where Assembler<'a>: SseHaddpdEmitter<A, B> {
431        <Self as SseHaddpdEmitter<A, B>>::sse_haddpd(self, op0, op1);
432    }
433    /// `SSE_HADDPS` (HADDPS). 
434    /// Adds the single precision floating-point values in the first and second dwords of the destination operand and stores the result in the first dword of the destination operand.
435    ///
436    ///
437    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/HADDPS.html).
438    ///
439    /// Supported operand variants:
440    ///
441    /// ```text
442    /// +---+----------+
443    /// | # | Operands |
444    /// +---+----------+
445    /// | 1 | Xmm, Mem |
446    /// | 2 | Xmm, Xmm |
447    /// +---+----------+
448    /// ```
449    #[inline]
450    pub fn sse_haddps<A, B>(&mut self, op0: A, op1: B)
451    where Assembler<'a>: SseHaddpsEmitter<A, B> {
452        <Self as SseHaddpsEmitter<A, B>>::sse_haddps(self, op0, op1);
453    }
454    /// `SSE_HSUBPD` (HSUBPD). 
455    /// The HSUBPD instruction subtracts horizontally the packed double precision floating-point numbers of both operands.
456    ///
457    ///
458    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/HSUBPD.html).
459    ///
460    /// Supported operand variants:
461    ///
462    /// ```text
463    /// +---+----------+
464    /// | # | Operands |
465    /// +---+----------+
466    /// | 1 | Xmm, Mem |
467    /// | 2 | Xmm, Xmm |
468    /// +---+----------+
469    /// ```
470    #[inline]
471    pub fn sse_hsubpd<A, B>(&mut self, op0: A, op1: B)
472    where Assembler<'a>: SseHsubpdEmitter<A, B> {
473        <Self as SseHsubpdEmitter<A, B>>::sse_hsubpd(self, op0, op1);
474    }
475    /// `SSE_HSUBPS` (HSUBPS). 
476    /// Subtracts the single precision floating-point value in the second dword of the destination operand from the first dword of the destination operand and stores the result in the first dword of the destination operand.
477    ///
478    ///
479    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/HSUBPS.html).
480    ///
481    /// Supported operand variants:
482    ///
483    /// ```text
484    /// +---+----------+
485    /// | # | Operands |
486    /// +---+----------+
487    /// | 1 | Xmm, Mem |
488    /// | 2 | Xmm, Xmm |
489    /// +---+----------+
490    /// ```
491    #[inline]
492    pub fn sse_hsubps<A, B>(&mut self, op0: A, op1: B)
493    where Assembler<'a>: SseHsubpsEmitter<A, B> {
494        <Self as SseHsubpsEmitter<A, B>>::sse_hsubps(self, op0, op1);
495    }
496    /// `SSE_LDDQU` (LDDQU). 
497    /// The instruction is functionally similar to (V)MOVDQU ymm/xmm, m256/m128 for loading from memory. That is: 32/16 bytes of data starting at an address specified by the source memory operand (second operand) are fetched from memory and placed in a destination register (first operand). The source operand need not be aligned on a 32/16-byte boundary. Up to 64/32 bytes may be loaded from memory; this is implementation dependent.
498    ///
499    ///
500    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/LDDQU.html).
501    ///
502    /// Supported operand variants:
503    ///
504    /// ```text
505    /// +---+----------+
506    /// | # | Operands |
507    /// +---+----------+
508    /// | 1 | Xmm, Mem |
509    /// +---+----------+
510    /// ```
511    #[inline]
512    pub fn sse_lddqu<A, B>(&mut self, op0: A, op1: B)
513    where Assembler<'a>: SseLddquEmitter<A, B> {
514        <Self as SseLddquEmitter<A, B>>::sse_lddqu(self, op0, op1);
515    }
516    /// `SSE_MOVDDUP` (MOVDDUP). 
517    /// For 256-bit or higher versions: Duplicates even-indexed double precision floating-point values from the source operand (the second operand) and into adjacent pair and store to the destination operand (the first operand).
518    ///
519    ///
520    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/MOVDDUP.html).
521    ///
522    /// Supported operand variants:
523    ///
524    /// ```text
525    /// +---+----------+
526    /// | # | Operands |
527    /// +---+----------+
528    /// | 1 | Xmm, Mem |
529    /// | 2 | Xmm, Xmm |
530    /// +---+----------+
531    /// ```
532    #[inline]
533    pub fn sse_movddup<A, B>(&mut self, op0: A, op1: B)
534    where Assembler<'a>: SseMovddupEmitter<A, B> {
535        <Self as SseMovddupEmitter<A, B>>::sse_movddup(self, op0, op1);
536    }
537    /// `SSE_MOVSHDUP` (MOVSHDUP). 
538    /// Duplicates odd-indexed single precision floating-point values from the source operand (the second operand) to adjacent element pair in the destination operand (the first operand). See Figure 4-3. The source operand is an XMM, YMM or ZMM register or 128, 256 or 512-bit memory location and the destination operand is an XMM, YMM or ZMM register.
539    ///
540    ///
541    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/MOVSHDUP.html).
542    ///
543    /// Supported operand variants:
544    ///
545    /// ```text
546    /// +---+----------+
547    /// | # | Operands |
548    /// +---+----------+
549    /// | 1 | Xmm, Mem |
550    /// | 2 | Xmm, Xmm |
551    /// +---+----------+
552    /// ```
553    #[inline]
554    pub fn sse_movshdup<A, B>(&mut self, op0: A, op1: B)
555    where Assembler<'a>: SseMovshdupEmitter<A, B> {
556        <Self as SseMovshdupEmitter<A, B>>::sse_movshdup(self, op0, op1);
557    }
558    /// `SSE_MOVSLDUP` (MOVSLDUP). 
559    /// Duplicates even-indexed single precision floating-point values from the source operand (the second operand). See Figure 4-4. The source operand is an XMM, YMM or ZMM register or 128, 256 or 512-bit memory location and the destination operand is an XMM, YMM or ZMM register.
560    ///
561    ///
562    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/MOVSLDUP.html).
563    ///
564    /// Supported operand variants:
565    ///
566    /// ```text
567    /// +---+----------+
568    /// | # | Operands |
569    /// +---+----------+
570    /// | 1 | Xmm, Mem |
571    /// | 2 | Xmm, Xmm |
572    /// +---+----------+
573    /// ```
574    #[inline]
575    pub fn sse_movsldup<A, B>(&mut self, op0: A, op1: B)
576    where Assembler<'a>: SseMovsldupEmitter<A, B> {
577        <Self as SseMovsldupEmitter<A, B>>::sse_movsldup(self, op0, op1);
578    }
579}