Here is what I'm testing as an incremental fix, so far OK on x86_64-darwin and powerpcle64 (GLIBC 2.34) .. others in progress. Does it help the Solaris cases?
--- 8< --- In some cases, we might be able to use strtold and snprintf for 128b IEEE754 (when the long double format agrees). libgcobol/ChangeLog: * intrinsic.cc (strtof128): Move handling to libgcobol-fp.h. (WEIRD_TRANSCENDENT_RETURN_VALUE): Handle F128, Q and L as suffixes. * libgcobol-fp.h (GCOB_FP128_LD, GCOB_FP128_F128, GCOB_FP128_Q): New. HAVE_STRTOF128, HAVE_STRTOF128: Handle long double as well as __float128. * libgcobol.cc: MOve handling of HAVE_STRTOF128 and HAVE_STRTOF128 to libgcobol-fp.h (format_for_display_internal): Handle long double as an alternate IEEE754 128b float. Signed-off-by: Iain Sandoe <i...@sandoe.co.uk> --- libgcobol/intrinsic.cc | 19 +++++++++---------- libgcobol/libgcobol-fp.h | 19 +++++++++++++++++++ libgcobol/libgcobol.cc | 31 +++++++++++++++---------------- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc index 9953b341488..e27107109e4 100644 --- a/libgcobol/intrinsic.cc +++ b/libgcobol/intrinsic.cc @@ -54,20 +54,19 @@ #include "libgcobol.h" #include "charmaps.h" - -#if !defined (HAVE_STRTOF128) -# if USE_QUADMATH -# define strtof128 strtoflt128 -# else -# error "no available string to float 128" -# endif -#endif - #pragma GCC diagnostic ignored "-Wformat-truncation" #define JD_OF_1601_01_02 2305812.5 -#define WEIRD_TRANSCENDENT_RETURN_VALUE (0.0Q) +#if defined (GCOB_FP128_LD) +# define WEIRD_TRANSCENDENT_RETURN_VALUE (0.0L) +#elif defined (GCOB_FP128_F128) +# define WEIRD_TRANSCENDENT_RETURN_VALUE (0.0F128) +#elif defined (GCOB_FP128_Q) +# define WEIRD_TRANSCENDENT_RETURN_VALUE (0.0Q) +#else +# define WEIRD_TRANSCENDENT_RETURN_VALUE (0.0) +#endif #define NO_RDIGITS (0) struct cobol_tm diff --git a/libgcobol/libgcobol-fp.h b/libgcobol/libgcobol-fp.h index bd443f3a234..f9f67fd6178 100644 --- a/libgcobol/libgcobol-fp.h +++ b/libgcobol/libgcobol-fp.h @@ -25,17 +25,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if __LDBL_MANT_DIG__ == 113 && __LDBL_MIN_EXP__ == -16381 // Use long double, l suffix on calls, l or L suffix in literals +# define GCOB_FP128_LD # define GCOB_FP128 long double # define GCOB_FP128_LITERAL(lit) (lit ## l) # define FP128_FUNC(funcname) funcname ## l #elif __FLT128_MANT_DIG__ == 113 && __FLT128_MIN_EXP__ == -16381 \ && defined(USE_IEC_60559) // Use _Float128, f128 suffix on calls, f128 or F128 suffix on literals +# define GCOB_FP128_F128 # define GCOB_FP128 _Float128 # define GCOB_FP128_LITERAL(lit) (lit ## f128) # define FP128_FUNC(funcname) funcname ## f128 #elif __FLT128_MANT_DIG__ == 113 && __FLT128_MIN_EXP__ == -16381 // Use __float128, q suffix on calls, q or Q suffix on literals +# define GCOB_FP128_Q # define GCOB_FP128 __float128 # define GCOB_FP128_LITERAL(lit) (lit ## q) # define FP128_FUNC(funcname) funcname ## q @@ -48,3 +51,19 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see representative trig functions, we need libquadmath to support those. */ # include "quadmath.h" #endif + +#if !defined (HAVE_STRTOF128) +# if USE_QUADMATH +# define strtof128 strtoflt128 +# elif defined (GCOB_FP128_LD) +# define strtof128 strtold +# else +# error "no available string to float 128" +# endif +#endif + +#if !defined (HAVE_STRFROMF128) +# if ! defined (USE_QUADMATH) && !defined (GCOB_FP128_LD) +# error "no available float 128 to string" +# endif +#endif diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc index b907b67e9bc..8853b95abf6 100644 --- a/libgcobol/libgcobol.cc +++ b/libgcobol/libgcobol.cc @@ -93,20 +93,6 @@ strfromf64 (char *s, size_t n, const char *f, double v) # endif #endif -#if !defined (HAVE_STRFROMF128) -# if !USE_QUADMATH -# error "no available float 128 to string" -# endif -#endif - -#if !defined (HAVE_STRTOF128) -# if USE_QUADMATH -# define strtof128 strtoflt128 -# else -# error "no available string to float 128" -# endif -#endif - // This couldn't be defined in symbols.h because it conflicts with a LEVEL66 // in parse.h #define LEVEL66 (66) @@ -3265,8 +3251,14 @@ format_for_display_internal(char **dest, // on a 16-bit boundary. GCOB_FP128 floatval; memcpy(&floatval, actual_location, 16); -#if !defined (HAVE_STRFROMF128) && USE_QUADMATH +#if !defined (HAVE_STRFROMF128) +# if defined (GCOB_FP128_LD) + snprintf(ach, sizeof(ach), "%.36LE", floatval); +# elif defined (USE_QUADMATH) quadmath_snprintf(ach, sizeof(ach), "%.36QE", floatval); +# else +# error "no supported print for 128b floats" +# endif #else strfromf128(ach, sizeof(ach), "%.36E", floatval); #endif @@ -3291,9 +3283,16 @@ format_for_display_internal(char **dest, int precision = 36 - exp; char achFormat[24]; -#if !defined (HAVE_STRFROMF128) && USE_QUADMATH +#if !defined (HAVE_STRFROMF128) +# if defined (GCOB_FP128_LD) + sprintf(achFormat, "%%.%dLf", precision); + snprintf(ach, sizeof(ach), achFormat, floatval); +# elif defined (USE_QUADMATH) sprintf(achFormat, "%%.%dQf", precision); quadmath_snprintf(ach, sizeof(ach), achFormat, floatval); +# else +# error "no supported print for 128b floats" +# endif #else sprintf(achFormat, "%%.%df", precision); strfromf128(ach, sizeof(ach), achFormat, floatval); -- 2.39.2 (Apple Git-143)