asm_dip/toolchain/fasmg.kl0e/examples/x86/include/ext/sse.inc
2024-11-24 23:13:28 -05:00

433 lines
12 KiB
PHP

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