[gcc(refs/users/meissner/heads/work255-float)] Add HF/BF emulation functions to libgcc.

Michael Meissner via Gcc-cvs <[email protected]> Tue, 4 Aug 2026 02:16:44 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:cafcee5f0c7b40eecc5c19a46809f79fca5d15c1

commit cafcee5f0c7b40eecc5c19a46809f79fca5d15c1
Author: Michael Meissner <[email protected]>
Date:   Mon Aug 3 19:19:08 2026 -0400

    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.
    
    I have committed all of the patches in my backlog (dense math registers, other
    -mcpu=future instructions, random bug fixes, support for _Float16 and
    __bf16, and optimizations for vector logical operations on power10/power11)
    into the IBM vendor branch:
    
            vendors/ibm/gcc-17-future
    
    2026-08-03  Michael Meissner  <[email protected]>
    
    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 __bf16 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 319d6cfe0eff..08f10b427f22 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -1305,6 +1305,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 3d7d65d2eca5..02c71cb783db 100755
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -5239,6 +5239,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"
@@ -5333,6 +5335,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
 
 case ${host} in
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 70b10ac31ef3..3c1262b8a2fd 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
 
 case ${host} in