This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

libio/floatconv.c fix


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]