aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/gjavah.c
diff options
context:
space:
mode:
authorZack Weinberg <zack@gcc.gnu.org>2003-03-21 17:10:02 +0000
committerZack Weinberg <zack@gcc.gnu.org>2003-03-21 17:10:02 +0000
commit649eaf9bfd466d7e98f1ba41e57ac39f440c989e (patch)
treef92bcd0dd5b17043f1634195bcbf18c4df1df8da /gcc/java/gjavah.c
parentc0510d84b7e1e57f475d27a3390b7177a1cf9d27 (diff)
downloadgcc-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.c84
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: