1 | double floating point divide routine
3 | written by Kai-Uwe Bloem
(I5110401@dbstu1.bitnet
).
4 | Based on
a 80x86 floating point packet from comp.os.minix
, written by P.Housel
7 | Revision
1.2, kub
01-90 :
8 | added support for denormalized numbers
10 | Revision
1.1, kub
12-89 :
11 | Ported over to
68k assembler
14 | original
8088 code from P.S.Housel
24 lea
%sp@
(4),%a0 | pointer to parameters u
and v
25 moveml
%d2-
%d7
,%sp@
- | save registers
26 moveml
%a0@
,%d4-
%d5
/%d6-
%d7 |
%d4-
%d5
= u
, %d6-
%d7
= v
28 movel
%d4
,%d0 |
%d0
= u.exp
30 movew
%d0
,%d2 |
%d2
= u.sign
32 andw
#0x07ff,%d0 | kill sign bit
34 movel
%d6
,%d1 |
%d1
= v.exp
36 eorw
%d1
,%d2 |
%d2
= u.sign ^ v.sign
(in bit
31)
38 andw
#0x07ff,%d1 | kill sign bit
40 andl
#0x0fffff,%d4 | remove exponent from u.mantissa
41 tstw
%d0 | check for zero exponent
- no leading
"1"
43 orl
#0x100000,%d4 | restore implied leading "1"
45 L_00
: addw
#1,%d0 | "normalize" exponent
48 beq retz | dividing zero
50 andl
#0x0fffff,%d6 | remove exponent from v.mantissa
51 tstw
%d1 | check for zero exponent
- no leading
"1"
53 orl
#0x100000,%d6 | restore implied leading "1"
55 L_01
: addw
#1,%d1 | "normalize" exponent
58 beq divz | divide by zero
60 movew
%d2
,%a0 | save sign
62 subw
%d1
,%d0 | subtract exponents
,
63 addw
#BIAS8-11+1,%d0 | add bias back in, account for shift
64 addw
#66,%d0 | add loop offset, +2 for extra rounding bits
65 | for denormalized numbers
(2 implied by dbra
)
66 movew
#24,%d1 | bit number for "implied" pos (+4 for rounding)
67 movel
#-1,%d2 | zero the quotient
68 movel
#-1,%d3 | (for speed it is a one's complement)
69 subl
%d7
,%d5 | initial subtraction
,
70 subxl
%d6
,%d4 | u
= u
- v
72 btst
%d1
,%d2 | divide until
1 in implied position
77 bcs L_4 | if carry is set
, add, else subtract
79 addxl
%d3
,%d3 | shift quotient
and set bit zero
81 subl
%d7
,%d5 | subtract
82 subxl
%d6
,%d4 | u
= u
- v
83 dbra
%d0
,L_2 | give up if result is denormalized
86 addxl
%d3
,%d3 | shift quotient
and clear bit zero
88 addl
%d7
,%d5 |
add (restore
)
89 addxl
%d6
,%d4 | u
= u
+ v
90 dbra
%d0
,L_2 | give up if result is denormalized
91 L_5
: subw
#2,%d0 | remove rounding offset for denormalized nums
92 notl
%d2 | invert quotient to get it right
95 movel
%d2
,%d4 | save quotient mantissa
97 movew
%a0
,%d2 | get sign back
98 clrw
%d1 | zero rounding bits
99 jmp norm_df |
(registers on stack removed by norm_df
)
101 retz
: clrl
%d0 | zero destination
104 rts | no normalization needed
106 divz
: moveml _infinitydf
,%d0-
%d1 | return infinty value
107 moveml
%sp@
+,%d2-
%d7 | should really cause
trap ?
!?