NOTE => NOTES
[AROS.git] / arch / m68k-all / libgcc1 / _divsf3.s
blob09dbed129409737ed0b3a8430eae2fdfee3d2f8f
1 | single 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 | Created single float version for 68000
13 | Revision 1.0:
14 | original 8088 code from P.S.Housel for double floats
16 BIAS4 = 0x7F-1
18 .text
19 .even
20 .globl __divsf3
21 .globl _infinitysf
23 __divsf3:
24 lea %sp@(4),%a0 | pointer to parameters u and v
25 moveml %d2-%d5,%sp@- | save registers
26 moveml %a0@,%d4/%d5 | %d4 = u, %d5 = v
28 movel %d4,%d0 | %d0 = u.exp
29 swap %d0
30 movew %d0,%d2 | %d2 = u.sign
31 lsrw #7,%d0
32 andw #0xff,%d0 | kill sign bit
34 movel %d5,%d1 | %d1 = v.exp
35 swap %d1
36 eorw %d1,%d2 | %d2 = u.sign ^ v.sign (in bit 31)
37 lsrw #7,%d1
38 andw #0xff,%d1 | kill sign bit
40 andl #0x7fffff,%d4 | remove exponent from u.mantissa
41 tstw %d0 | check for zero exponent - no leading "1"
42 beq L_00
43 orl #0x800000,%d4 | restore implied leading "1"
44 bra L_10
45 L_00: addw #1,%d0 | "normalize" exponent
46 L_10: tstl %d4
47 beq retz | dividing zero
49 andl #0x7fffff,%d5 | remove exponent from v.mantissa
50 tstw %d1 | check for zero exponent - no leading "1"
51 beq L_01
52 orl #0x800000,%d5 | restore implied leading "1"
53 bra L_11
54 L_01: addw #1,%d1 | "normalize" exponent
55 L_11: tstl %d5
56 beq divz | divide by zero
58 subw %d1,%d0 | subtract exponents,
59 addw #BIAS4-8+1,%d0 | add bias back in, account for shift
60 addw #34,%d0 | add loop offset, +2 for extra rounding bits
61 | for denormalized numbers (2 implied by dbra)
62 movew #27,%d1 | bit number for "implied" pos (+4 for rounding)
63 movel #-1,%d3 | zero quotient (for speed a one's complement)
64 subl %d5,%d4 | initial subtraction, u = u - v
65 L_2:
66 btst %d1,%d3 | divide until 1 in implied position
67 beq L_5
69 addl %d4,%d4
70 bcs L_4 | if carry is set, add, else subtract
72 addxl %d3,%d3 | shift quotient and set bit zero
73 subl %d5,%d4 | subtract, u = u - v
74 dbra %d0,L_2 | give up if result is denormalized
75 bra L_5
76 L_4:
77 addxl %d3,%d3 | shift quotient and clear bit zero
78 addl %d5,%d4 | add (restore), u = u + v
79 dbra %d0,L_2 | give up if result is denormalized
80 L_5: subw #2,%d0 | remove rounding offset for denormalized nums
81 notl %d3 | invert quotient to get it right
83 movel %d3,%d4 | save quotient mantissa
84 clrw %d1 | zero rounding bits
85 jmp norm_sf | (registers on stack removed by norm_sf)
87 retz: clrl %d0 | zero destination
88 moveml %sp@+,%d2-%d5
89 rts | no normalization needed
91 divz: movel _infinitysf,%d0 | return infinty value
92 moveml %sp@+,%d2-%d5 | should really cause trap ?!?
93 rts