This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
libio/floatconv.c fix
- To: gcc-patches at gcc dot gnu dot org
- Subject: libio/floatconv.c fix
- From: Toshiyasu Morita <tm at netcom dot com>
- Date: Sun, 30 Jan 2000 04:57:59 -0800 (PST)
- Cc: amylaar at cygnus dot com, taruna at cygnus dot com
There is a problem in that ostream has never been able to print out
floats/doubles properly when sizeof(double) == 2. This occurs on the
Hitachi SH toolchain when using the option -m4-single-only, and probably
on the d10v as well when __DOUBLE__!=64.
I traced the problem down to libio/floatconv.c. The file seems to support
32-bit doubles by setting the define _DOUBLE_IS_32_BITS, but this does
not actually work because #defines which set the properties of the double
(number of bits/shifts/bitmasks for exponent, etc) are still set for a
64-bit double.
So, the library thinks 32-bit doubles have 11 bits of exponent and 53
bits of mantissa, and (in little-endian mode) winds up grabbing a zero for
the exponent and the upper bits of the mantissa, which causes it to think
it's a denormalized number which is very very small, so it prints out the
number "3.0f" as "0e-40".
Anyway, here are my patches to fix the floating-point properties for
_DOUBLE_IS_32_BITS, and also a patch to fetch the exponent and the higher
bits of the mantissa from the correct longword in little-endian mode.
With these patches, I seem to be able to print float-point numbers properly
in both big and little-endian modes when using -m4-single-only.
Toshi
Sun Jan 30 04:14:42 PST 2000 Toshiyasu Morita (toshi.morita@sega.com)
* floatconv.c (Exp_shift, Exp_shift1, Exp_msk1, Exp_msk11, Exp_mask,
P, Bias, IEEE_Arith, Emin, Exp_1, Exp_11, Ebits, Frac_mask, Frac_mask1,
Ten_pmax, Bletch, Bndry_mask, Bndry_mask1, LSB, Sign_bit, Log2P,
Tiny0, Tiny1, Quick_max, Int_max, Infinite): New macros for
_DOUBLE_IS_32BITS case. Add comment on fixes.
(HIWORD, LOWORD): Fix definitions when _DOUBLE_IS_32BITS.
*** floatconv.c.bak Thu Jan 27 16:59:52 2000
--- floatconv.c Sun Jan 30 04:12:40 2000
*************** the executable file might be covered by
*** 46,51 ****
--- 46,53 ----
/* Some cleaning up by Per Bothner, bothner@cygnus.com, 1992, 1993.
Re-written to not need static variables
(except result, result_k, HIWORD, LOWORD). */
+ /* _DOUBLE_IS_32BITS parameters & various fixes added
+ by Toshiyasu Morita, toshi.morita@sega.com, 2000 */
/* Note that the checking of _DOUBLE_IS_32BITS is for use with the
cross targets that employ the newlib ieeefp.h header. -- brendan */
*************** union doubleword {
*** 181,192 ****
unsigned32 u[2];
};
! #ifdef IEEE_8087
#define HIWORD 1
#define LOWORD 0
#define TEST_ENDIANNESS /* nothing */
#else
! #if defined(IEEE_MC68k)
#define HIWORD 0
#define LOWORD 1
#define TEST_ENDIANNESS /* nothing */
--- 183,199 ----
unsigned32 u[2];
};
! #ifdef _DOUBLE_IS_32BITS
! #define HIWORD 0
! #define LOWORD 0
! #define TEST_ENDIANNESS /* nothing */
! #else
! #if defined(IEEE_8087) || defined(__LITTLE_ENDIAN__)
#define HIWORD 1
#define LOWORD 0
#define TEST_ENDIANNESS /* nothing */
#else
! #if defined(IEEE_MC68k) || defined(__BIG_ENDIAN__)
#define HIWORD 0
#define LOWORD 1
#define TEST_ENDIANNESS /* nothing */
*************** static void test_endianness()
*** 204,209 ****
--- 211,217 ----
#define TEST_ENDIANNESS if (HIWORD<0) test_endianness();
#endif
#endif
+ #endif
#if 0
union doubleword _temp;
*************** union doubleword _temp;
*** 256,261 ****
--- 264,297 ----
/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+ #ifdef _DOUBLE_IS_32BITS
+ #define Exp_shift 23
+ #define Exp_shift1 23
+ #define Exp_msk1 0x800000
+ #define Exp_msk11 0x800000
+ #define Exp_mask 0x7f800000
+ #define P 24
+ #define Bias 127
+ #define IEEE_Arith
+ #define Emin (-128)
+ #define Exp_1 0x3f800000
+ #define Exp_11 0x3f800000
+ #define Ebits 11
+ #define Frac_mask 0x7fffff
+ #define Frac_mask1 0x7fffff
+ #define Ten_pmax 10
+ #define Bletch 2
+ #define Bndry_mask 0x7fffff
+ #define Bndry_mask1 0x7fffff
+ #define LSB 1
+ #define Sign_bit 0x80000000
+ #define Log2P 1 /* Is this correct? */
+ #define Tiny0 1
+ #define Tiny1 0
+ #define Quick_max 5
+ #define Int_max 6
+ #define Infinite(x) (word0(x) == 0x7f800000) /* sufficient test for here */
+ #else
#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_Unknown)
#define Exp_shift 20
#define Exp_shift1 20
*************** union doubleword _temp;
*** 336,341 ****
--- 372,378 ----
#define Int_max 15
#endif
#endif
+ #endif /* _DOUBLE_IS_32BITS */
#ifndef IEEE_Arith
#define ROUND_BIASED