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);

Reply via email to