From 7c476bdec6f46df5da4984a0a0cdff2ce4f00ff1 Mon Sep 17 00:00:00 2001
From: Richard Sandiford <rsandifo@redhat.com>
Date: Sun, 8 Feb 2004 20:00:30 +0000
Subject: [PATCH] real.c (encode_ibm_extended): Normalize the input value
 before converting it to a double.

	* real.c (encode_ibm_extended): Normalize the input value before
	converting it to a double.  Handle the case where a normal value
	rounds to infinity.

From-SVN: r77498
---
 gcc/ChangeLog                                    |  6 ++++++
 gcc/real.c                                       | 13 +++++++++----
 gcc/testsuite/ChangeLog                          |  4 ++++
 gcc/testsuite/gcc.c-torture/execute/20040208-1.c | 10 ++++++++++
 gcc/testsuite/gcc.c-torture/execute/20040208-2.c | 11 +++++++++++
 5 files changed, 40 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/20040208-1.c
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/20040208-2.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0b35c432740f..8ea1cd6f7cdf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2004-02-08  Richard Sandiford  <rsandifo@redhat.com>
+
+	* real.c (encode_ibm_extended): Normalize the input value before
+	converting it to a double.  Handle the case where a normal value
+	rounds to infinity.
+
 2004-02-08  Kazu Hirata  <kazu@cs.umass.edu>
 
 	* c-objc-common.c (): Fix a typo in a warning.
diff --git a/gcc/real.c b/gcc/real.c
index cd27d3e0501c..474da31df6c2 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -3230,19 +3230,24 @@ static void
 encode_ibm_extended (const struct real_format *fmt, long *buf,
 		     const REAL_VALUE_TYPE *r)
 {
-  REAL_VALUE_TYPE u, v;
+  REAL_VALUE_TYPE u, normr, v;
   const struct real_format *base_fmt;
 
   base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format;
 
+  /* Renormlize R before doing any arithmetic on it.  */
+  normr = *r;
+  if (normr.class == rvc_normal)
+    normalize (&normr);
+
   /* u = IEEE double precision portion of significand.  */
-  u = *r;
+  u = normr;
   round_for_format (base_fmt, &u);
   encode_ieee_double (base_fmt, &buf[0], &u);
 
-  if (r->class == rvc_normal)
+  if (u.class == rvc_normal)
     {
-      do_add (&v, r, &u, 1);
+      do_add (&v, &normr, &u, 1);
       round_for_format (base_fmt, &v);
       encode_ieee_double (base_fmt, &buf[2], &v);
     }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a4e9a01a488f..d8aa19d5f777 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-02-08  Richard Sandiford  <rsandifo@redhat.com>
+
+	* gcc.c-torture/execute/20040208-[12].c: New tests.
+
 2004-02-08  Eric Botcazou  <ebotcazou@libertysurf.fr>
 
 	* g++.dg/eh/simd-2.C: Adjust line numbers for SPARC.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040208-1.c b/gcc/testsuite/gcc.c-torture/execute/20040208-1.c
new file mode 100644
index 000000000000..023575910727
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20040208-1.c
@@ -0,0 +1,10 @@
+int main ()
+{
+  long double x;
+
+  x = 0x1.0p-500L;
+  x *= 0x1.0p-522L;
+  if (x != 0x1.0p-1022L)
+    abort ();
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040208-2.c b/gcc/testsuite/gcc.c-torture/execute/20040208-2.c
new file mode 100644
index 000000000000..d8a5afc94623
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20040208-2.c
@@ -0,0 +1,11 @@
+int main ()
+{
+  long double x, y;
+
+  x = 0x1.fffffffffffff8p1022L;
+  x *= 2;
+  y = 0x1.fffffffffffff8p1023L;
+  if (memcmp (&x, &y, sizeof (x)) != 0)
+    abort ();
+  exit (0);
+}
-- 
GitLab