device/lib/_fsdiv.c: replaced (1<<31) by (1ul<<31)
[fw/sdcc] / device / lib / _fsdiv.c
1 /*
2 ** libgcc support for software floating point.
3 ** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
4 ** Permission is granted to do *anything* you want with this file,
5 ** commercial or otherwise, provided this message remains intact.  So there!
6 ** I would appreciate receiving any updates/patches/changes that anyone
7 ** makes, and am willing to be the repository for said changes (am I
8 ** making a big mistake?).
9 **
10 ** Pat Wood
11 ** Pipeline Associates, Inc.
12 ** pipeline!phw@motown.com or
13 ** sun!pipeline!phw or
14 ** uunet!motown!pipeline!phw
15 */
16
17 /* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
18
19 #include <float.h>
20
21 union float_long
22   {
23     float f;
24     long l;
25   };
26
27 /* divide two floats */
28 float __fsdiv (float a1, float a2)
29 {
30   volatile union float_long fl1, fl2;
31   volatile long result;
32   volatile unsigned long mask;
33   volatile long mant1, mant2;
34   volatile int exp ;
35   char sign;
36
37   fl1.f = a1;
38   fl2.f = a2;
39
40   /* subtract exponents */
41   exp = EXP (fl1.l) ;
42   exp -= EXP (fl2.l);
43   exp += EXCESS;
44
45   /* compute sign */
46   sign = SIGN (fl1.l) ^ SIGN (fl2.l);
47
48   /* divide by zero??? */
49   if (!fl2.l)
50     /* return NaN or -NaN */
51     return (-1.0);
52
53   /* numerator zero??? */
54   if (!fl1.l)
55     return (0);
56
57   /* now get mantissas */
58   mant1 = MANT (fl1.l);
59   mant2 = MANT (fl2.l);
60
61   /* this assures we have 25 bits of precision in the end */
62   if (mant1 < mant2)
63     {
64       mant1 <<= 1;
65       exp--;
66     }
67
68   /* now we perform repeated subtraction of fl2.l from fl1.l */
69   mask = 0x1000000;
70   result = 0;
71   while (mask)
72     {
73       if (mant1 >= mant2)
74         {
75           result |= mask;
76           mant1 -= mant2;
77         }
78       mant1 <<= 1;
79       mask >>= 1;
80     }
81
82   /* round */
83   result += 1;
84
85   /* normalize down */
86   exp++;
87   result >>= 1;
88
89   result &= ~HIDDEN;
90
91   /* pack up and go home */
92   fl1.l = PACK (sign ? 1ul<<31 : 0, (unsigned long) exp, result);
93   return (fl1.f);
94 }
95