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)

Reply via email to