From f3d110ef046e4dd98a82ba8a6365427181c16b1e Mon Sep 17 00:00:00 2001 From: Janis Johnson Date: Tue, 11 Sep 2007 01:11:16 +0000 Subject: [PATCH] re PR c/30013 (Multiple flaws in decimal floating-point arithmetic conversions fixed) gcc/ 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. From-SVN: r128361 --- gcc/ChangeLog | 22 ++ gcc/config/dfp-bit.c | 28 +- gcc/config/dfp-bit.h | 78 +++- gcc/doc/libgcc.texi | 12 + gcc/testsuite/ChangeLog | 15 + gcc/testsuite/gcc.dg/dfp/convert-bfp-10.c | 114 ++++++ gcc/testsuite/gcc.dg/dfp/convert-bfp-11.c | 61 +++ gcc/testsuite/gcc.dg/dfp/convert-bfp-2.c | 37 ++ gcc/testsuite/gcc.dg/dfp/convert-bfp-3.c | 25 ++ gcc/testsuite/gcc.dg/dfp/convert-bfp-4.c | 25 ++ gcc/testsuite/gcc.dg/dfp/convert-bfp-5.c | 25 ++ gcc/testsuite/gcc.dg/dfp/convert-bfp-6.c | 179 +++++++++ gcc/testsuite/gcc.dg/dfp/convert-bfp-7.c | 85 ++++ gcc/testsuite/gcc.dg/dfp/convert-bfp-8.c | 73 ++++ gcc/testsuite/gcc.dg/dfp/convert-bfp-9.c | 193 +++++++++ gcc/testsuite/gcc.dg/dfp/convert-bfp.c | 54 +-- gcc/testsuite/gcc.dg/dfp/convert.h | 461 ++++++++++++++++++++++ 17 files changed, 1426 insertions(+), 61 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/dfp/convert-bfp-10.c create mode 100644 gcc/testsuite/gcc.dg/dfp/convert-bfp-11.c create mode 100644 gcc/testsuite/gcc.dg/dfp/convert-bfp-2.c create mode 100644 gcc/testsuite/gcc.dg/dfp/convert-bfp-3.c create mode 100644 gcc/testsuite/gcc.dg/dfp/convert-bfp-4.c create mode 100644 gcc/testsuite/gcc.dg/dfp/convert-bfp-5.c create mode 100644 gcc/testsuite/gcc.dg/dfp/convert-bfp-6.c create mode 100644 gcc/testsuite/gcc.dg/dfp/convert-bfp-7.c create mode 100644 gcc/testsuite/gcc.dg/dfp/convert-bfp-8.c create mode 100644 gcc/testsuite/gcc.dg/dfp/convert-bfp-9.c create mode 100644 gcc/testsuite/gcc.dg/dfp/convert.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 223e8fe90c3..2ed812ce9b5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2007-09-10 Janis Johnson + + 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 * config/mips/mips.c (mips_scalar_mode_supported_p): Declare. diff --git a/gcc/config/dfp-bit.c b/gcc/config/dfp-bit.c index 6a1bc30a21a..8ee4dec6f44 100644 --- a/gcc/config/dfp-bit.c +++ b/gcc/config/dfp-bit.c @@ -34,16 +34,11 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA Contributed by Ben Elliston . */ -/* 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 #include +/* 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 #include @@ -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 diff --git a/gcc/config/dfp-bit.h b/gcc/config/dfp-bit.h index 7c4738760ed..27c6a8a26c7 100644 --- a/gcc/config/dfp-bit.h +++ b/gcc/config/dfp-bit.h @@ -30,6 +30,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #ifndef _DFPBIT_H #define _DFPBIT_H +#include #include #include #include @@ -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 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 diff --git a/gcc/doc/libgcc.texi b/gcc/doc/libgcc.texi index 161cfc6cbe4..e977b24de05 100644 --- a/gcc/doc/libgcc.texi +++ b/gcc/doc/libgcc.texi @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aca143371ff..bce206ebb60 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2007-09-10 Janis Johnson + + * 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 * 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 index 00000000000..dec7b515fcf --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-10.c @@ -0,0 +1,114 @@ +/* { dg-options "-std=gnu99" } */ + +/* This test assumes IEEE float and double. */ + +#define __STDC_WANT_DEC_FP__ +#include + +#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 index 00000000000..283f9bd4f88 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-11.c @@ -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 index 00000000000..28273512005 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-2.c @@ -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 index 00000000000..67d31c33ac9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-3.c @@ -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 index 00000000000..feba37a9eae --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-4.c @@ -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 index 00000000000..cfb86fd015d --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-5.c @@ -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 index 00000000000..6dc2a9e720e --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-6.c @@ -0,0 +1,179 @@ +/* { dg-options "-std=gnu99 -w" } */ + +/* This test assumes IEEE float and double. */ + +#define __STDC_WANT_DEC_FP__ +#include + +#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 index 00000000000..0fb4f076d25 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-7.c @@ -0,0 +1,85 @@ +/* { dg-options "-std=gnu99 -w" } */ + +/* This test assumes IEEE float and double. */ + +#define __STDC_WANT_DEC_FP__ +#include + +#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 index 00000000000..269fc37f208 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-8.c @@ -0,0 +1,73 @@ +/* { dg-options "-std=gnu99 -w" } */ + +/* This test assumes IEEE float and double. */ + +#define __STDC_WANT_DEC_FP__ +#include + +#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 index 00000000000..86ae4303034 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp-9.c @@ -0,0 +1,193 @@ +/* { dg-options "-std=gnu99 -w" } */ + +/* This test assumes IEEE float and double. */ + +#define __STDC_WANT_DEC_FP__ +#include + +#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; +} diff --git a/gcc/testsuite/gcc.dg/dfp/convert-bfp.c b/gcc/testsuite/gcc.dg/dfp/convert-bfp.c index c65210fe0b9..b2e8ca87b16 100644 --- a/gcc/testsuite/gcc.dg/dfp/convert-bfp.c +++ b/gcc/testsuite/gcc.dg/dfp/convert-bfp.c @@ -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 index 00000000000..bc9ef42f4dd --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/convert.h @@ -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 +#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)