add flat assembler toolchain

This commit is contained in:
2024-11-24 23:13:28 -05:00
parent 99e8e4072b
commit dbfd94ea40
302 changed files with 145599 additions and 0 deletions

View File

@ -0,0 +1,21 @@
iterate <instr,pfx>, adcx,66h, adox,0F3h
macro instr? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg')
if @src.size <> 0 & @src.size <> @dest.size
err 'operand sizes do not match'
end if
if @dest.size = 8 & x86.mode = 64
@src.prefix = 48h
else if @dest.size <> 4
err 'invalid operand size'
end if
@src.opcode_prefix = pfx
x86.store_instruction@src <0Fh,38h,0F6h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,43 @@
include 'sse.inc'
iterate <instr,supp>, aesdec,0DEh, aesenc,0DCh, aesimc,0DBh, aesdeclast,0DFh, aesenclast,0DDh
macro instr? dest*,src*
SSE.basic_instruction 66h,<38h,supp>,16,dest,src
end macro
end iterate
iterate <instr,supp>, aeskeygenassist,0DFh
macro instr? dest*,src*,imm*
SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm
end macro
end iterate
if defined AVX
iterate <instr,opcode>, aesenc,0DCh, aesenclast,0DDh, aesdec,0DEh, aesdeclast,0DFh
macro v#instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,opcode,16,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, aesimc,0DBh
macro v#instr? dest*,src*
AVX.single_source_instruction VEX_66_0F38_W0,opcode,16,dest,src
end macro
end iterate
iterate <instr,opcode>, aeskeygenassist,0DFh
macro v#instr? dest*,src*,imm*
AVX.single_source_instruction_imm8 VEX_66_0F3A_W0,opcode,16,dest,src,imm
end macro
end iterate
end if

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,502 @@
if ~ defined AVX2
restore AVX2 ; this ensures that symbol cannot be forward-referenced
AVX2 = 1
include 'avx.inc'
iterate context, @dest,@src,@src2,@aux
namespace context
define visize
calminstruction AVX.parse_vsib_operand#context operand
local i, pre, suf
compute segment_prefix, 0
compute size, 0
compute displacement_size, 0
transform operand
match pre suf, operand
jno no_size_prefix
transform pre, x86
jno no_size_prefix
match :size, pre
jno no_size_prefix
arrange operand, suf
no_size_prefix:
match [address], operand
jyes memory_operand
match =ptr? address, operand
jyes memory_operand
jump invalid_operand
memory_operand:
compute type, 'mem'
match segment:address, address
jno segment_prefix_ok
check segment eq 1 elementof segment & 1 metadataof segment relativeto x86.sreg
jno invalid_operand
compute segment, 1 metadataof segment - x86.sreg
check segment >= 4
jyes segment_prefix_386
compute segment_prefix, 26h + segment shl 3
jump segment_prefix_ok
segment_prefix_386:
compute segment_prefix, 64h + segment-4
segment_prefix_ok:
match pre suf, address
jno no_address_size_prefix
transform pre, x86
jno no_address_size_prefix
match :pre, pre
jno no_address_size_prefix
arrange address, suf
check pre = 4 | pre = 8
jno invalid_address_size
compute mode, pre shl 3
no_address_size_prefix:
compute mode, 0
compute scale, 0
compute index, 0
compute base, 0
compute auto_relative, 0
check size
jyes size_override
compute size, sizeof address
size_override:
compute address, address
compute base_registers, 0
compute index_registers, 0
compute i, 1
extract_registers:
check i > elementsof address
jyes registers_extracted
check i metadataof address relativeto SSE.reg | i metadataof address relativeto AVX.reg
jyes index_term
check i metadataof address relativeto x86.r32 | i metadataof address relativeto x86.r64
jno next_term
compute base_registers, base_registers + i elementof address * i scaleof address
jump next_term
index_term:
compute index_registers, index_registers + i elementof address * i scaleof address
next_term:
compute i, i+1
jump extract_registers
registers_extracted:
compute displacement, address - base_registers - index_registers
compute auto_relative, 0
check elementsof index_registers = 1
jno invalid_address
compute scale, 1 scaleof index_registers
compute index, 0 scaleof (1 metadataof index_registers)
check scale and (scale-1) | scale > 8
jyes invalid_address
check 1 metadataof index_registers relativeto SSE.reg
jyes xmm_index
compute visize, 32
jump index_ok
xmm_index:
compute visize, 16
index_ok:
compute rm, 4
check elementsof base_registers = 1 & 1 scaleof base_registers = 1
jyes base_and_index
check elementsof base_registers = 0
jno invalid_address
compute base, 5
compute displacement_size, 4
compute mod, 0
compute mode, x86.mode
check mode > 16
jyes ready
compute mode, 32
jump ready
base_and_index:
compute base, 0 scaleof (1 metadataof base_registers)
check mode & mode <> 0 scaleof (1 metadataof (1 metadataof base_registers)) shl 3
jyes invalid_address
compute mode, 0 scaleof (1 metadataof (1 metadataof base_registers)) shl 3
setup_displacement:
check displacement relativeto 0
jno displacement_32bit
check displacement = 0 & rm and 111b <> 5 & (rm <> 4 | base and 111b <> 5)
jyes displacement_empty
check displacement < 80h & displacement >= -80h
jyes displacement_8bit
check displacement - 1 shl mode >= -80h & displacement < 1 shl mode
jyes displacement_8bit_wrap
displacement_32bit:
compute displacement_size, 4
compute mod, 2
jump ready
displacement_8bit_wrap:
compute displacement, displacement - 1 shl mode
displacement_8bit:
compute displacement_size, 1
compute mod, 1
jump ready
index_only:
compute displacement_size, 4
compute mod, 0
jump ready
displacement_empty:
compute displacement_size, 0
compute mod, 0
ready:
exit
invalid_operand:
err 'invalid operand'
exit
invalid_address:
err 'invalid address'
exit
invalid_address_size:
err 'invalid address size'
exit
end calminstruction
end namespace
end iterate
iterate <instr,opcode,asize>, vpgatherdd,90h,4, vpgatherqd,91h,8, vgatherdps,92h,4, vgatherqps,93h,8
macro instr? dest*,src*,mask*
AVX.parse_operand@dest dest
AVX.parse_vsib_operand@src src
AVX.parse_operand@aux mask
if @dest.type = 'mmreg' & @src.type = 'mem' & @aux.type = 'mmreg'
if @src.size and not 4 | (@dest.size > 16 & @dest.size * (asize shr 2) > @src.visize) | (@src.visize > 16 & @dest.size * (asize shr 2) < @src.visize)
err 'invalid operand size'
else if @aux.size <> @dest.size
err 'operand sizes do not match'
else if @dest.rm = @aux.rm | @dest.rm = @src.index | @aux.rm = @src.index
err 'disallowed combination of registers'
end if
AVX.store_instruction@src @src.visize,VEX_66_0F38_W0,opcode,@dest.rm,@aux.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode,asize>, vpgatherdq,90h,4, vpgatherqq,91h,8, vgatherdpd,92h,4, vgatherqpd,93h,8
macro instr? dest*,src*,mask*
AVX.parse_operand@dest dest
AVX.parse_vsib_operand@src src
AVX.parse_operand@aux mask
if @dest.type = 'mmreg' & @src.type = 'mem' & @aux.type = 'mmreg'
if @src.size and not 8 | (@dest.size > 16 & @dest.size * (asize shr 2) > @src.visize * 2) | (@src.visize > 16 & @dest.size * (asize shr 2) < @src.visize * 2)
err 'invalid operand size'
else if @aux.size <> @dest.size
err 'operand sizes do not match'
else if @dest.rm = @aux.rm | @dest.rm = @src.index | @aux.rm = @src.index
err 'disallowed combination of registers'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F38_W1,opcode,@dest.rm,@aux.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, packsswb,63h, packuswb,67h, packssdw,6Bh, paddb,0FCh, paddw,0FDh, paddd,0FEh, paddq,0D4h, paddsb,0ECh, paddsw,0EDh, paddusb,0DCh, paddusw,0DDh, \
pand,0DBh, pandn,0DFh, pavgb,0E0h, pavgw,0E3h, pcmpeqb,74h, pcmpeqw,75h, pcmpeqd,76h, pcmpgtb,64h, pcmpgtw,65h, pcmpgtd,66h, \
pmaddwd,0F5h, pmaxsw,0EEh, pmaxub,0DEh, pminsw,0EAh, pminub,0DAh, pmulhuw,0E4h, pmulhw,0E5h, pmullw,0D5h, pmuludq,0F4h, \
por,0EBh, psadbw,0F6h, psubb,0F8h, psubw,0F9h, psubd,0FAh, psubq,0FBh, psubsb,0E8h, psubsw,0E9h, psubusb,0D8h, psubusw,0D9h, \
punpckhbw,68h, punpckhwd,69h, punpckhdq,6Ah, punpckhqdq,6Dh, punpcklbw,60h, punpcklwd,61h, punpckldq,62h, punpcklqdq,6Ch, pxor,0EFh
macro v#instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F_W0,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, packusdw,2Bh, pcmpeqq,29h, pcmpgtq,37h, phaddw,1, phaddd,2, phaddsw,3, phsubw,5, phsubd,6, phsubsw,7, pmaddubsw,4, \
pmaxsb,3Ch, pmaxsd,3Dh, pmaxuw,3Eh, pmaxud,3Fh, pminsb,38h, pminsd,39h, pminuw,3Ah, pminud,3Bh, pmulhrsw,0Bh, pmulld,40h, pmuldq,28h, \
pshufb,0, psignb,8, psignw,9, psignd,0Ah
macro v#instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, mpsadbw,42h, palignr,0Fh, pblendd,02h
macro v#instr? dest*,src*,src2*,imm*
AVX.basic_instruction_imm8 VEX_66_0F3A_W0,opcode,0,dest,src,src2,imm
end macro
end iterate
iterate <instr,opcode>, pabsb,1Ch, pabsw,1Dh, pabsd,1Eh, pblendw,0Eh
macro v#instr? dest*,src*
AVX.single_source_instruction VEX_66_0F38_W0,opcode,0,dest,src
end macro
end iterate
iterate <instr,vex_mpw>, pshufd,VEX_66_0F_W0, pshufhw,VEX_F3_0F_W0, pshuflw,VEX_F2_0F_W0
macro v#instr? dest*,src*,imm*
AVX.single_source_instruction_imm8 vex_mpw,70h,0,dest,src,imm
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpsllvd,VEX_66_0F38_W0,47h, vpsllvq,VEX_66_0F38_W1,47h, vpsrlvd,VEX_66_0F38_W0,45h, vpsrlvq,VEX_66_0F38_W1,45h, vpsravd,VEX_66_0F38_W0,46h
macro instr? dest*,src*,src2*
AVX.basic_instruction vex_mpw,opcode,0,dest,src,src2
end macro
end iterate
macro vpblendvb? dest*,src*,src2*,mask*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
AVX.parse_operand@src2 src2
AVX.parse_operand@aux mask
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'mmreg'
if @src.size <> @dest.size | @src2.size and not @dest.size | @aux.size <> @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src2 @dest.size,VEX_66_0F3A_W0,4Ch,@dest.rm,@src.rm,1,(@aux.rm and 1111b) shl 4
else
err 'invalid combination of operands'
end if
end macro
macro vpmovmskb? dest*,src*
x86.parse_operand@dest dest
AVX.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
AVX.store_instruction@src @src.size,VEX_66_0F_W0,0D7h,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,opcode,msize>, pmovsxbw,20h,8, pmovsxbd,21h,4, pmovsxbq,22h,2, pmovsxwd,23h,8, pmovsxwq,24h,4, pmovsxdq,25h,8, \
pmovzxbw,30h,8, pmovzxbd,31h,4, pmovzxbq,32h,2, pmovzxwd,33h,8, pmovzxwq,34h,4, pmovzxdq,35h,8
macro v#instr? dest*,src*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not (msize * (@dest.size shr 4)))
err 'invalid operand size'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,opcode,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,postbyte>, pslldq,7, psrldq,3
macro v#instr dest*,src*,src2*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
x86.parse_operand@src2 src2
if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'imm'
if @src2.size and not 1
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F_W0,73h,postbyte,@dest.rm,1,@src2.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode_rrm,opcode,postbyte>, psllw,0F1h,71h,6, pslld,0F2h,72h,6, psllq,0F3h,73h,6, psraw,0E1h,71h,4, psrad,0E2h,72h,4, psrlw,0D1h,71h,2, psrld,0D2h,72h,2, psrlq,0D3h,73h,2
macro v#instr? dest*,src*,src2*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
AVX.parse_operand@src2 src2
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @src2.size and not 16
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src2 @dest.size,VEX_66_0F_W0,opcode_rrm,@dest.rm,@src.rm
else if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'imm'
if @src2.size and not 1
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F_W0,opcode,postbyte,@dest.rm,1,@src2.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro vmovntdqa? dest*,src*
AVX.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if @src.size and not @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,2Ah,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,w>, vpmaskmovd,0, vpmaskmovq,1
macro instr? dest*,src*,src2*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
AVX.parse_operand@src2 src2
if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mem'
if @src.size <> @dest.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
AVX.store_instruction@src2 @dest.size,VEX_66_0F38_W#w,8Ch,@dest.rm,@src.rm
else if @dest.type = 'mem' & @src.type = 'mmreg' & @src2.type = 'mmreg'
if @src.size <> @src2.size | @dest.size and not @src.size
err 'operand sizes do not match'
end if
AVX.store_instruction@dest @src.size,VEX_66_0F38_W#w,8Eh,@src2.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro vbroadcasti128? dest*,src*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if @dest.size <> 32 | @src.size and not 16
err 'invalid operand size'
end if
AVX.store_instruction@src 32,VEX_66_0F38_W0,5Ah,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro vextracti128? dest*,src*,aux*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
x86.parse_operand@aux aux
if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size and not 16 | @src.size <> 32 | @aux.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@dest 32,VEX_66_0F3A_W0,39h,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vinserti128? dest*,src*,src2*,aux*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
AVX.parse_operand@src2 src2
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mmreg' | @src2.type = 'mem') & @aux.type = 'imm'
if @dest.size <> 32 | @src.size <> 32 | @src2.size and not 16 | @aux.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@src2 32,VEX_66_0F3A_W0,38h,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vperm2i128? dest*,src*,src2*,imm*
AVX.basic_instruction_imm8 VEX_66_0F3A_W0,46h,32,dest,src,src2,imm
end macro
iterate <instr,opcode,msize>, vbroadcastss,18h,4, vpbroadcastb,78h,1, vpbroadcastw,79h,2, vpbroadcastd,58h,4, vpbroadcastq,59h,8
macro instr? dest*,src*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if (@src.type='mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not msize)
err 'invalid operand size'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,opcode,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro vbroadcastsd? dest*,src*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if @dest.size <> 32 | (@src.type='mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not 8)
err 'invalid operand size'
end if
AVX.store_instruction@src 32,VEX_66_0F38_W0,19h,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,opcode>, vpermq,0, vpermpd,1
macro instr? dest*,src*,imm*
AVX.single_source_instruction_imm8 VEX_66_0F3A_W1,opcode,32,dest,src,imm
end macro
end iterate
iterate <instr,opcode>, vpermd,36h, vpermps,16h
macro instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,opcode,32,dest,src,src2
end macro
end iterate
end if

View File

@ -0,0 +1,10 @@
include 'avx512f.inc'
include 'avx512cd.inc'
include 'avx512vl.inc'
include 'avx512bw.inc'
include 'avx512dq.inc'
include 'avx512_ifma.inc'
include 'avx512_vbmi.inc'

View File

@ -0,0 +1,31 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,opcode>, vp4dpwssd,52h, vp4dpwssds,53h
macro instr? dest*,src*,src2*
AVX_512.parse_k1z_operand@dest dest
match rsrc+=3, src
AVX_512.parse_operand@src rsrc
else
AVX_512.parse_operand@src src
end match
AVX_512.parse_operand@src2 src2
if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mem'
if @dest.size <> 64 | @src2.size and not 16
err 'invalid operand size'
else if @dest.size <> @src.size
err 'operand sizes do not match'
end if
@src2.memsize = 0
AVX_512.store_instruction@src2 @dest.size,VEX_F2_0F38_W0,EVEX_REQUIRED,opcode,@dest.mask,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,29 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,vex_mpw,opcode>, vpopcntb,VEX_66_0F38_W0,54h, vpopcntw,VEX_66_0F38_W1,54h
macro instr? dest*,src*
AVX_512.single_source_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src
end macro
end iterate
macro vpshufbitqmb? dest*,src*,src2*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @src2.size and not @src.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @src.size,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,8Fh,@dest.mask,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,15 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,opcode>, vpmadd52luq,0B4h, vpmadd52huq,0B5h
macro instr? dest*,src*,src2*
AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2
end macro
end iterate

View File

@ -0,0 +1,22 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
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*
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*
AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2
end macro
end iterate

View File

@ -0,0 +1,65 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,vex_mpw,opcode>, vpshldw,VEX_66_0F3A_W1,70h, vpshrdw,VEX_66_0F3A_W1,72h
macro instr? dest*,src*,src2*,aux*&
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*&
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*
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*
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*
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*
AVX_512.single_source_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src
end macro
end iterate

View File

@ -0,0 +1,14 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,opcode>, vpdpbusd,50h, vpdpbusds,51h, vpdpwssd,52h, vpdpwssds,53h
macro instr? dest*,src*,src2*
AVX_512.basic_instruction_bcst VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,4,dest,src,src2
end macro
end iterate

View File

@ -0,0 +1,16 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,unit,vex_mpw,opcode>, vpopcntd,4,VEX_66_0F38_W0,55h, vpopcntq,8,VEX_66_0F38_W1,55h
macro instr? dest*,src*
AVX_512.single_source_instruction_bcst vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src
end macro
end iterate

View File

@ -0,0 +1,494 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <t,vex_mpw,msize>, d,VEX_66_0F_W1,4, q,VEX_0F_W1,8
iterate <instr,opcode>, kand,41h, kandn,42h, knot,44h, kor,45h, kxnor,46h, kxor,47h, kadd,4Ah
macro instr#t? dest*,src*,src2*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg'
AVX.store_instruction@src2 32,vex_mpw,opcode,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, knot,44h, kortest,98h, ktest,99h
macro instr#t? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & @src.type = 'maskreg'
AVX.store_instruction@src 16,vex_mpw,opcode,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro kmov#t? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & (@src.type = 'maskreg' | @src.type = 'mem')
if @src.type = 'mem' & @src.size and not msize
err 'invalid operand size'
end if
AVX.store_instruction@src 16,vex_mpw,90h,@dest.rm
else if @dest.type = 'mem' & @src.type = 'maskreg'
if @dest.size and not msize
err 'invalid operand size'
end if
AVX.store_instruction@dest 16,vex_mpw,91h,@src.rm
else if @dest.type = 'maskreg' & @src.type = 'reg'
if (msize < 8 & @src.size <> 4) | (msize = 8 & @src.size <> 8)
err 'invalid operand size'
else if msize = 8 & x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,vex_mpw,92h,@dest.rm
else if @dest.type = 'reg' & @src.type = 'maskreg'
if (msize < 8 & @dest.size <> 4) | (msize = 8 & @dest.size <> 8)
err 'invalid operand size'
else if msize = 8 & x86.mode < 64
err 'instruction requires long mode'
end if
AVX.store_instruction@src 16,vex_mpw,93h,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, kshiftrd,VEX_66_0F3A_W0,31h, kshiftrq,VEX_66_0F3A_W1,31h, \
kshiftld,VEX_66_0F3A_W0,33h, kshiftlq,VEX_66_0F3A_W1,33h
macro instr? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'maskreg' & @src.type = 'maskreg' & @aux.type = 'imm'
if @aux.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@src 16,vex_mpw,opcode,@dest.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw>, kunpckwd,VEX_0F_W0, kunpckdq,VEX_0F_W1
macro 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 = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg'
AVX.store_instruction@src2 32,vex_mpw,4Bh,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,evex_f,opcode_rm,opcode_mr>, vmovdqu8,VEX_F2_0F_W0,EVEX_REQUIRED+EVEX_VL,6Fh,7Fh, vmovdqu16,VEX_F2_0F_W1,EVEX_REQUIRED+EVEX_VL,6Fh,7Fh
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if @src.size and not @dest.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src @dest.size,vex_mpw,evex_f,opcode_rm,@dest.mask,@dest.rm
else if @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_f,opcode_mr,@dest.mask,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, vpabsb,1Ch, vpabsw,1Dh
macro instr? dest*,src*
AVX_512.single_source_instruction VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src
end macro
end iterate
iterate <instr,opcode>, vpacksswb,63h, vpackuswb,67h, vpaddb,0FCh, vpaddw,0FDh, vpaddsb,0ECh, vpaddsw,0EDh, vpaddusb,0DCh, vpaddusw,0DDh, vpavgb,0E0h, vpavgw,0E3h, \
vpmaddwd,0F5h, vpmaxsw,0EEh, vpmaxub,0DEh, vpminsw,0EAh, vpminub,0DAh, vpmulhuw,0E4h, vpmulhw,0E5h, vpmullw,0D5h, \
vpsadbw,0F6h, vpsubb,0F8h, vpsubw,0F9h, vpsubsb,0E8h, vpsubsw,0E9h, vpsubusb,0D8h, vpsubusw,0D9h, \
vpunpckhbw,68h, vpunpckhwd,69h, vpunpcklbw,60h, vpunpcklwd,61h
macro instr? dest*,src*,src2*
AVX_512.basic_instruction VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, vpackssdw,6Bh
macro instr? dest*,src*,src2*
AVX_512.basic_instruction_bcst VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, vpackusdw,2Bh
macro instr? dest*,src*,src2*
AVX_512.basic_instruction_bcst VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, vpalignr,0Fh
macro instr? dest*,src*,src2*,imm*
AVX_512.basic_instruction_imm8 VEX_66_0F3A_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src,src2,imm
end macro
end iterate
iterate <instr,opcode>, vpmaddubsw,4, vpmaxsb,3Ch, vpmaxuw,3Eh, vpminsb,38h, vpminuw,3Ah, vpmulhrsw,0Bh, vpshufb,0
macro instr? dest*,src*,src2*
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>, vpcmpeqb,74h, vpcmpeqw,75h, vpcmpgtb,64h, vpcmpgtw,65h
macro instr? dest*,src*,src2*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @src2.size and not @src.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @src.size,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm
else if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @src.size <> @dest.size | @src2.size and not @dest.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @src.size,VEX_66_0F_W0,EVEX_FORBIDDEN,opcode,@dest.mask,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro vpextrb? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if (@dest.type = 'reg' & @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | (@dest.type = 'mem' & @dest.size and not 1) | @src.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.memsize = 1
AVX_512.store_instruction@dest 16,VEX_66_0F3A_W0,EVEX_AS_VEX,14h,0,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vpextrw? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8) | @src.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
AVX_512.store_instruction@src 16,VEX_66_0F_W0,EVEX_AS_VEX,0C5h,0,@dest.rm,,1,@aux.imm
else if @dest.type = 'mem' & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size and not 2 | @src.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.memsize = 2
AVX_512.store_instruction@dest 16,VEX_66_0F3A_W0,EVEX_AS_VEX,15h,0,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,vex_mpw,opcode,msize>, vpinsrb,VEX_66_0F3A_W0,20h,1, vpinsrw,VEX_66_0F_W0,0C4h,2
macro instr? dest*,src*,src2*,aux*
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 = 'reg' | @src2.type = 'mem') & @aux.type = 'imm'
if @dest.size <> 16 | @src.size <> 16 | (@src2.type = 'reg' & @src2.size <> 4) | (@src2.type = 'mem' & @src2.size and not msize) | @aux.size and not 1
err 'invalid operand size'
end if
@src2.memsize = msize
AVX_512.store_instruction@src2 16,vex_mpw,EVEX_AS_VEX,opcode,0,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode,msize>, vpmovsxbw,20h,8, vpmovzxbw,30h,8
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
@src.memsize = msize * (@dest.size shr 4)
if (@src.type = 'mmreg' & @src.size <> (@src.memsize-1) and not 15 + 16) | (@src.type = 'mem' & @src.size and not @src.memsize)
err 'invalid operand size'
end if
AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw>, vpshufhw,VEX_F3_0F_W0, vpshuflw,VEX_F2_0F_W0
macro instr? dest*,src*,aux*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if @aux.size and not 1
err 'invalid operand size'
else if @src.size and not @dest.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_AS_VEX+EVEX_VL,70h,@dest.mask,@dest.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,postbyte>, vpslldq,7, vpsrldq,3
macro instr? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') & @aux.type = 'imm'
if @aux.size and not 1
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
if @src.type = 'mem'
AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,73h,0,postbyte,@dest.rm,1,@aux.imm
else
AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,73h,0,postbyte,@dest.rm,1,@aux.imm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode_rrm,opcode,postbyte>, vpsllw,0F1h,71h,6, vpsraw,0E1h,71h,4, vpsrlw,0D1h,71h,2
macro instr? dest*,src*,src2*
AVX_512.parse_k1z_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')
@src2.memsize = 16
if @src2.size and not @src2.memsize
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @dest.size,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode_rrm,@dest.mask,@dest.rm,@src.rm
else if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') & @src2.type = 'imm'
if @src2.size and not 1
err 'invalid operand size'
else if @src.size <> @dest.size
err 'operand sizes do not match'
end if
if @src.type = 'mem'
AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,postbyte,@dest.rm,1,@src2.imm
else
AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,postbyte,@dest.rm,1,@src2.imm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vdbpsadbw,VEX_66_0F3A_W0,42h
macro instr? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_imm8 vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2,aux
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpblendmb,VEX_66_0F38_W0,66h, vpblendmw,VEX_66_0F38_W1,66h
macro instr? dest*,src*,src2*&
AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode,opcode_g,msize>, vpbroadcastb,78h,7Ah,1, vpbroadcastw,79h,7Bh,2
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if (@src.type='mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not msize)
err 'invalid operand size'
end if
@src.memsize = msize
AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,@dest.rm
else if @dest.type = 'mmreg' & @src.type = 'reg'
if @src.size <> msize & (@src.size <> 4 | msize = 8)
err 'invalid operand size'
end if
@src.memsize = msize
if msize = 8
AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode_g,@dest.mask,@dest.rm
else
AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode_g,@dest.mask,@dest.rm
end if
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpcmpb,VEX_66_0F3A_W0,3Fh, vpcmpub,VEX_66_0F3A_W0,3Eh, vpcmpw,VEX_66_0F3A_W1,3Fh, vpcmpuw,VEX_66_0F3A_W1,3Eh
macro instr? dest*,src*,src2*,aux*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
x86.parse_operand@aux aux
if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm'
if @src2.size and not @src.size | @aux.size and not 1
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpermw,VEX_66_0F38_W1,8Dh, vpermi2w,VEX_66_0F38_W1,75h, vpermt2w,VEX_66_0F38_W1,7Dh
macro instr? dest*,src*,src2*
AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpmovb2m,VEX_F3_0F38_W0,29h, vpmovw2m,VEX_F3_0F38_W1,29h
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & @src.type = 'mmreg'
AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpmovm2b,VEX_F3_0F38_W0,28h, vpmovm2w,VEX_F3_0F38_W1,28h
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'maskreg'
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,ratio,opcode>, vpmovuswb,2,10h, vpmovswb,2,20h, vpmovwb,2,30h
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg'
@dest.memsize = @src.size / ratio
if (@dest.type = 'mmreg' & @dest.size <> (@dest.memsize-1) and not 15 + 16) | (@dest.type = 'mem' & @dest.size and not @dest.memsize)
err 'invalid operand size'
end if
AVX_512.store_instruction@dest @src.size,VEX_F3_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, vpsllvw,12h, vpsrlvw,10h, vpsravw,11h
macro instr? dest*,src*,src2*
AVX_512.basic_instruction VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vptestnmb,VEX_F3_0F38_W0,26h, vptestnmw,VEX_F3_0F38_W1,26h, vptestmb,VEX_66_0F38_W0,26h, vptestmw,VEX_66_0F38_W1,26h
macro instr? dest*,src*,src2*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg')
if @src2.size and not @src.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src2 @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,29 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,vex_mpw,opcode>, vpbroadcastmb2q,VEX_F3_0F38_W1,2Ah, vpbroadcastmw2d,VEX_F3_0F38_W0,3Ah
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'maskreg'
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,unit,vex_mpw,opcode>, vpconflictd,4,VEX_66_0F38_W0,0C4h, vpconflictq,8,VEX_66_0F38_W1,0C4h, vplzcntd,4,VEX_66_0F38_W0,44h, vplzcntq,8,VEX_66_0F38_W1,44h
macro instr? dest*,src*&
AVX_512.single_source_instruction_bcst vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src
end macro
end iterate

View File

@ -0,0 +1,463 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,opcode>, kandb,41h, kandnb,42h, knotb,44h, korb,45h, kxnorb,46h, kxorb,47h, kaddb,4Ah
macro 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 = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg'
AVX.store_instruction@src2 32,VEX_66_0F_W0,opcode,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, knotb,44h, kortestb,98h, ktestb,99h
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & @src.type = 'maskreg'
AVX.store_instruction@src 16,VEX_66_0F_W0,opcode,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro kmovb? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & (@src.type = 'maskreg' | @src.type = 'mem')
if @src.type = 'mem' & @src.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@src 16,VEX_66_0F_W0,90h,@dest.rm
else if @dest.type = 'mem' & @src.type = 'maskreg'
if @dest.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@dest 16,VEX_66_0F_W0,91h,@src.rm
else if @dest.type = 'maskreg' & @src.type = 'reg'
if @src.size <> 4
err 'invalid operand size'
end if
AVX.store_instruction@src 16,VEX_66_0F_W0,92h,@dest.rm
else if @dest.type = 'reg' & @src.type = 'maskreg'
if @dest.size <> 4
err 'invalid operand size'
end if
AVX.store_instruction@src 16,VEX_66_0F_W0,93h,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro kaddw? dest*,src*,src2*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
AVX_512.parse_operand@src2 src2
if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg'
AVX.store_instruction@src2 32,VEX_0F_W0,opcode,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
macro ktestw? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & @src.type = 'maskreg'
AVX.store_instruction@src 16,VEX_0F_W0,opcode,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
iterate <instr,vex_mpw,opcode>, kshiftrb,VEX_66_0F3A_W0,30h, kshiftlb,VEX_66_0F3A_W0,32h
macro instr? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'maskreg' & @src.type = 'maskreg' & @aux.type = 'imm'
if @aux.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@src 16,vex_mpw,opcode,@dest.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, and,54h, andn,55h, or,56h, xor,57h
macro v#instr#pd? dest*,src*,src2*&
AVX_512.basic_instruction_bcst VEX_66_0F_W0,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2
end macro
macro v#instr#ps? dest*,src*,src2*&
AVX_512.basic_instruction_bcst VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, vbroadcastf32x2,19h, vbroadcasti32x2,59h
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if @dest.size = 16 | (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not 8)
err 'invalid operand size'
end if
@src.memsize = 8
AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode,msize>, vbroadcastf32x8,VEX_66_0F38_W0,1Bh,32, vbroadcastf64x2,VEX_66_0F38_W1,1Ah,16, \
vbroadcasti32x8,VEX_66_0F38_W0,5Bh,32, vbroadcasti64x2,VEX_66_0F38_W1,5Ah,16
macro instr? dest*,src*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'mem'
if @dest.size <= msize | @src.size and not msize
err 'invalid operand size'
end if
@src.memsize = msize
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vcvtpd2qq,VEX_66_0F_W1,7Bh, vcvtpd2uqq,VEX_66_0F_W1,79h, \
vcvtqq2pd,VEX_F3_0F_W1,0E6h, vcvtuqq2pd,VEX_F3_0F_W1,7Ah
macro instr? dest*,src*&
AVX_512.single_source_instruction_bcst_er vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vcvttpd2qq,VEX_66_0F_W1,7Ah, vcvttpd2uqq,VEX_66_0F_W1,78h
macro instr? dest*,src*&
AVX_512.single_source_instruction_bcst_sae vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vcvtps2qq,VEX_66_0F_W0,7Bh, vcvtps2uqq,VEX_66_0F_W0,79h
macro instr? dest*,src_er*&
AVX_512.parse_k1z_operand@dest dest
match src=,er, src_er
AVX_512.parse_operand@src src
AVX_512.parse_er@src er,32
else
AVX_512.parse_bcst_operand@src src_er,4
end match
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if (@src.type = 'mem' & @src.size and not (@dest.size shr 1)) | (@src.type = 'mmreg' & (@dest.size shr 1 - 1) and not 15 + 16 <> @src.size)
err 'invalid operand size'
end if
if @src.memsize = 0
@src.memsize = @dest.size shr 1
end if
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vcvtqq2ps,VEX_0F_W1,5Bh, vcvtuqq2ps,VEX_F2_0F_W1,7Ah
macro instr? dest*,src_er*&
AVX_512.parse_k1z_operand@dest dest
match src=,er, src_er
AVX_512.parse_operand@src src
AVX_512.parse_er@src er
else
AVX_512.parse_bcst_operand@src src_er,8
end match
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @src.size = 0
if @dest.size = 16
err 'operand size not specified'
else
@src.size = 64
end if
end if
if (@src.size shr 1 - 1) and not 15 + 16 <> @dest.size | @src.size > 64
err 'invalid operand size'
end if
AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vcvttps2qq,VEX_66_0F_W0,7Ah, vcvttps2uqq,VEX_66_0F_W0,78h
macro instr? dest*,src_sae*&
AVX_512.parse_k1z_operand@dest dest
match src=,sae, src_sae
AVX_512.parse_operand@src src
AVX_512.parse_sae @src,sae
else
AVX_512.parse_bcst_operand@src src_sae,4
end match
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if (@src.type = 'mem' & @src.size and not (@dest.size shr 1)) | (@src.type = 'mmreg' & (@dest.size shr 1 - 1) and not 15 + 16 <> @src.size)
err 'invalid operand size'
end if
if @src.memsize = 0
@src.memsize = @dest.size shr 1
end if
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode,msize>, vextractf32x8,VEX_66_0F3A_W0,1Bh,32, vextractf64x2,VEX_66_0F3A_W1,19h,16, \
vextracti32x8,VEX_66_0F3A_W0,3Bh,32, vextracti64x2,VEX_66_0F3A_W1,39h,16
macro instr? dest*,src*,aux*
AVX_512.parse_k1z_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size and not msize | @src.size <= msize | @aux.size and not 1
err 'invalid operand size'
end if
@dest.memsize = msize
AVX_512.store_instruction@dest @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode,msize>, vinsertf32x8,VEX_66_0F3A_W0,1Ah,32, vinsertf64x2,VEX_66_0F3A_W1,18h,16, \
vinserti32x8,VEX_66_0F3A_W0,3Ah,32, vinserti64x2,VEX_66_0F3A_W1,38h,16
macro instr? dest*,src*,src2*,aux*
AVX_512.parse_k1z_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 = 'mmreg' | @src2.type = 'mem') & @aux.type = 'imm'
if @dest.size <= msize | @src.size <= msize | @src2.size and not msize | @aux.size and not 1
err 'invalid operand size'
end if
@src2.memsize = msize
AVX_512.store_instruction@src2 @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,unit,vex_mpw>, vfpclasspd,8,VEX_66_0F3A_W1, vfpclassps,4,VEX_66_0F3A_W0
macro instr? dest*,src*,aux*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_bcst_operand@src src,unit
x86.parse_operand@aux aux
if @dest.type = 'maskreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if @src.size = 0
err 'operand size not specified'
else if (@src.size <> 16 & @src.size <> 32 & @src.size <> 64) | @aux.size and not 1
err 'invalid operand size'
end if
AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,66h,@dest.mask,@dest.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,unit,vex_mpw>, vfpclasssd,8,VEX_66_0F3A_W1, vfpclassss,4,VEX_66_0F3A_W0
macro instr? dest*,src*,aux*
AVX_512.parse_k1_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if @dest.type = 'maskreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm'
if (@src.type = 'mem' & @src.size and not unit) | (@src.type = 'mmreg' & @src.size <> 16) | @aux.size and not 1
err 'invalid operand size'
end if
@src.memsize = 16
AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED,67h,@dest.mask,@dest.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
end iterate
macro vpextrd? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if (@dest.type = 'reg' & @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | (@dest.type = 'mem' & @dest.size and not 4) | @src.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
@dest.memsize = 4
AVX_512.store_instruction@dest 16,VEX_66_0F3A_W0,EVEX_AS_VEX,16h,0,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vpinsrd? dest*,src*,src2*,aux*
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 = 'reg' | @src2.type = 'mem') & @aux.type = 'imm'
if @dest.size <> 16 | @src.size <> 16 | (@src2.type = 'reg' & @src2.size <> 4) | (@src2.type = 'mem' & @src2.size and not 4) | @aux.size and not 1
err 'invalid operand size'
end if
@src2.memsize = 4
AVX_512.store_instruction@src2 16,VEX_66_0F3A_W0,EVEX_AS_VEX,22h,0,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vpextrq? dest*,src*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@aux aux
if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if @dest.size and not 8 | @src.size <> 16 | @aux.size and not 1
err 'invalid operand size'
end if
if x86.mode < 64
err 'instruction requires long mode'
end if
@dest.memsize = 8
AVX_512.store_instruction@dest 16,VEX_66_0F3A_W1,EVEX_AS_VEX,16h,0,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vpinsrq? dest*,src*,src2*,aux*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
x86.parse_operand@src2 src2
x86.parse_operand@aux aux
if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') & @aux.type = 'imm'
if @dest.size <> 16 | @src.size <> 16 | @src2.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
@src2.memsize = 8
AVX_512.store_instruction@src2 16,VEX_66_0F3A_W1,EVEX_AS_VEX,22h,0,@dest.rm,@src.rm,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro
macro vpmullq? dest*,src*,src2*
AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,40h,8,dest,src,src2
end macro
iterate <instr,vex_mpw,opcode>, vpmovm2d,VEX_F3_0F38_W0,38h, vpmovm2q,VEX_F3_0F38_W1,38h
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'mmreg' & @src.type = 'maskreg'
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,vex_mpw,opcode>, vpmovd2m,VEX_F3_0F38_W0,39h, vpmovq2m,VEX_F3_0F38_W1,39h
macro instr? dest*,src*
AVX_512.parse_operand@dest dest
AVX_512.parse_operand@src src
if @dest.type = 'maskreg' & @src.type = 'mmreg'
AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,opcode>, range,50h
macro v#instr#pd? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_bcst_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2,aux
end macro
macro v#instr#ps? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_bcst_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED+EVEX_VL,opcode,4,dest,src,src2,aux
end macro
macro v#instr#sd? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED,opcode+1,8,dest,src,src2,aux
end macro
macro v#instr#ss? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED,opcode+1,4,dest,src,src2,aux
end macro
end iterate
macro vreducepd? dest*,src*,aux*&
AVX_512.single_source_instruction_bcst_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED+EVEX_VL,56h,8,dest,src,aux
end macro
macro vreduceps? dest*,src*,aux*&
AVX_512.single_source_instruction_bcst_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED+EVEX_VL,56h,4,dest,src,aux
end macro
macro vreducesd? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED,57h,8,dest,src,src2,aux
end macro
macro vreducess? dest*,src*,src2*,aux*&
AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED,57h,4,dest,src,src2,aux
end macro

View File

@ -0,0 +1,39 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,unit,vex_mpw,opcode>, vexp2ps,4,VEX_66_0F38_W0,0C8h, vexp2pd,4,VEX_66_0F38_W1,0C8h, \
vrcp28ps,4,VEX_66_0F38_W0,0CAh, vrcp28pd,8,VEX_66_0F38_W1,0CAh, vrsqrt28ps,4,VEX_66_0F38_W0,0CCh, vrsqrt28pd,8,VEX_66_0F38_W1,0CCh
macro instr? dest*,src_sae*&
AVX_512.parse_k1z_operand@dest dest
match src=,sae, src_sae
AVX_512.parse_operand@src src
AVX_512.parse_sae@src sae
else
AVX_512.parse_bcst_operand@src src_sae,unit
end match
if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg')
if @dest.size <> 64
err 'invalid operand size'
else if @src.size and not @dest.size
err 'operand sizes do not match'
end if
AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED,opcode,@dest.mask,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
iterate <instr,unit,vex_mpw,opcode>, vrcp28ss,4,VEX_66_0F38_W0,0CBh, vrcp28sd,8,VEX_66_0F38_W1,0CBh, vrsqrt28ss,4,VEX_66_0F38_W0,0CDh, vrsqrt28sd,8,VEX_66_0F38_W1,0CDh
macro instr? dest*,src*,src2*&
AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED,opcode,unit,dest,src,src2
end macro
end iterate

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
iterate <instr,postbyte>, gatherpf0,1 ,gatherpf1,2 ,scatterpf0,5, scatterpf1,6
macro v#instr#dps? src*
AVX_512.parse_k1_vsib_operand@src src
if @src.type = 'mem' & @src.mask
if @src.size and not 4 | @src.visize <> 64
err 'invalid operand size'
end if
@src.memsize = 4
AVX_512.store_instruction@src 64,VEX_66_0F38_W0,EVEX_REQUIRED,0C6h,@src.mask,postbyte,@src.index and 10000b
else
err 'invalid combination of operands'
end if
end macro
macro v#instr#qps? src*
AVX_512.parse_k1_vsib_operand@src src
if @src.type = 'mem' & @src.mask
if @src.size and not 8 | @src.visize <> 64
err 'invalid operand size'
end if
@src.memsize = 4
AVX_512.store_instruction@src 64,VEX_66_0F38_W0,EVEX_REQUIRED,0C7h,@src.mask,postbyte,@src.index and 10000b
else
err 'invalid combination of operands'
end if
end macro
macro v#instr#dpd? src*
AVX_512.parse_k1_vsib_operand@src src
if @src.type = 'mem' & @src.mask
if @src.size and not 4 | @src.visize <> 32
err 'invalid operand size'
end if
@src.memsize = 8
AVX_512.store_instruction@src 64,VEX_66_0F38_W1,EVEX_REQUIRED,0C6h,@src.mask,postbyte,@src.index and 10000b
else
err 'invalid combination of operands'
end if
end macro
macro v#instr#qpd? src*
AVX_512.parse_k1_vsib_operand@src src
if @src.type = 'mem' & @src.mask
if @src.size and not 8 | @src.visize <> 64
err 'invalid operand size'
end if
@src.memsize = 8
AVX_512.store_instruction@src 64,VEX_66_0F38_W1,EVEX_REQUIRED,0C7h,@src.mask,postbyte,@src.index and 10000b
else
err 'invalid combination of operands'
end if
end macro
end iterate

View File

@ -0,0 +1,8 @@
if ~ defined AVX_512
include 'avx512f.inc'
end if
AVX512VL = 1

View File

@ -0,0 +1,97 @@
include 'avx.inc'
macro andn? dest*,src*,src2*
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*
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*
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*
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

View File

@ -0,0 +1,106 @@
include 'bmi1.inc'
iterate <instr,opcode>, bzhi,0F5h
macro instr? dest*,src*,src2*
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*
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*
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*
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

View File

@ -0,0 +1,8 @@
iterate <instr,modrm>, endbr32,0FBh, endbr64,0FAh
macro instr?
db 0F3h,0Fh,1Eh,modrm
end macro
end iterate

View File

@ -0,0 +1,106 @@
iterate <instr,ext,postbyte>, clrssbsy,0AEh,6, rstorssp,01h,5
macro instr? src*
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*
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*
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?
db 0F3h,0Fh,01h,modrm
end macro
end iterate
iterate <instr,prefix,ext>, wrssd,0,0F6h, wrussd,66h,0F5h
macro instr? dest*,src*
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*
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,29 @@
include 'avx.inc'
macro vcvtph2ps? dest*,src*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem')
if (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size*2 <> @dest.size)
err 'invalid operand size'
end if
AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,13h,@dest.rm
else
err 'invalid combination of operands'
end if
end macro
macro vcvtps2ph? dest*,src*,round*
AVX.parse_operand@dest dest
AVX.parse_operand@src src
x86.parse_operand@aux round
if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm'
if (@dest.type = 'mmreg' & @dest.size <> 16) | (@dest.type = 'mem' & @dest.size*2 <> @src.size) | @aux.size and not 1
err 'invalid operand size'
end if
AVX.store_instruction@dest @src.size,VEX_66_0F3A_W0,1Dh,@src.rm,,1,@aux.imm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,30 @@
include 'avx.inc'
iterate <instr,lcode>, vfmaddsub,6, vfmsubadd,7, vfmadd,8, vfmsub,0Ah, vfnmadd,0Ch, vfnmsub,0Eh
iterate <order,hcode>, 132,90h, 213,0A0h, 231,0B0h
macro instr#order#pd? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W1,hcode+lcode,0,dest,src,src2
end macro
macro instr#order#ps? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,hcode+lcode,0,dest,src,src2
end macro
if lcode > 7
macro instr#order#sd? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W1,hcode+lcode+1,8,dest,src,src2
end macro
macro instr#order#ss? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,hcode+lcode+1,4,dest,src,src2
end macro
end if
end iterate
end iterate

View File

@ -0,0 +1,24 @@
iterate <instr,postbyte>, rdfsbase,0, rdgsbase,1, wrfsbase,2, wrgsbase,3
macro instr? dest*
if x86.mode = 64
x86.parse_operand@dest dest
if @dest.type = 'reg'
if @dest.size >= 4
@dest.opcode_prefix = 0F3h
x86.select_operand_prefix@dest @dest.size
x86.store_instruction@dest <0Fh,0AEh>,postbyte
else
err 'invalid operand size'
end if
else
err 'invalid operand'
end if
else
err 'instruction requires long mode'
end if
end macro
end iterate

View File

@ -0,0 +1,53 @@
include 'sse.inc'
iterate <instr,supp>, gf2p8mulb,0CFh
macro instr? dest*,src*
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*
SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm
end macro
end iterate
if defined AVX_512
iterate <instr,opcode>, gf2p8mulb,0CFh
macro v#instr? dest*,src*,src2*&
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*&
AVX_512.basic_instruction_bcst_imm8 VEX_66_0F3A_W1,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2,imm
end macro
end iterate
else if defined AVX
iterate <instr,opcode>, gf2p8mulb,0CFh
macro v#instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,opcode,0,dest,src,src2
end macro
end iterate
iterate <instr,opcode>, gf2p8affineinvqb,0CFh, gf2p8affineqb,0CEh
macro v#instr? dest*,src*,src2*,imm*
AVX.basic_instruction_imm8 VEX_66_0F3A_W1,opcode,0,dest,src,src2,imm
end macro
end iterate
end if

View File

@ -0,0 +1,16 @@
macro xacquire? instr&
db 0F2h
instr
end macro
macro xrelease? instr&
db 0F3h
instr
end macro
macro xtest?
db 0Fh,1,0D6h
end macro

View File

@ -0,0 +1,15 @@
macro invpcid? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mem'
if (x86.mode < 64 & @dest.size <> 4) | (x86.mode = 64 & @dest.size <> 8) | @src.size and not 16
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,38h,82h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,149 @@
if ~ defined MMX
restore MMX ; this ensures that symbol cannot be forward-referenced
MMX = 1
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
end namespace
end iterate
calminstruction MMX.basic_instruction ext,dest,src
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')
jno invalid_combination_of_operands
xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm
exit
invalid_combination_of_operands:
err 'invalid combination of operands'
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 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 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
calminstruction MMX.bit_shift_instruction ext,dest,src
call MMX.parse_operand@dest, dest
call MMX.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 8
jno mmreg_rm_ok
err 'invalid operand size'
mmreg_rm_ok:
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
xcall x86.store_instruction@dest, <0Fh,iext>,irm,byte,@src.imm
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
macro emms?
db 0Fh,77h
end macro
end if

View File

@ -0,0 +1,23 @@
if ~ defined AVX512
define x86.dqqword? :64
define x86.zword? :64
end if
macro movdir64b? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @dest.type = 'reg' & @src.type = 'mem'
if @src.size and not 64
err 'invalid operand size'
end if
if (@src.mode = 16 & @dest.size <> 2) | (@src.mode = 32 & @dest.size <> 4) | (@src.mode = 64 & @dest.size <> 8)
err 'invalid operand size'
end if
@src.opcode_prefix = 66h
x86.store_instruction@src <0Fh,38h,0F8h>,@dest.rm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,19 @@
macro movdiri? dest*,src*
x86.parse_operand@dest dest
x86.parse_operand@src src
if @src.type = 'reg' & @dest.type = 'mem'
if @dest.size <> 0 & @src.size <> @dest.size
err 'operand sizes do not match'
end if
if @src.size = 8 & x86.mode = 64
@dest.prefix = 48h
else if @src.size <> 4
err 'invalid operand size'
end if
x86.store_instruction@dest <0Fh,38h,0F9h>,@src.rm
else
err 'invalid combination of operands'
end if
end macro

View File

@ -0,0 +1,196 @@
if ~ defined MPX
restore MPX ; this ensures that symbol cannot be forward-referenced
MPX = 1
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*&
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*
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*
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*&
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*&
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
end if

View File

@ -0,0 +1,14 @@
include 'sse.inc'
macro pclmulqdq? dest*,src*,imm*
SSE.basic_instruction_imm8 66h,<3Ah,44h>,16,dest,src,imm
end macro
if defined AVX
macro vpclmulqdq? dest*,src*,src2*,imm*
AVX.basic_instruction_imm8 VEX_66_0F3A_W0,44h,16,dest,src,src2,imm
end macro
end if

View File

@ -0,0 +1,18 @@
macro ptwrite? src*
x86.parse_operand@src src
if @src.size = 0
err 'operand size not specified'
else if @src.size <> 4 & (@src.size <> 8 | x86.mode <> 64)
err 'invalid operand size'
end if
if @src.type = 'reg' | @src.type = 'mem'
if @src.size = 8
x86.select_operand_prefix@src 8
end if
@src.opcode_prefix = 0F3h
x86.store_instruction@src <0Fh,0AEh>,4
else
err 'invalid operand'
end if
end macro

View File

@ -0,0 +1,10 @@
macro rdrand? dest*
x86.parse_operand@dest dest
if @dest.type = 'reg'
x86.select_operand_prefix@dest @dest.size
x86.store_instruction@dest <0Fh,0C7h>,6
else
err 'invalid operand'
end if
end macro

View File

@ -0,0 +1,10 @@
macro rdseed? dest*
x86.parse_operand@dest dest
if @dest.type = 'reg'
x86.select_operand_prefix@dest @dest.size
x86.store_instruction@dest <0Fh,0C7h>,7
else
err 'invalid operand'
end if
end macro

View File

@ -0,0 +1,4 @@
macro rdtscp?
db 0Fh,1,0F9h
end macro

View File

@ -0,0 +1,39 @@
macro xbegin? dest*
x86.parse_jump_operand@dest dest
if @dest.type = 'imm' & ~ @dest.jump_type
if x86.mode shr 3 <> @dest.size
err 'invalid operand size'
end if
if x86.mode = 16
db 0C7h,0F8h
dw @dest.imm-($+2)
else
if ~ $ relativeto 0 & @dest.imm relativeto 0
@dest.imm = @dest.imm + $ - 0 scaleof $
err 'invalid address'
end if
if @dest.unresolved | ( @dest.imm relativeto $ & @dest.imm-($+5) < 8000h & @dest.imm-($+5) >= -8000h )
db 66h,0C7h,0F8h
dw @dest.imm-($+2)
else
db 0C7h,0F8h
dd @dest.imm-($+4)
end if
end if
else
err 'invalid operand'
end if
end macro
macro xabort? imm*
db 0C6h,0F8h,imm
end macro
macro xend?
db 0Fh,1,0D5h
end macro
macro xtest?
db 0Fh,1,0D6h
end macro

View File

@ -0,0 +1,4 @@
macro getsec?
db 0Fh,37h
end macro

View File

@ -0,0 +1,433 @@
if ~ defined SSE
restore SSE ; this ensures that symbol cannot be forward-referenced
SSE = 1
include 'mmx.inc'
element SSE.reg
repeat 8, i:0
element xmm#i? : SSE.reg + i
end repeat
define x86.dqword? :16
define x86.xword? :16
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 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 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*
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*
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*
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*
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*
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*
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*
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*
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*
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*
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*
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*
MMX.basic_instruction ext,dest,src
end macro
end iterate
macro pinsrw? dest*,src*,sel*
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*
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*
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*
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*
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*
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*
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*
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*
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
end if

View File

@ -0,0 +1,603 @@
if ~ defined SSE2
restore SSE2 ; this ensures that symbol cannot be forward-referenced
SSE2 = 1
include 'sse.inc'
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*
SSE.basic_instruction 66h,ext,16,dest,src
end macro
macro instr#sd? dest*,src*
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*
SSE.basic_instruction 66h,ext,16,dest,src
end macro
end iterate
macro cmppd? dest*,src*,code*
SSE.basic_instruction_imm8 66h,0C2h,16,dest,src,code
end macro
macro SSE.cmpsd? dest*,src*,code*
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*
cmppd dest,src,code
end macro
macro cmp#cond#sd? dest*,src*
cmpsd dest,src,code
end macro
end iterate
macro shufpd? dest*,src*,imm*
SSE.basic_instruction_imm8 66h,0C6h,16,dest,src,imm
end macro
iterate <instr,ext>, movapd,28h, movupd,10h
macro instr? dest*,src*
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*
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*
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*
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*
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*
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*
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*
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*
SSE.basic_instruction 0,5Ah,8,dest,src
end macro
macro cvtpd2ps? dest*,src*
SSE.basic_instruction 66h,5Ah,16,dest,src
end macro
macro cvtsd2ss? dest*,src*
SSE.basic_instruction 0F2h,5Ah,8,dest,src
end macro
macro cvtss2sd? dest*,src*
SSE.basic_instruction 0F3h,5Ah,4,dest,src
end macro
macro cvtdq2ps? dest*,src*
SSE.basic_instruction 0,5Bh,16,dest,src
end macro
macro cvtps2dq? dest*,src*
SSE.basic_instruction 66h,5Bh,16,dest,src
end macro
macro cvttps2dq? dest*,src*
SSE.basic_instruction 0F3h,5Bh,16,dest,src
end macro
macro cvttpd2dq? dest*,src*
SSE.basic_instruction 66h,0E6h,16,dest,src
end macro
macro cvtpd2dq? dest*,src*
SSE.basic_instruction 0F2h,0E6h,16,dest,src
end macro
macro cvtdq2pd? dest*,src*
SSE.basic_instruction 0F3h,0E6h,8,dest,src
end macro
macro movdq2q? dest*,src*
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*
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*
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*
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*
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*
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
calminstruction MMX.select_operand_prefix rm_operand*,size*
local sym, prefix
check size = 16
jno no_prefix
compute prefix, 66h
arrange sym, rm_operand.=prefix
publish sym, prefix
exit
no_prefix:
check size <> 8
jno done
err 'invalid operand size'
done:
end calminstruction
calminstruction MMX.basic_instruction ext,dest,src
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 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,ext>, paddq,0D4h, pmuludq,0F4h, psubq,0FBh
macro instr? dest*,src*
MMX.basic_instruction ext,dest,src
end macro
end iterate
macro movq? dest*,src*
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*
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*
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*
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*
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*
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*
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*
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*
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*
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?
db 0Fh,0AEh,0E8h
end macro
macro mfence?
db 0Fh,0AEh,0F0h
end macro
end if

View File

@ -0,0 +1,72 @@
include 'sse2.inc'
macro fisttp? src*
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*
SSE.basic_instruction 66h,ext,16,dest,src
end macro
macro instr#ps? dest*,src*
SSE.basic_instruction 0F2h,ext,16,dest,src
end macro
end iterate
iterate <instr,ext>, movsldup,12h, movshdup,16h
macro instr? dest*,src*
SSE.basic_instruction 0F3h,ext,16,dest,src
end macro
end iterate
macro movddup? dest*,src*
SSE.basic_instruction 0F2h,12h,8,dest,src
end macro
macro lddqu? dest*,src*
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
macro monitor? arg1,arg2,arg3
match any, arg1 arg2 arg3
if ~ arg1 eq eax | ~ arg2 eq ecx | ~ arg3 eq edx
err 'invalid combination of operands'
end if
end match
db 0Fh,01h,0C8h
end macro
macro mwait? arg1,arg2
match any, arg1 arg2
if ~ arg1 eq eax | ~ arg2 eq ecx
err 'invalid combination of operands'
end if
end match
db 0Fh,01h,0C9h
end macro

View File

@ -0,0 +1,204 @@
include 'ssse3.inc'
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*
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*
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*
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*
SSE.basic_instruction 66h,<38h,20h+code>,msize,dest,src
end macro
macro pmovzx#conv? dest*,src*
SSE.basic_instruction 66h,<38h,30h+code>,msize,dest,src
end macro
end iterate
macro insertps? dest*,src*,sel*
SSE.basic_instruction_imm8 66h,<3Ah,21h>,4,dest,src,sel
end macro
macro extractps? dest*,src*,sel*
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*
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*
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*
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*
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*
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*
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*
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*
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

View File

@ -0,0 +1,54 @@
include 'sse4.1.inc'
iterate <instr,supp>, pcmpgtq,37h
macro instr? dest*,src*
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*
SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm
end macro
end iterate
macro crc32? dest*,src*
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*
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,26 @@
include 'sse3.inc'
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*
MMX.basic_instruction <38h,supp>,dest,src
end macro
end iterate
macro palignr? dest*,src*,aux*
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,37 @@
include 'aes.inc'
if defined AVX_512
iterate <instr,opcode>, aesenc,0DCh, aesenclast,0DDh, aesdec,0DEh, aesdeclast,0DFh
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
AVX_512.store_instruction@src2 @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,@dest.rm,@src.rm
else
err 'invalid combination of operands'
end if
end macro
end iterate
else
include 'avx.inc'
iterate <instr,opcode>, aesenc,0DCh, aesenclast,0DDh, aesdec,0DEh, aesdeclast,0DFh
macro v#instr? dest*,src*,src2*
AVX.basic_instruction VEX_66_0F38_W0,opcode,0,dest,src,src2
end macro
end iterate
end if

View File

@ -0,0 +1,65 @@
iterate <instr,prefix,ext,postbyte>, vmxon,0F3h,0C7h,6, vmclear,66h,0C7h,6, \
vmptrld,0,0C7h,6, vmptrst,0,0C7h,7
macro instr? src*
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?
db 0Fh,1,0C4h
end macro
macro vmcall?
db 0Fh,1,0C1h
end macro
macro vmlaunch?
db 0Fh,1,0C2h
end macro
macro vmresume?
db 0Fh,1,0C3h
end macro
macro vmread? dest*,src*
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*
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

View File

@ -0,0 +1,32 @@
include 'pclmulqdq.inc'
if defined AVX_512
macro vpclmulqdq? dest*,src*,src2*,aux*
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
else
include 'avx.inc'
macro vpclmulqdq? dest*,src*,src2*,imm*
AVX.basic_instruction_imm8 VEX_66_0F3A_W0,44h,0,dest,src,src2,imm
end macro
end if

View File

@ -0,0 +1,35 @@
iterate <instr,postbyte>, xsave,4, xrstor,5
macro instr? src*
x86.parse_operand@src src
if @src.type = 'mem'
x86.store_instruction@src <0Fh,0AEh>,postbyte
else
err 'invalid operand'
end if
end macro
macro instr#64? src*
if x86.mode = 64
x86.parse_operand@src src
if @src.type = 'mem'
x86.select_operand_prefix@src 8
x86.store_instruction@src <0Fh,0AEh>,postbyte
else
err 'invalid operand'
end if
else
err 'instruction requires long mode'
end if
end macro
end iterate
macro xgetbv?
db 0Fh,1,0D0h
end macro
macro xsetbv?
db 0Fh,1,0D1h
end macro