public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] DFP internal support for FP exceptions
@ 2006-12-01 18:07 Janis Johnson
  2006-12-01 18:14 ` Andrew Pinski
  2006-12-06 23:22 ` Ben Elliston
  0 siblings, 2 replies; 10+ messages in thread
From: Janis Johnson @ 2006-12-01 18:07 UTC (permalink / raw)
  To: gcc-patches; +Cc: bje

This patch adds parameterized support to the decimal float runtime to
detect conditions that require floating point exceptions to be raised
and then raise them, if the appropriate support is defined.

By default, the functions use undocumented support used for testing
purposes, but that can be overridden to do something else, such as
calling feraiseexcept.  That might be done in a separate version of
the library compiled with such support, rather than in libgcc which
shouldn't have dependencies on libm.  This support is modelled after
the soft-fp support for fp exceptions.

I realize that GCC optimizers don't properly support fp exceptions, but
this is useful as part of the first implementation of C decimal float
for people trying out the extension.

Tested on powerpc64-linux; ok for trunk?

2006-12-01  Janis Johnson  <janis187@us.ibm.com>

libdecnumber/
	* decExcept.c: New.
	* decExcept.h: New.

gcc/
	* config/dfp-bit.c: Add parameterized support for fp exceptions.
	* config/dfp-bit.h: Ditto.
	* mklibgcc.in: Add decExcept.h to dfp-bit.c dependencies.

gcc/testsuite/
	* gcc.dg/dfp/dfp-except.h: New file.
	* gcc.dg/dfp/fe-check.h: New file.
	* gcc.dg/dfp/fe-binop.c: New test.
	* gcc.dg/dfp/fe-convert-1.c: New test.
	* gcc.dg/dfp/fe-convert-2.c: New test.

Index: libdecnumber/decExcept.c
===================================================================
--- libdecnumber/decExcept.c	(revision 0)
+++ libdecnumber/decExcept.c	(revision 0)
@@ -0,0 +1,50 @@
+/* Temporary library support for decimal floating point.
+   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include <fenv.h>
+#include "config.h"
+#include "decContext.h"
+#include "decExcept.h"
+
+/* Internal, non-documented functions for testing libgcc functions.
+   This support is not sufficient for real use.  */
+
+static int __dfp_except_flags = 0;
+
+/* Clear the dummy exception flags.  */
+void
+__dfp_clear_except (void)
+{
+  __dfp_except_flags = 0;
+}
+
+/* Return the dummy exception flags corresponding to the mask.  */
+int
+__dfp_test_except (int mask)
+{
+  return __dfp_except_flags & mask;
+}
+
+/* Set dummy exception flags.  */
+void
+__dfp_raise_except (int flags)
+{
+  __dfp_except_flags |= flags;
+}
Index: libdecnumber/decExcept.h
===================================================================
--- libdecnumber/decExcept.h	(revision 0)
+++ libdecnumber/decExcept.h	(revision 0)
@@ -0,0 +1,30 @@
+/* Temporary library support for decimal floating point.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include <fenv.h>
+#include "config.h"
+#include "decContext.h"
+
+#define DFP_EXCEPTIONS_ENABLED 1
+#define DFP_HANDLE_EXCEPTIONS(A) __dfp_raise_except(A)
+
+void __dfp_clear_except (void);
+int __dfp_test_except (int);
+void __dfp_raise_except (int);
Index: gcc/config/dfp-bit.c
===================================================================
--- gcc/config/dfp-bit.c	(revision 119368)
+++ gcc/config/dfp-bit.c	(working copy)
@@ -88,6 +88,19 @@
   /* Perform the operation.  */
   op (&res, &arg1, &context);
 
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Division_by_zero | DEC_IEEE_854_Inexact
+		      | DEC_IEEE_854_Invalid_operation | DEC_IEEE_854_Overflow
+		      | DEC_IEEE_854_Underflow;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   TO_ENCODED (&encoded_result, &res, &context);
   IEEE_TO_HOST (encoded_result, &result);
   return result;
@@ -115,6 +128,19 @@
   /* Perform the operation.  */
   op (&res, &arg1, &arg2, &context);
 
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Division_by_zero | DEC_IEEE_854_Inexact
+		      | DEC_IEEE_854_Invalid_operation | DEC_IEEE_854_Overflow
+		      | DEC_IEEE_854_Underflow;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   TO_ENCODED (&encoded_result, &res, &context);
   IEEE_TO_HOST (encoded_result, &result);
   return result;
@@ -142,6 +168,17 @@
   /* Perform the comparison.  */
   op (&res, &arg1, &arg2, &context);
 
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Invalid_operation;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   if (decNumberIsNegative (&res))
     result = -1;
   else if (decNumberIsZero (&res))
@@ -371,6 +408,17 @@
   TO_INTERNAL (&s_from, &d);
   TO_ENCODED_TO (&s_to, &d, &context);
 
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Inexact | DEC_IEEE_854_Invalid_operation;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   IEEE_TO_HOST_TO (s_to, &f_to);
   return f_to;
 }
@@ -405,6 +453,18 @@
   decNumberFromString (&qval, (char *) "1.0", &context);
   /* Force the exponent to zero.  */
   decNumberQuantize (&n1, &n2, &qval, &context);
+
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Invalid_operation;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   /* Get a string, which at this point will not include an exponent.  */
   decNumberToString (&n1, buf);
   /* Ignore the fractional part.  */
@@ -436,6 +496,19 @@
   /* Convert from the floating point string to a decimal* type.  */
   FROM_STRING (&s, buf, &context);
   IEEE_TO_HOST (s, &f);
+
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Inexact | DEC_IEEE_854_Invalid_operation
+		      | DEC_IEEE_854_Overflow;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   return f;
 }
 #endif
@@ -484,6 +557,19 @@
   /* Convert from the floating point string to a decimal* type.  */
   FROM_STRING (&s, buf, &context);
   IEEE_TO_HOST (s, &f);
+
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Inexact | DEC_IEEE_854_Invalid_operation
+		      | DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   return f;
 }
 #endif
Index: gcc/config/dfp-bit.h
===================================================================
--- gcc/config/dfp-bit.h	(revision 119368)
+++ gcc/config/dfp-bit.h	(working copy)
@@ -32,6 +32,7 @@
 
 #include <fenv.h>
 #include <decRound.h>
+#include <decExcept.h>
 #include "tconfig.h"
 #include "coretypes.h"
 #include "tm.h"
@@ -120,6 +121,27 @@
 #define DFP_INIT_ROUNDMODE(A) A = DEC_ROUND_HALF_EVEN
 #endif
 
+#ifdef DFP_EXCEPTIONS_ENABLED
+/* Return IEEE exception flags based on decNumber status flags.  */
+#define DFP_IEEE_FLAGS(DEC_FLAGS) __extension__			\
+({int _fe_flags = 0;						\
+  if ((dec_flags & DEC_IEEE_854_Division_by_zero) != 0)		\
+    _fe_flags |= FE_DIVBYZERO;					\
+  if ((dec_flags & DEC_IEEE_854_Inexact) != 0)			\
+    _fe_flags |= FE_INEXACT;					\
+  if ((dec_flags & DEC_IEEE_854_Invalid_operation) != 0)	\
+    _fe_flags |= FE_INVALID;					\
+  if ((dec_flags & DEC_IEEE_854_Overflow) != 0)			\
+    _fe_flags |= FE_OVERFLOW;					\
+  if ((dec_flags & DEC_IEEE_854_Underflow) != 0)		\
+    _fe_flags |= FE_UNDERFLOW;					\
+  _fe_flags; })
+#else
+#define DFP_EXCEPTIONS_ENABLED 0
+#define DFP_IEEE_FLAGS(A) 0
+#define DFP_HANDLE_EXCEPTIONS(A) do {} while (0)
+#endif
+
 /* Conversions between different decimal float types use WIDTH_TO to
    determine additional macros to define.  */
 
Index: gcc/mklibgcc.in
===================================================================
--- gcc/mklibgcc.in	(revision 119368)
+++ gcc/mklibgcc.in	(working copy)
@@ -146,7 +146,7 @@
 	$(srcdir)/../libdecnumber/decimal128.h $(srcdir)/../libdecnumber/decDPD.h $(srcdir)/../libdecnumber/decUtility.h'
 
 # Dependencies for dfp-bit.c
-dfpbit_c_dep='$(srcdir)/../libdecnumber/decRound.h'" $libgcc_dep $decnumber_dep"
+dfpbit_c_dep='$(srcdir)/../libdecnumber/decRound.h $(srcdir)/../libdecnumber/decExcept.h'" $libgcc_dep $decnumber_dep"
 
 # Flag whether we need eh_dummy.c
 need_eh_dummy=
Index: gcc/testsuite/gcc.dg/dfp/dfp-except.h
===================================================================
--- gcc/testsuite/gcc.dg/dfp/dfp-except.h	(revision 0)
+++ gcc/testsuite/gcc.dg/dfp/dfp-except.h	(revision 0)
@@ -0,0 +1,13 @@
+/* Use undocumented functions in libgcc to clear and test dummy floating
+   point exception flags.  That functionality is in libgcc just for
+   testing purposes.
+
+   If fesetexcept and feclearexcept are available, use those instead.  */
+
+/* Get names of exception flags.  */
+#include <fenv.h>
+
+extern void __dfp_clear_except (int);
+#define DFP_CLEAR_EXCEPT(M) __dfp_clear_except(M)
+extern int __dfp_test_except (int);
+#define DFP_TEST_EXCEPT(M) __dfp_test_except(M)
Index: gcc/testsuite/gcc.dg/dfp/fe-check.h
===================================================================
--- gcc/testsuite/gcc.dg/dfp/fe-check.h	(revision 0)
+++ gcc/testsuite/gcc.dg/dfp/fe-check.h	(revision 0)
@@ -0,0 +1,70 @@
+/* Common support for checking that appropriate floating point exceptions
+   are raised for decimal float operations.  These tests are here to test
+   the software decimal float support in libgcc.  */
+
+#include "dfp-except.h"
+
+extern void abort (void);
+static int failcnt = 0;
+
+/* Support compiling the test to report individual failures; default is
+   to abort as soon as a check fails.  */
+#if defined(DBG) || defined(DBG2)
+#include <stdio.h>
+#define FAILURE(NUM,KIND,EXCEPT) \
+  { printf ("failed for test %d: %s %s\n", NUM, KIND, EXCEPT); failcnt++; }
+#else
+#define FAILURE(N,K,E) abort ();
+#endif
+
+/* This is useful when modifying the test to make sure that tests are
+   actually run.  */
+#if defined(DBG2)
+#define SUCCESS(NUM,EXCEPT) \
+  { printf ("passed for test %d: %s\n", NUM, EXCEPT); }
+#else
+#define SUCCESS(N,E) ;
+#endif
+
+#define CHECKFLAG(NUM,EXCEPT,FLAGS,MASK)			\
+  if ((MASK & EXCEPT) != (FLAGS & EXCEPT))			\
+    {								\
+      if ((MASK & EXCEPT) != 0)					\
+        FAILURE (NUM, "missing", #EXCEPT)			\
+      else							\
+        FAILURE (NUM, "unexpected", #EXCEPT)			\
+    }								\
+  else								\
+    SUCCESS (NUM, #EXCEPT)
+
+void
+checkflags (int num, int mask)
+{
+  int flags = DFP_TEST_EXCEPT (FE_ALL_EXCEPT);
+  CHECKFLAG (num, FE_INVALID, flags, mask)
+  CHECKFLAG (num, FE_OVERFLOW, flags, mask)
+  CHECKFLAG (num, FE_UNDERFLOW, flags, mask)
+  CHECKFLAG (num, FE_DIVBYZERO, flags, mask)
+  CHECKFLAG (num, FE_INEXACT, flags, mask)
+}
+
+#define BINOP(NUM,OP,VAR1,VAL1,VAR2,VAL2,VAR3,EXCEPT)		\
+void								\
+binop_##NUM (void)						\
+{								\
+  VAR1 = VAL1;							\
+  VAR2 = VAL2;							\
+  DFP_CLEAR_EXCEPT (FE_ALL_EXCEPT);				\
+  VAR3 = VAR1 OP VAR2;						\
+  checkflags (NUM, EXCEPT);					\
+}
+
+#define CONVERT(NUM,FROM,TO,VALUE,EXCEPT)			\
+void								\
+convert_##NUM (void)						\
+{								\
+  FROM = VALUE;							\
+  DFP_CLEAR_EXCEPT (FE_ALL_EXCEPT);				\
+  TO = FROM;							\
+  checkflags (NUM, EXCEPT);					\
+}
Index: gcc/testsuite/gcc.dg/dfp/fe-binop.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/fe-binop.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dfp/fe-binop.c	(revision 0)
@@ -0,0 +1,107 @@
+/* { dg-options "-std=gnu99" } */
+
+/* Touch tests that check for raising appropriate exceptions for binary
+   arithmetic operations on decimal float values.  */
+
+#include "fe-check.h"
+
+volatile _Decimal32 a32, b32, c32;
+volatile _Decimal64 a64, b64, c64;
+volatile _Decimal128 a128, b128, c128;
+_Decimal32 inf32;
+_Decimal64 inf64;
+_Decimal128 inf128;
+
+BINOP (100, /, a32, 2.0df, b32, 0.df, c32, FE_DIVBYZERO)
+BINOP (101, /, a64, 2.0dd, b64, 0.dd, c64, FE_DIVBYZERO)
+BINOP (102, /, a128, 2.0dl, b128, 0.dl, c128, FE_DIVBYZERO)
+
+BINOP (200, /, a32, 0.df, b32, 0.df, c32, FE_INVALID)
+BINOP (201, /, a64, 0.dd, b64, 0.dd, c64, FE_INVALID)
+BINOP (202, /, a128, 0.dl, b128, 0.dl, c128, FE_INVALID)
+BINOP (203, /, a32, inf32, b32, inf32, c32, FE_INVALID)
+BINOP (204, /, a64, inf64, b64, inf64, c64, FE_INVALID)
+BINOP (205, /, a128, inf128, b128, inf128, c128, FE_INVALID)
+BINOP (206, *, a32, 0.df, b32, __builtin_infd32(), c32, FE_INVALID)
+BINOP (207, *, a32, __builtin_infd32(), b32, 0.df, c32, FE_INVALID)
+BINOP (208, *, a64, 0.df, b64, __builtin_infd64(), c64, FE_INVALID)
+BINOP (209, *, a64, __builtin_infd64(), b64, 0.df, c64, FE_INVALID)
+BINOP (210, *, a128, 0.df, b128, __builtin_infd128(), c128, FE_INVALID)
+BINOP (211, *, a128, __builtin_infd128(), b128, 0.df, c128, FE_INVALID)
+BINOP (212, +, a32, inf32, b32, -inf32, c32, FE_INVALID)
+BINOP (213, +, a64, inf64, b64, -inf64, c64, FE_INVALID)
+BINOP (214, +, a128, inf128, b128, -inf128, c128, FE_INVALID)
+BINOP (215, -, a32, inf32, b32, inf32, c32, FE_INVALID)
+BINOP (216, -, a64, inf64, b64, inf64, c64, FE_INVALID)
+BINOP (217, -, a128, inf128, b128, inf128, c128, FE_INVALID)
+
+BINOP (300, /, a32, 9.9e94df, b32, 1.e-3df, c32, FE_OVERFLOW|FE_INEXACT)
+BINOP (301, /, a64, 9.9e382dd, b64, 1.e-3dd, c64, FE_OVERFLOW|FE_INEXACT)
+BINOP (302, /, a128, 9.9e6142dl, b128, 1.e-3dl, c128, FE_OVERFLOW|FE_INEXACT)
+BINOP (303, +, a32, 9.9e96df, b32, 1.e96df, c32, FE_OVERFLOW|FE_INEXACT)
+BINOP (304, +, a64, 9.9e384dd, b64, 1.e384dd, c64, FE_OVERFLOW|FE_INEXACT)
+BINOP (305, +, a128, 9.9e6144dl, b128, 1.e6144dl, c128, FE_OVERFLOW|FE_INEXACT)
+
+BINOP (400, /, a32, 1.e-3df, b32, 9.9e94df, c32, FE_UNDERFLOW|FE_INEXACT)
+BINOP (401, /, a64, 1.e-3dd, b64, 9.9e382dd, c64, FE_UNDERFLOW|FE_INEXACT)
+BINOP (402, /, a128, 1.e-3dl, b128, 9.9e6142dl, c128, FE_UNDERFLOW|FE_INEXACT)
+BINOP (403, *, a32, 1.e-95df, b32, 1.e-7df, c32, FE_UNDERFLOW|FE_INEXACT)
+BINOP (404, *, a64, 1.e-383dd, b64, 1.e-16dd, c64, FE_UNDERFLOW|FE_INEXACT)
+BINOP (405, *, a128, 1.e-6143dl, b128, 1.e-34dl, c128, FE_UNDERFLOW|FE_INEXACT)
+
+BINOP (500, /, a32, 1.df, b32, 3.df, c32, FE_INEXACT)
+BINOP (501, /, a64, 1.dd, b64, 3.dd, c64, FE_INEXACT)
+BINOP (502, /, a128, 1.dl, b128, 3.dl, c128, FE_INEXACT)
+
+int
+main ()
+{
+  inf32 = __builtin_infd32();
+  inf64 = __builtin_infd64();
+  inf128 = __builtin_infd128();
+
+  binop_100 ();
+  binop_101 ();
+  binop_102 ();
+
+  binop_200 ();
+  binop_201 ();
+  binop_202 ();
+  binop_203 ();
+  binop_204 ();
+  binop_205 ();
+  binop_206 ();
+  binop_207 ();
+  binop_208 ();
+  binop_209 ();
+  binop_210 ();
+  binop_211 ();
+  binop_212 ();
+  binop_213 ();
+  binop_214 ();
+  binop_215 ();
+  binop_216 ();
+  binop_217 ();
+
+  binop_300 ();
+  binop_301 ();
+  binop_302 ();
+  binop_303 ();
+  binop_304 ();
+  binop_305 ();
+
+  binop_400 ();
+  binop_401 ();
+  binop_402 ();
+  binop_403 ();
+  binop_404 ();
+  binop_405 ();
+
+  binop_500 ();
+  binop_501 ();
+  binop_502 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/dfp/fe-convert-1.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/fe-convert-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dfp/fe-convert-1.c	(revision 0)
@@ -0,0 +1,54 @@
+/* { dg-options "-std=gnu99" } */
+
+/* Check that appropriate exceptions are raised for conversions involving
+   decimal float values.  */
+
+#include "fe-check.h"
+
+volatile _Decimal32 d32;
+volatile _Decimal64 d64;
+volatile _Decimal128 d128;
+volatile char sc;
+volatile int si;
+volatile short ss;
+volatile long sl;
+volatile long long sll;
+volatile unsigned char uc;
+volatile unsigned int ui;
+volatile unsigned short us;
+volatile unsigned long ul;
+volatile unsigned long long ull;
+_Decimal32 inf32;
+_Decimal64 inf64;
+_Decimal128 inf128;
+
+/* Conversions from decimal float to integer types should raise an
+   invalid exception if the values doesn't fit.  */
+CONVERT (100, d32, si, 1.123e10df, FE_INVALID)
+CONVERT (101, d32, ui, 1.123e10df, FE_INVALID)
+CONVERT (102, d32, si, inf32, FE_INVALID)
+CONVERT (103, d32, ui, inf32, FE_INVALID)
+
+/* Test types smaller than int using values larger than int.  */
+CONVERT (300, d32, sc, 1.123e10df, FE_INVALID)
+CONVERT (301, d32, ss, 1.123e10df, FE_INVALID)
+
+int
+main ()
+{
+  inf32 = __builtin_infd32 ();
+  inf64 = __builtin_infd64 ();
+  inf128 = __builtin_infd128 ();
+
+  convert_100 ();
+  convert_101 ();
+  convert_102 ();
+  convert_103 ();
+
+  convert_300 ();
+  convert_301 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/dfp/fe-convert-2.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/fe-convert-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dfp/fe-convert-2.c	(revision 0)
@@ -0,0 +1,38 @@
+/* { dg-options "-std=gnu99" } */
+
+/* Check that appropriate exceptions are raised for conversions involving
+   decimal float values.  */
+
+#include "fe-check.h"
+
+volatile _Decimal32 d32;
+volatile _Decimal64 d64;
+volatile _Decimal128 d128;
+volatile float f;
+volatile double d;
+
+_Decimal32 inf32;
+_Decimal64 inf64;
+_Decimal128 inf128;
+float inff;
+double infd;
+
+CONVERT (100, d, d32, 1.e100, FE_OVERFLOW|FE_INEXACT)
+CONVERT (200, d, d32, 1.e-110, FE_UNDERFLOW|FE_INEXACT)
+
+int
+main ()
+{
+  inf32 = __builtin_infd32 ();
+  inf64 = __builtin_infd64 ();
+  inf128 = __builtin_infd128 ();
+  inff = __builtin_inf ();
+  infd = __builtin_inf ();
+
+  convert_100 ();
+  convert_200 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] DFP internal support for FP exceptions
  2006-12-01 18:07 [PATCH] DFP internal support for FP exceptions Janis Johnson
@ 2006-12-01 18:14 ` Andrew Pinski
  2006-12-06 23:42   ` Ben Elliston
  2006-12-06 23:22 ` Ben Elliston
  1 sibling, 1 reply; 10+ messages in thread
From: Andrew Pinski @ 2006-12-01 18:14 UTC (permalink / raw)
  To: Janis Johnson; +Cc: gcc-patches, bje

On Fri, 2006-12-01 at 10:06 -0800, Janis Johnson wrote:
> This patch adds parameterized support to the decimal float runtime to
> detect conditions that require floating point exceptions to be raised
> and then raise them, if the appropriate support is defined.


> +  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)

Hmm, I would also use __builtin_expect here as I hope exceptions are
rare.  Right now IIRC != 0 makes this branch a 50/50 change of going
either way so it would be useful to mark this branch with
__builtin_expect.

Thanks,
Andrew Pinski



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] DFP internal support for FP exceptions
  2006-12-01 18:07 [PATCH] DFP internal support for FP exceptions Janis Johnson
  2006-12-01 18:14 ` Andrew Pinski
@ 2006-12-06 23:22 ` Ben Elliston
  2006-12-13  0:25   ` Janis Johnson
  1 sibling, 1 reply; 10+ messages in thread
From: Ben Elliston @ 2006-12-06 23:22 UTC (permalink / raw)
  To: Janis Johnson; +Cc: gcc-patches

> libdecnumber/
> 	* decExcept.c: New.
> 	* decExcept.h: New.
> 
> gcc/
> 	* config/dfp-bit.c: Add parameterized support for fp exceptions.
> 	* config/dfp-bit.h: Ditto.
> 	* mklibgcc.in: Add decExcept.h to dfp-bit.c dependencies.
> 
> gcc/testsuite/
> 	* gcc.dg/dfp/dfp-except.h: New file.
> 	* gcc.dg/dfp/fe-check.h: New file.
> 	* gcc.dg/dfp/fe-binop.c: New test.
> 	* gcc.dg/dfp/fe-convert-1.c: New test.
> 	* gcc.dg/dfp/fe-convert-2.c: New test.

OK.  Thanks for all those tests!

BTW, I don't know if you ran them, but for these kinds of changes to
the runtime, I've found it a good idea to set $DECTEST and run the
decTest testsuite, too.

Cheers, Ben

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] DFP internal support for FP exceptions
  2006-12-01 18:14 ` Andrew Pinski
@ 2006-12-06 23:42   ` Ben Elliston
  0 siblings, 0 replies; 10+ messages in thread
From: Ben Elliston @ 2006-12-06 23:42 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: Janis Johnson, gcc-patches

On Fri, Dec 01, 2006 at 10:14:07AM -0800, Andrew Pinski wrote:

> > +  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
> 
> Hmm, I would also use __builtin_expect here as I hope exceptions are
> rare.  Right now IIRC != 0 makes this branch a 50/50 change of going
> either way so it would be useful to mark this branch with
> __builtin_expect.

Ah, yes.  Please include this suggested change, Janis.

Cheers, Ben

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] DFP internal support for FP exceptions
  2006-12-06 23:22 ` Ben Elliston
@ 2006-12-13  0:25   ` Janis Johnson
  2007-01-16 20:15     ` Janis Johnson
  0 siblings, 1 reply; 10+ messages in thread
From: Janis Johnson @ 2006-12-13  0:25 UTC (permalink / raw)
  To: Ben Elliston; +Cc: Janis Johnson, gcc-patches

On Thu, Dec 07, 2006 at 10:21:52AM +1100, Ben Elliston wrote:
> > libdecnumber/
> > 	* decExcept.c: New.
> > 	* decExcept.h: New.
> >
> > gcc/
> > 	* config/dfp-bit.c: Add parameterized support for fp exceptions.
> > 	* config/dfp-bit.h: Ditto.
> > 	* mklibgcc.in: Add decExcept.h to dfp-bit.c dependencies.
> >
> > gcc/testsuite/
> > 	* gcc.dg/dfp/dfp-except.h: New file.
> > 	* gcc.dg/dfp/fe-check.h: New file.
> > 	* gcc.dg/dfp/fe-binop.c: New test.
> > 	* gcc.dg/dfp/fe-convert-1.c: New test.
> > 	* gcc.dg/dfp/fe-convert-2.c: New test.
> 
> OK.  Thanks for all those tests!

I've discovered some problems with this patch, so I'll withdraw it and
submit a better one later.

Janis

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] DFP internal support for FP exceptions
  2006-12-13  0:25   ` Janis Johnson
@ 2007-01-16 20:15     ` Janis Johnson
  2007-01-16 21:58       ` Mike Stump
  2007-01-28 22:55       ` Ben Elliston
  0 siblings, 2 replies; 10+ messages in thread
From: Janis Johnson @ 2007-01-16 20:15 UTC (permalink / raw)
  To: Janis Johnson; +Cc: Ben Elliston, gcc-patches

On Tue, Dec 12, 2006 at 04:25:41PM -0800, Janis Johnson wrote:
> On Thu, Dec 07, 2006 at 10:21:52AM +1100, Ben Elliston wrote:
> > > libdecnumber/
> > > 	* decExcept.c: New.
> > > 	* decExcept.h: New.
> > >
> > > gcc/
> > > 	* config/dfp-bit.c: Add parameterized support for fp exceptions.
> > > 	* config/dfp-bit.h: Ditto.
> > > 	* mklibgcc.in: Add decExcept.h to dfp-bit.c dependencies.
> > >
> > > gcc/testsuite/
> > > 	* gcc.dg/dfp/dfp-except.h: New file.
> > > 	* gcc.dg/dfp/fe-check.h: New file.
> > > 	* gcc.dg/dfp/fe-binop.c: New test.
> > > 	* gcc.dg/dfp/fe-convert-1.c: New test.
> > > 	* gcc.dg/dfp/fe-convert-2.c: New test.
> >
> > OK.  Thanks for all those tests!
> 
> I've discovered some problems with this patch, so I'll withdraw it and
> submit a better one later.

Here's the new one.  It omits some checks that were wrong, deals with
top-level libgcc, and beefs up the testing.

One big question: originally I put a GPL license into new files
decExcept.[ch] but this time used GPL+exception.  Is it valid to do
that after a file has been submitted but before it's been checked in?
These files are for testing purposes and will most likely be
configured out before any release, so it's not a big deal if they
have to stay GPL.

Tested on powerpc64-linux; ok for trunk?

2007-01-16  Janis Johnson  <janis187@us.ibm.com>

libdecnumber/
	* decExcept.c: New.
	* decExcept.h: New.

libgcc/
	* Makefile.in (dec-filenames): Add decExcept.

gcc/
	* config/dfp-bit.c: Add parameterized support for fp exceptions.
	* config/dfp-bit.h: Ditto.

gcc/testsuite/
	* gcc.dg/dfp/dfp-except.h: New file.
	* gcc.dg/dfp/fe-check.h: New file.
	* gcc.dg/dfp/fe-binop.c: New test.
	* gcc.dg/dfp/fe-convert-1.c: New test.
	* gcc.dg/dfp/fe-convert-2.c: New test.
	* gcc.dg/dfp/fe-convert-3.c: New test.

Index: gcc/config/dfp-bit.c
===================================================================
--- gcc/config/dfp-bit.c	(revision 120830)
+++ gcc/config/dfp-bit.c	(working copy)
@@ -88,6 +88,19 @@
   /* Perform the operation.  */
   op (&res, &arg1, &context);
 
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Division_by_zero | DEC_IEEE_854_Inexact
+		      | DEC_IEEE_854_Invalid_operation | DEC_IEEE_854_Overflow
+		      | DEC_IEEE_854_Underflow;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   TO_ENCODED (&encoded_result, &res, &context);
   IEEE_TO_HOST (encoded_result, &result);
   return result;
@@ -115,6 +128,19 @@
   /* Perform the operation.  */
   op (&res, &arg1, &arg2, &context);
 
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Division_by_zero | DEC_IEEE_854_Inexact
+		      | DEC_IEEE_854_Invalid_operation | DEC_IEEE_854_Overflow
+		      | DEC_IEEE_854_Underflow;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   TO_ENCODED (&encoded_result, &res, &context);
   IEEE_TO_HOST (encoded_result, &result);
   return result;
@@ -379,6 +405,17 @@
   TO_INTERNAL (&s_from, &d);
   TO_ENCODED_TO (&s_to, &d, &context);
 
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Inexact | DEC_IEEE_854_Invalid_operation;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   IEEE_TO_HOST_TO (s_to, &f_to);
   return f_to;
 }
@@ -394,6 +431,9 @@
   /* decNumber's decimal* types have the same format as C's _Decimal*
      types, but they have different calling conventions.  */
 
+  /* TODO: Decimal float to integer conversions should raise FE_INVALID
+     if the result value does not fit into the result type.  */
+
   IEEE_TYPE s;
   char buf[BUFMAX];
   char *pos;
@@ -444,6 +484,19 @@
   /* Convert from the floating point string to a decimal* type.  */
   FROM_STRING (&s, buf, &context);
   IEEE_TO_HOST (s, &f);
+
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Inexact | DEC_IEEE_854_Invalid_operation
+		      | DEC_IEEE_854_Overflow;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   return f;
 }
 #endif
@@ -492,6 +545,19 @@
   /* Convert from the floating point string to a decimal* type.  */
   FROM_STRING (&s, buf, &context);
   IEEE_TO_HOST (s, &f);
+
+  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
+    {
+      /* decNumber exception flags we care about here.  */
+      int ieee_flags;
+      int dec_flags = DEC_IEEE_854_Inexact | DEC_IEEE_854_Invalid_operation
+		      | DEC_IEEE_854_Overflow | DEC_IEEE_854_Underflow;
+      dec_flags &= context.status;
+      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
+      if (ieee_flags != 0)
+        DFP_HANDLE_EXCEPTIONS (ieee_flags);
+    }
+
   return f;
 }
 #endif
Index: gcc/config/dfp-bit.h
===================================================================
--- gcc/config/dfp-bit.h	(revision 120830)
+++ gcc/config/dfp-bit.h	(working copy)
@@ -32,6 +32,7 @@
 
 #include <fenv.h>
 #include <decRound.h>
+#include <decExcept.h>
 #include "tconfig.h"
 #include "coretypes.h"
 #include "tm.h"
@@ -120,6 +121,27 @@
 #define DFP_INIT_ROUNDMODE(A) A = DEC_ROUND_HALF_EVEN
 #endif
 
+#ifdef DFP_EXCEPTIONS_ENABLED
+/* Return IEEE exception flags based on decNumber status flags.  */
+#define DFP_IEEE_FLAGS(DEC_FLAGS) __extension__			\
+({int _fe_flags = 0;						\
+  if ((dec_flags & DEC_IEEE_854_Division_by_zero) != 0)		\
+    _fe_flags |= FE_DIVBYZERO;					\
+  if ((dec_flags & DEC_IEEE_854_Inexact) != 0)			\
+    _fe_flags |= FE_INEXACT;					\
+  if ((dec_flags & DEC_IEEE_854_Invalid_operation) != 0)	\
+    _fe_flags |= FE_INVALID;					\
+  if ((dec_flags & DEC_IEEE_854_Overflow) != 0)			\
+    _fe_flags |= FE_OVERFLOW;					\
+  if ((dec_flags & DEC_IEEE_854_Underflow) != 0)		\
+    _fe_flags |= FE_UNDERFLOW;					\
+  _fe_flags; })
+#else
+#define DFP_EXCEPTIONS_ENABLED 0
+#define DFP_IEEE_FLAGS(A) 0
+#define DFP_HANDLE_EXCEPTIONS(A) do {} while (0)
+#endif
+
 /* Conversions between different decimal float types use WIDTH_TO to
    determine additional macros to define.  */
 
Index: libgcc/Makefile.in
===================================================================
--- libgcc/Makefile.in	(revision 120830)
+++ libgcc/Makefile.in	(working copy)
@@ -460,7 +460,7 @@
 
 dec-filenames =
 ifneq ($(D32PBIT)$(D64PBIT)$(D128PBIT),)
-dec-filenames += decContext decNumber decRound decLibrary decUtility
+dec-filenames += decContext decNumber decExcept decRound decLibrary decUtility
 endif
 
 ifneq ($(D32PBIT),)
Index: libdecnumber/decExcept.c
===================================================================
--- libdecnumber/decExcept.c	(revision 0)
+++ libdecnumber/decExcept.c	(revision 0)
@@ -0,0 +1,59 @@
+/* Temporary library support for decimal floating point.
+   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   In addition to the permissions in the GNU General Public License, the
+   Free Software Foundation gives you unlimited permission to link the
+   compiled version of this file into combinations with other programs,
+   and to distribute those combinations without any restriction coming
+   from the use of this file.  (The General Public License restrictions
+   do apply in other respects; for example, they cover modification of
+   the file, and distribution when not linked into a combine
+   executable.)
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include <fenv.h>
+#include "config.h"
+#include "decContext.h"
+#include "decExcept.h"
+
+/* Internal, non-documented functions for testing libgcc functions.
+   This support is not sufficient for real use.  */
+
+static int __dfp_except_flags = 0;
+
+/* Clear the dummy exception flags.  */
+void
+__dfp_clear_except (void)
+{
+  __dfp_except_flags = 0;
+}
+
+/* Return the dummy exception flags corresponding to the mask.  */
+int
+__dfp_test_except (int mask)
+{
+  return __dfp_except_flags & mask;
+}
+
+/* Set dummy exception flags.  */
+void
+__dfp_raise_except (int flags)
+{
+  __dfp_except_flags |= flags;
+}
Index: libdecnumber/decExcept.h
===================================================================
--- libdecnumber/decExcept.h	(revision 0)
+++ libdecnumber/decExcept.h	(revision 0)
@@ -0,0 +1,39 @@
+/* Temporary library support for decimal floating point.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   In addition to the permissions in the GNU General Public License, the
+   Free Software Foundation gives you unlimited permission to link the
+   compiled version of this file into combinations with other programs,
+   and to distribute those combinations without any restriction coming
+   from the use of this file.  (The General Public License restrictions
+   do apply in other respects; for example, they cover modification of
+   the file, and distribution when not linked into a combine
+   executable.)
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include <fenv.h>
+#include "config.h"
+#include "decContext.h"
+
+#define DFP_EXCEPTIONS_ENABLED 1
+#define DFP_HANDLE_EXCEPTIONS(A) __dfp_raise_except(A)
+
+void __dfp_clear_except (void);
+int __dfp_test_except (int);
+void __dfp_raise_except (int);
Index: gcc/testsuite/gcc.dg/dfp/dfp-except.h
===================================================================
--- gcc/testsuite/gcc.dg/dfp/dfp-except.h	(revision 0)
+++ gcc/testsuite/gcc.dg/dfp/dfp-except.h	(revision 0)
@@ -0,0 +1,13 @@
+/* Use undocumented functions in libgcc to clear and test dummy floating
+   point exception flags.  That functionality is in libgcc just for
+   testing purposes.
+
+   If fesetexcept and feclearexcept are available, use those instead.  */
+
+/* Get names of exception flags.  */
+#include <fenv.h>
+
+extern void __dfp_clear_except (int);
+#define DFP_CLEAR_EXCEPT(M) __dfp_clear_except(M)
+extern int __dfp_test_except (int);
Index: gcc/testsuite/gcc.dg/dfp/fe-check.h
===================================================================
--- gcc/testsuite/gcc.dg/dfp/fe-check.h	(revision 0)
+++ gcc/testsuite/gcc.dg/dfp/fe-check.h	(revision 0)
@@ -0,0 +1,70 @@
+/* Common support for checking that appropriate floating point exceptions
+   are raised for decimal float operations.  These tests are here to test
+   the software decimal float support in libgcc.  */
+
+#include "dfp-except.h"
+
+extern void abort (void);
+static int failcnt = 0;
+
+/* Support compiling the test to report individual failures; default is
+   to abort as soon as a check fails.  */
+#if defined(DBG) || defined(DBG2)
+#include <stdio.h>
+#define FAILURE(NUM,KIND,EXCEPT) \
+  { printf ("failed for test %d: %s %s\n", NUM, KIND, EXCEPT); failcnt++; }
+#else
+#define FAILURE(N,K,E) abort ();
+#endif
+
+/* This is useful when modifying the test to make sure that tests are
+   actually run.  */
+#if defined(DBG2)
+#define SUCCESS(NUM,EXCEPT) \
+  { printf ("passed for test %d: %s\n", NUM, EXCEPT); }
+#else
+#define SUCCESS(N,E) ;
+#endif
+
+#define CHECKFLAG(NUM,EXCEPT,GOT,WANT)				\
+  if ((WANT & EXCEPT) != (GOT & EXCEPT))			\
+    {								\
+      if ((WANT & EXCEPT) != 0)					\
+        FAILURE (NUM, "missing", #EXCEPT)			\
+      else							\
+        FAILURE (NUM, "unexpected", #EXCEPT)			\
+    }								\
+  else								\
+    SUCCESS (NUM, #EXCEPT)
+
+void
+checkflags (int num, int want)
+{
+  int got = DFP_TEST_EXCEPT (FE_ALL_EXCEPT);
+  CHECKFLAG (num, FE_INVALID, got, want)
+  CHECKFLAG (num, FE_OVERFLOW, got, want)
+  CHECKFLAG (num, FE_UNDERFLOW, got, want)
+  CHECKFLAG (num, FE_DIVBYZERO, got, want)
+  CHECKFLAG (num, FE_INEXACT, got, want)
+}
+
+#define BINOP(NUM,OP,VAR1,VAL1,VAR2,VAL2,VAR3,EXCEPT)		\
+void								\
+binop_##NUM (void)						\
+{								\
+  VAR1 = VAL1;							\
+  VAR2 = VAL2;							\
+  DFP_CLEAR_EXCEPT (FE_ALL_EXCEPT);				\
+  VAR3 = VAR1 OP VAR2;						\
+  checkflags (NUM, EXCEPT);					\
+}
+
+#define CONVERT(NUM,FROM,TO,VALUE,EXCEPT)			\
+void								\
+convert_##NUM (void)						\
+{								\
+  FROM = VALUE;							\
+  DFP_CLEAR_EXCEPT (FE_ALL_EXCEPT);				\
+  TO = FROM;							\
+  checkflags (NUM, EXCEPT);					\
+}
+#define DFP_TEST_EXCEPT(M) __dfp_test_except(M)
Index: gcc/testsuite/gcc.dg/dfp/fe-binop.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/fe-binop.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dfp/fe-binop.c	(revision 0)
@@ -0,0 +1,107 @@
+/* { dg-options "-std=gnu99" } */
+
+/* Touch tests that check for raising appropriate exceptions for binary
+   arithmetic operations on decimal float values.  */
+
+#include "fe-check.h"
+
+volatile _Decimal32 a32, b32, c32;
+volatile _Decimal64 a64, b64, c64;
+volatile _Decimal128 a128, b128, c128;
+_Decimal32 inf32;
+_Decimal64 inf64;
+_Decimal128 inf128;
+
+BINOP (100, /, a32, 2.0df, b32, 0.df, c32, FE_DIVBYZERO)
+BINOP (101, /, a64, 2.0dd, b64, 0.dd, c64, FE_DIVBYZERO)
+BINOP (102, /, a128, 2.0dl, b128, 0.dl, c128, FE_DIVBYZERO)
+
+BINOP (200, /, a32, 0.df, b32, 0.df, c32, FE_INVALID)
+BINOP (201, /, a64, 0.dd, b64, 0.dd, c64, FE_INVALID)
+BINOP (202, /, a128, 0.dl, b128, 0.dl, c128, FE_INVALID)
+BINOP (203, /, a32, inf32, b32, inf32, c32, FE_INVALID)
+BINOP (204, /, a64, inf64, b64, inf64, c64, FE_INVALID)
+BINOP (205, /, a128, inf128, b128, inf128, c128, FE_INVALID)
+BINOP (206, *, a32, 0.df, b32, __builtin_infd32(), c32, FE_INVALID)
+BINOP (207, *, a32, __builtin_infd32(), b32, 0.df, c32, FE_INVALID)
+BINOP (208, *, a64, 0.df, b64, __builtin_infd64(), c64, FE_INVALID)
+BINOP (209, *, a64, __builtin_infd64(), b64, 0.df, c64, FE_INVALID)
+BINOP (210, *, a128, 0.df, b128, __builtin_infd128(), c128, FE_INVALID)
+BINOP (211, *, a128, __builtin_infd128(), b128, 0.df, c128, FE_INVALID)
+BINOP (212, +, a32, inf32, b32, -inf32, c32, FE_INVALID)
+BINOP (213, +, a64, inf64, b64, -inf64, c64, FE_INVALID)
+BINOP (214, +, a128, inf128, b128, -inf128, c128, FE_INVALID)
+BINOP (215, -, a32, inf32, b32, inf32, c32, FE_INVALID)
+BINOP (216, -, a64, inf64, b64, inf64, c64, FE_INVALID)
+BINOP (217, -, a128, inf128, b128, inf128, c128, FE_INVALID)
+
+BINOP (300, /, a32, 9.9e94df, b32, 1.e-3df, c32, FE_OVERFLOW|FE_INEXACT)
+BINOP (301, /, a64, 9.9e382dd, b64, 1.e-3dd, c64, FE_OVERFLOW|FE_INEXACT)
+BINOP (302, /, a128, 9.9e6142dl, b128, 1.e-3dl, c128, FE_OVERFLOW|FE_INEXACT)
+BINOP (303, +, a32, 9.9e96df, b32, 1.e96df, c32, FE_OVERFLOW|FE_INEXACT)
+BINOP (304, +, a64, 9.9e384dd, b64, 1.e384dd, c64, FE_OVERFLOW|FE_INEXACT)
+BINOP (305, +, a128, 9.9e6144dl, b128, 1.e6144dl, c128, FE_OVERFLOW|FE_INEXACT)
+
+BINOP (400, /, a32, 1.e-3df, b32, 9.9e94df, c32, FE_UNDERFLOW|FE_INEXACT)
+BINOP (401, /, a64, 1.e-3dd, b64, 9.9e382dd, c64, FE_UNDERFLOW|FE_INEXACT)
+BINOP (402, /, a128, 1.e-3dl, b128, 9.9e6142dl, c128, FE_UNDERFLOW|FE_INEXACT)
+BINOP (403, *, a32, 1.e-95df, b32, 1.e-7df, c32, FE_UNDERFLOW|FE_INEXACT)
+BINOP (404, *, a64, 1.e-383dd, b64, 1.e-16dd, c64, FE_UNDERFLOW|FE_INEXACT)
+BINOP (405, *, a128, 1.e-6143dl, b128, 1.e-34dl, c128, FE_UNDERFLOW|FE_INEXACT)
+
+BINOP (500, /, a32, 1.df, b32, 3.df, c32, FE_INEXACT)
+BINOP (501, /, a64, 1.dd, b64, 3.dd, c64, FE_INEXACT)
+BINOP (502, /, a128, 1.dl, b128, 3.dl, c128, FE_INEXACT)
+
+int
+main ()
+{
+  inf32 = __builtin_infd32();
+  inf64 = __builtin_infd64();
+  inf128 = __builtin_infd128();
+
+  binop_100 ();
+  binop_101 ();
+  binop_102 ();
+
+  binop_200 ();
+  binop_201 ();
+  binop_202 ();
+  binop_203 ();
+  binop_204 ();
+  binop_205 ();
+  binop_206 ();
+  binop_207 ();
+  binop_208 ();
+  binop_209 ();
+  binop_210 ();
+  binop_211 ();
+  binop_212 ();
+  binop_213 ();
+  binop_214 ();
+  binop_215 ();
+  binop_216 ();
+  binop_217 ();
+
+  binop_300 ();
+  binop_301 ();
+  binop_302 ();
+  binop_303 ();
+  binop_304 ();
+  binop_305 ();
+
+  binop_400 ();
+  binop_401 ();
+  binop_402 ();
+  binop_403 ();
+  binop_404 ();
+  binop_405 ();
+
+  binop_500 ();
+  binop_501 ();
+  binop_502 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/dfp/fe-convert-1.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/fe-convert-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dfp/fe-convert-1.c	(revision 0)
@@ -0,0 +1,42 @@
+/* { dg-options "-std=gnu99" } */
+
+/* Check that appropriate exceptions are raised for conversions involving
+   decimal float values.  */
+
+#include "fe-check.h"
+
+volatile _Decimal32 d32;
+volatile _Decimal64 d64;
+volatile _Decimal128 d128;
+
+/* Conversions between decimal float types should raise an invalid
+   exception if the values doesn't fit, either because the value
+   is too large or the result can't hold the full precision.  */
+
+CONVERT (100, d64, d32, 9.999999e96DD, 0)
+CONVERT (101, d64, d32, 10.000000e96DD, FE_INEXACT)
+CONVERT (102, d64, d32, 1.1111111DD, FE_INEXACT)
+CONVERT (110, d128, d32, 9.999999e96DL, 0)
+CONVERT (111, d128, d32, 10.000000e96DL, FE_INEXACT)
+CONVERT (112, d128, d32, 1.1111111DL, FE_INEXACT)
+CONVERT (120, d128, d64, 9.999999999999999E384DL, 0)
+CONVERT (121, d128, d64, 10.00000000000000E384DL, FE_INEXACT)
+CONVERT (122, d128, d64, 1.1111111111111111DL, FE_INEXACT)
+
+int
+main ()
+{
+  convert_100 ();
+  convert_101 ();
+  convert_102 ();
+  convert_110 ();
+  convert_111 ();
+  convert_112 ();
+  convert_120 ();
+  convert_121 ();
+  convert_122 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/dfp/fe-convert-2.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/fe-convert-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dfp/fe-convert-2.c	(revision 0)
@@ -0,0 +1,34 @@
+/* { dg-options "-std=gnu99" } */
+
+/* Check that appropriate exceptions are raised for BFP to DFP conversions.
+   The test only uses double and _Decimal32; tests for conversions to
+   _Decimal64 would need 128-bit long double.  */
+
+#include "fe-check.h"
+
+volatile _Decimal32 d32;
+volatile double d;
+
+CONVERT (100, d, d32, 1.0e96, 0)
+CONVERT (101, d, d32, 1.0e97, FE_OVERFLOW|FE_INEXACT) 
+CONVERT (102, d, d32, -1.0e96, 0)
+CONVERT (103, d, d32, -1.0e97, FE_OVERFLOW|FE_INEXACT) 
+
+#if 0
+/* These should result in fp exceptions but don't.  */
+CONVERT (xxx, d, d32, 1.0e-96, FE_UNDERFLOW|FE_INEXACT)
+CONVERT (xxx, d, d32, 0.00048828125, FE_INEXACT)  /* exact power of 2 */
+#endif
+
+int
+main ()
+{
+  convert_100 ();
+  convert_101 ();
+  convert_102 ();
+  convert_103 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/dfp/fe-convert-3.c
===================================================================
--- gcc/testsuite/gcc.dg/dfp/fe-convert-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/dfp/fe-convert-3.c	(revision 0)
@@ -0,0 +1,49 @@
+/* { dg-options "-std=gnu99" } */
+
+/* Check that appropriate exceptions are raised for int to DFP conversions.  */
+
+#include "fe-check.h"
+
+volatile _Decimal32 d32;
+volatile _Decimal64 d64;
+volatile signed int si;
+volatile unsigned int ui;
+volatile signed long long sll;
+volatile unsigned long long ull;
+
+CONVERT (100, si, d32, 9999999, 0)
+CONVERT (101, si, d32, 11111111, FE_INEXACT)
+CONVERT (102, si, d32, -9999999, 0)
+CONVERT (103, si, d32, -10000001, FE_INEXACT)
+CONVERT (110, ui, d32, 9999999, 0)
+CONVERT (111, ui, d32, 10000001, FE_INEXACT)
+CONVERT (200, sll, d64, 9999999999999999, 0)
+CONVERT (201, sll, d64, 10000000000000001, FE_INEXACT)
+CONVERT (202, sll, d64, -9999999999999999, 0)
+CONVERT (203, sll, d64, -10000000000000001, FE_INEXACT)
+CONVERT (210, ull, d64, 9999999999999999, 0)
+CONVERT (211, ull, d64, 10000000000000001, FE_INEXACT)
+
+int
+main ()
+{
+  if (sizeof (long long) != 16)
+    return 0;
+
+  convert_100 ();
+  convert_101 ();
+  convert_102 ();
+  convert_103 ();
+  convert_110 ();
+  convert_111 ();
+  convert_200 ();
+  convert_201 ();
+  convert_202 ();
+  convert_203 ();
+  convert_210 ();
+  convert_211 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] DFP internal support for FP exceptions
  2007-01-16 20:15     ` Janis Johnson
@ 2007-01-16 21:58       ` Mike Stump
  2007-01-16 22:19         ` Janis Johnson
  2007-01-28 22:55       ` Ben Elliston
  1 sibling, 1 reply; 10+ messages in thread
From: Mike Stump @ 2007-01-16 21:58 UTC (permalink / raw)
  To: Janis Johnson; +Cc: Ben Elliston, gcc-patches

On Jan 16, 2007, at 12:15 PM, Janis Johnson wrote:
> One big question: originally I put a GPL license into new files
> decExcept.[ch] but this time used GPL+exception.  Is it valid to do
> that after a file has been submitted but before it's been checked in?

If you own the file, you can submit it for consideration with the GPL 
+exception license.  If others might have any ownership say in it,  
you'd have to get the approval of all authors.  So, if you stole GPL  
code from glibc, you'd need the FSF to sign off on the change.  If  
you worked on it with RedHat, you'd need RedHat to sign off.  If  
someone contributed substantial (anything for which a copyright claim  
might be reasonable) bits, you need them to approve the change.

I'm hoping that no runtime approver would approve the wrong license  
going into the runtime libraries as once that is done, and checked in  
and other people contribute to it, then we most likely have to ask  
rms to change the license.  Better all the way around to get it right  
the first time.  If ever in doubt, don't check it in, ask the SC for  
guidance.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] DFP internal support for FP exceptions
  2007-01-16 21:58       ` Mike Stump
@ 2007-01-16 22:19         ` Janis Johnson
  2007-01-16 23:39           ` Mike Stump
  0 siblings, 1 reply; 10+ messages in thread
From: Janis Johnson @ 2007-01-16 22:19 UTC (permalink / raw)
  To: Mike Stump; +Cc: Janis Johnson, Ben Elliston, gcc-patches

On Tue, Jan 16, 2007 at 01:58:33PM -0800, Mike Stump wrote:
> On Jan 16, 2007, at 12:15 PM, Janis Johnson wrote:
> >One big question: originally I put a GPL license into new files
> >decExcept.[ch] but this time used GPL+exception.  Is it valid to do
> >that after a file has been submitted but before it's been checked in?
> 
> If you own the file, you can submit it for consideration with the GPL
> +exception license.  If others might have any ownership say in it,
> you'd have to get the approval of all authors.  So, if you stole GPL
> code from glibc, you'd need the FSF to sign off on the change.  If
> you worked on it with RedHat, you'd need RedHat to sign off.  If
> someone contributed substantial (anything for which a copyright claim
> might be reasonable) bits, you need them to approve the change.

In this case the files were written only by me.  They've never been
checked in anywhere, but had the wrong license in the original patch
submission.
 
> I'm hoping that no runtime approver would approve the wrong license
> going into the runtime libraries as once that is done, and checked in
> and other people contribute to it, then we most likely have to ask
> rms to change the license.  Better all the way around to get it right
> the first time.  If ever in doubt, don't check it in, ask the SC for
> guidance.

Unfortunately I'm very much aware of that; see PR 28002 (decNumber
sources need GPL+exception for use in libgcc).

Janis

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] DFP internal support for FP exceptions
  2007-01-16 22:19         ` Janis Johnson
@ 2007-01-16 23:39           ` Mike Stump
  0 siblings, 0 replies; 10+ messages in thread
From: Mike Stump @ 2007-01-16 23:39 UTC (permalink / raw)
  To: Janis Johnson; +Cc: Ben Elliston, gcc-patches

On Jan 16, 2007, at 2:19 PM, Janis Johnson wrote:
> In this case the files were written only by me.

Sounds good then.  Now, just on to review...

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] DFP internal support for FP exceptions
  2007-01-16 20:15     ` Janis Johnson
  2007-01-16 21:58       ` Mike Stump
@ 2007-01-28 22:55       ` Ben Elliston
  1 sibling, 0 replies; 10+ messages in thread
From: Ben Elliston @ 2007-01-28 22:55 UTC (permalink / raw)
  To: Janis Johnson; +Cc: gcc-patches

On Tue, 2007-01-16 at 12:15 -0800, Janis Johnson wrote:

> libdecnumber/
> 	* decExcept.c: New.
> 	* decExcept.h: New.
> 
> libgcc/
> 	* Makefile.in (dec-filenames): Add decExcept.
> 
> gcc/
> 	* config/dfp-bit.c: Add parameterized support for fp exceptions.
> 	* config/dfp-bit.h: Ditto.
> 
> gcc/testsuite/
> 	* gcc.dg/dfp/dfp-except.h: New file.
> 	* gcc.dg/dfp/fe-check.h: New file.
> 	* gcc.dg/dfp/fe-binop.c: New test.
> 	* gcc.dg/dfp/fe-convert-1.c: New test.
> 	* gcc.dg/dfp/fe-convert-2.c: New test.
> 	* gcc.dg/dfp/fe-convert-3.c: New test.

OK.

Thanks,
Ben

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-01-28 22:55 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-12-01 18:07 [PATCH] DFP internal support for FP exceptions Janis Johnson
2006-12-01 18:14 ` Andrew Pinski
2006-12-06 23:42   ` Ben Elliston
2006-12-06 23:22 ` Ben Elliston
2006-12-13  0:25   ` Janis Johnson
2007-01-16 20:15     ` Janis Johnson
2007-01-16 21:58       ` Mike Stump
2007-01-16 22:19         ` Janis Johnson
2007-01-16 23:39           ` Mike Stump
2007-01-28 22:55       ` Ben Elliston

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).