summaryrefslogtreecommitdiff
path: root/gcc/java
diff options
context:
space:
mode:
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-21 17:10:02 +0000
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-21 17:10:02 +0000
commit778ba491062e7454fdec2fe4e7667f3500b10c44 (patch)
treef92bcd0dd5b17043f1634195bcbf18c4df1df8da /gcc/java
parent7f6007b45f71f43498b27d8fa69bc151fe9976f5 (diff)
downloadgcc-778ba491062e7454fdec2fe4e7667f3500b10c44.tar.gz
* javaop.h (jfloat, jdouble): Make them structures mirroring
the bit fields of IEEE float and double respectively. (JFLOAT_FINITE, JFLOAT_QNAN_MASK, JFLOAT_EXP_BIAS, JDOUBLE_FINITE, JDOUBLE_QNAN_MASK, JDOUBLE_EXP_BIAS): New. (union Word, union DWord): Delete. (WORD_TO_FLOAT, WORDS_TO_DOUBLE): Update to match. * gjavah.c (java_float_finite, java_double_finite, F_NAN_MASK, D_NAN_MASK): Delete. (jni_print_float, jni_print_double): New. Generate hexadecimal floating constants. (print_field_info): Use jni_print_float/double. * jcf-dump.c: Include math.h. Use ldexp/frexp to assemble finite floating point numbers for output; special case non-finite floats. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@64671 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java')
-rw-r--r--gcc/java/ChangeLog39
-rw-r--r--gcc/java/gjavah.c84
-rw-r--r--gcc/java/javaop.h68
-rw-r--r--gcc/java/jcf-dump.c85
4 files changed, 188 insertions, 88 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index db5651b37e2..1b980aea610 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,22 @@
+2003-03-21 Zack Weinberg <zack@codesourcery.com>
+
+ * javaop.h (jfloat, jdouble): Make them structures mirroring
+ the bit fields of IEEE float and double respectively.
+ (JFLOAT_FINITE, JFLOAT_QNAN_MASK, JFLOAT_EXP_BIAS,
+ JDOUBLE_FINITE, JDOUBLE_QNAN_MASK, JDOUBLE_EXP_BIAS): New.
+ (union Word, union DWord): Delete.
+ (WORD_TO_FLOAT, WORDS_TO_DOUBLE): Update to match.
+
+ * gjavah.c (java_float_finite, java_double_finite, F_NAN_MASK,
+ D_NAN_MASK): Delete.
+ (jni_print_float, jni_print_double): New. Generate
+ hexadecimal floating constants.
+ (print_field_info): Use jni_print_float/double.
+
+ * jcf-dump.c: Include math.h. Use ldexp/frexp to assemble
+ finite floating point numbers for output; special case
+ non-finite floats.
+
2003-03-19 Nathanael Nerode <neroden@gcc.gnu.org>
* lang.c (java_dump_tree): Change return type from 'int' to 'bool'.
@@ -16,10 +35,10 @@
2003-03-04 Andrew Haley <aph@redhat.com>
- * gjavah.c (is_first_data_member): New global variable.
- (print_c_decl): If it's the first data member, align it as the
- superclass.
- (process_file): Set is_first_data_member.
+ * gjavah.c (is_first_data_member): New global variable.
+ (print_c_decl): If it's the first data member, align it as the
+ superclass.
+ (process_file): Set is_first_data_member.
2003-03-11 Tom Tromey <tromey@redhat.com>
@@ -57,7 +76,7 @@
"strcmp" to compare file name components.
Use IS_DIR_SEPARATOR instead of comparing directly against
DIR_SEPARATOR.
- (jcf_path_extdirs_arg): Use IS_DIR_SEPARATOR instead of
+ (jcf_path_extdirs_arg): Use IS_DIR_SEPARATOR instead of
comparing directly against DIR_SEPARATOR.
2003-03-04 Tom Tromey <tromey@redhat.com>
@@ -91,7 +110,7 @@
* java/decl.c (java_init_decl_processing): Get soft_fmod_node from
built_in_decls[BUILT_IN_FMOD] rather than define it ourselves.
-
+
2003-02-23 Tom Tromey <tromey@redhat.com>
* lang-options.h: Added -Wdeprecated.
@@ -133,12 +152,12 @@
2003-02-12 Ranjit Mathew <rmathew@hotmail.com>
- * decl.c (java_init_decl_processing): Change
+ * decl.c (java_init_decl_processing): Change
soft_lookupjnimethod_node to reflect the change in
signature of _Jv_LookupJNIMethod in libjava/jni.cc
* expr.c (build_jni_stub): Calculate and pass the size
on the stack of the arguments to a JNI function. Use
- new target macro MODIFY_JNI_METHOD_CALL to allow a
+ new target macro MODIFY_JNI_METHOD_CALL to allow a
target to modify the call to a JNI method.
2003-02-08 Roger Sayle <roger@eyesopen.com>
@@ -324,7 +343,7 @@
2003-01-14 Andrew Haley <aph@redhat.com>
* decl.c (java_init_decl_processing): _Jv_NewMultiArray is a
- varargs function -- correct.
+ varargs function -- correct.
2003-01-14 Andrew Haley <aph@redhat.com>
@@ -571,7 +590,7 @@
* gcj.texi: Change version number to 3.4.
2002-12-05 Ranjit Mathew <rmathew@hotmail.com>
- Andrew Haley <aph@redhat.com>
+ Andrew Haley <aph@redhat.com>
* parse.y (source_end_java_method): Remove custom encoding of line
numbers for a function decl before passing it to the back end.
diff --git a/gcc/java/gjavah.c b/gcc/java/gjavah.c
index 23af65ab352..51cfe7cffbc 100644
--- a/gcc/java/gjavah.c
+++ b/gcc/java/gjavah.c
@@ -134,8 +134,6 @@ static void print_full_cxx_name (FILE*, JCF*, int, int, int, const char *, int);
static void decompile_method (FILE*, JCF*, int);
static void add_class_decl (FILE*, JCF*, JCF_u2);
-static int java_float_finite (jfloat);
-static int java_double_finite (jdouble);
static void print_name (FILE *, JCF *, int);
static void print_base_classname (FILE *, JCF *, int);
static int utf8_cmp (const unsigned char *, int, const char *);
@@ -158,6 +156,8 @@ static void version (void) ATTRIBUTE_NORETURN;
static int overloaded_jni_method_exists_p (const unsigned char *, int,
const char *, int);
static void jni_print_char (FILE *, int);
+static void jni_print_float (FILE *, jfloat);
+static void jni_print_double (FILE *, jdouble);
static void decompile_return_statement (FILE *, JCF *, int, int, int);
JCF_u2 current_field_name;
@@ -247,36 +247,54 @@ 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)
+/* Print a single-precision float, suitable for parsing by g++. */
+static void
+jni_print_float (FILE *stream, 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;
+ /* It'd be nice to use __builtin_nan/__builtin_inf here but they don't
+ work in data initializers. FIXME. */
+ if (JFLOAT_FINITE (f))
+ {
+ fputs (" = ", stream);
+ if (f.negative)
+ putc ('-', stream);
+ if (f.exponent)
+ fprintf (stream, "0x1.%.6xp%+df",
+ ((unsigned int)f.mantissa) << 1,
+ f.exponent - JFLOAT_EXP_BIAS);
+ else
+ /* Exponent of 0x01 is -125; exponent of 0x00 is *also* -125,
+ because the implicit leading 1 bit is no longer present. */
+ fprintf (stream, "0x0.%.6xp%+df",
+ ((unsigned int)f.mantissa) << 1,
+ f.exponent + 1 - JFLOAT_EXP_BIAS);
+ }
+ fputs (";\n", stream);
}
-/* Return 1 if D is not Inf or NaN. */
-static int
-java_double_finite (jdouble d)
+/* Print a double-precision float, suitable for parsing by g++. */
+static void
+jni_print_double (FILE *stream, jdouble f)
{
- union DWord u;
- u.d = d;
-
- /* Now check for all NaNs. */
- return (u.l & D_NAN_MASK) != D_NAN_MASK;
+ /* It'd be nice to use __builtin_nan/__builtin_inf here but they don't
+ work in data initializers. FIXME. */
+ if (JDOUBLE_FINITE (f))
+ {
+ fputs (" = ", stream);
+ if (f.negative)
+ putc ('-', stream);
+ if (f.exponent)
+ fprintf (stream, "0x1.%.5x%.8xp%+d",
+ f.mantissa0, f.mantissa1,
+ f.exponent - JDOUBLE_EXP_BIAS);
+ else
+ /* Exponent of 0x001 is -1022; exponent of 0x000 is *also* -1022,
+ because the implicit leading 1 bit is no longer present. */
+ fprintf (stream, "0x0.%.5x%.8xp%+d",
+ f.mantissa0, f.mantissa1,
+ f.exponent + 1 - JDOUBLE_EXP_BIAS);
+ }
+ fputs (";\n", stream);
}
/* Print a character, appropriately mangled for JNI. */
@@ -732,10 +750,7 @@ print_field_info (FILE *stream, JCF* jcf, int name_index, int sig_index,
jfloat fnum = JPOOL_FLOAT (jcf, current_field_value);
fputs ("const jfloat ", out);
print_field_name (out, jcf, name_index, 0);
- if (! java_float_finite (fnum))
- fputs (";\n", out);
- else
- fprintf (out, " = %.10g;\n", fnum);
+ jni_print_float (out, fnum);
}
break;
case CONSTANT_Double:
@@ -743,10 +758,7 @@ print_field_info (FILE *stream, JCF* jcf, int name_index, int sig_index,
jdouble dnum = JPOOL_DOUBLE (jcf, current_field_value);
fputs ("const jdouble ", out);
print_field_name (out, jcf, name_index, 0);
- if (! java_double_finite (dnum))
- fputs (";\n", out);
- else
- fprintf (out, " = %.17g;\n", dnum);
+ jni_print_double (out, dnum);
}
break;
default:
diff --git a/gcc/java/javaop.h b/gcc/java/javaop.h
index da09254ad10..bdf3fa6e41f 100644
--- a/gcc/java/javaop.h
+++ b/gcc/java/javaop.h
@@ -55,21 +55,26 @@ 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;
+#define JFLOAT_FINITE(f) ((f).exponent != 0xFF)
+#define JFLOAT_QNAN_MASK 0x400000
+#define JFLOAT_EXP_BIAS 0x7f
+
+/* 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;
+#define JDOUBLE_FINITE(f) ((f).exponent != 0x7FF)
+#define JDOUBLE_QNAN_MASK 0x80000 /* apply to mantissa0 */
+#define JDOUBLE_EXP_BIAS 0x3ff
/* 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
@@ -102,9 +107,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 +136,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,
diff --git a/gcc/java/jcf-dump.c b/gcc/java/jcf-dump.c
index 6d976e53450..a87dd401e0f 100644
--- a/gcc/java/jcf-dump.c
+++ b/gcc/java/jcf-dump.c
@@ -62,6 +62,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "version.h"
#include <getopt.h>
+#include <math.h>
/* Outout file. */
FILE *out;
@@ -504,24 +505,86 @@ print_constant (FILE *out, JCF *jcf, int index, int verbosity)
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);
+
+ if (verbosity > 0)
+ fputs ("Float ", out);
+
+ if (fnum.negative)
+ putc ('-', out);
+
+ if (JFLOAT_FINITE (fnum))
+ {
+ int dummy;
+ int exponent = fnum.exponent - JFLOAT_EXP_BIAS;
+ double f;
+ uint32 mantissa = fnum.mantissa;
+ if (fnum.exponent == 0)
+ /* Denormal. */
+ exponent++;
+ else
+ /* Normal; add the implicit bit. */
+ mantissa |= ((uint32)1 << 23);
+
+ f = frexp (mantissa, &dummy);
+ f = ldexp (f, exponent + 1);
+ fprintf (out, "%.10g", f);
+ }
+ else
+ {
+ if (fnum.mantissa == 0)
+ fputs ("Inf", out);
+ else if (fnum.mantissa & JFLOAT_QNAN_MASK)
+ fprintf (out, "QNaN(%u)", (fnum.mantissa & ~JFLOAT_QNAN_MASK));
+ else
+ fprintf (out, "SNaN(%u)", (fnum.mantissa & ~JFLOAT_QNAN_MASK));
+ }
+
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);
+
+ if (verbosity > 0)
+ fputs ("Double ", out);
+
+ if (dnum.negative)
+ putc ('-', out);
+
+ if (JDOUBLE_FINITE (dnum))
+ {
+ int dummy;
+ int exponent = dnum.exponent - JDOUBLE_EXP_BIAS;
+ double d;
+ uint64 mantissa = ((((uint64) dnum.mantissa0) << 32)
+ + dnum.mantissa1);
+ if (dnum.exponent == 0)
+ /* Denormal. */
+ exponent++;
+ else
+ /* Normal; add the implicit bit. */
+ mantissa |= ((uint64)1 << 52);
+
+ d = frexp (mantissa, &dummy);
+ d = ldexp (d, exponent + 1);
+ fprintf (out, "%.20g", d);
+ }
+ else
+ {
+ uint64 mantissa = dnum.mantissa0 & ~JDOUBLE_QNAN_MASK;
+ mantissa = (mantissa << 32) + dnum.mantissa1;
+
+ if (dnum.mantissa0 == 0 && dnum.mantissa1 == 0)
+ fputs ("Inf", out);
+ else if (dnum.mantissa0 & JDOUBLE_QNAN_MASK)
+ fprintf (out, "QNaN(%llu)", (unsigned long long)mantissa);
+ else
+ fprintf (out, "SNaN(%llu)", (unsigned long long)mantissa);
+ }
if (verbosity > 1)
{
int32 hi, lo;