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

[Commits] r19802 - in /libdfp/trunk: ./ sysdeps/dpd/ sysdeps/powerpc/dfpu/ tests/



Author: ryanarn
Date: Tue Jul 24 23:40:38 2012
New Revision: 19802

Log:
2012-07-24  Ryan S. Arnold  <rsa@xxxxxxxxxxxxxxxxxx>

	* Makefile.in (check): Add printf_dfp.o dependency to check in order to
	have make check automatically rebuild libdfp is printf_dfp.c has
	changed.
	* tests/test-decode.c: Add tests for decoding numbers with high
	exponents near __DEC*_MAX_EXP__.
	* tests/test-param.c (param_test): Remove unnecessary assingments.
	* tests/test-printf.c: Add tests for __DEC64_MAX__.
	* tests/test-numdigits.c: Add tests for __DEC64_MAX__ and numbers
	approaching __DEC*_MAX_EXP__.
	* tests/test-GCC-PR52140.c (main): Remove unnecessary assignments.
	* tests/test-ostream.cpp: Formatting.
	* tests/debug-test.sh: Add ./ as a path prefix.
	* sysdeps/powerpc/dfpu/numdigits.h (numdigitsd*): Fix for numbers with
	exponent approaching __DEC*_MAX_EXP__ by biasing the exponent toward
	zero.
	* sysdeps/dpd/dpd-private.c: Formatting.
	* TODO: New items.
	* printf_dfp.c (__printf_dfp): Fix for g/G specifier that converst to
	f/F form.  Fix for a/A when the user supplied precision is 0, i.e.
	%.Ha.

Modified:
    libdfp/trunk/Makefile.in
    libdfp/trunk/TODO
    libdfp/trunk/printf_dfp.c
    libdfp/trunk/sysdeps/dpd/dpd-private.c
    libdfp/trunk/sysdeps/powerpc/dfpu/numdigits.h
    libdfp/trunk/tests/debug-test.sh
    libdfp/trunk/tests/test-GCC-PR52140.c
    libdfp/trunk/tests/test-decode.c
    libdfp/trunk/tests/test-numdigits.c
    libdfp/trunk/tests/test-ostream.cpp
    libdfp/trunk/tests/test-param.c
    libdfp/trunk/tests/test-printf.c

Modified: libdfp/trunk/Makefile.in
==============================================================================
--- libdfp/trunk/Makefile.in (original)
+++ libdfp/trunk/Makefile.in Tue Jul 24 23:40:38 2012
@@ -341,6 +341,8 @@
 
 libdfp_tests = $(libdfp_c_tests) $(libdfp_cxx_tests)
 
+CFLAGS-test-param.c += -O0
+
 # Empty rule which simply makes the libdfp_tests .so's dependent on
 # tests/scaffold.c so that when the scaffold file changes all of the test .so
 # files are rebuilt since almost all of them depend on the scaffold anyway.
@@ -393,7 +395,7 @@
 # We use debug-test.conf as an input file for some debugging utilities.  The
 # .out files are predicated in another rule on the actual test executables, so
 # those are built from those rules.
-check: $(top_builddir)/debug-test.conf $(addsuffix .conf,$(libdfp_tests)) $(addsuffix .out,$(libdfp_tests))
+check: $(top_builddir)/printf_dfp.o $(top_builddir)/debug-test.conf $(addsuffix .conf,$(libdfp_tests)) $(addsuffix .out,$(libdfp_tests))
 	@echo +Completed make check
 
 .PHONY: check

Modified: libdfp/trunk/TODO
==============================================================================
--- libdfp/trunk/TODO (original)
+++ libdfp/trunk/TODO Tue Jul 24 23:40:38 2012
@@ -1,4 +1,8 @@
+Add tests/test-getexp to determine whether the hardware dfp version stores the
+proper sign of the exponent with the stfiwx call.
 
+Make get_digits calls use getexp_d* rather than computing the exponent
+directly.
 
 Upgrade libdecnumber version.
   Upgrade autoconf version

Modified: libdfp/trunk/printf_dfp.c
==============================================================================
--- libdfp/trunk/printf_dfp.c (original)
+++ libdfp/trunk/printf_dfp.c Tue Jul 24 23:40:38 2012
@@ -219,6 +219,13 @@
       OUT("prec",pr); \
     } while (0)
 
+#define OUT_INPUT_PREC(pr) \
+  do \
+    { \
+      OUT("input_prec",pr); \
+    } while (0)
+
+
 #define OUT_INDEX(idx) \
   do \
     { \
@@ -540,14 +547,7 @@
 	  {
 	    /* The DFP spec addition for %a refers to all of the significant
 	     * digits in the precision.  */
-	    if (exp < 0)
-	      {
-		  input_prec = nd;
-	      }
-	    else
-	      {
-	        input_prec = 1;
-	      }
+	    input_prec = nd;
 
 	    /* This same check is done in two different places but it'll only
 	     * effect a single pass through once.  If prec is not set it'll hit
@@ -607,8 +607,8 @@
 	      {
 		prec = P - 1;
 		spec = 'e';
-		input_prec = nd - 1;
 	      }
+	    input_prec = nd - 1;
 	  break;
 	  }
 	case 'e':
@@ -646,8 +646,10 @@
 	index = n + nd + exp + prec;
       /* Goofy special case where we round significant digits which aren't
        * right of the decimal place.  */
-      else if (tolower(info->spec) == 'a')
+      else if (tolower(info->spec) == 'a' && prec > 0)
+       {
 	index = n + prec;
+       }
       else
 	index = n + prec + 1;
 

Modified: libdfp/trunk/sysdeps/dpd/dpd-private.c
==============================================================================
--- libdfp/trunk/sysdeps/dpd/dpd-private.c (original)
+++ libdfp/trunk/sysdeps/dpd/dpd-private.c Tue Jul 24 23:40:38 2012
@@ -775,6 +775,7 @@
   union ieee754r_Decimal64 d;
   d.dd = x;
   c_f =  c_decoder[d.ieee.c];
+  /* Consider replacing with a call to getexp_d* for hardware support  */
   exp = c_f.lm_exp << DECIMAL64_BEC_bits;
   exp += d.ieee.bec;
   exp -= DECIMAL64_Bias;

Modified: libdfp/trunk/sysdeps/powerpc/dfpu/numdigits.h
==============================================================================
--- libdfp/trunk/sysdeps/powerpc/dfpu/numdigits.h (original)
+++ libdfp/trunk/sysdeps/powerpc/dfpu/numdigits.h Tue Jul 24 23:40:38 2012
@@ -122,27 +122,55 @@
 #endif
   double f1, f2;
   DEC_TYPE f3;
-  int i1, i2;
+  long long i1, i2;
   static union
   {
     int i[2];
+    long long l;
     double f;
-  } u = { { 0, 1 } };
+  } u = { { 0, 1 } }, v = { { 0, 398 } };
   asm (
 #if _DECIMAL_SIZE != 128
-    "dxex %2,%5\n\t"
-    "drrnd %4,%6,%5,1\n\t"
-    "dxex %3,%4\n\t"
-#else /* _DECIMAL_SIZE == 128 */
-    "dxexq %2,%5\n\t"
-    "drrndq %4,%6,%5,1\n\t"
-    "dxexq %3,%4\n\t"
-#endif
-    "stfiwx %2,%y0\n\t"
-    "stfiwx %3,%y1\n\t"
-    : "=Z"(i1), "=Z"(i2), "=&d"(f1), "=&d"(f2), "=&d"(f3)
-    : "d"(tmp), "d"(u.f));
-  return i2 - i1 + 1;
+    /* Prep for a NAN test.  */
+    "dxex %0,%4\n\t"
+    "stfd %0,%3\n\t"
+    /* We don't care what the exponent actually is, as long at it's less than
+     * '369'.  Set the exponent to zero in preparation for the reround.  Biased
+     * exponent '398' equals zero.*/
+    "diex %2,%5,%4\n\t"
+#else /* _DECIMAL_SIZE == 128  */
+    /* Prep for a NAN test.  */
+    "dxexq %0,%4\n\t"
+    "stfd %0,%3\n\t"
+    /* We don't care what the exponent actually is, as long at it's less than
+     * '369'.  Set the exponent to zero in preparation for the reround.  Biased
+     * exponent '398' equals zero.*/
+    "diexq %2,%5,%4\n\t"
+#endif
+  : "=&d"(f1), "=&d"(f2), "=&d"(f3), "=m"(i1)
+  : "d"(tmp), "d"(v.f));
+
+  /* check for NaN and infinity.  dxex returns < 0 for qnan, snan, and inf.  */
+  if (i1 < 0)
+    return i1;
+
+  asm (
+#if _DECIMAL_SIZE != 128
+    "drrnd %0,%3,%4,1\n\t" 
+    "dxex %1,%0\n\t"
+    "stfd %1,%2\n\t"
+#else /* _DECIMAL_SIZE == 128  */
+    "drrndq %0,%3,%4,1\n\t" 
+    "dxexq %1,%0\n\t"
+    "stfd %1,%2\n\t"
+#endif
+    : "=&d"(f1), "=&d"(f2), "=m"(i2)
+    : "d"(u.f), "d"(f3));
+
+  /* v.l holds the normalized reference exponent.
+     i2 holds the computed exponent after reround.  */
+
+  return i2 - v.l + 1;
 }
 
 static inline DEC_TYPE

Modified: libdfp/trunk/tests/debug-test.sh
==============================================================================
--- libdfp/trunk/tests/debug-test.sh (original)
+++ libdfp/trunk/tests/debug-test.sh Tue Jul 24 23:40:38 2012
@@ -3,8 +3,8 @@
 if test -z "$1"; then
 	echo "$1 must be the test-*.conf file name you wish to debug."
 fi
-	source debug-test.conf
-	source $1
+	source ./debug-test.conf
+	source ./$1
 
 # Depending on whether a [system|standalone] loader or a non-installed glibc
 # build's loader this will be invoked differently.

Modified: libdfp/trunk/tests/test-GCC-PR52140.c
==============================================================================
--- libdfp/trunk/tests/test-GCC-PR52140.c (original)
+++ libdfp/trunk/tests/test-GCC-PR52140.c Tue Jul 24 23:40:38 2012
@@ -26,6 +26,8 @@
 #define __STDC_WANT_DEC_FP__
 #endif
 
+int foo (_Decimal64 x, _Decimal64 y);
+
 int
 foo (_Decimal64 x, _Decimal64 y)
 {
@@ -37,9 +39,8 @@
 
 int main(void)
 {
-  int ret = -1;
   _Decimal64 a = 12.45DD;
   _Decimal64 b = 12.43DD;
-  ret = foo (a,b);
+  foo (a,b);
   return 0;
 }

Modified: libdfp/trunk/tests/test-decode.c
==============================================================================
--- libdfp/trunk/tests/test-decode.c (original)
+++ libdfp/trunk/tests/test-decode.c Tue Jul 24 23:40:38 2012
@@ -46,7 +46,7 @@
   const char *expect;
 } d64_type;
 
-typedef union{
+/*typedef union{
   _Decimal128 d;
   long i[4];
 } d128_u;
@@ -54,23 +54,37 @@
 typedef union{
   _Decimal64 d;
   long i[4];
-} d64_u;
+} d64_u; */
+
+#define DEC_INFINITY	__builtin_infd32()
+#define DEC_NAN		(0.0DF * DEC_INFINITY)
 
 int main (void)
 {
   d64_type *d64ptr = NULL;
   d128_type *d128ptr = NULL;
 
-  d64_u d64u;
+/*  d64_u d64u;
   d64u.d = 1.00DD;
 
   d128_u d128u;
-  d128u.d = 1.00DL;
+  d128u.d = 1.00DL; */
 
   d64_type d64types[] =
     {
 #ifdef _DPD_BACKEND
       {__LINE__,1.00DD, "+0,000,000,000,000,100E-2"},
+      {__LINE__,__DEC64_MAX__, "+9,999,999,999,999,999E+369"},
+      {__LINE__,-DEC_NAN, "-0,000,000,000,000,000E-398"},
+      {__LINE__,9.999999999999999E369DD, "+9,999,999,999,999,999E+354"},
+      {__LINE__,9.999999999999999E370DD, "+9,999,999,999,999,999E+355"},
+      {__LINE__,9.999999999999999E384DD, "+9,999,999,999,999,999E+369"},
+      {__LINE__,__DEC64_MIN__, "+0,000,000,000,000,001E-383"},
+      {__LINE__,__DEC64_SUBNORMAL_MIN__, "+0,000,000,000,000,001E-398"},
+      {__LINE__,1E-398DD, "+0,000,000,000,000,001E-398" },
+      /* Notice, this number exceeds DEC64_SUBNORMAL_MIN.  */
+      {__LINE__,1E-399DD, "+0,000,000,000,000,000E-398" },
+      {__LINE__, 9E370DD, "+0,000,000,000,000,090E+369"},
 #else
       {__LINE__,1.00DD, "BID not supported."},
 #endif

Modified: libdfp/trunk/tests/test-numdigits.c
==============================================================================
--- libdfp/trunk/tests/test-numdigits.c (original)
+++ libdfp/trunk/tests/test-numdigits.c Tue Jul 24 23:40:38 2012
@@ -92,7 +92,7 @@
 
 d64_type printf_d64s[] =
 {
-  {__LINE__, 0.02E-2DD, 1,  "%d"},
+/*  {__LINE__, 0.02E-2DD, 1,  "%d"},
   {__LINE__, 0.0200E-2DD, 3,  "%d"},
   {__LINE__, 1.0E-2DD, 2,  "%d"},
   {__LINE__, 0.0000345E-2DD, 3,  "%d"},
@@ -100,9 +100,34 @@
   {__LINE__, 123456.0E-2DD, 7,  "%d"},
   {__LINE__, 123456.000E-2DD, 9,  "%d"},
   {__LINE__, 123456.000E-4DD, 9,  "%d"},
-  {__LINE__, 123456.000E-6DD, 9,  "%d"},
-  /* can't exceed __DEC64_MANT_DIG__  */
-  {__LINE__, 123456.00000000000000E-18DD, 16,  "%d"},
+  {__LINE__, 123456.000E-6DD, 9,  "%d"}, */
+
+  /* Can't exceed __DEC64_MANT_DIG__.  This test has 17 digits but the
+   * compiler will truncate it (or round) before it's passed   */
+  {__LINE__, 9.9999999999999999E300DD, 16, "%d"},
+
+  /* There was a known bug with any value where the normalized exponent
+   * exceeded 369.  This caused __DEC64_MAX__ to return incorrect results.  */
+  {__LINE__, __DEC64_MAX__, 16, "%d"},
+
+  /* The normalized exponent is '369' so the right justified encoding has two
+   * digits, '90', in the mantissa.  */
+
+  {__LINE__, 9E370DD, 2, "%d"},
+
+  /* Fails the same way since the absolute value of the exponent exceeds 369.
+   */
+  {__LINE__, __DEC64_MIN__, 1, "%d"},
+  {__LINE__, 1E-398DD, 1, "%d"},
+
+  /* 0.000000000000001E-383DD  */
+  {__LINE__, __DEC64_SUBNORMAL_MIN__, 1, "%d"},
+
+  /* The compiler truncates this and anything with a smaller (more negative)
+   * exponent than 398 to zero when normalizing the constant into DFP
+   * representation.  */
+  {__LINE__, 1E-399DD, 1, "%d"}, 
+
   {0,0,0,0 }
 };
 
@@ -148,6 +173,26 @@
   {0,0,0,0 }
 };
 
+int nd128 (_Decimal128 d);
+int nd64 (_Decimal64 d);
+int nd32 (_Decimal32 d);
+
+/* Use these so that the inline function is inlined into a wrapper function
+ * for easier debugging.  */
+int nd128(_Decimal128 d)
+{
+	return numdigitsd128(d);
+}
+int nd64(_Decimal64 d)
+{
+	return numdigitsd64(d);
+}
+
+int nd32(_Decimal32 d)
+{
+	return numdigitsd32(d);
+}
+
 int main (void)
 {
   d128_type *d128ptr;
@@ -156,21 +201,21 @@
 
   for (d128ptr = printf_d128s; d128ptr->line; d128ptr++)
     {
-      int retval = numdigitsd128(d128ptr->x);
+      int retval = nd128(d128ptr->x);
       fprintf(stdout,"numdigitsd128(%DDfDL) in: %s:%d\n", d128ptr->x,__FILE__,__LINE__-1);
       _VC_P(__FILE__,d128ptr->line, d128ptr->e,retval,d128ptr->format);
     }
 
   for (d64ptr = printf_d64s; d64ptr->line; d64ptr++)
     {
-      int retval = numdigitsd64(d64ptr->x);
+      int retval = nd64(d64ptr->x);
       fprintf(stdout,"numdigitsd64(%DfDD) in: %s:%d\n", d64ptr->x,__FILE__,__LINE__-1);
       _VC_P(__FILE__,d64ptr->line, d64ptr->e,retval,d64ptr->format);
     }
 
   for (d32ptr = printf_d32s; d32ptr->line; d32ptr++)
     {
-      int retval = numdigitsd32(d32ptr->x);
+      int retval = nd32(d32ptr->x);
       fprintf(stdout,"numdigitsd32(%HfDF) in: %s:%d\n", d32ptr->x,__FILE__,__LINE__-1);
       _VC_P(__FILE__,d32ptr->line, d32ptr->e,retval,d32ptr->format);
     }

Modified: libdfp/trunk/tests/test-ostream.cpp
==============================================================================
--- libdfp/trunk/tests/test-ostream.cpp (original)
+++ libdfp/trunk/tests/test-ostream.cpp Tue Jul 24 23:40:38 2012
@@ -83,6 +83,8 @@
   {__LINE__, __builtin_infd64(), "INF", -1, 'u', 'a' },
   {__LINE__, (0.0DD * __builtin_infd64()), "NAN", -1, 'u', 'a' },
   {__LINE__, (0.0DD * __builtin_infd64()), "nan", -1, 'l', 'a' },
+  {__LINE__, -(0.0DD * __builtin_infd64()), "-NAN", -1, 'u', 'a' },
+  {__LINE__, -(0.0DD * __builtin_infd64()), "-nan", -1, 'l', 'a' },
   {0,0,0,0,0,0}
 };
 
@@ -100,6 +102,10 @@
   {__LINE__, -1234.56789123456789123455678DL, "-1234.57", -1, 'l', 'a' },
   {__LINE__, -1234.56789123456789123455678DL, "-1234.5679", 8, 'l', 'a' },
   {__LINE__, -12345678912345678.9123455678DL, "-12345678912345678.9123455678", 10, 'u', 'f' },
+  {__LINE__, (0.0DL * __builtin_infd128()), "NAN", -1, 'u', 'a' },
+  {__LINE__, (0.0DL * __builtin_infd128()), "nan", -1, 'l', 'a' },
+  {__LINE__, -(0.0DL * __builtin_infd128()), "-NAN", -1, 'u', 'a' },
+  {__LINE__, -(0.0DL * __builtin_infd128()), "-nan", -1, 'l', 'a' },
   {0,0,0,0,0,0}
 };
 

Modified: libdfp/trunk/tests/test-param.c
==============================================================================
--- libdfp/trunk/tests/test-param.c (original)
+++ libdfp/trunk/tests/test-param.c Tue Jul 24 23:40:38 2012
@@ -80,10 +80,10 @@
 	       _Decimal64 f64 __attribute__ ((unused)),
 	       _Decimal128 f128)
 {
-  volatile _Decimal128 z;
-  volatile _Decimal128 y;
-  z = e128;
-  y = f128;
+  volatile _Decimal128 z = e128;
+  volatile _Decimal128 y = f128;
+//  z = e128;
+ // y = f128;
   return 0;
 }
 

Modified: libdfp/trunk/tests/test-printf.c
==============================================================================
--- libdfp/trunk/tests/test-printf.c (original)
+++ libdfp/trunk/tests/test-printf.c Tue Jul 24 23:40:38 2012
@@ -119,6 +119,8 @@
   /* Erroneously prints "1e+6" due to the '.' with no explicit precision. FIX
    * ME.  */
   {__LINE__, 6.0E5DF, "6e+5", "%.Ha"},
+  {__LINE__, 6.0E5DF, "6e+5", "%.0Ha"},
+  {__LINE__, 6.E5DF, "6e+5", "%.0Ha"},
 
   {__LINE__, 0.0e10DF, "0.000000e+00", "%He"},
   {__LINE__, 0.0e10DF, "0.000000", "%Hf"},
@@ -217,6 +219,7 @@
   {__LINE__, 6543.00DF, "6543.00", "%Ha"},
   {__LINE__, 6543.00DF, "6543.00", "%.6Ha"},
   {__LINE__, 6543.00DF, "6543.0", "%.5Ha"},
+  {__LINE__, 6543.09DF, "6543.1", "%.5Ha"},
   {__LINE__, 6543.00DF, "6543", "%.4Ha"},
   {__LINE__, 6543.00DF, "6.54e+3", "%.3Ha"},
   {__LINE__, 6543.00DF, "6.5e+3", "%.2Ha"},
@@ -487,6 +490,18 @@
 
   {__LINE__, 6543.00DD, " 6543.00", "%8Da"},
 
+  {__LINE__, __DEC64_MAX__, "9.999999999999999e+384", "%.17Dg" },
+  {__LINE__, 9.999999999999999E16DD, "9.999999999999999e+16", "%.16Dg" },
+  {__LINE__, 9.999999999999999E23DD, "9.999999999999999e+23", "%.16Dg" },
+  {__LINE__, 9.999999999999999E300DD, "9.999999999999999e+300", "%.16Dg" },
+  {__LINE__, 9.999999999999999E360DD, "9.999999999999999e+360", "%.16Dg" },
+  {__LINE__, 9.999999999999999E369DD, "9.999999999999999e+369", "%.16Dg" },
+  {__LINE__, 9.999999999999999E370DD, "9.999999999999999e+370", "%.16Dg" },
+  {__LINE__, 9.999999999999999E379DD, "9.999999999999999e+379", "%.16Dg" },
+  {__LINE__, 9.999999999999999E380DD, "9.999999999999999e+380", "%.16Dg" },
+  {__LINE__, 9999999999999999E369DD, "9.999999999999999e+384", "%.16Dg" },
+
+
   {0,0,0,0 }
 };
 
@@ -720,8 +735,11 @@
   {__LINE__, (1.0DL / 1.000000e-123DL), "1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000", "%DDf"},
 
   {__LINE__, -1234.56789123456789123455678DL, "-1234.56789123", "%.8DDf"},
-  /* This should be the same as %.8DDf.  FIX ME. */
-  {__LINE__, -1234.56789123456789123455678DL, "-1234.56789123", "%.8DDg"},
+  /* This prints like f/F but g/G computes precision based on all digits in
+   * the mantissa, not just those to the right of the decimal place like
+   * regular f/F.  */
+  {__LINE__, -1234.56789123456789123455678DL, "-1234.5679", "%.8DDg"},
+  {__LINE__, -1234.56789123456789123455678DL, "-1234.56789123", "%.12DDg"},
   /* This isn't properly rounding after the truncated.  FIX ME. */
   {__LINE__, -1234.56789123456789123455678DL, "-1234.57", "%DDg"},
   {__LINE__, -1234.56789123456789123455678DL, "-1234.5679", "%.8DDa"},

_______________________________________________
Commits mailing list
Commits@xxxxxxxxxx
http://eglibc.org/cgi-bin/mailman/listinfo/commits