aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/src/c++17
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/src/c++17')
-rw-r--r--libstdc++-v3/src/c++17/Makefile.am7
-rw-r--r--libstdc++-v3/src/c++17/Makefile.in11
-rw-r--r--libstdc++-v3/src/c++17/floating_from_chars.cc38
3 files changed, 54 insertions, 2 deletions
diff --git a/libstdc++-v3/src/c++17/Makefile.am b/libstdc++-v3/src/c++17/Makefile.am
index 642efb9..37cdb53 100644
--- a/libstdc++-v3/src/c++17/Makefile.am
+++ b/libstdc++-v3/src/c++17/Makefile.am
@@ -61,6 +61,13 @@ vpath % $(top_srcdir)/src/c++17
libc__17convenience_la_SOURCES = $(sources) $(inst_sources)
+if GLIBCXX_LDBL_ALT128_COMPAT
+floating_from_chars.lo: floating_from_chars.cc
+ $(LTCXXCOMPILE) -mabi=ibmlongdouble $(LONG_DOUBLE_128_FLAGS) -c $<
+floating_from_chars.o: floating_from_chars.cc
+ $(CXXCOMPILE) -mabi=ibmlongdouble $(LONG_DOUBLE_128_FLAGS) -c $<
+endif
+
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
# modified in a per-library or per-sub-library way. Need to manually
# set this option because CONFIG_CXXFLAGS has to be after
diff --git a/libstdc++-v3/src/c++17/Makefile.in b/libstdc++-v3/src/c++17/Makefile.in
index ce08eb3..ccae721 100644
--- a/libstdc++-v3/src/c++17/Makefile.in
+++ b/libstdc++-v3/src/c++17/Makefile.in
@@ -262,6 +262,8 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LONG_DOUBLE_128_FLAGS = @LONG_DOUBLE_128_FLAGS@
+LONG_DOUBLE_ALT128_COMPAT_FLAGS = @LONG_DOUBLE_ALT128_COMPAT_FLAGS@
LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
LTLIBICONV = @LTLIBICONV@
LTLIBOBJS = @LTLIBOBJS@
@@ -401,11 +403,13 @@ toolexeclibdir = $(glibcxx_toolexeclibdir)
@ENABLE_WERROR_TRUE@WERROR_FLAG = -Werror
@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
+@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@LDBL_128_FLAGS =
+@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@LDBL_128_FLAGS = $(LONG_DOUBLE_128_FLAGS)
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
CONFIG_CXXFLAGS = \
- $(SECTION_FLAGS) $(HWCAP_CFLAGS) -frandom-seed=$@
+ $(SECTION_FLAGS) $(HWCAP_CFLAGS) -frandom-seed=$@ $(LDBL_128_FLAGS)
WARN_CXXFLAGS = \
$(WARN_FLAGS) $(WERROR_FLAG) -fdiagnostics-show-location=once
@@ -752,6 +756,11 @@ uninstall-am:
vpath % $(top_srcdir)/src/c++17
+@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@floating_from_chars.lo: floating_from_chars.cc
+@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ $(LTCXXCOMPILE) -mabi=ibmlongdouble $(LONG_DOUBLE_128_FLAGS) -c $<
+@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@floating_from_chars.o: floating_from_chars.cc
+@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ $(CXXCOMPILE) -mabi=ibmlongdouble $(LONG_DOUBLE_128_FLAGS) -c $<
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/libstdc++-v3/src/c++17/floating_from_chars.cc b/libstdc++-v3/src/c++17/floating_from_chars.cc
index c279809..a194335 100644
--- a/libstdc++-v3/src/c++17/floating_from_chars.cc
+++ b/libstdc++-v3/src/c++17/floating_from_chars.cc
@@ -44,6 +44,14 @@
# include <xlocale.h>
#endif
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+#ifndef __LONG_DOUBLE_IBM128__
+#error "floating_from_chars.cc must be compiled with -mabi=ibmlongdouble"
+#endif
+// strtold for __ieee128
+extern "C" __ieee128 __strtoieee128(const char*, char**);
+#endif
+
#if _GLIBCXX_HAVE_USELOCALE
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -316,6 +324,10 @@ namespace
tmpval = std::strtod(str, &endptr);
else if constexpr (is_same_v<T, long double>)
tmpval = std::strtold(str, &endptr);
+# ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+ else if constexpr (is_same_v<T, __ieee128>)
+ tmpval = __strtoieee128(str, &endptr);
+# endif
#else
tmpval = std::strtod(str, &endptr);
#endif
@@ -332,7 +344,7 @@ namespace
const ptrdiff_t n = endptr - str;
if (conv_errno == ERANGE) [[unlikely]]
{
- if (isinf(tmpval)) // overflow
+ if (__builtin_isinf(tmpval)) // overflow
ec = errc::result_out_of_range;
else // underflow (LWG 3081 wants to set value = tmpval here)
ec = errc::result_out_of_range;
@@ -469,6 +481,8 @@ from_chars(const char* first, const char* last, long double& value,
}
#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
+// Make std::from_chars for 64-bit long double an alias for the overload
+// for double.
extern "C" from_chars_result
_ZSt10from_charsPKcS0_ReSt12chars_format(const char* first, const char* last,
long double& value,
@@ -476,6 +490,28 @@ _ZSt10from_charsPKcS0_ReSt12chars_format(const char* first, const char* last,
__attribute__((alias ("_ZSt10from_charsPKcS0_RdSt12chars_format")));
#endif
+#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
+from_chars_result
+from_chars(const char* first, const char* last, __ieee128& value,
+ chars_format fmt) noexcept
+{
+ buffer_resource mr;
+ pmr::string buf(&mr);
+ size_t len = 0;
+ errc ec = errc::invalid_argument;
+ __try
+ {
+ if (const char* pat = pattern(first, last, fmt, buf)) [[likely]]
+ len = from_chars_impl(pat, value, ec);
+ }
+ __catch (const std::bad_alloc&)
+ {
+ fmt = chars_format{};
+ }
+ return make_result(first, len, fmt, ec);
+}
+#endif
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // _GLIBCXX_HAVE_USELOCALE