ack/mach/i386/libem/fp8087.s
1994-06-24 14:02:31 +00:00

425 lines
5.4 KiB
ArmAsm

.define .adf4, .adf8, .sbf4, .sbf8, .mlf4, .mlf8, .dvf4, .dvf8
.define .ngf4, .ngf8, .fif4, .fif8, .fef4, .fef8
.define .cif4, .cif8, .cuf4, .cuf8, .cfi, .cfu, .cff4, .cff8
.define .cmf4, .cmf8
.sect .text; .sect .rom; .sect .data; .sect .bss
! $Id$
! Implement interface to floating point package for Intel 8087
.sect .rom
one:
.data2 1
two:
.data2 2
bigmin:
.data4 -2147483648
.sect .text
.adf4:
mov bx,sp
flds 4(bx)
fadds 8(bx)
fstps 8(bx)
wait
ret
.adf8:
mov bx,sp
fldd 4(bx)
faddd 12(bx)
fstpd 12(bx)
wait
ret
.sbf4:
mov bx,sp
flds 8(bx)
fsubs 4(bx)
fstps 8(bx)
wait
ret
.sbf8:
mov bx,sp
fldd 12(bx)
fsubd 4(bx)
fstpd 12(bx)
wait
ret
.mlf4:
mov bx,sp
flds 4(bx)
fmuls 8(bx)
fstps 8(bx)
wait
ret
.mlf8:
mov bx,sp
fldd 4(bx)
fmuld 12(bx)
fstpd 12(bx)
wait
ret
.dvf4:
mov bx,sp
flds 8(bx)
fdivs 4(bx)
fstps 8(bx)
wait
ret
.dvf8:
mov bx,sp
fldd 12(bx)
fdivd 4(bx)
fstpd 12(bx)
wait
ret
.ngf4:
mov bx,sp
flds 4(bx)
fchs
fstps 4(bx)
wait
ret
.ngf8:
mov bx,sp
fldd 4(bx)
fchs
fstpd 4(bx)
wait
ret
.fif4:
mov bx,sp
flds 8(bx)
fmuls 12(bx) ! multiply
fld st ! copy result
ftst ! test sign; handle negative separately
fstsw ax
wait
sahf ! result of test in condition codes
jb 1f
frndint ! this one rounds (?)
fcom st(1) ! compare with original; if <=, then OK
fstsw ax
wait
sahf
jbe 2f
fisubs (one) ! else subtract 1
jmp 2f
1: ! here, negative case
frndint ! this one rounds (?)
fcom st(1) ! compare with original; if >=, then OK
fstsw ax
wait
sahf
jae 2f
fiadds (one) ! else add 1
2:
fsub st(1),st ! subtract integer part
mov bx,4(bx)
fstps (bx)
fstps 4(bx)
wait
ret
.fif8:
mov bx,sp
fldd 8(bx)
fmuld 16(bx) ! multiply
fld st ! and copy result
ftst ! test sign; handle negative separately
fstsw ax
wait
sahf ! result of test in condition codes
jb 1f
frndint ! this one rounds (?)
fcom st(1) ! compare with original; if <=, then OK
fstsw ax
wait
sahf
jbe 2f
fisubs (one) ! else subtract 1
jmp 2f
1: ! here, negative case
frndint ! this one rounds (?)
fcom st(1) ! compare with original; if >=, then OK
fstsw ax
wait
sahf
jae 2f
fiadds (one) ! else add 1
2:
fsub st(1),st ! subtract integer part
mov bx,4(bx)
fstpd (bx)
fstpd 8(bx)
wait
ret
.fef4:
! this could be simpler, if only the
! fxtract instruction was emulated properly
mov bx,sp
mov ax,8(bx)
and ax,0x7f800000
je 1f ! zero exponent
shr ax,23
sub ax,126
mov cx,ax ! exponent in cx
mov ax,8(bx)
and ax,0x807fffff
or ax,0x3f000000 ! load -1 exponent
mov bx,4(bx)
mov 4(bx),ax
mov (bx),cx
ret
1: ! we get here on zero exp
mov ax,8(bx)
and ax,0x007fffff
jne 1f ! zero result
mov bx,4(bx)
mov (bx),ax
mov 4(bx),ax
ret
1: ! otherwise unnormalized number
mov cx,8(bx)
and cx,0x807fffff
mov dx,cx
and cx,0x80000000
mov ax,-125
2:
test dx,0x800000
jne 1f
dec ax
shl dx,1
or dx,cx
jmp 2b
1:
mov bx,4(bx)
mov (bx),ax
and dx,0x807fffff
or dx,0x3f000000 ! load -1 exponent
mov 4(bx),dx
ret
.fef8:
! this could be simpler, if only the
! fxtract instruction was emulated properly
mov bx,sp
mov ax,12(bx)
and ax,0x7ff00000
je 1f ! zero exponent
shr ax,20
sub ax,1022
mov cx,ax ! exponent in cx
mov ax,12(bx)
and ax,0x800fffff
or ax,0x3fe00000 ! load -1 exponent
mov dx,8(bx)
mov bx,4(bx)
mov 4(bx),dx
mov 8(bx),ax
mov (bx),cx
ret
1: ! we get here on zero exp
mov ax,12(bx)
and ax,0xfffff
or ax,8(bx)
jne 1f ! zero result
mov bx,4(bx)
mov (bx),ax
mov 4(bx),ax
mov 8(bx),ax
ret
1: ! otherwise unnormalized number
mov cx,12(bx)
and cx,0x800fffff
mov dx,cx
and cx,0x80000000
mov ax,-1021
2:
test dx,0x100000
jne 1f
dec ax
shl 8(bx),1
rcl dx,1
or dx,cx
jmp 2b
1:
and dx,0x800fffff
or dx,0x3fe00000 ! load -1 exponent
mov cx,8(bx)
mov bx,4(bx)
mov (bx),ax
mov 8(bx),dx
mov 4(bx),cx
ret
.cif4:
mov bx,sp
fildl 8(bx)
fstps 8(bx)
wait
ret
.cif8:
mov bx,sp
fildl 8(bx)
fstpd 4(bx)
wait
ret
.cuf4:
mov bx,sp
fildl 8(bx)
cmp 8(bx),0
jge 1f
fisubl (bigmin)
fisubl (bigmin)
1:
fstps 8(bx)
wait
ret
.cuf8:
mov bx,sp
fildl 8(bx)
cmp 8(bx),0
jge 1f
fisubl (bigmin)
fisubl (bigmin)
1:
fstpd 4(bx)
wait
ret
.cfi:
mov bx,sp
fstcw 4(bx)
wait
mov dx,4(bx)
or 4(bx),0xc00 ! truncating mode
wait
fldcw 4(bx)
cmp 8(bx),4
jne 2f
! loc 4 loc ? cfi
flds 12(bx)
fistpl 12(bx)
1:
mov 4(bx),dx
wait
fldcw 4(bx)
ret
2:
! loc 8 loc ? cfi
fldd 12(bx)
fistpl 16(bx)
jmp 1b
.cfu:
mov bx,sp
fstcw 4(bx)
wait
mov dx,4(bx)
and 4(bx),0xf3ff
or 4(bx),0x400 ! to -infinity
wait
fldcw 4(bx)
cmp 8(bx),4
jne 2f
! loc 4 loc ? cfu
flds 12(bx)
fabs ! ???
fiaddl (bigmin)
fistpl 12(bx)
wait
mov ax,12(bx)
sub ax,(bigmin)
mov 12(bx),ax
1:
mov 4(bx),dx
wait
fldcw 4(bx)
ret
2:
! loc 8 loc ? cfu
fldd 12(bx)
fabs ! ???
fiaddl (bigmin)
fistpl 16(bx)
wait
mov ax,16(bx)
sub ax,(bigmin)
mov 16(bx),ax
jmp 1b
.cff4:
mov bx,sp
fldd 4(bx)
fstcw 4(bx)
wait
mov dx,4(bx)
and 4(bx),0xf3ff ! set to rounding mode
wait
fldcw 4(bx)
fstps 8(bx)
mov 4(bx),dx
wait
fldcw 4(bx)
wait
ret
.cff8:
mov bx,sp
flds 4(bx)
fstpd 4(bx)
wait
ret
.cmf4:
mov bx,sp
xor cx,cx
flds 8(bx)
flds 4(bx)
fcompp ! compare and pop operands
fstsw ax
wait
sahf
je 1f
jb 2f
dec cx
jmp 1f
2:
inc cx
1:
mov ax,cx
ret
.cmf8:
mov bx,sp
xor cx,cx
fldd 12(bx)
fldd 4(bx)
fcompp ! compare and pop operands
fstsw ax
wait
sahf
je 1f
jb 2f
dec cx
jmp 1f
2:
inc cx
1:
mov ax,cx
ret