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