https://gcc.gnu.org/g:36ad1e09a9eddacd63070e016cb5465d623efafe
commit 36ad1e09a9eddacd63070e016cb5465d623efafe Author: Michael Meissner <[email protected]> Date: Thu Oct 22 04:05:31 2026 -0400 Pass and return 16-bit fp library values in GPRs This patch changes all of the 16-bit floating point library functions to pass and return 16-bit floating point values as unsigned short. The intention is to prepare for modifying the calling sequence so that the values are converted to 32/64-bit scalar floating point. However, we can't call the library functions which are used to do the conversion if we have to convert the argument on a machine that does not have native conversion instructions. This patch adds support in libgcc to build the normal conversion functions and a modified conversion that has a _gpr suffix, and are the functions called when -mfloat16-gpr-convert is one. This patch also does conversions between TFmode, KFmode, IFmode and BFmode or HFmode even if we do not have hardware support for BFmode or HFmode. 2026-10-22 Michael Meissner <[email protected]> gcc/ * config/rs6000/float16.md (extend<FP16_HW:mode><FP16_FLOAT_CONVERT:mode>2): Allow insn even if we do not have hardware support. (trunc<FP16_FLOAT_CONVERT:mode><FP16_HW:mode>2): Likewise. * config/rs6000/rs6000-call.cc (FP16_USE_GPR): New macro. (USE_FP_FOR_ARG_P) Add support for 16-bit fp library functions passing 16-bit fp in GPR registers. (init_cumulative_args): Print the function name if it exists and if the function is a library function when -mdebug=ag is used. * config/rs6000/rs6000.cc (rs6000_debug_reg_global): Print 16-bit floating point information if -mdebug=reg. (init_float16): New function. Mark all of the 16-bit floating point library functions as passing/returning 16-bit floating point values in GPR registers and change the name to have a '_gpr' suffix. (rs6000_init_libfuncs): Likewise. (rs6000_opt_vars): Add -mfloat16-gpr-convert switch. * config/rs6000/rs6000.opt (-mfloat16-gpr-convert): New switch. libgcc/ * config/rs6000/convert-16bit-fp-extend: New file. * config/rs6000/convert-16bit-fp-fix: Likewise. * config/rs6000/convert-16bit-fp-float: Likewise. * config/rs6000/convert-16bit-fp-trunc: Likewise. * config/rs6000/ppc-eqbf2.c: Likewise. * config/rs6000/ppc-eqhf2.c: Likewise. * config/rs6000/ppc-fixbfbitint.c: Likewise. * config/rs6000/ppc-fixhfbitint.c: Likewise. * config/rs6000/ppc-floatbitintbf.c: Likewise. * config/rs6000/ppc-floatbitinthf.c: Likewise. * config/rs6000/ppc-truncbfhf2.c: Likewise. * config/rs6000/ppc-trunchfbf2.c: Likewise. * config/rs6000/sfp-machine.h: Add declarations for declaring the *_gpr library functions. * config/rs6000/t-float16: Build all of the new 16-bit floating point conversion functions that pass and return 16-bit floating point in GPR registers. Diff: --- gcc/config/rs6000/float16.md | 8 +- gcc/config/rs6000/rs6000-call.cc | 23 ++++- gcc/config/rs6000/rs6000.cc | 158 +++++++++++++++++++++++++++++ gcc/config/rs6000/rs6000.opt | 4 + libgcc/config/rs6000/sfp-machine.h | 111 +++++++++++++++----- libgcc/config/rs6000/t-float16 | 202 +++++++++++++++++++++++++++++++++---- 6 files changed, 453 insertions(+), 53 deletions(-) diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md index 1bbad9729c5e..6485f4d2d62d 100644 --- a/gcc/config/rs6000/float16.md +++ b/gcc/config/rs6000/float16.md @@ -729,9 +729,9 @@ ;; types might not have valid RTX expanders. We use DFmode as the ;; intermediate conversion destination. -(define_expand "extend<FP16_HW:mode><FP16_FLOAT_CONVERT:mode>2" +(define_expand "extend<FP16:mode><FP16_FLOAT_CONVERT:mode>2" [(use (match_operand:FP16_FLOAT_CONVERT 0 "vsx_register_operand")) - (use (match_operand:FP16_HW 1 "vsx_register_operand"))] + (use (match_operand:FP16 1 "vsx_register_operand"))] "can_create_pseudo_p ()" { rtx df_tmp = gen_reg_rtx (DFmode); @@ -741,8 +741,8 @@ DONE; }) -(define_expand "trunc<FP16_FLOAT_CONVERT:mode><FP16_HW:mode>2" - [(use (match_operand:FP16_HW 0 "vsx_register_operand")) +(define_expand "trunc<FP16_FLOAT_CONVERT:mode><FP16:mode>2" + [(use (match_operand:FP16 0 "vsx_register_operand")) (use (match_operand:FP16_FLOAT_CONVERT 1 "vsx_register_operand"))] "can_create_pseudo_p ()" { diff --git a/gcc/config/rs6000/rs6000-call.cc b/gcc/config/rs6000/rs6000-call.cc index 790f86218870..e970f63f2f08 100644 --- a/gcc/config/rs6000/rs6000-call.cc +++ b/gcc/config/rs6000/rs6000-call.cc @@ -81,10 +81,17 @@ #define TARGET_NO_PROTOTYPE 0 #endif -/* Nonzero if we can use a floating-point register to pass this arg. */ -#define USE_FP_FOR_ARG_P(CUM,MODE) \ - (SCALAR_FLOAT_MODE_NOT_VECTOR_P (MODE) \ - && (CUM)->fregno <= FP_ARG_MAX_REG \ +/* Whether we pass 16-bit floating point values in GPRs for library + calls. */ +#define FP16_USE_GPR(MODE, LIBCALL) \ + (FP16_SCALAR_MODE_P (MODE) && TARGET_FLOAT16_GPR_CONVERT && LIBCALL) + +/* Nonzero if we can use a floating-point register to pass this arg. 16-bit + floating point arguments to library functions are passed as ints. */ +#define USE_FP_FOR_ARG_P(CUM,MODE) \ + (SCALAR_FLOAT_MODE_NOT_VECTOR_P (MODE) \ + && !FP16_USE_GPR (MODE, (CUM)->libcall) \ + && (CUM)->fregno <= FP_ARG_MAX_REG \ && TARGET_HARD_FLOAT) /* Nonzero if we can use an AltiVec register to pass this arg. */ @@ -590,7 +597,7 @@ call_ABI_of_interest (tree fndecl) void init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, - rtx libname ATTRIBUTE_UNUSED, int incoming, + rtx libname, int incoming, int libcall, int n_named_args, tree fndecl, machine_mode return_mode ATTRIBUTE_UNUSED) @@ -653,6 +660,12 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, if (cum->call_cookie & CALL_LONG) fprintf (stderr, " longcall,"); + if (libname) + fprintf (stderr, " name=%s,", XSTR (libname, 0)); + + if (libcall) + fprintf (stderr, " libcall,"); + fprintf (stderr, " proto = %d, nargs = %d\n", cum->prototype, cum->nargs_prototype); } diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 7ae3c55f8a69..8107cd14a9a3 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -2636,6 +2636,33 @@ rs6000_debug_reg_global (void) if (TARGET_DIRECT_MOVE_128) fprintf (stderr, DEBUG_FMT_D, "VSX easy 64-bit mfvsrld element", (int)VECTOR_ELEMENT_MFVSRLD_64BIT); + + if (TARGET_FLOAT16) + { + fprintf (stderr, DEBUG_FMT_S, "_Float16", + (TARGET_FLOAT16_HW ? "hardware" : "software")); + fprintf (stderr, DEBUG_FMT_S, "__bf16", + (TARGET_BFLOAT16_HW ? "hardware" : "software")); + fprintf (stderr, DEBUG_FMT_S, "-mfloat16-gpr-convert", + (TARGET_FLOAT16_GPR_CONVERT ? "yes" : "no")); + +#if POWERPC_FLOAT16_DEFAULT + fprintf (stderr, DEBUG_FMT_S, "float16 configured", "enabled"); +#else + fprintf (stderr, DEBUG_FMT_S, "float16 configured", "disabled"); +#endif + +#if POWERPC_FLOAT16_DISABLE_WARNING + fprintf (stderr, DEBUG_FMT_S, "float16 call warnings", "disabled"); +#else + fprintf (stderr, DEBUG_FMT_S, "float16 call warnings", "enabled"); +#endif + } + else + { + fprintf (stderr, DEBUG_FMT_S, "_Float16", "disabled"); + fprintf (stderr, DEBUG_FMT_S, "__bf16", "disabled"); + } } @@ -11837,6 +11864,128 @@ init_float128_ieee (machine_mode mode) } } +/* For 16-bit floating point, mark the identifier of the conversion functions + so they pass/register the HFmode and BFmode in a GPR register rather than a + floating point register. Thus if HFmode/BFmode are converted to DFmode for + passing and returning values, we can do the conversion on machines that + don't have the conversions. */ + +static void +init_float16 (void) +{ + char fname[80]; + + /* Map mode to a string. */ + struct mode_string { + const enum machine_mode mode; + const char *const name; + }; + + const static struct mode_string fp16_modes[] = { + { E_BFmode, "bf" }, + { E_HFmode, "hf" }, + }; + + const static struct mode_string fp_modes[] = { + { E_SFmode, "sf" }, + { E_DFmode, "df" }, + }; + + const static struct mode_string int_modes[] = { + { E_SImode, "si" }, + { E_DImode, "di" }, + { E_TImode, "ti" }, + }; + + for (size_t i = 0; i < ARRAY_SIZE (fp16_modes); i++) + { + enum machine_mode fp16_mode = fp16_modes[i].mode; + const char *fp16_name = fp16_modes[i].name; + + /* Conversions between {SFmode,DFmode} <=> {BFmode,HFmode}. */ + for (size_t j = 0; j < ARRAY_SIZE (fp_modes); j++) + { + enum machine_mode fp_mode = fp_modes[j].mode; + const char *fp_name = fp_modes[j].name; + + sprintf (fname, "__extend%s%s2_gpr", fp16_name, fp_name); + set_conv_libfunc (sext_optab, fp_mode, fp16_mode, fname); + if (TARGET_DEBUG_ARG) + fprintf (stderr, "Special %s to %s conversion: %s\n", + fp16_name, fp_name, fname); + + sprintf (fname, "__trunc%s%s2_gpr", fp_name, fp16_name); + set_conv_libfunc (trunc_optab, fp16_mode, fp_mode, fname); + if (TARGET_DEBUG_ARG) + fprintf (stderr, "Special %s to %s conversion: %s\n", + fp_name, fp16_name, fname); + } + + /* Conversions between {SImode,DImode} <=> {BFmode,HFmode}. */ + for (size_t j = 0; j < ARRAY_SIZE (int_modes); j++) + { + enum machine_mode int_mode = int_modes[j].mode; + const char *int_name = int_modes[j].name; + + if (int_mode == SImode || TARGET_POWERPC64) + { + sprintf (fname, "__float%s%s_gpr", int_name, fp16_name); + set_conv_libfunc (sfloat_optab, fp16_mode, int_mode, fname); + if (TARGET_DEBUG_ARG) + fprintf (stderr, "Special signed %s to %s conversion: %s\n", + int_name, fp16_name, fname); + + sprintf (fname, "__floatun%s%s_gpr", int_name, fp16_name); + set_conv_libfunc (ufloat_optab, fp16_mode, int_mode, fname); + if (TARGET_DEBUG_ARG) + fprintf (stderr, "Special unsigned %s to %s conversion: %s\n", + int_name, fp16_name, fname); + + sprintf (fname, "__fix%s%s_gpr", fp16_name, int_name); + set_conv_libfunc (sfix_optab, int_mode, fp16_mode, fname); + if (TARGET_DEBUG_ARG) + fprintf (stderr, "Special signed %s to %s conversion: %s\n", + fp16_name, int_name, fname); + + sprintf (fname, "__fixuns%s%s_gpr", fp16_name, int_name); + set_conv_libfunc (ufix_optab, int_mode, fp16_mode, fname); + if (TARGET_DEBUG_ARG) + fprintf (stderr, "Special unsigned %s to %s conversion: %s\n", + fp16_name, int_name, fname); + } + } + + /* Conversions between the two 16-bit floating point formats. */ + for (size_t j = 0; j < ARRAY_SIZE (fp16_modes); j++) + { + enum machine_mode fp16_mode2 = fp16_modes[j].mode; + const char *fp16_name2 = fp16_modes[j].name; + + if (fp16_mode != fp16_mode2) + { + sprintf (fname, "__trunc%s%s2_gpr", fp16_name, fp16_name2); + set_conv_libfunc (trunc_optab, fp16_mode2, fp16_mode, fname); + if (TARGET_DEBUG_ARG) + fprintf (stderr, "Special signed %s to %s conversion: %s\n", + fp16_name, fp16_name2, fname); + } + } + + /* Bitint support. */ + sprintf (fname, "__floatbitint%s_gpr", fp16_name); + set_optab_libfunc (bitinttofp_optab, fp16_mode, fname); + if (TARGET_DEBUG_ARG) + fprintf (stderr, "Special %s to bitint conversion: %s\n", + fp16_name, fname); + + sprintf (fname, "__fix%sbitint_gpr", fp16_name); + set_optab_libfunc (bitintfromfp_optab, fp16_mode, fname); + if (TARGET_DEBUG_ARG) + fprintf (stderr, "Special bitint to %s conversion: %s\n", + fp16_name, fname); + } +} + static void rs6000_init_libfuncs (void) { @@ -11857,6 +12006,10 @@ rs6000_init_libfuncs (void) else init_float128_ieee (TFmode); } + + /* 16-bit float support functions. */ + if (TARGET_FLOAT16 && TARGET_FLOAT16_GPR_CONVERT) + init_float16 (); } /* Emit a potentially record-form instruction, setting DST from SRC. @@ -24450,6 +24603,8 @@ rs6000_libcall_value (machine_mode mode) if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT) /* _Decimal128 must use an even/odd register pair. */ regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN; + else if (FP16_SCALAR_MODE_P (mode) && TARGET_FLOAT16_GPR_CONVERT) + regno = GP_ARG_RETURN; else if (SCALAR_FLOAT_MODE_NOT_VECTOR_P (mode) && TARGET_HARD_FLOAT) regno = FP_ARG_RETURN; /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same @@ -25042,6 +25197,9 @@ static struct rs6000_opt_var const rs6000_opt_vars[] = { "speculate-indirect-jumps", offsetof (struct gcc_options, x_rs6000_speculate_indirect_jumps), offsetof (struct cl_target_option, x_rs6000_speculate_indirect_jumps), }, + { "float16-gpr-convert", + offsetof (struct gcc_options, x_TARGET_FLOAT16_GPR_CONVERT), + offsetof (struct cl_target_option, x_TARGET_FLOAT16_GPR_CONVERT), }, }; /* Inner function to handle attribute((target("..."))) and #pragma GCC target diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index f39d6f0a3107..83b99bd1b491 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -658,6 +658,10 @@ mfloat16-debug2 Target Undocumented Var(TARGET_FLOAT16_DEBUG2) Init(0) Save Turn on float16 debugging #2. +mfloat16-gpr-convert +Target Undocumented Var(TARGET_FLOAT16_GPR_CONVERT) Init(1) Save +Pass/return (do not pass/return) 16-it float conversions in GPR registers. + ; Documented parameters -param=rs6000-vect-unroll-limit= diff --git a/libgcc/config/rs6000/sfp-machine.h b/libgcc/config/rs6000/sfp-machine.h index b6dd03a710e3..b37bf0903a87 100644 --- a/libgcc/config/rs6000/sfp-machine.h +++ b/libgcc/config/rs6000/sfp-machine.h @@ -170,42 +170,105 @@ void __sfp_handle_exceptions (int); /* 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 HItype2 __attribute__ ((mode (HI))); +typedef unsigned int UHItype2 __attribute__ ((mode (HI))); typedef int SItype2 __attribute__ ((mode (SI))); typedef unsigned int USItype2 __attribute__ ((mode (SI))); +typedef int DItype2 __attribute__ ((mode (DI))); +typedef unsigned int UDItype2 __attribute__ ((mode (DI))); +typedef int TItype2 __attribute__ ((mode (TI))); +typedef unsigned int UTItype2 __attribute__ ((mode (TI))); + +/* We have 2 different conversion functions. One passes or returns the 16-bit + floating point type in a floating point register, and the other passes or + returns it in a general purpose register. If 16-bit floating point is + normally converted to the 32/64-bit scalar represention, we need a function + that does not do this conversion. */ +#define PASS_FP16(NAME, RET, FP16) \ +extern RET NAME (FP16); \ +extern RET NAME ## _gpr (UHItype2) + +#define PASS_FP16_2(NAME, RET, FP16_1, FP16_2) \ +extern RET NAME (FP16_1, FP16_2); \ +extern RET NAME ## _gpr (UHItype2, UHItype2) + +#define RETURN_FP16(NAME, FP16, ARG) \ +extern FP16 NAME (ARG); \ +extern UHItype2 NAME ## _gpr (ARG) + +#define CONVERT_FP16(NAME, FP16_RET, FP16_ARG) \ +extern FP16_RET NAME (FP16_ARG); \ +extern UHItype2 NAME ## _gpr (UHItype2) #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); +/* Move between HFtype and unsigned short. */ +union ushort_hf { + unsigned short us; + HFtype2 hf; +}; + +PASS_FP16_2 (__eqhf2, CMPtype, HFtype2, HFtype2); + +PASS_FP16 (__extendhfsf2, SFtype2, HFtype2); +PASS_FP16 (__extendhfdf2, DFtype2, HFtype2); + +PASS_FP16 (__fixhfsi, SItype2, HFtype2); +PASS_FP16 (__fixhfdi, DItype2, HFtype2); +PASS_FP16 (__fixhfti, TItype2, HFtype2); + +PASS_FP16 (__fixunshfsi, USItype2, HFtype2); +PASS_FP16 (__fixunshfdi, UDItype2, HFtype2); +PASS_FP16 (__fixunshfti, UTItype2, HFtype2); + +RETURN_FP16 (__floatsihf, HFtype2, SItype2); +RETURN_FP16 (__floatdihf, HFtype2, DItype2); +RETURN_FP16 (__floattihf, HFtype2, TItype2); + +RETURN_FP16 (__floatunsihf, HFtype2, USItype2); +RETURN_FP16 (__floatundihf, HFtype2, UDItype2); +RETURN_FP16 (__floatuntihf, HFtype2, UTItype2); + +RETURN_FP16 (__truncsfhf2, HFtype2, SFtype2); +RETURN_FP16 (__truncdfhf2, HFtype2, DFtype2); #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); +/* Move between BFtype and unsigned short. */ +union ushort_bf { + unsigned short us; + BFtype2 bf; +}; + +PASS_FP16_2 (__eqbf2, CMPtype, BFtype2, BFtype2); + +PASS_FP16 (__extendbfsf2, SFtype2, BFtype2); +PASS_FP16 (__extendbfdf2, DFtype2, BFtype2); + +PASS_FP16 (__fixbfsi, SItype2, BFtype2); +PASS_FP16 (__fixbfdi, DItype2, BFtype2); +PASS_FP16 (__fixbfti, TItype2, BFtype2); + +PASS_FP16 (__fixunsbfsi, USItype2, BFtype2); +PASS_FP16 (__fixunsbfdi, UDItype2, BFtype2); +PASS_FP16 (__fixunsbfti, UTItype2, BFtype2); + +RETURN_FP16 (__floatsibf, BFtype2, SItype2); +RETURN_FP16 (__floatdibf, BFtype2, DItype2); +RETURN_FP16 (__floattibf, BFtype2, TItype2); + +RETURN_FP16 (__floatunsibf, BFtype2, USItype2); +RETURN_FP16 (__floatundibf, BFtype2, UDItype2); +RETURN_FP16 (__floatuntibf, BFtype2, UTItype2); + +RETURN_FP16 (__truncsfbf2, BFtype2, SFtype2); +RETURN_FP16 (__truncdfbf2, BFtype2, DFtype2); #endif #if defined(__FLOAT16__) && defined(__BFLOAT16__) -extern HFtype2 __truncbfhf2 (BFtype2); -extern BFtype2 __trunchfbf2 (HFtype2); +CONVERT_FP16 (__truncbfhf2, HFtype2, BFtype2); +CONVERT_FP16 (__trunchfbf2, BFtype2, HFtype2); #endif diff --git a/libgcc/config/rs6000/t-float16 b/libgcc/config/rs6000/t-float16 index f77df910b3ff..2e5c04e44a7c 100644 --- a/libgcc/config/rs6000/t-float16 +++ b/libgcc/config/rs6000/t-float16 @@ -1,42 +1,160 @@ -# _Float16 library support +PERL := perl -fp16_funcs = eqhf2 extendhfdf2 extendhfsf2 \ - fixhfsi fixhfdi fixhfti fixunshfsi fixunshfdi fixunshfti \ - floatsihf floatdihf floattihf floatunsihf floatundihf floatuntihf \ - truncdfhf2 truncsfhf2 +# _Float16 library support, source files in soft-ftp +fp16_funcs = ppc-eqhf2 ppc-floatbitinthf ppc-fixhfbitint -fp16_src = $(addprefix $(srcdir)/soft-fp/,$(addsuffix .c,$(fp16_funcs))) +fp16_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix .c,$(fp16_funcs))) fp16_obj = $(addsuffix $(objext),$(fp16_funcs)) FP16_CFLAGS = -mfloat16 -Wno-psabi \ - -I$(srcdir)/soft-fp -I$(srcdir)/config/rs6000 + -I$(srcdir)/soft-fp \ + -I$(srcdir)/config/rs6000 $(fp16_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS) -# __bfloat16 library support +# __bf16 library support, source files in config/rs6000 +bfp16_funcs = ppc-eqbf2 ppc-floatbitintbf ppc-fixbfbitint -bfp16_funcs = extendbfsf2 floatdibf floatsibf floatundibf floatunsibf \ - truncdfbf2 truncsfbf2 - -bfp16_src = $(addprefix $(srcdir)/soft-fp/,$(addsuffix .c,$(bfp16_funcs))) +bfp16_src = $(addprefix $(srcdir)/config/rs6000/,$(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))) +# Conversion between __bf16 and _Float16 +both_fp16_funcs = ppc-truncbfhf2 ppc-trunchfbf2 +both_fp16_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix .c,$(both_fp16_funcs))) both_fp16_obj = $(addsuffix $(objext),$(both_fp16_funcs)) $(both_fp16_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS) +# Convert functions in soft-fp to powerpc, building 2 versions, one +# with normal __bf16/_Float16 arguments, and the other where we +# pass/return 16-bit floating point in gprs. + +float16_prefix = ppc- +float16_dep = $(srcdir)/config/rs6000/t-float16 + +# We don't have a full set of BFmode conversions in soft-fp, so modify the HFmode +# conversions to do what we want for BFmode as well as HFmode. +float16_fix_ti_orig = $(srcdir)/soft-fp/fixhfti.c +float16_fix_di_orig = $(srcdir)/soft-fp/fixhfdi.c +float16_fix_si_orig = $(srcdir)/soft-fp/fixhfsi.c +float16_fixuns_ti_orig = $(srcdir)/soft-fp/fixunshfti.c +float16_fixuns_di_orig = $(srcdir)/soft-fp/fixunshfdi.c +float16_fixuns_si_orig = $(srcdir)/soft-fp/fixunshfsi.c +float16_extend_orig = $(srcdir)/soft-fp/extendhfsf2.c +float16_trunc_orig = $(srcdir)/soft-fp/truncsfhf2.c + +float16_fix_script = $(srcdir)/config/rs6000/convert-16bit-fp-fix +float16_float_script = $(srcdir)/config/rs6000/convert-16bit-fp-float +float16_extend_script = $(srcdir)/config/rs6000/convert-16bit-fp-extend +float16_trunc_script = $(srcdir)/config/rs6000/convert-16bit-fp-trunc + +float16_fix_ti_funcs = fixhfti fixbfti +float16_fix_di_funcs = fixhfdi fixbfdi +float16_fix_si_funcs = fixhfsi fixbfsi +float16_fixuns_ti_funcs = fixunshfti fixunsbfti +float16_fixuns_di_funcs = fixunshfdi fixunsbfdi +float16_fixuns_si_funcs = fixunshfsi fixunsbfsi + +float16_fix_ti_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fix_ti_funcs))) +float16_fix_di_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fix_di_funcs))) +float16_fix_si_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fix_si_funcs))) +float16_fixuns_ti_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fixuns_ti_funcs))) +float16_fixuns_di_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fixuns_di_funcs))) +float16_fixuns_si_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fixuns_si_funcs))) + +float16_fix_funcs = $(float16_fix_ti_funcs) \ + $(float16_fix_di_funcs) \ + $(float16_fix_si_funcs) \ + $(float16_fixuns_ti_funcs) \ + $(float16_fixuns_di_funcs) \ + $(float16_fixuns_si_funcs) + +float16_fix_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_fix_funcs))) +float16_fix_dep = $(float16_fix_orig) \ + $(float16_fix_script) \ + $(float16_dep) + +float16_float_sign_funcs = floattihf floatdihf floatsihf \ + floattibf floatdibf floatsibf + +float16_float_uns_funcs = floatuntihf floatundihf floatunsihf \ + floatuntibf floatundibf floatunsibf + +float16_float_uns_obj = $(addprefix $(float16_prefix),$(addsuffix $(objext),$(float16_float_uns_funcs))) + +float16_float_funcs = $(float16_float_sign_funcs) \ + $(float16_float_uns_funcs) + +float16_float_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_float_funcs))) +float16_float_dep = $(float16_float_script) \ + +float16_extend_funcs = extendhfsf2 extendhfdf2 extendbfsf2 extendbfdf2 +float16_extend_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_extend_funcs))) +float16_extend_dep = $(float16_extend_orig) \ + $(float16_extend_script) \ + $(float16_dep) + +float16_trunc_funcs = truncdfbf2 truncdfhf2 truncsfbf2 truncsfhf2 +float16_trunc_src = $(addprefix $(float16_prefix),$(addsuffix .c,$(float16_trunc_funcs))) +float16_trunc_dep = $(float16_trunc_orig) \ + $(float16_trunc_script) \ + $(float16_dep) + +float16_all_funcs = $(float16_fix_funcs) \ + $(float16_float_funcs) \ + $(float16_extend_funcs) \ + $(float16_trunc_funcs) + +float16_all_src = $(float16_fix_src) \ + $(float16_float_src) \ + $(float16_extend_src) \ + $(float16_trunc_src) + +float16_all_obj = $(addprefix $(float16_prefix),$(addsuffix $(objext),$(float16_all_funcs))) + +$(float16_all_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS) + +# Turn off the unsigned comparison is always false warning in the +# conversion from unsigned int to float +$(float16_float_uns_obj) : INTERNAL_CFLAGS += -Wno-type-limits + +# Build the ppc-* sources +$(float16_fix_ti_src) : $(float16_fix_ti_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fix_ti_orig) > $@ + +$(float16_fix_di_src) : $(float16_fix_di_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fix_di_orig) > $@ + +$(float16_fix_si_src) : $(float16_fix_si_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fix_si_orig) > $@ + +$(float16_fixuns_ti_src) : $(float16_fixuns_ti_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fixuns_ti_orig) > $@ + +$(float16_fixuns_di_src) : $(float16_fixuns_di_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fixuns_di_orig) > $@ + +$(float16_fixuns_si_src) : $(float16_fixuns_si_orig) $(float16_fix_dep) + $(PERL) $(float16_fix_script) -t $@ $(float16_fixuns_si_orig) > $@ + +$(float16_float_src) : $(subst $(float16_prefix),$(srcdir)/soft-fp/,$@) $(float16_float_dep) + $(PERL) $(float16_float_script) -t $@ $(subst $(float16_prefix),$(srcdir)/soft-fp/,$@) > $@ + +$(float16_extend_src) : $(float16_extend_dep) + $(PERL) $(float16_extend_script) -t $@ $(float16_extend_orig) > $@ + +$(float16_trunc_src) : $(float16_trunc_dep) + $(PERL) $(float16_trunc_script) -t $@ $(float16_trunc_orig) > $@ + # For now, only put it in the static library -# LIB2ADD += $(fp16_src) $(bfp16_src) $(both_fp16_src) +# LIB2ADD += $(fp16_src) $(bfp16_src) $(both_fp16_src) $(float16_all_src) -LIB2ADD_ST += $(fp16_src) $(bfp16_src) $(both_fp16_src) +LIB2ADD_ST += $(fp16_src) $(bfp16_src) $(both_fp16_src) \ + $(float16_all_src) -.PHONY: test-float16 clean-float16 +.PHONY: test-float16 clean-float16 ppc-srcfiles test-float16: @echo "fp16_src:"; \ @@ -55,7 +173,51 @@ test-float16: for x in $(bfp16_obj); do echo " $$x"; done; \ echo; \ echo "both_fp16_obj:"; \ - for x in $(bfp16_obj); do echo " $$x"; done; + for x in $(bfp16_obj); do echo " $$x"; done; \ + echo; \ + echo "float16_fix_funcs:"; \ + for x in $(float16_fix_funcs); do echo " $$x"; done; \ + echo; \ + echo "float16_float_funcs:"; \ + for x in $(float16_float_funcs); do echo " $$x"; done; \ + echo; \ + echo "float16_extend_funcs:"; \ + for x in $(float16_extend_funcs); do echo " $$x"; done; \ + echo; \ + echo "float16_trunc_funcs:"; \ + for x in $(float16_trunc_funcs); do echo " $$x"; done; \ + echo; \ + echo "float16_all_funcs:"; \ + for x in $(float16_all_funcs); do echo " $$x"; done; \ + echo; \ + echo "float16_all_src:"; \ + for x in $(float16_all_src); do echo " $$x"; done; \ + echo; \ + echo "float16_all_obj:"; \ + for x in $(float16_all_obj); do echo " $$x"; done; \ + echo; \ + echo "LIB2ADD_ST:"; \ + for x in $(LIB2ADD_ST); do echo " $$x"; done; \ + echo; \ + echo "float16_prefix = $(float16_prefix)"; \ + echo "float16_fix_ti_orig = $(float16_fix_ti_orig)"; \ + echo "float16_fix_di_orig = $(float16_fix_di_orig)"; \ + echo "float16_fix_si_orig = $(float16_fix_si_orig)"; \ + echo "float16_fixuns_ti_orig = $(float16_fixuns_ti_orig)"; \ + echo "float16_fixuns_di_orig = $(float16_fixuns_di_orig)"; \ + echo "float16_fixuns_si_orig = $(float16_fixuns_si_orig)"; \ + echo "float16_extend_orig = $(float16_extend_orig)"; \ + echo "float16_trunc_orig = $(float16_trunc_orig)"; \ + echo; \ + echo "float16_fix_script = $(float16_fix_script)"; \ + echo "float16_float_script = $(float16_float_script)"; \ + echo "float16_extend_script = $(float16_extend_script)"; \ + echo "float16_trunc_script = $(float16_trunc_script)"; \ + echo clean-float16: @$(MULTICLEAN) multi-clean DO=clean-float16 + rm -f $(float16_all_src) ppc-srcfiles + +ppc-srcfiles: $(float16_all_src) + @touch ppc-srcfiles
