OSDN Git Service

* javaop.h (jfloat, jdouble): Make them structures mirroring
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 Mar 2003 17:10:02 +0000 (17:10 +0000)
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 Mar 2003 17:10:02 +0000 (17:10 +0000)
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

gcc/java/ChangeLog
gcc/java/gjavah.c
gcc/java/javaop.h
gcc/java/jcf-dump.c

index db5651b..1b980ae 100644 (file)
@@ -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'.
 
 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>
 
        * 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.
 
 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>
 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>
 
        * 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.
index 23af65a..51cfe7c 100644 (file)
@@ -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:
index da09254..bdf3fa6 100644 (file)
@@ -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,
index 6d976e5..a87dd40 100644 (file)
@@ -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;