[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libdfp-patches] [PATCH] Fix latest testsuite failures on S/390



Hi,

the attached patch fixes some new failures occuring with the latest
libdfp version on the S/390 hardware variant.

Please apply if ok.

Bye,

-Andreas-


2011-01-20  Andreas Krebbel  <Andreas.Krebbel@xxxxxxxxxx>

	* sysdeps/s390/dfpu/numdigits.h (setexp): Zero extend the exponent
	input value to 64 bit.
	(numdigits): Mimic the Power and soft-dfp behaviour of never
	returning zero.
	* sysdeps/s390/dfpu/fe_decround.c (__fe_dec_setround): Enabled the
	non-standard rounding modes supported by Power, s390 and the
	software implementation.
	Zero extend the rounding mode parameter to 64 bit.


Index: sysdeps/s390/dfpu/numdigits.h
===================================================================
--- sysdeps/s390/dfpu/numdigits.h.orig
+++ sysdeps/s390/dfpu/numdigits.h
@@ -86,6 +86,8 @@ FUNC_D (getexp) (DEC_TYPE x)
 static inline DEC_TYPE
 FUNC_D (setexp) (DEC_TYPE x, int exp)
 {
+  int biased_exp = exp + DECIMAL_BIAS;
+
 #if _DECIMAL_SIZE == 32
   _Decimal64 tmp = (_Decimal64)x;
 #elif _DECIMAL_SIZE == 128
@@ -95,12 +97,13 @@ FUNC_D (setexp) (DEC_TYPE x, int exp)
 #endif
 
   asm (
+    "llgfr %1,%1   \n\t"
 #if _DECIMAL_SIZE == 128
     "iextr %0,%0,%1"
 #else
     "iedtr %0,%0,%1"
 #endif
-    : "+f" (tmp) : "r" (exp + DECIMAL_BIAS));
+    : "+f" (tmp), "+d" (biased_exp));
 
 #if _DECIMAL_SIZE == 32
   return (_Decimal32)tmp;
@@ -131,7 +134,12 @@ FUNC_D (numdigits) (DEC_TYPE x)
 #endif
    : "=d"(result) : "f"(tmp));
 
-  return result;
+  /* The Power hardware implementation returns 1 even for a zero
+     mantissa.  The software implementation in soft-dfp mimics that
+     behaviour.  The S/390 instructions return 0 for zero values.  So
+     we have to adjust this here in order to match the behaviour of
+     the existing functions.  */
+  return (result == 0 ? 1 : result);
 }
 
 static DEC_TYPE
Index: sysdeps/s390/dfpu/fe_decround.c
===================================================================
--- sysdeps/s390/dfpu/fe_decround.c.orig
+++ sysdeps/s390/dfpu/fe_decround.c
@@ -43,15 +43,17 @@ hidden_def(__fe_dec_getround)
 int
 __fe_dec_setround (int round)
 {
-  if ((round|FPC_DFP_RM_MASK) != FPC_DFP_RM_MASK
-      || (round > FE_DEC_TONEARESTFROMZERO))
+  /* This currently also allows the extended rounding modes (5, 6 and
+     7) which are not covered by the standard.  Please see
+     fe_decround.c in the root dir for more information.  */
+  if (((round << 4) | FPC_DFP_RM_MASK) != FPC_DFP_RM_MASK)
     {
       /* ROUND is not a valid rounding mode.  */
       return 1;
     }
-  __asm__ volatile ("srnmt 0(%0)"
-		 		     :
-		 		     : "a" (round << 4));
+  __asm__ volatile ("llgfr %0,%0  \n\t"
+		    "srnmt 0(%0)"
+		    : "+a" (round));
 
   return 0;
 }