start service tasks separately in-case platforms need to perform additional set-up...
[AROS.git] / workbench / libs / mathffp / spdiv.c
blobd2b851de031a00675a2459f5ec35ccad1193ff87
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "mathffp_intern.h"
8 /*****************************************************************************
10 NAME */
12 AROS_LH2(float, SPDiv,
14 /* SYNOPSIS */
15 AROS_LHA(float, fnum1, D1),
16 AROS_LHA(float, fnum2, D0),
18 /* LOCATION */
19 struct LibHeader *, MathBase, 14, Mathffp)
21 /* FUNCTION
22 Divide two ffp numbers
23 fnum = fnum2 / fnum1;
25 INPUTS
27 RESULT
28 Flags:
29 zero : result is zero
30 negative : result is negative
31 overflow : result is out of range
33 BUGS
34 The parameters are swapped!
36 INTERNALS
37 ALGORITHM:
38 Check if fnum2 == 0: result = 0;
39 Check if fnum1 == 0: result = overflow;
40 The further algorithm comes down to a pen & paper division
42 *****************************************************************************/
44 AROS_LIBFUNC_INIT
46 LONG Res = 0;
47 char Exponent = ((char) fnum2 & FFPExponent_Mask) -
48 ((char) fnum1 & FFPExponent_Mask) + 0x41;
50 LONG Mant2 = ((ULONG)fnum2 & FFPMantisse_Mask);
51 LONG Mant1 = ((ULONG)fnum1 & FFPMantisse_Mask);
52 ULONG Bit_Mask = 0x80000000;
54 /* check if the dividend is zero */
55 if (0 == fnum2)
57 SetSR(Zero_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
58 return 0;
61 /* check for division by zero */
62 if (0 == fnum1)
64 SetSR(Overflow_Bit, Zero_Bit | Negative_Bit | Overflow_Bit);
65 return 0;
68 while (Bit_Mask >= 0x40 && Mant2 != 0)
70 if (Mant2 - Mant1 >= 0)
72 Mant2 -= Mant1;
73 Res |= Bit_Mask;
75 while (Mant2 > 0)
77 Mant2 <<= 1;
78 Bit_Mask >>= 1;
81 while (Mant1 > 0)
83 Mant1 <<=1;
84 Bit_Mask <<=1;
86 } /* if */
87 else
89 Mant1 = (ULONG) Mant1 >> 1;
90 Bit_Mask >>= 1;
92 } /* while */
94 /* normalize the mantisse */
95 while (Res > 0)
97 if (Res >= 0x40000000)
98 Res = Res - 0x80000000;
99 Res += Res;
100 Exponent --;
103 if ((char) Res < 0)
105 Res += 0x00000100;
108 Res &= FFPMantisse_Mask;
109 Res |= (Exponent & 0x7f);
110 Res |= (fnum1 & FFPSign_Mask) ^ (fnum2 & FFPSign_Mask);
112 if ((char) Res < 0)
114 SetSR(Negative_Bit, Zero_Bit | Overflow_Bit | Negative_Bit);
117 if ((char) Exponent < 0)
119 SetSR(Overflow_Bit, Zero_Bit | Overflow_Bit | Negative_Bit);
120 return(Res | (FFPMantisse_Mask | FFPExponent_Mask));
123 D(kprintf("SPDiv(%x / %x) = %x\n", fnum2, fnum1, Res));
125 return Res;
127 AROS_LIBFUNC_EXIT