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}