From patchwork Fri Jan 29 02:42:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Meissner X-Patchwork-Id: 1433092 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=YtBSDj+k; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DRhT42ZfCz9sCq for ; Fri, 29 Jan 2021 13:42:29 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 83E4F384A018; Fri, 29 Jan 2021 02:42:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 83E4F384A018 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1611888143; bh=wQKHfNDy7hmigzuKgU3gnn2bdJa6GcnKqYnK1i8VF1U=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=YtBSDj+kybQu4WrSphR+EEdQRehD22eNiwEVeMVFlMWB96YutBb9piv31Ik1mHJau 1x9S0xsrm7qNRGU9oQAnjCz8P4z+KS/gAAvcldqw4iNT7QUhntH/vMQaeDYaLq2Aeq 5H3TpAljkBF+RFO+UX9QTqh+Gr8g8mpMvWMLDnuk= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 9B17B384B823 for ; Fri, 29 Jan 2021 02:42:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 9B17B384B823 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 10T2VnBh177093; Thu, 28 Jan 2021 21:42:15 -0500 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 36c8ysh2p5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 28 Jan 2021 21:42:15 -0500 Received: from m0098394.ppops.net (m0098394.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 10T2X1kG181617; Thu, 28 Jan 2021 21:42:14 -0500 Received: from ppma04dal.us.ibm.com (7a.29.35a9.ip4.static.sl-reverse.com [169.53.41.122]) by mx0a-001b2d01.pphosted.com with ESMTP id 36c8ysh2nv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 28 Jan 2021 21:42:14 -0500 Received: from pps.filterd (ppma04dal.us.ibm.com [127.0.0.1]) by ppma04dal.us.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 10T2bJmT025684; Fri, 29 Jan 2021 02:42:13 GMT Received: from b03cxnp08027.gho.boulder.ibm.com (b03cxnp08027.gho.boulder.ibm.com [9.17.130.19]) by ppma04dal.us.ibm.com with ESMTP id 36agvfa5jk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 Jan 2021 02:42:13 +0000 Received: from b03ledav002.gho.boulder.ibm.com (b03ledav002.gho.boulder.ibm.com [9.17.130.233]) by b03cxnp08027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 10T2gCNM12452238 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 29 Jan 2021 02:42:12 GMT Received: from b03ledav002.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0D219136081; Fri, 29 Jan 2021 02:42:12 +0000 (GMT) Received: from b03ledav002.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 238A9136059; Fri, 29 Jan 2021 02:42:11 +0000 (GMT) Received: from ibm-toto.the-meissners.org (unknown [9.65.214.235]) by b03ledav002.gho.boulder.ibm.com (Postfix) with ESMTPS; Fri, 29 Jan 2021 02:42:10 +0000 (GMT) Date: Thu, 28 Jan 2021 21:42:08 -0500 To: gcc-patches@gcc.gnu.org, Michael Meissner , Segher Boessenkool , David Edelsohn , Bill Schmidt , Peter Bergner Subject: [PATCH] Add conversions between _Float128 and Decimal. Message-ID: <20210129024208.GA25608@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-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-28_12:2021-01-28, 2021-01-28 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 lowpriorityscore=0 mlxscore=0 phishscore=0 clxscore=1015 impostorscore=0 suspectscore=0 malwarescore=0 spamscore=0 adultscore=0 bulkscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2101290008 X-Spam-Status: No, score=-10.4 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_H3, 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-Patchwork-Original-From: Michael Meissner via Gcc-patches From: Michael Meissner Reply-To: Michael Meissner Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" [PATCH] Add conversions between _Float128 and Decimal. This patch implements conversions between _Float128 and the 3 Decimal floating types. It does by extendending the dfp-bit conversions to add a new binary floating point type (KF), and doing the conversions in the same mannor as the other binary/decimal conversions. In particular for conversions from _Float128 to Decimal, it uses a sprintf variant to convert _Float128 to strings, and a type specific function that converts the string output to the appropriate Decimal type For conversions from one of the Decimal types to _Float128, it uses a decimal function to convert to string (i.e. __decimalToString), and then uses a variant of strtold to convert to _Float128. If the user is linked against GLIBC 2.32 or newer, then the sprintf and strtold variant functions can use the features directly in GLIBC 2.32 to do this conversion. If you have an older GLIBC and want to convert _Float128 to one of the Decimal types, it will convert the _Float128 to __ibm128 and then convert that to Decimal. Similarly if you have one of the Decimal types, and want to convert to _Float128, it will first convert the Decimal type to __ibm128, and then convert __ibm128 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. One test case relating to Decimal fails if I build a compiler where the default is IEEE 128-bit: * c-c++-common/dfp/convert-bfp-11.c I have patches for this test, and they have been submitted separately. 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? I have also built compilers with this patch on a big endian power8 system that has both 32-bit and 64-bit support. There were no regressions in running these tests on the system. Can I check this patch into the master branch? libgcc/ 2021-01-28 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..5e3bfa65ab8 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 "%.36Le" +#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 */