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]

[PATCH] DFP internal support for FP exceptions


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;
+}


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