From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by sourceware.org (Postfix) with ESMTPS id B538B385781F for ; Thu, 14 Jan 2021 17:09:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B538B385781F Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 10EH2Wst153449; Thu, 14 Jan 2021 12:09:43 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 362t090ajq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 14 Jan 2021 12:09:42 -0500 Received: from m0098413.ppops.net (m0098413.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 10EH4ZAG166045; Thu, 14 Jan 2021 12:09:41 -0500 Received: from ppma03dal.us.ibm.com (b.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.11]) by mx0b-001b2d01.pphosted.com with ESMTP id 362t090agt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 14 Jan 2021 12:09:41 -0500 Received: from pps.filterd (ppma03dal.us.ibm.com [127.0.0.1]) by ppma03dal.us.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 10EH26PN019149; Thu, 14 Jan 2021 17:09:39 GMT Received: from b01cxnp23032.gho.pok.ibm.com (b01cxnp23032.gho.pok.ibm.com [9.57.198.27]) by ppma03dal.us.ibm.com with ESMTP id 35y449r9sk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 14 Jan 2021 17:09:39 +0000 Received: from b01ledav001.gho.pok.ibm.com (b01ledav001.gho.pok.ibm.com [9.57.199.106]) by b01cxnp23032.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 10EH9dCV29426160 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 14 Jan 2021 17:09:39 GMT Received: from b01ledav001.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EE55228059; Thu, 14 Jan 2021 17:09:38 +0000 (GMT) Received: from b01ledav001.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5D6FE28058; Thu, 14 Jan 2021 17:09:38 +0000 (GMT) Received: from ibm-toto.the-meissners.org (unknown [9.160.46.99]) by b01ledav001.gho.pok.ibm.com (Postfix) with ESMTPS; Thu, 14 Jan 2021 17:09:38 +0000 (GMT) Date: Thu, 14 Jan 2021 12:09:36 -0500 From: Michael Meissner To: gcc-patches@gcc.gnu.org, Michael Meissner , Segher Boessenkool , David Edelsohn , Bill Schmidt , Peter Bergner Subject: [PATCH] PowerPC: Add float128/Decimal conversions. Message-ID: <20210114170936.GA3319@ibm-toto.the-meissners.org> Mail-Followup-To: Michael Meissner , gcc-patches@gcc.gnu.org, Segher Boessenkool , David Edelsohn , Bill Schmidt , Peter Bergner MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.343, 18.0.737 definitions=2021-01-14_06:2021-01-14, 2021-01-14 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 adultscore=0 clxscore=1015 mlxscore=0 impostorscore=0 bulkscore=0 spamscore=0 mlxlogscore=999 malwarescore=0 priorityscore=1501 lowpriorityscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2101140094 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, BIGNUM_EMAILS, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jan 2021 17:09:47 -0000 [PATCH] PowerPC: Add float128/Decimal conversions. This patch replaces the following two patches: September 24th, 2020: Message-ID: <20200924203545.GD31597@ibm-toto.the-meissners.org> October 22nd, 2020: Message-ID: <20201022220603.GA11658@ibm-toto.the-meissners.org> This patch rewrites those patches. In order to run with older GLIBC's, this patch uses weak references to the IEEE 128-bit conversions to/from string that are found in GLIBC 2.32. If the user uses GLIBC 2.32 or later, the Decimal <-> Float128 conversions will call the functions in that library. This isn't ideal, as IEEE 128-bit has more exponent range than IBM 128-bit. If an older library is used, these patches will convert IEEE 128-bit to IBM 128-bit and do the conversion with IBM 128-bit. I have tested this with a compiler configured to use an older library, and it worked for the conversion if the number could be represented in the IBM 128-bit format. While most of the Decimal <-> Long double tests now pass when long doubles are IEEE 128-bit, there are two tests that fails: * c-c++-common/dfp/convert-bfp-6.c * c-c++-common/dfp/convert-bfp-11.c I have patches for the bfp-11 test (which requires that long double be IBM 128-bit). I have not looked at the bfp-6 test but I will shortly. I have tested this patch by doing builds, bootstraps, and make check with 3 builds on a power9 little endian server: * Build one used the default long double being IBM 128-bit; * Build two set the long double default to IEEE 128-bit; (and) * Build three set the long double default to 64-bit. The compilers built fine providing I recompiled gmp, mpc, and mpfr with the appropriate long double options. There were a few differences in the test suite runs that will be addressed in later patches, but over all it works well. This patch is required to be able to build a toolchain where the default long double is IEEE 128-bit. Can I check this patch into the master branch for GCC 11? libgcc/ 2021-01-14 Michael Meissner * 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. --- libgcc/config/rs6000/_dd_to_kf.c | 37 ++++++++++++++++++ libgcc/config/rs6000/_kf_to_dd.c | 37 ++++++++++++++++++ libgcc/config/rs6000/_kf_to_sd.c | 37 ++++++++++++++++++ libgcc/config/rs6000/_kf_to_td.c | 37 ++++++++++++++++++ libgcc/config/rs6000/_sd_to_kf.c | 37 ++++++++++++++++++ libgcc/config/rs6000/_sprintfkf.c | 57 ++++++++++++++++++++++++++++ libgcc/config/rs6000/_sprintfkf.h | 28 ++++++++++++++ libgcc/config/rs6000/_strtokf.c | 56 +++++++++++++++++++++++++++ libgcc/config/rs6000/_strtokf.h | 27 +++++++++++++ libgcc/config/rs6000/_td_to_kf.c | 37 ++++++++++++++++++ libgcc/config/rs6000/quad-float128.h | 8 ++++ libgcc/config/rs6000/t-float128 | 37 +++++++++++++++++- libgcc/dfp-bit.c | 12 +++++- libgcc/dfp-bit.h | 26 +++++++++++++ 14 files changed, 470 insertions(+), 3 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/_sprintfkf.c create mode 100644 libgcc/config/rs6000/_sprintfkf.h create mode 100644 libgcc/config/rs6000/_strtokf.c create mode 100644 libgcc/config/rs6000/_strtokf.h 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..3b4d8500a57 --- /dev/null +++ b/libgcc/config/rs6000/_dd_to_kf.c @@ -0,0 +1,37 @@ +/* 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 +. */ + +/* 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 00000000000..8d1c49dd396 --- /dev/null +++ b/libgcc/config/rs6000/_kf_to_dd.c @@ -0,0 +1,37 @@ +/* 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 +. */ + +/* _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 00000000000..b02082d6f52 --- /dev/null +++ b/libgcc/config/rs6000/_kf_to_sd.c @@ -0,0 +1,37 @@ +/* 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 +. */ + +/* _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 00000000000..f120709bb42 --- /dev/null +++ b/libgcc/config/rs6000/_kf_to_td.c @@ -0,0 +1,37 @@ +/* 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 +. */ + +/* _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 00000000000..df222abdeab --- /dev/null +++ b/libgcc/config/rs6000/_sd_to_kf.c @@ -0,0 +1,37 @@ +/* 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 +. */ + +/* 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 00000000000..e5ea8eb3b4e --- /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 +. */ + +/* Conversion to IEEE 128-bit floating point from string using snprintf. */ + +#include +#include +#include +#include +#include + +/* 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 sprinf 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 00000000000..637d104c882 --- /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 +. */ + +/* 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 00000000000..696a2c907bb --- /dev/null +++ b/libgcc/config/rs6000/_strtokf.c @@ -0,0 +1,56 @@ +/* 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 +. */ + +/* Conversion to IEEE 128-bit floating point from string. */ + +#include +#include +#include +#include + +/* 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) +{ + long double num; + + if (__strtoieee128) + return __strtoieee128 (string, endptr); + + num = strtold (string, endptr); + return (_Float128) num; +} diff --git a/libgcc/config/rs6000/_strtokf.h b/libgcc/config/rs6000/_strtokf.h new file mode 100644 index 00000000000..a7ca8e09244 --- /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 +. */ + +/* 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 00000000000..330a7802827 --- /dev/null +++ b/libgcc/config/rs6000/_td_to_kf.c @@ -0,0 +1,37 @@ +/* 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 +. */ + +/* 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 0eb1d34691f..5beb1531d2b 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 #include #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 d5413445189..6fb1a3d871b 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 $@"; \ diff --git a/libgcc/dfp-bit.c b/libgcc/dfp-bit.c index 17bca9cf203..0b0f9ace1fa 100644 --- a/libgcc/dfp-bit.c +++ b/libgcc/dfp-bit.c @@ -606,6 +606,7 @@ INT_TO_DFP (INT_TYPE i) #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \ || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \ + || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \ || ((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)) \ @@ -626,6 +627,7 @@ DFP_TO_BFP (DFP_C_TYPE f) #if defined (L_sf_to_sd) || defined (L_sf_to_dd) || defined (L_sf_to_td) \ || defined (L_df_to_sd) || defined (L_df_to_dd) || defined (L_df_to_td) \ + || defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td) \ || ((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)) \ @@ -641,8 +643,14 @@ BFP_TO_DFP (BFP_TYPE x) decContextDefault (&context, CONTEXT_INIT); DFP_INIT_ROUNDMODE (context.round); - /* Use a C library function to write the floating point value to a string. */ - sprintf (buf, BFP_FMT, (BFP_VIA_TYPE) x); + /* Use the sprintf library function to write the floating point value to a string. + + If we are handling the IEEE 128-bit floating point on PowerPC, use the + special function __sprintfkf instead of sprintf. This function allows us + to use __sprintfieee128 if we have a new enough GLIBC, and it can fall back + to using the traditional sprintf via conversion to IBM 128-bit if the glibc + is older. */ + BFP_SPRINTF (buf, BFP_FMT, (BFP_VIA_TYPE) x); /* 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 1fa42ee621f..e33bc22f7cc 100644 --- a/libgcc/dfp-bit.h +++ b/libgcc/dfp-bit.h @@ -241,6 +241,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #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) #define BFP_KIND 4 +#elif 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 BFP_KIND 5 #endif /* If BFP_KIND is defined, define additional macros: @@ -291,6 +294,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define BFP_VIA_TYPE long double #endif /* LONG_DOUBLE_HAS_TF_MODE */ +#elif BFP_KIND == 5 +#define BFP_TYPE _Float128 +#define BFP_FMT "%.21Le" +#define BFP_VIA_TYPE _Float128 +#define STR_TO_BFP __strtokf +#include <_strtokf.h> + #endif /* BFP_KIND */ #if WIDTH == 128 || WIDTH_TO == 128 @@ -490,6 +500,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #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) +#elif BFP_KIND == 5 +#define BFP_TO_DFP DPD_BID_NAME(__dpd_trunckfsd,__bid_trunckfsd) +#define DFP_TO_BFP DPD_BID_NAME(__dpd_extendsdkf,__bid_extendsdkf) #endif /* BFP_KIND */ #elif WIDTH == 64 @@ -505,6 +518,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #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) +#elif BFP_KIND == 5 +#define BFP_TO_DFP DPD_BID_NAME(__dpd_trunckfdd,__bid_trunckfdd) +#define DFP_TO_BFP DPD_BID_NAME(__dpd_extendddkf,__bid_extendddkf) #endif /* BFP_KIND */ #elif WIDTH == 128 @@ -520,6 +536,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #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) +#elif BFP_KIND == 5 +#define BFP_TO_DFP DPD_BID_NAME(__dpd_extendkftd,__bid_extendkftd) +#define DFP_TO_BFP DPD_BID_NAME(__dpd_trunctdkf,__bid_trunctdkf) #endif /* BFP_KIND */ #endif /* WIDTH */ @@ -609,6 +628,7 @@ extern DFP_C_TYPE INT_TO_DFP (INT_TYPE); #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \ || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \ + || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \ || ((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)) \ @@ -623,6 +643,12 @@ extern BFP_TYPE DFP_TO_BFP (DFP_C_TYPE); || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \ && LONG_DOUBLE_HAS_TF_MODE) extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE); +#define BFP_SPRINTF sprintf + +#elif defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td) +extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE); +#include <_sprintfkf.h> +#define BFP_SPRINTF __sprintfkf #endif #endif /* _DFPBIT_H */ -- 2.22.0 -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meissner@linux.ibm.com, phone: +1 (978) 899-4797