asm_dip/toolchain/fasmg.kl0e/examples/x86/include/ext/mmx.inc

150 lines
4.0 KiB
PHP
Raw Normal View History

2024-11-24 20:13:28 -08:00
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