https://gcc.gnu.org/g:b4f3b9423015a33402e39c31817629d8b9b1ce9d

commit b4f3b9423015a33402e39c31817629d8b9b1ce9d
Author: Michael Meissner <[email protected]>
Date:   Mon Dec 8 14:52:16 2025 -0500

    Add initial 16-bit floating point support.
    
    This patch adds the initial support for the 16-bit floating point formats.
    _Float16 is the IEEE 754 half precision format.  __bfloat16 is the Google 
Brain
    16-bit format.
    
    In order to use both _Float16 and __bfloat16, the user has to use the 
-mfloat16
    option to enable the support.
    
    In this patch only the machine indepndent support is used.  In order to be
    usable, the next patch will also need to be installed. That patch will add
    support in libgcc for 16-bit floating point support.
    
    2025-12-08  Michael Meissner  <[email protected]>
    
    gcc/
    
            * config/rs6000/constraints.md (eZ): New constraint for -0.0.
            * config/rs6000/float16.md: New file to add basic 16-bit floating 
point
            support.
            * config/rs6000/predicates.md (easy_fp_constant): Add support for 
HFmode
            and BFmode constants.
            (easy_vector_constant): Add support for V8HFmode and V8BFmode to 
load up
            the vector -0.0 constant.
            (minus_zero_constant): New predicate.
            (fp16_xxspltiw_constant): Likewise.
            * config/rs6000/rs6000-builtin.cc (rs6000_type_string): Add support 
for
            16-bit floating point types.
            (rs6000_init_builtins): Create the bfloat16_type_node if needed.
            * config/rs6000/rs6000-c.cc (rs6000_target_modify_macros): Define
            __FLOAT16__ and __BFLOAT16__ if 16-bit floating pont is enabled.
            * config/rs6000/rs6000-call.cc (init_cumulative_args): Warn if a
            function returns a 16-bit floating point value unless -Wno-psabi is
            used.
            (rs6000_function_arg): Warn if a 16-bit floating point value is 
passed
            to a function unless -Wno-psabi is ued.
            * config/rs6000/rs6000-protos.h (vec_const_128bit_type): Add mode 
field
            to detect initializing 16-bit floating constants.
            * config/rs6000/rs6000.cc (rs6000_hard_regno_mode_ok_uncached): Add
            support for 16-bit floating point.
            (rs6000_modes_tieable_p): Don't allow 16-bit floating point modes 
to tie
            with other modes.
            (rs6000_debug_reg_global): Add BFmode and HFmode.
            (rs6000_setup_reg_addr_masks): Add support for 16-bit floating point
            types.
            (rs6000_setup_reg_addr_masks): Likewise.
            (rs6000_init_hard_regno_mode_ok): Likewise.
            (rs6000_option_override_internal): Add a check whether -mfloat16 
can be
            used.
            (easy_altivec_constant): Add suport for 16-bit floating point.
            (xxspltib_constant_p): Likewise.
            (rs6000_expand_vector_init): Likewise.
            (rs6000_expand_vector_set): Likewise.
            (rs6000_expand_vector_extract): Likewise.
            (rs6000_split_vec_extract_var): Likewise.
            (reg_offset_addressing_ok_p): Likewise.
            (rs6000_legitimate_offset_address_p): Likewise.
            (legitimate_lo_sum_address_p): Likewise.
            (rs6000_secondary_reload_simple_move): Likewise.
            (rs6000_preferred_reload_class): Likewise.
            (rs6000_can_change_mode_class): Likewise.
            (rs6000_output_move_128bit): Likewise.
            (rs6000_load_constant_and_splat): Likewise.
            (rs6000_scalar_mode_supported_p): Likewise.
            (rs6000_libgcc_floating_mode_supported_p): Return true for HFmode 
and
            BFmode if -mfloat16.
            (rs6000_floatn_mode): Enable _Float16 if -mfloat16.
            (rs6000_opt_masks): Add -mfloat16.
            (constant_fp_to_128bit_vector): Add support for 16-bit floating 
point.
            (vec_const_128bit_to_bytes): Likewise.
            (constant_generates_xxspltiw): Likewise.
            * config/rs6000/rs6000.h (FP16_SCALAR_MODE_P): Ne macro.
            (FP16_VECTOR_MODE_P): Likewise.
            (TARGET_BFLOAT16_HW): New macro.
            (TARGET_FLOAT16_HW): Likewise.
            (TARGET_BFLOAT16_HW_VECTOR): Likewise.
            (TARGET_FLOAT16_HW_VECTOR): Likewise.
            * config/rs6000/rs6000.md (wd): Add BFmode and HFmode.
            (toplevel): Include float16.md.
            * config/rs6000/rs6000.opt (-mloat16): New option.
            * doc/invoke.texi (RS/6000 and PowerPC Options): Document -mfloat16.

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 82ea1772f516..e1b9cd055be8 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 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 d5e80d227ff6..d53bcf5a1277 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 65cd3c6aa1a5..0e95dc97c867 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.

Reply via email to