Commit 649eaf9b by Zack Weinberg

javaop.h (jfloat, jdouble): Make them structures mirroring the bit fields of…

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
parent c0510d84
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> 2003-03-19 Nathanael Nerode <neroden@gcc.gnu.org>
* lang.c (java_dump_tree): Change return type from 'int' to 'bool'. * lang.c (java_dump_tree): Change return type from 'int' to 'bool'.
...@@ -16,10 +35,10 @@ ...@@ -16,10 +35,10 @@
2003-03-04 Andrew Haley <aph@redhat.com> 2003-03-04 Andrew Haley <aph@redhat.com>
* gjavah.c (is_first_data_member): New global variable. * gjavah.c (is_first_data_member): New global variable.
(print_c_decl): If it's the first data member, align it as the (print_c_decl): If it's the first data member, align it as the
superclass. superclass.
(process_file): Set is_first_data_member. (process_file): Set is_first_data_member.
2003-03-11 Tom Tromey <tromey@redhat.com> 2003-03-11 Tom Tromey <tromey@redhat.com>
...@@ -57,7 +76,7 @@ ...@@ -57,7 +76,7 @@
"strcmp" to compare file name components. "strcmp" to compare file name components.
Use IS_DIR_SEPARATOR instead of comparing directly against Use IS_DIR_SEPARATOR instead of comparing directly against
DIR_SEPARATOR. 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. comparing directly against DIR_SEPARATOR.
2003-03-04 Tom Tromey <tromey@redhat.com> 2003-03-04 Tom Tromey <tromey@redhat.com>
...@@ -91,7 +110,7 @@ ...@@ -91,7 +110,7 @@
* java/decl.c (java_init_decl_processing): Get soft_fmod_node from * java/decl.c (java_init_decl_processing): Get soft_fmod_node from
built_in_decls[BUILT_IN_FMOD] rather than define it ourselves. built_in_decls[BUILT_IN_FMOD] rather than define it ourselves.
2003-02-23 Tom Tromey <tromey@redhat.com> 2003-02-23 Tom Tromey <tromey@redhat.com>
* lang-options.h: Added -Wdeprecated. * lang-options.h: Added -Wdeprecated.
...@@ -133,12 +152,12 @@ ...@@ -133,12 +152,12 @@
2003-02-12 Ranjit Mathew <rmathew@hotmail.com> 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 soft_lookupjnimethod_node to reflect the change in
signature of _Jv_LookupJNIMethod in libjava/jni.cc signature of _Jv_LookupJNIMethod in libjava/jni.cc
* expr.c (build_jni_stub): Calculate and pass the size * expr.c (build_jni_stub): Calculate and pass the size
on the stack of the arguments to a JNI function. Use 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. target to modify the call to a JNI method.
2003-02-08 Roger Sayle <roger@eyesopen.com> 2003-02-08 Roger Sayle <roger@eyesopen.com>
...@@ -324,7 +343,7 @@ ...@@ -324,7 +343,7 @@
2003-01-14 Andrew Haley <aph@redhat.com> 2003-01-14 Andrew Haley <aph@redhat.com>
* decl.c (java_init_decl_processing): _Jv_NewMultiArray is a * decl.c (java_init_decl_processing): _Jv_NewMultiArray is a
varargs function -- correct. varargs function -- correct.
2003-01-14 Andrew Haley <aph@redhat.com> 2003-01-14 Andrew Haley <aph@redhat.com>
...@@ -571,7 +590,7 @@ ...@@ -571,7 +590,7 @@
* gcj.texi: Change version number to 3.4. * gcj.texi: Change version number to 3.4.
2002-12-05 Ranjit Mathew <rmathew@hotmail.com> 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 * parse.y (source_end_java_method): Remove custom encoding of line
numbers for a function decl before passing it to the back end. numbers for a function decl before passing it to the back end.
......
...@@ -134,8 +134,6 @@ static void print_full_cxx_name (FILE*, JCF*, int, int, int, const char *, int); ...@@ -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 decompile_method (FILE*, JCF*, int);
static void add_class_decl (FILE*, JCF*, JCF_u2); 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_name (FILE *, JCF *, int);
static void print_base_classname (FILE *, JCF *, int); static void print_base_classname (FILE *, JCF *, int);
static int utf8_cmp (const unsigned char *, int, const char *); static int utf8_cmp (const unsigned char *, int, const char *);
...@@ -158,6 +156,8 @@ static void version (void) ATTRIBUTE_NORETURN; ...@@ -158,6 +156,8 @@ static void version (void) ATTRIBUTE_NORETURN;
static int overloaded_jni_method_exists_p (const unsigned char *, int, static int overloaded_jni_method_exists_p (const unsigned char *, int,
const char *, int); const char *, int);
static void jni_print_char (FILE *, 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); static void decompile_return_statement (FILE *, JCF *, int, int, int);
JCF_u2 current_field_name; JCF_u2 current_field_name;
...@@ -247,36 +247,54 @@ static int decompiled = 0; ...@@ -247,36 +247,54 @@ static int decompiled = 0;
#include "jcf-reader.c" #include "jcf-reader.c"
/* Some useful constants. */ /* Print a single-precision float, suitable for parsing by g++. */
#define F_NAN_MASK 0x7f800000 static void
#if (1 == HOST_FLOAT_WORDS_BIG_ENDIAN) && ! defined (HOST_WORDS_BIG_ENDIAN) jni_print_float (FILE *stream, jfloat f)
#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; /* It'd be nice to use __builtin_nan/__builtin_inf here but they don't
u.f = f; work in data initializers. FIXME. */
if (JFLOAT_FINITE (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 fputs (" = ", stream);
test here. See The Java Language Specification, section 20.9. */ if (f.negative)
return (u.i & F_NAN_MASK) != F_NAN_MASK; 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. */ /* Print a double-precision float, suitable for parsing by g++. */
static int static void
java_double_finite (jdouble d) jni_print_double (FILE *stream, jdouble f)
{ {
union DWord u; /* It'd be nice to use __builtin_nan/__builtin_inf here but they don't
u.d = d; work in data initializers. FIXME. */
if (JDOUBLE_FINITE (f))
/* Now check for all NaNs. */ {
return (u.l & D_NAN_MASK) != D_NAN_MASK; 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. */ /* Print a character, appropriately mangled for JNI. */
...@@ -732,10 +750,7 @@ print_field_info (FILE *stream, JCF* jcf, int name_index, int sig_index, ...@@ -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); jfloat fnum = JPOOL_FLOAT (jcf, current_field_value);
fputs ("const jfloat ", out); fputs ("const jfloat ", out);
print_field_name (out, jcf, name_index, 0); print_field_name (out, jcf, name_index, 0);
if (! java_float_finite (fnum)) jni_print_float (out, fnum);
fputs (";\n", out);
else
fprintf (out, " = %.10g;\n", fnum);
} }
break; break;
case CONSTANT_Double: case CONSTANT_Double:
...@@ -743,10 +758,7 @@ print_field_info (FILE *stream, JCF* jcf, int name_index, int sig_index, ...@@ -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); jdouble dnum = JPOOL_DOUBLE (jcf, current_field_value);
fputs ("const jdouble ", out); fputs ("const jdouble ", out);
print_field_name (out, jcf, name_index, 0); print_field_name (out, jcf, name_index, 0);
if (! java_double_finite (dnum)) jni_print_double (out, dnum);
fputs (";\n", out);
else
fprintf (out, " = %.17g;\n", dnum);
} }
break; break;
default: default:
......
...@@ -55,21 +55,26 @@ typedef int32 jint; ...@@ -55,21 +55,26 @@ typedef int32 jint;
typedef int64 jlong; typedef int64 jlong;
typedef void* jref; typedef void* jref;
/* A 32-bit IEEE single-precision float. */ /* A 32-bit big-endian IEEE single-precision float. */
#ifndef jfloat typedef struct _jfloat {
#define jfloat float unsigned int negative : 1;
#endif unsigned int exponent : 8;
unsigned int mantissa : 23;
/* A 32-bit IEEE double-precision float. */ } jfloat;
#ifndef jdouble #define JFLOAT_FINITE(f) ((f).exponent != 0xFF)
#define jdouble double #define JFLOAT_QNAN_MASK 0x400000
#endif #define JFLOAT_EXP_BIAS 0x7f
union Word { /* A 32-bit big-endian IEEE double-precision float. */
jint i; typedef struct _jdouble {
jfloat f; unsigned int negative : 1;
void *p; 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 /* 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 or jfloat *or* a pointer. It is the type appropriate for stack
...@@ -102,9 +107,14 @@ union Word { ...@@ -102,9 +107,14 @@ union Word {
static inline jfloat static inline jfloat
WORD_TO_FLOAT(jword w) WORD_TO_FLOAT(jword w)
{ union Word wu; {
wu.i = w; jfloat f;
return wu.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 /* Sign extend w. If the host on which this cross-compiler runs uses
...@@ -126,21 +136,17 @@ WORDS_TO_LONG(jword hi, jword lo) ...@@ -126,21 +136,17 @@ WORDS_TO_LONG(jword hi, jword lo)
return ((jlong) hi << 32) | ((jlong)lo & (((jlong)1 << 32) -1)); return ((jlong) hi << 32) | ((jlong)lo & (((jlong)1 << 32) -1));
} }
union DWord {
jdouble d;
jlong l;
jword w[2];
};
static inline jdouble static inline jdouble
WORDS_TO_DOUBLE(jword hi, jword lo) WORDS_TO_DOUBLE(jword hi, jword lo)
{ union DWord wu; {
#if (1 == HOST_FLOAT_WORDS_BIG_ENDIAN) jdouble d;
wu.l = WORDS_TO_LONG(lo, hi);
#else d.negative = (hi & 0x80000000) >> 31;
wu.l = WORDS_TO_LONG(hi, lo); d.exponent = (hi & 0x7ff00000) >> 20;
#endif d.mantissa0 = (hi & 0x000fffff);
return wu.d; d.mantissa1 = lo;
return d;
} }
/* If PREFIX_CHAR is the first character of the Utf8 encoding of a character, /* If PREFIX_CHAR is the first character of the Utf8 encoding of a character,
......
...@@ -62,6 +62,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ ...@@ -62,6 +62,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "version.h" #include "version.h"
#include <getopt.h> #include <getopt.h>
#include <math.h>
/* Outout file. */ /* Outout file. */
FILE *out; FILE *out;
...@@ -504,24 +505,86 @@ print_constant (FILE *out, JCF *jcf, int index, int verbosity) ...@@ -504,24 +505,86 @@ print_constant (FILE *out, JCF *jcf, int index, int verbosity)
break; break;
case CONSTANT_Float: case CONSTANT_Float:
{ {
union jfloat fnum = JPOOL_FLOAT (jcf, index);
{
jfloat f; if (verbosity > 0)
int32 i; fputs ("Float ", out);
} pun;
if (fnum.negative)
pun.f = JPOOL_FLOAT (jcf, index); putc ('-', out);
fprintf (out, "%s%.10g",
verbosity > 0 ? "Float " : "", (double) pun.f); 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) if (verbosity > 1)
fprintf (out, ", bits = 0x%08lx", (long) pun.i); fprintf (out, ", bits = 0x%08lx", JPOOL_UINT (jcf, index));
break; break;
} }
case CONSTANT_Double: case CONSTANT_Double:
{ {
jdouble dnum = JPOOL_DOUBLE (jcf, index); 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) if (verbosity > 1)
{ {
int32 hi, lo; int32 hi, lo;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment