flat assembler
Message board for the users of flat assembler.

flat assembler > Programming Language Design > [FASMG] Floating Point Instructions. Complete FPU

Author
Thread Post new topic Reply to topic
codestar



Joined: 25 Dec 2014
Posts: 254
Registers
Code:
numeric st, st0=0, st1, st2,\ st3, st4, st5, st6, st7
Get Type Size
Code:
; return size of type name macro fpu_get_size size, type size=0 match =word, type size='2' else match =dword, type size='4' else match =qword, type size='8' else match =tword, type size='t' else error `type, ' - Invalid type' end match end macro
Get Operand Type
Code:
; given operand, return type='r' (stx), ; 'm', 'm2', 'm4', 'm8', 'mt' macro fpu_get_type type, p local n, is, size n=0 is=0 type=0 size=0 match t[m], p fpu_get_size size, t if size='2' type='m2' else if size='4' type='m4' else if size='8' type='m8' else if size='t' type='mt' end if get_mode_m m else match [m], p type='m' get_mode_m m its_size=0 else match a, p name_length a, n if n=2 match =st, a ; st0 type='r' end match else if n=3 is_in is, a,\ st0, st1, st2, st3,\ st4, st5, st6, st7 if is type='r' ; stx end if end if else error 'Operand/s expected' end match end macro
Get Operands Mode
Code:
; return mode = 'r0'=st0, 'rx'=stx, ; 'r0rx'=st0,stx, 'rxr0'=stx,st0, ; 'm2/4/8/t'=m16/32/64/80 macro fpu_get_mode mode, p& local n, s, is, type1, type2 n=0 s=0 is=0 mode=0 match a=,b, p fpu_get_type type1, a fpu_get_type type2, b if type1='r' & type2='r' if a=0 mode='r0rx' its_index=b else mode='rxr0' its_index=a end if else error `a, ',', `b, ' - ',\ 'Invalid operands' end if else match a, p fpu_get_type mode, p if mode=0 error `p, ' - Invalid operand' end if if mode='r' if a=0 mode='r0' else mode='rx' end if end if end match end macro
Example FPU instructions. See attachment: \INCLUDE\FPU and \EXAMPLES\TEST\:

No-Operands: 1-3 bytes each:
Code:
irp <name,a,b,c>,\ fclex,$9B,$DB,$E2, finit,$9B,$DB,$E3 macro name db a, b, c end macro end irp irp <name,a,b>,\ f2xm1,$D9,$F0, fabs,$D9,$E1,\ fchs,$D9,$E0, fnclex,$DB,$E2,\ fcompp,$DE,$D9, fcos,$D9,$FF,\ fdecstp,$D9,$F6, femms,$0F,$0E,\ fincstp,$D9,$F7, fninit,$DB,$E3,\ fld1,$D9,$E8, fldl2e,$D9,$EA,\ fldl2t,$D9,$E9, fldlg2,$D9,$EC,\ fldln2,$D9,$ED, fldpi,$D9,$EB,\ fldz,$D9,$EE, fnop,$D9,$D0,\ fpatan,$D9,$F3, fptan,$D9,$F2,\ fprem,$D9,$F8, fprem1,$D9,$F5,\ frndint,$D9,$FC, fscale,$D9,$FD,\ fsin,$D9,$FE, fsincos,$D9,$FB,\ fsqrt,$D9,$FA macro name db a, b end macro end irp
Load, Store: FLD, FST/P
Code:
; fld stx = $D9 C0+r ; fld m32 = $D9 /0 ; fld m64 = $DD /0 ; fld m80 = $DB /5 macro fld x local type type=0 fpu_get_type type, x if type='r' db $D9, $C0+x else if type='m4' db $D9 write_mode 0 else if type='m8' db $DD write_mode 0 else if type='mt' db $DB write_mode 5 else error `x, ' - Invalid operand/s' end if end macro ; fst stx = $DD $D0+r ; fst m32 = $D9 /2 ; fst m64 = $DD /2 macro fst x local type type=0 fpu_get_type type, x if type='r' db $DD, $D0+x else if type='m4' db $D9 write_mode 2 else if type='m8' db $DD write_mode 2 else error `x, ' - Invalid operand/s' end if end macro ; fstp stx = $DD $D8+r ; fstp m32 = $D9 /3 ; fstp m64 = $DD /3 ; fstp m80 = $DB /7 macro fstp x local type type=0 fpu_get_type type, x if type='r' db $DD, $D8+x else if type='m4' db $D9 write_mode 3 else if type='m8' db $DD write_mode 3 else if type='mt' db $DB write_mode 7 else error `x, '- Invalid operand/s' end if end macro
Integer Load, Store: FILD, FIST/P
Code:
; fild m16 = $DF /0 ; fild m32 = $DB /0 ; fild m64 = $DF /5 macro fild x local type type=0 fpu_get_type type, x if type='m2' db $DF write_mode 0 else if type='m4' db $DB write_mode 0 else if type='m8' db $DF write_mode 5 else error `x, ' - Invalid operand' end if end macro ; fist m16 = $DF /2 ; fist m32 = $DB /2 macro fist x local type type=0 fpu_get_type type, x if type='m2' db $DF write_mode 2 else if type='m4' db $DB write_mode 2 else error `x, ' - Invalid operand' end if end macro ; fistp m16 = $DF /3 ; fistp m32 = $DB /3 ; fistp m64 = $DF /7 macro fistp x local type type=0 fpu_get_type type, x if type='m2' db $DF write_mode 3 else if type='m4' db $DB write_mode 3 else if type='m8' db $DF write_mode 7 else error `x, ' - Invalid operand' end if end macro
Arithmetic: FADD/P, FMUL/P, FDIV/P, FDIVR/P
Code:
; fadd stx = $D8 $C0+r ; fadd st0,stx = $D8 $C0+r ; fadd stx,st0 = $DC $C0+r ; fadd m32 = $D8 /0 ; fadd m64 = $DC /0 ; fmul stx = $D8 $C8+r ; fmul st0,stx = $D8 $C8+r ; fmul stx,st0 = $DC $C8+r ; fmul m32 = $D8 /1 ; fmul m64 = $DC /1 ; fdiv stx = $D8 $F0+r ; fdiv st0,stx = $D8 $F0+r ; fdiv stx,st0 = $DC $F8+r ; fdiv m32 = $D8 /6 ; fdiv m64 = $DC /6 ; fdivr stx = $D8 $F8+r ; fdivr st0,stx = $D8 $F8+r ; fdivr stx,st0 = $DC $F0+r ; fdivr m32 = $D8 /7 ; fdivr m64 = $DC /7 irp <name,opcode,opcode2,digit>,\ fadd,$C0,$C0,0, fmul,$C8,$C8,1,\ fdiv,$F0,$F8,6, fdivr,$F8,$F0,7 macro name p& local r, mode r=0 mode=0 fpu_get_mode mode, p r=its_index if mode='r0' ; st0 db $D8, opcode+0 else if mode='rx' ; stx db $D8, opcode+r else if mode='r0rx' ; st0, stx db $D8, opcode+r else if mode='rxr0' ; stx, st0 db $DC, opcode2+r else if mode='m4' ; dword [m] db $D8 write_mode digit else if mode='m8' ; qword [m] db $DC write_mode digit else error `p, ' - Invalid mode' end if end macro end irp ; faddp stx = $DE C0+r ; faddp stx,st0 = $DE C0+r ; fmulp stx = $DE C8+r ; fmulp stx,st0 = $DE C8+r ; fdivp stx = $DE F8+r ; fdivp stx,st0 = $DE F8+r ; fdivrp stx = $DE F0+r ; fdivrp stx,st0 = $DE F0+r irp <name,opcode>,\ faddp,$C0, fmulp,$C8,\ fdivp,$F8, fdivrp,$F0 macro name p& local r, mode r=0 mode=0 fpu_get_mode mode, p r=its_index if mode='r0' | mode='rx' \ | mode='rxr0' db $DE, opcode+r else error `p, ' - Invalid mode' end if end macro end irp
Arithmetic with Integer: FIADD, FIMUL, FISUB/R, FIDIV/R
Code:
; fiadd m16 = $DE /0 ; fiadd m32 = $DA /0 ; fimul m16 = $DE /1 ; fimul m32 = $DA /1 ; fisub m16 = $DE /4 ; fisub m32 = $DA /4 ; fisubr m16 = $DE /5 ; fisubr m32 = $DA /5 ; fidiv m16 = $DE /6 ; fidiv m32 = $DA /6 ; fidivr m16 = $DE /7 ; fidivr m32 = $DA /7 irp <name,digit>,\ fiadd,0, fimul,1, fisub,4,\ fisubr,5, fidiv,6, fidivr,7 macro name p local size size=0 match t[m], p fpu_get_size size, t if size='2' db $DE else if size='4' db $DA else error 'Invalid size' end if get_mode_m m write_mode digit else error 'Invalid operand' end match end macro end irp
Compare: FCOM/P, FCOMI/P, FICOM/P
Code:
; fcom stx = $D8 $D0+r ; fcom st0,stx = $D8 $D0+r ; fcom m32 = $D8 /2 ; fcom m64 = $DC /2 ; fcomp stx = $D8 $D8+r ; fcomp st0,stx = $D8 $D8+r ; fcomp m32 = $D8 /3 ; fcomp m64 = $DC /3 irp <name,opcode,digit>,\ fcom,$D0,2, fcomp,$D8,3 macro name p& local r, mode r=0 mode=0 fpu_get_mode mode, p r=its_index if mode='r0' ; st0 db $D8, opcode+0 else if mode='rx' ; stx db $D8, opcode+r else if mode='r0rx' ; st0, stx db $D8, opcode+r else if mode='m4' ; dword [m] db $D8 write_mode digit else if mode='m8' ; qword [m] db $DC write_mode digit else error `p, ' - Invalid mode' end if end macro end irp ; fcomi stx = $DB $F0+r ; fcomi st0,stx = $DB $F0+r ; fcomip stx = $DF $F0+r ; fcomip st0,stx = $DF $F0+r irp <name,opcode>, fcomi,$DB, fcomip,$DF macro name p& local r, mode r=0 mode=0 fpu_get_mode mode, p r=its_index if mode='r0' | mode='rx' \ | mode='r0rx' db opcode, $F0+r else error `p, ' - Invalid mode' end if end macro end irp ; ficom m16 = $DE /2 ; ficom m32 = $DA /2 ; ficomp m16 = $DE /3 ; ficomp m32 = $DA /3 irp <name,digit>, ficom,2, ficomp,3 macro name p& local size size=0 match t[m], p fpu_get_size size, t if size='2' db $DE else if size='4' db $DA else error 'Invalid size' end if get_mode_m m write_mode digit else error 'Invalid operand' end match end macro end irp
Conditional Move: CMOVX
Code:
; fcmovb stx = $DA $C0+r ; fcmovb st0,stx = $DA $C0+r ; fcmove stx = $DA $C8+r ; fcmove st0,stx = $DA $C8+r ; fcmovbe stx = $DA $D0+r ; fcmovbe st0,stx = $DA $D0+r ; fcmovu stx = $DA $D8+r ; fcmovu st0,stx = $DA $D8+r ; fcmovnb stx = $DB $C0+r ; fcmovnb st0,stx = $DB $C0+r ; fcmovne stx = $DB $C8+r ; fcmovne st0,stx = $DB $C8+r ; fcmovnbe stx = $DB $D0+r ; fcmovnbe st0,stx = $DB $D0+r ; fcmovnu stx = $DB $D8+r ; fcmovnu st0,stx = $DB $D8+r irp <name,opcode,opcode2>,\ fcmovb,$DA,$C0, fcmove,$DA,$C8,\ fcmovbe,$DA,$D0, fcmovu,$DA,$D8,\ fcmovnb,$DB,$C0, fcmovne,$DB,$C8,\ fcmovnbe,$DB,$D0, fcmovnu,$DB,$D8 macro name p& local r, mode r=0 mode=0 fpu_get_mode mode, p r=its_index if mode='r0' | mode='rx' \ | mode='r0rx' db opcode, opcode2+r else error `p, ' - Invalid mode' end if end macro end irp
Test FPU Instructions:
Code:
macro test_fpu_load_store fld st1 fld dword [edi] fld qword [eax+ecx*8] fld tword [$CAFEBABE] fst st3 fst dword [$12345678] fst qword [$ABCD1234] fstp st7 fstp dword [ebx+edx*4] fstp qword [edi] fstp tword [$CAFEBABE] fbld tword [edi] fbstp tword [ebx] fild word [eax] fild dword [ecx] fild qword [edx] fist word [eax+ecx*2] fist dword [esi+$BABE1234] fldenv [eax] fnsave [ecx] frstor [edx] ffree st7 end macro macro test_fpu_arithmetic fadd st1 fadd st1,st0 fadd dword [$12345678] fadd qword [$ABCD1234] fmul st1 fmul st1,st0 fmul dword [$12345678] fmul qword [$ABCD1234] fdiv st3 fdiv st0,st7 fdiv st7,st0 fdiv dword [eax+4] fdiv qword [ecx+8] fdivr st3 fdivr st0,st7 fdivr st7,st0 fdivr dword [eax+4] fdivr qword [ecx+$CAFEBABE] faddp st1 faddp st2,st0 fmulp st3 fmulp st4,st0 fdivp st5 fdivp st7,st0 fdivrp st1 fdivrp st2,st0 fiadd word [eax] fiadd dword [ecx] fimul word [edx] fimul dword [ebx] fisub word [eax] fisub dword [ecx] fisubr word [edx] fisubr dword [ebx] fidiv word [eax] fidiv dword [ecx] fidivr word [edx] fidivr dword [ebx] end macro macro test_fpu_compare fcom st1 fcom st0,st7 fcom dword [eax] fcom qword [ecx] fcomp st2 fcomp st0,st3 fcomp dword [eax] fcomp qword [ecx] fcomi st1 fcomi st0,st2 fcomip st3 fcomip st0,st4 ficom word [eax] ficom dword [ecx] ficomp word [eax] ficomp dword [edi+$CAFEBABE] end macro macro test_fpu_cmove fcmovb st1 fcmovb st0,st2 fcmove st3 fcmove st0,st4 fcmovbe st5 fcmovbe st0,st6 fcmovu st7 fcmovu st0,st1 fcmovnb st2 fcmovnb st0,st3 fcmovne st4 fcmovne st0,st5 fcmovnbe st6 fcmovnbe st0,st7 fcmovnu st1 fcmovnu st0,st2 end macro macro test_fpu test_fpu_load_store test_fpu_arithmetic test_fpu_compare test_fpu_cmove end macro
Verified with PE Browse Pro disassembler:
Code:
D9C1 FLD ST(1) D907 FLD DWORD [EDI] DD04C8 FLD QWORD [EAX+ECX*8] DDD3 FST ST(3) D91578563412 FST DWORD [0x12345678] DD153412CDAB FST QWORD [0xABCD1234] DDDF FSTP ST(7) D91C93 FSTP DWORD [EBX+EDX*4] DD1F FSTP QWORD [EDI] DB3DBEBAFECA FSTP TBYTE [0xCAFEBABE] DF27 FBLD TBYTE [EDI] DF33 FBSTP TBYTE [EBX] DF00 FILD WORD [EAX] DB01 FILD DWORD [ECX] DF2A FILD QWORD [EDX] DF1448 FIST WORD [EAX+ECX*2] DB963412BEBA FIST DWORD [ESI+0xBABE1234] D920 FLDENV DWORD [EAX] DD31 FNSAVE [ECX] DD22 FRSTOR [EDX] DDC7 FFREE ST(7) D8C1 FADD ST(0),ST(1) DCC1 FADD ST(1),ST(0) D80578563412 FADD DWORD [0x12345678] DC053412CDAB FADD QWORD [0xABCD1234] D8C9 FMUL ST(0),ST(1) DCC9 FMUL ST(1),ST(0) D80D78563412 FMUL DWORD [0x12345678] DC0D3412CDAB FMUL QWORD [0xABCD1234] D8F3 FDIV ST(0),ST(3) D8F7 FDIV ST(0),ST(7) DCFF FDIV ST(7),ST(0) D87004 FDIV DWORD [EAX+0x4] DC7108 FDIV QWORD [ECX+0x8] D8FB FDIVR ST(0),ST(3) D8FF FDIVR ST(0),ST(7) DCF7 FDIVR ST(7),ST(0) D87804 FDIVR DWORD [EAX+0x4] DCB9BEBAFECA FDIVR QWORD [ECX+0xCAFEBABE] DEC1 FADDP ST(1),ST(0) DEC2 FADDP ST(2),ST(0) DECB FMULP ST(3),ST(0) DECC FMULP ST(4),ST(0) DEFD FDIVP ST(5),ST(0) DEFF FDIVP ST(7),ST(0) DEF1 FDIVRP ST(1),ST(0) DEF2 FDIVRP ST(2),ST(0) DE00 FIADD WORD [EAX] DA01 FIADD DWORD [ECX] DE0A FIMUL WORD [EDX] DA0B FIMUL DWORD [EBX] DE20 FISUB WORD [EAX] DA21 FISUB DWORD [ECX] DE2A FISUBR WORD [EDX] DA2B FISUBR DWORD [EBX] DE30 FIDIV WORD [EAX] DA31 FIDIV DWORD [ECX] DE3A FIDIVR WORD [EDX] DA3B FIDIVR DWORD [EBX] D8D1 FCOM ST(1) D8D7 FCOM ST(7) D810 FCOM DWORD [EAX] DC11 FCOM QWORD [ECX] D8DA FCOMP ST(2) D8DB FCOMP ST(3) D818 FCOMP DWORD [EAX] DC19 FCOMP QWORD [ECX] DBF1 FCOMI ST,ST(1) DBF2 FCOMI ST,ST(2) DFF3 FCOMIP ST,ST(3) DFF4 FCOMIP ST,ST(4) DE10 FICOM WORD [EAX] DA11 FICOM DWORD [ECX] DE18 FICOMP WORD [EAX] DA9FBEBAFECA FICOMP DWORD [EDI+0xCAFEBABE] DAC1 FCMOVB ST(0),ST(1) DAC2 FCMOVB ST(0),ST(2) DACB FCMOVE ST(0),ST(3) DACC FCMOVE ST(0),ST(4) DAD5 FCMOVBE ST(0),ST(5) DAD6 FCMOVBE ST(0),ST(6) DADF FCMOVU ST(0),ST(7) DAD9 FCMOVU ST(0),ST(1) DBC2 FCMOVNB ST(0),ST(2) DBC3 FCMOVNB ST(0),ST(3) DBCC FCMOVNE ST(0),ST(4) DBCD FCMOVNE ST(0),ST(5) DBD6 FCMOVNBE ST(0),ST(6) DBD7 FCMOVNBE ST(0),ST(7) DBD9 FCMOVNU ST(0),ST(1) DBDA FCMOVNU ST(0),ST(2)


Description: Examples
Download
Filename: fpu_g.zip
Filesize: 19.04 KB
Downloaded: 103 Time(s)

Post 30 May 2015, 11:23
View user's profile Send private message Reply with quote
CandyMan



Joined: 04 Sep 2009
Posts: 269
Location: film "CandyMan" directed through Bernard Rose OR Candy Shop
good work, but where is FISTTP opcode?

_________________
smaller is better
Post 30 May 2015, 15:51
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >

Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 2004-2018, Tomasz Grysztar.

Powered by rwasa.