1 | single 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
(more optimization is of course
12 | possible by doing shifts all in one intruction
, but what about the rounding
15 | Revision
1.1, kub
12-89 :
16 | Created single float version for
68000
19 | original
8088 code from P.S.Housel for double floats
27 eorb
#0x80,%sp@(8) | reverse sign of v
29 lea
%sp@
(4),%a0 | pointer to u
and v parameter
30 moveml
%d2-
%d5
,%sp@
- | save registers
31 moveml
%a0@
,%d4
/%d5 |
%d4
= v
, %d5
= u
33 movel
%d5
,%d0 |
%d0
= u.exp
35 movel
%d5
,%d2 |
%d2.h
= u.sign
38 andw
#0xff,%d0 | kill sign bit (exponent is 8 bits)
40 movel
%d4
,%d1 |
%d1
= v.exp
42 eorw
%d1
,%d2 |
%d2.
l = u.sign ^ v.sign
44 andw
#0xff,%d1 | kill sign bit (exponent is 8 bits)
46 andl
#0x7fffff,%d5 | remove exponent from mantissa
47 tstw
%d0 | check for zero exponent
- no leading
"1"
49 orl
#0x800000,%d5 | restore implied leading "1"
51 L_00
: addw
#1,%d0 | "normalize" exponent
53 andl
#0x7fffff,%d4 | remove exponent from mantissa
54 tstw
%d1 | check for zero exponent
- no leading
"1"
56 orl
#0x800000,%d4 | restore implied leading "1"
58 L_01
: addw
#1,%d1 | "normalize" exponent
60 clrw
%d3 |
(put initial zero rounding bits in
%d3
)
61 negw
%d1 |
%d1
= u.exp
- v.exp
63 beq L_5 | exponents are equal
- no shifting neccessary
64 bgt L_12 |
not equal but no exchange neccessary
65 exg
%d4
,%d5 | exchange u
and v
66 subw
%d1
,%d0 |
%d0
= u.exp
- (u.exp
- v.exp
) = v.exp
68 tstw
%d2 |
%d2.h
= u.sign ^
(u.sign ^ v.sign
) = v.sign
72 cmpw #24,%d1 | is u so much bigger that v is not
73 bge L_7 | significant ?
75 movew
#7-1,%d3 | shift u left up to 7 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
%d4
,%d3 | set rounding bits
87 sne
%d2 |
"sticky byte"
90 clrw
%d4 | rotate by swapping register halfs
94 lsrl
#1,%d4 | shift v.mant right the rest of the way
95 orb
%d3
,%d2 | set
"sticky byte" if necessary
96 roxrw
#1,%d3 | shift into rounding bits
97 L_4
: dbra
%d1
,L_02 | loop
98 andb
#1,%d2 | see if "sticky bit" should be set
101 tstw
%d2 | are the signs equal ?
102 bpl L_6 | yes
, no negate necessary
104 negb
%d3 | negate rounding bits
and v.mant
107 addl
%d4
,%d5 | u.mant
= u.mant
+ v.mant
108 bcs L_7 | needn
't negate
109 tstw %d2 | opposite signs ?
110 bpl L_7 | don't need to negate result
112 negb
%d3 | negate rounding bits
and u.mant
114 notl
%d2 | switch sign
116 movel
%d5
,%d4 | move result for normalization
117 moveb
%d3
,%d1 | put rounding bits in
%d1 for norm_sf
118 swap
%d2 | put sign into
%d2
(exponent is in
%d0
)
119 jmp norm_sf | leave registers on stack for norm_sf