[gcc(refs/users/meissner/heads/work233-float)] Add HF/BF emulation functions to libgcc.
Michael Meissner
meissner@gcc.gnu.org
Tue Jan 6 03:25:36 GMT 2026
https://gcc.gnu.org/g:ae2ccff15b51b7b42e6b826fd04d365c22d96381
commit ae2ccff15b51b7b42e6b826fd04d365c22d96381
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Mon Jan 5 22:09:34 2026 -0500
Add HF/BF emulation functions to libgcc.
This patch adds the necessary support in libgcc to allow using the machine
independent 16-bit floating point support.
2026-01-05 Michael Meissner <meissner@linux.ibm.com>
libgcc/
* config.host (powerpc*-*-linux*): Add HF/BF emulation functions to
PowerPC libgcc.
* config/rs6000/sfp-machine.h (_FP_NANFRAC_H): New macro.
(_FP_NANFRAC_B): Likewise.
(_FP_NANSIGN_H): Likewise.
(_FP_NANSIGN_B): Likewise.
(DFtype2): Add HF/BF emulation function declarations.
(SFtype2): Likewise.
(DItype2): Likewise.
(UDItype2): Likewise.
(SItype2): Likewise.
(USItype2): Likewise.
(HFtype2): Likewise.
(__eqhf2): Likewise.
(__extendhfdf2): Likewise.
(__extendhfsf2): Likewise.
(__fixhfdi): Likewise.
(__fixhfsi): Likewise.
(__fixunshfdi): Likewise.
(__fixunshfsi): Likewise.
(__floatdihf): Likewise.
(__floatsihf): Likewise.
(__floatundihf): Likewise.
(__floatunsihf): Likewise.
(__truncdfhf2): Likewise.
(__truncsfhf2): Likewise.
(BFtype2): Likewise.
(__extendbfsf2): Likewise.
(__floatdibf): Likewise.
(__floatsibf): Likewise.
(__floatundibf): Likewise.
(__floatunsibf): Likewise.
(__truncdfbf2): Likewise.
(__truncsfbf2): Likewise.
(__truncbfhf2): Likewise.
(__trunchfbf2): Likewise.
* config/rs6000/t-float16: New file.
* configure.ac (powerpc*-*-linux*): Check if the PowerPC compiler
supports _Float16 and __bfloat16 types.
* configure: Regenerate.
Diff:
---
libgcc/config.host | 4 +++
libgcc/config/rs6000/sfp-machine.h | 48 ++++++++++++++++++++++++++++++
libgcc/config/rs6000/t-float16 | 61 ++++++++++++++++++++++++++++++++++++++
libgcc/configure | 23 ++++++++++++++
libgcc/configure.ac | 11 +++++++
5 files changed, 147 insertions(+)
diff --git a/libgcc/config.host b/libgcc/config.host
index 2434844b8337..0aa54c9358b2 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -1302,6 +1302,10 @@ powerpc*-*-linux*)
tmake_file="${tmake_file} rs6000/t-float128-p10-hw"
fi
+ if test $libgcc_cv_powerpc_float16 = yes; then
+ tmake_file="${tmake_file} rs6000/t-float16"
+ fi
+
extra_parts="$extra_parts ecrti.o ecrtn.o ncrti.o ncrtn.o"
md_unwind_header=rs6000/linux-unwind.h
;;
diff --git a/libgcc/config/rs6000/sfp-machine.h b/libgcc/config/rs6000/sfp-machine.h
index f0ede0e042a3..b6dd03a710e3 100644
--- a/libgcc/config/rs6000/sfp-machine.h
+++ b/libgcc/config/rs6000/sfp-machine.h
@@ -22,6 +22,9 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
#define _FP_I_TYPE int
#endif /* 32-bits */
+#define _FP_NANFRAC_H _FP_QNANBIT_H
+#define _FP_NANFRAC_B _FP_QNANBIT_B
+
/* The type of the result of a floating point comparison. This must
match `__libgcc_cmp_return__' in GCC for the target. */
typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
@@ -62,6 +65,8 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
#endif
+#define _FP_NANSIGN_H 1
+#define _FP_NANSIGN_B 1
#define _FP_NANSIGN_S 0
#define _FP_NANSIGN_D 0
#define _FP_NANSIGN_Q 0
@@ -161,3 +166,46 @@ void __sfp_handle_exceptions (int);
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+
+/* Add prototypes for the HFmode and BFmode functions. */
+typedef double DFtype2;
+typedef float SFtype2;
+typedef int DItype2 __attribute__ ((mode (DI)));
+typedef unsigned int UDItype2 __attribute__ ((mode (DI)));
+typedef int SItype2 __attribute__ ((mode (SI)));
+typedef unsigned int USItype2 __attribute__ ((mode (SI)));
+
+#ifdef __FLOAT16__
+typedef float HFtype2 __attribute__ ((mode (HF)));
+
+extern CMPtype __eqhf2 (HFtype2, HFtype2);
+extern DFtype2 __extendhfdf2 (HFtype2);
+extern SFtype2 __extendhfsf2 (HFtype2);
+extern DItype2 __fixhfdi (HFtype2);
+extern SItype2 __fixhfsi (HFtype2);
+extern UDItype2 __fixunshfdi (HFtype2);
+extern USItype2 __fixunshfsi (HFtype2);
+extern HFtype2 __floatdihf (DItype2);
+extern HFtype2 __floatsihf (SItype2);
+extern HFtype2 __floatundihf (UDItype2);
+extern HFtype2 __floatunsihf (USItype2);
+extern HFtype2 __truncdfhf2 (DFtype2);
+extern HFtype2 __truncsfhf2 (SFtype2);
+#endif
+
+#ifdef __BFLOAT16__
+typedef float BFtype2 __attribute__ ((mode (BF)));
+
+extern SFtype2 __extendbfsf2 (BFtype2);
+extern BFtype2 __floatdibf (DItype2);
+extern BFtype2 __floatsibf (SItype2);
+extern BFtype2 __floatundibf (UDItype2);
+extern BFtype2 __floatunsibf (USItype2);
+extern BFtype2 __truncdfbf2 (DFtype2);
+extern BFtype2 __truncsfbf2 (SFtype2);
+#endif
+
+#if defined(__FLOAT16__) && defined(__BFLOAT16__)
+extern HFtype2 __truncbfhf2 (BFtype2);
+extern BFtype2 __trunchfbf2 (HFtype2);
+#endif
diff --git a/libgcc/config/rs6000/t-float16 b/libgcc/config/rs6000/t-float16
new file mode 100644
index 000000000000..f77df910b3ff
--- /dev/null
+++ b/libgcc/config/rs6000/t-float16
@@ -0,0 +1,61 @@
+# _Float16 library support
+
+fp16_funcs = eqhf2 extendhfdf2 extendhfsf2 \
+ fixhfsi fixhfdi fixhfti fixunshfsi fixunshfdi fixunshfti \
+ floatsihf floatdihf floattihf floatunsihf floatundihf floatuntihf \
+ truncdfhf2 truncsfhf2
+
+fp16_src = $(addprefix $(srcdir)/soft-fp/,$(addsuffix .c,$(fp16_funcs)))
+fp16_obj = $(addsuffix $(objext),$(fp16_funcs))
+
+FP16_CFLAGS = -mfloat16 -Wno-psabi \
+ -I$(srcdir)/soft-fp -I$(srcdir)/config/rs6000
+
+$(fp16_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS)
+
+# __bfloat16 library support
+
+bfp16_funcs = extendbfsf2 floatdibf floatsibf floatundibf floatunsibf \
+ truncdfbf2 truncsfbf2
+
+bfp16_src = $(addprefix $(srcdir)/soft-fp/,$(addsuffix .c,$(bfp16_funcs)))
+bfp16_obj = $(addsuffix $(objext),$(bfp16_funcs))
+
+$(bfp16_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS)
+
+# Conversion between __bfloat16 and _Float16
+
+both_fp16_funcs = truncbfhf2 trunchfbf2
+both_fp16_src = $(addprefix $(srcdir)/soft-fp/,$(addsuffix .c,$(both_fp16_funcs)))
+both_fp16_obj = $(addsuffix $(objext),$(both_fp16_funcs))
+
+$(both_fp16_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS)
+
+# For now, only put it in the static library
+# LIB2ADD += $(fp16_src) $(bfp16_src) $(both_fp16_src)
+
+LIB2ADD_ST += $(fp16_src) $(bfp16_src) $(both_fp16_src)
+
+.PHONY: test-float16 clean-float16
+
+test-float16:
+ @echo "fp16_src:"; \
+ for x in $(fp16_src); do echo " $$x"; done; \
+ echo; \
+ echo "bfp16_src:"; \
+ for x in $(bfp16_src); do echo " $$x"; done; \
+ echo; \
+ echo "both_fp16_src:"; \
+ for x in $(both_fp16_src); do echo " $$x"; done; \
+ echo; \
+ echo "fp16_obj:"; \
+ for x in $(fp16_obj); do echo " $$x"; done; \
+ echo; \
+ echo "bfp16_obj:"; \
+ for x in $(bfp16_obj); do echo " $$x"; done; \
+ echo; \
+ echo "both_fp16_obj:"; \
+ for x in $(bfp16_obj); do echo " $$x"; done;
+
+clean-float16:
+ @$(MULTICLEAN) multi-clean DO=clean-float16
diff --git a/libgcc/configure b/libgcc/configure
index 8cdc021f9c18..62f55357624f 100755
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -5240,6 +5240,8 @@ case ${host} in
# check if we have VSX (ISA 2.06) support to build the software libraries, and
# whether the assembler can handle xsaddqp for hardware support. Also check if
# a new glibc is being used so that __builtin_cpu_supports can be used.
+#
+# Add float16 support also
powerpc*-*-linux*)
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -mabi=altivec -mvsx -mfloat128"
@@ -5334,6 +5336,27 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_powerpc_3_1_float128_hw" >&5
$as_echo "$libgcc_cv_powerpc_3_1_float128_hw" >&6; }
CFLAGS="$saved_CFLAGS"
+
+ CFLAGS="$CFLAGS -mfloat16 -Wno-psabi"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the PowerPC can build the _Float16 libraries" >&5
+$as_echo_n "checking whether the PowerPC can build the _Float16 libraries... " >&6; }
+if ${libgcc_cv_powerpc_float16+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+_Float16 addf16 (_Float16 a, _Float16 b) { return a + b; }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ libgcc_cv_powerpc_float16=yes
+else
+ libgcc_cv_powerpc_float16=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_powerpc_float16" >&5
+$as_echo "$libgcc_cv_powerpc_float16" >&6; }
+ CFLAGS="$saved_CFLAGS"
esac
# Collect host-machine-specific information.
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 1ae782c480c8..5b019a1352eb 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -419,6 +419,8 @@ case ${host} in
# check if we have VSX (ISA 2.06) support to build the software libraries, and
# whether the assembler can handle xsaddqp for hardware support. Also check if
# a new glibc is being used so that __builtin_cpu_supports can be used.
+#
+# Add float16 support also
powerpc*-*-linux*)
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -mabi=altivec -mvsx -mfloat128"
@@ -477,6 +479,15 @@ powerpc*-*-linux*)
[libgcc_cv_powerpc_3_1_float128_hw=yes],
[libgcc_cv_powerpc_3_1_float128_hw=no])])
CFLAGS="$saved_CFLAGS"
+
+ CFLAGS="$CFLAGS -mfloat16 -Wno-psabi"
+ AC_CACHE_CHECK([whether the PowerPC can build the _Float16 libraries],
+ [libgcc_cv_powerpc_float16],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([_Float16 addf16 (_Float16 a, _Float16 b) { return a + b; }])],
+ [libgcc_cv_powerpc_float16=yes],
+ [libgcc_cv_powerpc_float16=no])])
+ CFLAGS="$saved_CFLAGS"
esac
# Collect host-machine-specific information.
More information about the Gcc-cvs
mailing list