https://gcc.gnu.org/g:6369c6b55cc13fad5deefe9579e66fe477bd83f0
commit 6369c6b55cc13fad5deefe9579e66fe477bd83f0 Author: Michael Meissner <[email protected]> Date: Tue Sep 29 21:01:46 2026 -0400 Add fixbfbitint, fixhfbitint. Fix 16-bit fp bitint calls. 2026-09-26 Michael Meissner <[email protected]> gcc/ * config/rs6000/rs6000.cc (init_float16): Properly set up the conversions between 16-bit floating point and bitint to pass arguments in GPRs. libgcc/ * config/rs6000/ppc-fixbfbitint.c: New file. * config/rs6000/ppc-fixhfbitint.c: Likewise. * config/rs6000/t-float16: Build ppc-fixbfbitint and ppc-fixhfbitint. Diff: --- gcc/config/rs6000/rs6000.cc | 7 ++ libgcc/config/rs6000/ppc-fixbfbitint.c | 128 +++++++++++++++++++++++++++++++++ libgcc/config/rs6000/ppc-fixhfbitint.c | 127 ++++++++++++++++++++++++++++++++ libgcc/config/rs6000/t-float16 | 4 +- 4 files changed, 264 insertions(+), 2 deletions(-) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 1aed909feab6..6e4c13ecd523 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -11949,6 +11949,13 @@ init_float16 (void) set_conv_libfunc (trunc_optab, fp16_mode2, fp16_mode, fname); } } + + /* Bitint support. */ + sprintf (fname, "__floatbitint%s_gpr", fp16_name); + set_optab_libfunc (bitinttofp_optab, fp16_mode, fname); + + sprintf (fname, "__fix%sbitint_gpr", fp16_name); + set_optab_libfunc (bitintfromfp_optab, fp16_mode, fname); } } diff --git a/libgcc/config/rs6000/ppc-fixbfbitint.c b/libgcc/config/rs6000/ppc-fixbfbitint.c new file mode 100644 index 000000000000..3271912dc260 --- /dev/null +++ b/libgcc/config/rs6000/ppc-fixbfbitint.c @@ -0,0 +1,128 @@ +/* Software floating-point emulation. + Convert IEEE single to signed or unsigned _BitInt. + + Copyright (C) 2023 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. + +This is a clone of softfp/fixsfbit.c + +We provide 2 conversions, one that passes 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" +#include "bitint.h" + +#ifdef __BITINT_MAXWIDTH__ +/* Silence declaration without prototype warning. */ +extern void __fixbfbitint (UBILtype *, SItype, BFtype); +extern void __fixbfbitint_gpr (UBILtype *, SItype, unsigned short); + +/* BFtype is passed in FPR registers. */ +void +__fixbfbitint (UBILtype *r, SItype rprec, BFtype a) +{ + FP_DECL_EX; + FP_DECL_B (A); + USItype arprec = rprec < 0 ? -rprec : rprec; + USItype rn = ((USItype) arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + USItype rv; + USItype rsize = arprec > SI_BITS ? SI_BITS : arprec; + USItype rsigned = rprec < 0; + USItype ovf = 0; + USItype shift = 0; + + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_B (A, a); + if (arprec > SI_BITS) + { + if (A_e < _FP_EXPBIAS_B || (A_s && !rsigned)) + ovf = 1; + else if (A_e >= (_FP_EXPMAX_B < _FP_EXPBIAS_B + arprec + ? _FP_EXPMAX_B + : _FP_EXPBIAS_B + arprec - rsigned)) + { + ovf = 1; + if (A_s + && A_e == _FP_EXPBIAS_B + arprec - 1 + && A_e < _FP_EXPMAX_B) + A_e -= arprec - SI_BITS; + } + else if (A_e >= _FP_EXPBIAS_B + SI_BITS - rsigned) + { + shift = A_e - (_FP_EXPBIAS_B + SI_BITS - rsigned - 1); + A_e -= shift; + } + } + FP_TO_INT_B (rv, A, rsize, rsigned); + FP_HANDLE_EXCEPTIONS; + FP_TO_BITINT (r, rn, arprec, shift, rv, rsize, rsigned, ovf, SI); +} + +/* BFtype is passed in GPR registers. */ +void +__fixbfbitint_gpr (UBILtype *r, SItype rprec, unsigned short us) +{ + FP_DECL_EX; + FP_DECL_B (A); + USItype arprec = rprec < 0 ? -rprec : rprec; + USItype rn = ((USItype) arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + USItype rv; + USItype rsize = arprec > SI_BITS ? SI_BITS : arprec; + USItype rsigned = rprec < 0; + USItype ovf = 0; + USItype shift = 0; + BFtype a; + union ushort_bf u; + + u.us = us; + a = u.bf; + + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_B (A, a); + if (arprec > SI_BITS) + { + if (A_e < _FP_EXPBIAS_B || (A_s && !rsigned)) + ovf = 1; + else if (A_e >= (_FP_EXPMAX_B < _FP_EXPBIAS_B + arprec + ? _FP_EXPMAX_B + : _FP_EXPBIAS_B + arprec - rsigned)) + { + ovf = 1; + if (A_s + && A_e == _FP_EXPBIAS_B + arprec - 1 + && A_e < _FP_EXPMAX_B) + A_e -= arprec - SI_BITS; + } + else if (A_e >= _FP_EXPBIAS_B + SI_BITS - rsigned) + { + shift = A_e - (_FP_EXPBIAS_B + SI_BITS - rsigned - 1); + A_e -= shift; + } + } + FP_TO_INT_B (rv, A, rsize, rsigned); + FP_HANDLE_EXCEPTIONS; + FP_TO_BITINT (r, rn, arprec, shift, rv, rsize, rsigned, ovf, SI); +} +#endif diff --git a/libgcc/config/rs6000/ppc-fixhfbitint.c b/libgcc/config/rs6000/ppc-fixhfbitint.c new file mode 100644 index 000000000000..bb1818ec0695 --- /dev/null +++ b/libgcc/config/rs6000/ppc-fixhfbitint.c @@ -0,0 +1,127 @@ +/* Software floating-point emulation. + Convert IEEE single to signed or unsigned _BitInt. + + Copyright (C) 2023 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. + +This is a clone of softfp/fixsfbit.c + +We provide 2 conversions, one that passes the HFtype in a floating point +register and the other returns it in a general purpose register that is used +when HFtype must be converted to the 32/64-bit scalar type. */ + +#include "soft-fp.h" +#include "half.h" +#include "bitint.h" + +#ifdef __BITINT_MAXWIDTH__ +extern void __fixhfbitint (UBILtype *, SItype, HFtype); +extern void __fixhfbitint_gpr (UBILtype *, SItype, unsigned short); + +/* HFtype is passed in FPR registers. */ +void +__fixhfbitint (UBILtype *r, SItype rprec, HFtype a) +{ + FP_DECL_EX; + FP_DECL_H (A); + USItype arprec = rprec < 0 ? -rprec : rprec; + USItype rn = ((USItype) arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + USItype rv; + USItype rsize = arprec > SI_BITS ? SI_BITS : arprec; + USItype rsigned = rprec < 0; + USItype ovf = 0; + USItype shift = 0; + + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_H (A, a); + if (arprec > SI_BITS) + { + if (A_e < _FP_EXPBIAS_H || (A_s && !rsigned)) + ovf = 1; + else if (A_e >= (_FP_EXPMAX_H < _FP_EXPBIAS_H + arprec + ? _FP_EXPMAX_H + : _FP_EXPBIAS_H + arprec - rsigned)) + { + ovf = 1; + if (A_s + && A_e == _FP_EXPBIAS_H + arprec - 1 + && A_e < _FP_EXPMAX_H) + A_e -= arprec - SI_BITS; + } + else if (A_e >= _FP_EXPBIAS_H + SI_BITS - rsigned) + { + shift = A_e - (_FP_EXPBIAS_H + SI_BITS - rsigned - 1); + A_e -= shift; + } + } + FP_TO_INT_H (rv, A, rsize, rsigned); + FP_HANDLE_EXCEPTIONS; + FP_TO_BITINT (r, rn, arprec, shift, rv, rsize, rsigned, ovf, SI); +} + +/* HFtype is passed in GPR registers. */ +void +__fixhfbitint_gpr (UBILtype *r, SItype rprec, unsigned short us) +{ + FP_DECL_EX; + FP_DECL_H (A); + USItype arprec = rprec < 0 ? -rprec : rprec; + USItype rn = ((USItype) arprec + BIL_TYPE_SIZE - 1) / BIL_TYPE_SIZE; + USItype rv; + USItype rsize = arprec > SI_BITS ? SI_BITS : arprec; + USItype rsigned = rprec < 0; + USItype ovf = 0; + USItype shift = 0; + HFtype a; + union ushort_hf u; + + u.us = us; + a = u.hf; + + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_H (A, a); + if (arprec > SI_BITS) + { + if (A_e < _FP_EXPBIAS_H || (A_s && !rsigned)) + ovf = 1; + else if (A_e >= (_FP_EXPMAX_H < _FP_EXPBIAS_H + arprec + ? _FP_EXPMAX_H + : _FP_EXPBIAS_H + arprec - rsigned)) + { + ovf = 1; + if (A_s + && A_e == _FP_EXPBIAS_H + arprec - 1 + && A_e < _FP_EXPMAX_H) + A_e -= arprec - SI_BITS; + } + else if (A_e >= _FP_EXPBIAS_H + SI_BITS - rsigned) + { + shift = A_e - (_FP_EXPBIAS_H + SI_BITS - rsigned - 1); + A_e -= shift; + } + } + FP_TO_INT_H (rv, A, rsize, rsigned); + FP_HANDLE_EXCEPTIONS; + FP_TO_BITINT (r, rn, arprec, shift, rv, rsize, rsigned, ovf, SI); +} +#endif diff --git a/libgcc/config/rs6000/t-float16 b/libgcc/config/rs6000/t-float16 index b6d342e25312..6b548b084fef 100644 --- a/libgcc/config/rs6000/t-float16 +++ b/libgcc/config/rs6000/t-float16 @@ -4,7 +4,7 @@ fp16_funcs = extendhf-sfdf2 truncsfdf-hf2 \ ppc-fixunshfsi ppc-fixunshfdi ppc-fixunshfti \ ppc-floatsihf ppc-floatdihf ppc-floattihf \ ppc-floatunsihf ppc-floatundihf ppc-floatuntihf \ - ppc-eqhf2 ppc-floatbitinthf + ppc-eqhf2 ppc-floatbitinthf ppc-fixhfbitint fp16_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix .c,$(fp16_funcs))) fp16_obj = $(addsuffix $(objext),$(fp16_funcs)) @@ -21,7 +21,7 @@ bfp16_funcs = extendbf-sfdf2 truncsfdf-bf2 \ ppc-floatunsibf ppc-floatundibf ppc-floatuntibf \ ppc-fixbfsi ppc-fixbfdi ppc-fixbfti \ ppc-fixunsbfsi ppc-fixunsbfdi ppc-fixunsbfti \ - ppc-eqbf2 ppc-floatbitintbf + ppc-eqbf2 ppc-floatbitintbf ppc-fixbfbitint bfp16_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix .c,$(bfp16_funcs))) bfp16_obj = $(addsuffix $(objext),$(bfp16_funcs))
