https://gcc.gnu.org/g:218f857bbf9785b4cd17155f067e1389e876c325
commit 218f857bbf9785b4cd17155f067e1389e876c325 Author: Michael Meissner <[email protected]> Date: Tue Oct 27 01:37:12 2026 -0400 Add 16-bit floating point pow support. This patch adds simple pow and powi support functions for 16-bit floating point types. 2026-10-27 Michael Meissner <[email protected]> libgcc/ * config/rs6000/ppc-powbf16.c: New file. * config/rs6000/ppc-powf16.c: Likewise. * config/rs6000/sfp-machine.h: Add 16-bit pow and powi support. * config/rs6000/t-float16: Likewise. Diff: --- libgcc/config/rs6000/ppc-powbf16.c | 106 +++++++++++++++++++++++++++++++++++++ libgcc/config/rs6000/ppc-powf16.c | 106 +++++++++++++++++++++++++++++++++++++ libgcc/config/rs6000/sfp-machine.h | 12 +++++ libgcc/config/rs6000/t-float16 | 4 +- 4 files changed, 226 insertions(+), 2 deletions(-) diff --git a/libgcc/config/rs6000/ppc-powbf16.c b/libgcc/config/rs6000/ppc-powbf16.c new file mode 100644 index 000000000000..89602838dbb3 --- /dev/null +++ b/libgcc/config/rs6000/ppc-powbf16.c @@ -0,0 +1,106 @@ +/* Software floating-point emulation. + Return 0 iff a == b, 1 otherwise + Copyright (C) 2021-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + The code is cloned from the code in libgcc2.c (which handles the standard + SF, DF, TF, and XF types). + + We provide 2 conversions, one that returns the BFtype in a floating point + register and the other returns it in a general purpose register that is used + when BFtype must be converted to the 32/64-bit scalar type. */ + +#include "soft-fp.h" +#include "brain.h" + +#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1 +#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1 +#define __STDC_WANT_IEC_60559_BFP_EXT__ 1 + +#include <math.h> + +#define ONE ((BFtype) 1.0) + +BFtype +powbf16 (BFtype x, BFtype y) +{ + return (BFtype) powf ((float) x, (float) y); +} + +BFtype +__powibf2 (BFtype x, SItype m) +{ + unsigned int n = m < 0 ? -m : m; + BFtype y = n % 2 ? x : ONE; + + while (n >>= 1) + { + x = x * x; + if (n % 2) + y = y * x; + } + + return m < 0 ? ONE/y : y; +} + +/* Versions of the pow functions that pass and return _Float16 values in + gprs. */ + + +unsigned short +powbf16_gpr (unsigned short us_x, unsigned short us_y) +{ + union ushort_bf u_x, u_y, u_r; + + u_x.us = us_x; + u_y.us = us_y; + u_r.bf = (BFtype) powf ((float) u_x.bf, (float) u_y.bf); + + return u_r.us; +} + +unsigned short +__powibf2_gpr (unsigned short us_x, SItype m) +{ + union ushort_bf u_x, u_r; + unsigned int n; + BFtype x, y; + + u_x.us = us_x; + n = m < 0 ? -m : m; + x = u_x.bf; + y = n % 2 ? x : ONE; + + while (n >>= 1) + { + x = x * x; + if (n % 2) + y = y * x; + } + + u_r.bf = m < 0 ? ONE/y : y; + return u_r.us; +} diff --git a/libgcc/config/rs6000/ppc-powf16.c b/libgcc/config/rs6000/ppc-powf16.c new file mode 100644 index 000000000000..146fa68599ca --- /dev/null +++ b/libgcc/config/rs6000/ppc-powf16.c @@ -0,0 +1,106 @@ +/* Software floating-point emulation. + Return 0 iff a == b, 1 otherwise + Copyright (C) 2021-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file into + combinations with other programs, and to distribute those + combinations without any restriction coming from the use of this + file. (The Lesser General Public License restrictions do apply in + other respects; for example, they cover modification of the file, + and distribution when not linked into a combine executable.) + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + The code is cloned from the code in libgcc2.c (which handles the standard + SF, DF, TF, and XF types). + + We provide 2 conversions, one that returns the BFtype in a floating point + register and the other returns it in a general purpose register that is used + when BFtype must be converted to the 32/64-bit scalar type. */ + +#include "soft-fp.h" +#include "half.h" + +#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1 +#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1 +#define __STDC_WANT_IEC_60559_BFP_EXT__ 1 + +#include <math.h> + +#define ONE ((HFtype) 1.0) + +HFtype +powf16 (HFtype x, HFtype y) +{ + return (HFtype) powf ((float) x, (float) y); +} + +HFtype +__powihf2 (HFtype x, SItype m) +{ + unsigned int n = m < 0 ? -m : m; + HFtype y = n % 2 ? x : ONE; + + while (n >>= 1) + { + x = x * x; + if (n % 2) + y = y * x; + } + + return m < 0 ? ONE/y : y; +} + +/* Versions of the pow functions that pass and return _Float16 values in + gprs. */ + + +unsigned short +powf16_gpr (unsigned short us_x, unsigned short us_y) +{ + union ushort_hf u_x, u_y, u_r; + + u_x.us = us_x; + u_y.us = us_y; + u_r.hf = (HFtype) powf ((float) u_x.hf, (float) u_y.hf); + + return u_r.us; +} + +unsigned short +__powihf2_gpr (unsigned short us_x, SItype m) +{ + union ushort_hf u_x, u_r; + unsigned int n; + HFtype x, y; + + u_x.us = us_x; + n = m < 0 ? -m : m; + x = u_x.hf; + y = n % 2 ? x : ONE; + + while (n >>= 1) + { + x = x * x; + if (n % 2) + y = y * x; + } + + u_r.hf = m < 0 ? ONE/y : y; + return u_r.us; +} diff --git a/libgcc/config/rs6000/sfp-machine.h b/libgcc/config/rs6000/sfp-machine.h index b37bf0903a87..5e87e3e0b4da 100644 --- a/libgcc/config/rs6000/sfp-machine.h +++ b/libgcc/config/rs6000/sfp-machine.h @@ -232,6 +232,12 @@ RETURN_FP16 (__floatuntihf, HFtype2, UTItype2); RETURN_FP16 (__truncsfhf2, HFtype2, SFtype2); RETURN_FP16 (__truncdfhf2, HFtype2, DFtype2); + +extern HFtype2 powf16 (HFtype2, HFtype2); +extern UHItype2 powf16_gpr (UHItype2, UHItype2); + +extern HFtype2 __powihf2 (HFtype2, SItype2); +extern UHItype2 __powihf2_gpr (UHItype2, SItype2); #endif #ifdef __BFLOAT16__ @@ -266,6 +272,12 @@ RETURN_FP16 (__floatuntibf, BFtype2, UTItype2); RETURN_FP16 (__truncsfbf2, BFtype2, SFtype2); RETURN_FP16 (__truncdfbf2, BFtype2, DFtype2); + +extern BFtype2 powbf16 (BFtype2, BFtype2); +extern UHItype2 powbf16_gpr (UHItype2, UHItype2); + +extern BFtype2 __powibf2 (BFtype2, SItype2); +extern UHItype2 __powibf2_gpr (UHItype2, SItype2); #endif #if defined(__FLOAT16__) && defined(__BFLOAT16__) diff --git a/libgcc/config/rs6000/t-float16 b/libgcc/config/rs6000/t-float16 index 2e5c04e44a7c..9d9f1bd9559a 100644 --- a/libgcc/config/rs6000/t-float16 +++ b/libgcc/config/rs6000/t-float16 @@ -1,7 +1,7 @@ PERL := perl # _Float16 library support, source files in soft-ftp -fp16_funcs = ppc-eqhf2 ppc-floatbitinthf ppc-fixhfbitint +fp16_funcs = ppc-eqhf2 ppc-floatbitinthf ppc-fixhfbitint ppc-powf16 fp16_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix .c,$(fp16_funcs))) fp16_obj = $(addsuffix $(objext),$(fp16_funcs)) @@ -13,7 +13,7 @@ FP16_CFLAGS = -mfloat16 -Wno-psabi \ $(fp16_obj) : INTERNAL_CFLAGS += $(FP16_CFLAGS) # __bf16 library support, source files in config/rs6000 -bfp16_funcs = ppc-eqbf2 ppc-floatbitintbf ppc-fixbfbitint +bfp16_funcs = ppc-eqbf2 ppc-floatbitintbf ppc-fixbfbitint ppc-powbf16 bfp16_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix .c,$(bfp16_funcs))) bfp16_obj = $(addsuffix $(objext),$(bfp16_funcs))
