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;
+}