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

AltStyle によって変換されたページ (->オリジナル) /