From 5fb54b91980565f03b96cadfc55dff8ddf5236ca Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 24 Apr 2007 08:28:21 -0700 Subject: [PATCH] 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 --- gcc/ChangeLog | 9 +++++++++ gcc/libgcc2.c | 44 ++++++++++++++++++++++++++------------------ gcc/libgcc2.h | 10 ++++++++-- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9912ca74258..7cc6435ea02 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2007-04-24 Richard Henderson + + * 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 * dwarf2out.c (field_byte_offset): Move the existing logic diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c index 8c0c9d1122d..a026fff4a87 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 b1c749f0c99..c6084dc00fa 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 -- 2.30.2