4 restore MMX ; this ensures that symbol cannot be forward-referenced
\r
10 element mm#i? : MMX.reg + i
\r
13 calminstruction MMX.parse_operand namespace, operand
\r
15 local size, type, mod, rm, imm
\r
18 asmcmd =x86.=parse_operand namespace, operand
\r
20 arrange type, namespace.=type
\r
21 arrange size, namespace.=size
\r
22 arrange imm, namespace.=imm
\r
24 check type = 'imm' & size = 0
\r
26 check imm eq 1 elementof imm & 1 metadataof imm relativeto MMX.reg
\r
29 compute type, 'mmreg'
\r
31 compute rm, 1 metadataof imm - MMX.reg
\r
34 arrange sym, namespace.=mod
\r
37 arrange sym, namespace.=rm
\r
40 arrange sym, namespace.=type
\r
43 arrange sym, namespace.=size
\r
50 calminstruction MMX.basic_instruction ext,dest,src
\r
51 asmcmd =MMX.=parse_operand =@dest,dest
\r
52 asmcmd =MMX.=parse_operand =@src,src
\r
53 check (@src.size or @dest.size) and not 8
\r
55 asmcmd =err 'invalid operand size'
\r
57 check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
\r
58 jno invalid_combination_of_operands
\r
59 asmcmd =x86.=store_instruction <0Fh,ext>,=@src,=@dest.=rm
\r
61 invalid_combination_of_operands:
\r
62 asmcmd =err 'invalid combination of operands'
\r
65 iterate <instr,opcode>, punpcklbw,60h, punpcklwd,61h, punpckldq,62h, packsswb,63h, pcmpgtb,64h, pcmpgtw,65h, pcmpgtd,66h, packuswb,67h, punpckhbw,68h, \
\r
66 punpckhwd,69h, punpckhdq,6Ah, packssdw,6Bh, pcmpeqb,74h, pcmpeqw,75h, pcmpeqd,76h, pmullw,0D5h, psubusb,0D8h, psubusw,0D9h, \
\r
67 pand,0DBh, paddusb,0DCh, paddusw,0DDh, pandn,0DFh, pmulhw,0E5h, psubsb,0E8h, psubsw,0E9h, por,0EBh, paddsb,0ECh, paddsw,0EDh, \
\r
68 pxor,0EFh, pmaddwd,0F5h, psubb,0F8h, psubw,0F9h, psubd,0FAh, paddb,0FCh, paddw,0FDh, paddd,0FEh
\r
70 macro instr? dest*,src*
\r
71 MMX.basic_instruction opcode,dest,src
\r
76 calminstruction movq? dest*,src*
\r
77 asmcmd =MMX.=parse_operand =@dest,dest
\r
78 asmcmd =MMX.=parse_operand =@src,src
\r
79 check (@src.size or @dest.size) and not 8
\r
81 asmcmd =err 'invalid operand size'
\r
83 check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
\r
85 check @dest.type = 'mem' & @src.type = 'mmreg'
\r
87 asmcmd =err 'invalid combination of operands'
\r
90 asmcmd =x86.=store_instruction <0Fh,6Fh>,=@src,=@dest.=rm
\r
93 asmcmd =x86.=store_instruction <0Fh,7Fh>,=@dest,=@src.=rm
\r
97 calminstruction movd? dest*,src*
\r
98 asmcmd =MMX.=parse_operand =@dest,dest
\r
99 asmcmd =MMX.=parse_operand =@src,src
\r
100 check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg')
\r
102 check (@dest.type = 'mem' | @dest.type = 'reg') & @src.type = 'mmreg'
\r
104 asmcmd =err 'invalid combination of operands'
\r
107 check @src.size and not 4
\r
109 asmcmd =err 'invalid operand size'
\r
111 asmcmd =x86.=store_instruction <0Fh,6Eh>,=@src,=@dest.=rm
\r
114 check @dest.size and not 4
\r
116 asmcmd =err 'invalid operand size'
\r
118 asmcmd =x86.=store_instruction <0Fh,7Eh>,=@dest,=@src.=rm
\r
119 end calminstruction
\r
121 calminstruction MMX.bit_shift_instruction ext,dest,src
\r
122 asmcmd =MMX.=parse_operand =@dest,dest
\r
123 asmcmd =MMX.=parse_operand =@src,src
\r
124 check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
\r
126 check @dest.type = 'mmreg' & @src.type = 'imm'
\r
128 asmcmd =err 'invalid combination of operands'
\r
131 check @src.size and not 8
\r
133 asmcmd =err 'invalid operand size'
\r
135 asmcmd =x86.=store_instruction <0Fh,ext>,=@src,=@dest.=rm
\r
138 check @src.size and not 1
\r
140 asmcmd =err 'invalid operand size'
\r
143 compute iext, 70h+(ext and 0Fh)
\r
144 compute irm, ((ext shr 4)-0Ch) shl 1
\r
145 asmcmd =x86.=store_instruction <0Fh,iext>,=@dest,irm,1,=@src.=imm
\r
146 end calminstruction
\r
148 iterate <instr,opcode>, psrlw,0D1h, psrld,0D2h, psrlq,0D3h, psrad,0E2h, psraw,0E1h, psllw,0F1h, pslld,0F2h, psllq,0F3h
\r
150 macro instr? dest*,src*
\r
151 MMX.bit_shift_instruction opcode,dest,src
\r