PR target/24837
[official-gcc.git] / gcc / config / fixunstfdi.c
blob4a0012a1abd6c9b2c9e616a26423ddf74cfca3d4
1 /* Public domain. */
2 #if __LDBL_MANT_DIG__ == 106 || __LDBL_MANT_DIG__ == 113
3 typedef int DItype __attribute__ ((mode (DI)));
4 typedef int SItype __attribute__ ((mode (SI)));
5 typedef unsigned int UDItype __attribute__ ((mode (DI)));
6 typedef unsigned int USItype __attribute__ ((mode (SI)));
7 typedef float TFtype __attribute__ ((mode (TF)));
9 DItype __fixunstfdi (TFtype);
11 DItype
12 __fixunstfdi (TFtype a)
14 if (a < 0)
15 return 0;
17 /* Compute high word of result, as a flonum. */
18 const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8)));
19 /* Convert that to fixed (but not to DItype!),
20 and shift it into the high word. */
21 UDItype v = (USItype) b;
22 v <<= (sizeof (SItype) * 8);
23 /* Remove high part from the TFtype, leaving the low part as flonum. */
24 a -= (TFtype) v;
25 /* Convert that to fixed (but not to DItype!) and add it in.
26 Sometimes A comes out negative. This is significant, since
27 A has more bits than a long int does. */
28 if (a < 0)
29 v -= (USItype) (-a);
30 else
31 v += (USItype) a;
32 return v;
35 #endif