Bug 14610
authorZack Weinberg <zack@gcc.gnu.org>
Thu, 17 Jun 2004 17:05:48 +0000 (17:05 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Thu, 17 Jun 2004 17:05:48 +0000 (17:05 +0000)
Bug 14610
* Makefile.in (min-insn-modes.o): Correct dependencies.
* real.c (encode_ieee_extended, decode_ieee_extended): Always
produce/consume 12-byte little-endian Intel format.
(encode_ieee_extended_128, decode_ieee_extended_128): Delete.
(encode_ieee_extended_motorola, decode_ieee_extended_motorola)
(encode_ieee_extended_intel_96, decode_ieee_extended_intel_96)
(encode_ieee_extended_intel_128, decode_ieee_extended_intel_128):
New functions which convert between 12-byte little-endian Intel
format and the desired format.
(ieee_extended_motorola_format, ieee_extended_intel_96_round_53_format)
(ieee_extended_intel_96_format, ieee_extended_intel_128_format):
Update.
testsuite:
* gcc.dg/ia64-float80-1.c, gcc.dg/ia64-float80-2.c: New testcases.

From-SVN: r83295

gcc/ChangeLog
gcc/Makefile.in
gcc/real.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ia64-float80-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/ia64-float80-2.c [new file with mode: 0644]

index 5a1a3c205a0e9d671638423c0a86e2481ae1d8f8..6c7e48588f1e588bbdc1950ed82c4467fe4eb0e9 100644 (file)
@@ -1,3 +1,19 @@
+2004-06-17  Zack Weinberg  <zack@codesourcery.com>
+
+       Bug 14610
+       * Makefile.in (min-insn-modes.o): Correct dependencies.
+       * real.c (encode_ieee_extended, decode_ieee_extended): Always
+       produce/consume 12-byte little-endian Intel format.
+       (encode_ieee_extended_128, decode_ieee_extended_128): Delete.
+       (encode_ieee_extended_motorola, decode_ieee_extended_motorola)
+       (encode_ieee_extended_intel_96, decode_ieee_extended_intel_96)
+       (encode_ieee_extended_intel_128, decode_ieee_extended_intel_128):
+       New functions which convert between 12-byte little-endian Intel
+       format and the desired format.
+       (ieee_extended_motorola_format, ieee_extended_intel_96_round_53_format)
+       (ieee_extended_intel_96_format, ieee_extended_intel_128_format):
+       Update.
+
 2004-06-17  Zack Weinberg  <zack@codesourcery.com>
 
        * expmed.c (expand_mult_const): In sanity check, compare only
@@ -43,7 +59,7 @@
        * tree-inline.c: Correct comment about this file's purpose.
        * tree-optimize.c: Likewise.
        * tree-tailcall.c: Likewise.
-       
+
        * tree-alias-ander.h: Add standard top-of-file comment.
        * tree-alias-common.h: Likewise.
        * tree-alias-type.h: Likewise.
index dd7e65d4ca11b36c738b08955488b65c950c9ccf..3db6176f03d159a59edca5594193adedd1028cb5 100644 (file)
@@ -2561,7 +2561,7 @@ $(BUILD_PREFIX_1)ggc-none.o: ggc-none.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYST
        sed -e 's/config[.]h/bconfig.h/' $(srcdir)/ggc-none.c > $(BUILD_PREFIX)ggc-none.c
        $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)ggc-none.c $(OUTPUT_OPTION)
 
-min-insn-modes.o: insn-modes.c $(BCONFIG_H) $(SYSTEM_H) $(MACHMODE_H)
+min-insn-modes.o: min-insn-modes.c $(BCONFIG_H) $(SYSTEM_H) $(MACHMODE_H)
        $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \
            min-insn-modes.c $(OUTPUT_OPTION)
 
index a9bad46fffaac6e8805e1c968a0c785bca887830..896aa9dd3e19a65112c516a112af295995e041f4 100644 (file)
@@ -2912,20 +2912,14 @@ const struct real_format mips_double_format =
   };
 
 \f
-/* IEEE extended double precision format.  This comes in three
-   flavors: Intel's as a 12 byte image, Intel's as a 16 byte image,
-   and Motorola's.  */
-
-static void encode_ieee_extended (const struct real_format *fmt,
-                                 long *, const REAL_VALUE_TYPE *);
-static void decode_ieee_extended (const struct real_format *,
-                                 REAL_VALUE_TYPE *, const long *);
-
-static void encode_ieee_extended_128 (const struct real_format *fmt,
-                                     long *, const REAL_VALUE_TYPE *);
-static void decode_ieee_extended_128 (const struct real_format *,
-                                     REAL_VALUE_TYPE *, const long *);
-
+/* IEEE extended real format.  This comes in three flavors: Intel's as
+   a 12 byte image, Intel's as a 16 byte image, and Motorola's.  Intel
+   12- and 16-byte images may be big- or little endian; Motorola's is
+   always big endian.  */
+
+/* Helper subroutine which converts from the internal format to the
+   12-byte little-endian Intel format.  Functions below adjust this
+   for the other possible formats.  */
 static void
 encode_ieee_extended (const struct real_format *fmt, long *buf,
                      const REAL_VALUE_TYPE *r)
@@ -3033,20 +3027,65 @@ encode_ieee_extended (const struct real_format *fmt, long *buf,
       abort ();
     }
 
+  buf[0] = sig_lo, buf[1] = sig_hi, buf[2] = image_hi;
+}
+
+/* Convert from the internal format to the 12-byte Motorola format
+   for an IEEE extended real.  */
+static void
+encode_ieee_extended_motorola (const struct real_format *fmt, long *buf,
+                              const REAL_VALUE_TYPE *r)
+{
+  long intermed[3];
+  encode_ieee_extended (fmt, intermed, r);
+
+  /* Motorola chips are assumed always to be big-endian.  Also, the
+     padding in a Motorola extended real goes between the exponent and
+     the mantissa.  At this point the mantissa is entirely within
+     elements 0 and 1 of intermed, and the exponent entirely within
+     element 2, so all we have to do is swap the order around, and
+     shift element 2 left 16 bits.  */
+  buf[0] = intermed[2] << 16;
+  buf[1] = intermed[1];
+  buf[2] = intermed[0];
+}
+
+/* Convert from the internal format to the 12-byte Intel format for
+   an IEEE extended real.  */
+static void
+encode_ieee_extended_intel_96 (const struct real_format *fmt, long *buf,
+                              const REAL_VALUE_TYPE *r)
+{
   if (FLOAT_WORDS_BIG_ENDIAN)
-    buf[0] = image_hi << 16, buf[1] = sig_hi, buf[2] = sig_lo;
+    {
+      /* All the padding in an Intel-format extended real goes at the high
+        end, which in this case is after the mantissa, not the exponent.
+        Therefore we must shift everything down 16 bits.  */
+      long intermed[3];
+      encode_ieee_extended (fmt, intermed, r);
+      buf[0] = ((intermed[2] << 16) | ((unsigned long)(intermed[1] & 0xFFFF0000) >> 16));
+      buf[1] = ((intermed[1] << 16) | ((unsigned long)(intermed[0] & 0xFFFF0000) >> 16));
+      buf[2] =  (intermed[0] << 16);
+    }
   else
-    buf[0] = sig_lo, buf[1] = sig_hi, buf[2] = image_hi;
+    /* encode_ieee_extended produces what we want directly.  */
+    encode_ieee_extended (fmt, buf, r);
 }
 
+/* Convert from the internal format to the 16-byte Intel format for
+   an IEEE extended real.  */
 static void
-encode_ieee_extended_128 (const struct real_format *fmt, long *buf,
-                         const REAL_VALUE_TYPE *r)
+encode_ieee_extended_intel_128 (const struct real_format *fmt, long *buf,
+                               const REAL_VALUE_TYPE *r)
 {
-  buf[3 * !FLOAT_WORDS_BIG_ENDIAN] = 0;
-  encode_ieee_extended (fmt, buf+!!FLOAT_WORDS_BIG_ENDIAN, r);
+  /* All the padding in an Intel-format extended real goes at the high end.  */
+  encode_ieee_extended_intel_96 (fmt, buf, r);
+  buf[3] = 0;
 }
 
+/* As above, we have a helper function which converts from 12-byte
+   little-endian Intel format to internal format.  Functions below
+   adjust for the other possible formats.  */
 static void
 decode_ieee_extended (const struct real_format *fmt, REAL_VALUE_TYPE *r,
                      const long *buf)
@@ -3055,10 +3094,7 @@ decode_ieee_extended (const struct real_format *fmt, REAL_VALUE_TYPE *r,
   bool sign;
   int exp;
 
-  if (FLOAT_WORDS_BIG_ENDIAN)
-    image_hi = buf[0] >> 16, sig_hi = buf[1], sig_lo = buf[2];
-  else
-    sig_lo = buf[0], sig_hi = buf[1], image_hi = buf[2];
+  sig_lo = buf[0], sig_hi = buf[1], image_hi = buf[2];
   sig_lo &= 0xffffffff;
   sig_hi &= 0xffffffff;
   image_hi &= 0xffffffff;
@@ -3135,17 +3171,62 @@ decode_ieee_extended (const struct real_format *fmt, REAL_VALUE_TYPE *r,
     }
 }
 
+/* Convert from the internal format to the 12-byte Motorola format
+   for an IEEE extended real.  */
+static void
+decode_ieee_extended_motorola (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+                              const long *buf)
+{
+  long intermed[3];
+
+  /* Motorola chips are assumed always to be big-endian.  Also, the
+     padding in a Motorola extended real goes between the exponent and
+     the mantissa; remove it.  */
+  intermed[0] = buf[2];
+  intermed[1] = buf[1];
+  intermed[2] = (unsigned long)buf[0] >> 16;
+
+  decode_ieee_extended (fmt, r, intermed);
+}
+
+/* Convert from the internal format to the 12-byte Intel format for
+   an IEEE extended real.  */
+static void
+decode_ieee_extended_intel_96 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+                              const long *buf)
+{
+  if (FLOAT_WORDS_BIG_ENDIAN)
+    {
+      /* All the padding in an Intel-format extended real goes at the high
+        end, which in this case is after the mantissa, not the exponent.
+        Therefore we must shift everything up 16 bits.  */
+      long intermed[3];
+
+      intermed[0] = (((unsigned long)buf[2] >> 16) | (buf[1] << 16));
+      intermed[1] = (((unsigned long)buf[1] >> 16) | (buf[0] << 16));
+      intermed[2] =  ((unsigned long)buf[0] >> 16);
+
+      decode_ieee_extended (fmt, r, intermed);
+    }
+  else
+    /* decode_ieee_extended produces what we want directly.  */
+    decode_ieee_extended (fmt, r, buf);
+}
+
+/* Convert from the internal format to the 16-byte Intel format for
+   an IEEE extended real.  */
 static void
-decode_ieee_extended_128 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
-                         const long *buf)
+decode_ieee_extended_intel_128 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+                               const long *buf)
 {
-  decode_ieee_extended (fmt, r, buf+!!FLOAT_WORDS_BIG_ENDIAN);
+  /* All the padding in an Intel-format extended real goes at the high end.  */
+  decode_ieee_extended_intel_96 (fmt, r, buf);
 }
 
 const struct real_format ieee_extended_motorola_format =
   {
-    encode_ieee_extended,
-    decode_ieee_extended,
+    encode_ieee_extended_motorola,
+    decode_ieee_extended_motorola,
     2,
     1,
     64,
@@ -3162,8 +3243,8 @@ const struct real_format ieee_extended_motorola_format =
 
 const struct real_format ieee_extended_intel_96_format =
   {
-    encode_ieee_extended,
-    decode_ieee_extended,
+    encode_ieee_extended_intel_96,
+    decode_ieee_extended_intel_96,
     2,
     1,
     64,
@@ -3180,8 +3261,8 @@ const struct real_format ieee_extended_intel_96_format =
 
 const struct real_format ieee_extended_intel_128_format =
   {
-    encode_ieee_extended_128,
-    decode_ieee_extended_128,
+    encode_ieee_extended_intel_128,
+    decode_ieee_extended_intel_128,
     2,
     1,
     64,
@@ -3200,8 +3281,8 @@ const struct real_format ieee_extended_intel_128_format =
    to 53 bits instead of 64, e.g. FreeBSD.  */
 const struct real_format ieee_extended_intel_96_round_53_format =
   {
-    encode_ieee_extended,
-    decode_ieee_extended,
+    encode_ieee_extended_intel_96,
+    decode_ieee_extended_intel_96,
     2,
     1,
     53,
index 286cbb60575086f717cd8448d68830b03e3eed65..9411b50a1963d3d84460bc8d29498ba06f31406a 100644 (file)
@@ -1,3 +1,8 @@
+2004-06-17  Zack Weinberg  <zack@codesourcery.com>
+
+       Bug 14610
+       * gcc.dg/ia64-float80-1.c, gcc.dg/ia64-float80-2.c: New testcases.
+
 2004-06-15  Richard Henderson  <rth@redhat.com>
 
        * gcc.dg/20001116-1.c: Move expected warning line.
@@ -91,7 +96,7 @@
 
        PR fortran/14957
        * gfortran.fortran-torture/execute/stack_varsize.f90: Correct
-        syntax errors in end statements of contained subroutines.
+       syntax errors in end statements of contained subroutines.
 
 2004-06-12  Tobias Schlueter  <tobias.schlueter@physik.uni-muenchen.de>
 
 
 2004-06-09  Bud Davis  <bdavis9659@comcast.net>
 
-        PR gfortran/15755
+       PR gfortran/15755
        * gfortran.fortran-torture/execute/backspace.c : New test.
 
 2004-06-09  Paul Brook  <paul@codesourcery.com>
diff --git a/gcc/testsuite/gcc.dg/ia64-float80-1.c b/gcc/testsuite/gcc.dg/ia64-float80-1.c
new file mode 100644 (file)
index 0000000..dd39f3e
--- /dev/null
@@ -0,0 +1,12 @@
+/* Bug 14610 */
+/* { dg-do run { target ia64-*-* } } */
+
+extern void abort(void);
+volatile __float80 x = 30.0;
+
+int main(void)
+{
+  double d = x;
+  if (d != 30.0) abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ia64-float80-2.c b/gcc/testsuite/gcc.dg/ia64-float80-2.c
new file mode 100644 (file)
index 0000000..6293124
--- /dev/null
@@ -0,0 +1,13 @@
+/* Bug 14610 */
+/* { dg-do run { target ia64-*-* } } */
+/* { dg-options "-minline-int-divide-max-throughput" } */
+
+extern void abort(void);
+volatile int j = 30;
+
+int main(void)
+{
+  if (29 % j != 29) abort();
+  if (30 % j != 0)  abort();
+  return 0;
+}