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 <[email protected]>
---
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)