Skip to main content

asmkit/x86/features/
SSE3.rs

1use super::super::opcodes::*;
2use crate::core::emitter::*;
3use crate::core::operand::*;
4use crate::x86::assembler::*;
5use crate::x86::operands::*;
6
7/// A dummy operand that represents no register. Here just for simplicity.
8const NOREG: Operand = Operand::new();
9
10/// `FISTTP`.
11///
12/// Supported operand variants:
13///
14/// ```text
15/// +---+----------+
16/// | # | Operands |
17/// +---+----------+
18/// | 1 | Mem      |
19/// +---+----------+
20/// ```
21pub trait FisttpEmitter<A> {
22    fn fisttp(&mut self, op0: A);
23}
24
25impl<'a> FisttpEmitter<Mem> for Assembler<'a> {
26    fn fisttp(&mut self, op0: Mem) {
27        self.emit(FISTTPM32, op0.as_operand(), &NOREG, &NOREG, &NOREG);
28    }
29}
30
31/// `SSE_ADDSUBPD`.
32///
33/// Supported operand variants:
34///
35/// ```text
36/// +---+----------+
37/// | # | Operands |
38/// +---+----------+
39/// | 1 | Xmm, Mem |
40/// | 2 | Xmm, Xmm |
41/// +---+----------+
42/// ```
43pub trait SseAddsubpdEmitter<A, B> {
44    fn sse_addsubpd(&mut self, op0: A, op1: B);
45}
46
47impl<'a> SseAddsubpdEmitter<Xmm, Xmm> for Assembler<'a> {
48    fn sse_addsubpd(&mut self, op0: Xmm, op1: Xmm) {
49        self.emit(
50            SSE_ADDSUBPDRR,
51            op0.as_operand(),
52            op1.as_operand(),
53            &NOREG,
54            &NOREG,
55        );
56    }
57}
58
59impl<'a> SseAddsubpdEmitter<Xmm, Mem> for Assembler<'a> {
60    fn sse_addsubpd(&mut self, op0: Xmm, op1: Mem) {
61        self.emit(
62            SSE_ADDSUBPDRM,
63            op0.as_operand(),
64            op1.as_operand(),
65            &NOREG,
66            &NOREG,
67        );
68    }
69}
70
71/// `SSE_ADDSUBPS`.
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(
90            SSE_ADDSUBPSRR,
91            op0.as_operand(),
92            op1.as_operand(),
93            &NOREG,
94            &NOREG,
95        );
96    }
97}
98
99impl<'a> SseAddsubpsEmitter<Xmm, Mem> for Assembler<'a> {
100    fn sse_addsubps(&mut self, op0: Xmm, op1: Mem) {
101        self.emit(
102            SSE_ADDSUBPSRM,
103            op0.as_operand(),
104            op1.as_operand(),
105            &NOREG,
106            &NOREG,
107        );
108    }
109}
110
111/// `SSE_HADDPD`.
112///
113/// Supported operand variants:
114///
115/// ```text
116/// +---+----------+
117/// | # | Operands |
118/// +---+----------+
119/// | 1 | Xmm, Mem |
120/// | 2 | Xmm, Xmm |
121/// +---+----------+
122/// ```
123pub trait SseHaddpdEmitter<A, B> {
124    fn sse_haddpd(&mut self, op0: A, op1: B);
125}
126
127impl<'a> SseHaddpdEmitter<Xmm, Xmm> for Assembler<'a> {
128    fn sse_haddpd(&mut self, op0: Xmm, op1: Xmm) {
129        self.emit(
130            SSE_HADDPDRR,
131            op0.as_operand(),
132            op1.as_operand(),
133            &NOREG,
134            &NOREG,
135        );
136    }
137}
138
139impl<'a> SseHaddpdEmitter<Xmm, Mem> for Assembler<'a> {
140    fn sse_haddpd(&mut self, op0: Xmm, op1: Mem) {
141        self.emit(
142            SSE_HADDPDRM,
143            op0.as_operand(),
144            op1.as_operand(),
145            &NOREG,
146            &NOREG,
147        );
148    }
149}
150
151/// `SSE_HADDPS`.
152///
153/// Supported operand variants:
154///
155/// ```text
156/// +---+----------+
157/// | # | Operands |
158/// +---+----------+
159/// | 1 | Xmm, Mem |
160/// | 2 | Xmm, Xmm |
161/// +---+----------+
162/// ```
163pub trait SseHaddpsEmitter<A, B> {
164    fn sse_haddps(&mut self, op0: A, op1: B);
165}
166
167impl<'a> SseHaddpsEmitter<Xmm, Xmm> for Assembler<'a> {
168    fn sse_haddps(&mut self, op0: Xmm, op1: Xmm) {
169        self.emit(
170            SSE_HADDPSRR,
171            op0.as_operand(),
172            op1.as_operand(),
173            &NOREG,
174            &NOREG,
175        );
176    }
177}
178
179impl<'a> SseHaddpsEmitter<Xmm, Mem> for Assembler<'a> {
180    fn sse_haddps(&mut self, op0: Xmm, op1: Mem) {
181        self.emit(
182            SSE_HADDPSRM,
183            op0.as_operand(),
184            op1.as_operand(),
185            &NOREG,
186            &NOREG,
187        );
188    }
189}
190
191/// `SSE_HSUBPD`.
192///
193/// Supported operand variants:
194///
195/// ```text
196/// +---+----------+
197/// | # | Operands |
198/// +---+----------+
199/// | 1 | Xmm, Mem |
200/// | 2 | Xmm, Xmm |
201/// +---+----------+
202/// ```
203pub trait SseHsubpdEmitter<A, B> {
204    fn sse_hsubpd(&mut self, op0: A, op1: B);
205}
206
207impl<'a> SseHsubpdEmitter<Xmm, Xmm> for Assembler<'a> {
208    fn sse_hsubpd(&mut self, op0: Xmm, op1: Xmm) {
209        self.emit(
210            SSE_HSUBPDRR,
211            op0.as_operand(),
212            op1.as_operand(),
213            &NOREG,
214            &NOREG,
215        );
216    }
217}
218
219impl<'a> SseHsubpdEmitter<Xmm, Mem> for Assembler<'a> {
220    fn sse_hsubpd(&mut self, op0: Xmm, op1: Mem) {
221        self.emit(
222            SSE_HSUBPDRM,
223            op0.as_operand(),
224            op1.as_operand(),
225            &NOREG,
226            &NOREG,
227        );
228    }
229}
230
231/// `SSE_HSUBPS`.
232///
233/// Supported operand variants:
234///
235/// ```text
236/// +---+----------+
237/// | # | Operands |
238/// +---+----------+
239/// | 1 | Xmm, Mem |
240/// | 2 | Xmm, Xmm |
241/// +---+----------+
242/// ```
243pub trait SseHsubpsEmitter<A, B> {
244    fn sse_hsubps(&mut self, op0: A, op1: B);
245}
246
247impl<'a> SseHsubpsEmitter<Xmm, Xmm> for Assembler<'a> {
248    fn sse_hsubps(&mut self, op0: Xmm, op1: Xmm) {
249        self.emit(
250            SSE_HSUBPSRR,
251            op0.as_operand(),
252            op1.as_operand(),
253            &NOREG,
254            &NOREG,
255        );
256    }
257}
258
259impl<'a> SseHsubpsEmitter<Xmm, Mem> for Assembler<'a> {
260    fn sse_hsubps(&mut self, op0: Xmm, op1: Mem) {
261        self.emit(
262            SSE_HSUBPSRM,
263            op0.as_operand(),
264            op1.as_operand(),
265            &NOREG,
266            &NOREG,
267        );
268    }
269}
270
271/// `SSE_LDDQU`.
272///
273/// Supported operand variants:
274///
275/// ```text
276/// +---+----------+
277/// | # | Operands |
278/// +---+----------+
279/// | 1 | Xmm, Mem |
280/// +---+----------+
281/// ```
282pub trait SseLddquEmitter<A, B> {
283    fn sse_lddqu(&mut self, op0: A, op1: B);
284}
285
286impl<'a> SseLddquEmitter<Xmm, Mem> for Assembler<'a> {
287    fn sse_lddqu(&mut self, op0: Xmm, op1: Mem) {
288        self.emit(
289            SSE_LDDQURM,
290            op0.as_operand(),
291            op1.as_operand(),
292            &NOREG,
293            &NOREG,
294        );
295    }
296}
297
298/// `SSE_MOVDDUP`.
299///
300/// Supported operand variants:
301///
302/// ```text
303/// +---+----------+
304/// | # | Operands |
305/// +---+----------+
306/// | 1 | Xmm, Mem |
307/// | 2 | Xmm, Xmm |
308/// +---+----------+
309/// ```
310pub trait SseMovddupEmitter<A, B> {
311    fn sse_movddup(&mut self, op0: A, op1: B);
312}
313
314impl<'a> SseMovddupEmitter<Xmm, Xmm> for Assembler<'a> {
315    fn sse_movddup(&mut self, op0: Xmm, op1: Xmm) {
316        self.emit(
317            SSE_MOVDDUPRR,
318            op0.as_operand(),
319            op1.as_operand(),
320            &NOREG,
321            &NOREG,
322        );
323    }
324}
325
326impl<'a> SseMovddupEmitter<Xmm, Mem> for Assembler<'a> {
327    fn sse_movddup(&mut self, op0: Xmm, op1: Mem) {
328        self.emit(
329            SSE_MOVDDUPRM,
330            op0.as_operand(),
331            op1.as_operand(),
332            &NOREG,
333            &NOREG,
334        );
335    }
336}
337
338/// `SSE_MOVSHDUP`.
339///
340/// Supported operand variants:
341///
342/// ```text
343/// +---+----------+
344/// | # | Operands |
345/// +---+----------+
346/// | 1 | Xmm, Mem |
347/// | 2 | Xmm, Xmm |
348/// +---+----------+
349/// ```
350pub trait SseMovshdupEmitter<A, B> {
351    fn sse_movshdup(&mut self, op0: A, op1: B);
352}
353
354impl<'a> SseMovshdupEmitter<Xmm, Xmm> for Assembler<'a> {
355    fn sse_movshdup(&mut self, op0: Xmm, op1: Xmm) {
356        self.emit(
357            SSE_MOVSHDUPRR,
358            op0.as_operand(),
359            op1.as_operand(),
360            &NOREG,
361            &NOREG,
362        );
363    }
364}
365
366impl<'a> SseMovshdupEmitter<Xmm, Mem> for Assembler<'a> {
367    fn sse_movshdup(&mut self, op0: Xmm, op1: Mem) {
368        self.emit(
369            SSE_MOVSHDUPRM,
370            op0.as_operand(),
371            op1.as_operand(),
372            &NOREG,
373            &NOREG,
374        );
375    }
376}
377
378/// `SSE_MOVSLDUP`.
379///
380/// Supported operand variants:
381///
382/// ```text
383/// +---+----------+
384/// | # | Operands |
385/// +---+----------+
386/// | 1 | Xmm, Mem |
387/// | 2 | Xmm, Xmm |
388/// +---+----------+
389/// ```
390pub trait SseMovsldupEmitter<A, B> {
391    fn sse_movsldup(&mut self, op0: A, op1: B);
392}
393
394impl<'a> SseMovsldupEmitter<Xmm, Xmm> for Assembler<'a> {
395    fn sse_movsldup(&mut self, op0: Xmm, op1: Xmm) {
396        self.emit(
397            SSE_MOVSLDUPRR,
398            op0.as_operand(),
399            op1.as_operand(),
400            &NOREG,
401            &NOREG,
402        );
403    }
404}
405
406impl<'a> SseMovsldupEmitter<Xmm, Mem> for Assembler<'a> {
407    fn sse_movsldup(&mut self, op0: Xmm, op1: Mem) {
408        self.emit(
409            SSE_MOVSLDUPRM,
410            op0.as_operand(),
411            op1.as_operand(),
412            &NOREG,
413            &NOREG,
414        );
415    }
416}
417
418impl<'a> Assembler<'a> {
419    /// `FISTTP`.
420    ///
421    /// Supported operand variants:
422    ///
423    /// ```text
424    /// +---+----------+
425    /// | # | Operands |
426    /// +---+----------+
427    /// | 1 | Mem      |
428    /// +---+----------+
429    /// ```
430    #[inline]
431    pub fn fisttp<A>(&mut self, op0: A)
432    where
433        Assembler<'a>: FisttpEmitter<A>,
434    {
435        <Self as FisttpEmitter<A>>::fisttp(self, op0);
436    }
437    /// `SSE_ADDSUBPD`.
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_addsubpd<A, B>(&mut self, op0: A, op1: B)
451    where
452        Assembler<'a>: SseAddsubpdEmitter<A, B>,
453    {
454        <Self as SseAddsubpdEmitter<A, B>>::sse_addsubpd(self, op0, op1);
455    }
456    /// `SSE_ADDSUBPS`.
457    ///
458    /// Supported operand variants:
459    ///
460    /// ```text
461    /// +---+----------+
462    /// | # | Operands |
463    /// +---+----------+
464    /// | 1 | Xmm, Mem |
465    /// | 2 | Xmm, Xmm |
466    /// +---+----------+
467    /// ```
468    #[inline]
469    pub fn sse_addsubps<A, B>(&mut self, op0: A, op1: B)
470    where
471        Assembler<'a>: SseAddsubpsEmitter<A, B>,
472    {
473        <Self as SseAddsubpsEmitter<A, B>>::sse_addsubps(self, op0, op1);
474    }
475    /// `SSE_HADDPD`.
476    ///
477    /// Supported operand variants:
478    ///
479    /// ```text
480    /// +---+----------+
481    /// | # | Operands |
482    /// +---+----------+
483    /// | 1 | Xmm, Mem |
484    /// | 2 | Xmm, Xmm |
485    /// +---+----------+
486    /// ```
487    #[inline]
488    pub fn sse_haddpd<A, B>(&mut self, op0: A, op1: B)
489    where
490        Assembler<'a>: SseHaddpdEmitter<A, B>,
491    {
492        <Self as SseHaddpdEmitter<A, B>>::sse_haddpd(self, op0, op1);
493    }
494    /// `SSE_HADDPS`.
495    ///
496    /// Supported operand variants:
497    ///
498    /// ```text
499    /// +---+----------+
500    /// | # | Operands |
501    /// +---+----------+
502    /// | 1 | Xmm, Mem |
503    /// | 2 | Xmm, Xmm |
504    /// +---+----------+
505    /// ```
506    #[inline]
507    pub fn sse_haddps<A, B>(&mut self, op0: A, op1: B)
508    where
509        Assembler<'a>: SseHaddpsEmitter<A, B>,
510    {
511        <Self as SseHaddpsEmitter<A, B>>::sse_haddps(self, op0, op1);
512    }
513    /// `SSE_HSUBPD`.
514    ///
515    /// Supported operand variants:
516    ///
517    /// ```text
518    /// +---+----------+
519    /// | # | Operands |
520    /// +---+----------+
521    /// | 1 | Xmm, Mem |
522    /// | 2 | Xmm, Xmm |
523    /// +---+----------+
524    /// ```
525    #[inline]
526    pub fn sse_hsubpd<A, B>(&mut self, op0: A, op1: B)
527    where
528        Assembler<'a>: SseHsubpdEmitter<A, B>,
529    {
530        <Self as SseHsubpdEmitter<A, B>>::sse_hsubpd(self, op0, op1);
531    }
532    /// `SSE_HSUBPS`.
533    ///
534    /// Supported operand variants:
535    ///
536    /// ```text
537    /// +---+----------+
538    /// | # | Operands |
539    /// +---+----------+
540    /// | 1 | Xmm, Mem |
541    /// | 2 | Xmm, Xmm |
542    /// +---+----------+
543    /// ```
544    #[inline]
545    pub fn sse_hsubps<A, B>(&mut self, op0: A, op1: B)
546    where
547        Assembler<'a>: SseHsubpsEmitter<A, B>,
548    {
549        <Self as SseHsubpsEmitter<A, B>>::sse_hsubps(self, op0, op1);
550    }
551    /// `SSE_LDDQU`.
552    ///
553    /// Supported operand variants:
554    ///
555    /// ```text
556    /// +---+----------+
557    /// | # | Operands |
558    /// +---+----------+
559    /// | 1 | Xmm, Mem |
560    /// +---+----------+
561    /// ```
562    #[inline]
563    pub fn sse_lddqu<A, B>(&mut self, op0: A, op1: B)
564    where
565        Assembler<'a>: SseLddquEmitter<A, B>,
566    {
567        <Self as SseLddquEmitter<A, B>>::sse_lddqu(self, op0, op1);
568    }
569    /// `SSE_MOVDDUP`.
570    ///
571    /// Supported operand variants:
572    ///
573    /// ```text
574    /// +---+----------+
575    /// | # | Operands |
576    /// +---+----------+
577    /// | 1 | Xmm, Mem |
578    /// | 2 | Xmm, Xmm |
579    /// +---+----------+
580    /// ```
581    #[inline]
582    pub fn sse_movddup<A, B>(&mut self, op0: A, op1: B)
583    where
584        Assembler<'a>: SseMovddupEmitter<A, B>,
585    {
586        <Self as SseMovddupEmitter<A, B>>::sse_movddup(self, op0, op1);
587    }
588    /// `SSE_MOVSHDUP`.
589    ///
590    /// Supported operand variants:
591    ///
592    /// ```text
593    /// +---+----------+
594    /// | # | Operands |
595    /// +---+----------+
596    /// | 1 | Xmm, Mem |
597    /// | 2 | Xmm, Xmm |
598    /// +---+----------+
599    /// ```
600    #[inline]
601    pub fn sse_movshdup<A, B>(&mut self, op0: A, op1: B)
602    where
603        Assembler<'a>: SseMovshdupEmitter<A, B>,
604    {
605        <Self as SseMovshdupEmitter<A, B>>::sse_movshdup(self, op0, op1);
606    }
607    /// `SSE_MOVSLDUP`.
608    ///
609    /// Supported operand variants:
610    ///
611    /// ```text
612    /// +---+----------+
613    /// | # | Operands |
614    /// +---+----------+
615    /// | 1 | Xmm, Mem |
616    /// | 2 | Xmm, Xmm |
617    /// +---+----------+
618    /// ```
619    #[inline]
620    pub fn sse_movsldup<A, B>(&mut self, op0: A, op1: B)
621    where
622        Assembler<'a>: SseMovsldupEmitter<A, B>,
623    {
624        <Self as SseMovsldupEmitter<A, B>>::sse_movsldup(self, op0, op1);
625    }
626}