1 | double floating point
add/subtract 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.3, kub
01-90 :
8 | added support for denormalized numbers
10 | Revision
1.2, kub
01-90 :
11 | replace far shifts by swaps to gain speed
13 | Revision
1.1, kub
12-89 :
14 | Ported over to
68k assembler
17 | original
8088 code from P.S.Housel
25 eorb
#0x80,%sp@(12) | reverse sign of v
27 lea
%sp@
(4),%a0 | pointer to u
and v parameter
28 moveml
%d2-
%d7
,%sp@
- | save registers
29 moveml
%a0@
,%d4-
%d5
/%d6-
%d7 |
%d4-
%d5
= v
, %d6-
%d7
= u
31 movel
%d6
,%d0 |
%d0
= u.exp
33 movel
%d6
,%d2 |
%d2.h
= u.sign
36 andw
#0x07ff,%d0 | kill sign bit
38 movel
%d4
,%d1 |
%d1
= v.exp
40 eorw
%d1
,%d2 |
%d2.
l = u.sign ^ v.sign
42 andw
#0x07ff,%d1 | kill sign bit
44 andl
#0x0fffff,%d6 | remove exponent from u.mantissa
45 tstw
%d0 | check for zero exponent
- no leading
"1"
47 orl
#0x100000,%d6 | restore implied leading "1"
49 L_00
: addw
#1,%d0 | "normalize" exponent
51 andl
#0x0fffff,%d4 | remove exponent from v.mantissa
52 tstw
%d1 | check for zero exponent
- no leading
"1"
54 orl
#0x100000,%d4 | restore implied leading "1"
56 L_01
: addw
#1,%d1 | "normalize" exponent
58 clrw
%d3 |
(put initial zero rounding bits in
%d3
)
59 negw
%d1 |
%d1
= u.exp
- v.exp
61 beq L_5 | exponents are equal
- no shifting neccessary
62 bgt L_12 |
not equal but no exchange neccessary
63 exg
%d4
,%d6 | exchange u
and v
65 subw
%d1
,%d0 |
%d0
= u.exp
- (u.exp
- v.exp
) = v.exp
67 tstw
%d2 |
%d2.h
= u.sign ^
(u.sign ^ v.sign
) = v.sign
71 cmpw #53,%d1 | is u so much bigger that v is not
72 bge L_7 | significant ?
74 movew
#10-1,%d3 | shift u left up to 10 bits to minimize loss
78 subw
#1,%d0 | decrement exponent
79 subw
#1,%d1 | done shifting altogether ?
80 dbeq
%d3
,L_2 | loop if still can shift u.mant more
83 cmpw #16,%d1 | see if fast rotate possible
85 orb
%d5
,%d3 | set rounding bits
87 sne
%d2 |
"sticky byte"
90 movew
%d4
,%d5 | rotate by swapping register halfs
97 lsrl
#1,%d4 | shift v.mant right the rest of the way
98 roxrl
#1,%d5 | to line it up with u.mant
99 orb
%d3
,%d2 | set
"sticky byte" if necessary
100 roxrw
#1,%d3 | shift into rounding bits
101 L_4
: dbra
%d1
,L_0 | loop
102 andb
#1,%d2 | see if "sticky bit" should be set
105 tstw
%d2 | are the signs equal ?
106 bpl L_6 | yes
, no negate necessary
108 negb
%d3 | negate rounding bits
and v.mant
112 addl
%d5
,%d7 | u.mant
= u.mant
+ v.mant
114 bcs L_7 | needn
't negate
115 tstw %d2 | opposite signs ?
116 bpl L_7 | don't need to negate result
118 negb
%d3 | negate rounding bits
and u.mant
121 notl
%d2 | switch sign
123 movel
%d6
,%d4 | move result for normalization
125 moveb
%d3
,%d1 | put rounding bits in
%d1 for norm_df
126 swap
%d2 | put sign into
%d2
(exponent is in
%d0
)
127 jmp norm_df | leave registers on stack for norm_df