Skip to main content

asmkit/x86/features/
SSE42.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/// `CRC32` (CRC32). 
11/// Starting with an initial value in the first operand (destination operand), accumulates a CRC32 (polynomial 11EDC6F41H) value for the second operand (source operand) and stores the result in the destination operand. The source operand can be a register or a memory location. The destination operand must be an r32 or r64 register. If the destination is an r64 register, then the 32-bit result is stored in the least significant double word and 00000000H is stored in the most significant double word of the r64 register.
12///
13///
14/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/CRC32.html).
15///
16/// Supported operand variants:
17///
18/// ```text
19/// +---+------------+
20/// | # | Operands   |
21/// +---+------------+
22/// | 1 | Gpd, GpbLo |
23/// | 2 | Gpd, Gpd   |
24/// | 3 | Gpd, Gpq   |
25/// | 4 | Gpd, Gpw   |
26/// | 5 | Gpd, Mem   |
27/// +---+------------+
28/// ```
29pub trait Crc32Emitter<A, B> {
30    fn crc32(&mut self, op0: A, op1: B);
31}
32
33impl<'a> Crc32Emitter<Gpd, GpbLo> for Assembler<'a> {
34    fn crc32(&mut self, op0: Gpd, op1: GpbLo) {
35        self.emit(CRC32_8RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
36    }
37}
38
39impl<'a> Crc32Emitter<Gpd, Mem> for Assembler<'a> {
40    fn crc32(&mut self, op0: Gpd, op1: Mem) {
41        self.emit(CRC32_8RM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
42    }
43}
44
45impl<'a> Crc32Emitter<Gpd, Gpw> for Assembler<'a> {
46    fn crc32(&mut self, op0: Gpd, op1: Gpw) {
47        self.emit(CRC32_16RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
48    }
49}
50
51impl<'a> Crc32Emitter<Gpd, Gpd> for Assembler<'a> {
52    fn crc32(&mut self, op0: Gpd, op1: Gpd) {
53        self.emit(CRC32_32RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
54    }
55}
56
57impl<'a> Crc32Emitter<Gpd, Gpq> for Assembler<'a> {
58    fn crc32(&mut self, op0: Gpd, op1: Gpq) {
59        self.emit(CRC32_64RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
60    }
61}
62
63/// `SSE_PCMPESTRI`.
64///
65/// Supported operand variants:
66///
67/// ```text
68/// +---+---------------+
69/// | # | Operands      |
70/// +---+---------------+
71/// | 1 | Xmm, Mem, Imm |
72/// | 2 | Xmm, Xmm, Imm |
73/// +---+---------------+
74/// ```
75pub trait SsePcmpestriEmitter<A, B, C> {
76    fn sse_pcmpestri(&mut self, op0: A, op1: B, op2: C);
77}
78
79impl<'a> SsePcmpestriEmitter<Xmm, Xmm, Imm> for Assembler<'a> {
80    fn sse_pcmpestri(&mut self, op0: Xmm, op1: Xmm, op2: Imm) {
81        self.emit(SSE_PCMPESTRIRRI, op0.as_operand(), op1.as_operand(), op2.as_operand(), &NOREG);
82    }
83}
84
85impl<'a> SsePcmpestriEmitter<Xmm, Mem, Imm> for Assembler<'a> {
86    fn sse_pcmpestri(&mut self, op0: Xmm, op1: Mem, op2: Imm) {
87        self.emit(SSE_PCMPESTRIRMI, op0.as_operand(), op1.as_operand(), op2.as_operand(), &NOREG);
88    }
89}
90
91/// `SSE_PCMPESTRM`.
92///
93/// Supported operand variants:
94///
95/// ```text
96/// +---+---------------+
97/// | # | Operands      |
98/// +---+---------------+
99/// | 1 | Xmm, Mem, Imm |
100/// | 2 | Xmm, Xmm, Imm |
101/// +---+---------------+
102/// ```
103pub trait SsePcmpestrmEmitter<A, B, C> {
104    fn sse_pcmpestrm(&mut self, op0: A, op1: B, op2: C);
105}
106
107impl<'a> SsePcmpestrmEmitter<Xmm, Xmm, Imm> for Assembler<'a> {
108    fn sse_pcmpestrm(&mut self, op0: Xmm, op1: Xmm, op2: Imm) {
109        self.emit(SSE_PCMPESTRMRRI, op0.as_operand(), op1.as_operand(), op2.as_operand(), &NOREG);
110    }
111}
112
113impl<'a> SsePcmpestrmEmitter<Xmm, Mem, Imm> for Assembler<'a> {
114    fn sse_pcmpestrm(&mut self, op0: Xmm, op1: Mem, op2: Imm) {
115        self.emit(SSE_PCMPESTRMRMI, op0.as_operand(), op1.as_operand(), op2.as_operand(), &NOREG);
116    }
117}
118
119/// `SSE_PCMPISTRI`.
120///
121/// Supported operand variants:
122///
123/// ```text
124/// +---+---------------+
125/// | # | Operands      |
126/// +---+---------------+
127/// | 1 | Xmm, Mem, Imm |
128/// | 2 | Xmm, Xmm, Imm |
129/// +---+---------------+
130/// ```
131pub trait SsePcmpistriEmitter<A, B, C> {
132    fn sse_pcmpistri(&mut self, op0: A, op1: B, op2: C);
133}
134
135impl<'a> SsePcmpistriEmitter<Xmm, Xmm, Imm> for Assembler<'a> {
136    fn sse_pcmpistri(&mut self, op0: Xmm, op1: Xmm, op2: Imm) {
137        self.emit(SSE_PCMPISTRIRRI, op0.as_operand(), op1.as_operand(), op2.as_operand(), &NOREG);
138    }
139}
140
141impl<'a> SsePcmpistriEmitter<Xmm, Mem, Imm> for Assembler<'a> {
142    fn sse_pcmpistri(&mut self, op0: Xmm, op1: Mem, op2: Imm) {
143        self.emit(SSE_PCMPISTRIRMI, op0.as_operand(), op1.as_operand(), op2.as_operand(), &NOREG);
144    }
145}
146
147/// `SSE_PCMPISTRM`.
148///
149/// Supported operand variants:
150///
151/// ```text
152/// +---+---------------+
153/// | # | Operands      |
154/// +---+---------------+
155/// | 1 | Xmm, Mem, Imm |
156/// | 2 | Xmm, Xmm, Imm |
157/// +---+---------------+
158/// ```
159pub trait SsePcmpistrmEmitter<A, B, C> {
160    fn sse_pcmpistrm(&mut self, op0: A, op1: B, op2: C);
161}
162
163impl<'a> SsePcmpistrmEmitter<Xmm, Xmm, Imm> for Assembler<'a> {
164    fn sse_pcmpistrm(&mut self, op0: Xmm, op1: Xmm, op2: Imm) {
165        self.emit(SSE_PCMPISTRMRRI, op0.as_operand(), op1.as_operand(), op2.as_operand(), &NOREG);
166    }
167}
168
169impl<'a> SsePcmpistrmEmitter<Xmm, Mem, Imm> for Assembler<'a> {
170    fn sse_pcmpistrm(&mut self, op0: Xmm, op1: Mem, op2: Imm) {
171        self.emit(SSE_PCMPISTRMRMI, op0.as_operand(), op1.as_operand(), op2.as_operand(), &NOREG);
172    }
173}
174
175
176impl<'a> Assembler<'a> {
177    /// `CRC32` (CRC32). 
178    /// Starting with an initial value in the first operand (destination operand), accumulates a CRC32 (polynomial 11EDC6F41H) value for the second operand (source operand) and stores the result in the destination operand. The source operand can be a register or a memory location. The destination operand must be an r32 or r64 register. If the destination is an r64 register, then the 32-bit result is stored in the least significant double word and 00000000H is stored in the most significant double word of the r64 register.
179    ///
180    ///
181    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/CRC32.html).
182    ///
183    /// Supported operand variants:
184    ///
185    /// ```text
186    /// +---+------------+
187    /// | # | Operands   |
188    /// +---+------------+
189    /// | 1 | Gpd, GpbLo |
190    /// | 2 | Gpd, Gpd   |
191    /// | 3 | Gpd, Gpq   |
192    /// | 4 | Gpd, Gpw   |
193    /// | 5 | Gpd, Mem   |
194    /// +---+------------+
195    /// ```
196    #[inline]
197    pub fn crc32<A, B>(&mut self, op0: A, op1: B)
198    where Assembler<'a>: Crc32Emitter<A, B> {
199        <Self as Crc32Emitter<A, B>>::crc32(self, op0, op1);
200    }
201    /// `SSE_PCMPESTRI`.
202    ///
203    /// Supported operand variants:
204    ///
205    /// ```text
206    /// +---+---------------+
207    /// | # | Operands      |
208    /// +---+---------------+
209    /// | 1 | Xmm, Mem, Imm |
210    /// | 2 | Xmm, Xmm, Imm |
211    /// +---+---------------+
212    /// ```
213    #[inline]
214    pub fn sse_pcmpestri<A, B, C>(&mut self, op0: A, op1: B, op2: C)
215    where Assembler<'a>: SsePcmpestriEmitter<A, B, C> {
216        <Self as SsePcmpestriEmitter<A, B, C>>::sse_pcmpestri(self, op0, op1, op2);
217    }
218    /// `SSE_PCMPESTRM`.
219    ///
220    /// Supported operand variants:
221    ///
222    /// ```text
223    /// +---+---------------+
224    /// | # | Operands      |
225    /// +---+---------------+
226    /// | 1 | Xmm, Mem, Imm |
227    /// | 2 | Xmm, Xmm, Imm |
228    /// +---+---------------+
229    /// ```
230    #[inline]
231    pub fn sse_pcmpestrm<A, B, C>(&mut self, op0: A, op1: B, op2: C)
232    where Assembler<'a>: SsePcmpestrmEmitter<A, B, C> {
233        <Self as SsePcmpestrmEmitter<A, B, C>>::sse_pcmpestrm(self, op0, op1, op2);
234    }
235    /// `SSE_PCMPISTRI`.
236    ///
237    /// Supported operand variants:
238    ///
239    /// ```text
240    /// +---+---------------+
241    /// | # | Operands      |
242    /// +---+---------------+
243    /// | 1 | Xmm, Mem, Imm |
244    /// | 2 | Xmm, Xmm, Imm |
245    /// +---+---------------+
246    /// ```
247    #[inline]
248    pub fn sse_pcmpistri<A, B, C>(&mut self, op0: A, op1: B, op2: C)
249    where Assembler<'a>: SsePcmpistriEmitter<A, B, C> {
250        <Self as SsePcmpistriEmitter<A, B, C>>::sse_pcmpistri(self, op0, op1, op2);
251    }
252    /// `SSE_PCMPISTRM`.
253    ///
254    /// Supported operand variants:
255    ///
256    /// ```text
257    /// +---+---------------+
258    /// | # | Operands      |
259    /// +---+---------------+
260    /// | 1 | Xmm, Mem, Imm |
261    /// | 2 | Xmm, Xmm, Imm |
262    /// +---+---------------+
263    /// ```
264    #[inline]
265    pub fn sse_pcmpistrm<A, B, C>(&mut self, op0: A, op1: B, op2: C)
266    where Assembler<'a>: SsePcmpistrmEmitter<A, B, C> {
267        <Self as SsePcmpistrmEmitter<A, B, C>>::sse_pcmpistrm(self, op0, op1, op2);
268    }
269}