libgcc2.h (AVOID_FP_TYPE_CONVERSION): Rename from IS_IBM_EXTENDED.
authorRichard Henderson <rth@redhat.com>
Tue, 24 Apr 2007 15:28:21 +0000 (08:28 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Tue, 24 Apr 2007 15:28:21 +0000 (08:28 -0700)
        * libgcc2.h (AVOID_FP_TYPE_CONVERSION): Rename from
        IS_IBM_EXTENDED.  Also define in terms of WIDEST_HARDWARE_FP_SIZE.
        * libgcc2.c (__floatdisf): Avoid double-word arithmetic when
        looking for non-zero bits shifted out.  Avoid a recursive call
        when constructing the scalar.
        (__floatundisf): Likewise.

From-SVN: r124106

gcc/ChangeLog
gcc/libgcc2.c
gcc/libgcc2.h

index 9912ca74258e7a7f08b018b8bbae1c2b040987a6..7cc6435ea0220e7d580e98b3a40c6397f17f0cc6 100644 (file)
@@ -1,3 +1,12 @@
+2007-04-24  Richard Henderson  <rth@redhat.com>
+
+       * libgcc2.h (AVOID_FP_TYPE_CONVERSION): Rename from 
+       IS_IBM_EXTENDED.  Also define in terms of WIDEST_HARDWARE_FP_SIZE.
+       * libgcc2.c (__floatdisf): Avoid double-word arithmetic when
+       looking for non-zero bits shifted out.  Avoid a recursive call
+       when constructing the scalar.
+       (__floatundisf): Likewise.
+
 2007-04-24  Nathan Froyd  <froydnj@codesourcery.com>
 
        * dwarf2out.c (field_byte_offset): Move the existing logic
index 8c0c9d1122d73ca69e55b7efdfdbc8b5213ce199..a026fff4a870125456e48a7149f730b5f990afcb 100644 (file)
@@ -1420,11 +1420,7 @@ __floatunditf (UDWtype u)
 #define F_MODE_OK(SIZE) \
   (SIZE < DI_SIZE                                                      \
    && SIZE > (DI_SIZE - SIZE + FSSIZE)                                 \
-   /* Don't use IBM Extended Double TFmode for TI->SF calculations.    \
-      The conversion from long double to float suffers from double     \
-      rounding, because we convert via double.  In any case, the       \
-      fallback code is faster.  */                                     \
-   && !IS_IBM_EXTENDED (SIZE))
+   && !AVOID_FP_TYPE_CONVERSION(SIZE))
 #if defined(L_floatdisf)
 #define FUNC __floatdisf
 #define FSTYPE SFtype
@@ -1515,13 +1511,21 @@ FUNC (DWtype u)
   hi = u >> shift;
 
   /* If we lost any nonzero bits, set the lsb to ensure correct rounding.  */
-  if (u & (((DWtype)1 << shift) - 1))
+  if ((UWtype)u << (W_TYPE_SIZE - shift))
     hi |= 1;
 
   /* Convert the one word of data, and rescale.  */
-  FSTYPE f = hi;
-  f *= (UDWtype)1 << shift;
-  return f;
+  FSTYPE f = hi, e;
+  if (shift == W_TYPE_SIZE)
+    e = Wtype_MAXp1_F;
+  /* The following two cases could be merged if we knew that the target
+     supported a native unsigned->float conversion.  More often, we only
+     have a signed conversion, and have to add extra fixup code.  */
+  else if (shift == W_TYPE_SIZE - 1)
+    e = Wtype_MAXp1_F / 2;
+  else
+    e = (Wtype)1 << shift;
+  return f * e;
 #endif
 }
 #endif
@@ -1532,11 +1536,7 @@ FUNC (DWtype u)
 #define F_MODE_OK(SIZE) \
   (SIZE < DI_SIZE                                                      \
    && SIZE > (DI_SIZE - SIZE + FSSIZE)                                 \
-   /* Don't use IBM Extended Double TFmode for TI->SF calculations.    \
-      The conversion from long double to float suffers from double     \
-      rounding, because we convert via double.  In any case, the       \
-      fallback code is faster.  */                                     \
-   && !IS_IBM_EXTENDED (SIZE))
+   && !AVOID_FP_TYPE_CONVERSION(SIZE))
 #if defined(L_floatundisf)
 #define FUNC __floatundisf
 #define FSTYPE SFtype
@@ -1620,13 +1620,21 @@ FUNC (UDWtype u)
   hi = u >> shift;
 
   /* If we lost any nonzero bits, set the lsb to ensure correct rounding.  */
-  if (u & (((UDWtype)1 << shift) - 1))
+  if ((UWtype)u << (W_TYPE_SIZE - shift))
     hi |= 1;
 
   /* Convert the one word of data, and rescale.  */
-  FSTYPE f = hi;
-  f *= (UDWtype)1 << shift;
-  return f;
+  FSTYPE f = hi, e;
+  if (shift == W_TYPE_SIZE)
+    e = Wtype_MAXp1_F;
+  /* The following two cases could be merged if we knew that the target
+     supported a native unsigned->float conversion.  More often, we only
+     have a signed conversion, and have to add extra fixup code.  */
+  else if (shift == W_TYPE_SIZE - 1)
+    e = Wtype_MAXp1_F / 2;
+  else
+    e = (Wtype)1 << shift;
+  return f * e;
 #endif
 }
 #endif
index b1c749f0c99382f0c3577ceb4be69cb001da9132..c6084dc00faac15387badf47023fdc920a0ebdab 100644 (file)
@@ -115,10 +115,16 @@ extern void __eprintf (const char *, const char *, unsigned int, const char *)
 
 /* FIXME: This #ifdef probably should be removed, ie. enable the test
    for mips too.  */
+/* Don't use IBM Extended Double TFmode for TI->SF calculations.
+   The conversion from long double to float suffers from double
+   rounding, because we convert via double.  In other cases, going
+   through the software fp routines is much slower than the fallback.  */
 #ifdef __powerpc__
-#define IS_IBM_EXTENDED(SIZE) (SIZE == 106)
+#define AVOID_FP_TYPE_CONVERSION(SIZE) (SIZE == 106)
+#elif defined(WIDEST_HARDWARE_FP_SIZE)
+#define AVOID_FP_TYPE_CONVERSION(SIZE) (SIZE > WIDEST_HARDWARE_FP_SIZE)
 #else
-#define IS_IBM_EXTENDED(SIZE) 0
+#define AVOID_FP_TYPE_CONVERSION(SIZE) 0
 #endif
 
 /* In the first part of this file, we are interfacing to calls generated