use the spinlock_t header, and add the stubs to the kernel
[AROS.git] / arch / m68k-all / libgcc1 / _normsf.s
blobd5c89089dc983995bd0de09dacc6cbba18ca8c71
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
20 | Revision 1.0:
21 | original 8088 code from P.S.Housel
23 .text
24 .even
25 .globl _infinitysf
26 .globl __normsf
27 .globl norm_sf
29 | C entry, for procs dealing with the internal representation :
30 | float _normsf(long mant, short exp, short sign, short rbits);
31 __normsf:
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 !
42 norm_sf:
43 tstl %d4 | rounding and u.mant == 0 ?
44 bne L_00
45 tstb %d1
46 beq retz
47 L_00:
48 clrb %d2 | "sticky byte"
49 movel #0xff000000,%d5
50 L_10: tstw %d0 | divide (shift)
51 ble L_01 | denormalized number
52 movel %d4,%d3
53 andl %d5,%d3 | or until no bits above 23
54 beq L_2
55 L_01: addw #1,%d0 | increment exponent
56 lsrl #1,%d4
57 orb %d1,%d2 | set "sticky"
58 roxrb #1,%d1 | shift into rounding bits
59 bra L_10
60 L_2:
61 andb #1,%d2
62 orb %d2,%d1 | make least sig bit "sticky"
63 movel #0xff800000,%d5
64 L_3: movel %d4,%d3 | multiply (shift) until
65 andl %d5,%d3 | one in "implied" position
66 bne L_4
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 *
70 addxl %d4,%d4
71 bra L_3
72 L_4:
73 tstb %d1 | check rounding bits
74 bge L_6 | round down - no action neccessary
75 negb %d1
76 bvc L_5 | round up
77 bclr #0,%d4 | tie case - round to even
78 bra L_6
79 L_5:
80 clrw %d1 | zero rounding bits
81 addl #1,%d4
82 tstw %d0
83 bne L_02 | renormalize if number was denormalized
84 addw #1,%d0 | correct exponent for denormalized numbers
85 bra L_10
86 L_02: movel %d4,%d3 | check for rounding overflow
87 andl #0xff000000,%d3
88 bne L_10 | go back and renormalize
89 L_6:
90 tstl %d4 | check if normalization caused an underflow
91 beq retz
92 cmpw #0,%d0 | check for exponent overflow or underflow
93 blt retz
94 cmpw #255,%d0
95 bge oflow
97 lslw #7,%d0 | re-position exponent
98 andw #0x8000,%d2 | sign bit
99 orw %d2,%d0
100 swap %d0 | map to upper word
101 clrw %d0
102 andl #0x7fffff,%d4 | top mantissa bits
103 orl %d4,%d0 | insert exponent and sign
104 moveml %sp@+,%d2-%d5
107 retz: clrl %d0
108 moveml %sp@+,%d2-%d5
111 oflow: movel _infinitysf,%d0 | return infinty value
112 moveml %sp@+,%d2-%d5 | should really cause trap ?!?
115 _infinitysf: | +infinity as proposed by IEEE
116 .long 0x7f800000