completely wrong. Chebychev (Remez), Padé, and maybe Taylor.
[fmap.git] / x86_64_sse2_x87 / fasm / examples / x86 / include / ext / sse2.inc
blob340c14157a8fc1ebb80498bfca12134f2f83c150
1 \r
2 if ~ defined SSE2\r
3 \r
4         restore SSE2    ; this ensures that symbol cannot be forward-referenced\r
5         SSE2 = 1\r
6 \r
7         include 'sse.inc'\r
8 \r
9         iterate <instr,ext>, sqrt,51h, rsqrt,52h, rcp,53h, add,58h, mul,59h, sub,5Ch, min,5Dh, div,5Eh, max,5Fh\r
10                 macro instr#pd? dest*,src*\r
11                         SSE.basic_instruction 66h,ext,16,dest,src\r
12                 end macro\r
13                 macro instr#sd? dest*,src*\r
14                         SSE.basic_instruction 0F2h,ext,8,dest,src\r
15                 end macro\r
16         end iterate\r
18         iterate <instr,ext>, and,54h, andn,55h, or,56h, xor,57h, unpckl,14h, unpckh,15h\r
19                 macro instr#pd? dest*,src*\r
20                         SSE.basic_instruction 66h,ext,16,dest,src\r
21                 end macro\r
22         end iterate\r
24         macro cmppd? dest*,src*,code*\r
25                 SSE.basic_instruction_imm8 66h,0C2h,16,dest,src,code\r
26         end macro\r
28         macro SSE.cmpsd? dest*,src*,code*\r
29                 SSE.basic_instruction_imm8 0F2h,0C2h,8,dest,src,code\r
30         end macro\r
32         calminstruction cmpsd? args&\r
33                 match   , args\r
34                 jno     sse\r
35                 assemble x86.o32\r
36                 assemble x86.cmpsw\r
37                 exit\r
38             sse:\r
39                 arrange args, =SSE.=cmpsd args\r
40                 assemble args\r
41         end calminstruction\r
43         iterate <cond,code>, eq,0, lt,1, le,2, unord,3, neq,4, nlt,5, nle,6, ord,7\r
44                 macro cmp#cond#pd? dest*,src*\r
45                         cmppd dest,src,code\r
46                 end macro\r
47                 macro cmp#cond#sd? dest*,src*\r
48                         cmpsd dest,src,code\r
49                 end macro\r
50         end iterate\r
52         macro shufpd? dest*,src*,imm*\r
53                 SSE.basic_instruction_imm8 66h,0C6h,16,dest,src,imm\r
54         end macro\r
56         iterate <instr,ext>, movapd,28h, movupd,10h\r
57                 macro instr? dest*,src*\r
58                         SSE.parse_operand @dest,dest\r
59                         SSE.parse_operand @src,src\r
60                         if (@dest.size or @src.size) and not 16\r
61                                 err 'invalid operand size'\r
62                         end if\r
63                         if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')\r
64                                 @src.opcode_prefix = 66h\r
65                                 x86.store_instruction <0Fh,ext>,@src,@dest.rm\r
66                         else if @dest.type = 'mem' & @src.type = 'mmreg'\r
67                                 @dest.opcode_prefix = 66h\r
68                                 x86.store_instruction <0Fh,ext+1>,@dest,@src.rm\r
69                         else\r
70                                 err 'invalid combination of operands'\r
71                         end if\r
72                 end macro\r
73         end iterate\r
75         iterate <instr,ext>, movlpd,12h, movhpd,16h\r
76                 macro instr? dest*,src*\r
77                         SSE.parse_operand @dest,dest\r
78                         SSE.parse_operand @src,src\r
79                         if @dest.type = 'mmreg' & @src.type = 'mem'\r
80                                 if @dest.size <> 16 | @src.size and not 8\r
81                                         err 'invalid operand size'\r
82                                 end if\r
83                                 @src.opcode_prefix = 66h\r
84                                 x86.store_instruction <0Fh,ext>,@src,@dest.rm\r
85                         else if @dest.type = 'mem' & @src.type = 'mmreg'\r
86                                 if @dest.size and not 8 | @src.size <> 16\r
87                                         err 'invalid operand size'\r
88                                 end if\r
89                                 @dest.opcode_prefix = 66h\r
90                                 x86.store_instruction <0Fh,ext+1>,@dest,@src.rm\r
91                         else\r
92                                 err 'invalid combination of operands'\r
93                         end if\r
94                 end macro\r
95         end iterate\r
97         macro SSE.movsd? dest*,src*\r
98                 SSE.parse_operand @dest,dest\r
99                 SSE.parse_operand @src,src\r
100                 if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')\r
101                         if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> 16)\r
102                                 err 'invalid operand size'\r
103                         end if\r
104                         @src.opcode_prefix = 0F2h\r
105                         x86.store_instruction <0Fh,10h>,@src,@dest.rm\r
106                 else if @dest.type = 'mem' & @src.type = 'mmreg'\r
107                         if @dest.size and not 8 | @src.size <> 16\r
108                                 err 'invalid operand size'\r
109                         end if\r
110                         @dest.opcode_prefix = 0F2h\r
111                         x86.store_instruction <0Fh,11h>,@dest,@src.rm\r
112                 else\r
113                         err 'invalid combination of operands'\r
114                 end if\r
115         end macro\r
117         calminstruction movsd? args&\r
118                 match   , args\r
119                 jno     sse\r
120                 assemble x86.o32\r
121                 assemble x86.movsw\r
122                 exit\r
123             sse:\r
124                 arrange args, =SSE.=movsd args\r
125                 assemble args\r
126         end calminstruction\r
128         iterate <instr,pre>, movdqa,66h, movdqu,0F3h\r
129                 macro instr? dest*,src*\r
130                         SSE.parse_operand @dest,dest\r
131                         SSE.parse_operand @src,src\r
132                         if (@dest.size or @src.size) and not 16\r
133                                 err 'invalid operand size'\r
134                         end if\r
135                         if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')\r
136                                 @src.opcode_prefix = pre\r
137                                 x86.store_instruction <0Fh,6Fh>,@src,@dest.rm\r
138                         else if @dest.type = 'mem' & @src.type = 'mmreg'\r
139                                 @dest.opcode_prefix = pre\r
140                                 x86.store_instruction <0Fh,7Fh>,@dest,@src.rm\r
141                         else\r
142                                 err 'invalid combination of operands'\r
143                         end if\r
144                 end macro\r
145         end iterate\r
147         iterate <instr,ext>, movntpd,2Bh, movntdq,0E7h\r
148                 macro instr? dest*,src*\r
149                         SSE.parse_operand @dest,dest\r
150                         SSE.parse_operand @src,src\r
151                         if @dest.type = 'mem' & @src.type = 'mmreg'\r
152                                 if (@dest.size or @src.size) and not 16\r
153                                         err 'invalid operand size'\r
154                                 end if\r
155                                 @dest.opcode_prefix = 66h\r
156                                 x86.store_instruction <0Fh,ext>,@dest,@src.rm\r
157                         else\r
158                                 err 'invalid combination of operands'\r
159                         end if\r
160                 end macro\r
161         end iterate\r
163         macro movmskpd? dest*,src*\r
164                 SSE.parse_operand @dest,dest\r
165                 SSE.parse_operand @src,src\r
166                 if @dest.type = 'reg' & @src.type = 'mmreg'\r
167                         if (@dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | @src.size <> 16\r
168                                 err 'invalid operand size'\r
169                         end if\r
170                         @src.opcode_prefix = 66h\r
171                         x86.store_instruction <0Fh,50h>,@src,@dest.rm\r
172                 else\r
173                         err 'invalid combination of operands'\r
174                 end if\r
175         end macro\r
177         macro maskmovdqu? dest*,src*\r
178                 SSE.parse_operand @dest,dest\r
179                 SSE.parse_operand @src,src\r
180                 if @dest.type = 'mmreg' & @src.type = 'mmreg'\r
181                         if (@dest.size or @src.size) <> 16\r
182                                 err 'invalid operand size'\r
183                         end if\r
184                         @src.opcode_prefix = 66h\r
185                         x86.store_instruction <0Fh,0F7h>,@src,@dest.rm\r
186                 else\r
187                         err 'invalid combination of operands'\r
188                 end if\r
189         end macro\r
191         iterate <instr,ext>, ucomisd,2Eh, comisd,2Fh\r
192                 macro instr? dest*,src*\r
193                         SSE.parse_operand @dest,dest\r
194                         SSE.parse_operand @src,src\r
195                         if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')\r
196                                 if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> 16)\r
197                                         err 'invalid operand size'\r
198                                 end if\r
199                                 @src.opcode_prefix = 66h\r
200                                 x86.store_instruction <0Fh,ext>,@src,@dest.rm\r
201                         else\r
202                                 err 'invalid combination of operands'\r
203                         end if\r
204                 end macro\r
205         end iterate\r
207         macro cvtps2pd? dest*,src*\r
208                 SSE.basic_instruction 0,5Ah,8,dest,src\r
209         end macro\r
211         macro cvtpd2ps? dest*,src*\r
212                 SSE.basic_instruction 66h,5Ah,16,dest,src\r
213         end macro\r
215         macro cvtsd2ss? dest*,src*\r
216                 SSE.basic_instruction 0F2h,5Ah,8,dest,src\r
217         end macro\r
219         macro cvtss2sd? dest*,src*\r
220                 SSE.basic_instruction 0F3h,5Ah,4,dest,src\r
221         end macro\r
223         macro cvtdq2ps? dest*,src*\r
224                 SSE.basic_instruction 0,5Bh,16,dest,src\r
225         end macro\r
227         macro cvtps2dq? dest*,src*\r
228                 SSE.basic_instruction 66h,5Bh,16,dest,src\r
229         end macro\r
231         macro cvttps2dq? dest*,src*\r
232                 SSE.basic_instruction 0F3h,5Bh,16,dest,src\r
233         end macro\r
235         macro cvttpd2dq? dest*,src*\r
236                 SSE.basic_instruction 66h,0E6h,16,dest,src\r
237         end macro\r
239         macro cvtpd2dq? dest*,src*\r
240                 SSE.basic_instruction 0F2h,0E6h,16,dest,src\r
241         end macro\r
243         macro cvtdq2pd? dest*,src*\r
244                 SSE.basic_instruction 0F3h,0E6h,8,dest,src\r
245         end macro\r
247         macro movdq2q? dest*,src*\r
248                 SSE.parse_operand @dest,dest\r
249                 SSE.parse_operand @src,src\r
250                 if @dest.type = 'mmreg' & @src.type = 'mmreg'\r
251                         if @dest.size <> 8 | @src.size <> 16\r
252                                 err 'invalid operand size'\r
253                         end if\r
254                         @src.opcode_prefix = 0F2h\r
255                         x86.store_instruction <0Fh,0D6h>,@src,@dest.rm\r
256                 else\r
257                         err 'invalid combination of operands'\r
258                 end if\r
259         end macro\r
261         macro movq2dq? dest*,src*\r
262                 SSE.parse_operand @dest,dest\r
263                 SSE.parse_operand @src,src\r
264                 if @dest.type = 'mmreg' & @src.type = 'mmreg'\r
265                         if @dest.size <> 16 | @src.size <> 8\r
266                                 err 'invalid operand size'\r
267                         end if\r
268                         @src.opcode_prefix = 0F3h\r
269                         x86.store_instruction <0Fh,0D6h>,@src,@dest.rm\r
270                 else\r
271                         err 'invalid combination of operands'\r
272                 end if\r
273         end macro\r
275         macro cvtpi2pd? dest*,src*\r
276                 SSE.parse_operand @dest,dest\r
277                 SSE.parse_operand @src,src\r
278                 if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')\r
279                         if @dest.size <> 16 | @src.size and not 8\r
280                                 err 'invalid operand size'\r
281                         end if\r
282                         @src.opcode_prefix = 66h\r
283                         x86.store_instruction <0Fh,2Ah>,@src,@dest.rm\r
284                 else\r
285                         err 'invalid combination of operands'\r
286                 end if\r
287         end macro\r
289         macro cvtsi2sd? dest*,src*\r
290                 SSE.parse_operand @dest,dest\r
291                 x86.parse_operand @src,src\r
292                 if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg')\r
293                         if @src.size = 0\r
294                                 err 'operand size not specified'\r
295                         else if @dest.size <> 16 | @src.size < 4\r
296                                 err 'invalid operand size'\r
297                         end if\r
298                         x86.select_operand_prefix @src,@src.size\r
299                         @src.opcode_prefix = 0F2h\r
300                         x86.store_instruction <0Fh,2Ah>,@src,@dest.rm\r
301                 else\r
302                         err 'invalid combination of operands'\r
303                 end if\r
304         end macro\r
306         iterate <instr,ext>, cvttpd2pi,2Ch, cvtpd2pi,2Dh\r
307                 macro instr? dest*,src*\r
308                         SSE.parse_operand @dest,dest\r
309                         SSE.parse_operand @src,src\r
310                         if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')\r
311                                 if @dest.size <> 8 | @src.size and not 16\r
312                                         err 'invalid operand size'\r
313                                 end if\r
314                                 @src.opcode_prefix = 66h\r
315                                 x86.store_instruction <0Fh,ext>,@src,@dest.rm\r
316                         else\r
317                                 err 'invalid combination of operands'\r
318                         end if\r
319                 end macro\r
320         end iterate\r
322         iterate <instr,ext>, cvttsd2si,2Ch, cvtsd2si,2Dh\r
323                 macro instr? dest*,src*\r
324                         x86.parse_operand @dest,dest\r
325                         SSE.parse_operand @src,src\r
326                         if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'mmreg')\r
327                                 if @dest.size < 4 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <>16)\r
328                                         err 'invalid operand size'\r
329                                 end if\r
330                                 x86.select_operand_prefix @src,@dest.size\r
331                                 @src.opcode_prefix = 0F2h\r
332                                 x86.store_instruction <0Fh,ext>,@src,@dest.rm\r
333                         else\r
334                                 err 'invalid combination of operands'\r
335                         end if\r
336                 end macro\r
337         end iterate\r
339         calminstruction MMX.select_operand_prefix rm_operand*,size*\r
340                 local   sym, prefix\r
341                 check   size = 16\r
342                 jno     no_prefix\r
343                 compute prefix, 66h\r
344                 arrange sym, rm_operand.=prefix\r
345                 publish sym, prefix\r
346                 exit\r
347             no_prefix:\r
348                 check   size <> 8\r
349                 jno     done\r
350                 asmcmd  =err 'invalid operand size'\r
351             done:\r
352         end calminstruction\r
354         calminstruction MMX.basic_instruction ext,dest,src\r
355                 asmcmd  =SSE.=parse_operand =@dest,dest\r
356                 asmcmd  =SSE.=parse_operand =@src,src\r
357                 check   @src.size and not @dest.size\r
358                 jno     size_ok\r
359                 asmcmd  =err 'operand sizes do not match'\r
360             size_ok:\r
361                 check   @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')\r
362                 jno     invalid_combination_of_operands\r
363                 asmcmd  =MMX.=select_operand_prefix =@src,=@dest.=size\r
364                 asmcmd  =x86.=store_instruction <0Fh,ext>,=@src,=@dest.=rm\r
365                 exit\r
366             invalid_combination_of_operands:\r
367                 asmcmd  =err 'invalid combination of operands'\r
368         end calminstruction\r
370         calminstruction MMX.bit_shift_instruction ext,dest,src\r
371                 asmcmd  =SSE.=parse_operand =@dest,dest\r
372                 asmcmd  =SSE.=parse_operand =@src,src\r
373                 check   @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')\r
374                 jyes    mmreg_rm\r
375                 check   @dest.type = 'mmreg' & @src.type = 'imm'\r
376                 jyes    mmreg_imm\r
377                 asmcmd  =err 'invalid combination of operands'\r
378                 exit\r
379             mmreg_rm:\r
380                 check   @src.size and not @dest.size\r
381                 jno     mmreg_rm_ok\r
382                 asmcmd  =err 'operand sizes do not match'\r
383               mmreg_rm_ok:\r
384                 asmcmd  =MMX.=select_operand_prefix =@src,=@dest.=size\r
385                 asmcmd  =x86.=store_instruction <0Fh,ext>,=@src,=@dest.=rm\r
386                 exit\r
387             mmreg_imm:\r
388                 check   @src.size and not 1\r
389                 jno     rm_mmreg_ok\r
390                 asmcmd  =err 'invalid operand size'\r
391               rm_mmreg_ok:\r
392                 local   iext, irm\r
393                 compute iext, 70h+(ext and 0Fh)\r
394                 compute irm, ((ext shr 4)-0Ch) shl 1\r
395                 asmcmd  =MMX.=select_operand_prefix =@dest,=@dest.=size\r
396                 asmcmd  =x86.=store_instruction <0Fh,iext>,=@dest,irm,1,=@src.=imm\r
397         end calminstruction\r
399         iterate <instr,ext>, paddq,0D4h, pmuludq,0F4h, psubq,0FBh\r
400                 macro instr? dest*,src*\r
401                         MMX.basic_instruction ext,dest,src\r
402                 end macro\r
403         end iterate\r
405         macro movq? dest*,src*\r
406                 SSE.parse_operand @dest,dest\r
407                 SSE.parse_operand @src,src\r
408                 if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')\r
409                         if (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> @dest.size)\r
410                                 err 'invalid operand size'\r
411                         end if\r
412                         if @dest.size = 8\r
413                                 x86.store_instruction <0Fh,6Fh>,@src,@dest.rm\r
414                         else\r
415                                 @src.opcode_prefix = 0F3h\r
416                                 x86.store_instruction <0Fh,7Eh>,@src,@dest.rm\r
417                         end if\r
418                 else if @dest.type = 'mem' & @src.type = 'mmreg'\r
419                         if @dest.size and not 8\r
420                                 err 'invalid operand size'\r
421                         end if\r
422                         if @src.size = 8\r
423                                 x86.store_instruction <0Fh,7Fh>,@dest,@src.rm\r
424                         else\r
425                                 @dest.opcode_prefix = 66h\r
426                                 x86.store_instruction <0Fh,0D6h>,@dest,@src.rm\r
427                         end if\r
428                 else if @dest.type = 'reg' & @src.type = 'mmreg'\r
429                         if @dest.size <> 8\r
430                                 err 'invalid operand size'\r
431                         end if\r
432                         if @src.size = 16\r
433                                 @dest.opcode_prefix = 66h\r
434                         end if\r
435                         @dest.prefix = 48h\r
436                         x86.store_instruction <0Fh,7Eh>,@dest,@src.rm\r
437                 else if @dest.type = 'mmreg' & @src.type = 'reg'\r
438                         if @src.size <> 8\r
439                                 err 'invalid operand size'\r
440                         end if\r
441                         if @dest.size = 16\r
442                                 @src.opcode_prefix = 66h\r
443                         end if\r
444                         @src.prefix = 48h\r
445                         x86.store_instruction <0Fh,6Eh>,@src,@dest.rm\r
446                 else\r
447                         err 'invalid combination of operands'\r
448                 end if\r
449         end macro\r
451         macro movd? dest*,src*\r
452                 SSE.parse_operand @dest,dest\r
453                 SSE.parse_operand @src,src\r
454                 if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg')\r
455                         if @src.size and not 4\r
456                                 err 'invalid operand size'\r
457                         end if\r
458                         MMX.select_operand_prefix @src,@dest.size\r
459                         x86.store_instruction <0Fh,6Eh>,@src,@dest.rm\r
460                 else if (@dest.type = 'mem' | @dest.type = 'reg') & @src.type = 'mmreg'\r
461                         if @dest.size and not 4\r
462                                 err 'invalid operand size'\r
463                         end if\r
464                         MMX.select_operand_prefix @dest,@src.size\r
465                         x86.store_instruction <0Fh,7Eh>,@dest,@src.rm\r
466                 else\r
467                         err 'invalid combination of operands'\r
468                 end if\r
469         end macro\r
471         macro pinsrw? dest*,src*,sel*\r
472                 SSE.parse_operand @dest,dest\r
473                 x86.parse_operand @src,src\r
474                 x86.parse_operand @aux,sel\r
475                 if @dest.type = 'mmreg' & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm'\r
476                         if (@src.type = 'reg' & @src.size <> 4) | (@src.type = 'mem' & @src.size and not 2) | @aux.size and not 1\r
477                                 err 'invalid operand size'\r
478                         end if\r
479                         MMX.select_operand_prefix @src,@dest.size\r
480                         x86.store_instruction <0Fh,0C4h>,@src,@dest.rm,1,@aux.imm\r
481                 else\r
482                         err 'invalid combination of operands'\r
483                 end if\r
484         end macro\r
486         macro pextrw? dest*,src*,sel*\r
487                 x86.parse_operand @dest,dest\r
488                 SSE.parse_operand @src,src\r
489                 x86.parse_operand @aux,sel\r
490                 if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm'\r
491                         if x86.mode = 64 & @dest.size = 8\r
492                                 @dest.size = 4\r
493                         end if\r
494                         if @dest.size <> 4 | @aux.size and not 1\r
495                                 err 'invalid operand size'\r
496                         end if\r
497                         MMX.select_operand_prefix @src,@src.size\r
498                         x86.store_instruction <0Fh,0C5h>,@src,@dest.rm,1,@aux.imm\r
499                 else\r
500                         err 'invalid combination of operands'\r
501                 end if\r
502         end macro\r
504         iterate <instr,pre>, pshufd,66h, pshuflw,0F2h, pshufhw,0F3h\r
505                 macro instr? dest*,src*,sel*\r
506                         SSE.parse_operand @dest,dest\r
507                         SSE.parse_operand @src,src\r
508                         x86.parse_operand @aux,sel\r
509                         if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'\r
510                                 if @dest.size <> 16 | @src.size and not 16 | @aux.size and not 1\r
511                                         err 'invalid operand size'\r
512                                 end if\r
513                                 @src.opcode_prefix = pre\r
514                                 x86.store_instruction <0Fh,70h>,@src,@dest.rm,1,@aux.imm\r
515                         else\r
516                                 err 'invalid combination of operands'\r
517                         end if\r
518                 end macro\r
519         end iterate\r
521         macro pmovmskb? dest*,src*\r
522                 x86.parse_operand @dest,dest\r
523                 SSE.parse_operand @src,src\r
524                 if @dest.type = 'reg' & @src.type = 'mmreg'\r
525                         if @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)\r
526                                 err 'invalid operand size'\r
527                         end if\r
528                         MMX.select_operand_prefix @src,@src.size\r
529                         x86.store_instruction <0Fh,0D7h>,@src,@dest.rm\r
530                 else\r
531                         err 'invalid combination of operands'\r
532                 end if\r
533         end macro\r
535         iterate <instr,postbyte>, psrldq,3, pslldq,7\r
536                 macro instr? dest*,cnt*\r
537                         SSE.parse_operand @dest,dest\r
538                         x86.parse_operand @aux,cnt\r
539                         if @dest.type = 'mmreg' & @aux.type = 'imm'\r
540                                 if @dest.size <> 16 | @aux.size and not 1\r
541                                         err 'invalid operand size'\r
542                                 end if\r
543                                 @dest.opcode_prefix = 66h\r
544                                 x86.store_instruction <0Fh,73h>,@dest,postbyte,1,@aux.imm\r
545                         else\r
546                                 err 'invalid combination of operands'\r
547                         end if\r
548                 end macro\r
549         end iterate\r
551         iterate <instr,ext>, punpcklqdq,6Ch, punpckhqdq,6Dh\r
552                 macro instr? dest*,src*\r
553                         SSE.parse_operand @dest,dest\r
554                         SSE.parse_operand @src,src\r
555                         if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')\r
556                                 if (@dest.size or @src.size) and not 16\r
557                                         err 'invalid operand size'\r
558                                 end if\r
559                                 @src.opcode_prefix = 66h\r
560                                 x86.store_instruction <0Fh,ext>,@src,@dest.rm\r
561                         else\r
562                                 err 'invalid combination of operands'\r
563                         end if\r
564                 end macro\r
565         end iterate\r
567         macro movnti? dest*,src*\r
568                 x86.parse_operand @dest,dest\r
569                 x86.parse_operand @src,src\r
570                 if @dest.type = 'mem' & @src.type = 'reg'\r
571                         if @dest.size and not @src.size\r
572                                 err 'operand sizes do not match'\r
573                         else if @src.size <> 4 & @src.size <> 8\r
574                                 err 'invalid operand size'\r
575                         end if\r
576                         x86.select_operand_prefix @dest,@src.size\r
577                         x86.store_instruction <0Fh,0C3h>,@dest,@src.rm\r
578                 else\r
579                         err 'invalid combination of operands'\r
580                 end if\r
581         end macro\r
583         macro clflush? src*\r
584                 x86.parse_operand @src,src\r
585                 if @src.type = 'mem'\r
586                         if @src.size and not 1\r
587                                 err 'invalid operand size'\r
588                         end if\r
589                         x86.store_instruction <0Fh,0AEh>,@src,7\r
590                 else\r
591                         err 'invalid operand'\r
592                 end if\r
593         end macro\r
595         macro lfence?\r
596                 db 0Fh,0AEh,0E8h\r
597         end macro\r
599         macro mfence?\r
600                 db 0Fh,0AEh,0F0h\r
601         end macro\r
603 end if