This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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 */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]