Skip to main content

asmkit/x86/features/
SSE42.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/// `CRC32`.
11///
12/// Supported operand variants:
13///
14/// ```text
15/// +---+------------+
16/// | # | Operands   |
17/// +---+------------+
18/// | 1 | Gpd, GpbLo |
19/// | 2 | Gpd, Gpd   |
20/// | 3 | Gpd, Gpq   |
21/// | 4 | Gpd, Gpw   |
22/// | 5 | Gpd, Mem   |
23/// +---+------------+
24/// ```
25pub trait Crc32Emitter<A, B> {
26    fn crc32(&mut self, op0: A, op1: B);
27}
28
29impl<'a> Crc32Emitter<Gpd, GpbLo> for Assembler<'a> {
30    fn crc32(&mut self, op0: Gpd, op1: GpbLo) {
31        self.emit(
32            CRC32_8RR,
33            op0.as_operand(),
34            op1.as_operand(),
35            &NOREG,
36            &NOREG,
37        );
38    }
39}
40
41impl<'a> Crc32Emitter<Gpd, Mem> for Assembler<'a> {
42    fn crc32(&mut self, op0: Gpd, op1: Mem) {
43        self.emit(
44            CRC32_8RM,
45            op0.as_operand(),
46            op1.as_operand(),
47            &NOREG,
48            &NOREG,
49        );
50    }
51}
52
53impl<'a> Crc32Emitter<Gpd, Gpw> for Assembler<'a> {
54    fn crc32(&mut self, op0: Gpd, op1: Gpw) {
55        self.emit(
56            CRC32_16RR,
57            op0.as_operand(),
58            op1.as_operand(),
59            &NOREG,
60            &NOREG,
61        );
62    }
63}
64
65impl<'a> Crc32Emitter<Gpd, Gpd> for Assembler<'a> {
66    fn crc32(&mut self, op0: Gpd, op1: Gpd) {
67        self.emit(
68            CRC32_32RR,
69            op0.as_operand(),
70            op1.as_operand(),
71            &NOREG,
72            &NOREG,
73        );
74    }
75}
76
77impl<'a> Crc32Emitter<Gpd, Gpq> for Assembler<'a> {
78    fn crc32(&mut self, op0: Gpd, op1: Gpq) {
79        self.emit(
80            CRC32_64RR,
81            op0.as_operand(),
82            op1.as_operand(),
83            &NOREG,
84            &NOREG,
85        );
86    }
87}
88
89/// `SSE_PCMPESTRI`.
90///
91/// Supported operand variants:
92///
93/// ```text
94/// +---+---------------+
95/// | # | Operands      |
96/// +---+---------------+
97/// | 1 | Xmm, Mem, Imm |
98/// | 2 | Xmm, Xmm, Imm |
99/// +---+---------------+
100/// ```
101pub trait SsePcmpestriEmitter<A, B, C> {
102    fn sse_pcmpestri(&mut self, op0: A, op1: B, op2: C);
103}
104
105impl<'a> SsePcmpestriEmitter<Xmm, Xmm, Imm> for Assembler<'a> {
106    fn sse_pcmpestri(&mut self, op0: Xmm, op1: Xmm, op2: Imm) {
107        self.emit(
108            SSE_PCMPESTRIRRI,
109            op0.as_operand(),
110            op1.as_operand(),
111            op2.as_operand(),
112            &NOREG,
113        );
114    }
115}
116
117impl<'a> SsePcmpestriEmitter<Xmm, Mem, Imm> for Assembler<'a> {
118    fn sse_pcmpestri(&mut self, op0: Xmm, op1: Mem, op2: Imm) {
119        self.emit(
120            SSE_PCMPESTRIRMI,
121            op0.as_operand(),
122            op1.as_operand(),
123            op2.as_operand(),
124            &NOREG,
125        );
126    }
127}
128
129/// `SSE_PCMPESTRM`.
130///
131/// Supported operand variants:
132///
133/// ```text
134/// +---+---------------+
135/// | # | Operands      |
136/// +---+---------------+
137/// | 1 | Xmm, Mem, Imm |
138/// | 2 | Xmm, Xmm, Imm |
139/// +---+---------------+
140/// ```
141pub trait SsePcmpestrmEmitter<A, B, C> {
142    fn sse_pcmpestrm(&mut self, op0: A, op1: B, op2: C);
143}
144
145impl<'a> SsePcmpestrmEmitter<Xmm, Xmm, Imm> for Assembler<'a> {
146    fn sse_pcmpestrm(&mut self, op0: Xmm, op1: Xmm, op2: Imm) {
147        self.emit(
148            SSE_PCMPESTRMRRI,
149            op0.as_operand(),
150            op1.as_operand(),
151            op2.as_operand(),
152            &NOREG,
153        );
154    }
155}
156
157impl<'a> SsePcmpestrmEmitter<Xmm, Mem, Imm> for Assembler<'a> {
158    fn sse_pcmpestrm(&mut self, op0: Xmm, op1: Mem, op2: Imm) {
159        self.emit(
160            SSE_PCMPESTRMRMI,
161            op0.as_operand(),
162            op1.as_operand(),
163            op2.as_operand(),
164            &NOREG,
165        );
166    }
167}
168
169/// `SSE_PCMPISTRI`.
170///
171/// Supported operand variants:
172///
173/// ```text
174/// +---+---------------+
175/// | # | Operands      |
176/// +---+---------------+
177/// | 1 | Xmm, Mem, Imm |
178/// | 2 | Xmm, Xmm, Imm |
179/// +---+---------------+
180/// ```
181pub trait SsePcmpistriEmitter<A, B, C> {
182    fn sse_pcmpistri(&mut self, op0: A, op1: B, op2: C);
183}
184
185impl<'a> SsePcmpistriEmitter<Xmm, Xmm, Imm> for Assembler<'a> {
186    fn sse_pcmpistri(&mut self, op0: Xmm, op1: Xmm, op2: Imm) {
187        self.emit(
188            SSE_PCMPISTRIRRI,
189            op0.as_operand(),
190            op1.as_operand(),
191            op2.as_operand(),
192            &NOREG,
193        );
194    }
195}
196
197impl<'a> SsePcmpistriEmitter<Xmm, Mem, Imm> for Assembler<'a> {
198    fn sse_pcmpistri(&mut self, op0: Xmm, op1: Mem, op2: Imm) {
199        self.emit(
200            SSE_PCMPISTRIRMI,
201            op0.as_operand(),
202            op1.as_operand(),
203            op2.as_operand(),
204            &NOREG,
205        );
206    }
207}
208
209/// `SSE_PCMPISTRM`.
210///
211/// Supported operand variants:
212///
213/// ```text
214/// +---+---------------+
215/// | # | Operands      |
216/// +---+---------------+
217/// | 1 | Xmm, Mem, Imm |
218/// | 2 | Xmm, Xmm, Imm |
219/// +---+---------------+
220/// ```
221pub trait SsePcmpistrmEmitter<A, B, C> {
222    fn sse_pcmpistrm(&mut self, op0: A, op1: B, op2: C);
223}
224
225impl<'a> SsePcmpistrmEmitter<Xmm, Xmm, Imm> for Assembler<'a> {
226    fn sse_pcmpistrm(&mut self, op0: Xmm, op1: Xmm, op2: Imm) {
227        self.emit(
228            SSE_PCMPISTRMRRI,
229            op0.as_operand(),
230            op1.as_operand(),
231            op2.as_operand(),
232            &NOREG,
233        );
234    }
235}
236
237impl<'a> SsePcmpistrmEmitter<Xmm, Mem, Imm> for Assembler<'a> {
238    fn sse_pcmpistrm(&mut self, op0: Xmm, op1: Mem, op2: Imm) {
239        self.emit(
240            SSE_PCMPISTRMRMI,
241            op0.as_operand(),
242            op1.as_operand(),
243            op2.as_operand(),
244            &NOREG,
245        );
246    }
247}
248
249impl<'a> Assembler<'a> {
250    /// `CRC32`.
251    ///
252    /// Supported operand variants:
253    ///
254    /// ```text
255    /// +---+------------+
256    /// | # | Operands   |
257    /// +---+------------+
258    /// | 1 | Gpd, GpbLo |
259    /// | 2 | Gpd, Gpd   |
260    /// | 3 | Gpd, Gpq   |
261    /// | 4 | Gpd, Gpw   |
262    /// | 5 | Gpd, Mem   |
263    /// +---+------------+
264    /// ```
265    #[inline]
266    pub fn crc32<A, B>(&mut self, op0: A, op1: B)
267    where
268        Assembler<'a>: Crc32Emitter<A, B>,
269    {
270        <Self as Crc32Emitter<A, B>>::crc32(self, op0, op1);
271    }
272    /// `SSE_PCMPESTRI`.
273    ///
274    /// Supported operand variants:
275    ///
276    /// ```text
277    /// +---+---------------+
278    /// | # | Operands      |
279    /// +---+---------------+
280    /// | 1 | Xmm, Mem, Imm |
281    /// | 2 | Xmm, Xmm, Imm |
282    /// +---+---------------+
283    /// ```
284    #[inline]
285    pub fn sse_pcmpestri<A, B, C>(&mut self, op0: A, op1: B, op2: C)
286    where
287        Assembler<'a>: SsePcmpestriEmitter<A, B, C>,
288    {
289        <Self as SsePcmpestriEmitter<A, B, C>>::sse_pcmpestri(self, op0, op1, op2);
290    }
291    /// `SSE_PCMPESTRM`.
292    ///
293    /// Supported operand variants:
294    ///
295    /// ```text
296    /// +---+---------------+
297    /// | # | Operands      |
298    /// +---+---------------+
299    /// | 1 | Xmm, Mem, Imm |
300    /// | 2 | Xmm, Xmm, Imm |
301    /// +---+---------------+
302    /// ```
303    #[inline]
304    pub fn sse_pcmpestrm<A, B, C>(&mut self, op0: A, op1: B, op2: C)
305    where
306        Assembler<'a>: SsePcmpestrmEmitter<A, B, C>,
307    {
308        <Self as SsePcmpestrmEmitter<A, B, C>>::sse_pcmpestrm(self, op0, op1, op2);
309    }
310    /// `SSE_PCMPISTRI`.
311    ///
312    /// Supported operand variants:
313    ///
314    /// ```text
315    /// +---+---------------+
316    /// | # | Operands      |
317    /// +---+---------------+
318    /// | 1 | Xmm, Mem, Imm |
319    /// | 2 | Xmm, Xmm, Imm |
320    /// +---+---------------+
321    /// ```
322    #[inline]
323    pub fn sse_pcmpistri<A, B, C>(&mut self, op0: A, op1: B, op2: C)
324    where
325        Assembler<'a>: SsePcmpistriEmitter<A, B, C>,
326    {
327        <Self as SsePcmpistriEmitter<A, B, C>>::sse_pcmpistri(self, op0, op1, op2);
328    }
329    /// `SSE_PCMPISTRM`.
330    ///
331    /// Supported operand variants:
332    ///
333    /// ```text
334    /// +---+---------------+
335    /// | # | Operands      |
336    /// +---+---------------+
337    /// | 1 | Xmm, Mem, Imm |
338    /// | 2 | Xmm, Xmm, Imm |
339    /// +---+---------------+
340    /// ```
341    #[inline]
342    pub fn sse_pcmpistrm<A, B, C>(&mut self, op0: A, op1: B, op2: C)
343    where
344        Assembler<'a>: SsePcmpistrmEmitter<A, B, C>,
345    {
346        <Self as SsePcmpistrmEmitter<A, B, C>>::sse_pcmpistrm(self, op0, op1, op2);
347    }
348}