>From 698a22ded27f3a1b85f496b2a777730186994605 Mon Sep 17 00:00:00 2001
From: Michael Meissner <[email protected]>
Date: Fri, 14 Nov 2025 03:11:08 -0500
Subject: [PATCH 212/219] 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.

All 11 patches have been tested on little endian and big endian PowerPC
servers with no regressions.  Can I check in these patches?

2025-11-14  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.
---
 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(+)
 create mode 100644 libgcc/config/rs6000/t-float16

diff --git a/libgcc/config.host b/libgcc/config.host
index 82ea1772f51..e1b9cd055be 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 f0ede0e042a..b6dd03a710e 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 00000000000..f77df910b3f
--- /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 d5e80d227ff..d53bcf5a127 100755
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -5188,6 +5188,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"
@@ -5282,6 +5284,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 65cd3c6aa1a..0e95dc97c86 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -407,6 +407,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"
@@ -465,6 +467,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.
-- 
2.51.1


-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: [email protected]

Reply via email to