Squelch HOST_FLOAT_WORDS_BIG_ENDIAN

Zack Weinberg zack@codesourcery.com
Wed Mar 12 09:10:00 GMT 2003


This patch removes the last remaining use of HOST_FLOAT_WORDS_BIG_ENDIAN 
from GCC.  As HOST_FLOAT_FORMAT was already unused, that means
gcc_AC_C_FLOAT_FORMAT and gcc_AC_EXAMINE_OBJECT can follow it to the
junk pile.

The change to aclocal.m4, configure.in, and defaults.h are
uncontroversial assuming that they can be made at all.  I would
appreciate a second opinion on the changes to gjavah.c, javaop.h, and
jcf-dump.c.  What I did was turn jfloat and jdouble into structures,
and then have WORD_TO_FLOAT/WORDS_TO_LONG unpack their input into
these structures using integer arithmetic.  Java .class files are
specified to be big-endian, so we don't need to worry about that.
Then, on the output side, I emit C99-style hexadecimal floating
constants, which can be done using pure integer arithmetic.  Thus, no
need to know anything about the host's floating point.  Hexadecimal
floating constants are not yet a feature of standard C++, but g++
accepts them, and gjavah-generated headers are probably going to be
used with g++, so that should be fine.  I may not have gotten that
part 100% correct.

Bootstrapped i686-linux without regressions, and I did a cursory test
to make sure jcf-dump did something plausible.  I wasn't able to get
gjavah to exercise this code.  I don't know if this stuff gets tested
by the libjava testsuite.

Comments please?

zw

java:
         * javaop.h (jfloat, jdouble): Now structures.
         (Word, DWord): Delete, no longer used.
         (WORD_TO_FLOAT, WORDS_TO_DOUBLE): Update to match new
         definition of jfloat, jdouble respectively.
         * gjavah.c (F_NAN_MASK, D_NAN_MASK): Delete.
         (java_float_finite, java_double_finite): Update to match new
         definitions of jfloat, jdouble.
         (print_field_info): Generate hexadecimal floating constants;
         don't use host floating point.
         * jcf-dump.c (print_constant): Likewise.

gcc:
        * aclocal.m4 (gcc_AC_EXAMINE_OBJECT, gcc_AC_C_FLOAT_FORMAT): Delete.
        * configure.in: Don't call gcc_AC_C_FLOAT_FORMAT.
        * defaults.h: Remove reference to HOST_FLOAT_WORDS_BIG_ENDIAN
        in comment.

===================================================================
Index: java/javaop.h
--- java/javaop.h	18 Jan 2003 22:15:51 -0000	1.13
+++ java/javaop.h	12 Mar 2003 08:53:02 -0000
@@ -55,27 +55,25 @@ typedef int32                   jint;
 typedef int64                   jlong;
 typedef void*                   jref;
 
-/* A 32-bit IEEE single-precision float. */
-#ifndef jfloat 
-#define jfloat float
-#endif
-
-/* A 32-bit IEEE double-precision float. */
-#ifndef jdouble
-#define jdouble double
-#endif
-
-union Word {
-  jint i;
-  jfloat f;
-  void *p;
-};
+/* A 32-bit big-endian IEEE single-precision float. */
+typedef struct _jfloat {
+  unsigned int negative : 1;
+  unsigned int exponent : 8;
+  unsigned int mantissa : 23;
+} jfloat;
+
+/* A 32-bit big-endian IEEE double-precision float. */
+typedef struct _jdouble {
+  unsigned int negative : 1;
+  unsigned int exponent : 11;
+  unsigned int mantissa0: 20;
+  unsigned int mantissa1: 32;
+} jdouble;
 
 /* A jword is an unsigned integral type big enough for a 32-bit jint
    or jfloat *or* a pointer.  It is the type appropriate for stack
    locations and local variables in a Java interpreter. */
 
-
 #ifndef jword
 #define jword uint32
 #endif
@@ -102,9 +100,14 @@ union Word {
 
 static inline jfloat
 WORD_TO_FLOAT(jword w)
-{ union Word wu;
-  wu.i = w;
-  return wu.f;
+{
+  jfloat f;
+
+  f.negative = (w & 0x80000000) >> 31;
+  f.exponent = (w & 0x7f800000) >> 23;
+  f.mantissa = (w & 0x007fffff);
+
+  return f;
 } 
 
 /* Sign extend w.  If the host on which this cross-compiler runs uses
@@ -126,21 +129,17 @@ WORDS_TO_LONG(jword hi, jword lo)
   return ((jlong) hi << 32) | ((jlong)lo & (((jlong)1 << 32) -1));
 }
 
-union DWord {
-  jdouble d;
-  jlong l;
-  jword w[2];
-};
-
 static inline jdouble
 WORDS_TO_DOUBLE(jword hi, jword lo)
-{ union DWord wu;
-#if (1 == HOST_FLOAT_WORDS_BIG_ENDIAN)
-  wu.l = WORDS_TO_LONG(lo, hi);
-#else
-  wu.l = WORDS_TO_LONG(hi, lo);
-#endif
-  return wu.d;
+{
+  jdouble d;
+
+  d.negative  = (hi & 0x80000000) >> 31;
+  d.exponent  = (hi & 0x7ff00000) >> 20;
+  d.mantissa0 = (hi & 0x000fffff);
+  d.mantissa1 = lo;
+
+  return d;
 } 
 
 /* If PREFIX_CHAR is the first character of the Utf8 encoding of a character,
===================================================================
Index: java/gjavah.c
--- java/gjavah.c	1 Feb 2003 01:31:31 -0000	1.104
+++ java/gjavah.c	12 Mar 2003 08:53:02 -0000
@@ -244,36 +244,22 @@ static int decompiled = 0;
 
 #include "jcf-reader.c"
 
-/* Some useful constants.  */
-#define F_NAN_MASK 0x7f800000
-#if (1 == HOST_FLOAT_WORDS_BIG_ENDIAN) && ! defined (HOST_WORDS_BIG_ENDIAN)
-#define D_NAN_MASK 0x000000007ff00000LL
-#else
-#define D_NAN_MASK 0x7ff0000000000000LL
-#endif
-
 /* Return 1 if F is not Inf or NaN.  */
 static int
 java_float_finite (jfloat f)
 {
-  union Word u;
-  u.f = f;
-
-  /* We happen to know that F_NAN_MASK will match all NaN values, and
-     also positive and negative infinity.  That's why we only need one
-     test here.  See The Java Language Specification, section 20.9.  */
-  return (u.i & F_NAN_MASK) != F_NAN_MASK;
+  /* An IEEE float with all 8 bits of its exponent set is either
+     infinite or NaN.  */
+  return (f.exponent == 0xFF);
 }
 
 /* Return 1 if D is not Inf or NaN.  */
 static int
 java_double_finite (jdouble d)
 {
-  union DWord u;
-  u.d = d;
-
-  /* Now check for all NaNs.  */
-  return (u.l & D_NAN_MASK) != D_NAN_MASK;
+  /* An IEEE double with all 11 bits of its exponent set is either
+     infinite or NaN.  */
+  return (d.exponent == 0x7FF);
 }
 
 /* Print a character, appropriately mangled for JNI.  */
@@ -729,10 +715,14 @@ print_field_info (FILE *stream, JCF* jcf
 		jfloat fnum = JPOOL_FLOAT (jcf, current_field_value);
 		fputs ("const jfloat ", out);
 		print_field_name (out, jcf, name_index, 0);
+		/* C99 doesn't allow use of hexadecimal floating constants
+		   to represent infinities and NaN.  Bleh.  */
 		if (! java_float_finite (fnum))
 		  fputs (";\n", out);
 		else
-		  fprintf (out, " = %.10g;\n",  fnum);
+		  fprintf (out, " = %c0x1.%xp%+d;\n",
+			   fnum.negative ? '-' : ' ',
+			   fnum.mantissa, fnum.exponent);
 	      }
 	      break;
 	    case CONSTANT_Double:
@@ -743,7 +733,10 @@ print_field_info (FILE *stream, JCF* jcf
 		if (! java_double_finite (dnum))
 		  fputs (";\n", out);
 		else
-		  fprintf (out, " = %.17g;\n",  dnum);
+		  fprintf (out, " = %c0x1.%x%08xp%+d;\n",
+			   dnum.negative ? '-' : ' ',
+			   dnum.mantissa0, dnum.mantissa1,
+			   dnum.exponent);
 	      }
 	      break;
 	    default:
===================================================================
Index: java/jcf-dump.c
--- java/jcf-dump.c	18 Jan 2003 22:15:51 -0000	1.55
+++ java/jcf-dump.c	12 Mar 2003 08:53:02 -0000
@@ -504,24 +504,24 @@ print_constant (FILE *out, JCF *jcf, int
       break;
     case CONSTANT_Float:
       {
-	union
-	{
-	  jfloat f;
-	  int32 i;
-	} pun;
-	
-	pun.f = JPOOL_FLOAT (jcf, index);
-	fprintf (out, "%s%.10g",
-		 verbosity > 0 ? "Float " : "", (double) pun.f);
+	jfloat fnum = JPOOL_FLOAT (jcf, index);
+	fprintf (out, "%s%c0x1.%xp%+d",
+		 verbosity > 0 ? "Float " : "",
+		 fnum.negative ? '-' : ' ',
+		 fnum.mantissa, fnum.exponent);
 	if (verbosity > 1)
-	  fprintf (out, ", bits = 0x%08lx", (long) pun.i);
+	  fprintf (out, ", bits = 0x%08lx", JPOOL_UINT (jcf, index));
 	
 	break;
       }
     case CONSTANT_Double:
       {
 	jdouble dnum = JPOOL_DOUBLE (jcf, index);
-	fprintf (out, "%s%.20g", verbosity > 0 ? "Double " : "", dnum);
+	fprintf (out, "%s%c0x1.%x%08xp%+d",
+		 verbosity > 0 ? "Double " : "",
+		 dnum.negative ? '-' : ' ',
+		 dnum.mantissa0, dnum.mantissa1,
+		 dnum.exponent);
 	if (verbosity > 1)
 	  {
 	    int32 hi, lo;
===================================================================
Index: aclocal.m4
--- aclocal.m4	13 Jan 2003 17:23:25 -0000	1.65
+++ aclocal.m4	12 Mar 2003 08:52:58 -0000
@@ -885,145 +885,6 @@ elif test $ac_cv_c_charset = EBCDIC; the
   [Define if the host execution character set is EBCDIC.])
 fi])
 
-dnl Utility macro used by next two tests.
-dnl AC_EXAMINE_OBJECT(C source code,
-dnl	commands examining object file,
-dnl	[commands to run if compile failed]):
-dnl
-dnl Compile the source code to an object file; then convert it into a
-dnl printable representation.  All unprintable characters and
-dnl asterisks (*) are replaced by dots (.).  All white space is
-dnl deleted.  Newlines (ASCII 0x10) in the input are preserved in the
-dnl output, but runs of newlines are compressed to a single newline.
-dnl Finally, line breaks are forcibly inserted so that no line is
-dnl longer than 80 columns and the file ends with a newline.  The
-dnl result of all this processing is in the file conftest.dmp, which
-dnl may be examined by the commands in the second argument.
-dnl
-AC_DEFUN([gcc_AC_EXAMINE_OBJECT],
-[AC_LANG_SAVE
-AC_LANG_C
-dnl Next bit cribbed from AC_TRY_COMPILE.
-cat > conftest.$ac_ext <<EOF
-[#line __oline__ "configure"
-#include "confdefs.h"
-$1
-]EOF
-if AC_TRY_EVAL(ac_compile); then
-  od -c conftest.o |
-    sed ['s/^[0-7]*[ 	]*/ /
-	  s/\*/./g
-	  s/ \\n/*/g
-	  s/ [0-9][0-9][0-9]/./g
-	  s/  \\[^ ]/./g'] |
-    tr -d '
- ' | tr -s '*' '
-' | fold | sed '$a\
-' > conftest.dmp
-  $2
-ifelse($3, , , else
-  $3
-)dnl
-fi
-rm -rf conftest*
-AC_LANG_RESTORE])
-
-dnl Floating point format probe.
-dnl The basic concept is the same as the above: grep the object
-dnl file for an interesting string.  We have to watch out for
-dnl rounding changing the values in the object, however; this is
-dnl handled by ignoring the least significant byte of the float.
-dnl
-dnl Does not know about VAX G-float or C4x idiosyncratic format.
-dnl It does know about PDP-10 idiosyncratic format, but this is
-dnl not presently supported by GCC.  S/390 "binary floating point"
-dnl is in fact IEEE (but maybe we should have that in EBCDIC as well
-dnl as ASCII?)
-dnl
-AC_DEFUN([gcc_AC_C_FLOAT_FORMAT],
-[AC_CACHE_CHECK(floating point format, ac_cv_c_float_format,
-[gcc_AC_EXAMINE_OBJECT(
-[/* This will not work unless sizeof(double) == 8.  */
-extern char sizeof_double_must_be_8 [sizeof(double) == 8 ? 1 : -1];
-
-/* This structure must have no internal padding.  */
-struct possibility {
-  char prefix[8];
-  double candidate;
-  char postfix[8];
-};
-
-#define C(cand) { "\nformat:", cand, ":tamrof\n" }
-struct possibility table [] =
-{
-  C( 3.25724264705901305206e+01), /* @@IEEEFP - IEEE 754 */
-  C( 3.53802595280598432000e+18), /* D__float - VAX */
-  C( 5.32201830133125317057e-19), /* D.PDP-10 - PDP-10 - the dot is 0x13a */
-  C( 1.77977764695171661377e+10), /* IBMHEXFP - s/390 format, ascii */
-  C(-5.22995989424860458374e+10)  /* IBMHEXFP - s/390 format, EBCDIC */
-};],
- [if   grep 'format:.@IEEEF.:tamrof' conftest.dmp >/dev/null 2>&1; then
-    ac_cv_c_float_format='IEEE (big-endian)'
-  elif grep 'format:.I@@PFE.:tamrof' conftest.dmp >/dev/null 2>&1; then
-    ac_cv_c_float_format='IEEE (big-endian)'
-  elif grep 'format:.FEEEI@.:tamrof' conftest.dmp >/dev/null 2>&1; then
-    ac_cv_c_float_format='IEEE (little-endian)'
-  elif grep 'format:.EFP@@I.:tamrof' conftest.dmp >/dev/null 2>&1; then
-    ac_cv_c_float_format='IEEE (little-endian)'
-  elif grep 'format:.__floa.:tamrof' conftest.dmp >/dev/null 2>&1; then
-    ac_cv_c_float_format='VAX D-float'
-  elif grep 'format:..PDP-1.:tamrof' conftest.dmp >/dev/null 2>&1; then
-    ac_cv_c_float_format='PDP-10'
-  elif grep 'format:.BMHEXF.:tamrof' conftest.dmp >/dev/null 2>&1; then
-    ac_cv_c_float_format='IBM 370 hex'
-  else
-    AC_MSG_ERROR(Unknown floating point format)
-  fi],
-  [AC_MSG_ERROR(compile failed)])
-])
-# IEEE is the default format.  If the float endianness isn't the same
-# as the integer endianness, we have to set FLOAT_WORDS_BIG_ENDIAN
-# (which is a tristate: yes, no, default).  This is only an issue with
-# IEEE; the other formats are only supported by a few machines each,
-# all with the same endianness.
-format=
-fbigend=
-case $ac_cv_c_float_format in
-    'IEEE (big-endian)' )
-	if test $ac_cv_c_bigendian = no; then
-	    fbigend=1
-	fi
-	;;
-    'IEEE (little-endian)' )
-	if test $ac_cv_c_bigendian = yes; then
-	    fbigend=0
-	fi
-	;;
-    'VAX D-float' )
-	format=VAX_FLOAT_FORMAT
-	;;
-    'PDP-10' )
-	format=PDP10_FLOAT_FORMAT
-	;;
-    'IBM 370 hex' )
-	format=IBM_FLOAT_FORMAT
-	;;
-esac
-if test -n "$format"; then
-	AC_DEFINE_UNQUOTED(HOST_FLOAT_FORMAT, $format,
-  [Define to the floating point format of the host machine, if not IEEE.])
-fi
-if test -n "$fbigend"; then
-	AC_DEFINE_UNQUOTED(HOST_FLOAT_WORDS_BIG_ENDIAN, $fbigend,
-  [Define to 1 if the host machine stores floating point numbers in
-   memory with the word containing the sign bit at the lowest address,
-   or to 0 if it does it the other way around.
-
-   This macro should not be defined if the ordering is the same as for
-   multi-word integers.])
-fi
-])
-
 #serial AM2
 
 dnl From Bruno Haible.
===================================================================
Index: configure.in
--- configure.in	4 Mar 2003 21:48:51 -0000	1.649
+++ configure.in	12 Mar 2003 08:53:01 -0000
@@ -642,7 +642,6 @@ AC_CHECK_HEADER(pthread.h, [have_pthread
 # These tests can't be done till we know if we have limits.h.
 gcc_AC_C_CHAR_BIT
 AC_C_BIGENDIAN_CROSS
-gcc_AC_C_FLOAT_FORMAT
 
 # See if we have the mktemp command.
 AC_CHECK_PROG(have_mktemp_command, mktemp, yes, no)
===================================================================
Index: defaults.h
--- defaults.h	5 Feb 2003 22:37:51 -0000	1.102
+++ defaults.h	12 Mar 2003 08:53:01 -0000
@@ -572,9 +572,8 @@ You Lose!  You must define PREFERRED_DEB
    && !ROUND_TOWARDS_ZERO)
 #endif
 
-/* If FLOAT_WORDS_BIG_ENDIAN and HOST_FLOAT_WORDS_BIG_ENDIAN are not defined
-   in the header files, then this implies the word-endianness is the same as
-   for integers.  */
+/* If FLOAT_WORDS_BIG_ENDIAN is not defined in the header files,
+   then the word-endianness is the same as for integers.  */
 #ifndef FLOAT_WORDS_BIG_ENDIAN
 #define FLOAT_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
 #endif



More information about the Java mailing list