mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 19:03:59 +08:00
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.
This commit is contained in:
parent
60b6f5c0a3
commit
246127ab23
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
45
libgcc/soft-fp/floattibf.c
Normal file
45
libgcc/soft-fp/floattibf.c
Normal file
@ -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;
|
||||
}
|
45
libgcc/soft-fp/floatuntibf.c
Normal file
45
libgcc/soft-fp/floatuntibf.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user