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-01 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 a685d5da7a1..b066712d003 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 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 f2bee6d90fe..2e4b564100c 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
case ${host} in
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 72d23b427d0..ea53fd799e1 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
--
2.54.0
--
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: [email protected]