add flat assembler toolchain
This commit is contained in:
21
toolchain/fasmg.kl0e/examples/x86/include/ext/adx.inc
Normal file
21
toolchain/fasmg.kl0e/examples/x86/include/ext/adx.inc
Normal 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
|
43
toolchain/fasmg.kl0e/examples/x86/include/ext/aes.inc
Normal file
43
toolchain/fasmg.kl0e/examples/x86/include/ext/aes.inc
Normal 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
|
||||
|
1266
toolchain/fasmg.kl0e/examples/x86/include/ext/avx.inc
Normal file
1266
toolchain/fasmg.kl0e/examples/x86/include/ext/avx.inc
Normal file
File diff suppressed because it is too large
Load Diff
502
toolchain/fasmg.kl0e/examples/x86/include/ext/avx2.inc
Normal file
502
toolchain/fasmg.kl0e/examples/x86/include/ext/avx2.inc
Normal 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
|
10
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512.inc
Normal file
10
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512.inc
Normal 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'
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
494
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512bw.inc
Normal file
494
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512bw.inc
Normal 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
|
29
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512cd.inc
Normal file
29
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512cd.inc
Normal 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
|
||||
|
463
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512dq.inc
Normal file
463
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512dq.inc
Normal 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
|
39
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512er.inc
Normal file
39
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512er.inc
Normal 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
|
2660
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512f.inc
Normal file
2660
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512f.inc
Normal file
File diff suppressed because it is too large
Load Diff
62
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512pf.inc
Normal file
62
toolchain/fasmg.kl0e/examples/x86/include/ext/avx512pf.inc
Normal 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
|
@ -0,0 +1,8 @@
|
||||
|
||||
if ~ defined AVX_512
|
||||
|
||||
include 'avx512f.inc'
|
||||
|
||||
end if
|
||||
|
||||
AVX512VL = 1
|
97
toolchain/fasmg.kl0e/examples/x86/include/ext/bmi1.inc
Normal file
97
toolchain/fasmg.kl0e/examples/x86/include/ext/bmi1.inc
Normal 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
|
106
toolchain/fasmg.kl0e/examples/x86/include/ext/bmi2.inc
Normal file
106
toolchain/fasmg.kl0e/examples/x86/include/ext/bmi2.inc
Normal 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
|
@ -0,0 +1,8 @@
|
||||
|
||||
iterate <instr,modrm>, endbr32,0FBh, endbr64,0FAh
|
||||
|
||||
macro instr?
|
||||
db 0F3h,0Fh,1Eh,modrm
|
||||
end macro
|
||||
|
||||
end iterate
|
106
toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ss.inc
Normal file
106
toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ss.inc
Normal 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
|
29
toolchain/fasmg.kl0e/examples/x86/include/ext/f16c.inc
Normal file
29
toolchain/fasmg.kl0e/examples/x86/include/ext/f16c.inc
Normal 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
|
30
toolchain/fasmg.kl0e/examples/x86/include/ext/fma.inc
Normal file
30
toolchain/fasmg.kl0e/examples/x86/include/ext/fma.inc
Normal 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
|
24
toolchain/fasmg.kl0e/examples/x86/include/ext/fsgsbase.inc
Normal file
24
toolchain/fasmg.kl0e/examples/x86/include/ext/fsgsbase.inc
Normal 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
|
||||
|
53
toolchain/fasmg.kl0e/examples/x86/include/ext/gfni.inc
Normal file
53
toolchain/fasmg.kl0e/examples/x86/include/ext/gfni.inc
Normal 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
|
||||
|
16
toolchain/fasmg.kl0e/examples/x86/include/ext/hle.inc
Normal file
16
toolchain/fasmg.kl0e/examples/x86/include/ext/hle.inc
Normal 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
|
||||
|
||||
|
15
toolchain/fasmg.kl0e/examples/x86/include/ext/invpcid.inc
Normal file
15
toolchain/fasmg.kl0e/examples/x86/include/ext/invpcid.inc
Normal 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
|
||||
|
149
toolchain/fasmg.kl0e/examples/x86/include/ext/mmx.inc
Normal file
149
toolchain/fasmg.kl0e/examples/x86/include/ext/mmx.inc
Normal 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
|
23
toolchain/fasmg.kl0e/examples/x86/include/ext/movdir64b.inc
Normal file
23
toolchain/fasmg.kl0e/examples/x86/include/ext/movdir64b.inc
Normal 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
|
||||
|
19
toolchain/fasmg.kl0e/examples/x86/include/ext/movdiri.inc
Normal file
19
toolchain/fasmg.kl0e/examples/x86/include/ext/movdiri.inc
Normal 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
|
||||
|
196
toolchain/fasmg.kl0e/examples/x86/include/ext/mpx.inc
Normal file
196
toolchain/fasmg.kl0e/examples/x86/include/ext/mpx.inc
Normal 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
|
14
toolchain/fasmg.kl0e/examples/x86/include/ext/pclmulqdq.inc
Normal file
14
toolchain/fasmg.kl0e/examples/x86/include/ext/pclmulqdq.inc
Normal 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
|
18
toolchain/fasmg.kl0e/examples/x86/include/ext/ptwrite.inc
Normal file
18
toolchain/fasmg.kl0e/examples/x86/include/ext/ptwrite.inc
Normal 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
|
10
toolchain/fasmg.kl0e/examples/x86/include/ext/rdrand.inc
Normal file
10
toolchain/fasmg.kl0e/examples/x86/include/ext/rdrand.inc
Normal 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
|
10
toolchain/fasmg.kl0e/examples/x86/include/ext/rdseed.inc
Normal file
10
toolchain/fasmg.kl0e/examples/x86/include/ext/rdseed.inc
Normal 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
|
4
toolchain/fasmg.kl0e/examples/x86/include/ext/rdtscp.inc
Normal file
4
toolchain/fasmg.kl0e/examples/x86/include/ext/rdtscp.inc
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
macro rdtscp?
|
||||
db 0Fh,1,0F9h
|
||||
end macro
|
39
toolchain/fasmg.kl0e/examples/x86/include/ext/rtm.inc
Normal file
39
toolchain/fasmg.kl0e/examples/x86/include/ext/rtm.inc
Normal 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
|
4
toolchain/fasmg.kl0e/examples/x86/include/ext/smx.inc
Normal file
4
toolchain/fasmg.kl0e/examples/x86/include/ext/smx.inc
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
macro getsec?
|
||||
db 0Fh,37h
|
||||
end macro
|
433
toolchain/fasmg.kl0e/examples/x86/include/ext/sse.inc
Normal file
433
toolchain/fasmg.kl0e/examples/x86/include/ext/sse.inc
Normal 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
|
603
toolchain/fasmg.kl0e/examples/x86/include/ext/sse2.inc
Normal file
603
toolchain/fasmg.kl0e/examples/x86/include/ext/sse2.inc
Normal 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
|
72
toolchain/fasmg.kl0e/examples/x86/include/ext/sse3.inc
Normal file
72
toolchain/fasmg.kl0e/examples/x86/include/ext/sse3.inc
Normal 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
|
204
toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.1.inc
Normal file
204
toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.1.inc
Normal 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
|
54
toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.2.inc
Normal file
54
toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.2.inc
Normal 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
|
26
toolchain/fasmg.kl0e/examples/x86/include/ext/ssse3.inc
Normal file
26
toolchain/fasmg.kl0e/examples/x86/include/ext/ssse3.inc
Normal 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
|
37
toolchain/fasmg.kl0e/examples/x86/include/ext/vaes.inc
Normal file
37
toolchain/fasmg.kl0e/examples/x86/include/ext/vaes.inc
Normal 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
|
65
toolchain/fasmg.kl0e/examples/x86/include/ext/vmx.inc
Normal file
65
toolchain/fasmg.kl0e/examples/x86/include/ext/vmx.inc
Normal 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
|
32
toolchain/fasmg.kl0e/examples/x86/include/ext/vpclmulqdq.inc
Normal file
32
toolchain/fasmg.kl0e/examples/x86/include/ext/vpclmulqdq.inc
Normal 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
|
35
toolchain/fasmg.kl0e/examples/x86/include/ext/xsave.inc
Normal file
35
toolchain/fasmg.kl0e/examples/x86/include/ext/xsave.inc
Normal 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
|
Reference in New Issue
Block a user