464 lines
15 KiB
PHP
464 lines
15 KiB
PHP
|
|
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
|