Hi Iain, > 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?
I'll give it a try. Here's what I have (I believe it's more readable in some cases), but as I said something's not right yet (probably something very stupid). I'm taking a step back now, going for your original patch with __float128 support added on sparc to have a baseline, than retry both your and my patch afresh. Rainer -- ----------------------------------------------------------------------------- Rainer Orth, Center for Biotechnology, Bielefeld University 2025-04-09 Rainer Orth <r...@cebitec.uni-bielefeld.de> libgcobol: * libgcobol-fp.h (FP128_FMT): Define. [!HAVE_STRTOF128] (strtof128): Provide fallback. * intrinsic.cc [!HAVE_STRTOF128] (strtof128): Remove. (WEIRD_TRANSCENDENT_RETURN_VALUE): Define using GCOB_FP128_LITERAL. * libgcobol.cc [!HAVE_STRFROMF128] (strfromf128): New function. [!HAVE_STRTOF128] (strtof128): Remove. (format_for_display_internal): Always use strfromf128. Construct format string using FP128_FMT.
# HG changeset patch # Parent cce3487b5da0bb5001444ca0948d7cbc6d9a5fbf libgcobol: Support 128-bit IEEE long double diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc --- a/libgcobol/intrinsic.cc +++ b/libgcobol/intrinsic.cc @@ -54,20 +54,11 @@ #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) +#define WEIRD_TRANSCENDENT_RETURN_VALUE GCOB_FP128_LITERAL (0.0) #define NO_RDIGITS (0) struct cobol_tm diff --git a/libgcobol/libgcobol-fp.h b/libgcobol/libgcobol-fp.h --- a/libgcobol/libgcobol-fp.h +++ b/libgcobol/libgcobol-fp.h @@ -27,22 +27,35 @@ see the files COPYING3 and COPYING.RUNTI // Use long double, l suffix on calls, l or L suffix in literals # define GCOB_FP128 long double # define GCOB_FP128_LITERAL(lit) (lit ## l) +# define FP128_FMT "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 _Float128 # define GCOB_FP128_LITERAL(lit) (lit ## f128) +# define FP128_FMT "" # 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 __float128 # define GCOB_FP128_LITERAL(lit) (lit ## q) +# define FP128_FMT "Q" # define FP128_FUNC(funcname) funcname ## q #else # error "libgcobol requires 128b floating point" #endif +#if !defined (HAVE_STRTOF128) +# if USE_QUADMATH +# define strtof128 strtoflt128 +# elif __LDBL_MANT_DIG__ == 113 && __LDBL_MIN_EXP__ == -16381 +# define strtof128 strtold +# else +# error "no available string to float 128" +# endif +#endif + #if USE_QUADMATH /* We will assume that unless we found the 128 to/from string and some representative trig functions, we need libquadmath to support those. */ diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc --- a/libgcobol/libgcobol.cc +++ b/libgcobol/libgcobol.cc @@ -94,17 +94,17 @@ strfromf64 (char *s, size_t n, const cha #endif #if !defined (HAVE_STRFROMF128) -# if !USE_QUADMATH +static int +strfromf128 (char *s, size_t n, const char *f, long double v) +{ +# if USE_QUADMATH + return quadmath_snprintf(s, n, f, v); +# elif __LDBL_MANT_DIG__ == 113 && __LDBL_MIN_EXP__ == -16381 + return snprintf (s, n, f, v); +# else # 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 @@ -3265,11 +3265,7 @@ 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 - quadmath_snprintf(ach, sizeof(ach), "%.36QE", floatval); -#else - strfromf128(ach, sizeof(ach), "%.36E", floatval); -#endif + strfromf128(ach, sizeof(ach), "%.36" FP128_FMT "E", floatval); char *p = strchr(ach, 'E'); if( !p ) { @@ -3291,13 +3287,8 @@ format_for_display_internal(char **dest, int precision = 36 - exp; char achFormat[24]; -#if !defined (HAVE_STRFROMF128) && USE_QUADMATH - sprintf(achFormat, "%%.%dQf", precision); - quadmath_snprintf(ach, sizeof(ach), achFormat, floatval); -#else - sprintf(achFormat, "%%.%df", precision); + sprintf(achFormat, "%%.%d" FP128_FMT "f", precision); strfromf128(ach, sizeof(ach), achFormat, floatval); -#endif } __gg__remove_trailing_zeroes(ach); __gg__realloc_if_necessary(dest, dest_size, strlen(ach)+1);