]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/gcc/config/floatdisf.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / gcc / config / floatdisf.c
1 /* Public domain.  */
2 typedef int DItype __attribute__ ((mode (DI)));
3 typedef unsigned int UDItype __attribute__ ((mode (DI)));
4 typedef int SItype __attribute__ ((mode (SI)));
5 typedef unsigned int USItype __attribute__ ((mode (SI)));
6 typedef float SFtype __attribute__ ((mode (SF)));
7 typedef float DFtype __attribute__ ((mode (DF)));
8
9 SFtype __floatdisf (DItype);
10
11 SFtype
12 __floatdisf (DItype u)
13 {
14   /* Protect against double-rounding error.
15      Represent any low-order bits, that might be truncated by a bit that
16      won't be lost.  The bit can go in anywhere below the rounding position
17      of SFtype.  A fixed mask and bit position handles all usual
18      configurations.  */
19   if (53 < (sizeof (DItype) * 8)
20       && 53 > ((sizeof (DItype) * 8) - 53 + 24))
21     {
22       if (!(- ((DItype) 1 << 53) < u
23             && u < ((DItype) 1 << 53)))
24         {
25           if ((UDItype) u & (((UDItype) 1 << (sizeof (DItype) * 8 - 53)) - 1))
26             {
27               u &= ~ (((UDItype) 1 << (sizeof (DItype) * 8 - 53)) - 1);
28               u |= (UDItype) 1 << (sizeof (DItype) * 8 - 53);
29             }
30         }
31     }
32   /* Do the calculation in a wider type so that we don't lose any of
33      the precision of the high word while multiplying it.  */
34   DFtype f = (SItype) (u >> (sizeof (SItype) * 8));
35   f *= 0x1p32f;
36   f += (USItype) u;
37   return (SFtype) f;
38 }