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

Michael Meissner via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:a03ad5538d890ea1a2d6f675d20872363e26a20b

commit a03ad5538d890ea1a2d6f675d20872363e26a20b
Author: Michael Meissner <[email protected]>
Date:   Mon Jul 27 00:44:32 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
    __bfloat16, and optimizations for vector logical operations on power10/power11)
    into the IBM vendor branch:
    
            vendors/ibm/gcc-17-future
    
    2026-07-27  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 __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 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.