This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: ping: c/41049 fixes for int to dfp conversions
- From: Janis Johnson <janis187 at us dot ibm dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org, bje at au1 dot ibm dot com
- Date: Thu, 17 Sep 2009 10:13:03 -0700
- Subject: Re: ping: c/41049 fixes for int to dfp conversions
- References: <1253032096.6483.2.camel@janis-laptop> <4AB1090D.7050703@redhat.com>
- Reply-to: janis187 at us dot ibm dot com
On Wed, 2009-09-16 at 10:49 -0500, Richard Henderson wrote:
> On 09/15/2009 11:28 AM, Janis Johnson wrote:
> > Ping:
> >
> > http://gcc.gnu.org/ml/gcc-patches/2009-08/msg01364.html
>
>
> > + one = real_digit (1);
> > + ten = ten_to_ptwo (0);
> > + pten = *one;
> > +
> > + sign = r.sign;
> > + r.sign = 0;
> > +
> > + dec_exp = REAL_EXP (&r) * M_LOG10_2;
> > + for (i = 0; i < dec_exp; i++)
> > + do_multiply (&pten, &pten, ten);
>
> Use times_pten. Ok with that change.
>
> It's marginally unfortunate that you don't seem to be able
> to re-use real_to_decimal_for_mode, but I won't quibble.
Here are the changes I checked in for real.c. Is this OK for 4.4
and 4.3 as well?
I also made a minor change to the test to use a new header file for
debugging macros.
Index: gcc/real.c
===================================================================
--- gcc/real.c (revision 151782)
+++ gcc/real.c (working copy)
@@ -110,6 +110,9 @@ static int do_compare (const REAL_VALUE_
static void do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
static unsigned long rtd_divmod (REAL_VALUE_TYPE *, REAL_VALUE_TYPE *);
+static void decimal_from_integer (REAL_VALUE_TYPE *);
+static void decimal_integer_string (char *, const REAL_VALUE_TYPE *,
+ size_t);
static const REAL_VALUE_TYPE * ten_to_ptwo (int);
static const REAL_VALUE_TYPE * ten_to_mptwo (int);
@@ -2168,10 +2171,70 @@ real_from_integer (REAL_VALUE_TYPE *r, e
normalize (r);
}
- if (mode != VOIDmode)
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ decimal_from_integer (r);
+ else if (mode != VOIDmode)
real_convert (r, mode, r);
}
+/* Render R, an integral value, as a floating point constant with no
+ specified exponent. */
+
+static void
+decimal_integer_string (char *str, const REAL_VALUE_TYPE *r_orig,
+ size_t buf_size)
+{
+ int dec_exp, digit, digits;
+ REAL_VALUE_TYPE r, pten;
+ char *p;
+ bool sign;
+
+ r = *r_orig;
+
+ if (r.cl == rvc_zero)
+ {
+ strcpy (str, "0.");
+ return;
+ }
+
+ sign = r.sign;
+ r.sign = 0;
+
+ dec_exp = REAL_EXP (&r) * M_LOG10_2;
+ digits = dec_exp + 1;
+ gcc_assert ((digits + 2) < (int)buf_size);
+
+ pten = *real_digit (1);
+ times_pten (&pten, dec_exp);
+
+ p = str;
+ if (sign)
+ *p++ = '-';
+
+ digit = rtd_divmod (&r, &pten);
+ gcc_assert (digit >= 0 && digit <= 9);
+ *p++ = digit + '0';
+ while (--digits > 0)
+ {
+ times_pten (&r, 1);
+ digit = rtd_divmod (&r, &pten);
+ *p++ = digit + '0';
+ }
+ *p++ = '.';
+ *p++ = '\0';
+}
+
+/* Convert a real with an integral value to decimal float. */
+
+static void
+decimal_from_integer (REAL_VALUE_TYPE *r)
+{
+ char str[256];
+
+ decimal_integer_string (str, r, sizeof (str) - 1);
+ decimal_real_from_string (r, str);
+}
+
/* Returns 10**2**N. */
static const REAL_VALUE_TYPE *