public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-6598] libgcc, i386: Add __fix{, uns}bfti and __float{, un}tibf [PR107703]
@ 2023-03-10 19:43 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2023-03-10 19:43 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:246127ab238bac6aa71a9b4ee1f6fabf776b5ccb

commit r13-6598-g246127ab238bac6aa71a9b4ee1f6fabf776b5ccb
Author: Jakub Jelinek <jakub@redhat.com>
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  <jakub@redhat.com>
    
            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
+   <https://www.gnu.org/licenses/>.  */
+
+#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
+   <https://www.gnu.org/licenses/>.  */
+
+#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;
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-03-10 19:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-10 19:43 [gcc r13-6598] libgcc, i386: Add __fix{, uns}bfti and __float{, un}tibf [PR107703] Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).