>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]
