OSDN Git Service

gcc/
authorjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Sep 2007 01:11:16 +0000 (01:11 +0000)
committerjanis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Sep 2007 01:11:16 +0000 (01:11 +0000)
PR c/30013
* config/dfp-bit.c: Don't skip TFmode conversions; move strto*
declarations to top.
(DFP_TO_BFP): Use for either XFmode or TFmode.
(BFP_TO_DFP): Use for either XFmode or TFmode; always use cast
of BFP_VIA_TYPE.
* config/dfp-bit.h: Include float.h.
(LONG_DOUBLE_HAS_XF_MODE, LONG_DOUBLE_HAS_TF_MODE): Define if long
double is one of these modes, rather than using LIBGCC_HAS_*F_MODE
which doesn't mean the same thing.
(BFP_KIND): Use 4 to mean TFmode.
(BFP_FMT): Specify the number of decimal digits based on the
number of mantissa digits.
(BFP_VIA_TYPE): Binary float type to use as cast for sprintf.
(BFP_TO_DFP, DFP_TO_BFP): Define names for TFmode variants.
(STR_TO_BFP): Use strtold for XFmode or TFmode.
(TFtype): Define if TFmode is supported.
* doc/libgcc.texi (Decimal float library routines): Document
TF conversion functions.

gcc/testsuite/
* gcc.dg/dfp/convert-bfp.c: Replace SKIP_LONG_DOUBLE with runtime
checks for size of long double.
* gcc.dg/dfp/convert.h: New file.
* gcc.dg/dfp/convert-bfp-2.c: New test.
* gcc.dg/dfp/convert-bfp-3.c: Ditto.
* gcc.dg/dfp/convert-bfp-4.c: Ditto.
* gcc.dg/dfp/convert-bfp-5.c: Ditto.
* gcc.dg/dfp/convert-bfp-6.c: Ditto.
* gcc.dg/dfp/convert-bfp-7.c: Ditto.
* gcc.dg/dfp/convert-bfp-8.c: Ditto.
* gcc.dg/dfp/convert-bfp-9.c: Ditto.
* gcc.dg/dfp/convert-bfp-10.c: Ditto.
* gcc.dg/dfp/convert-bfp-11.c: Ditto.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128361 138bc75d-0d04-0410-961f-82ee72b054a4

17 files changed:
gcc/ChangeLog
gcc/config/dfp-bit.c
gcc/config/dfp-bit.h
gcc/doc/libgcc.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/dfp/convert-bfp-10.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/convert-bfp-11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/convert-bfp-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/convert-bfp-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/convert-bfp-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/convert-bfp-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/convert-bfp-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/convert-bfp-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/convert-bfp-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/convert-bfp-9.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/convert-bfp.c
gcc/testsuite/gcc.dg/dfp/convert.h [new file with mode: 0644]

index 223e8fe..2ed812c 100644 (file)
@@ -1,3 +1,25 @@
+2007-09-10  Janis Johnson  <janis187@us.ibm.com>
+
+       PR c/30013
+       * config/dfp-bit.c: Don't skip TFmode conversions; move strto*
+       declarations to top.
+       (DFP_TO_BFP): Use for either XFmode or TFmode.
+       (BFP_TO_DFP): Use for either XFmode or TFmode; always use cast
+       of BFP_VIA_TYPE.
+       * config/dfp-bit.h: Include float.h.
+       (LONG_DOUBLE_HAS_XF_MODE, LONG_DOUBLE_HAS_TF_MODE): Define if long
+       double is one of these modes, rather than using LIBGCC_HAS_*F_MODE
+       which doesn't mean the same thing.
+       (BFP_KIND): Use 4 to mean TFmode.
+       (BFP_FMT): Specify the number of decimal digits based on the
+       number of mantissa digits.
+       (BFP_VIA_TYPE): Binary float type to use as cast for sprintf.
+       (BFP_TO_DFP, DFP_TO_BFP): Define names for TFmode variants.
+       (STR_TO_BFP): Use strtold for XFmode or TFmode.
+       (TFtype): Define if TFmode is supported.
+       * doc/libgcc.texi (Decimal float library routines): Document
+       TF conversion functions.
+
 2007-09-10  Chao-ying Fu  <fu@mips.com>
 
        * config/mips/mips.c (mips_scalar_mode_supported_p): Declare.
index 6a1bc30..8ee4dec 100644 (file)
@@ -34,16 +34,11 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 
    Contributed by Ben Elliston  <bje@au.ibm.com>.  */
 
-/* The intended way to use this file is to make two copies, add `#define '
-   to one copy, then compile both copies and add them to libgcc.a.  */
-
-/* FIXME: This implementation doesn't support TFmode conversions.  */
-#if !(defined (L_sd_to_tf) || defined (L_dd_to_tf) \
-      || defined (L_td_to_tf) || defined (L_tf_to_sd) \
-      || defined (L_tf_to_dd) || defined (L_tf_to_td))
-
 #include <stdio.h>
 #include <stdlib.h>
+/* FIXME: compile with -std=gnu99 to get these from stdlib.h */
+extern float strtof (const char *, char **);
+extern long double strtold (const char *, char **);
 #include <string.h>
 #include <limits.h>
 
@@ -471,7 +466,9 @@ INT_TO_DFP (INT_TYPE i)
 #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \
  || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \
  || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \
-     && LIBGCC2_HAS_XF_MODE)
+     && LONG_DOUBLE_HAS_XF_MODE) \
+ || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \
+     && LONG_DOUBLE_HAS_TF_MODE)
 BFP_TYPE
 DFP_TO_BFP (DFP_C_TYPE f)
 {
@@ -489,7 +486,9 @@ DFP_TO_BFP (DFP_C_TYPE f)
 #if defined (L_sf_to_sd) || defined (L_sf_to_dd) || defined (L_sf_to_td) \
  || defined (L_df_to_sd) || defined (L_df_to_dd) || defined (L_df_to_td) \
  || ((defined (L_xf_to_sd) || defined (L_xf_to_dd) || defined (L_xf_to_td)) \
-     && LIBGCC2_HAS_XF_MODE)
+     && LONG_DOUBLE_HAS_XF_MODE) \
+ || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \
+     && LONG_DOUBLE_HAS_TF_MODE)
 DFP_C_TYPE
 BFP_TO_DFP (BFP_TYPE x)
 {
@@ -502,12 +501,7 @@ BFP_TO_DFP (BFP_TYPE x)
   DFP_INIT_ROUNDMODE (context.round);
 
   /* Use a C library function to write the floating point value to a string.  */
-#ifdef BFP_VIA_TYPE
-  /* FIXME: Is there a better way to output an XFmode variable in C?  */
   sprintf (buf, BFP_FMT, (BFP_VIA_TYPE) x);
-#else
-  sprintf (buf, BFP_FMT, x);
-#endif
 
   /* Convert from the floating point string to a decimal* type.  */
   FROM_STRING (&s, buf, &context);
@@ -543,7 +537,3 @@ DFP_UNORD (DFP_C_TYPE arg_a, DFP_C_TYPE arg_b)
   return (decNumberIsNaN (&arg1) || decNumberIsNaN (&arg2));
 }
 #endif /* L_unord_sd || L_unord_dd || L_unord_td */
-
-/* !(L_sd_to_tf || L_dd_to_tf || L_td_to_tf \
-     || L_tf_to_sd || L_tf_to_dd || L_tf_to_td)  */
-#endif
index 7c47387..27c6a8a 100644 (file)
@@ -30,6 +30,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #ifndef _DFPBIT_H
 #define _DFPBIT_H
 
+#include <float.h>
 #include <fenv.h>
 #include <decRound.h>
 #include <decExcept.h>
@@ -49,10 +50,15 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
 #endif
 
-#ifndef LIBGCC2_HAS_XF_MODE
-#define LIBGCC2_HAS_XF_MODE \
+/* We need to know the size of long double that the C library supports.
+   Don't use LIBGCC2_HAS_XF_MODE or LIBGCC2_HAS_TF_MODE here because
+   some targets set both of those.  */
+
+#define LONG_DOUBLE_HAS_XF_MODE \
   (BITS_PER_UNIT == 8 && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 80)
-#endif
+
+#define LONG_DOUBLE_HAS_TF_MODE \
+  (BITS_PER_UNIT == 8 && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
 
 /* Depending on WIDTH, define a number of macros:
 
@@ -242,6 +248,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #elif defined (L_sd_to_xf) || defined (L_dd_to_xf ) || defined (L_td_to_xf) \
  ||   defined (L_xf_to_sd) || defined (L_xf_to_dd) || defined (L_xf_to_td)
 #define BFP_KIND 3
+#elif defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf) \
+ ||   defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)
+#define BFP_KIND 4
 #endif
 
 /*  If BFP_KIND is defined, define additional macros:
@@ -249,29 +258,48 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
     BFP_TYPE: The binary floating point data type.
 
     BFP_FMT: The format string for writing the value to a string.
+    The number of decimal digits printed is
+       ceil (nbits / log2 (10.) + 1)
+    as described in David Matula's CACM 19(3) 716-723 June 1968 paper.
 
+    BFP_VIA_TYPE: Type to which to cast a variable of BPF_TYPE for a
+    call to sprintf.
+    
     STR_TO_BFP: The function to read the value from a string.  */
 
 #if BFP_KIND == 1
-/* strtof is declared in <stdlib.h> only for C99.  */
-extern float strtof (const char *, char **);
 #define BFP_TYPE SFtype
-#define BFP_FMT "%e"
+#define BFP_FMT "%.9e"
+#define BFP_VIA_TYPE double
 #define STR_TO_BFP strtof
 
 #elif BFP_KIND == 2
 #define BFP_TYPE DFtype
-#define BFP_FMT "%e"
+#define BFP_FMT "%.17e"
+#define BFP_VIA_TYPE double
 #define STR_TO_BFP strtod
 
 #elif BFP_KIND == 3
-#if LIBGCC2_HAS_XF_MODE
-/* These aren't used if XF mode is not supported.  */
+#if LONG_DOUBLE_HAS_XF_MODE
 #define BFP_TYPE XFtype
-#define BFP_FMT "%e"
-#define BFP_VIA_TYPE double
-#define STR_TO_BFP strtod
-#endif
+#define BFP_FMT "%.21Le"
+#define BFP_VIA_TYPE long double
+#define STR_TO_BFP strtold
+#endif /* LONG_DOUBLE_HAS_XF_MODE */
+
+#elif BFP_KIND == 4
+#if LONG_DOUBLE_HAS_TF_MODE
+#define BFP_TYPE TFtype
+#if LDBL_MANT_DIG == 106
+#define BFP_FMT "%.33Le"
+#elif LDBL_MANT_DIG == 113
+#define BFP_FMT "%.36Le"
+#else
+#error "unknown long double size, cannot define BFP_FMT"
+#endif /* LDBL_MANT_DIG */
+#define STR_TO_BFP strtold
+#define BFP_VIA_TYPE long double
+#endif /* LONG_DOUBLE_HAS_TF_MODE */
 
 #endif /* BFP_KIND */
 
@@ -455,6 +483,9 @@ extern float strtof (const char *, char **);
 #elif BFP_KIND == 3
 #define BFP_TO_DFP     DPD_BID_NAME(__dpd_truncxfsd,__bid_truncxfsd)
 #define DFP_TO_BFP     DPD_BID_NAME(__dpd_extendsdxf,__bid_extendsdxf)
+#elif BFP_KIND == 4
+#define BFP_TO_DFP     DPD_BID_NAME(__dpd_trunctfsd,__bid_trunctfsd)
+#define DFP_TO_BFP     DPD_BID_NAME(__dpd_extendsdtf,__bid_extendsdtf)
 #endif /* BFP_KIND */
 
 #elif WIDTH == 64
@@ -467,6 +498,9 @@ extern float strtof (const char *, char **);
 #elif BFP_KIND == 3
 #define BFP_TO_DFP     DPD_BID_NAME(__dpd_truncxfdd,__bid_truncxfdd)
 #define DFP_TO_BFP     DPD_BID_NAME(__dpd_extendddxf,__bid_extendddxf)
+#elif BFP_KIND == 4
+#define BFP_TO_DFP     DPD_BID_NAME(__dpd_trunctfdd,__bid_trunctfdd)
+#define DFP_TO_BFP     DPD_BID_NAME(__dpd_extendddtf,__bid_extendddtf)
 #endif /* BFP_KIND */
 
 #elif WIDTH == 128
@@ -479,6 +513,9 @@ extern float strtof (const char *, char **);
 #elif BFP_KIND == 3
 #define BFP_TO_DFP     DPD_BID_NAME(__dpd_extendxftd,__bid_extendxftd)
 #define DFP_TO_BFP     DPD_BID_NAME(__dpd_trunctdxf,__bid_trunctdxf)
+#elif BFP_KIND == 4
+#define BFP_TO_DFP     DPD_BID_NAME(__dpd_extendtftd,__bid_extendtftd)
+#define DFP_TO_BFP     DPD_BID_NAME(__dpd_trunctdtf,__bid_trunctdtf)
 #endif /* BFP_KIND */
 
 #endif /* WIDTH */
@@ -487,9 +524,12 @@ extern float strtof (const char *, char **);
 
 typedef float SFtype __attribute__ ((mode (SF)));
 typedef float DFtype __attribute__ ((mode (DF)));
-#if LIBGCC2_HAS_XF_MODE
+#if LONG_DOUBLE_HAS_XF_MODE
 typedef float XFtype __attribute__ ((mode (XF)));
-#endif /* LIBGCC2_HAS_XF_MODE */
+#endif /* LONG_DOUBLE_HAS_XF_MODE */
+#if LONG_DOUBLE_HAS_TF_MODE
+typedef float TFtype __attribute__ ((mode (TF)));
+#endif /* LONG_DOUBLE_HAS_TF_MODE */
 
 typedef int SItype __attribute__ ((mode (SI)));
 typedef int DItype __attribute__ ((mode (DI)));
@@ -566,14 +606,18 @@ extern DFP_C_TYPE INT_TO_DFP (INT_TYPE);
 #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \
  || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \
  || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \
-     && LIBGCC2_HAS_XF_MODE)
+     && LONG_DOUBLE_HAS_XF_MODE) \
+ || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \
+     && LONG_DOUBLE_HAS_TF_MODE)
 extern BFP_TYPE DFP_TO_BFP (DFP_C_TYPE);
 #endif
 
 #if defined (L_sf_to_sd) || defined (L_sf_to_dd) || defined (L_sf_to_td) \
  || defined (L_df_to_sd) || defined (L_df_to_dd) || defined (L_df_to_td) \
  || ((defined (L_xf_to_sd) || defined (L_xf_to_dd) || defined (L_xf_to_td)) \
-     && LIBGCC2_HAS_XF_MODE)
+     && LONG_DOUBLE_HAS_XF_MODE) \
+ || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \
+     && LONG_DOUBLE_HAS_TF_MODE)
 extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE);
 #endif
 
index 161cfc6..e977b24 100644 (file)
@@ -585,8 +585,12 @@ to another.
 @deftypefnx {Runtime Function} _Decimal32 __bid_truncdfsd (double @var{a})
 @deftypefnx {Runtime Function} _Decimal32 __dpd_truncxfsd ({long double} @var{a})
 @deftypefnx {Runtime Function} _Decimal32 __bid_truncxfsd ({long double} @var{a})
+@deftypefnx {Runtime Function} _Decimal32 __dpd_trunctfsd ({long double} @var{a})
+@deftypefnx {Runtime Function} _Decimal32 __bid_trunctfsd ({long double} @var{a})
 @deftypefnx {Runtime Function} _Decimal64 __dpd_truncxfdd ({long double} @var{a})
 @deftypefnx {Runtime Function} _Decimal64 __bid_truncxfdd ({long double} @var{a})
+@deftypefnx {Runtime Function} _Decimal64 __dpd_trunctfdd ({long double} @var{a})
+@deftypefnx {Runtime Function} _Decimal64 __bid_trunctfdd ({long double} @var{a})
 These functions convert the value of @var{a} from a binary floating type
 to a decimal floating type of a different size.
 @end deftypefn
@@ -605,6 +609,10 @@ to a decimal floating type of a different size.
 @deftypefnx {Runtime Function} {long double} __bid_extendddxf (_Decimal64 @var{a})
 @deftypefnx {Runtime Function} {long double} __dpd_trunctdxf (_Decimal128 @var{a})
 @deftypefnx {Runtime Function} {long double} __bid_trunctdxf (_Decimal128 @var{a})
+@deftypefnx {Runtime Function} {long double} __dpd_extendsdtf (_Decimal32 @var{a})
+@deftypefnx {Runtime Function} {long double} __bid_extendsdtf (_Decimal32 @var{a})
+@deftypefnx {Runtime Function} {long double} __dpd_extendddtf (_Decimal64 @var{a})
+@deftypefnx {Runtime Function} {long double} __bid_extendddtf (_Decimal64 @var{a})
 These functions convert the value of @var{a} from a decimal floating type
 to a binary floating type of a different size.
 @end deftypefn
@@ -613,10 +621,14 @@ to a binary floating type of a different size.
 @deftypefnx {Runtime Function} _Decimal32 __bid_extendsfsd (float @var{a})
 @deftypefnx {Runtime Function} _Decimal64 __dpd_extenddfdd (double @var{a})
 @deftypefnx {Runtime Function} _Decimal64 __bid_extenddfdd (double @var{a})
+@deftypefnx {Runtime Function} _Decimal128 __dpd_extendtftd ({long double} @var{a})
+@deftypefnx {Runtime Function} _Decimal128 __bid_extendtftd ({long double} @var{a})
 @deftypefnx {Runtime Function} float __dpd_truncsdsf (_Decimal32 @var{a})
 @deftypefnx {Runtime Function} float __bid_truncsdsf (_Decimal32 @var{a})
 @deftypefnx {Runtime Function} double __dpd_truncdddf (_Decimal64 @var{a})
 @deftypefnx {Runtime Function} double __bid_truncdddf (_Decimal64 @var{a})
+@deftypefnx {Runtime Function} {long double} __dpd_trunctdtf (_Decimal128 @var{a})
+@deftypefnx {Runtime Function} {long double} __bid_trunctdtf (_Decimal128 @var{a})
 These functions convert the value of @var{a} between decimal and
 binary floating types of the same size.
 @end deftypefn
index aca1433..bce206e 100644 (file)
@@ -1,3 +1,18 @@
+2007-09-10  Janis Johnson  <janis187@us.ibm.com>
+
+       * gcc.dg/dfp/convert-bfp.c: Replace SKIP_LONG_DOUBLE with runtime
+       checks for size of long double.
+       * gcc.dg/dfp/convert.h: New file.
+       * gcc.dg/dfp/convert-bfp-2.c: New test.
+       * gcc.dg/dfp/convert-bfp-3.c: Ditto.
+       * gcc.dg/dfp/convert-bfp-4.c: Ditto.
+       * gcc.dg/dfp/convert-bfp-5.c: Ditto.
+       * gcc.dg/dfp/convert-bfp-6.c: Ditto.
+       * gcc.dg/dfp/convert-bfp-7.c: Ditto.
+       * gcc.dg/dfp/convert-bfp-8.c: Ditto.
+       * gcc.dg/dfp/convert-bfp-9.c: Ditto.
+       * gcc.dg/dfp/convert-bfp-10.c: Ditto.
+       * gcc.dg/dfp/convert-bfp-11.c: Ditto.
 2007-09-10  Harsha Jagasia <harsha.jagasia@amd.com>
 
         * gcc.dg/vect/costmodel/i386/costmodel-vect-31.c: 
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-10.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-10.c
new file mode 100644 (file)
index 0000000..dec7b51
--- /dev/null
@@ -0,0 +1,114 @@
+/* { dg-options "-std=gnu99" } */
+
+/* This test assumes IEEE float and double.  */
+
+#define __STDC_WANT_DEC_FP__
+#include <float.h>
+
+#include "convert.h"
+
+volatile _Decimal32 sd;
+volatile _Decimal64 dd;
+volatile _Decimal128 td;
+volatile float sf;
+volatile double df;
+
+/* Conversions using denormalized float values.  */
+CONVERT_VALID (111, sf, sd, 1.2e-38f, 1.2e-38df, 0.df)
+CONVERT_VALID (112, sf, sd, 1.1e-38f, 1.1e-38df, 0.df)
+CONVERT_VALID (113, sf, sd, 1.1e-40f, 1.1e-40df, 1.1e-45df)
+
+CONVERT_VALID (121, sd, sf, 1.2e-38df, 1.2e-38f, 0.f)
+CONVERT_VALID (122, sd, sf, 1.1e-38df, 1.1e-38f, 0.f)
+
+CONVERT_VALID (131, sf, sd, -1.2e-38f, -1.2e-38df, 0.df)
+CONVERT_VALID (132, sf, sd, -1.1e-38f, -1.1e-38df, 0.df)
+
+CONVERT_VALID (141, sd, sf, -1.2e-38df, -1.2e-38f, 0.f)
+CONVERT_VALID (142, sd, sf, -1.1e-38df, -1.1e-38f, 0.f)
+
+/* Conversions using denormalized double values.  */
+CONVERT_VALID (211, df, sd, 1.2e-38, 1.2e-38df, 0.df)
+CONVERT_VALID (212, df, sd, 1.1e-38, 1.1e-38df, 0.df)
+CONVERT_VALID (213, df, sd, 1.e-40, 1.e-40df, 0.df)
+CONVERT_VALID (214, df, sd, 8.e-44, 8.e-44df, 0.df)
+CONVERT_VALID (215, df, sd, 9.e-44, 9.e-44df, 0.df)
+CONVERT_VALID (216, df, sd, 8.e-46, 8.e-46df, 0.df)
+CONVERT_VALID (217, df, sd, 7.e-46, 7.e-46df, 0.df)
+
+CONVERT_VALID (221, sd, df, 1.2e-38df, 1.2e-38, 1.e-53)
+CONVERT_VALID (222, sd, df, 1.1e-38df, 1.1e-38, 1.e-53)
+CONVERT_VALID (223, sd, df, 1.e-40df, 1.e-40, 0.)
+CONVERT_VALID (224, sd, df, 8.e-44df, 8.e-44, 0.)
+CONVERT_VALID (225, sd, df, 9.e-44df, 9.e-44, 0.)
+CONVERT_VALID (226, sd, df, 8.e-46df, 8.e-46, 0.)
+CONVERT_VALID (227, sd, df, 7.e-46df, 7.e-46, 0.)
+
+CONVERT_VALID (231, df, sd, -1.2e-38, -1.2e-38df, 0.df)
+CONVERT_VALID (232, df, sd, -1.1e-38f, -1.1e-38df, 0.df)
+CONVERT_VALID (233, df, sd, -1.e-40, -1.e-40df, 0.df)
+CONVERT_VALID (234, df, sd, -8.e-44, -8.e-44df, 0.df)
+CONVERT_VALID (235, df, sd, -9.e-44, -9.e-44df, 0.df)
+CONVERT_VALID (236, df, sd, -8.e-46, -8.e-46df, 0.df)
+CONVERT_VALID (237, df, sd, -7.e-46, -7.e-46df, 0.df)
+
+CONVERT_VALID (241, sd, df, -1.2e-38df, -1.2e-38, 1.e-53)
+CONVERT_VALID (242, sd, df, -1.1e-38df, -1.1e-38, 1.e-53)
+CONVERT_VALID (243, sd, df, -1.e-40df, -1.e-40, 0.)
+CONVERT_VALID (244, sd, df, -8.e-44df, -8.e-44, 0.)
+CONVERT_VALID (245, sd, df, -9.e-44df, -9.e-44, 0.)
+CONVERT_VALID (246, sd, df, -8.e-46df, -8.e-46, 0.)
+CONVERT_VALID (247, sd, df, -7.e-46df, -7.e-46, 0.)
+
+int
+main ()
+{
+  convert_111 ();
+  convert_112 ();
+  convert_113 ();
+
+  convert_121 ();
+  convert_122 ();
+
+  convert_131 ();
+  convert_132 ();
+
+  convert_141 ();
+  convert_142 ();
+
+  convert_211 ();
+  convert_212 ();
+  convert_213 ();
+  convert_214 ();
+  convert_215 ();
+  convert_216 ();
+  convert_217 ();
+
+  convert_221 ();
+  convert_222 ();
+  convert_223 ();
+  convert_224 ();
+  convert_225 ();
+  convert_226 ();
+  convert_227 ();
+
+  convert_231 ();
+  convert_232 ();
+  convert_233 ();
+  convert_234 ();
+  convert_235 ();
+  convert_236 ();
+  convert_237 ();
+
+  convert_241 ();
+  convert_242 ();
+  convert_243 ();
+  convert_244 ();
+  convert_245 ();
+  convert_246 ();
+  convert_247 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-11.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-11.c
new file mode 100644 (file)
index 0000000..283f9bd
--- /dev/null
@@ -0,0 +1,61 @@
+/* { dg-options "-std=gnu99" } */
+/* { dg-skip-if "" { ! "powerpc*-*-linux*" } { "*" } { "" } } */
+
+/* Test decimal float conversions to and from IBM 128-bit long double. 
+   Checks are skipped at runtime if long double is not 128 bits.
+   Don't force 128-bit long doubles because runtime support depends
+   on glibc.  */
+
+#include "convert.h"
+
+volatile _Decimal32 sd;
+volatile _Decimal64 dd;
+volatile _Decimal128 td;
+volatile float sf;
+volatile double df;
+volatile long double tf;
+
+/* A value slightly less than DEC32_MAX can be converted in both directions.  */
+CONVERT_VALID (101, sd, tf, 9.999998e96df, 9.999998e96L, 1.e+81L)
+CONVERT_VALID (102, tf, sd, 9.999998e96L, 9.999998e96df, 0.df)
+
+/* A value slightly less than DBL_MAX can be converted in both directions.  */
+CONVERT_VALID (201, tf, dd, 1.79768e+308l, 1.79768e+308dd, 0.dd)
+CONVERT_VALID (202, dd, tf, 1.79768e+308dd, 1.79768e+308l, 2.e292l)
+CONVERT_VALID (203, tf, td, 1.79768e+308l, 1.79768e+308dl, 1.e292dl)
+CONVERT_VALID (204, td, tf, 1.79768e+308dl, 1.79768e+308l, 2.e292l)
+
+/* Check values that are too large for the result type.  */
+CONVERT_TO_PINF (301, dd, tf, 1.8e+308dd, l)
+CONVERT_TO_PINF (302, dd, tf, 9.9e+384dd, l)
+CONVERT_TO_PINF (303, td, tf, 1.8e+308dl, l)
+CONVERT_TO_PINF (304, td, tf, 9.9e+384dl, l)
+
+CONVERT_TO_PINF (311, tf, sd, 1.0e+97L, d32)
+CONVERT_TO_PINF (312, tf, sd, 1.6e+308L, d32)
+
+int
+main ()
+{
+  if (sizeof (long double) != 16)
+    return 0;
+
+  convert_101 ();
+  convert_102 ();
+
+  convert_201 ();
+  convert_202 ();
+  convert_203 ();
+  convert_204 ();
+
+  convert_301 ();
+  convert_302 ();
+  convert_303 ();
+  convert_304 ();
+  convert_311 ();
+  convert_312 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-2.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-2.c
new file mode 100644 (file)
index 0000000..2827351
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-options "-std=gnu99" } */
+
+/* This test assumes IEEE float and double.  It also tests long double
+   but makes no assumption about its size or range of values.  */
+
+#include "convert.h"
+
+volatile _Decimal32 sd;
+volatile _Decimal64 dd;
+volatile _Decimal128 td;
+volatile float sf;
+volatile double df;
+volatile long double tf;   /* might actually be df or xf, doesn't matter */
+
+CONVERT_VALID_ALL (t1, 0.0, 0.)
+CONVERT_VALID_ALL (t2, 1.0, 0.)
+CONVERT_VALID_ALL (t3, -11.5, 0.)
+CONVERT_VALID_ALL (t4, 7.0, 0.1e-14)
+CONVERT_VALID_ALL (t5, -7.0, 0.1e-14)
+CONVERT_VALID_ALL (t6, 999999., 0.)
+CONVERT_VALID_ALL (t7, -999999., 0.)
+
+int
+main ()
+{
+  CALL_VALID_ALL (t1)
+  CALL_VALID_ALL (t2)
+  CALL_VALID_ALL (t3)
+  CALL_VALID_ALL (t4)
+  CALL_VALID_ALL (t5)
+  CALL_VALID_ALL (t6)
+  CALL_VALID_ALL (t7)
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-3.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-3.c
new file mode 100644 (file)
index 0000000..67d31c3
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-options "-std=gnu99" } */
+
+/* This test assumes IEEE float and double.  It also tests long double
+   but makes no assumption about its size or range of values.  */
+
+#include "convert.h"
+
+volatile _Decimal32 sd;
+volatile _Decimal64 dd;
+volatile _Decimal128 td;
+volatile float sf;
+volatile double df;
+volatile long double tf;   /* might actually be df or xf, doesn't matter */
+
+CONVERT_ZEROES_ALL (t);
+
+int
+main ()
+{
+  CALL_ZEROES_ALL (t)
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-4.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-4.c
new file mode 100644 (file)
index 0000000..feba37a
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-options "-std=gnu99" } */
+
+/* This test assumes IEEE float and double.  It also tests long double
+   but makes no assumption about its size or range of values.  */
+
+#include "convert.h"
+
+volatile _Decimal32 sd;
+volatile _Decimal64 dd;
+volatile _Decimal128 td;
+volatile float sf;
+volatile double df;
+volatile long double tf;   /* might actually be df or xf, doesn't matter */
+
+CONVERT_INF_ALL (t);
+
+int
+main ()
+{
+  CALL_INF_ALL (t)
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-5.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-5.c
new file mode 100644 (file)
index 0000000..cfb86fd
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-options "-std=gnu99" } */
+
+/* This test assumes IEEE float and double.  It also tests long double
+   but makes no assumption about its size or range of values.  */
+
+#include "convert.h"
+
+volatile _Decimal32 sd;
+volatile _Decimal64 dd;
+volatile _Decimal128 td;
+volatile float sf;
+volatile double df;
+volatile long double tf;   /* might actually be df or xf, doesn't matter */
+
+CONVERT_NAN_ALL (t);
+
+int
+main ()
+{
+  CALL_NAN_ALL (t)
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-6.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-6.c
new file mode 100644 (file)
index 0000000..6dc2a9e
--- /dev/null
@@ -0,0 +1,179 @@
+/* { dg-options "-std=gnu99 -w" } */
+
+/* This test assumes IEEE float and double.  */
+
+#define __STDC_WANT_DEC_FP__
+#include <float.h>
+
+#include "convert.h"
+
+volatile _Decimal32 sd;
+volatile _Decimal64 dd;
+volatile _Decimal128 td;
+volatile float sf;
+volatile double df;
+volatile long double tf;
+
+CONVERT_VALID (101, td, sf, 0.000488281251dl, 0.00048828125f, 0.f)
+
+/* 2**(-25) = 0.298023223876953125E-7.  */
+CONVERT_VALID (102, td, sf, 2.98023223876953125e-8dl, 2.9802322387695312e-08f,
+               01.e-13f)
+
+/* Fractional part doesn't fit.  */
+CONVERT_VALID (103, df, sd, 1.0e-20, 1.0e-20df, 0.df)
+
+/* Exact power of 2.  */
+CONVERT_VALID (104, df, sd, 0.00048828125, 0.00048828125df, 0.df)
+CONVERT_VALID (105, df, sd, 1.0e-96, 0.dd, DEC32_MIN)
+
+/* A value slightly less than FLT_MAX can be converted in both directions.  */
+CONVERT_VALID (201, sf, sd, 3.402819e+38f, 3.402819e+38df, 0.df)
+CONVERT_VALID (202, sd, sf, 3.402819e+38df, 3.402819e+38f, 0.f)
+CONVERT_VALID (203, sf, dd, 3.402819e+38f, 3.402819e+38dd, 1.e+30dd)
+CONVERT_VALID (204, dd, sf, 3.402819e+38dd, 3.402819e+38f, 0.f)
+CONVERT_VALID (205, sf, td, 3.402819e+38f, 3.402819e+38dl, 1.e+30dl)
+CONVERT_VALID (206, td, sf, 3.402819e+38dl, 3.402819e+38f, 0.f)
+
+/* A value slightly less than DEC32_MAX can be converted in both directions.  */
+CONVERT_VALID (211, sd, df, 9.999998e96df, 9.999998e96, 0.)
+CONVERT_VALID (212, df, sd, 9.999998e96, 9.999998e96df, 0.df)
+
+/* A value slightly less than DBL_MAX can be converted in both directions.  */
+CONVERT_VALID (221, df, dd, 1.79768e+308, 1.79768e+308dd, 0.dd)
+CONVERT_VALID (222, dd, df, 1.79768e+308dd, 1.79768e+308, 0.)
+CONVERT_VALID (223, df, td, 1.79768e+308, 1.79768e+308dl, 1.e292dl)
+CONVERT_VALID (224, td, df, 1.79768e+308dl, 1.79768e+308, 0.)
+
+/* An integral value with 6 digits (FLT_DIG) can be converted between float
+   and _Decimal32 in both directions.  */
+CONVERT_VALID (301, sd, sf, 100000.DF, 100000.F, 0.F)
+CONVERT_VALID (302, sf, sd, 100000.F, 100000.DF, 0.DF)
+CONVERT_VALID (303, sd, sf, 999999.DF, 999999.F, 0.F)
+CONVERT_VALID (304, sf, sd, 999999.F, 999999.DF, 0.DF)
+
+/* An integral value with 7 digits (DEC32_MANT_DIG) can be converted between
+   _Decimal32 and double in both directions.  */
+CONVERT_VALID (311, sd, df, 1000000.DF, 1000000., 0.)
+CONVERT_VALID (312, df, sd, 1000000., 1000000.DF, 0.DF)
+CONVERT_VALID (313, sd, df, 9999999.DF, 9999999., 0.)
+CONVERT_VALID (314, df, sd, 9999999., 9999999.DF, 0.DF)
+
+/* An integral value with 15 digits (DBL_DIG) can be converted between
+   double and _Decimal64 in both directions.  */
+CONVERT_VALID (321, dd, df, 100000000000000.DD, 100000000000000., 0.)
+CONVERT_VALID (322, df, dd, 100000000000000., 100000000000000.DD, 0.DD);
+CONVERT_VALID (323, dd, df, 999999999999999.DD, 999999999999999., 0.);
+CONVERT_VALID (324, df, dd, 999999999999999., 999999999999999.DD, 0.DD);
+
+/* If LDBL_DIG is at least 16, an integral value with 16 digits can be
+   converted between _Decimal64 and long double in both directions.  */
+CONVERT_VALID (331, dd, tf, 1000000000000000.DD, 1000000000000000.L, 0.L)
+CONVERT_VALID (332, td, dd, 1000000000000000.L, 1000000000000000.DD, 0.DD)
+CONVERT_VALID (333, dd, tf, 9999999999999999.DD, 9999999999999999.L, 0.L)
+CONVERT_VALID (334, td, dd, 9999999999999999.L, 9999999999999999.DD, 0.DD)
+
+/* If LDBL_DIG is at least 18, an integral value with 18 digits can be
+   converted between long double and _Decimal128 in both directions.  */
+CONVERT_VALID (341, td, tf, 100000000000000000.DL, 100000000000000000.L, 0.L)
+CONVERT_VALID (342, tf, td, 100000000000000000.L, 100000000000000000.DL, 0.DL)
+CONVERT_VALID (343, td, tf, 999999999999999999.DL, 999999999999999999.L, 0.L)
+CONVERT_VALID (344, tf, td, 999999999999999999.L, 999999999999999999.DL, 0.DL)
+
+/* If LDBL_DIG is at least 31, an integral value with 31 digits can be
+   converted between long double and _Decimal128 in both directions.  */
+CONVERT_VALID (351, td, tf, 1000000000000000000000000000000.DL,
+                           1000000000000000000000000000000.L, 0.L)
+CONVERT_VALID (352, tf, td, 1000000000000000000000000000000.L,
+                           1000000000000000000000000000000.DL, 0.DL)
+CONVERT_VALID (353, td, tf, 9999999999999999999999999999999.DL,
+                           9999999999999999999999999999999.L, 0.L)
+CONVERT_VALID (354, tf, td, 9999999999999999999999999999999.L,
+                           9999999999999999999999999999999.DL, 0.DL)
+
+/* If LDBL_DIG is at least 33, an integral value with 33 digits can be
+   converted between long double and _Decimal128 in both directions.  */
+CONVERT_VALID (361, td, tf, 100000000000000000000000000000000.DL,
+                           100000000000000000000000000000000.L, 0.L)
+CONVERT_VALID (362, tf, td, 100000000000000000000000000000000.L,
+                           100000000000000000000000000000000.DL, 0.DL)
+CONVERT_VALID (363, td, tf, 999999999999999999999999999999999.DL,
+                           999999999999999999999999999999999.L, 0.L)
+CONVERT_VALID (364, tf, td, 999999999999999999999999999999999.L,
+                           999999999999999999999999999999999.DL, 0.DL)
+
+int
+main ()
+{
+  convert_101 ();
+  convert_102 ();
+  convert_103 ();
+  convert_104 ();
+  convert_105 ();
+
+  convert_201 ();
+  convert_202 ();
+  convert_203 ();
+  convert_204 ();
+  convert_205 ();
+  convert_206 ();
+
+  convert_211 ();
+  convert_212 ();
+
+  convert_221 ();
+  convert_222 ();
+  convert_223 ();
+  convert_224 ();
+
+  convert_301 ();
+  convert_302 ();
+  convert_303 ();
+  convert_304 ();
+
+  convert_311 ();
+  convert_312 ();
+  convert_313 ();
+  convert_314 ();
+
+  convert_321 ();
+  convert_322 ();
+  convert_323 ();
+  convert_324 ();
+
+  if (LDBL_DIG >= 16)
+    {
+      convert_331 ();
+      convert_332 ();
+      convert_333 ();
+      convert_334 ();
+    }
+
+  if (LDBL_DIG >= 18)
+    {
+      convert_341 ();
+      convert_342 ();
+      convert_343 ();
+      convert_344 ();
+    }
+
+  if (LDBL_DIG >= 31)
+    {
+      convert_351 ();
+      convert_352 ();
+      convert_353 ();
+      convert_354 ();
+    }
+
+  if (LDBL_DIG >= 33)
+    {
+      convert_361 ();
+      convert_362 ();
+      convert_363 ();
+      convert_364 ();
+    }
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-7.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-7.c
new file mode 100644 (file)
index 0000000..0fb4f07
--- /dev/null
@@ -0,0 +1,85 @@
+/* { dg-options "-std=gnu99 -w" } */
+
+/* This test assumes IEEE float and double.  */
+
+#define __STDC_WANT_DEC_FP__
+#include <float.h>
+
+#include "convert.h"
+
+volatile _Decimal32 sd;
+volatile _Decimal64 dd;
+volatile _Decimal128 td;
+volatile float sf;
+volatile double df;
+
+/* Check values that are too large for the result type.  */
+CONVERT_TO_PINF (301, sd, sf, 4.e+38df, f)
+CONVERT_TO_PINF (303, dd, sf, 4.e+38dd, f)
+CONVERT_TO_PINF (302, sd, sf, 9.9e+384df, f)
+CONVERT_TO_PINF (304, dd, sf, 9.9e+384dd, f)
+CONVERT_TO_PINF (305, td, sf, 4.e+38dl, f)
+CONVERT_TO_PINF (306, td, sf, 1.e+39dl, f)
+CONVERT_TO_MINF (311, sd, sf, -4.e+38df, f)
+CONVERT_TO_MINF (312, dd, sf, -4.e+38dd, f)
+CONVERT_TO_MINF (313, sd, sf, -9.9e+384df, f)
+CONVERT_TO_MINF (314, dd, sf, -9.9e+384dd, f)
+CONVERT_TO_MINF (315, td, sf, -4.e+38dl, f)
+CONVERT_TO_MINF (316, td, sf, -1.e+39dl, f)
+
+CONVERT_TO_PINF (321, dd, df, 1.8e+308dd,)
+CONVERT_TO_PINF (322, dd, df, 9.9e+384dd,)
+CONVERT_TO_PINF (323, td, df, 1.8e+308dl,)
+CONVERT_TO_PINF (324, td, df, 9.9e+384dl,)
+CONVERT_TO_PINF (325, dd, df, 1.e309dd,)
+CONVERT_TO_PINF (326, td, df, 1.e309dl,)
+CONVERT_TO_MINF (331, dd, df, -1.8e+308dd,)
+CONVERT_TO_MINF (332, dd, df, -9.9e+384dd,)
+CONVERT_TO_MINF (333, td, df, -1.8e+308dl,)
+CONVERT_TO_MINF (334, td, df, -9.9e+384dl,)
+CONVERT_TO_MINF (335, dd, df, -1.e309dd,)
+CONVERT_TO_MINF (336, td, df, -1.e309dl,)
+
+CONVERT_TO_PINF (341, df, sd, 1.0e+97, d32)
+CONVERT_TO_PINF (342, df, sd, 1.6e+308, d32)
+CONVERT_TO_MINF (351, df, sd, -1.0e+97, d32)
+CONVERT_TO_MINF (352, df, sd, -1.6e+308, d32)
+
+int
+main ()
+{
+  convert_301 ();
+  convert_302 ();
+  convert_303 ();
+  convert_304 ();
+  convert_305 ();
+  convert_306 ();
+  convert_311 ();
+  convert_312 ();
+  convert_313 ();
+  convert_314 ();
+  convert_315 ();
+  convert_316 ();
+
+  convert_321 ();
+  convert_322 ();
+  convert_323 ();
+  convert_324 ();
+  convert_325 ();
+  convert_326 ();
+  convert_331 ();
+  convert_332 ();
+  convert_333 ();
+  convert_334 ();
+  convert_335 ();
+  convert_336 ();
+
+  convert_341 ();
+  convert_342 ();
+  convert_351 ();
+  convert_352 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-8.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-8.c
new file mode 100644 (file)
index 0000000..269fc37
--- /dev/null
@@ -0,0 +1,73 @@
+/* { dg-options "-std=gnu99 -w" } */
+
+/* This test assumes IEEE float and double.  */
+
+#define __STDC_WANT_DEC_FP__
+#include <float.h>
+
+#include "convert.h"
+
+volatile _Decimal32 sd;
+volatile _Decimal64 dd;
+volatile _Decimal128 td;
+volatile float sf;
+volatile double df;
+
+/* Values slightly smaller than minimum (closest to zero) for result type.  */
+CONVERT_VALID (401, sd, sf, 1.e-39df, 0.f, FLT_MIN)
+CONVERT_VALID (402, sd, sf, -1.e-39df, 0.f, FLT_MIN)
+CONVERT_VALID (403, sd, sf, 1.1e-38df, 0.f, FLT_MIN)
+CONVERT_VALID (404, sd, sf, -1.1e-38df, 0.f, FLT_MIN)
+
+CONVERT_VALID (411, dd, sf, 1.e-39dd, 0.f, FLT_MIN)
+CONVERT_VALID (412, dd, sf, -1.e-39dd, 0.f, FLT_MIN)
+CONVERT_VALID (413, dd, sf, 1.1e-38dd, 0.f, FLT_MIN)
+CONVERT_VALID (414, dd, sf, -1.1e-38dd, 0.f, FLT_MIN)
+
+CONVERT_VALID (421, dd, df, 3.e-309dd, 0., DBL_MIN)
+CONVERT_VALID (422, dd, df, -3.e-309dd, 0., DBL_MIN)
+CONVERT_VALID (423, dd, df, 2.e-308dd, 0., DBL_MIN)
+CONVERT_VALID (424, dd, df, -2.e-308dd, 0., DBL_MIN)
+
+CONVERT_VALID (431, td, sf, 1.e-39dl, 0.f, FLT_MIN)
+CONVERT_VALID (432, td, sf, -1.e-39dl, 0.f, FLT_MIN)
+CONVERT_VALID (433, td, sf, 1.1e-38dl, 0.f, FLT_MIN)
+CONVERT_VALID (434, td, sf, -1.1e-38dl, 0.f, FLT_MIN)
+
+CONVERT_VALID (441, td, df, 3.e-309dl, 0., DBL_MIN)
+CONVERT_VALID (442, td, df, -3.e-309dl, 0., DBL_MIN)
+CONVERT_VALID (443, td, df, 2.e-308dl, 0., DBL_MIN)
+CONVERT_VALID (444, td, df, -2.e-308dl, 0., DBL_MIN)
+
+int
+main ()
+{
+  convert_401 ();
+  convert_402 ();
+  convert_403 ();
+  convert_404 ();
+
+  convert_411 ();
+  convert_412 ();
+  convert_413 ();
+  convert_414 ();
+
+  convert_421 ();
+  convert_422 ();
+  convert_423 ();
+  convert_424 ();
+
+  convert_431 ();
+  convert_432 ();
+  convert_433 ();
+  convert_434 ();
+
+  convert_441 ();
+  convert_442 ();
+  convert_443 ();
+  convert_444 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp-9.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp-9.c
new file mode 100644 (file)
index 0000000..86ae430
--- /dev/null
@@ -0,0 +1,193 @@
+/* { dg-options "-std=gnu99 -w" } */
+
+/* This test assumes IEEE float and double.  */
+
+#define __STDC_WANT_DEC_FP__
+#include <float.h>
+
+#include "convert.h"
+
+volatile _Decimal32 sd;
+volatile _Decimal64 dd;
+volatile _Decimal128 td;
+volatile float sf;
+volatile double df;
+
+/* Exponent values that might cause problems with a particular
+   implementation.  */
+
+CONVERT_VALID (101, dd, df, 1.e309dd, 1.e309, 0.) 
+CONVERT_VALID (102, dd, df, 1.e308dd, 1.e308, 0.)
+CONVERT_VALID (103, dd, df, 1.e307dd, 1.e307, 0.) 
+CONVERT_VALID (104, dd, df, 1.e306dd, 1.e306, 0.) 
+CONVERT_VALID (105, dd, df, 1.e305dd, 1.e305, 0.)
+CONVERT_VALID (106, dd, df, 1.e304dd, 1.e304, 0.)
+CONVERT_VALID (107, dd, df, 1.e303dd, 1.e303, 0.) 
+CONVERT_VALID (108, dd, df, 1.e302dd, 1.e302, 0.) 
+CONVERT_VALID (109, dd, df, 1.e301dd, 1.e301, 0.) 
+CONVERT_VALID (110, dd, df, 1.e300dd, 1.e300, 0.) 
+CONVERT_VALID (111, dd, df, 1.e299dd, 1.e299, 0.) 
+CONVERT_VALID (112, dd, df, 1.e298dd, 1.e298, 0.) 
+CONVERT_VALID (113, dd, df, 1.e297dd, 1.e297, 0.) 
+CONVERT_VALID (114, dd, df, 1.e296dd, 1.e296, 0.) 
+CONVERT_VALID (115, dd, df, 1.e295dd, 1.e295, 0.) 
+CONVERT_VALID (116, dd, df, 1.e294dd, 1.e294, 0.) 
+CONVERT_VALID (117, dd, df, 1.e293dd, 1.e293, 0.) 
+CONVERT_VALID (118, dd, df, 1.e292dd, 1.e292, 0.) 
+CONVERT_VALID (119, dd, df, 1.e291dd, 1.e291, 0.)
+CONVERT_VALID (120, dd, df, 1.e290dd, 1.e290, 0.)
+
+CONVERT_VALID (201, dd, df, 1.e-309dd, 1.e-309, 0.) 
+CONVERT_VALID (202, dd, df, 1.e-308dd, 1.e-308, 0.) 
+CONVERT_VALID (203, dd, df, 1.e-307dd, 1.e-307, 0.) 
+CONVERT_VALID (204, dd, df, 1.e-306dd, 1.e-306, 0.) 
+CONVERT_VALID (205, dd, df, 1.e-305dd, 1.e-305, 0.) 
+CONVERT_VALID (206, dd, df, 1.e-304dd, 1.e-304, 0.) 
+CONVERT_VALID (207, dd, df, 1.e-303dd, 1.e-303, 0.) 
+CONVERT_VALID (208, dd, df, 1.e-302dd, 1.e-302, 0.) 
+CONVERT_VALID (209, dd, df, 1.e-301dd, 1.e-301, 0.) 
+CONVERT_VALID (210, dd, df, 1.e-300dd, 1.e-300, 0.) 
+CONVERT_VALID (211, dd, df, 1.e-299dd, 1.e-299, 0.) 
+CONVERT_VALID (212, dd, df, 1.e-298dd, 1.e-298, 0.) 
+CONVERT_VALID (213, dd, df, 1.e-297dd, 1.e-297, 0.) 
+CONVERT_VALID (214, dd, df, 1.e-296dd, 1.e-296, 0.) 
+CONVERT_VALID (215, dd, df, 1.e-295dd, 1.e-295, 0.)
+CONVERT_VALID (216, dd, df, 1.e-294dd, 1.e-294, 0.)
+CONVERT_VALID (217, dd, df, 1.e-293dd, 1.e-293, 0.) 
+CONVERT_VALID (218, dd, df, 1.e-292dd, 1.e-292, 0.) 
+CONVERT_VALID (219, dd, df, 1.e-291dd, 1.e-291, 0.) 
+CONVERT_VALID (220, dd, df, 1.e-290dd, 1.e-290, 0.) 
+
+CONVERT_VALID (301, td, df, 1.e309dl, 1.e309, 0.) 
+CONVERT_VALID (302, td, df, 1.e308dl, 1.e308, 0.)
+CONVERT_VALID (303, td, df, 1.e307dl, 1.e307, 0.) 
+CONVERT_VALID (304, td, df, 1.e306dl, 1.e306, 0.) 
+CONVERT_VALID (305, td, df, 1.e305dl, 1.e305, 0.)
+CONVERT_VALID (306, td, df, 1.e304dl, 1.e304, 0.)
+CONVERT_VALID (307, td, df, 1.e303dl, 1.e303, 0.) 
+CONVERT_VALID (308, td, df, 1.e302dl, 1.e302, 0.) 
+CONVERT_VALID (309, td, df, 1.e301dl, 1.e301, 0.)
+CONVERT_VALID (310, td, df, 1.e300dl, 1.e300, 0.) 
+CONVERT_VALID (311, td, df, 1.e299dl, 1.e299, 0.)
+CONVERT_VALID (312, td, df, 1.e298dl, 1.e298, 0.)
+CONVERT_VALID (313, td, df, 1.e297dl, 1.e297, 0.) 
+CONVERT_VALID (314, td, df, 1.e296dl, 1.e296, 0.) 
+CONVERT_VALID (315, td, df, 1.e295dl, 1.e295, 0.)
+CONVERT_VALID (316, td, df, 1.e294dl, 1.e294, 0.)
+CONVERT_VALID (317, td, df, 1.e293dl, 1.e293, 0.) 
+CONVERT_VALID (318, td, df, 1.e292dl, 1.e292, 0.) 
+CONVERT_VALID (319, td, df, 1.e291dl, 1.e291, 0.) 
+CONVERT_VALID (320, td, df, 1.e290dl, 1.e290, 0.)
+
+CONVERT_VALID (401, td, df, 1.e-309dl, 1.e-309, 0.) 
+CONVERT_VALID (402, td, df, 1.e-308dl, 1.e-308, 0.) 
+CONVERT_VALID (403, td, df, 1.e-307dl, 1.e-307, 0.) 
+CONVERT_VALID (404, td, df, 1.e-306dl, 1.e-306, 0.) 
+CONVERT_VALID (405, td, df, 1.e-305dl, 1.e-305, 0.) 
+CONVERT_VALID (406, td, df, 1.e-304dl, 1.e-304, 0.) 
+CONVERT_VALID (407, td, df, 1.e-303dl, 1.e-303, 0.) 
+CONVERT_VALID (408, td, df, 1.e-302dl, 1.e-302, 0.) 
+CONVERT_VALID (409, td, df, 1.e-301dl, 1.e-301, 0.) 
+CONVERT_VALID (410, td, df, 1.e-300dl, 1.e-300, 0.) 
+CONVERT_VALID (411, td, df, 1.e-299dl, 1.e-299, 0.) 
+CONVERT_VALID (412, td, df, 1.e-298dl, 1.e-298, 0.) 
+CONVERT_VALID (413, td, df, 1.e-297dl, 1.e-297, 0.) 
+CONVERT_VALID (414, td, df, 1.e-296dl, 1.e-296, 0.) 
+CONVERT_VALID (415, td, df, 1.e-295dl, 1.e-295, 0.) 
+CONVERT_VALID (416, td, df, 1.e-294dl, 1.e-294, 0.) 
+CONVERT_VALID (417, td, df, 1.e-293dl, 1.e-293, 0.) 
+CONVERT_VALID (418, td, df, 1.e-292dl, 1.e-292, 0.)
+CONVERT_VALID (419, td, df, 1.e-291dl, 1.e-291, 0.) 
+CONVERT_VALID (420, td, df, 1.e-290dl, 1.e-290, 0.)
+
+int
+main ()
+{
+  convert_101 ();
+  convert_102 ();
+  convert_103 ();
+  convert_104 ();
+  convert_105 ();
+  convert_106 ();
+  convert_107 ();
+  convert_108 ();
+  convert_109 ();
+  convert_110 ();
+  convert_111 ();
+  convert_112 ();
+  convert_113 ();
+  convert_114 ();
+  convert_115 ();
+  convert_116 ();
+  convert_117 ();
+  convert_118 ();
+  convert_119 ();
+  convert_120 ();
+
+  convert_201 ();
+  convert_202 ();
+  convert_203 ();
+  convert_204 ();
+  convert_205 ();
+  convert_206 ();
+  convert_207 ();
+  convert_208 ();
+  convert_209 ();
+  convert_210 ();
+  convert_211 ();
+  convert_212 ();
+  convert_213 ();
+  convert_214 ();
+  convert_215 ();
+  convert_216 ();
+  convert_217 ();
+  convert_218 ();
+  convert_219 ();
+  convert_220 ();
+
+  convert_301 ();
+  convert_302 ();
+  convert_303 ();
+  convert_304 ();
+  convert_305 ();
+  convert_306 ();
+  convert_307 ();
+  convert_308 ();
+  convert_309 ();
+  convert_310 ();
+  convert_311 ();
+  convert_312 ();
+  convert_313 ();
+  convert_314 ();
+  convert_315 ();
+  convert_316 ();
+  convert_317 ();
+  convert_318 ();
+  convert_319 ();
+  convert_320 ();
+
+  convert_401 ();
+  convert_402 ();
+  convert_403 ();
+  convert_404 ();
+  convert_405 ();
+  convert_406 ();
+  convert_407 ();
+  convert_408 ();
+  convert_409 ();
+  convert_410 ();
+  convert_411 ();
+  convert_412 ();
+  convert_413 ();
+  convert_414 ();
+  convert_415 ();
+  convert_416 ();
+  convert_417 ();
+  convert_418 ();
+  convert_419 ();
+  convert_420 ();
+
+  if (failcnt != 0)
+    abort ();
+  return 0;
+}
index c65210f..b2e8ca8 100644 (file)
@@ -5,10 +5,10 @@
    C99 6.3.1.5(4) Conversions, arithmetic operands, real floating types.  */
 
 /* Long double isn't supported yet at runtime, so disable those checks.  */
-#define SKIP_LONG_DOUBLE
 
 extern void abort (void);
 static int failcnt;
+static int skip_long_double;
 
 /* Support compiling the test to report individual failures; default is
    to abort as soon as a check fails.  */
@@ -24,15 +24,16 @@ volatile _Decimal64 d64;
 volatile _Decimal128 d128;
 volatile float sf;
 volatile double df;
-#ifndef SKIP_LONG_DOUBLE
 volatile long double tf;
-#endif
 
 int
 main ()
 {
   /* Conversions from decimal float to binary float. */
 
+  if (sizeof (long double) == sizeof (double))
+    skip_long_double = 1;
+
   /* Conversions from _Decimal32. */
   d32 = 2.0df;
   sf = d32;
@@ -43,11 +44,12 @@ main ()
   if (df != 2.0)
     FAILURE
 
-#ifndef SKIP_LONG_DOUBLE
-  tf = d32;
-  if (tf != 2.0l)
-    FAILURE
-#endif
+  if (skip_long_double == 0)
+    {
+      tf = d32;
+      if (tf != 2.0l)
+       FAILURE
+    }
 
   /* Conversions from _Decimal64. */
   d64 = -7.0dd;
@@ -59,11 +61,12 @@ main ()
   if (df != -7.0)
     FAILURE
 
-#ifndef SKIP_LONG_DOUBLE
-  tf = d64;
-  if (tf != -7.0l)
-    FAILURE
-#endif
+  if (skip_long_double == 0)
+    {
+      tf = d64;
+      if (tf != -7.0l)
+       FAILURE
+    }
 
   /* Conversions from _Decimal128. */
   d128 = 30.0dl;
@@ -107,20 +110,21 @@ main ()
   if (d128 != 30.0dl)
     FAILURE
 
-#ifndef SKIP_LONG_DOUBLE
-  tf = -22.0l;
-  d32 = tf;
-  if (d32 != -22.0df)
-    FAILURE
+  if (skip_long_double == 0)
+    {
+      tf = -22.0l;
+      d32 = tf;
+      if (d32 != -22.0df)
+       FAILURE
 
-  d64 = tf;
-  if (d64 != -22.0dd)
-    FAILURE
+      d64 = tf;
+      if (d64 != -22.0dd)
+       FAILURE
 
-  d128 = tf;
-  if (d128 != -22.0dl)
-    FAILURE
-#endif
+      d128 = tf;
+      if (d128 != -22.0dl)
+       FAILURE
+     }
 
   /* 2**(-11) = 0.00048828125. */
   d128 = 0.000488281251dl;
diff --git a/gcc/testsuite/gcc.dg/dfp/convert.h b/gcc/testsuite/gcc.dg/dfp/convert.h
new file mode 100644 (file)
index 0000000..bc9ef42
--- /dev/null
@@ -0,0 +1,461 @@
+extern void abort (void);
+static int failcnt = 0;
+
+/* Macros are set up to skip using long double, which doesn't necessarily
+   map to TF mode.  If there's a reason to skip those for a test, the
+   test itself can define USE_TF to be zero.  */
+#ifndef USE_TF
+#define USE_TF 1
+#endif
+
+/* 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) \
+  { printf ("failed for test %s\n", NUM); failcnt++; }
+#else
+#define FAILURE(N) abort ();
+#endif
+
+/* This is useful when modifying the test to make sure that tests are
+   actually run.  */
+#if defined(DBG2)
+#define REPORT(NUM) \
+  { printf ("%s\n", NUM); }
+#else
+#define REPORT(N) ;
+#endif
+
+#define CONVERT_VALID(NUM,FROM,TO,FROMVAL,TOVAL,DIFF)          \
+void                                                           \
+convert_##NUM (void)                                           \
+{                                                              \
+  REPORT(#NUM " " #FROMVAL)                                    \
+  FROM = FROMVAL;                                              \
+  TO = FROM;                                                   \
+  if (TO < (TOVAL - DIFF) || TO > (TOVAL + DIFF))              \
+    FAILURE (#NUM);                                            \
+}
+
+#define CONVERT_TO_PINF(NUM,FROM,TO,FROMVAL,TOSUFFIX)          \
+void                                                           \
+convert_##NUM (void)                                           \
+{                                                              \
+  REPORT(#NUM " " #FROMVAL)                                    \
+  FROM = FROMVAL;                                              \
+  TO = FROM;                                                   \
+  if (__builtin_isinf##TOSUFFIX (TO) == 0)                     \
+    FAILURE (#NUM " pinf: isinf");                             \
+  if (__builtin_signbit##TOSUFFIX (TO) != 0)                   \
+    FAILURE (#NUM " pinf: sign");                              \
+}
+
+#define CONVERT_TO_MINF(NUM,FROM,TO,FROMVAL,TOSUFFIX)          \
+void                                                           \
+convert_##NUM (void)                                           \
+{                                                              \
+  REPORT(#NUM " " #FROMVAL)                                    \
+  FROM = FROMVAL;                                              \
+  TO = FROM;                                                   \
+  if (__builtin_isinf##TOSUFFIX (TO) == 0)                     \
+    FAILURE (#NUM " pinf: isinf");                             \
+  if (__builtin_signbit##TOSUFFIX (TO) == 0)                   \
+    FAILURE (#NUM " pinf: sign");                              \
+}
+
+#define CONVERT_TO_PZERO(NUM,FROM,TO,FROMVAL,TOVAL,TOSUFFIX)   \
+void                                                           \
+convert_##NUM (void)                                           \
+{                                                              \
+  REPORT(#NUM " " #FROMVAL)                                    \
+  FROM = FROMVAL;                                              \
+  TO = FROM;                                                   \
+  if (TO != TOVAL)                                             \
+    FAILURE (#NUM "_pzero: zero")                              \
+  if (__builtin_signbit##TOSUFFIX (TO) != 0)                   \
+    FAILURE (#NUM " _pzero: sign");                            \
+}
+
+#define CONVERT_TO_MZERO(NUM,FROM,TO,FROMVAL,TOVAL,TOSUFFIX)   \
+void                                                           \
+convert_##NUM (void)                                           \
+{                                                              \
+  REPORT(#NUM " " #FROMVAL)                                    \
+  FROM = FROMVAL;                                              \
+  TO = FROM;                                                   \
+  if (TO != TOVAL)                                             \
+    FAILURE (#NUM "_mzero: zero")                              \
+  if (__builtin_signbit##TOSUFFIX (TO) == 0)                   \
+    FAILURE (#NUM " _mzero: sign");                            \
+}
+
+#define CONVERT_NAN(NUM,FROM,TO,FROMSUFFIX,TOSUFFIX)           \
+void                                                           \
+convert_##NUM##_nan (void)                                     \
+{                                                              \
+  REPORT(#NUM "_nan")                                          \
+  FROM = __builtin_nan##FROMSUFFIX ("");                       \
+  TO = FROM;                                                   \
+  if (__builtin_isnan##TOSUFFIX (TO) == 0)                     \
+    FAILURE (#NUM " nan");                                     \
+}
+
+#define CONVERT_PINF(NUM,FROM,TO,FROMSUFFIX,TOSUFFIX)          \
+void                                                           \
+convert_##NUM##_pinf (void)                                    \
+{                                                              \
+  REPORT (#NUM "_pinf")                                                \
+  FROM = __builtin_inf##FROMSUFFIX ();                         \
+  TO = FROM;                                                   \
+  if (__builtin_isinf##TOSUFFIX (TO) == 0)                     \
+    FAILURE (#NUM " pinf: isinf");                             \
+  if (__builtin_signbit##TOSUFFIX (TO) != 0)                   \
+    FAILURE (#NUM " pinf: sign");                              \
+}
+
+#define CONVERT_MINF(NUM,FROM,TO,FROMSUFFIX,TOSUFFIX)          \
+void                                                           \
+convert_##NUM##_minf (void)                                    \
+{                                                              \
+  REPORT (#NUM "_minf")                                                \
+  FROM = -__builtin_inf##FROMSUFFIX ();                                \
+  TO = FROM;                                                   \
+  if (__builtin_isinf##TOSUFFIX (TO) == 0)                     \
+    FAILURE (#NUM " minf: isinf");                             \
+  if (__builtin_signbit##TOSUFFIX (TO) == 0)                   \
+    FAILURE (#NUM " minf: sign");                              \
+}
+
+#define CONVERT_PZERO(NUM,FROM,TO,FROMVALUE,TOVALUE,TOSUFFIX)  \
+void                                                           \
+convert_##NUM##_pzero (void)                                   \
+{                                                              \
+  REPORT (#NUM "_pzero")                                       \
+  FROM = FROMVALUE;                                            \
+  TO = FROM;                                                   \
+  if (TO != TOVALUE)                                           \
+    FAILURE (#NUM "pzero: zero")                               \
+  if (__builtin_signbit##TOSUFFIX (TO) != 0)                   \
+    FAILURE (#NUM " pzero: sign");                             \
+}
+
+#define CONVERT_MZERO(NUM,FROM,TO,FROMVALUE,TOVALUE,TOSUFFIX)  \
+void                                                           \
+convert_##NUM##_mzero (void)                                   \
+{                                                              \
+  REPORT (#NUM "_mzero")                                       \
+  FROM = FROMVALUE;                                            \
+  TO = FROM;                                                   \
+  if (TO != TOVALUE)                                           \
+    FAILURE (#NUM "mzero: zero")                               \
+  if (__builtin_signbit##TOSUFFIX (TO) == 0)                   \
+    FAILURE (#NUM " mzero: sign");                             \
+}
+
+#define CONVERT_VALID_NOTF(NUM,VAL,DIFF)                       \
+CONVERT_VALID (NUM##_sdsf, sd, sf, VAL##df, VAL##f, DIFF##f)   \
+CONVERT_VALID (NUM##_sddf, sd, df, VAL##df, VAL, DIFF)         \
+CONVERT_VALID (NUM##_ddsf, dd, sf, VAL##dd, VAL##f, DIFF##f)   \
+CONVERT_VALID (NUM##_dddf, dd, df, VAL##dd, VAL, DIFF)         \
+CONVERT_VALID (NUM##_tdsf, td, sf, VAL##dl, VAL##f, DIFF##f)   \
+CONVERT_VALID (NUM##_tddf, td, df, VAL##dl, VAL, DIFF)         \
+CONVERT_VALID (NUM##_sfsd, sf, sd, VAL##f, VAL##df, DIFF##df)  \
+CONVERT_VALID (NUM##_sfdd, sf, dd, VAL##f, VAL##dd, DIFF##dd)  \
+CONVERT_VALID (NUM##_sftd, sf, td, VAL##f, VAL##dl, DIFF##dl)  \
+CONVERT_VALID (NUM##_dfsd, df, sd, VAL, VAL##df, DIFF##df)     \
+CONVERT_VALID (NUM##_dfdd, df, dd, VAL, VAL##dd, DIFF##dd)     \
+CONVERT_VALID (NUM##_dftd, df, td, VAL, VAL##dl, DIFF##dl)     \
+CONVERT_VALID (NUM##_sddd, sd, dd, VAL##df, VAL##dd, DIFF##dd) \
+CONVERT_VALID (NUM##_sdtd, sd, dd, VAL##df, VAL##dd, DIFF##dd) \
+CONVERT_VALID (NUM##_ddsd, dd, sd, VAL##dd, VAL##df, DIFF##dd) \
+CONVERT_VALID (NUM##_ddtd, dd, td, VAL##dd, VAL##dl, DIFF##dl) \
+CONVERT_VALID (NUM##_tdsd, td, sd, VAL##dl, VAL##df, DIFF##df) \
+CONVERT_VALID (NUM##_tddd, td, dd, VAL##dl, VAL##dd, DIFF##dd)
+
+#if USE_TF == 0
+#define CONVERT_VALID_TF(NUM,VAL,DIFF)
+#else
+#define CONVERT_VALID_TF(NUM,VAL,DIFF)                         \
+CONVERT_VALID (NUM##_sdtf, sd, tf, VAL##df, VAL##l, DIFF##l)   \
+CONVERT_VALID (NUM##_tdtf, td, tf, VAL##dl, VAL##l, DIFF##l)   \
+CONVERT_VALID (NUM##_ddtf, dd, tf, VAL##dd, VAL##l, DIFF##l)   \
+CONVERT_VALID (NUM##_tfsd, tf, sd, VAL##l, VAL##df, DIFF##df)  \
+CONVERT_VALID (NUM##_tfdd, tf, dd, VAL##l, VAL##dd, DIFF##dd)  \
+CONVERT_VALID (NUM##_tftd, tf, td, VAL##l, VAL##dl, DIFF##dl)
+#endif
+
+#define CONVERT_VALID_ALL(NUM,VAL,DIFF)                                \
+  CONVERT_VALID_NOTF(NUM,VAL,DIFF)                             \
+  CONVERT_VALID_TF(NUM,VAL,DIFF)
+
+#define CALL_VALID_NOTF(NUM)                                   \
+  convert_##NUM##_sdsf ();                                     \
+  convert_##NUM##_sddf ();                                     \
+  convert_##NUM##_ddsf ();                                     \
+  convert_##NUM##_dddf ();                                     \
+  convert_##NUM##_tdsf ();                                     \
+  convert_##NUM##_tddf ();                                     \
+  convert_##NUM##_sfsd ();                                     \
+  convert_##NUM##_sfdd ();                                     \
+  convert_##NUM##_sftd ();                                     \
+  convert_##NUM##_dfsd ();                                     \
+  convert_##NUM##_dfdd ();                                     \
+  convert_##NUM##_dftd ();                                     \
+  convert_##NUM##_sddd ();                                     \
+  convert_##NUM##_sdtd ();                                     \
+  convert_##NUM##_ddsd ();                                     \
+  convert_##NUM##_ddtd ();                                     \
+  convert_##NUM##_tdsd ();                                     \
+  convert_##NUM##_tddd ();
+
+#if USE_TF == 0
+#define CALL_VALID_TF(NUM)
+#else
+#define CALL_VALID_TF(NUM)                                     \
+  convert_##NUM##_sdtf ();                                     \
+  convert_##NUM##_ddtf ();                                     \
+  convert_##NUM##_tdtf ();                                     \
+  convert_##NUM##_tfsd ();                                     \
+  convert_##NUM##_tfdd ();                                     \
+  convert_##NUM##_tftd ();
+#endif
+
+#define CALL_VALID_ALL(NUM)                                    \
+  CALL_VALID_NOTF(NUM)                                         \
+  CALL_VALID_TF(NUM)
+
+#define CONVERT_ZEROES(NUM,FROM,TO,FROMVALUE,TOVALUE,TOSUFFIX) \
+CONVERT_PZERO(NUM, FROM, TO, FROMVALUE, TOVALUE, TOSUFFIX)     \
+CONVERT_MZERO(NUM, FROM, TO, -FROMVALUE, -TOVALUE, TOSUFFIX)
+
+#define CONVERT_ZEROES_NOTF(NUM)                               \
+CONVERT_ZEROES (NUM##_sdsf, sd, sf, 0.0df, 0.0f, f)            \
+CONVERT_ZEROES (NUM##_sddf, sd, df, 0.0df, 0.0, )              \
+CONVERT_ZEROES (NUM##_ddsf, dd, sf, 0.0dd, 0.0f, f)            \
+CONVERT_ZEROES (NUM##_dddf, dd, df, 0.0dd, 0.0, )              \
+CONVERT_ZEROES (NUM##_tdsf, td, sf, 0.0dl, 0.0f, f)            \
+CONVERT_ZEROES (NUM##_tddf, td, df, 0.0dl, 0.0, )              \
+CONVERT_ZEROES (NUM##_sfsd, sf, sd, 0.0f, 0.0df, d32)          \
+CONVERT_ZEROES (NUM##_sfdd, sf, dd, 0.0f, 0.0dd, d64)          \
+CONVERT_ZEROES (NUM##_sftd, sf, td, 0.0f, 0.0dl, d128)         \
+CONVERT_ZEROES (NUM##_dfsd, df, sd, 0.0, 0.0df, d32)           \
+CONVERT_ZEROES (NUM##_dfdd, df, dd, 0.0, 0.0dd, d64)           \
+CONVERT_ZEROES (NUM##_dftd, df, td, 0.0, 0.0dl, d128)          \
+CONVERT_ZEROES (NUM##_sddd, sd, dd, 0.0df, 0.0dd, d64)         \
+CONVERT_ZEROES (NUM##_sdtd, sd, td, 0.0dl, 0.0dl, d128)                \
+CONVERT_ZEROES (NUM##_ddsd, dd, sd, 0.0dd, 0.0df, d32)         \
+CONVERT_ZEROES (NUM##_ddtd, dd, td, 0.0dd, 0.0dl, d128)                \
+CONVERT_ZEROES (NUM##_tdsd, td, sd, 0.0dl, 0.0df, d32)         \
+CONVERT_ZEROES (NUM##_tddd, td, dd, 0.0dl, 0.0dd, d64)
+
+#if USE_TF == 0
+#define CONVERT_ZEROES_TF(NUM)
+#else
+#define CONVERT_ZEROES_TF(NUM)                                 \
+CONVERT_ZEROES (NUM##_sdtf, sd, tf, 0.0df, 0.0l, l)            \
+CONVERT_ZEROES (NUM##_ddtf, dd, tf, 0.0dd, 0.0l, l)            \
+CONVERT_ZEROES (NUM##_tdtf, td, tf, 0.0dl, 0.0l, l)            \
+CONVERT_ZEROES (NUM##_tfsd, tf, sd, 0.0l, 0.0df, d32)          \
+CONVERT_ZEROES (NUM##_tfdd, tf, dd, 0.0l, 0.0dd, d64)          \
+CONVERT_ZEROES (NUM##_tftd, tf, td, 0.0l, 0.0dl, d128)
+#endif
+
+#define CONVERT_ZEROES_ALL(NUM)                                        \
+  CONVERT_ZEROES_NOTF(NUM)                                     \
+  CONVERT_ZEROES_TF(NUM)
+
+#define CALL_ZEROES(NUM)                                       \
+  convert_##NUM##_pzero ();                                    \
+  convert_##NUM##_mzero ();
+
+#define CALL_ZEROES_NOTF(NUM)                                  \
+  CALL_ZEROES (NUM##_sdsf)                                     \
+  CALL_ZEROES (NUM##_sddf)                                     \
+  CALL_ZEROES (NUM##_ddsf)                                     \
+  CALL_ZEROES (NUM##_dddf)                                     \
+  CALL_ZEROES (NUM##_tdsf)                                     \
+  CALL_ZEROES (NUM##_tddf)                                     \
+  CALL_ZEROES (NUM##_sfsd)                                     \
+  CALL_ZEROES (NUM##_sfdd)                                     \
+  CALL_ZEROES (NUM##_sftd)                                     \
+  CALL_ZEROES (NUM##_dfsd)                                     \
+  CALL_ZEROES (NUM##_dfdd)                                     \
+  CALL_ZEROES (NUM##_dftd)                                     \
+  CALL_ZEROES (NUM##_sddd)                                     \
+  CALL_ZEROES (NUM##_sdtd)                                     \
+  CALL_ZEROES (NUM##_ddsd)                                     \
+  CALL_ZEROES (NUM##_ddtd)                                     \
+  CALL_ZEROES (NUM##_tdsd)                                     \
+  CALL_ZEROES (NUM##_tddd)
+
+#if USE_TF == 0
+#define CALL_ZEROES_TF(NUM)
+#else
+#define CALL_ZEROES_TF(NUM)                                    \
+  CALL_ZEROES (NUM##_sdtf)                                     \
+  CALL_ZEROES (NUM##_ddtf)                                     \
+  CALL_ZEROES (NUM##_tdtf)                                     \
+  CALL_ZEROES (NUM##_tfsd)                                     \
+  CALL_ZEROES (NUM##_tfdd)                                     \
+  CALL_ZEROES (NUM##_tftd)
+#endif
+
+#define CALL_ZEROES_ALL(NUM)                                   \
+  CALL_ZEROES_NOTF(NUM)                                                \
+  CALL_ZEROES_TF(NUM)
+
+#define CONVERT_INF(NUM,FROM,TO,FROMSUFFIX,TOSUFFIX)           \
+CONVERT_PINF (NUM, FROM, TO, FROMSUFFIX, TOSUFFIX)             \
+CONVERT_MINF (NUM, FROM, TO, FROMSUFFIX, TOSUFFIX)
+
+#define CONVERT_INF_NOTF(NUM)                                  \
+CONVERT_INF (NUM##_sdsf, sd, sf, d32, f)                       \
+CONVERT_INF (NUM##_sddf, sd, df, d32, )                                \
+CONVERT_INF (NUM##_ddsf, dd, sf, d64, f)                       \
+CONVERT_INF (NUM##_dddf, dd, df, d64, )                                \
+CONVERT_INF (NUM##_tdsf, td, sf, d128, f)                      \
+CONVERT_INF (NUM##_tddf, td, df, d128, )                       \
+CONVERT_INF (NUM##_sfsd, sf, sd, f, d32)                       \
+CONVERT_INF (NUM##_sfdd, sf, dd, f, d64)                       \
+CONVERT_INF (NUM##_sftd, sf, td, f, d128)                      \
+CONVERT_INF (NUM##_dfsd, df, sd, , d32)                                \
+CONVERT_INF (NUM##_dfdd, df, dd, , d64)                                \
+CONVERT_INF (NUM##_dftd, df, td, , d128)                       \
+CONVERT_INF (NUM##_sddd, sd, dd, d32, d64)                     \
+CONVERT_INF (NUM##_sdtd, sd, td, d32, d128)                    \
+CONVERT_INF (NUM##_ddsd, dd, sd, d64, d32)                     \
+CONVERT_INF (NUM##_ddtd, dd, td, d64, d128)                    \
+CONVERT_INF (NUM##_tdsd, td, sd, d128, d32)                    \
+CONVERT_INF (NUM##_tddd, td, dd, d128, d64)
+
+#if USE_TF == 0
+#define CONVERT_INF_TF(NUM)
+#else
+#define CONVERT_INF_TF(NUM)                                    \
+CONVERT_INF (NUM##_sdtf, sd, tf, d32, l)                       \
+CONVERT_INF (NUM##_ddtf, dd, tf, d64, l)                       \
+CONVERT_INF (NUM##_tdtf, td, tf, d128, l)                      \
+CONVERT_INF (NUM##_tfsd, tf, sd, l, d32)                       \
+CONVERT_INF (NUM##_tfdd, tf, dd, l, d64)                       \
+CONVERT_INF (NUM##_tftd, tf, td, l, d128)
+#endif
+
+#define CONVERT_INF_ALL(NUM)                                   \
+  CONVERT_INF_NOTF(NUM)                                                \
+  CONVERT_INF_TF(NUM)
+
+#define CALL_INF(NUM)                                          \
+  convert_##NUM##_pinf ();                                     \
+  convert_##NUM##_minf ();
+
+#define CALL_INF_NOTF(NUM)                                     \
+  CALL_INF (NUM##_sdsf)                                                \
+  CALL_INF (NUM##_sddf)                                                \
+  CALL_INF (NUM##_ddsf)                                                \
+  CALL_INF (NUM##_dddf)                                                \
+  CALL_INF (NUM##_tdsf)                                                \
+  CALL_INF (NUM##_tddf)                                                \
+  CALL_INF (NUM##_sfsd)                                                \
+  CALL_INF (NUM##_sfdd)                                                \
+  CALL_INF (NUM##_sftd)                                                \
+  CALL_INF (NUM##_dfsd)                                                \
+  CALL_INF (NUM##_dfdd)                                                \
+  CALL_INF (NUM##_dftd)                                                \
+  CALL_INF (NUM##_sddd)                                                \
+  CALL_INF (NUM##_sdtd)                                                \
+  CALL_INF (NUM##_ddsd)                                                \
+  CALL_INF (NUM##_ddtd)                                                \
+  CALL_INF (NUM##_tdsd)                                                \
+  CALL_INF (NUM##_tddd)
+
+#if USE_TF == 0
+#define CALL_INF_TF(NUM)
+#else
+#define CALL_INF_TF(NUM)                                       \
+  CALL_INF (NUM##_sdtf)                                                \
+  CALL_INF (NUM##_ddtf)                                                \
+  CALL_INF (NUM##_tdtf)                                                \
+  CALL_INF (NUM##_tfsd)                                                \
+  CALL_INF (NUM##_tfdd)                                                \
+  CALL_INF (NUM##_tftd)
+#endif
+
+#define CALL_INF_ALL(NUM)                                      \
+  CALL_INF_NOTF(NUM)                                           \
+  CALL_INF_TF(NUM)
+
+#define CONVERT_NAN_NOTF(NUM)                                  \
+CONVERT_NAN (NUM##_sdsf, sd, sf, d32, f)                       \
+CONVERT_NAN (NUM##_sddf, sd, df, d32, )                                \
+CONVERT_NAN (NUM##_ddsf, dd, sf, d64, f)                       \
+CONVERT_NAN (NUM##_dddf, dd, df, d64, )                                \
+CONVERT_NAN (NUM##_tdsf, td, sf, d128, f)                      \
+CONVERT_NAN (NUM##_tddf, td, df, d128, )                       \
+CONVERT_NAN (NUM##_sfsd, sf, sd, f, d32)                       \
+CONVERT_NAN (NUM##_sfdd, sf, dd, f, d64)                       \
+CONVERT_NAN (NUM##_sftd, sf, td, f, d128)                      \
+CONVERT_NAN (NUM##_dfsd, df, sd, , d32)                                \
+CONVERT_NAN (NUM##_dfdd, df, dd, , d64)                                \
+CONVERT_NAN (NUM##_dftd, df, td, , d128)                       \
+CONVERT_NAN (NUM##_sddd, sd, dd, d32, d64)                     \
+CONVERT_NAN (NUM##_sdtd, sd, td, d32, d128)                    \
+CONVERT_NAN (NUM##_ddsd, dd, sd, d64, d32)                     \
+CONVERT_NAN (NUM##_ddtd, dd, td, d64, d128)                    \
+CONVERT_NAN (NUM##_tdsd, td, sd, d128, d32)                    \
+CONVERT_NAN (NUM##_tddd, td, dd, d128, d64)
+
+#if USE_TF == 0
+#define CONVERT_NAN_TF(NUM)
+#else
+#define CONVERT_NAN_TF(NUM)                                    \
+CONVERT_NAN (NUM##_sdtf, sd, tf, d32, l)                       \
+CONVERT_NAN (NUM##_ddtf, dd, tf, d64, l)                       \
+CONVERT_NAN (NUM##_tdtf, td, tf, d128, l)                      \
+CONVERT_NAN (NUM##_tfsd, tf, sd, l, d32)                       \
+CONVERT_NAN (NUM##_tfdd, tf, dd, l, d64)                       \
+CONVERT_NAN (NUM##_tftd, tf, td, l, d128)
+#endif
+
+#define CONVERT_NAN_ALL(NUM)                                   \
+  CONVERT_NAN_NOTF(NUM)                                                \
+  CONVERT_NAN_TF(NUM)
+
+#define CALL_NAN(NUM)                                          \
+  convert_##NUM##_nan ();
+
+#define CALL_NAN_NOTF(NUM)                                     \
+  CALL_NAN (NUM##_sdsf)                                                \
+  CALL_NAN (NUM##_sddf)                                                \
+  CALL_NAN (NUM##_ddsf)                                                \
+  CALL_NAN (NUM##_dddf)                                                \
+  CALL_NAN (NUM##_tdsf)                                                \
+  CALL_NAN (NUM##_tddf)                                                \
+  CALL_NAN (NUM##_sfsd)                                                \
+  CALL_NAN (NUM##_sfdd)                                                \
+  CALL_NAN (NUM##_sftd)                                                \
+  CALL_NAN (NUM##_dfsd)                                                \
+  CALL_NAN (NUM##_dfdd)                                                \
+  CALL_NAN (NUM##_dftd)                                                \
+  CALL_NAN (NUM##_sddd)                                                \
+  CALL_NAN (NUM##_sdtd)                                                \
+  CALL_NAN (NUM##_ddsd)                                                \
+  CALL_NAN (NUM##_ddtd)                                                \
+  CALL_NAN (NUM##_tdsd)                                                \
+  CALL_NAN (NUM##_tddd)
+
+#if USE_TF == 0
+#define CALL_NAN_TF(NUM)
+#else
+#define CALL_NAN_TF(NUM)                                       \
+  CALL_NAN (NUM##_sdtf)                                                \
+  CALL_NAN (NUM##_ddtf)                                                \
+  CALL_NAN (NUM##_tdtf)                                                \
+  CALL_NAN (NUM##_tfsd)                                                \
+  CALL_NAN (NUM##_tfdd)                                                \
+  CALL_NAN (NUM##_tftd)
+#endif
+
+#define CALL_NAN_ALL(NUM)                                      \
+  CALL_NAN_NOTF(NUM)                                           \
+  CALL_NAN_TF(NUM)