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>
* lang.c (java_dump_tree): Change return type from 'int' to 'bool'.
......
......@@ -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:
......
......@@ -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,
......
......@@ -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 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
{
jfloat f;
int32 i;
} pun;
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));
}
pun.f = JPOOL_FLOAT (jcf, index);
fprintf (out, "%s%.10g",
verbosity > 0 ? "Float " : "", (double) pun.f);
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;
......
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