- Removed unnecessary casts.
[AROS.git] / arch / m68k-all / libgcc1 / _divdf3.s
bloba621e566b7cb2d615af53a118c6050a79bdc4148
1 | double 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 | Ported over to 68k assembler
13 | Revision 1.0:
14 | original 8088 code from P.S.Housel
16 BIAS8 = 0x3FF-1
18 .text
19 .even
20 .globl __divdf3
21 .globl _infinitydf
23 __divdf3:
24 lea %sp@(4),%a0 | pointer to parameters u and v
25 moveml %d2-%d7,%sp@- | save registers
26 moveml %a0@,%d4-%d5/%d6-%d7 | %d4-%d5 = u, %d6-%d7 = v
28 movel %d4,%d0 | %d0 = u.exp
29 swap %d0
30 movew %d0,%d2 | %d2 = u.sign
31 lsrw #4,%d0
32 andw #0x07ff,%d0 | kill sign bit
34 movel %d6,%d1 | %d1 = v.exp
35 swap %d1
36 eorw %d1,%d2 | %d2 = u.sign ^ v.sign (in bit 31)
37 lsrw #4,%d1
38 andw #0x07ff,%d1 | kill sign bit
40 andl #0x0fffff,%d4 | remove exponent from u.mantissa
41 tstw %d0 | check for zero exponent - no leading "1"
42 beq L_00
43 orl #0x100000,%d4 | restore implied leading "1"
44 bra L_10
45 L_00: addw #1,%d0 | "normalize" exponent
46 L_10: movel %d4,%d3
47 orl %d5,%d3
48 beq retz | dividing zero
50 andl #0x0fffff,%d6 | remove exponent from v.mantissa
51 tstw %d1 | check for zero exponent - no leading "1"
52 beq L_01
53 orl #0x100000,%d6 | restore implied leading "1"
54 bra L_11
55 L_01: addw #1,%d1 | "normalize" exponent
56 L_11: movel %d6,%d3
57 orl %d7,%d3
58 beq divz | divide by zero
60 movew %d2,%a0 | save sign
62 subw %d1,%d0 | subtract exponents,
63 addw #BIAS8-11+1,%d0 | add bias back in, account for shift
64 addw #66,%d0 | add loop offset, +2 for extra rounding bits
65 | for denormalized numbers (2 implied by dbra)
66 movew #24,%d1 | bit number for "implied" pos (+4 for rounding)
67 movel #-1,%d2 | zero the quotient
68 movel #-1,%d3 | (for speed it is a one's complement)
69 subl %d7,%d5 | initial subtraction,
70 subxl %d6,%d4 | u = u - v
71 L_2:
72 btst %d1,%d2 | divide until 1 in implied position
73 beq L_5
75 addl %d5,%d5
76 addxl %d4,%d4
77 bcs L_4 | if carry is set, add, else subtract
79 addxl %d3,%d3 | shift quotient and set bit zero
80 addxl %d2,%d2
81 subl %d7,%d5 | subtract
82 subxl %d6,%d4 | u = u - v
83 dbra %d0,L_2 | give up if result is denormalized
84 bra L_5
85 L_4:
86 addxl %d3,%d3 | shift quotient and clear bit zero
87 addxl %d2,%d2
88 addl %d7,%d5 | add (restore)
89 addxl %d6,%d4 | u = u + v
90 dbra %d0,L_2 | give up if result is denormalized
91 L_5: subw #2,%d0 | remove rounding offset for denormalized nums
92 notl %d2 | invert quotient to get it right
93 notl %d3
95 movel %d2,%d4 | save quotient mantissa
96 movel %d3,%d5
97 movew %a0,%d2 | get sign back
98 clrw %d1 | zero rounding bits
99 jmp norm_df | (registers on stack removed by norm_df)
101 retz: clrl %d0 | zero destination
102 clrl %d1
103 moveml %sp@+,%d2-%d7
104 rts | no normalization needed
106 divz: moveml _infinitydf,%d0-%d1 | return infinty value
107 moveml %sp@+,%d2-%d7 | should really cause trap ?!?