aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2007-04-24 08:28:21 -0700
committerRichard Henderson <rth@gcc.gnu.org>2007-04-24 08:28:21 -0700
commit5fb54b91980565f03b96cadfc55dff8ddf5236ca (patch)
tree02de3c14605545c31467f9847eec2443b8c6117d /gcc
parent688518053c61ccb6d52aa647d6ba6b04fdc1b04c (diff)
downloadgcc-5fb54b91980565f03b96cadfc55dff8ddf5236ca.zip
gcc-5fb54b91980565f03b96cadfc55dff8ddf5236ca.tar.gz
gcc-5fb54b91980565f03b96cadfc55dff8ddf5236ca.tar.bz2
libgcc2.h (AVOID_FP_TYPE_CONVERSION): Rename from IS_IBM_EXTENDED.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/libgcc2.c44
-rw-r--r--gcc/libgcc2.h10
3 files changed, 43 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9912ca7..7cc6435 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index 8c0c9d1..a026fff 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -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
diff --git a/gcc/libgcc2.h b/gcc/libgcc2.h
index b1c749f..c6084dc 100644
--- a/gcc/libgcc2.h
+++ b/gcc/libgcc2.h
@@ -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