This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH: PR other/30530: dfp.c assumes DPD encoding
On Sun, Jan 21, 2007 at 02:57:54PM -0800, H. J. Lu wrote:
> On Mon, Jan 22, 2007 at 09:19:43AM +1100, Ben Elliston wrote:
> > Hi HJ
> >
> > On Sun, 2007-01-21 at 13:55 -0800, H. J. Lu wrote:
> >
> > > Does this patch look OK?
> >
> > Yes, but how did you test it?
> >
>
> I tested it on Linux/x86-64 with --enable-decimal-float=dpd.
> Unfortunately, there are 2 problems:
>
> 1. There are
>
> if test x$enablevar = xyes ; then
> case $target in
> powerpc*-*-linux* | i?86*-*-linux*)
> enable_decimal_float=yes
> ;;
> in configure.ac. That means DFP isn't enabled on Linux/x86-64 even
> if it should work.
>
> 2. There are
>
> /* Set sign [this assumes sign previously 0] */
> #define decimal128SetSign(d, b) { \
> (d)->bytes[0]|=((unsigned)(b)<<7);}
>
> That means decimal128SetSign(d, 0) doesn't work. Why does it need
> the second arg at all when only 1 works for the second arg? I
> think we should change it to
>
> #define decimal128SetSign(d) { (d)->bytes[0]|=0x80;}
>
> and add
>
> #define decimal128ClearSign(d) { (d)->bytes[0]&=~0x80;}
> #define decimal128FlipSign(d) { (d)->bytes[0]^=0x80;}
>
> The same apply for decimal32/decimal64.
>
> I will prepare a patch.
>
I am testing this patch on Linux/x86-64 now.
H.J.
---
gcc/
2007-01-21 H.J. Lu <hongjiu.lu@intel.com>
PR other/30529
* config/dfp-bit.c (__dec_byte_swap): Use uint32_t instead of
unsigned long.
* configure.ac: Enable decimal float for x86_64-*-linux*.
* configure: Regenerated.
PR other/30530
* dfp.c (decimal_real_arithmetic): Use decimal128FlipSign and
decimal128ClearSign to flip and clear the sign bit in decimal128.
(decimal_real_maxval): Set decimal128SetSign to set the sign
bit in decimal128.
libdecnumber/
2007-01-21 H.J. Lu <hongjiu.lu@intel.com>
PR other/30530
* decimal128.h(decimal128SetSign): Only take one arg.
(decimal128ClearSign): New.
(decimal128FlipSign): Likewise.
* decimal128.c (decimal128FromNumber): Upate decimal128SetSign
usage.
* decimal32.h(decimal32SetSign): Only take one arg.
(decimal32ClearSign): New.
(decimal32FlipSign): Likewise.
* decimal32.c (decimal32FromNumber): Upate decimal32SetSign
usage.
* decimal64.h(decimal64SetSign): Only take one arg.
(decimal64ClearSign): New.
(decimal64FlipSign): Likewise.
* decimal64.c (decimal64FromNumber): Upate decimal64SetSign
usage.
--- gcc/gcc/config/dfp-bit.c.dpd 2007-01-18 10:42:38.000000000 -0800
+++ gcc/gcc/config/dfp-bit.c 2007-01-21 15:04:23.000000000 -0800
@@ -66,7 +66,7 @@ typedef decNumber* (*dfp_unary_func)
typedef decNumber* (*dfp_binary_func)
(decNumber *, const decNumber *, const decNumber *, decContext *);
-extern unsigned long __dec_byte_swap (unsigned long);
+extern uint32_t __dec_byte_swap (uint32_t);
/* Unary operations. */
--- gcc/gcc/configure.ac.dpd 2007-01-14 07:18:03.000000000 -0800
+++ gcc/gcc/configure.ac 2007-01-21 15:09:17.000000000 -0800
@@ -671,7 +671,7 @@ AC_ARG_ENABLE(decimal-float,
[
if test x$enablevar = xyes ; then
case $target in
- powerpc*-*-linux* | i?86*-*-linux*)
+ powerpc*-*-linux* | i?86*-*-linux* | x86_64-*-linux* )
enable_decimal_float=yes
;;
*)
--- gcc/gcc/dfp.c.dpd 2006-09-27 22:38:25.000000000 -0700
+++ gcc/gcc/dfp.c 2007-01-21 15:16:10.000000000 -0800
@@ -656,11 +656,9 @@ decimal_real_arithmetic (REAL_VALUE_TYPE
case NEGATE_EXPR:
{
- decimal128 *d128;
*r = *op0;
- d128 = (decimal128 *) r->sig;
- /* Flip high bit. */
- d128->bytes[0] ^= 1 << 7;
+ /* Flip sign bit. */
+ decimal128FlipSign ((decimal128 *) r->sig);
/* Keep sign field in sync. */
r->sign ^= 1;
}
@@ -668,11 +666,9 @@ decimal_real_arithmetic (REAL_VALUE_TYPE
case ABS_EXPR:
{
- decimal128 *d128;
*r = *op0;
- d128 = (decimal128 *) r->sig;
- /* Clear high bit. */
- d128->bytes[0] &= 0x7f;
+ /* Clear sign bit. */
+ decimal128ClearSign ((decimal128 *) r->sig);
/* Keep sign field in sync. */
r->sign = 0;
}
@@ -712,5 +708,5 @@ decimal_real_maxval (REAL_VALUE_TYPE *r,
decimal_real_from_string (r, max);
if (sign)
- r->sig[0] |= 0x80000000;
+ decimal128SetSign ((decimal128 *) r->sig);
}
--- gcc/libdecnumber/decimal128.c.dpd 2006-09-27 22:33:08.000000000 -0700
+++ gcc/libdecnumber/decimal128.c 2007-01-21 15:05:16.000000000 -0800
@@ -169,7 +169,7 @@ decimal128FromNumber (decimal128 * d128,
}
if (isneg)
- decimal128SetSign (d128, 1);
+ decimal128SetSign (d128);
if (status != 0)
decContextSetStatus (set, status); /* pass on status */
--- gcc/libdecnumber/decimal128.h.dpd 2006-09-27 22:33:08.000000000 -0700
+++ gcc/libdecnumber/decimal128.h 2007-01-21 15:12:33.000000000 -0800
@@ -77,9 +77,14 @@ typedef struct
| ((unsigned)(d)->bytes[1]<<2) \
| ((unsigned)(d)->bytes[2]>>6))
- /* Set sign [this assumes sign previously 0] */
-#define decimal128SetSign(d, b) { \
- (d)->bytes[0]|=((unsigned)(b)<<7);}
+ /* Set sign */
+#define decimal128SetSign(d) {(d)->bytes[0]|=0x80;}
+
+ /* Clear sign */
+#define decimal128ClearSign(d) {(d)->bytes[0]&=~0x80;}
+
+ /* Flip sign */
+#define decimal128FlipSign(d) {(d)->bytes[0]^=0x80;}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; */
--- gcc/libdecnumber/decimal32.c.dpd 2006-09-27 22:33:08.000000000 -0700
+++ gcc/libdecnumber/decimal32.c 2007-01-21 15:05:23.000000000 -0800
@@ -166,7 +166,7 @@ decimal32FromNumber (decimal32 * d32, co
}
if (isneg)
- decimal32SetSign (d32, 1);
+ decimal32SetSign (d32);
if (status != 0)
decContextSetStatus (set, status); /* pass on status */
--- gcc/libdecnumber/decimal32.h.dpd 2006-09-27 22:33:08.000000000 -0700
+++ gcc/libdecnumber/decimal32.h 2007-01-21 15:12:21.000000000 -0800
@@ -68,9 +68,14 @@ typedef struct
#define decimal32ExpCon(d) ((((d)->bytes[0] & 0x03)<<4) \
| ((unsigned)(d)->bytes[1]>>4))
- /* Set sign [this assumes sign previously 0] */
-#define decimal32SetSign(d, b) { \
- (d)->bytes[0]|=((unsigned)(b)<<7);}
+ /* Set sign */
+#define decimal32SetSign(d) {(d)->bytes[0]|=0x80;}
+
+ /* Clear sign */
+#define decimal32ClearSign(d) {(d)->bytes[0]&=~0x80;}
+
+ /* Flip sign */
+#define decimal32FlipSign(d) {(d)->bytes[0]^=0x80;}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; */
--- gcc/libdecnumber/decimal64.c.dpd 2006-09-27 22:33:08.000000000 -0700
+++ gcc/libdecnumber/decimal64.c 2007-01-21 15:05:30.000000000 -0800
@@ -165,7 +165,7 @@ decimal64FromNumber (decimal64 * d64, co
}
if (isneg)
- decimal64SetSign (d64, 1);
+ decimal64SetSign (d64);
if (status != 0)
decContextSetStatus (set, status); /* pass on status */
--- gcc/libdecnumber/decimal64.h.dpd 2006-09-27 22:33:08.000000000 -0700
+++ gcc/libdecnumber/decimal64.h 2007-01-21 15:12:47.000000000 -0800
@@ -72,9 +72,14 @@ typedef struct
#define decimal64ExpCon(d) ((((d)->bytes[0] & 0x03)<<6) \
| ((unsigned)(d)->bytes[1]>>2))
- /* Set sign [this assumes sign previously 0] */
-#define decimal64SetSign(d, b) { \
- (d)->bytes[0]|=((unsigned)(b)<<7);}
+ /* Set sign */
+#define decimal64SetSign(d) {(d)->bytes[0]|=0x80;}
+
+ /* Clear sign */
+#define decimal64ClearSign(d) {(d)->bytes[0]&=~0x80;}
+
+ /* Flip sign */
+#define decimal64FlipSign(d) {(d)->bytes[0]^=0x80;}
/* Set exponent continuation [does not apply bias] */
/* This assumes range has been checked and exponent previously 0; type */