Skip to main content

asmkit/x86/features/
BMI1.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/// `ANDN`.
11///
12/// Supported operand variants:
13///
14/// ```text
15/// +---+---------------+
16/// | # | Operands      |
17/// +---+---------------+
18/// | 1 | Gpd, Gpd, Gpd |
19/// | 2 | Gpd, Gpd, Mem |
20/// | 3 | Gpq, Gpq, Gpq |
21/// | 4 | Gpq, Gpq, Mem |
22/// +---+---------------+
23/// ```
24pub trait AndnEmitter<A, B, C> {
25    fn andn(&mut self, op0: A, op1: B, op2: C);
26}
27
28impl<'a> AndnEmitter<Gpd, Gpd, Gpd> for Assembler<'a> {
29    fn andn(&mut self, op0: Gpd, op1: Gpd, op2: Gpd) {
30        self.emit(
31            ANDN32RRR,
32            op0.as_operand(),
33            op1.as_operand(),
34            op2.as_operand(),
35            &NOREG,
36        );
37    }
38}
39
40impl<'a> AndnEmitter<Gpd, Gpd, Mem> for Assembler<'a> {
41    fn andn(&mut self, op0: Gpd, op1: Gpd, op2: Mem) {
42        self.emit(
43            ANDN32RRM,
44            op0.as_operand(),
45            op1.as_operand(),
46            op2.as_operand(),
47            &NOREG,
48        );
49    }
50}
51
52impl<'a> AndnEmitter<Gpq, Gpq, Gpq> for Assembler<'a> {
53    fn andn(&mut self, op0: Gpq, op1: Gpq, op2: Gpq) {
54        self.emit(
55            ANDN64RRR,
56            op0.as_operand(),
57            op1.as_operand(),
58            op2.as_operand(),
59            &NOREG,
60        );
61    }
62}
63
64impl<'a> AndnEmitter<Gpq, Gpq, Mem> for Assembler<'a> {
65    fn andn(&mut self, op0: Gpq, op1: Gpq, op2: Mem) {
66        self.emit(
67            ANDN64RRM,
68            op0.as_operand(),
69            op1.as_operand(),
70            op2.as_operand(),
71            &NOREG,
72        );
73    }
74}
75
76/// `BEXTR`.
77///
78/// Supported operand variants:
79///
80/// ```text
81/// +---+---------------+
82/// | # | Operands      |
83/// +---+---------------+
84/// | 1 | Gpd, Gpd, Gpd |
85/// | 2 | Gpd, Mem, Gpd |
86/// | 3 | Gpq, Gpq, Gpq |
87/// | 4 | Gpq, Mem, Gpq |
88/// +---+---------------+
89/// ```
90pub trait BextrEmitter<A, B, C> {
91    fn bextr(&mut self, op0: A, op1: B, op2: C);
92}
93
94impl<'a> BextrEmitter<Gpd, Gpd, Gpd> for Assembler<'a> {
95    fn bextr(&mut self, op0: Gpd, op1: Gpd, op2: Gpd) {
96        self.emit(
97            BEXTR32RRR,
98            op0.as_operand(),
99            op1.as_operand(),
100            op2.as_operand(),
101            &NOREG,
102        );
103    }
104}
105
106impl<'a> BextrEmitter<Gpd, Mem, Gpd> for Assembler<'a> {
107    fn bextr(&mut self, op0: Gpd, op1: Mem, op2: Gpd) {
108        self.emit(
109            BEXTR32RMR,
110            op0.as_operand(),
111            op1.as_operand(),
112            op2.as_operand(),
113            &NOREG,
114        );
115    }
116}
117
118impl<'a> BextrEmitter<Gpq, Gpq, Gpq> for Assembler<'a> {
119    fn bextr(&mut self, op0: Gpq, op1: Gpq, op2: Gpq) {
120        self.emit(
121            BEXTR64RRR,
122            op0.as_operand(),
123            op1.as_operand(),
124            op2.as_operand(),
125            &NOREG,
126        );
127    }
128}
129
130impl<'a> BextrEmitter<Gpq, Mem, Gpq> for Assembler<'a> {
131    fn bextr(&mut self, op0: Gpq, op1: Mem, op2: Gpq) {
132        self.emit(
133            BEXTR64RMR,
134            op0.as_operand(),
135            op1.as_operand(),
136            op2.as_operand(),
137            &NOREG,
138        );
139    }
140}
141
142/// `BLSI`.
143///
144/// Supported operand variants:
145///
146/// ```text
147/// +---+----------+
148/// | # | Operands |
149/// +---+----------+
150/// | 1 | Gpd, Gpd |
151/// | 2 | Gpd, Mem |
152/// | 3 | Gpq, Gpq |
153/// | 4 | Gpq, Mem |
154/// +---+----------+
155/// ```
156pub trait BlsiEmitter<A, B> {
157    fn blsi(&mut self, op0: A, op1: B);
158}
159
160impl<'a> BlsiEmitter<Gpd, Gpd> for Assembler<'a> {
161    fn blsi(&mut self, op0: Gpd, op1: Gpd) {
162        self.emit(BLSI32RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
163    }
164}
165
166impl<'a> BlsiEmitter<Gpd, Mem> for Assembler<'a> {
167    fn blsi(&mut self, op0: Gpd, op1: Mem) {
168        self.emit(BLSI32RM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
169    }
170}
171
172impl<'a> BlsiEmitter<Gpq, Gpq> for Assembler<'a> {
173    fn blsi(&mut self, op0: Gpq, op1: Gpq) {
174        self.emit(BLSI64RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
175    }
176}
177
178impl<'a> BlsiEmitter<Gpq, Mem> for Assembler<'a> {
179    fn blsi(&mut self, op0: Gpq, op1: Mem) {
180        self.emit(BLSI64RM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
181    }
182}
183
184/// `BLSMSK`.
185///
186/// Supported operand variants:
187///
188/// ```text
189/// +---+----------+
190/// | # | Operands |
191/// +---+----------+
192/// | 1 | Gpd, Gpd |
193/// | 2 | Gpd, Mem |
194/// | 3 | Gpq, Gpq |
195/// | 4 | Gpq, Mem |
196/// +---+----------+
197/// ```
198pub trait BlsmskEmitter<A, B> {
199    fn blsmsk(&mut self, op0: A, op1: B);
200}
201
202impl<'a> BlsmskEmitter<Gpd, Gpd> for Assembler<'a> {
203    fn blsmsk(&mut self, op0: Gpd, op1: Gpd) {
204        self.emit(
205            BLSMSK32RR,
206            op0.as_operand(),
207            op1.as_operand(),
208            &NOREG,
209            &NOREG,
210        );
211    }
212}
213
214impl<'a> BlsmskEmitter<Gpd, Mem> for Assembler<'a> {
215    fn blsmsk(&mut self, op0: Gpd, op1: Mem) {
216        self.emit(
217            BLSMSK32RM,
218            op0.as_operand(),
219            op1.as_operand(),
220            &NOREG,
221            &NOREG,
222        );
223    }
224}
225
226impl<'a> BlsmskEmitter<Gpq, Gpq> for Assembler<'a> {
227    fn blsmsk(&mut self, op0: Gpq, op1: Gpq) {
228        self.emit(
229            BLSMSK64RR,
230            op0.as_operand(),
231            op1.as_operand(),
232            &NOREG,
233            &NOREG,
234        );
235    }
236}
237
238impl<'a> BlsmskEmitter<Gpq, Mem> for Assembler<'a> {
239    fn blsmsk(&mut self, op0: Gpq, op1: Mem) {
240        self.emit(
241            BLSMSK64RM,
242            op0.as_operand(),
243            op1.as_operand(),
244            &NOREG,
245            &NOREG,
246        );
247    }
248}
249
250/// `BLSR`.
251///
252/// Supported operand variants:
253///
254/// ```text
255/// +---+----------+
256/// | # | Operands |
257/// +---+----------+
258/// | 1 | Gpd, Gpd |
259/// | 2 | Gpd, Mem |
260/// | 3 | Gpq, Gpq |
261/// | 4 | Gpq, Mem |
262/// +---+----------+
263/// ```
264pub trait BlsrEmitter<A, B> {
265    fn blsr(&mut self, op0: A, op1: B);
266}
267
268impl<'a> BlsrEmitter<Gpd, Gpd> for Assembler<'a> {
269    fn blsr(&mut self, op0: Gpd, op1: Gpd) {
270        self.emit(BLSR32RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
271    }
272}
273
274impl<'a> BlsrEmitter<Gpd, Mem> for Assembler<'a> {
275    fn blsr(&mut self, op0: Gpd, op1: Mem) {
276        self.emit(BLSR32RM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
277    }
278}
279
280impl<'a> BlsrEmitter<Gpq, Gpq> for Assembler<'a> {
281    fn blsr(&mut self, op0: Gpq, op1: Gpq) {
282        self.emit(BLSR64RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
283    }
284}
285
286impl<'a> BlsrEmitter<Gpq, Mem> for Assembler<'a> {
287    fn blsr(&mut self, op0: Gpq, op1: Mem) {
288        self.emit(BLSR64RM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
289    }
290}
291
292/// `TZCNT`.
293///
294/// Supported operand variants:
295///
296/// ```text
297/// +---+----------+
298/// | # | Operands |
299/// +---+----------+
300/// | 1 | Gpd, Gpd |
301/// | 2 | Gpd, Mem |
302/// | 3 | Gpq, Gpq |
303/// | 4 | Gpq, Mem |
304/// | 5 | Gpw, Gpw |
305/// | 6 | Gpw, Mem |
306/// +---+----------+
307/// ```
308pub trait TzcntEmitter<A, B> {
309    fn tzcnt(&mut self, op0: A, op1: B);
310}
311
312impl<'a> TzcntEmitter<Gpw, Gpw> for Assembler<'a> {
313    fn tzcnt(&mut self, op0: Gpw, op1: Gpw) {
314        self.emit(
315            TZCNT16RR,
316            op0.as_operand(),
317            op1.as_operand(),
318            &NOREG,
319            &NOREG,
320        );
321    }
322}
323
324impl<'a> TzcntEmitter<Gpw, Mem> for Assembler<'a> {
325    fn tzcnt(&mut self, op0: Gpw, op1: Mem) {
326        self.emit(
327            TZCNT16RM,
328            op0.as_operand(),
329            op1.as_operand(),
330            &NOREG,
331            &NOREG,
332        );
333    }
334}
335
336impl<'a> TzcntEmitter<Gpd, Gpd> for Assembler<'a> {
337    fn tzcnt(&mut self, op0: Gpd, op1: Gpd) {
338        self.emit(
339            TZCNT32RR,
340            op0.as_operand(),
341            op1.as_operand(),
342            &NOREG,
343            &NOREG,
344        );
345    }
346}
347
348impl<'a> TzcntEmitter<Gpd, Mem> for Assembler<'a> {
349    fn tzcnt(&mut self, op0: Gpd, op1: Mem) {
350        self.emit(
351            TZCNT32RM,
352            op0.as_operand(),
353            op1.as_operand(),
354            &NOREG,
355            &NOREG,
356        );
357    }
358}
359
360impl<'a> TzcntEmitter<Gpq, Gpq> for Assembler<'a> {
361    fn tzcnt(&mut self, op0: Gpq, op1: Gpq) {
362        self.emit(
363            TZCNT64RR,
364            op0.as_operand(),
365            op1.as_operand(),
366            &NOREG,
367            &NOREG,
368        );
369    }
370}
371
372impl<'a> TzcntEmitter<Gpq, Mem> for Assembler<'a> {
373    fn tzcnt(&mut self, op0: Gpq, op1: Mem) {
374        self.emit(
375            TZCNT64RM,
376            op0.as_operand(),
377            op1.as_operand(),
378            &NOREG,
379            &NOREG,
380        );
381    }
382}
383
384impl<'a> Assembler<'a> {
385    /// `ANDN`.
386    ///
387    /// Supported operand variants:
388    ///
389    /// ```text
390    /// +---+---------------+
391    /// | # | Operands      |
392    /// +---+---------------+
393    /// | 1 | Gpd, Gpd, Gpd |
394    /// | 2 | Gpd, Gpd, Mem |
395    /// | 3 | Gpq, Gpq, Gpq |
396    /// | 4 | Gpq, Gpq, Mem |
397    /// +---+---------------+
398    /// ```
399    #[inline]
400    pub fn andn<A, B, C>(&mut self, op0: A, op1: B, op2: C)
401    where
402        Assembler<'a>: AndnEmitter<A, B, C>,
403    {
404        <Self as AndnEmitter<A, B, C>>::andn(self, op0, op1, op2);
405    }
406    /// `BEXTR`.
407    ///
408    /// Supported operand variants:
409    ///
410    /// ```text
411    /// +---+---------------+
412    /// | # | Operands      |
413    /// +---+---------------+
414    /// | 1 | Gpd, Gpd, Gpd |
415    /// | 2 | Gpd, Mem, Gpd |
416    /// | 3 | Gpq, Gpq, Gpq |
417    /// | 4 | Gpq, Mem, Gpq |
418    /// +---+---------------+
419    /// ```
420    #[inline]
421    pub fn bextr<A, B, C>(&mut self, op0: A, op1: B, op2: C)
422    where
423        Assembler<'a>: BextrEmitter<A, B, C>,
424    {
425        <Self as BextrEmitter<A, B, C>>::bextr(self, op0, op1, op2);
426    }
427    /// `BLSI`.
428    ///
429    /// Supported operand variants:
430    ///
431    /// ```text
432    /// +---+----------+
433    /// | # | Operands |
434    /// +---+----------+
435    /// | 1 | Gpd, Gpd |
436    /// | 2 | Gpd, Mem |
437    /// | 3 | Gpq, Gpq |
438    /// | 4 | Gpq, Mem |
439    /// +---+----------+
440    /// ```
441    #[inline]
442    pub fn blsi<A, B>(&mut self, op0: A, op1: B)
443    where
444        Assembler<'a>: BlsiEmitter<A, B>,
445    {
446        <Self as BlsiEmitter<A, B>>::blsi(self, op0, op1);
447    }
448    /// `BLSMSK`.
449    ///
450    /// Supported operand variants:
451    ///
452    /// ```text
453    /// +---+----------+
454    /// | # | Operands |
455    /// +---+----------+
456    /// | 1 | Gpd, Gpd |
457    /// | 2 | Gpd, Mem |
458    /// | 3 | Gpq, Gpq |
459    /// | 4 | Gpq, Mem |
460    /// +---+----------+
461    /// ```
462    #[inline]
463    pub fn blsmsk<A, B>(&mut self, op0: A, op1: B)
464    where
465        Assembler<'a>: BlsmskEmitter<A, B>,
466    {
467        <Self as BlsmskEmitter<A, B>>::blsmsk(self, op0, op1);
468    }
469    /// `BLSR`.
470    ///
471    /// Supported operand variants:
472    ///
473    /// ```text
474    /// +---+----------+
475    /// | # | Operands |
476    /// +---+----------+
477    /// | 1 | Gpd, Gpd |
478    /// | 2 | Gpd, Mem |
479    /// | 3 | Gpq, Gpq |
480    /// | 4 | Gpq, Mem |
481    /// +---+----------+
482    /// ```
483    #[inline]
484    pub fn blsr<A, B>(&mut self, op0: A, op1: B)
485    where
486        Assembler<'a>: BlsrEmitter<A, B>,
487    {
488        <Self as BlsrEmitter<A, B>>::blsr(self, op0, op1);
489    }
490    /// `TZCNT`.
491    ///
492    /// Supported operand variants:
493    ///
494    /// ```text
495    /// +---+----------+
496    /// | # | Operands |
497    /// +---+----------+
498    /// | 1 | Gpd, Gpd |
499    /// | 2 | Gpd, Mem |
500    /// | 3 | Gpq, Gpq |
501    /// | 4 | Gpq, Mem |
502    /// | 5 | Gpw, Gpw |
503    /// | 6 | Gpw, Mem |
504    /// +---+----------+
505    /// ```
506    #[inline]
507    pub fn tzcnt<A, B>(&mut self, op0: A, op1: B)
508    where
509        Assembler<'a>: TzcntEmitter<A, B>,
510    {
511        <Self as TzcntEmitter<A, B>>::tzcnt(self, op0, op1);
512    }
513}