https://gcc.gnu.org/g:6dd9e1b15da204a59301cb34401641810f0095ec

commit 6dd9e1b15da204a59301cb34401641810f0095ec
Author: Michael Meissner <[email protected]>
Date:   Mon Oct 26 19:06:39 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-26  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))

Reply via email to