diff options
author | Zack Weinberg <zack@gcc.gnu.org> | 2003-03-21 17:10:02 +0000 |
---|---|---|
committer | Zack Weinberg <zack@gcc.gnu.org> | 2003-03-21 17:10:02 +0000 |
commit | 649eaf9bfd466d7e98f1ba41e57ac39f440c989e (patch) | |
tree | f92bcd0dd5b17043f1634195bcbf18c4df1df8da /gcc/java/gjavah.c | |
parent | c0510d84b7e1e57f475d27a3390b7177a1cf9d27 (diff) | |
download | gcc-649eaf9bfd466d7e98f1ba41e57ac39f440c989e.zip gcc-649eaf9bfd466d7e98f1ba41e57ac39f440c989e.tar.gz gcc-649eaf9bfd466d7e98f1ba41e57ac39f440c989e.tar.bz2 |
javaop.h (jfloat, jdouble): Make them structures mirroring the bit fields of IEEE float and double respectively.
* 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.
From-SVN: r64671
Diffstat (limited to 'gcc/java/gjavah.c')
-rw-r--r-- | gcc/java/gjavah.c | 84 |
1 files changed, 48 insertions, 36 deletions
diff --git a/gcc/java/gjavah.c b/gcc/java/gjavah.c index 23af65a..51cfe7c 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: |