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