aboutsummaryrefslogtreecommitdiff
path: root/libgcc/config/rs6000
diff options
context:
space:
mode:
authorMichael Meissner <meissner@linux.ibm.com>2021-02-22 15:33:29 -0500
committerMichael Meissner <meissner@linux.ibm.com>2021-02-22 15:33:29 -0500
commit781183595acba67a37c66f59a0c1d9b5fee7e248 (patch)
treeaebce9b934a865fdd62b1307093b2b7cd0c14fa2 /libgcc/config/rs6000
parent8e99b5ba4c19526335fe9cabdc6df7fb2edcfe6f (diff)
downloadgcc-781183595acba67a37c66f59a0c1d9b5fee7e248.zip
gcc-781183595acba67a37c66f59a0c1d9b5fee7e248.tar.gz
gcc-781183595acba67a37c66f59a0c1d9b5fee7e248.tar.bz2
Add conversions between _Float128 and Decimal.
This patch implements conversions between _Float128 and the 3 Decimal floating types. It does this by extendending the dfp-bit conversions to add a new binary floating point type (KF), and doing the conversions in the same manner as the other binary/decimal conversions. For conversions from _Float128 to Decimal, this patch uses a function (__sprintfkf) instead of the sprintf function to convert long double values to strings. The __sprintfkf function determines if GLIBC 2.32 or newer is used and calls the IEEE 128-bit version of sprintf (__sprintfieee128). If the GLIBC is earlier than 2.32, the code will convert _Float128 to __ibm128 and then use the normal sprintf to convert this value. For conversions from Decimal to _Float128, this patch uses a function (__strtokf) instead of strtold to convert the strings from the Decimal conversion to long double. The __strtokf function determines if GLIBC 2.32 or newer is used, and if it is, calls the IEEE 128-bit version (__strtoieee128). If the GLIBC is earlier than 2.32, the code will call strtold and convert the __ibm128 value to _Float128. These functions will primarily be used if/when the default PowerPC long double type is changed to IEEE 128-bit, but they could also be used if the user explicitly converts _Float128 to/from a Decimal type. libgcc/ 2021-02-22 Michael Meissner <meissner@linux.ibm.com> * config/rs6000/_dd_to_kf.c: New file. * config/rs6000/_kf_to_dd.c: New file. * config/rs6000/_kf_to_sd.c: New file. * config/rs6000/_kf_to_td.c: New file. * config/rs6000/_sd_to_kf.c: New file. * config/rs6000/_sprintfkf.c: New file. * config/rs6000/_sprintfkf.h: New file. * config/rs6000/_strtokf.h: New file. * config/rs6000/_strtokf.c: New file. * config/rs6000/_td_to_kf.c: New file. * config/rs6000/quad-float128.h: Add new declarations. * config/rs6000/t-float128 (fp128_dec_funcs): New macro. (fp128_decstr_funcs): New macro. (ibm128_dec_funcs): New macro. (fp128_ppc_funcs): Add the new conversions. (fp128_dec_objs): Force Decimal <-> __float128 conversions to be compiled with -mabi=ieeelongdouble. (fp128_decstr_objs): Force __float128 <-> string conversions to be compiled with -mabi=ibmlongdouble. (ibm128_dec_objs): Force Decimal <-> __float128 conversions to be compiled with -mabi=ieeelongdouble. (FP128_CFLAGS_DECIMAL): New macro. (IBM128_CFLAGS_DECIMAL): New macro. * dfp-bit.c (DFP_TO_BFP): Add PowerPC _Float128 support. (BFP_TO_DFP): Add PowerPC _Float128 support. * dfp-bit.h (BFP_KIND): Add new binary floating point kind for IEEE 128-bit floating point. (DFP_TO_BFP): Add PowerPC _Float128 support. (BFP_TO_DFP): Add PowerPC _Float128 support. (BFP_SPRINTF): New macro.
Diffstat (limited to 'libgcc/config/rs6000')
-rw-r--r--libgcc/config/rs6000/_dd_to_kf.c37
-rw-r--r--libgcc/config/rs6000/_kf_to_dd.c37
-rw-r--r--libgcc/config/rs6000/_kf_to_sd.c37
-rw-r--r--libgcc/config/rs6000/_kf_to_td.c37
-rw-r--r--libgcc/config/rs6000/_sd_to_kf.c37
-rw-r--r--libgcc/config/rs6000/_sprintfkf.c57
-rw-r--r--libgcc/config/rs6000/_sprintfkf.h28
-rw-r--r--libgcc/config/rs6000/_strtokf.c53
-rw-r--r--libgcc/config/rs6000/_strtokf.h27
-rw-r--r--libgcc/config/rs6000/_td_to_kf.c37
-rw-r--r--libgcc/config/rs6000/quad-float128.h8
-rw-r--r--libgcc/config/rs6000/t-float12837
12 files changed, 431 insertions, 1 deletions
diff --git a/libgcc/config/rs6000/_dd_to_kf.c b/libgcc/config/rs6000/_dd_to_kf.c
new file mode 100644
index 0000000..6613c44
--- /dev/null
+++ b/libgcc/config/rs6000/_dd_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* Decimal64 -> _Float128 conversion. */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to dd_to_tf conversion
+ function from dp-bits.c. */
+#define FINE_GRAINED_LIBRARIES 1
+#define L_dd_to_kf 1
+#define WIDTH 64
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work. */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_dd.c b/libgcc/config/rs6000/_kf_to_dd.c
new file mode 100644
index 0000000..93a1043
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_dd.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* _Float128 -> Decimal64 conversion. */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_dd conversion
+ function from dp-bits.c. */
+#define FINE_GRAINED_LIBRARIES 1
+#define L_kf_to_dd 1
+#define WIDTH 64
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work. */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_sd.c b/libgcc/config/rs6000/_kf_to_sd.c
new file mode 100644
index 0000000..01396da
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_sd.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* _Float128 -> Decimal32 conversion. */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_sd conversion
+ function from dp-bits.c. */
+#define FINE_GRAINED_LIBRARIES 1
+#define L_kf_to_sd 1
+#define WIDTH 32
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work. */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_kf_to_td.c b/libgcc/config/rs6000/_kf_to_td.c
new file mode 100644
index 0000000..45bba92
--- /dev/null
+++ b/libgcc/config/rs6000/_kf_to_td.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* _Float128 -> Decimal128 conversion. */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_td conversion
+ function from dp-bits.c. */
+#define FINE_GRAINED_LIBRARIES 1
+#define L_kf_to_td 1
+#define WIDTH 128
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work. */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_sd_to_kf.c b/libgcc/config/rs6000/_sd_to_kf.c
new file mode 100644
index 0000000..9224444
--- /dev/null
+++ b/libgcc/config/rs6000/_sd_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* Decimal32 -> _Float128 conversion. */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to sd_to_tf conversion
+ function from dp-bits.c. */
+#define FINE_GRAINED_LIBRARIES 1
+#define L_sd_to_kf 1
+#define WIDTH 32
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work. */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/_sprintfkf.c b/libgcc/config/rs6000/_sprintfkf.c
new file mode 100644
index 0000000..a7fdfb4
--- /dev/null
+++ b/libgcc/config/rs6000/_sprintfkf.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* Conversion to IEEE 128-bit floating point from string using snprintf. */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad-float128.h>
+#include <stdio.h>
+
+/* This function must be built with IBM 128-bit as long double, so that we can
+ access the strfroml function if do not have an IEEE 128-bit version, and if
+ that is not available, use sprintf. */
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IBM128__)
+#error "Long double is not IBM 128-bit"
+#endif
+
+/* If the user is using GLIBC 2.32, we can use the __snprintfieee128 function.
+
+ If we are linked against an earlier library, we will have fake it by
+ converting the value to long double, and using sprintf to do the conversion.
+ This isn't ideal, as IEEE 128-bit has more exponent range than IBM
+ 128-bit. */
+
+extern int __sprintfieee128 (char *restrict, const char *restrict, ...)
+ __attribute__ ((__weak__));
+
+int __sprintfkf (char *restrict string,
+ const char *restrict format,
+ _Float128 number)
+{
+ if (__sprintfieee128)
+ return __sprintfieee128 (string, format, number);
+
+ return sprintf (string, format, (long double) number);
+}
diff --git a/libgcc/config/rs6000/_sprintfkf.h b/libgcc/config/rs6000/_sprintfkf.h
new file mode 100644
index 0000000..637d104
--- /dev/null
+++ b/libgcc/config/rs6000/_sprintfkf.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* Declaration of the conversion function to IEEE 128-bit floating point from
+ string using snprintf. */
+
+extern int __sprintfkf (char *restrict, const char *restrict, ...);
+
diff --git a/libgcc/config/rs6000/_strtokf.c b/libgcc/config/rs6000/_strtokf.c
new file mode 100644
index 0000000..dc13534
--- /dev/null
+++ b/libgcc/config/rs6000/_strtokf.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* Conversion to IEEE 128-bit floating point from string. */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad-float128.h>
+
+/* This function must be built with IBM 128-bit as long double, so that we can
+ access the strtold function if do not have an IEEE 128-bit version. */
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IBM128__)
+#error "Long double is not IBM 128-bit"
+#endif
+
+/* If the user is using GLIBC 2.32, we can use the __strtoieee128 function.
+
+ If we are linked against an earlier library, we will have fake it by
+ converting the string to IBM 128-bit long double, and then converting that to
+ __float128. This isn't ideal, as IEEE 128-bit has more exponent range than
+ IBM 128-bit. */
+
+extern _Float128 __strtoieee128 (const char *, char **) __attribute__ ((__weak__));
+
+_Float128
+__strtokf (const char *string, char **endptr)
+{
+ if (__strtoieee128)
+ return __strtoieee128 (string, endptr);
+
+ return strtold (string, endptr);
+}
diff --git a/libgcc/config/rs6000/_strtokf.h b/libgcc/config/rs6000/_strtokf.h
new file mode 100644
index 0000000..a7ca8e0
--- /dev/null
+++ b/libgcc/config/rs6000/_strtokf.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* Declaration of the conversion function to IEEE 128-bit floating point from
+ string. */
+
+extern _Float128 __strtokf (const char *, char **);
diff --git a/libgcc/config/rs6000/_td_to_kf.c b/libgcc/config/rs6000/_td_to_kf.c
new file mode 100644
index 0000000..0134581
--- /dev/null
+++ b/libgcc/config/rs6000/_td_to_kf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* Decimal128 -> _Float128 conversion. */
+
+/* FINE_GRAINED_LIBRARIES is used so we can isolate just to td_to_tf conversion
+ function from dp-bits.c. */
+#define FINE_GRAINED_LIBRARIES 1
+#define L_td_to_kf 1
+#define WIDTH 128
+
+#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__)
+#error "Long double is not IEEE 128-bit"
+#endif
+
+/* Use dfp-bit.c to do the real work. */
+#include "dfp-bit.c"
diff --git a/libgcc/config/rs6000/quad-float128.h b/libgcc/config/rs6000/quad-float128.h
index 0eb1d34..5beb153 100644
--- a/libgcc/config/rs6000/quad-float128.h
+++ b/libgcc/config/rs6000/quad-float128.h
@@ -49,6 +49,7 @@ typedef __complex float TCtype __attribute__ ((mode (TC)));
#pragma GCC target ("vsx,float128")
#endif
+#include <stddef.h>
#include <quad.h>
#define IBM128_TYPE __ibm128
@@ -171,6 +172,13 @@ extern TFtype __trunctfkf2 (IBM128_TYPE);
extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype);
extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype);
+/* Convert IEEE 128-bit floating point to/from string. We explicitly use
+ _Float128 instead of TFmode because _strtokf and _strfromkf must be compiled
+ with long double being IBM 128. */
+extern _Float128 __strtokf (const char *, char **);
+extern int __strfromkf (char *restrict, size_t, const char *restrict,
+ _Float128);
+
/* Implementation of conversions between __ibm128 and __float128, to allow the
same code to be used on systems with IEEE 128-bit emulation and with IEEE
128-bit hardware support. */
diff --git a/libgcc/config/rs6000/t-float128 b/libgcc/config/rs6000/t-float128
index d541344..6fb1a3d 100644
--- a/libgcc/config/rs6000/t-float128
+++ b/libgcc/config/rs6000/t-float128
@@ -22,10 +22,23 @@ fp128_softfp_static_obj = $(addsuffix -sw$(objext),$(fp128_softfp_funcs))
fp128_softfp_shared_obj = $(addsuffix -sw_s$(objext),$(fp128_softfp_funcs))
fp128_softfp_obj = $(fp128_softfp_static_obj) $(fp128_softfp_shared_obj)
+# Decimal <-> _Float128 conversions
+fp128_dec_funcs = _kf_to_sd _kf_to_dd _kf_to_td \
+ _sd_to_kf _dd_to_kf _td_to_kf
+
+# _Float128 to/from string conversions that must be compiled with IBM 128-bit
+# long double.
+fp128_decstr_funcs = _strtokf _sprintfkf
+
+# Decimal <-> __ibm128 conversions
+ibm128_dec_funcs = _tf_to_sd _tf_to_dd _tf_to_td \
+ _sd_to_tf _dd_to_tf _td_to_tf
+
# New functions for software emulation
fp128_ppc_funcs = floattikf floatuntikf fixkfti fixunskfti \
extendkftf2-sw trunctfkf2-sw \
- sfp-exceptions _mulkc3 _divkc3 _powikf2
+ sfp-exceptions _mulkc3 _divkc3 _powikf2 \
+ $(fp128_dec_funcs) $(fp128_decstr_funcs)
fp128_ppc_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \
.c,$(fp128_ppc_funcs)))
@@ -69,6 +82,28 @@ $(fp128_ppc_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW)
$(fp128_obj) : $(fp128_includes)
$(fp128_obj) : $(srcdir)/config/rs6000/quad-float128.h
+# Force the TF mode to/from decimal functions to be compiled with IBM long
+# double. Add building the KF mode to/from decimal conversions with explict
+# IEEE long double.
+fp128_dec_objs = $(addsuffix $(objext),$(fp128_dec_funcs)) \
+ $(addsuffix _s$(objext),$(fp128_dec_funcs))
+
+fp128_decstr_objs = $(addsuffix $(objext),$(fp128_decstr_funcs)) \
+ $(addsuffix _s$(objext),$(fp128_decstr_funcs))
+
+ibm128_dec_objs = $(addsuffix $(objext),$(ibm128_dec_funcs)) \
+ $(addsuffix _s$(objext),$(ibm128_dec_funcs))
+
+FP128_CFLAGS_DECIMAL = -mno-gnu-attribute -Wno-psabi -mabi=ieeelongdouble
+IBM128_CFLAGS_DECIMAL = -mno-gnu-attribute -Wno-psabi -mabi=ibmlongdouble
+
+$(fp128_dec_objs) : INTERNAL_CFLAGS += $(FP128_CFLAGS_DECIMAL)
+$(fp128_decstr_objs) : INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL)
+$(ibm128_dec_objs) : INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL)
+
+$(fp128_decstr_objs) : $(srcdir)/config/rs6000/_strtokf.h \
+ $(srcdir)/config/rs6000/_sprintfkf.h \
+
$(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@)) $(fp128_dep)
@src="$(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@))"; \
echo "Create $@"; \