added fasm2 as well

This commit is contained in:
2024-11-25 00:04:53 -05:00
parent 8a974e9c89
commit dceb330571
165 changed files with 78512 additions and 0 deletions

View File

@ -0,0 +1,46 @@
iterate <instr,opcode>, pf2id,1Dh, pfacc,0AEh, pfadd,9Eh, pfmax,0A4h, pfmin,94h, \
pfmul,0B4h, pfrcp,96h, pfsub,9Ah, pi2fd,0Dh, pi2fw,0Ch, \
pfsubr,0AAh, pavgusb,0BFh, pfcmpeq,0B0h, pfcmpge,90h, pfcmpgt,0A0h, \
pfrsqrt,97h, pmulhrw,0B7h, pfrcpit2,0B6h, pfrsqit1,0A7h
calminstruction instr? dest*,src*
call x86.require.3DNow
call MMX.parse_operand@dest, dest
call MMX.parse_operand@src, src
check @src.size and not @dest.size
jno size_ok
err 'operand sizes do not match'
size_ok:
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
jno invalid_combination_of_operands
xcall x86.store_instruction@src, <0Fh,0Fh>,@dest.rm,(1),(opcode)
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
end iterate
calminstruction femms?
call x86.require.3DNow
emit 1, 0Fh
emit 1, 0Eh
end calminstruction
iterate <instr,postbyte>, prefetch,0, prefetchw,1
calminstruction instr? src*
call x86.require.3DNow
call MMX.parse_operand@src, src
check @src.type = 'mem'
jno invalid_operand
check @src.size and not 1
jno size_ok
err 'invalid operand size'
size_ok:
xcall x86.store_instruction@src, <0Fh,0Dh>,(postbyte)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate

View File

@ -0,0 +1,58 @@
iterate <instr,supp>, aesdec,0DEh, aesenc,0DCh, aesdeclast,0DFh, aesenclast,0DDh
macro instr? dest*,src*
require AESNI
SSE.basic_instruction 66h,<38h,supp>,16,dest,src
end macro
macro v#instr? dest*,src*,src2*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @dest.size <> @src.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
@src2.memsize = 0
if x86.ext and x86.VAES.ext
AVX_512.store_instruction@src2 @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,@dest.rm,@src.rm
else
require AESNI
AVX_512.store_instruction@src2 @dest.size,VEX_66_0F38_W0,EVEX_FORBIDDEN,opcode,0,@dest.rm,@src.rm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, aesimc,0DBh
macro instr? dest*,src*
require AESNI
SSE.basic_instruction 66h,<38h,supp>,16,dest,src
end macro
macro v#instr? dest*,src*
require AESNI
AVX_512.single_source_instruction VEX_66_0F38_W0,EVEX_FORBIDDEN,opcode,16,dest,src
end macro
end iterate
iterate <instr,supp>, aeskeygenassist,0DFh
macro instr? dest*,src*,imm*
require AESNI
SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm
end macro
macro v#instr? dest*,src*,imm*
require AESNI
AVX_512.single_source_instruction_imm8 VEX_66_0F3A_W0,EVEX_FORBIDDEN,opcode,16,dest,src,imm
end macro
end iterate

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,290 @@
macro andn? dest*,src*,src2*
require BMI1
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & @src.type = 'reg' & (@src2.type = 'mem' | @src2.type = 'reg')
if @dest.size < 4
err 'invalid operand size'
else if @src.size <> @dest.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src2 16,VEX_0F38_W1,0F2h,@dest.rm,@src.rm
else
AVX.store_instruction@src2 16,VEX_0F38_W0,0F2h,@dest.rm,@src.rm
end if
else
err 'invalid combination of operands'
end if
end macro
macro bextr? dest*,src*,src2*
require BMI1
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'reg'
if @dest.size < 4
err 'invalid operand size'
else if @src.size and not @dest.size | @src2.size <> @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,VEX_0F38_W1,0F7h,@dest.rm,@src2.rm
else
AVX.store_instruction@src 16,VEX_0F38_W0,0F7h,@dest.rm,@src2.rm
end if
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,opcode,postbyte>, blsi,0F3h,3, blsmsk,0F3h,2, blsr,0F3h,1
macro instr? dest*,src*
require BMI1
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg')
if @dest.size < 4
err 'invalid operand size'
else if @src.size and not @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,VEX_0F38_W1,opcode,postbyte,@dest.rm
else
AVX.store_instruction@src 16,VEX_0F38_W0,opcode,postbyte,@dest.rm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, lzcnt,0BDh, tzcnt,0BCh
macro instr? dest*,src*
require BMI1
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & ( @src.type = 'reg' | @src.type = 'mem' )
if @src.size and not @dest.size
err 'operand sizes do not match'
end if
@src.opcode_prefix = 0F3h
if @dest.size > 1
x86.select_operand_prefix@src @dest.size
x86.store_instruction@src <0Fh,opcode>,@dest.rm
else
err 'invalid operand size'
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, bzhi,0F5h
macro instr? dest*,src*,src2*
require BMI2
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'reg'
if @dest.size < 4
err 'invalid operand size'
else if @src.size and not @dest.size | @src2.size <> @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,VEX_0F38_W1,opcode,@dest.rm,@src2.rm
else
AVX.store_instruction@src 16,VEX_0F38_W0,opcode,@dest.rm,@src2.rm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mp,opcode>, mulx,VEX_F2_0F38,0F6h, pdep,VEX_F2_0F38,0F5h, pext,VEX_F3_0F38,0F5h
macro instr? dest*,src*,src2*
require BMI2
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & @src.type = 'reg' & (@src2.type = 'mem' | @src2.type = 'reg')
if @dest.size < 4
err 'invalid operand size'
else if @src.size <> @dest.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src2 16,vex_mp#_W1,opcode,@dest.rm,@src.rm
else
AVX.store_instruction@src2 16,vex_mp#_W0,opcode,@dest.rm,@src.rm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro rorx? dest*,src*,src2*
require BMI2
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'imm'
if @dest.size < 4 | @src2.size and not 1
err 'invalid operand size'
else if @src.size and not @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,VEX_F2_0F3A_W1,0F0h,@dest.rm,,1,@src2.imm
else
AVX.store_instruction@src 16,VEX_F2_0F3A_W0,0F0h,@dest.rm,,1,@src2.imm
end if
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,vex_mp,opcode>, sarx,VEX_F3_0F38,0F7h, shlx,VEX_66_0F38,0F7h, shrx,VEX_F2_0F38,0F7h
macro instr? dest*,src*,src2*
require BMI2
x86.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'reg'
if @dest.size < 4
err 'invalid operand size'
else if @src.size and not @dest.size | @src2.size <> @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8
if x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,vex_mp#_W1,opcode,@dest.rm,@src2.rm
else
AVX.store_instruction@src 16,vex_mp#_W0,opcode,@dest.rm,@src2.rm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpermb,VEX_66_0F38_W0,8Dh, vpermi2b,VEX_66_0F38_W0,75h, vpermt2b,VEX_66_0F38_W0,7Dh
macro instr? dest*,src*,src2*
require AVX512_VBMI
AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, vpmultishiftqb,83h
macro instr? dest*,src*,src2*
require AVX512_VBMI
AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpshldw,VEX_66_0F3A_W1,70h, vpshrdw,VEX_66_0F3A_W1,72h
macro instr? dest*,src*,src2*,aux*&
require AVX512_VBMI2
AVX_512.basic_instruction_imm8 vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2,aux
end macro
end iterate
iterate <instr,unit,vex_mpw,opcode>, vpshldd,4,VEX_66_0F3A_W0,71h, vpshldq,8,VEX_66_0F3A_W1,71h, \
vpshrdd,4,VEX_66_0F3A_W0,73h, vpshrdq,8,VEX_66_0F3A_W1,73h
macro instr? dest*,src*,src2*,aux*&
require AVX512_VBMI2
AVX_512.basic_instruction_bcst_imm8 vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src,src2,aux
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpshldvw,VEX_66_0F38_W1,70h, vpshrdvw,VEX_66_0F38_W1,72h
macro instr? dest*,src*,src2*
require AVX512_VBMI2
AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,unit,vex_mpw,opcode>, vpshldvd,4,VEX_66_0F38_W0,71h, vpshldvq,8,VEX_66_0F38_W1,71h, \
vpshrdvd,4,VEX_66_0F38_W0,73h, vpshrdvq,8,VEX_66_0F38_W1,73h
macro instr? dest*,src*,src2*
require AVX512_VBMI2
AVX_512.basic_instruction_bcst vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src,src2
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpcompressb,VEX_66_0F38_W0,63h, vpcompressw,VEX_66_0F38_W1,63h
macro instr? dest*,src*
require AVX512_VBMI2
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg'
if @dest.size and not @src.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@dest @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpexpandb,VEX_66_0F38_W0,62h, vpexpandw,VEX_66_0F38_W1,62h
macro instr? dest*,src*
require AVX512_VBMI2
AVX_512.single_source_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src
end macro
end iterate

View File

@ -0,0 +1,122 @@
iterate <instr,modrm>, endbr32,0FBh, endbr64,0FAh
macro instr?
require CET_IBT
db 0F3h,0Fh,1Eh,modrm
end macro
end iterate
iterate <instr,ext,postbyte>, clrssbsy,0AEh,6, rstorssp,01h,5
macro instr? src*
require CET_SS
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 8
err 'invalid operand size'
else
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,ext>,postbyte
end if
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,ext,postbyte>, incsspd,0AEh,5, rdsspd,1Eh,1
macro instr? src*
require CET_SS
x86.parse_operand@src src
if @src.type = 'reg'
if @src.size <> 4
err 'invalid operand size'
else
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,ext>,postbyte
end if
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,ext,postbyte>, incsspq,0AEh,5, rdsspq,1Eh,1
macro instr? src*
require CET_SS
x86.parse_operand@src src
if @src.type = 'reg'
if @src.size <> 8
err 'invalid operand size'
else
x86.select_operand_prefix@src 8
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,ext>,postbyte
end if
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,modrm>, saveprevssp,0EAh, setssbsy,0E8h
macro instr?
require CET_SS
db 0F3h,0Fh,01h,modrm
end macro
end iterate
iterate <instr,prefix,ext>, wrssd,0,0F6h, wrussd,66h,0F5h
macro instr? dest*,src*
require CET_SS
x86.parse_operand@dest dest
x86.parse_operand@src src
local size
if @src.size <> 4
err 'invalid operand size'
else if @dest.size and not @src.size
err 'operand sizes do not match'
end if
if @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' )
@dest.opcode_prefix = prefix
x86.store_instruction@dest <0Fh,38h,ext>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,prefix,ext>, wrssq,0,0F6h, wrussq,66h,0F5h
macro instr? dest*,src*
require CET_SS
x86.parse_operand@dest dest
x86.parse_operand@src src
local size
if @src.size <> 8
err 'invalid operand size'
else if @dest.size and not @src.size
err 'operand sizes do not match'
end if
if @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' )
x86.select_operand_prefix@dest 8
@dest.opcode_prefix = prefix
x86.store_instruction@dest <0Fh,38h,ext>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,742 @@
element st?
repeat 8, i:0
element st#i? : st? + i
end repeat
iterate context, @dest,@src,@src2,@aux
namespace context
calminstruction x87.parse_operand#context operand
local i
match =st?(i), operand
jyes indexed_streg_operand
call x86.parse_operand#context, operand
check type = 'imm' & size = 0
jno done
check imm eq 1 elementof imm & 1 metadataof imm relativeto st?
jyes streg_operand
check imm relativeto st? & imm = st?
jno done
compute type, 'streg'
compute mod, 11b
compute rm, 0
exit
streg_operand:
compute type, 'streg'
compute mod, 11b
compute rm, 1 metadataof imm - st?
exit
indexed_streg_operand:
compute size, 0
compute type, 'streg'
compute mod, 11b
compute rm, +i
done:
end calminstruction
end namespace
end iterate
iterate <instr,opcode>, fwait,9Bh, wait,9Bh
calminstruction instr?
call x86.require.8087
emit 1, opcode
end calminstruction
end iterate
iterate <instr,byte1,byte2>, fnop,0D9h,0D0h, fchs,0D9h,0E0h, fabs,0D9h,0E1h, ftst,0D9h,0E4h, fxam,0D9h,0E5h, fld1,0D9h,0E8h, \
fldl2t,0D9h,0E9h, fldl2e,0D9h,0EAh, fldpi,0D9h,0EBh, fldlg2,0D9h,0ECh, fldln2,0D9h,0EDh, fldz,0D9h,0EEh, \
f2xm1,0D9h,0F0h, fyl2x,0D9h,0F1h, fptan,0D9h,0F2h, fpatan,0D9h,0F3h, fxtract,0D9h,0F4h, \
fdecstp,0D9h,0F6h, fincstp,0D9h,0F7h, fprem,0D9h,0F8h, \
fyl2xp1,0D9h,0F9h, fsqrt,0D9h,0FAh, frndint,0D9h,0FCh, fscale,0D9h,0FDh, \
fneni,0DBh,0E0h, fndisi,0DBh,0E1h, fnclex,0DBh,0E2h, fninit,0DBh,0E3h, \
fcompp,0DEh,0D9h
calminstruction instr?
call x86.require.8087
emit 1, byte1
emit 1, byte2
end calminstruction
end iterate
iterate <instr,opcode>, fneni,0E0h, fndisi,0E1h
calminstruction instr?
call x86.requireexact.8087
emit 1, 0DBh
emit 1, opcode
end calminstruction
end iterate
iterate op, eni, disi, clex, init
calminstruction f#op?
asm fwait?
asm fn#op?
end calminstruction
end iterate
calminstruction fsetpm?
call x86.requireexact.80287
emit 1, 0DBh
emit 1, 0E4h
end calminstruction
iterate <instr,postbyte>, fadd,0, fmul,1, fsub,4, fsubr,5, fdiv,6, fdivr,7
calminstruction instr? operand&
call x86.require.8087
local dest, src
match dest=,src, operand
jyes st
call x87.parse_operand@dest, operand
check @dest.type = 'mem'
jno invalid_combination_of_operands
check @dest.size = 4
jyes mem_dword
check @dest.size = 8
jyes mem_qword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_dword
unknown_size:
err 'operand size not specified'
mem_dword:
xcall x86.store_instruction@dest, (0D8h),(postbyte)
exit
mem_qword:
xcall x86.store_instruction@dest, (0DCh),(postbyte)
exit
st:
call x87.parse_operand@dest, dest
call x87.parse_operand@src, src
check @dest.type = 'streg' & @src.type = 'streg'
jno invalid_combination_of_operands
check @dest.rm = 0
jyes st0_sti
check @src.rm = 0
jyes sti_st0
jump invalid_combination_of_operands
st0_sti:
emit 1, 0D8h
emit 1, 11b shl 6 + postbyte shl 3 + @src.rm
exit
sti_st0:
check postbyte >= 4
jyes switched
emit 1, 0DCh
emit 1, 11b shl 6 + postbyte shl 3 + @dest.rm
exit
switched:
emit 1, 0DCh
emit 1, 11b shl 6 + (postbyte xor 1) shl 3 + @dest.rm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
end iterate
iterate <instr,postbyte>, faddp,0, fmulp,1, fsubrp,4, fsubp,5, fdivrp,6, fdivp,7
calminstruction instr? operand&
call x86.require.8087
local dest, src
match , operand
jyes default
match dest=,src, operand
jno invalid_combination_of_operands
call x87.parse_operand@dest, dest
call x87.parse_operand@src, src
check @dest.type = 'streg' & @src.type = 'streg' & @src.rm = 0
jyes ok
invalid_combination_of_operands:
err 'invalid combination of operands'
exit
default:
compute @dest.rm, 1
ok:
emit 1, 0DEh
emit 1, 11b shl 6 + postbyte shl 3 + @dest.rm
end calminstruction
end iterate
iterate <instr,postbyte>, fcom,2, fcomp,3
calminstruction instr? src:st1
call x86.require.8087
call x87.parse_operand@src, src
check @src.type = 'streg'
jyes st
check @src.type = 'mem'
jno invalid_operand
check @src.size = 4
jyes mem_dword
check @src.size = 8
jyes mem_qword
check @src.size
jno unknown_size
err 'invalid operand size'
jump mem_dword
unknown_size:
err 'operand size not specified'
mem_dword: st:
xcall x86.store_instruction@src, (0D8h),(postbyte)
exit
mem_qword:
xcall x86.store_instruction@src, (0DCh),(postbyte)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, fiadd,0, fimul,1, ficom,2, ficomp,3, fisub,4, fisubr,5, fidiv,6, fidivr,7
calminstruction instr? src*
call x86.require.8087
call x87.parse_operand@src, src
check @src.type = 'mem'
jno invalid_operand
check @src.size = 2
jyes mem_word
check @src.size = 4
jyes mem_dword
check @src.size
jno unknown_size
err 'invalid operand size'
jump mem_word
unknown_size:
err 'operand size not specified'
mem_word:
xcall x86.store_instruction@src, (0DEh),(postbyte)
exit
mem_dword:
xcall x86.store_instruction@src, (0DAh),(postbyte)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
calminstruction fld? src*
call x86.require.8087
call x87.parse_operand@src, src
check @src.type = 'streg'
jyes st
check @src.type = 'mem'
jno invalid_operand
check @src.size = 4
jyes mem_dword
check @src.size = 8
jyes mem_qword
check @src.size = 10
jyes mem_tword
check @src.size
jno unknown_size
err 'invalid operand size'
jump mem_dword
unknown_size:
err 'operand size not specified'
mem_dword: st:
xcall x86.store_instruction@src, (0D9h),(0)
exit
mem_qword:
xcall x86.store_instruction@src, (0DDh),(0)
exit
mem_tword:
xcall x86.store_instruction@src, (0DBh),(5)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fst? dest*
call x86.require.8087
call x87.parse_operand@dest, dest
check @dest.type = 'streg'
jyes st
check @dest.type = 'mem'
jno invalid_operand
check @dest.size = 4
jyes mem_dword
check @dest.size = 8
jyes mem_qword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_dword
unknown_size:
err 'operand size not specified'
mem_dword:
xcall x86.store_instruction@dest, (0D9h),(2)
exit
mem_qword: st:
xcall x86.store_instruction@dest, (0DDh),(2)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fstp? dest*
call x86.require.8087
call x87.parse_operand@dest, dest
check @dest.type = 'streg'
jyes st
check @dest.type = 'mem'
jno invalid_operand
check @dest.size = 4
jyes mem_dword
check @dest.size = 8
jyes mem_qword
check @dest.size = 10
jyes mem_tword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_dword
unknown_size:
err 'operand size not specified'
mem_dword:
xcall x86.store_instruction@dest, (0D9h),(3)
exit
mem_qword: st:
xcall x86.store_instruction@dest, (0DDh),(3)
exit
mem_tword:
xcall x86.store_instruction@dest, (0DBh),(7)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fild? src*
call x86.require.8087
call x87.parse_operand@src, src
check @src.type = 'mem'
jno invalid_operand
check @src.size = 2
jyes mem_word
check @src.size = 4
jyes mem_dword
check @src.size = 8
jyes mem_qword
check @src.size
jno unknown_size
err 'invalid operand size'
jump mem_word
unknown_size:
err 'operand size not specified'
mem_word:
xcall x86.store_instruction@src, (0DFh),(0)
exit
mem_dword:
xcall x86.store_instruction@src, (0DBh),(0)
exit
mem_qword:
xcall x86.store_instruction@src, (0DFh),(5)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fist? dest*
call x86.require.8087
call x87.parse_operand@dest, dest
check @dest.type = 'mem'
jno invalid_operand
check @dest.size = 2
jyes mem_word
check @dest.size = 4
jyes mem_dword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_word
unknown_size:
err 'operand size not specified'
mem_word:
xcall x86.store_instruction@dest, (0DFh),(2)
exit
mem_dword:
xcall x86.store_instruction@dest, (0DBh),(2)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fistp? dest*
call x86.require.8087
call x87.parse_operand@dest, dest
check @dest.type = 'mem'
jno invalid_operand
check @dest.size = 2
jyes mem_word
check @dest.size = 4
jyes mem_dword
check @dest.size = 8
jyes mem_qword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_word
unknown_size:
err 'operand size not specified'
mem_word:
xcall x86.store_instruction@dest, (0DFh),(3)
exit
mem_dword:
xcall x86.store_instruction@dest, (0DBh),(3)
exit
mem_qword:
xcall x86.store_instruction@dest, (0DFh),(7)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
calminstruction fisttp? dest*
call x86.require.8087
call x87.parse_operand@dest, dest
check @dest.type = 'mem'
jno invalid_operand
check @dest.size = 2
jyes mem_word
check @dest.size = 4
jyes mem_dword
check @dest.size = 8
jyes mem_qword
check @dest.size
jno unknown_size
err 'invalid operand size'
jump mem_word
unknown_size:
err 'operand size not specified'
mem_word:
xcall x86.store_instruction@dest, (0DFh),(1)
exit
mem_dword:
xcall x86.store_instruction@dest, (0DBh),(1)
exit
mem_qword:
xcall x86.store_instruction@dest, (0DDh),(1)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
iterate <instr,postbyte>, fbld,4, fbstp,6
calminstruction instr? src*
call x86.require.8087
call x87.parse_operand@src, src
check @src.type = 'mem'
jno invalid_operand
check @src.size and not 10
jyes invalid_operand_size
xcall x86.store_instruction@src, (0DFh),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
calminstruction fxch? src:st1
call x86.require.8087
call x87.parse_operand@src, src
check @src.type = 'streg'
jno invalid_operand
emit 1, 0D9h
emit 1, 11b shl 6 + 1 shl 3 + @src.rm
exit
invalid_operand:
err 'invalid operand'
end calminstruction
iterate <instr,basecode>, ffree,0DDh, ffreep,0DFh
calminstruction instr? src*
call x86.require.8087
call x87.parse_operand@src, src
check @src.type = 'streg'
jno invalid_operand
emit 1, basecode
emit 1, 11b shl 6 + @src.rm
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
calminstruction fnstsw? dest*
call x86.require.8087
call x86.parse_operand@dest, dest
check @dest.size and not 2
jyes invalid_operand_size
check @dest.type = 'mem'
jyes mem
check @dest.type = 'reg' & @dest.rm = 0
jno invalid_operand
emit 1, 0DFh
emit 1, 0E0h
exit
mem:
xcall x86.store_instruction@dest, (0DDh),(7)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
iterate <instr,postbyte>, fldcw,5, fnstcw,7
calminstruction instr? dest*
call x86.parse_operand@dest, dest
check @dest.size and not 2
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_instruction@dest, (0D9h),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, fldenv,4, fnstenv,6
calminstruction instr? dest*
call x86.require.8087
call x86.parse_operand@dest, dest
check @dest.size and not 14
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_instruction@dest, (0D9h),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, frstor,4, fnsave,6
calminstruction instr? dest*
call x86.require.8087
call x86.parse_operand@dest, dest
check @dest.size and not 94
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_instruction@dest, (0DDh),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate op, stsw, stcw, stenv, save
calminstruction f#op? dest*
asm fwait?
asm fn#op? dest
end calminstruction
end iterate
iterate <instr,byte1,byte2>, fprem1,0D9h,0F5h, fsincos,0D9h,0FBh, fsin,0D9h,0FEh, fcos,0D9h,0FFh, fucompp,0DAh,0E9h
calminstruction instr?
call x86.require.80387
emit 1, byte1
emit 1, byte2
end calminstruction
end iterate
iterate <instr,postbyte>, fucom,4, fucomp,5
calminstruction instr? src:st1
call x86.require.80387
call x87.parse_operand@src, src
check @src.type = 'streg'
jno invalid_operand
xcall x86.store_instruction@src, (0DDh),(postbyte)
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, fldenv,4, fnstenv,6
calminstruction instr? dest*
call x86.require.80387
call x86.parse_operand@dest, dest
check @dest.size & ( ( x86.mode = 16 & @dest.size <> 14 ) | ( x86.mode = 32 & @dest.size <> 28 ) )
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_instruction@dest, (0D9h),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, fldenvw,4, fnstenvw,6
calminstruction instr? dest*
call x86.require.80387
call x86.parse_operand@dest, dest
check @dest.size and not 14
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_operand_prefix, (2)
xcall x86.store_instruction@dest, (0D9h),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, fldenvd,4, fnstenvd,6
calminstruction instr? dest*
call x86.require.80387
call x86.parse_operand@dest, dest
check @dest.size and not 28
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_operand_prefix, (4)
xcall x86.store_instruction@dest, (0D9h),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, frstor,4, fnsave,6
calminstruction instr? dest*
call x86.require.80387
call x86.parse_operand@dest, dest
check @dest.size & ( ( x86.mode = 16 & @dest.size <> 94 ) | ( x86.mode = 32 & @dest.size <> 108 ) )
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_instruction@dest, (0DDh),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, frstorw,4, fnsavew,6
calminstruction instr? dest*
call x86.require.80387
call x86.parse_operand@dest, dest
check @dest.size and not 94
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_operand_prefix, (2)
xcall x86.store_instruction@dest, (0DDh),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate <instr,postbyte>, frstord,4, fnsaved,6
calminstruction instr? dest*
call x86.require.80387
call x86.parse_operand@dest, dest
check @dest.size and not 108
jyes invalid_operand_size
check @dest.type = 'mem'
jno invalid_operand
xcall x86.store_operand_prefix, (4)
xcall x86.store_instruction@dest, (0DDh),(postbyte)
exit
invalid_operand_size:
err 'invalid operand size'
exit
invalid_operand:
err 'invalid operand'
end calminstruction
end iterate
iterate op, stenvw, stenvd, savew, saved
calminstruction f#op? dest*
asm fwait?
asm fn#op? dest
end calminstruction
end iterate

View File

@ -0,0 +1,33 @@
iterate <instr,supp>, gf2p8mulb,0CFh
macro instr? dest*,src*
require GFNI
SSE.basic_instruction 66h,<38h,supp>,16,dest,src
end macro
end iterate
iterate <instr,supp>, gf2p8affineinvqb,0CFh, gf2p8affineqb,0CEh
macro instr? dest*,src*,imm*
require GFNI
SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm
end macro
end iterate
iterate <instr,opcode>, gf2p8mulb,0CFh
macro v#instr? dest*,src*,src2*&
require GFNI
AVX_512.basic_instruction VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, gf2p8affineinvqb,0CFh, gf2p8affineqb,0CEh
macro v#instr? dest*,src*,src2*,imm*&
require GFNI
AVX_512.basic_instruction_bcst_imm8 VEX_66_0F3A_W1,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2,imm
end macro
end iterate

View File

@ -0,0 +1,164 @@
element MMX.reg
repeat 8, i:0
element mm#i? : MMX.reg + i
end repeat
iterate context, @dest,@src,@src2,@aux
namespace context
calminstruction MMX.parse_operand#context operand
call x86.parse_operand#context, operand
check type = 'imm' & size = 0
jno done
check imm eq 1 elementof imm & 1 metadataof imm relativeto MMX.reg
jno done
compute type, 'mmreg'
compute mod, 11b
compute rm, 1 metadataof imm - MMX.reg
compute size, 8
done:
end calminstruction
calminstruction MMX.select_operand_prefix#context size*
check size = 16
jno no_prefix
call x86.require.SSE2
compute prefix, 66h
exit
no_prefix:
check size <> 8
jno done
err 'invalid operand size'
done:
end calminstruction
end namespace
end iterate
calminstruction MMX.basic_instruction ext,dest,src
call x86.require.MMX
call SSE.parse_operand@dest, dest
call SSE.parse_operand@src, src
check @src.size and not @dest.size
jno size_ok
err 'operand sizes do not match'
size_ok:
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
jno invalid_combination_of_operands
call MMX.select_operand_prefix@src, @dest.size
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
calminstruction MMX.bit_shift_instruction ext,dest,src
call x86.require.MMX
call SSE.parse_operand@dest, dest
call SSE.parse_operand@src, src
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
jyes mmreg_rm
check @dest.type = 'mmreg' & @src.type = 'imm'
jyes mmreg_imm
err 'invalid combination of operands'
exit
mmreg_rm:
check @src.size and not @dest.size
jno mmreg_rm_ok
err 'operand sizes do not match'
mmreg_rm_ok:
call MMX.select_operand_prefix@src, @dest.size
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm
exit
mmreg_imm:
check @src.size and not 1
jno rm_mmreg_ok
err 'invalid operand size'
rm_mmreg_ok:
local iext, irm
compute iext, 70h+(ext and 0Fh)
compute irm, ((ext shr 4)-0Ch) shl 1
call MMX.select_operand_prefix@dest, @dest.size
xcall x86.store_instruction@dest, <0Fh,iext>,irm,byte,@src.imm
end calminstruction
iterate <instr,opcode>, punpcklbw,60h, punpcklwd,61h, punpckldq,62h, packsswb,63h, pcmpgtb,64h, pcmpgtw,65h, pcmpgtd,66h, packuswb,67h, punpckhbw,68h, \
punpckhwd,69h, punpckhdq,6Ah, packssdw,6Bh, pcmpeqb,74h, pcmpeqw,75h, pcmpeqd,76h, pmullw,0D5h, psubusb,0D8h, psubusw,0D9h, \
pand,0DBh, paddusb,0DCh, paddusw,0DDh, pandn,0DFh, pmulhw,0E5h, psubsb,0E8h, psubsw,0E9h, por,0EBh, paddsb,0ECh, paddsw,0EDh, \
pxor,0EFh, pmaddwd,0F5h, psubb,0F8h, psubw,0F9h, psubd,0FAh, paddb,0FCh, paddw,0FDh, paddd,0FEh
macro instr? dest*,src*
MMX.basic_instruction opcode,dest,src
end macro
end iterate
calminstruction movq? dest*,src*
call x86.require.MMX
call MMX.parse_operand@dest, dest
call MMX.parse_operand@src, src
check (@src.size or @dest.size) and not 8
jno size_ok
err 'invalid operand size'
size_ok:
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
jyes mmreg_mem
check @dest.type = 'mem' & @src.type = 'mmreg'
jyes mem_mmreg
err 'invalid combination of operands'
exit
mmreg_mem:
xcall x86.store_instruction@src, <0Fh,6Fh>,@dest.rm
exit
mem_mmreg:
xcall x86.store_instruction@dest, <0Fh,7Fh>,@src.rm
exit
end calminstruction
calminstruction movd? dest*,src*
call x86.require.MMX
call MMX.parse_operand@dest, dest
call MMX.parse_operand@src, src
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg')
jyes mmreg_rm
check (@dest.type = 'mem' | @dest.type = 'reg') & @src.type = 'mmreg'
jyes rm_mmreg
err 'invalid combination of operands'
exit
mmreg_rm:
check @src.size and not 4
jno mmreg_rm_ok
err 'invalid operand size'
mmreg_rm_ok:
xcall x86.store_instruction@src, <0Fh,6Eh>,@dest.rm
exit
rm_mmreg:
check @dest.size and not 4
jno rm_mmreg_ok
err 'invalid operand size'
rm_mmreg_ok:
xcall x86.store_instruction@dest, <0Fh,7Eh>,@src.rm
end calminstruction
iterate <instr,opcode>, psrlw,0D1h, psrld,0D2h, psrlq,0D3h, psrad,0E2h, psraw,0E1h, psllw,0F1h, pslld,0F2h, psllq,0F3h
macro instr? dest*,src*
MMX.bit_shift_instruction opcode,dest,src
end macro
end iterate
calminstruction emms?
call x86.require.MMX
emit 1, 0Fh
emit 1, 77h
end calminstruction

View File

@ -0,0 +1,194 @@
element MPX.bnd
repeat 4, i:0
element bnd#i? : MPX.bnd + i
end repeat
macro MPX.parse_operand ns,op
x86.parse_operand#ns op
if ns.type = 'imm' & ns.size = 0 & ns.imm eq 1 elementof ns.imm & 1 metadataof ns.imm relativeto MPX.bnd
ns.type = 'bnd'
ns.mod = 11b
ns.rm = 1 metadataof ns.imm - MPX.bnd
ns.size = 0
end if
end macro
macro MPX.parse_sib_operand ns,op&
match [b=,si], op
ns.split = 1
ns.segment_prefix = 0
ns.prefix = 0
ns.opcode_prefix = 0
ns.rex_prefix = 0
ns.size = 0
ns.type = 'mem'
ns.base_part = +b
ns.index_part = +si
if x86.mode = 64
ns.mode = 64
ns.address_registers_type = x86.r64
else
ns.mode = 32
ns.address_registers_type = x86.r32
end if
ns.base_registers = 0
ns.index_registers = 0
repeat elementsof ns.base_part
if % metadataof ns.base_part relativeto x86.r16 | % metadataof ns.base_part relativeto x86.r32 | % metadataof ns.base_part relativeto x86.r64 | % metadataof ns.address relativeto x86.ip
ns.base_registers = ns.base_registers + % elementof ns.base_part * % scaleof ns.base_part
end if
end repeat
repeat elementsof ns.index_part
if % metadataof ns.index_part relativeto x86.r16 | % metadataof ns.index_part relativeto x86.r32 | % metadataof ns.index_part relativeto x86.r64 | % metadataof ns.address relativeto x86.ip
ns.index_registers = ns.index_registers + % elementof ns.index_part * % scaleof ns.index_part
end if
end repeat
ns.displacement = ns.base_part - ns.base_registers + ns.index_part - ns.index_registers
if ns.index_registers eq 0
ns.index = 4
ns.scale = 1
else if elementsof ns.index_registers = 1 & 1 metadataof ns.index_registers relativeto ns.address_registers_type & 1 metadataof ns.index_registers - ns.address_registers_type <> 4
ns.index = 1 metadataof ns.index_registers - ns.address_registers_type
ns.scale = 1 scaleof ns.index_registers
else
err 'invalid address'
end if
if ns.base_registers eq 0
ns.rm = 4
ns.base = 5
ns.index_only = 1
else if ns.base_registers eq 1 elementof ns.base_registers & 1 metadataof ns.base_registers relativeto ns.address_registers_type
ns.base = 1 metadataof ns.base_registers - ns.address_registers_type
if ns.index = 4 & ns.base <> 4
ns.rm = ns.base
else
ns.rm = 4
end if
ns.index_only = 0
else
err 'invalid address'
end if
ns.auto_relative = 0
ns.displacement_size = 4
ns.mod = 2
if ns.index_only
ns.mod = 0
else if ns.displacement relativeto 0
if ns.displacement = 0 & ns.rm and 111b <> 5 & (ns.rm <> 4 | ns.base and 111b <> 5)
ns.displacement_size = 0
ns.mod = 0
else if ns.displacement < 80h & ns.displacement >= -80h
ns.displacement_size = 1
ns.mod = 1
else if ns.displacement - 1 shl ns.mode >= -80h & ns.displacement < 1 shl ns.mode
ns.displacement = ns.displacement - 1 shl ns.mode
ns.displacement_size = 1
ns.mod = 1
end if
end if
else
ns.split = 0
x86.parse_operand#ns op
end match
end macro
macro bndmk? dest*,src*&
require MPX
MPX.parse_operand @dest,dest
MPX.parse_sib_operand @src,src
if @dest.type = 'bnd' & @src.type = 'mem'
if @src.split & ~ 0 scaleof @src.base_part eq 0
err 'invalid base address'
end if
if (x86.mode = 64 & @src.size and not 8) | (x86.mode < 64 & @src.size and not 4)
err 'invalid operand size'
end if
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,1Bh>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro bndmov? dest*,src*
require MPX
MPX.parse_operand @dest,dest
MPX.parse_operand @src,src
if @dest.type = 'bnd' & (@src.type = 'bnd' | @src.type = 'mem')
if (x86.mode = 64 & @src.size and not 16) | (x86.mode < 64 & @src.size and not 8)
err 'invalid operand size'
end if
if @src.type = 'mem' & @src.mode <> x86.mode
err 'invalid address'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,1Ah>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'bnd'
if (x86.mode = 64 & @dest.size and not 16) | (x86.mode < 64 & @dest.size and not 8)
err 'invalid operand size'
end if
if @dest.type = 'mem' & @dest.mode <> x86.mode
err 'invalid address'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,1Bh>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,prefix,ext>, bndcl,0F3h,1Ah, bndcu,0F2h,1Ah, bndcn,0F2h,1Bh
macro instr? dest*,src*
require MPX
MPX.parse_operand @dest,dest
x86.parse_operand @src,src
if @dest.type = 'bnd' & (@src.type = 'reg' | @src.type = 'mem')
if (x86.mode = 64 & @src.size and not 8) | (x86.mode < 64 & @src.size and not 4)
err 'invalid operand size'
end if
if @src.type = 'mem' & @src.mode <> x86.mode
err 'invalid address'
end if
@src.opcode_prefix = prefix
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid operand'
end if
end macro
end iterate
macro bndldx? dest*,src*&
require MPX
MPX.parse_operand @dest,dest
MPX.parse_sib_operand @src,src
if @dest.type = 'bnd' & @src.type = 'mem'
if @src.scale > 1 | ( @src.split & ~ 0 scaleof @src.index_part eq 0 )
err 'invalid index'
end if
x86.store_instruction@src <0Fh,1Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro bndstx? operands*&
require MPX
match [dest] =, src, operands
MPX.parse_sib_operand @dest,[dest]
MPX.parse_operand @src,src
if @dest.type = 'mem' & @src.type = 'bnd'
if @dest.scale > 1 | ( @dest.split & ~ 0 scaleof @dest.index_part eq 0 )
err 'invalid index'
end if
x86.store_instruction@dest <0Fh,1Bh>,@src.rm
else
err 'invalid combination of operands'
end if
else
err 'invalid combination of operands'
end match
end macro

View File

@ -0,0 +1,24 @@
macro pclmulqdq? dest*,src*,imm*
require PCLMULQDQ
SSE.basic_instruction_imm8 66h,<3Ah,44h>,16,dest,src,imm
end macro
macro vpclmulqdq? dest*,src*,src2*,aux*
require VPCLMULQDQ
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm'
if @aux.size and not 1
err 'invalid operand size'
else if @dest.size <> @src.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
@src2.memsize = 0
AVX_512.store_instruction@src2 @dest.size,VEX_66_0F3A_W0,EVEX_AS_VEX+EVEX_VL,44h,@dest.mask,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,444 @@
element SSE.reg
repeat 16, i:0
element xmm#i? : SSE.reg + i
end repeat
iterate context, @dest,@src,@src2,@aux
namespace context
calminstruction SSE.parse_operand#context operand
call x86.parse_operand#context, operand
check type = 'imm' & size = 0
jno done
check imm eq 1 elementof imm & 1 metadataof imm relativeto MMX.reg
jyes mm_register
check imm eq 1 elementof imm & 1 metadataof imm relativeto SSE.reg
jyes xmm_register
exit
mm_register:
compute rm, 1 metadataof imm - MMX.reg
compute size, 8
jump export_mmreg
xmm_register:
compute rm, 1 metadataof imm - SSE.reg
compute size, 16
export_mmreg:
compute type, 'mmreg'
compute mod, 11b
done:
end calminstruction
end namespace
end iterate
calminstruction SSE.basic_instruction pre,ext,msize,dest,src
call x86.require.SSE
call SSE.parse_operand@dest, dest
call SSE.parse_operand@src, src
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
jno invalid_combination_of_operands
check @dest.size <> 16 | (@src.type = 'mem' & @src.size and not msize) | (@src.type = 'mmreg' & @src.size <> 16)
jno size_ok
err 'invalid operand size'
size_ok:
compute @src.opcode_prefix, pre
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
calminstruction SSE.basic_instruction_imm8 pre,ext,msize,dest,src,aux
call x86.require.SSE
call SSE.parse_operand@dest, dest
call SSE.parse_operand@src, src
call x86.parse_operand@aux, aux
check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
jno invalid_combination_of_operands
check @dest.size <> 16 | (@src.type = 'mem' & @src.size and not msize) | (@src.type = 'mmreg' & @src.size <> 16) | @aux.size and not 1
jno size_ok
err 'invalid operand size'
size_ok:
compute @src.opcode_prefix, pre
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm,byte,@aux.imm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
end calminstruction
iterate <instr,ext>, sqrt,51h, rsqrt,52h, rcp,53h, add,58h, mul,59h, sub,5Ch, min,5Dh, div,5Eh, max,5Fh
macro instr#ps? dest*,src*
SSE.basic_instruction 0,ext,16,dest,src
end macro
macro instr#ss? dest*,src*
SSE.basic_instruction 0F3h,ext,4,dest,src
end macro
end iterate
iterate <instr,ext>, and,54h, andn,55h, or,56h, xor,57h, unpckl,14h, unpckh,15h
macro instr#ps? dest*,src*
SSE.basic_instruction 0,ext,16,dest,src
end macro
end iterate
macro cmpps? dest*,src*,code*
SSE.basic_instruction_imm8 0,0C2h,16,dest,src,code
end macro
macro cmpss? dest*,src*,code*
SSE.basic_instruction_imm8 0F3h,0C2h,4,dest,src,code
end macro
iterate <cond,code>, eq,0, lt,1, le,2, unord,3, neq,4, nlt,5, nle,6, ord,7
macro cmp#cond#ps? dest*,src*
cmpps dest,src,code
end macro
macro cmp#cond#ss? dest*,src*
cmpss dest,src,code
end macro
end iterate
macro shufps? dest*,src*,imm*
SSE.basic_instruction_imm8 0,0C6h,16,dest,src,imm
end macro
iterate <instr,ext>, movaps,28h, movups,10h
macro instr? dest*,src*
require SSE+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
x86.store_instruction@src <0Fh,ext>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
x86.store_instruction@dest <0Fh,ext+1>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, movlps,12h, movhps,16h
macro instr? dest*,src*
require SSE+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if @dest.size <> 16 | @src.size and not 8
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,ext>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 8 | @src.size <> 16
err 'invalid operand size'
end if
x86.store_instruction@dest <0Fh,ext+1>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, movhlps,12h, movlhps,16h
macro instr? dest*,src*
require SSE+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
if @dest.type = 'mmreg' & @src.type = 'mmreg'
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro movss? dest*,src*
require SSE+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 4) | (@src.type = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,10h>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 4 | @src.size <> 16
err 'invalid operand size'
end if
@dest.opcode_prefix = 0F3h
x86.store_instruction@dest <0Fh,11h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro movntps? dest*,src*
require SSE+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mem' & @src.type = 'mmreg'
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
x86.store_instruction@dest <0Fh,2Bh>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro movmskps? dest*,src*
require SSE+
x86.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mmreg'
if (@dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | @src.size <> 16
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,50h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,ext>, ucomiss,2Eh, comiss,2Fh
macro instr? dest*,src*
require SSE+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 4) | (@src.type = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro cvtpi2ps? dest*,src*
require SSE+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | @src.size and not 8
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,2Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro cvtsi2ss? dest*,src*
require SSE+
SSE.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg')
if @src.size = 0
err 'operand size not specified'
else if @dest.size <> 16 | @src.size < 4
err 'invalid operand size'
end if
x86.select_operand_prefix@src @src.size
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,2Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,ext>, cvttps2pi,2Ch, cvtps2pi,2Dh
macro instr? dest*,src*
require SSE+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 8 | (@src.size = 'mem' & @src.size and not 8) | (@src.size = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, cvttss2si,2Ch, cvtss2si,2Dh
macro instr? dest*,src*
require SSE+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size < 4 | (@src.size = 'mem' & @src.size and not 4) | (@src.size = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
x86.select_operand_prefix@src @dest.size
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, pminub,0DAh, pmaxub,0DEh, pavgb,0E0h, pavgw,0E3h, pmulhuw,0E4h, pminsw,0EAh, pmaxsw,0EEh, psadbw,0F6h
macro instr? dest*,src*
require SSE+
MMX.basic_instruction ext,dest,src
end macro
end iterate
macro pinsrw? dest*,src*,sel*
require SSE+
MMX.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'mmreg' & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm'
if (@src.type = 'reg' & @src.size <> 4) | (@src.type = 'mem' & @src.size and not 2) | @aux.size and not 1
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0C4h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrw? dest*,src*,sel*
require SSE+
x86.parse_operand@dest dest
MMX.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size <> 4 | @aux.size and not 1
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0C5h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pshufw? dest*,src*,sel*
require SSE+
MMX.parse_operand@dest dest
MMX.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if @src.size and not 8 | @aux.size and not 1
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,70h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pmovmskb? dest*,src*
require SSE+
x86.parse_operand@dest dest
MMX.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mmreg'
if @dest.size <> 4
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0D7h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro movntq? dest*,src*
require SSE+
MMX.parse_operand@dest dest
MMX.parse_operand@src src
if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 8
err 'invalid operand size'
end if
x86.store_instruction@dest <0Fh,0E7h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro maskmovq? src*,sel*
require SSE+
MMX.parse_operand@src src
MMX.parse_operand@aux sel
if @src.type = 'mmreg' & @aux.type = 'mmreg'
x86.store_instruction@aux <0Fh,0F7h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,postbyte>, prefetchnta,0, prefetcht0,1, prefetcht1,2, prefetcht2,3
macro instr? src*
require SSE+
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 1
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,18h>,postbyte
else
err 'invalid operand'
end if
end macro
end iterate
macro sfence?
db 0Fh,0AEh,0F8h
end macro
iterate <instr,postbyte>, fxsave,0, fxrstor,1
macro instr? src*
require SSE+
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 512
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0AEh>,postbyte
else
err 'invalid operand'
end if
end macro
end iterate
iterate <instr,postbyte>, ldmxcsr,2, stmxcsr,3
macro instr? src*
require SSE+
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 4
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0AEh>,postbyte
else
err 'invalid operand'
end if
end macro
end iterate

View File

@ -0,0 +1,579 @@
iterate <instr,ext>, sqrt,51h, rsqrt,52h, rcp,53h, add,58h, mul,59h, sub,5Ch, min,5Dh, div,5Eh, max,5Fh
macro instr#pd? dest*,src*
require SSE2+
SSE.basic_instruction 66h,ext,16,dest,src
end macro
macro instr#sd? dest*,src*
require SSE2+
SSE.basic_instruction 0F2h,ext,8,dest,src
end macro
end iterate
iterate <instr,ext>, and,54h, andn,55h, or,56h, xor,57h, unpckl,14h, unpckh,15h
macro instr#pd? dest*,src*
require SSE2+
SSE.basic_instruction 66h,ext,16,dest,src
end macro
end iterate
macro cmppd? dest*,src*,code*
require SSE2+
SSE.basic_instruction_imm8 66h,0C2h,16,dest,src,code
end macro
macro SSE.cmpsd? dest*,src*,code*
require SSE2+
SSE.basic_instruction_imm8 0F2h,0C2h,8,dest,src,code
end macro
calminstruction cmpsd? args&
match , args
jno sse
xcall x86.store_operand_prefix, (4)
emit 1, 0A7h
exit
sse:
arrange args, =SSE.=cmpsd args
assemble args
end calminstruction
iterate <cond,code>, eq,0, lt,1, le,2, unord,3, neq,4, nlt,5, nle,6, ord,7
macro cmp#cond#pd? dest*,src*
require SSE2+
cmppd dest,src,code
end macro
macro cmp#cond#sd? dest*,src*
require SSE2+
cmpsd dest,src,code
end macro
end iterate
macro shufpd? dest*,src*,imm*
require SSE2+
SSE.basic_instruction_imm8 66h,0C6h,16,dest,src,imm
end macro
iterate <instr,ext>, movapd,28h, movupd,10h
macro instr? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,ext+1>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, movlpd,12h, movhpd,16h
macro instr? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if @dest.size <> 16 | @src.size and not 8
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 8 | @src.size <> 16
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,ext+1>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro SSE.movsd? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
@src.opcode_prefix = 0F2h
x86.store_instruction@src <0Fh,10h>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 8 | @src.size <> 16
err 'invalid operand size'
end if
@dest.opcode_prefix = 0F2h
x86.store_instruction@dest <0Fh,11h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
calminstruction movsd? args&
match , args
jno sse
xcall x86.store_operand_prefix, (4)
emit 1, 0A5h
exit
sse:
arrange args, =SSE.=movsd args
assemble args
end calminstruction
iterate <instr,pre>, movdqa,66h, movdqu,0F3h
macro instr? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
@src.opcode_prefix = pre
x86.store_instruction@src <0Fh,6Fh>,@dest.rm
else if @dest.type = 'mem' & @src.type = 'mmreg'
@dest.opcode_prefix = pre
x86.store_instruction@dest <0Fh,7Fh>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, movntpd,2Bh, movntdq,0E7h
macro instr? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mem' & @src.type = 'mmreg'
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,ext>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro movmskpd? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mmreg'
if (@dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | @src.size <> 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,50h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro maskmovdqu? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mmreg'
if (@dest.size or @src.size) <> 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,0F7h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,ext>, ucomisd,2Eh, comisd,2Fh
macro instr? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> 16)
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro cvtps2pd? dest*,src*
require SSE2+
SSE.basic_instruction 0,5Ah,8,dest,src
end macro
macro cvtpd2ps? dest*,src*
require SSE2+
SSE.basic_instruction 66h,5Ah,16,dest,src
end macro
macro cvtsd2ss? dest*,src*
require SSE2+
SSE.basic_instruction 0F2h,5Ah,8,dest,src
end macro
macro cvtss2sd? dest*,src*
require SSE2+
SSE.basic_instruction 0F3h,5Ah,4,dest,src
end macro
macro cvtdq2ps? dest*,src*
require SSE2+
SSE.basic_instruction 0,5Bh,16,dest,src
end macro
macro cvtps2dq? dest*,src*
require SSE2+
SSE.basic_instruction 66h,5Bh,16,dest,src
end macro
macro cvttps2dq? dest*,src*
require SSE2+
SSE.basic_instruction 0F3h,5Bh,16,dest,src
end macro
macro cvttpd2dq? dest*,src*
require SSE2+
SSE.basic_instruction 66h,0E6h,16,dest,src
end macro
macro cvtpd2dq? dest*,src*
require SSE2+
SSE.basic_instruction 0F2h,0E6h,16,dest,src
end macro
macro cvtdq2pd? dest*,src*
require SSE2+
SSE.basic_instruction 0F3h,0E6h,8,dest,src
end macro
macro movdq2q? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mmreg'
if @dest.size <> 8 | @src.size <> 16
err 'invalid operand size'
end if
@src.opcode_prefix = 0F2h
x86.store_instruction@src <0Fh,0D6h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro movq2dq? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mmreg'
if @dest.size <> 16 | @src.size <> 8
err 'invalid operand size'
end if
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,0D6h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro cvtpi2pd? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 16 | @src.size and not 8
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,2Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro cvtsi2sd? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg')
if @src.size = 0
err 'operand size not specified'
else if @dest.size <> 16 | @src.size < 4
err 'invalid operand size'
end if
x86.select_operand_prefix@src @src.size
@src.opcode_prefix = 0F2h
x86.store_instruction@src <0Fh,2Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,ext>, cvttpd2pi,2Ch, cvtpd2pi,2Dh
macro instr? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 8 | @src.size and not 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, cvttsd2si,2Ch, cvtsd2si,2Dh
macro instr? dest*,src*
require SSE2+
x86.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size < 4 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <>16)
err 'invalid operand size'
end if
x86.select_operand_prefix@src @dest.size
@src.opcode_prefix = 0F2h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, paddq,0D4h, pmuludq,0F4h, psubq,0FBh
macro instr? dest*,src*
require SSE2+
MMX.basic_instruction ext,dest,src
end macro
end iterate
macro movq? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> @dest.size)
err 'invalid operand size'
end if
if @dest.size = 8
x86.store_instruction@src <0Fh,6Fh>,@dest.rm
else
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,7Eh>,@dest.rm
end if
else if @dest.type = 'mem' & @src.type = 'mmreg'
if @dest.size and not 8
err 'invalid operand size'
end if
if @src.size = 8
x86.store_instruction@dest <0Fh,7Fh>,@src.rm
else
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,0D6h>,@src.rm
end if
else if @dest.type = 'reg' & @src.type = 'mmreg'
if @dest.size <> 8
err 'invalid operand size'
end if
if @src.size = 16
@dest.opcode_prefix = 66h
end if
@dest.prefix = 48h
x86.store_instruction@dest <0Fh,7Eh>,@src.rm
else if @dest.type = 'mmreg' & @src.type = 'reg'
if @src.size <> 8
err 'invalid operand size'
end if
if @dest.size = 16
@src.opcode_prefix = 66h
end if
@src.prefix = 48h
x86.store_instruction@src <0Fh,6Eh>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro movd? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg')
if @src.size and not 4
err 'invalid operand size'
end if
MMX.select_operand_prefix@src @dest.size
x86.store_instruction@src <0Fh,6Eh>,@dest.rm
else if (@dest.type = 'mem' | @dest.type = 'reg') & @src.type = 'mmreg'
if @dest.size and not 4
err 'invalid operand size'
end if
MMX.select_operand_prefix@dest @src.size
x86.store_instruction@dest <0Fh,7Eh>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro pinsrw? dest*,src*,sel*
require SSE2+
SSE.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'mmreg' & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm'
if (@src.type = 'reg' & @src.size <> 4) | (@src.type = 'mem' & @src.size and not 2) | @aux.size and not 1
err 'invalid operand size'
end if
MMX.select_operand_prefix@src @dest.size
x86.store_instruction@src <0Fh,0C4h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrw? dest*,src*,sel*
require SSE2+
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm'
if x86.mode = 64 & @dest.size = 8
@dest.size = 4
end if
if @dest.size <> 4 | @aux.size and not 1
err 'invalid operand size'
end if
MMX.select_operand_prefix@src @src.size
x86.store_instruction@src <0Fh,0C5h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,pre>, pshufd,66h, pshuflw,0F2h, pshufhw,0F3h
macro instr? dest*,src*,sel*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if @dest.size <> 16 | @src.size and not 16 | @aux.size and not 1
err 'invalid operand size'
end if
@src.opcode_prefix = pre
x86.store_instruction@src <0Fh,70h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro pmovmskb? dest*,src*
require SSE2+
x86.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mmreg'
if @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)
err 'invalid operand size'
end if
MMX.select_operand_prefix@src @src.size
x86.store_instruction@src <0Fh,0D7h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,postbyte>, psrldq,3, pslldq,7
macro instr? dest*,cnt*
require SSE2+
SSE.parse_operand@dest dest
x86.parse_operand@aux cnt
if @dest.type = 'mmreg' & @aux.type = 'imm'
if @dest.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,73h>,postbyte,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ext>, punpcklqdq,6Ch, punpckhqdq,6Dh
macro instr? dest*,src*
require SSE2+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,ext>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro movnti? dest*,src*
require SSE2+
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'mem' & @src.type = 'reg'
if @dest.size and not @src.size
err 'operand sizes do not match'
else if @src.size <> 4 & @src.size <> 8
err 'invalid operand size'
end if
x86.select_operand_prefix@dest @src.size
x86.store_instruction@dest <0Fh,0C3h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro clflush? src*
require SSE2+
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 1
err 'invalid operand size'
end if
x86.store_instruction@src <0Fh,0AEh>,7
else
err 'invalid operand'
end if
end macro
macro lfence?
require SSE2+
db 0Fh,0AEh,0E8h
end macro
macro mfence?
require SSE2+
db 0Fh,0AEh,0F0h
end macro

View File

@ -0,0 +1,84 @@
macro fisttp? src*
require SSE3+
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size = 2
x86.store_instruction@src 0DFh,1
else if @src.size = 4
x86.store_instruction@src 0DBh,1
else if @src.size = 8
x86.store_instruction@src 0DDh,1
else if @src.size
err 'invalid operand size'
else
err 'operand size not specified'
end if
else
err 'invalid operand'
end if
end macro
iterate <instr,ext>, addsub,0D0h, hadd,7Ch, hsub,7Dh
macro instr#pd? dest*,src*
require SSE3+
SSE.basic_instruction 66h,ext,16,dest,src
end macro
macro instr#ps? dest*,src*
require SSE3+
SSE.basic_instruction 0F2h,ext,16,dest,src
end macro
end iterate
iterate <instr,ext>, movsldup,12h, movshdup,16h
macro instr? dest*,src*
require SSE3+
SSE.basic_instruction 0F3h,ext,16,dest,src
end macro
end iterate
macro movddup? dest*,src*
require SSE3+
SSE.basic_instruction 0F2h,12h,8,dest,src
end macro
macro lddqu? dest*,src*
require SSE3+
SSE.parse_operand@src dest
SSE.parse_operand@src src
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
if @dest.type = 'mmreg' & @src.type = 'mem'
@src.opcode_prefix = 0F2h
x86.store_instruction@src <0Fh,0F0h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,supp>, pshufb,0, phaddw,1, phaddd,2, phaddsw,3, pmaddubsw,4, phsubw,5, phsubd,6, phsubsw,7, psignb,8, psignw,9, psignd,0Ah, pmulhrsw,0Bh, pabsb,1Ch, pabsw,1Dh, pabsd,1Eh
macro instr? dest*,src*
require SSSE3+
MMX.basic_instruction <38h,supp>,dest,src
end macro
end iterate
macro palignr? dest*,src*,aux*
require SSSE3+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if @src.size and not @dest.size
err 'operand sizes do not match'
end if
if @aux.size and not 1
err 'invalid operand size'
end if
MMX.select_operand_prefix@src @dest.size
x86.store_instruction@src <0Fh,3Ah,0Fh>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,278 @@
iterate <instr,supp>, ptest,17h, pmuldq,28h, pcmpeqq,29h, packusdw,2Bh, pminsb,38h, pminsd,39h, pminuw,3Ah, pminud,3Bh, pmaxsb,3Ch, pmaxsd,3Dh, pmaxuw,3Eh, pmaxud,3Fh, pmulld,40h, phminposuw,41h
macro instr? dest*,src*
require SSE4.1+
SSE.basic_instruction 66h,<38h,supp>,16,dest,src
end macro
end iterate
iterate <instr,supp>, roundps,08h, roundpd,09h, roundss,0Ah, roundsd,0Bh, blendps,0Ch, blendpd,0Dh, pblendw,0Eh, dpps,40h, dppd,41h, mpsadbw,42h
macro instr? dest*,src*,imm*
require SSE4.1+
SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm
end macro
end iterate
iterate <instr,supp>, pblendvb,10h, blendvps,14h, blendvpd,15h
macro instr? dest*,src*,sel*
require SSE4.1+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
SSE.parse_operand@aux sel
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'mmreg' & @aux.size = 16 & @aux.rm = 0
if @dest.size or @src.size and not 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,38h,supp>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <conv,code,msize>, bw,0,8, bd,1,4, bq,2,2, wd,3,8, wq,4,4, dq,5,8
macro pmovsx#conv? dest*,src*
require SSE4.1+
SSE.basic_instruction 66h,<38h,20h+code>,msize,dest,src
end macro
macro pmovzx#conv? dest*,src*
require SSE4.1+
SSE.basic_instruction 66h,<38h,30h+code>,msize,dest,src
end macro
end iterate
macro insertps? dest*,src*,sel*
require SSE4.1+
SSE.basic_instruction_imm8 66h,<3Ah,21h>,4,dest,src,sel
end macro
macro extractps? dest*,src*,sel*
require SSE4.1+
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm'
if x86.mode = 64 & @dest.size = 8
@dest.size = 4
end if
if @dest.size <> 4 | @src.size and not 16 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,3Ah,17h>,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pinsrb? dest*,src*,sel*
require SSE4.1+
SSE.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'mmreg' & @dest.size = 16) & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm'
if (@src.type = 'reg' & @src.size <> 4) | (@src.type = 'mem' & @src.size and not 1) | @aux.size and not 1
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,3Ah,20h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pinsrd? dest*,src*,sel*
require SSE4.1+
SSE.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'mmreg' & @dest.size = 16) & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm'
if @src.size and not 4 | @aux.size and not 1
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,3Ah,22h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pinsrq? dest*,src*,sel*
require SSE4.1+
SSE.parse_operand@dest dest
x86.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'mmreg' & @dest.size = 16) & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm'
if @src.size and not 8 | @aux.size and not 1
err 'invalid operand size'
end if
if x86.mode < 64
err 'instruction requires long mode'
end if
@src.opcode_prefix = 66h
@src.rex_prefix = 48h
x86.store_instruction@src <0Fh,3Ah,22h>,@dest.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrb? dest*,src*,sel*
require SSE4.1+
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'reg' | @dest.type = 'mem') & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm'
if x86.mode = 64 & @dest.type = 'reg' & @dest.size = 8
@dest.size = 4
end if
if (@dest.type = 'reg' & @dest.size <> 4) | (@dest.size = 'mem' & @dest.size and not 1) | @aux.size and not 1
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,3Ah,14h>,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrw? dest*,src*,sel*
require SSE4.1+
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm'
if x86.mode = 64 & @dest.size = 8
@dest.size = 4
end if
if @dest.size <> 4 | @aux.size and not 1
err 'invalid operand size'
end if
MMX.select_operand_prefix@src @src.size
x86.store_instruction@src <0Fh,0C5h>,@dest.rm,1,@aux.imm
else if @dest.type = 'mem' & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm'
if @dest.size and not 2 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,3Ah,15h>,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrd? dest*,src*,sel*
require SSE4.1+
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'reg' | @dest.type = 'mem') & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm'
if x86.mode = 64 & @dest.type = 'reg' & @dest.size = 8
@dest.size = 4
end if
if @dest.size and not 4 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.opcode_prefix = 66h
x86.store_instruction@dest <0Fh,3Ah,16h>,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro pextrq? dest*,src*,sel*
require SSE4.1+
x86.parse_operand@dest dest
SSE.parse_operand@src src
x86.parse_operand@aux sel
if (@dest.type = 'reg' | @dest.type = 'mem') & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm'
if @dest.size and not 8 | @aux.size and not 1
err 'invalid operand size'
end if
if x86.mode < 64
err 'instruction requires long mode'
end if
@dest.opcode_prefix = 66h
@dest.rex_prefix = 48h
x86.store_instruction@dest <0Fh,3Ah,16h>,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro movntdqa? dest*,src*
require SSE4.1+
SSE.parse_operand@dest dest
SSE.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if (@dest.size or @src.size) and not 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,38h,2Ah>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,supp>, pcmpgtq,37h
macro instr? dest*,src*
require SSE4.2+
SSE.basic_instruction 66h,<38h,supp>,16,dest,src
end macro
end iterate
iterate <instr,supp>, pcmpestrm,60h, pcmpestri,61h, pcmpistrm,62h, pcmpistri,63h
macro instr? dest*,src*,imm*
require SSE4.2+
SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm
end macro
macro v#instr? dest*,src*,imm*
require AVX+
AVX_512.single_source_instruction_imm8 VEX_66_0F3A_W0,EVEX_FORBIDDEN,supp,16,dest,src,imm
end macro
end iterate
macro crc32? dest*,src*
require SSE4.2+
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & ( @src.type = 'reg' | @src.type = 'mem' )
if @dest.size <> 4 & ( @dest.size <> 8 | x86.mode <> 64 )
err 'invalid operand size'
end if
@src.opcode_prefix = 0F2h
if @src.size > 1
x86.select_operand_prefix@src @src.size
x86.store_instruction@src <0Fh,38h,0F1h>,@dest.rm
else if @src.size > 0
x86.store_instruction@src <0Fh,38h,0F0h>,@dest.rm
else
err 'operand size not specified'
end if
else
err 'invalid combination of operands'
end if
end macro
macro popcnt? dest*,src*
require POPCNT
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & ( @src.type = 'reg' | @src.type = 'mem' )
if @src.size and not @dest.size
err 'operand sizes do not match'
end if
@src.opcode_prefix = 0F3h
if @dest.size > 1
x86.select_operand_prefix@src @dest.size
x86.store_instruction@src <0Fh,0B8h>,@dest.rm
else
err 'invalid operand size'
end if
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,72 @@
iterate <instr,prefix,ext,postbyte>, vmxon,0F3h,0C7h,6, vmclear,66h,0C7h,6, \
vmptrld,0,0C7h,6, vmptrst,0,0C7h,7
macro instr? src*
require VMX
x86.parse_operand@src src
if @src.type = 'mem'
if @src.size and not 8
err 'invalid operand size'
else
@src.opcode_prefix = prefix
x86.store_instruction@src <0Fh,ext>,postbyte
end if
else
err 'invalid operand'
end if
end macro
end iterate
macro vmxoff?
require VMX
db 0Fh,1,0C4h
end macro
macro vmcall?
require VMX
db 0Fh,1,0C1h
end macro
macro vmlaunch?
require VMX
db 0Fh,1,0C2h
end macro
macro vmresume?
require VMX
db 0Fh,1,0C3h
end macro
macro vmread? dest*,src*
require VMX
x86.parse_operand@dest dest
x86.parse_operand@src src
if @src.type = 'reg' & (@dest.type = 'mem' | @dest.type = 'reg')
if (x86.mode < 64 & @src.size <> 4) | (x86.mode = 64 & @src.size <> 8)
err 'invalid operand size'
else if @dest.size and not @src.size
err 'operand sizes do not match'
end if
x86.store_instruction@dest <0Fh,78h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro vmwrite? dest*,src*
require VMX
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg')
if (x86.mode < 64 & @dest.size <> 4) | (x86.mode = 64 & @dest.size <> 8)
err 'invalid operand size'
else if @src.size and not @dest.size
err 'operand sizes do not match'
end if
x86.store_instruction@src <0Fh,79h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro