PowerPC: Add IEEE 128-bit <-> Decimal conversions. This patch adds the basic support for converting between IEEE 128-bit floating point and Decimal types.
libgcc/ 2020-09-23 Michael Meissner <meiss...@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/_td_to_kf.c: New file. * config/rs6000/t-float128: Build __floating conversions to/from Decimal support functions. By default compile with long double being IBM extended double. * dfp-bit.c: Add support for building the PowerPC _Float128 to/from Decimal conversion functions. * dfp-bit.h: Likewise. --- libgcc/config/rs6000/_dd_to_kf.c | 30 ++++++++++++++++++++++++++ libgcc/config/rs6000/_kf_to_dd.c | 30 ++++++++++++++++++++++++++ libgcc/config/rs6000/_kf_to_sd.c | 30 ++++++++++++++++++++++++++ libgcc/config/rs6000/_kf_to_td.c | 30 ++++++++++++++++++++++++++ libgcc/config/rs6000/_sd_to_kf.c | 30 ++++++++++++++++++++++++++ libgcc/config/rs6000/_td_to_kf.c | 30 ++++++++++++++++++++++++++ libgcc/config/rs6000/t-float128 | 30 +++++++++++++++++++++++++- libgcc/dfp-bit.c | 10 +++++++-- libgcc/dfp-bit.h | 37 +++++++++++++++++++++++++++++--- 9 files changed, 251 insertions(+), 6 deletions(-) create mode 100644 libgcc/config/rs6000/_dd_to_kf.c create mode 100644 libgcc/config/rs6000/_kf_to_dd.c create mode 100644 libgcc/config/rs6000/_kf_to_sd.c create mode 100644 libgcc/config/rs6000/_kf_to_td.c create mode 100644 libgcc/config/rs6000/_sd_to_kf.c create mode 100644 libgcc/config/rs6000/_td_to_kf.c diff --git a/libgcc/config/rs6000/_dd_to_kf.c b/libgcc/config/rs6000/_dd_to_kf.c new file mode 100644 index 00000000000..081415fd393 --- /dev/null +++ b/libgcc/config/rs6000/_dd_to_kf.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1989-2020 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. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_dd_to_kf 1 +#define WIDTH 64 + +/* 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 00000000000..09a62cbe629 --- /dev/null +++ b/libgcc/config/rs6000/_kf_to_dd.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1989-2020 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. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_kf_to_dd 1 +#define WIDTH 64 + +/* 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 00000000000..f35b68eb4d9 --- /dev/null +++ b/libgcc/config/rs6000/_kf_to_sd.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1989-2020 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. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_kf_to_sd 1 +#define WIDTH 32 + +/* 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 00000000000..d35d09ed848 --- /dev/null +++ b/libgcc/config/rs6000/_kf_to_td.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1989-2020 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. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_kf_to_td 1 +#define WIDTH 128 + +/* 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 00000000000..9396b71f162 --- /dev/null +++ b/libgcc/config/rs6000/_sd_to_kf.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1989-2020 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. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_sd_to_kf 1 +#define WIDTH 32 + +/* Use dfp-bit.c to do the real work. */ +#include "dfp-bit.c" diff --git a/libgcc/config/rs6000/_td_to_kf.c b/libgcc/config/rs6000/_td_to_kf.c new file mode 100644 index 00000000000..fade2a28859 --- /dev/null +++ b/libgcc/config/rs6000/_td_to_kf.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1989-2020 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. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_td_to_kf 1 +#define WIDTH 128 + +/* Use dfp-bit.c to do the real work. */ +#include "dfp-bit.c" diff --git a/libgcc/config/rs6000/t-float128 b/libgcc/config/rs6000/t-float128 index d5413445189..3d6054c6a54 100644 --- a/libgcc/config/rs6000/t-float128 +++ b/libgcc/config/rs6000/t-float128 @@ -22,10 +22,15 @@ 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 + # 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_ppc_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \ .c,$(fp128_ppc_funcs))) @@ -69,6 +74,29 @@ $(fp128_ppc_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW) $(fp128_obj) : $(fp128_includes) $(fp128_obj) : $(srcdir)/config/rs6000/quad-float128.h + +# If we are switching the default long double type, we need to use +# -mno-gnu-attribute so that the __ibm128 support functions don't signal a +# linker error since the default long double is now IEEE 128-bit instead of IBM +# 128-bit. +ibm-ldouble$(objext) : INTERNAL_CFLAGS += -mno-gnu-attribute + +# Similarly for the decimal routines, compile with long double == IBM 128-bit, +# but set the flags so that it can be linked with either long double format. +#DECNUMINC += -Wno-psabi -mabi=ibmlongdouble -mno-gnu-attribute + +# Force the TF mode to/from decimal functions to be compiled with IBM long double +# Add building the KF mode to/from decimal conversions +TF_DECIMAL_OBJS = _dd_to_tf$(objext) _sd_to_tf$(objext) \ + _td_to_tf$(objext) _tf_to_dd$(objext) \ + _tf_to_sd$(objext) _tf_to_td$(objext) + +CFLAGS_TF_DECIMAL = -mno-gnu-attribute -Wno-psabi -mabi=ibmlongdouble +CFLAGS_KF_DECIMAL = -mno-gnu-attribute -Wno-psabi -mabi=ieeelongdouble +CFLAGS_KF_DECIMAL_SW = $(CFLAGS_KF_DECIMAL) -mno-float128-hardware + +$(TF_DECIMAL_OBJS) : INTERNAL_CFLAGS += $(CFLAGS_TF_DECIMAL) + $(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@)) $(fp128_dep) @src="$(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@))"; \ echo "Create $@"; \ diff --git a/libgcc/dfp-bit.c b/libgcc/dfp-bit.c index 935a1e340db..67212daa0bd 100644 --- a/libgcc/dfp-bit.c +++ b/libgcc/dfp-bit.c @@ -609,7 +609,8 @@ INT_TO_DFP (INT_TYPE i) || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \ && LONG_DOUBLE_HAS_XF_MODE) \ || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \ - && LONG_DOUBLE_HAS_TF_MODE) + && LONG_DOUBLE_HAS_TF_MODE) \ + || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) BFP_TYPE DFP_TO_BFP (DFP_C_TYPE f) { @@ -629,7 +630,8 @@ DFP_TO_BFP (DFP_C_TYPE f) || ((defined (L_xf_to_sd) || defined (L_xf_to_dd) || defined (L_xf_to_td)) \ && LONG_DOUBLE_HAS_XF_MODE) \ || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \ - && LONG_DOUBLE_HAS_TF_MODE) + && LONG_DOUBLE_HAS_TF_MODE) \ + || defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td) DFP_C_TYPE BFP_TO_DFP (BFP_TYPE x) { @@ -642,7 +644,11 @@ BFP_TO_DFP (BFP_TYPE x) DFP_INIT_ROUNDMODE (context.round); /* Use a C library function to write the floating point value to a string. */ +#if HAVE_KF_MODE + strfromf128 (buf, BUFMAX, BFP_FMT, (BFP_VIA_TYPE) x); +#else sprintf (buf, BFP_FMT, (BFP_VIA_TYPE) x); +#endif /* Convert from the floating point string to a decimal* type. */ FROM_STRING (&s, buf, &context); diff --git a/libgcc/dfp-bit.h b/libgcc/dfp-bit.h index 4215241da18..91fcdcdc7eb 100644 --- a/libgcc/dfp-bit.h +++ b/libgcc/dfp-bit.h @@ -226,6 +226,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define STR_TO_INT strtoull #endif +/* Support PowerPC KF mode, which is __float128 when long double is + IBM extended double. */ +#if defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \ + || defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td) +#define HAVE_KF_MODE 1 +#endif + /* Conversions between decimal float types and binary float types use BFP_KIND to determine the data type and C functions to use. */ @@ -239,7 +246,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see || defined (L_xf_to_sd) || defined (L_xf_to_dd) || defined (L_xf_to_td) #define BFP_KIND 3 #elif defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf) \ - || defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td) + || defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td) \ + || defined (HAVE_KF_MODE) #define BFP_KIND 4 #endif @@ -277,6 +285,18 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define STR_TO_BFP strtold #endif /* LONG_DOUBLE_HAS_XF_MODE */ +#elif BFP_KIND == 4 && HAVE_KF_MODE +#define BFP_TYPE _Float128 +#define BFP_FMT "%.36e" +#define STR_TO_BFP strtof128 +#define BFP_VIA_TYPE _Float128 +extern _Float128 strtof128 (const char *__restrict __nptr, + char **__restrict __endptr) + __THROW __nonnull ((1)); +extern int strfromf128 (char *__dest, size_t __size, const char * __format, + _Float128 __f) + __THROW __nonnull ((3)); + #elif BFP_KIND == 4 #if LONG_DOUBLE_HAS_TF_MODE #define BFP_TYPE TFtype @@ -487,6 +507,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #elif BFP_KIND == 3 #define BFP_TO_DFP DPD_BID_NAME(__dpd_truncxfsd,__bid_truncxfsd) #define DFP_TO_BFP DPD_BID_NAME(__dpd_extendsdxf,__bid_extendsdxf) +#elif BFP_KIND == 4 && HAVE_KF_MODE +#define BFP_TO_DFP DPD_BID_NAME(__dpd_trunckfsd,__bid_trunckfsd) +#define DFP_TO_BFP DPD_BID_NAME(__dpd_extendsdkf,__bid_extendsdkf) #elif BFP_KIND == 4 #define BFP_TO_DFP DPD_BID_NAME(__dpd_trunctfsd,__bid_trunctfsd) #define DFP_TO_BFP DPD_BID_NAME(__dpd_extendsdtf,__bid_extendsdtf) @@ -502,6 +525,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #elif BFP_KIND == 3 #define BFP_TO_DFP DPD_BID_NAME(__dpd_truncxfdd,__bid_truncxfdd) #define DFP_TO_BFP DPD_BID_NAME(__dpd_extendddxf,__bid_extendddxf) +#elif BFP_KIND == 4 && HAVE_KF_MODE +#define BFP_TO_DFP DPD_BID_NAME(__dpd_trunckfdd,__bid_trunckfdd) +#define DFP_TO_BFP DPD_BID_NAME(__dpd_extendddkf,__bid_extendddkf) #elif BFP_KIND == 4 #define BFP_TO_DFP DPD_BID_NAME(__dpd_trunctfdd,__bid_trunctfdd) #define DFP_TO_BFP DPD_BID_NAME(__dpd_extendddtf,__bid_extendddtf) @@ -517,6 +543,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #elif BFP_KIND == 3 #define BFP_TO_DFP DPD_BID_NAME(__dpd_extendxftd,__bid_extendxftd) #define DFP_TO_BFP DPD_BID_NAME(__dpd_trunctdxf,__bid_trunctdxf) +#elif BFP_KIND == 4 && HAVE_KF_MODE +#define BFP_TO_DFP DPD_BID_NAME(__dpd_extendkftd,__bid_extendkftd) +#define DFP_TO_BFP DPD_BID_NAME(__dpd_trunctdkf,__bid_trunctdkf) #elif BFP_KIND == 4 #define BFP_TO_DFP DPD_BID_NAME(__dpd_extendtftd,__bid_extendtftd) #define DFP_TO_BFP DPD_BID_NAME(__dpd_trunctdtf,__bid_trunctdtf) @@ -612,7 +641,8 @@ extern DFP_C_TYPE INT_TO_DFP (INT_TYPE); || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \ && LONG_DOUBLE_HAS_XF_MODE) \ || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \ - && LONG_DOUBLE_HAS_TF_MODE) + && LONG_DOUBLE_HAS_TF_MODE) \ + || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) extern BFP_TYPE DFP_TO_BFP (DFP_C_TYPE); #endif @@ -621,7 +651,8 @@ extern BFP_TYPE DFP_TO_BFP (DFP_C_TYPE); || ((defined (L_xf_to_sd) || defined (L_xf_to_dd) || defined (L_xf_to_td)) \ && LONG_DOUBLE_HAS_XF_MODE) \ || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \ - && LONG_DOUBLE_HAS_TF_MODE) + && LONG_DOUBLE_HAS_TF_MODE) \ + || defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td) extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE); #endif -- 2.22.0 -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797