summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config/rs6000/ppc64-fp.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/config/rs6000/ppc64-fp.c')
-rw-r--r--contrib/gcc/config/rs6000/ppc64-fp.c55
1 files changed, 50 insertions, 5 deletions
diff --git a/contrib/gcc/config/rs6000/ppc64-fp.c b/contrib/gcc/config/rs6000/ppc64-fp.c
index 3f6d7cd..c736d9a 100644
--- a/contrib/gcc/config/rs6000/ppc64-fp.c
+++ b/contrib/gcc/config/rs6000/ppc64-fp.c
@@ -31,19 +31,30 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#if defined(__powerpc64__)
-#include "fp-bit.h"
+#include "config/fp-bit.h"
+extern DItype __fixtfdi (TFtype);
extern DItype __fixdfdi (DFtype);
extern DItype __fixsfdi (SFtype);
extern USItype __fixunsdfsi (DFtype);
extern USItype __fixunssfsi (SFtype);
+extern TFtype __floatditf (DItype);
extern DFtype __floatdidf (DItype);
extern SFtype __floatdisf (DItype);
+extern DItype __fixunstfdi (TFtype);
static DItype local_fixunssfdi (SFtype);
static DItype local_fixunsdfdi (DFtype);
DItype
+__fixtfdi (TFtype a)
+{
+ if (a < 0)
+ return - __fixunstfdi (-a);
+ return __fixunstfdi (a);
+}
+
+DItype
__fixdfdi (DFtype a)
{
if (a < 0)
@@ -77,14 +88,25 @@ __fixunssfsi (SFtype a)
return (SItype) a;
}
+TFtype
+__floatditf (DItype u)
+{
+ DFtype dh, dl;
+
+ dh = (SItype) (u >> (sizeof (SItype) * 8));
+ dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+ dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+ return (TFtype) dh + (TFtype) dl;
+}
+
DFtype
__floatdidf (DItype u)
{
DFtype d;
d = (SItype) (u >> (sizeof (SItype) * 8));
- d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
- d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
+ d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return d;
@@ -109,13 +131,36 @@ __floatdisf (DItype u)
}
}
f = (SItype) (u >> (sizeof (SItype) * 8));
- f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
- f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
+ f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return (SFtype) f;
}
+DItype
+__fixunstfdi (TFtype a)
+{
+ if (a < 0)
+ return 0;
+
+ /* Compute high word of result, as a flonum. */
+ const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8)));
+ /* Convert that to fixed (but not to DItype!),
+ and shift it into the high word. */
+ UDItype v = (USItype) b;
+ v <<= (sizeof (SItype) * 8);
+ /* Remove high part from the TFtype, leaving the low part as flonum. */
+ a -= (TFtype) v;
+ /* Convert that to fixed (but not to DItype!) and add it in.
+ Sometimes A comes out negative. This is significant, since
+ A has more bits than a long int does. */
+ if (a < 0)
+ v -= (USItype) (-a);
+ else
+ v += (USItype) a;
+ return v;
+}
+
/* This version is needed to prevent recursion; fixunsdfdi in libgcc
calls fixdfdi, which in turn calls calls fixunsdfdi. */
OpenPOWER on IntegriCloud