1 | single floating point normalization 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.4, kub
03-90 :
8 | export ___normsf entry to C language. Rename the internal entry to
a name
9 |
not accessible from C to prevent crashes
11 | Revision
1.3, kub
01-90 :
12 | added support for denormalized numbers
14 | Revision
1.2, kub
01-90 :
15 | replace far shifts by swaps to gain speed
17 | Revision
1.1, kub
12-89 :
18 | Ported over to
68k assembler
21 | original
8088 code from P.S.Housel
29 | C entry
, for procs dealing with the internal representation
:
30 | float _normsf
(long mant
, short exp
, short sign
, short rbits
);
32 lea
%sp@
(4),%a0 | parameter pointer
33 moveml
%d2-
%d5
,%sp@
- | save working registers
34 movel
%a0@
+,%d4 | get mantissa
35 movew
%a0@
+,%d0 | get exponent
36 movew
%a0@
+,%d2 | get sign
37 movew
%a0@
+,%d1 | rounding information
39 | internal entry for floating point package
, saves time
40 |
%d0
=u.exp
, %d2
=u.sign
, %d1
=rounding bits
, %d4
/%d5
=mantissa
41 | registers
%d2-
%d7 must
be saved on the stack
!
43 tstl
%d4 | rounding
and u.mant
== 0 ?
48 clrb
%d2 |
"sticky byte"
50 L_10
: tstw
%d0 | divide
(shift
)
51 ble L_01 | denormalized number
53 andl
%d5
,%d3 |
or until no bits above
23
55 L_01
: addw
#1,%d0 | increment exponent
57 orb
%d1
,%d2 | set
"sticky"
58 roxrb
#1,%d1 | shift into rounding bits
62 orb
%d2
,%d1 | make least sig bit
"sticky"
64 L_3
: movel
%d4
,%d3 | multiply
(shift
) until
65 andl
%d5
,%d3 | one in
"implied" position
67 subw
#1,%d0 | decrement exponent
68 beq L_4 | too small. store as denormalized number
69 addb
%d1
,%d1 | some doubt about this one
*
73 tstb
%d1 | check rounding bits
74 bge L_6 | round down
- no action neccessary
77 bclr #0,%d4 | tie case - round to even
80 clrw
%d1 | zero rounding bits
83 bne L_02 | renormalize if number was denormalized
84 addw
#1,%d0 | correct exponent for denormalized numbers
86 L_02
: movel
%d4
,%d3 | check for rounding overflow
88 bne L_10 | go back
and renormalize
90 tstl
%d4 | check if normalization caused an underflow
92 cmpw #0,%d0 | check for exponent overflow or underflow
97 lslw
#7,%d0 | re-position exponent
98 andw
#0x8000,%d2 | sign bit
100 swap
%d0 | map to upper word
102 andl
#0x7fffff,%d4 | top mantissa bits
103 orl
%d4
,%d0 | insert exponent
and sign
111 oflow
: movel _infinitysf
,%d0 | return infinty value
112 moveml
%sp@
+,%d2-
%d5 | should really cause
trap ?
!?
115 _infinitysf
: |
+infinity as proposed by IEEE