This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Java floating-point mess
- From: Zack Weinberg <zack at codesourcery dot com>
- To: gcc at gcc dot gnu dot org
- Date: Thu, 4 Apr 2002 02:03:17 -0800
- Subject: Java floating-point mess
The Java front end has a number of places that assume not only that
the host and target floating point formats are identical, but that
both are IEEE. I've tried to get rid of them, but run afoul of its
not being possible to link real.o into gcjh -- it wants to drag in
most of the back end.
I've appended what I've got to this message. Suggestions would be
appreciated.
zw
===================================================================
Index: java/Make-lang.in
--- java/Make-lang.in 2002/03/29 21:46:26 1.82
+++ java/Make-lang.in 2002/04/04 10:02:52
@@ -107,7 +107,7 @@ JAVA_OBJS = java/parse.o java/class.o ja
java/jcf-path.o java/xref.o java/boehm.o mkdeps.o
GCJH_OBJS = java/gjavah.o java/jcf-io.o java/jcf-depend.o java/jcf-path.o \
- java/zextract.o version.o mkdeps.o errors.o
+ java/zextract.o version.o mkdeps.o errors.o real.o
JVSCAN_OBJS = java/parse-scan.o java/jv-scan.o version.o
@@ -278,7 +278,8 @@ java/expr.o: java/expr.c $(CONFIG_H) $(J
$(RTL_H) $(EXPR_H) java/javaop.h java/java-opcodes.h except.h \
java/java-except.h java/java-except.h java/parse.h toplev.h \
$(SYSTEM_H) $(GGC_H)
-java/jcf-depend.o: java/jcf-depend.c $(CONFIG_H) $(SYSTEM_H) java/jcf.h
+java/jcf-depend.o: java/jcf-depend.c $(CONFIG_H) $(SYSTEM_H) java/jcf.h \
+ real.h $(MACHMODE_H)
java/jcf-parse.o: java/jcf-parse.c $(CONFIG_H) $(JAVA_TREE_H) flags.h \
input.h java/java-except.h $(SYSTEM_H) toplev.h java/parse.h $(GGC_H) \
debug.h
@@ -310,7 +311,8 @@ java/jcf-io.o: java/jcf-io.c $(CONFIG_H)
$(srcdir)/java/jcf-io.c $(OUTPUT_OPTION)
# jcf-path.o needs a -D.
-java/jcf-path.o: java/jcf-path.c $(CONFIG_H) $(SYSTEM_H) java/jcf.h
+java/jcf-path.o: java/jcf-path.c $(CONFIG_H) $(SYSTEM_H) java/jcf.h \
+ real.h $(MACHMODE_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DLIBGCJ_ZIP_FILE='"$(prefix)/share/libgcj.jar"' \
$(srcdir)/java/jcf-path.c $(OUTPUT_OPTION)
===================================================================
Index: java/constants.c
--- java/constants.c 2001/04/26 18:32:22 1.19
+++ java/constants.c 2002/04/04 10:02:52
@@ -23,9 +23,9 @@ The Free Software Foundation is independ
#include "config.h"
#include "system.h"
-#include "jcf.h"
#include "tree.h"
#include "java-tree.h"
+#include "jcf.h"
#include "toplev.h"
#include "ggc.h"
===================================================================
Index: java/gjavah.c
--- java/gjavah.c 2002/03/03 08:35:11 1.85
+++ java/gjavah.c 2002/04/04 10:02:52
@@ -28,10 +28,10 @@ The Free Software Foundation is independ
#include "system.h"
#include <math.h>
-#include "jcf.h"
#include "tree.h"
-#include "javaop.h"
#include "java-tree.h"
+#include "javaop.h"
+#include "jcf.h"
#include "java-opcodes.h"
#include <getopt.h>
@@ -130,8 +130,6 @@ static void print_full_cxx_name PARAMS (
static void decompile_method PARAMS ((FILE*, JCF*, int));
static void add_class_decl PARAMS ((FILE*, JCF*, JCF_u2));
-static int java_float_finite PARAMS ((jfloat));
-static int java_double_finite PARAMS ((jdouble));
static void print_name PARAMS ((FILE *, JCF *, int));
static void print_base_classname PARAMS ((FILE *, JCF *, int));
static int utf8_cmp PARAMS ((const unsigned char *, int, const char *));
@@ -237,40 +235,6 @@ 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 (f)
- 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;
-}
-
-/* Return 1 if D is not Inf or NaN. */
-static int
-java_double_finite (d)
- jdouble d;
-{
- union DWord u;
- u.d = d;
-
- /* Now check for all NaNs. */
- return (u.l & D_NAN_MASK) != D_NAN_MASK;
-}
-
/* Print a character, appropriately mangled for JNI. */
static void
@@ -747,24 +711,32 @@ DEFUN(print_field_info, (stream, jcf, na
break;
case CONSTANT_Float:
{
- jfloat fnum = JPOOL_FLOAT (jcf, current_field_value);
+ REAL_VALUE_TYPE fnum = JPOOL_FLOAT (jcf, current_field_value);
+ char s[30];
fputs ("const jfloat ", out);
print_field_name (out, jcf, name_index, 0);
- if (! java_float_finite (fnum))
+ if (REAL_VALUE_ISINF (fnum) || REAL_VALUE_ISNAN (fnum))
fputs (";\n", out);
else
- fprintf (out, " = %.10g;\n", fnum);
+ {
+ REAL_VALUE_TO_DECIMAL (fnum, "%.10g", s);
+ fprintf (out, " = %s;\n", s);
+ }
}
break;
case CONSTANT_Double:
{
- jdouble dnum = JPOOL_DOUBLE (jcf, current_field_value);
+ REAL_VALUE_TYPE fnum = JPOOL_DOUBLE (jcf, current_field_value);
+ char s[30];
fputs ("const jdouble ", out);
print_field_name (out, jcf, name_index, 0);
- if (! java_double_finite (dnum))
+ if (REAL_VALUE_ISINF (fnum) || REAL_VALUE_ISNAN (fnum))
fputs (";\n", out);
else
- fprintf (out, " = %.17g;\n", dnum);
+ {
+ REAL_VALUE_TO_DECIMAL (fnum, "%.17g", s);
+ fprintf (out, " = %s;\n", s);
+ }
}
break;
default:
===================================================================
Index: java/javaop.h
--- java/javaop.h 2001/05/26 01:31:47 1.10
+++ java/javaop.h 2002/04/04 10:02:52
@@ -57,27 +57,15 @@ 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 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. */
+ 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,11 +90,10 @@ union Word {
| (BCODE[PC-2] << 8) | (BCODE[PC-1]))))
#endif
-static inline jfloat
+static inline REAL_VALUE_TYPE
WORD_TO_FLOAT(jword w)
-{ union Word wu;
- wu.i = w;
- return wu.f;
+{
+ return REAL_VALUE_FROM_TARGET_SINGLE (w);
}
/* Sign extend w. If the host on which this cross-compiler runs uses
@@ -129,20 +116,30 @@ WORDS_TO_LONG(jword hi, jword lo)
}
union DWord {
- jdouble d;
jlong l;
jword w[2];
};
-static inline jdouble
+static inline REAL_VALUE_TYPE
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;
+{
+ HOST_WIDE_INT h[2];
+ if (HOST_BITS_PER_WIDE_INT == 64)
+ {
+ h[0] = WORDS_TO_LONG (hi, lo);
+ h[1] = 0;
+ }
+ else if (FLOAT_WORDS_BIG_ENDIAN)
+ {
+ h[0] = hi;
+ h[1] = lo;
+ }
+ else
+ {
+ h[1] = hi;
+ h[0] = lo;
+ }
+ return REAL_VALUE_FROM_TARGET_DOUBLE (h);
}
/* If PREFIX_CHAR is the first character of the Utf8 encoding of a character,
===================================================================
Index: java/jcf-depend.c
--- java/jcf-depend.c 2001/01/05 07:50:24 1.13
+++ java/jcf-depend.c 2002/04/04 10:02:52
@@ -29,6 +29,8 @@ The Free Software Foundation is independ
#include <assert.h>
+#include "machmode.h"
+#include "real.h"
#include "jcf.h"
===================================================================
Index: java/jcf-dump.c
--- java/jcf-dump.c 2002/03/03 08:35:11 1.43
+++ java/jcf-dump.c 2002/04/04 10:02:53
@@ -504,16 +504,22 @@ DEFUN(print_constant, (out, jcf, index,
break;
case CONSTANT_Float:
{
- jfloat fnum = JPOOL_FLOAT (jcf, index);
- fprintf (out, "%s%.10g", verbosity > 0 ? "Float " : "", (double) fnum);
+ char s[30];
+ REAL_VALUE_TYPE r = JPOOL_FLOAT (jcf, index);
+ REAL_VALUE_TO_DECIMAL (r, "%.10g", s);
+
+ fprintf (out, "%s%s", verbosity > 0 ? "Float " : "", s);
if (verbosity > 1)
- fprintf (out, ", bits = 0x%08lx", (long) (* (int32 *) &fnum));
+ fprintf (out, ", bits = 0x%08lx", (long) JPOOL_UINT (jcf, index));
break;
}
case CONSTANT_Double:
{
- jdouble dnum = JPOOL_DOUBLE (jcf, index);
- fprintf (out, "%s%.20g", verbosity > 0 ? "Double " : "", dnum);
+ char s[30];
+ REAL_VALUE_TYPE r = JPOOL_DOUBLE (jcf, index);
+ REAL_VALUE_TO_DECIMAL (r, "%.20g", s);
+
+ fprintf (out, "%s%s", verbosity > 0 ? "Double " : "", s);
if (verbosity > 1)
{
int32 hi, lo;
===================================================================
Index: java/jcf-io.c
--- java/jcf-io.c 2001/12/03 19:13:40 1.33
+++ java/jcf-io.c 2002/04/04 10:02:53
@@ -25,10 +25,10 @@ The Free Software Foundation is independ
#include "config.h"
#include "system.h"
-#include "jcf.h"
#include "tree.h"
#include "toplev.h"
#include "java-tree.h"
+#include "jcf.h"
#include "zlib.h"
===================================================================
Index: java/jcf-path.c
--- java/jcf-path.c 2002/03/03 08:35:11 1.19
+++ java/jcf-path.c 2002/04/04 10:02:53
@@ -26,6 +26,8 @@ The Free Software Foundation is independ
#include "config.h"
#include "system.h"
+#include "machmode.h"
+#include "real.h"
#include "jcf.h"
/* Some boilerplate that really belongs in a header. */
===================================================================
Index: java/jcf-write.c
--- java/jcf-write.c 2002/03/12 10:32:38 1.100
+++ java/jcf-write.c 2002/04/04 10:02:53
@@ -23,9 +23,9 @@ The Free Software Foundation is independ
#include "config.h"
#include "system.h"
-#include "jcf.h"
#include "tree.h"
#include "java-tree.h"
+#include "jcf.h"
#include "obstack.h"
#undef AND
#include "rtl.h"
===================================================================
Index: java/jvgenmain.c
--- java/jvgenmain.c 2001/11/27 17:31:38 1.28
+++ java/jvgenmain.c 2002/04/04 10:02:54
@@ -27,9 +27,9 @@ The Free Software Foundation is independ
#include "config.h"
#include "system.h"
#include "obstack.h"
-#include "jcf.h"
#include "tree.h"
#include "java-tree.h"
+#include "jcf.h"
static char * do_mangle_classname PARAMS ((const char *string));
===================================================================
Index: java/mangle.c
--- java/mangle.c 2001/12/20 22:48:51 1.21
+++ java/mangle.c 2002/04/04 10:02:54
@@ -27,9 +27,9 @@ The Free Software Foundation is independ
#include "config.h"
#include "system.h"
-#include "jcf.h"
#include "tree.h"
#include "java-tree.h"
+#include "jcf.h"
#include "obstack.h"
#include "toplev.h"
#include "obstack.h"
===================================================================
Index: java/mangle_name.c
--- java/mangle_name.c 2001/12/20 22:48:51 1.4
+++ java/mangle_name.c 2002/04/04 10:02:54
@@ -27,9 +27,9 @@ The Free Software Foundation is independ
#include "config.h"
#include "system.h"
-#include "jcf.h"
#include "tree.h"
#include "java-tree.h"
+#include "jcf.h"
#include "obstack.h"
#include "toplev.h"
#include "obstack.h"