1use super::super::opcodes::*;
2use crate::core::emitter::*;
3use crate::core::operand::*;
4use crate::x86::assembler::*;
5use crate::x86::operands::*;
6
7const NOREG: Operand = Operand::new();
9
10pub trait BswapEmitter<A> {
24 fn bswap(&mut self, op0: A);
25}
26
27impl<'a> BswapEmitter<Gpw> for Assembler<'a> {
28 fn bswap(&mut self, op0: Gpw) {
29 self.emit(BSWAP16R, op0.as_operand(), &NOREG, &NOREG, &NOREG);
30 }
31}
32
33impl<'a> BswapEmitter<Gpd> for Assembler<'a> {
34 fn bswap(&mut self, op0: Gpd) {
35 self.emit(BSWAP32R, op0.as_operand(), &NOREG, &NOREG, &NOREG);
36 }
37}
38
39impl<'a> BswapEmitter<Gpq> for Assembler<'a> {
40 fn bswap(&mut self, op0: Gpq) {
41 self.emit(BSWAP64R, op0.as_operand(), &NOREG, &NOREG, &NOREG);
42 }
43}
44
45pub trait CmpxchgEmitter<A, B> {
64 fn cmpxchg(&mut self, op0: A, op1: B);
65}
66
67impl<'a> CmpxchgEmitter<GpbLo, GpbLo> for Assembler<'a> {
68 fn cmpxchg(&mut self, op0: GpbLo, op1: GpbLo) {
69 self.emit(
70 CMPXCHG8RR,
71 op0.as_operand(),
72 op1.as_operand(),
73 &NOREG,
74 &NOREG,
75 );
76 }
77}
78
79impl<'a> CmpxchgEmitter<Mem, GpbLo> for Assembler<'a> {
80 fn cmpxchg(&mut self, op0: Mem, op1: GpbLo) {
81 self.emit(
82 CMPXCHG8MR,
83 op0.as_operand(),
84 op1.as_operand(),
85 &NOREG,
86 &NOREG,
87 );
88 }
89}
90
91impl<'a> CmpxchgEmitter<Gpw, Gpw> for Assembler<'a> {
92 fn cmpxchg(&mut self, op0: Gpw, op1: Gpw) {
93 self.emit(
94 CMPXCHG16RR,
95 op0.as_operand(),
96 op1.as_operand(),
97 &NOREG,
98 &NOREG,
99 );
100 }
101}
102
103impl<'a> CmpxchgEmitter<Mem, Gpw> for Assembler<'a> {
104 fn cmpxchg(&mut self, op0: Mem, op1: Gpw) {
105 self.emit(
106 CMPXCHG16MR,
107 op0.as_operand(),
108 op1.as_operand(),
109 &NOREG,
110 &NOREG,
111 );
112 }
113}
114
115impl<'a> CmpxchgEmitter<Gpd, Gpd> for Assembler<'a> {
116 fn cmpxchg(&mut self, op0: Gpd, op1: Gpd) {
117 self.emit(
118 CMPXCHG32RR,
119 op0.as_operand(),
120 op1.as_operand(),
121 &NOREG,
122 &NOREG,
123 );
124 }
125}
126
127impl<'a> CmpxchgEmitter<Mem, Gpd> for Assembler<'a> {
128 fn cmpxchg(&mut self, op0: Mem, op1: Gpd) {
129 self.emit(
130 CMPXCHG32MR,
131 op0.as_operand(),
132 op1.as_operand(),
133 &NOREG,
134 &NOREG,
135 );
136 }
137}
138
139impl<'a> CmpxchgEmitter<Gpq, Gpq> for Assembler<'a> {
140 fn cmpxchg(&mut self, op0: Gpq, op1: Gpq) {
141 self.emit(
142 CMPXCHG64RR,
143 op0.as_operand(),
144 op1.as_operand(),
145 &NOREG,
146 &NOREG,
147 );
148 }
149}
150
151impl<'a> CmpxchgEmitter<Mem, Gpq> for Assembler<'a> {
152 fn cmpxchg(&mut self, op0: Mem, op1: Gpq) {
153 self.emit(
154 CMPXCHG64MR,
155 op0.as_operand(),
156 op1.as_operand(),
157 &NOREG,
158 &NOREG,
159 );
160 }
161}
162
163pub trait InvdEmitter {
175 fn invd(&mut self);
176}
177
178impl<'a> InvdEmitter for Assembler<'a> {
179 fn invd(&mut self) {
180 self.emit(INVD, &NOREG, &NOREG, &NOREG, &NOREG);
181 }
182}
183
184pub trait InvlpgEmitter<A> {
196 fn invlpg(&mut self, op0: A);
197}
198
199impl<'a> InvlpgEmitter<Mem> for Assembler<'a> {
200 fn invlpg(&mut self, op0: Mem) {
201 self.emit(INVLPG8M, op0.as_operand(), &NOREG, &NOREG, &NOREG);
202 }
203}
204
205pub trait WbinvdEmitter {
217 fn wbinvd(&mut self);
218}
219
220impl<'a> WbinvdEmitter for Assembler<'a> {
221 fn wbinvd(&mut self) {
222 self.emit(WBINVD, &NOREG, &NOREG, &NOREG, &NOREG);
223 }
224}
225
226pub trait XaddEmitter<A, B> {
245 fn xadd(&mut self, op0: A, op1: B);
246}
247
248impl<'a> XaddEmitter<GpbLo, GpbLo> for Assembler<'a> {
249 fn xadd(&mut self, op0: GpbLo, op1: GpbLo) {
250 self.emit(XADD8RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
251 }
252}
253
254impl<'a> XaddEmitter<Mem, GpbLo> for Assembler<'a> {
255 fn xadd(&mut self, op0: Mem, op1: GpbLo) {
256 self.emit(XADD8MR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
257 }
258}
259
260impl<'a> XaddEmitter<Gpw, Gpw> for Assembler<'a> {
261 fn xadd(&mut self, op0: Gpw, op1: Gpw) {
262 self.emit(XADD16RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
263 }
264}
265
266impl<'a> XaddEmitter<Mem, Gpw> for Assembler<'a> {
267 fn xadd(&mut self, op0: Mem, op1: Gpw) {
268 self.emit(XADD16MR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
269 }
270}
271
272impl<'a> XaddEmitter<Gpd, Gpd> for Assembler<'a> {
273 fn xadd(&mut self, op0: Gpd, op1: Gpd) {
274 self.emit(XADD32RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
275 }
276}
277
278impl<'a> XaddEmitter<Mem, Gpd> for Assembler<'a> {
279 fn xadd(&mut self, op0: Mem, op1: Gpd) {
280 self.emit(XADD32MR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
281 }
282}
283
284impl<'a> XaddEmitter<Gpq, Gpq> for Assembler<'a> {
285 fn xadd(&mut self, op0: Gpq, op1: Gpq) {
286 self.emit(XADD64RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
287 }
288}
289
290impl<'a> XaddEmitter<Mem, Gpq> for Assembler<'a> {
291 fn xadd(&mut self, op0: Mem, op1: Gpq) {
292 self.emit(XADD64MR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
293 }
294}
295
296impl<'a> Assembler<'a> {
297 #[inline]
311 pub fn bswap<A>(&mut self, op0: A)
312 where
313 Assembler<'a>: BswapEmitter<A>,
314 {
315 <Self as BswapEmitter<A>>::bswap(self, op0);
316 }
317 #[inline]
336 pub fn cmpxchg<A, B>(&mut self, op0: A, op1: B)
337 where
338 Assembler<'a>: CmpxchgEmitter<A, B>,
339 {
340 <Self as CmpxchgEmitter<A, B>>::cmpxchg(self, op0, op1);
341 }
342 #[inline]
354 pub fn invd(&mut self)
355 where
356 Assembler<'a>: InvdEmitter,
357 {
358 <Self as InvdEmitter>::invd(self);
359 }
360 #[inline]
372 pub fn invlpg<A>(&mut self, op0: A)
373 where
374 Assembler<'a>: InvlpgEmitter<A>,
375 {
376 <Self as InvlpgEmitter<A>>::invlpg(self, op0);
377 }
378 #[inline]
390 pub fn wbinvd(&mut self)
391 where
392 Assembler<'a>: WbinvdEmitter,
393 {
394 <Self as WbinvdEmitter>::wbinvd(self);
395 }
396 #[inline]
415 pub fn xadd<A, B>(&mut self, op0: A, op1: B)
416 where
417 Assembler<'a>: XaddEmitter<A, B>,
418 {
419 <Self as XaddEmitter<A, B>>::xadd(self, op0, op1);
420 }
421}