From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id 01C323858D32; Fri, 10 Mar 2023 19:43:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 01C323858D32 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1678477396; bh=8osFRJuwuPuWm8U5GjgwPNnu27+Mwk8Z2AXQ95YiqLw=; h=From:To:Subject:Date:From; b=KpwKICpeE97I3PCWiQLKhlRsfLIdDJ+rELsIyx/lf13xnqr2UBNpqd6GrsS5+7qWp ZLZvN8F3iA6GoSWfW0e727m2if6yc/R4835MhDhOQZKEMoq5GSSFbllVOHi1fLQXq8 DaNGcQGA0CrqPpJo/meOgVAB493poX7bL/bG8ngY= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jakub Jelinek To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-6598] libgcc, i386: Add __fix{, uns}bfti and __float{, un}tibf [PR107703] X-Act-Checkin: gcc X-Git-Author: Jakub Jelinek X-Git-Refname: refs/heads/master X-Git-Oldrev: 60b6f5c0a334db3f8f6dffaf0b9aab42fd5c54a2 X-Git-Newrev: 246127ab238bac6aa71a9b4ee1f6fabf776b5ccb Message-Id: <20230310194316.01C323858D32@sourceware.org> Date: Fri, 10 Mar 2023 19:43:16 +0000 (GMT) List-Id: https://gcc.gnu.org/g:246127ab238bac6aa71a9b4ee1f6fabf776b5ccb commit r13-6598-g246127ab238bac6aa71a9b4ee1f6fabf776b5ccb Author: Jakub Jelinek Date: Fri Mar 10 20:39:54 2023 +0100 libgcc, i386: Add __fix{,uns}bfti and __float{,un}tibf [PR107703] While DI <-> BF conversions can be handled (and are) through DI <-> XF <-> BF and for narrower integral modes even sometimes through DF or SF, because XFmode has 64-bit mantissa and so all the DImode values are exactly representable in XFmode. That is not the case for TImode, and while e.g. the HF -> TI conversions are IMHO useless in libgcc, because HFmode has -65504.0f16, 65504.0f16 range, all the integers will be already representable in SImode (or even HImode for unsigned) and so I think HF -> DI -> TI conversions are faster and valid, BFmode has roughly the same range as SFmode and so we absolutely need the TI -> BF conversions to avoid double rounding. As for BF -> TI conversions, they can be either also implemented in libgcc, or they can be implemented (as done in this commit) as BF -> SF -> TI conversions with the same code generation used elsewhere, just doing the 16-bit left shift of the bits - I think we don't need to handle sNaNs during the BF -> SF part because SF -> TI (which is already a libcall too) will handle that too. The BF -> SF -> TI path avoids wasting 32: 0000000000015e10 321 FUNC GLOBAL DEFAULT 13 __fixbfti@@GCC_13.0.0 89: 0000000000015f60 299 FUNC GLOBAL DEFAULT 13 __fixunsbfti@@GCC_13.0.0 2023-03-10 Jakub Jelinek PR target/107703 * optabs.cc (expand_fix): For conversions from BFmode to integral, use shifts to convert it to SFmode first and then convert SFmode to integral. * soft-fp/floattibf.c: New file. * soft-fp/floatuntibf.c: New file. * config/i386/libgcc-glibc.ver: Export __float{,un}tibf @ GCC_13.0.0. * config/i386/64/t-softfp (softfp_extras): Add floattibf and floatuntibf. (CFLAGS-floattibf.c, CFLAGS-floatunstibf.c): Add -msse2. Diff: --- gcc/optabs.cc | 48 +++++++++++++++++++++++++++++++++++-- libgcc/config/i386/64/t-softfp | 5 +++- libgcc/config/i386/libgcc-glibc.ver | 2 ++ libgcc/soft-fp/floattibf.c | 45 ++++++++++++++++++++++++++++++++++ libgcc/soft-fp/floatuntibf.c | 45 ++++++++++++++++++++++++++++++++++ 5 files changed, 142 insertions(+), 3 deletions(-) diff --git a/gcc/optabs.cc b/gcc/optabs.cc index 4c641cab192..c725f357b7f 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -5674,7 +5674,21 @@ expand_fix (rtx to, rtx from, int unsignedp) rtx_insn *last = get_last_insn (); rtx from1 = from; if (fmode != GET_MODE (from)) - from1 = convert_to_mode (fmode, from, 0); + { + if (REAL_MODE_FORMAT (GET_MODE (from)) + == &arm_bfloat_half_format + && REAL_MODE_FORMAT (fmode) == &ieee_single_format) + /* The BF -> SF conversions can be just a shift, doesn't + need to handle sNANs. */ + { + int save_flag_finite_math_only = flag_finite_math_only; + flag_finite_math_only = true; + from1 = convert_to_mode (fmode, from, 0); + flag_finite_math_only = save_flag_finite_math_only; + } + else + from1 = convert_to_mode (fmode, from, 0); + } if (must_trunc) { @@ -5746,7 +5760,21 @@ expand_fix (rtx to, rtx from, int unsignedp) lab2 = gen_label_rtx (); if (fmode != GET_MODE (from)) - from = convert_to_mode (fmode, from, 0); + { + if (REAL_MODE_FORMAT (GET_MODE (from)) + == &arm_bfloat_half_format + && REAL_MODE_FORMAT (fmode) == &ieee_single_format) + /* The BF -> SF conversions can be just a shift, doesn't + need to handle sNANs. */ + { + int save_flag_finite_math_only = flag_finite_math_only; + flag_finite_math_only = true; + from = convert_to_mode (fmode, from, 0); + flag_finite_math_only = save_flag_finite_math_only; + } + else + from = convert_to_mode (fmode, from, 0); + } /* See if we need to do the subtraction. */ do_pending_stack_adjust (); @@ -5790,6 +5818,22 @@ expand_fix (rtx to, rtx from, int unsignedp) } } +#ifdef HAVE_SFmode + if (REAL_MODE_FORMAT (GET_MODE (from)) == &arm_bfloat_half_format + && REAL_MODE_FORMAT (SFmode) == &ieee_single_format) + /* We don't have BF -> TI library functions, use BF -> SF -> TI + instead but the BF -> SF conversion can be just a shift, doesn't + need to handle sNANs. */ + { + int save_flag_finite_math_only = flag_finite_math_only; + flag_finite_math_only = true; + from = convert_to_mode (SFmode, from, 0); + flag_finite_math_only = save_flag_finite_math_only; + expand_fix (to, from, unsignedp); + return; + } +#endif + /* We can't do it with an insn, so use a library call. But first ensure that the mode of TO is at least as wide as SImode, since those are the only library calls we know about. */ diff --git a/libgcc/config/i386/64/t-softfp b/libgcc/config/i386/64/t-softfp index 3bec464d786..197fa1131f3 100644 --- a/libgcc/config/i386/64/t-softfp +++ b/libgcc/config/i386/64/t-softfp @@ -1,6 +1,9 @@ -softfp_extras := fixhfti fixunshfti floattihf floatuntihf +softfp_extras := fixhfti fixunshfti floattihf floatuntihf \ + floattibf floatuntibf CFLAGS-fixhfti.c += -msse2 CFLAGS-fixunshfti.c += -msse2 CFLAGS-floattihf.c += -msse2 CFLAGS-floatunstihf.c += -msse2 +CFLAGS-floattibf.c += -msse2 +CFLAGS-floatunstibf.c += -msse2 diff --git a/libgcc/config/i386/libgcc-glibc.ver b/libgcc/config/i386/libgcc-glibc.ver index fa8934b9bf4..d84d075cf9f 100644 --- a/libgcc/config/i386/libgcc-glibc.ver +++ b/libgcc/config/i386/libgcc-glibc.ver @@ -218,6 +218,8 @@ GCC_12.0.0 { %inherit GCC_13.0.0 GCC_12.0.0 GCC_13.0.0 { __extendbfsf2 + __floattibf + __floatuntibf __truncdfbf2 __truncsfbf2 __trunctfbf2 diff --git a/libgcc/soft-fp/floattibf.c b/libgcc/soft-fp/floattibf.c new file mode 100644 index 00000000000..f3336a95b06 --- /dev/null +++ b/libgcc/soft-fp/floattibf.c @@ -0,0 +1,45 @@ +/* Software floating-point emulation. + Convert a 128bit signed integer to bfloat16 + Copyright (C) 2007-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include "soft-fp.h" +#include "brain.h" + +BFtype +__floattibf (TItype i) +{ + FP_DECL_EX; + FP_DECL_B (A); + BFtype a; + + FP_INIT_ROUNDMODE; + FP_FROM_INT_B (A, i, TI_BITS, UTItype); + FP_PACK_RAW_B (a, A); + FP_HANDLE_EXCEPTIONS; + + return a; +} diff --git a/libgcc/soft-fp/floatuntibf.c b/libgcc/soft-fp/floatuntibf.c new file mode 100644 index 00000000000..362b0f6c1bb --- /dev/null +++ b/libgcc/soft-fp/floatuntibf.c @@ -0,0 +1,45 @@ +/* Software floating-point emulation. + Convert a 128bit unsigned integer to bfloat16 + Copyright (C) 2007-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include "soft-fp.h" +#include "brain.h" + +BFtype +__floatuntibf (UTItype i) +{ + FP_DECL_EX; + FP_DECL_B (A); + BFtype a; + + FP_INIT_ROUNDMODE; + FP_FROM_INT_B (A, i, TI_BITS, UTItype); + FP_PACK_RAW_B (a, A); + FP_HANDLE_EXCEPTIONS; + + return a; +}