diff mbox series

[v3,09/10] libgcc: Add support for HF mode (aka _Float16) in libbid

Message ID 20220516134753.152672-1-christophe.lyon@arm.com
State New
Headers show
Series None | expand

Commit Message

Christophe Lyon May 16, 2022, 1:47 p.m. UTC
This patch adds support for trunc and extend operations between HF
mode (_Float16) and Decimal Floating Point formats (_Decimal32,
_Decimal64 and _Decimal128).

For simplicity we rely on the implicit conversions inserted by the
compiler between HF and SD/DF/TF modes.  The existing bid*_to_binary*
and binary*_to_bid* functions are non-trivial and at this stage it is
not clear if there is a performance-critical use case involving _Float16
and _Decimal* formats.

The patch also adds two executable tests, to make sure the right
functions are called, available (link phase) and functional.

Tested on aarch64 and x86_86. The number of symbol matches in the
testcases includes the .global XXX to avoid having to match different
call instructions for different targets.

2022-05-04  Christophe Lyon  <christophe.lyon@arm.com>

libgcc/ChangeLog:

	* Makefile.in (D32PBIT_FUNCS): Add _hf_to_sd and _sd_to_hf.
	(D64PBIT_FUNCS): Add _hf_to_dd and _dd_to_hf.
	(D128PBIT_FUNCS): Add _hf_to_td _td_to_hf.

libgcc/config/libbid/ChangeLog:

	* bid_gcc_intrinsics.h (LIBGCC2_HAS_HF_MODE): Define according to
	__LIBGCC_HAS_HF_MODE__.
	(BID_HAS_HF_MODE): Define.
	(HFtype): Define.
	(__bid_extendhfsd): New prototype.
	(__bid_extendhfdd): Likewise.
	(__bid_extendhftd): Likewise.
	(__bid_truncsdhf): Likewise.
	(__bid_truncddhf): Likewise.
	(__bid_trunctdhf): Likewise.
	* _dd_to_hf.c: New file.
	* _hf_to_dd.c: New file.
	* _hf_to_sd.c: New file.
	* _hf_to_td.c: New file.
	* _sd_to_hf.c: New file.
	* _td_to_hf.c: New file.

gcc/testsuite/ChangeLog:

	* gcc.dg/torture/convert-dfp-2.c: New test.
	* gcc.dg/torture/convert-dfp.c: New test.
---
 gcc/testsuite/gcc.dg/torture/convert-dfp-2.c | 45 ++++++++++++++
 gcc/testsuite/gcc.dg/torture/convert-dfp.c   | 63 ++++++++++++++++++++
 libgcc/Makefile.in                           |  9 ++-
 libgcc/config/libbid/_dd_to_hf.c             | 38 ++++++++++++
 libgcc/config/libbid/_hf_to_dd.c             | 36 +++++++++++
 libgcc/config/libbid/_hf_to_sd.c             | 36 +++++++++++
 libgcc/config/libbid/_hf_to_td.c             | 36 +++++++++++
 libgcc/config/libbid/_sd_to_hf.c             | 38 ++++++++++++
 libgcc/config/libbid/_td_to_hf.c             | 38 ++++++++++++
 libgcc/config/libbid/bid_gcc_intrinsics.h    | 30 +++++++++-
 10 files changed, 364 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/convert-dfp-2.c
 create mode 100644 gcc/testsuite/gcc.dg/torture/convert-dfp.c
 create mode 100644 libgcc/config/libbid/_dd_to_hf.c
 create mode 100644 libgcc/config/libbid/_hf_to_dd.c
 create mode 100644 libgcc/config/libbid/_hf_to_sd.c
 create mode 100644 libgcc/config/libbid/_hf_to_td.c
 create mode 100644 libgcc/config/libbid/_sd_to_hf.c
 create mode 100644 libgcc/config/libbid/_td_to_hf.c

Comments

Christophe Lyon May 19, 2022, 1:03 p.m. UTC | #1
Hi Joseph,

May I ping you on this version? (I've moved the tests to gcc.dg/torture/ 
and checked they work on aarch64 and x86_64.

Thanks,

Christophe

On 5/16/22 15:47, Christophe Lyon wrote:
> This patch adds support for trunc and extend operations between HF
> mode (_Float16) and Decimal Floating Point formats (_Decimal32,
> _Decimal64 and _Decimal128).
> 
> For simplicity we rely on the implicit conversions inserted by the
> compiler between HF and SD/DF/TF modes.  The existing bid*_to_binary*
> and binary*_to_bid* functions are non-trivial and at this stage it is
> not clear if there is a performance-critical use case involving _Float16
> and _Decimal* formats.
> 
> The patch also adds two executable tests, to make sure the right
> functions are called, available (link phase) and functional.
> 
> Tested on aarch64 and x86_86. The number of symbol matches in the
> testcases includes the .global XXX to avoid having to match different
> call instructions for different targets.
> 
> 2022-05-04  Christophe Lyon  <christophe.lyon@arm.com>
> 
> libgcc/ChangeLog:
> 
> 	* Makefile.in (D32PBIT_FUNCS): Add _hf_to_sd and _sd_to_hf.
> 	(D64PBIT_FUNCS): Add _hf_to_dd and _dd_to_hf.
> 	(D128PBIT_FUNCS): Add _hf_to_td _td_to_hf.
> 
> libgcc/config/libbid/ChangeLog:
> 
> 	* bid_gcc_intrinsics.h (LIBGCC2_HAS_HF_MODE): Define according to
> 	__LIBGCC_HAS_HF_MODE__.
> 	(BID_HAS_HF_MODE): Define.
> 	(HFtype): Define.
> 	(__bid_extendhfsd): New prototype.
> 	(__bid_extendhfdd): Likewise.
> 	(__bid_extendhftd): Likewise.
> 	(__bid_truncsdhf): Likewise.
> 	(__bid_truncddhf): Likewise.
> 	(__bid_trunctdhf): Likewise.
> 	* _dd_to_hf.c: New file.
> 	* _hf_to_dd.c: New file.
> 	* _hf_to_sd.c: New file.
> 	* _hf_to_td.c: New file.
> 	* _sd_to_hf.c: New file.
> 	* _td_to_hf.c: New file.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.dg/torture/convert-dfp-2.c: New test.
> 	* gcc.dg/torture/convert-dfp.c: New test.
> ---
>   gcc/testsuite/gcc.dg/torture/convert-dfp-2.c | 45 ++++++++++++++
>   gcc/testsuite/gcc.dg/torture/convert-dfp.c   | 63 ++++++++++++++++++++
>   libgcc/Makefile.in                           |  9 ++-
>   libgcc/config/libbid/_dd_to_hf.c             | 38 ++++++++++++
>   libgcc/config/libbid/_hf_to_dd.c             | 36 +++++++++++
>   libgcc/config/libbid/_hf_to_sd.c             | 36 +++++++++++
>   libgcc/config/libbid/_hf_to_td.c             | 36 +++++++++++
>   libgcc/config/libbid/_sd_to_hf.c             | 38 ++++++++++++
>   libgcc/config/libbid/_td_to_hf.c             | 38 ++++++++++++
>   libgcc/config/libbid/bid_gcc_intrinsics.h    | 30 +++++++++-
>   10 files changed, 364 insertions(+), 5 deletions(-)
>   create mode 100644 gcc/testsuite/gcc.dg/torture/convert-dfp-2.c
>   create mode 100644 gcc/testsuite/gcc.dg/torture/convert-dfp.c
>   create mode 100644 libgcc/config/libbid/_dd_to_hf.c
>   create mode 100644 libgcc/config/libbid/_hf_to_dd.c
>   create mode 100644 libgcc/config/libbid/_hf_to_sd.c
>   create mode 100644 libgcc/config/libbid/_hf_to_td.c
>   create mode 100644 libgcc/config/libbid/_sd_to_hf.c
>   create mode 100644 libgcc/config/libbid/_td_to_hf.c
> 
> diff --git a/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c b/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c
> new file mode 100644
> index 00000000000..3e4ecb57ba6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c
> @@ -0,0 +1,45 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target float16_runtime } */
> +/* { dg-require-effective-target dfprt } */
> +/* { dg-options "-save-temps" } */
> +/* { dg-add-options float16 } */
> +
> +/* Test conversions from DFP to smaller types.  */
> +
> +_Decimal32 var32;
> +_Decimal64 var64;
> +_Decimal128 var128;
> +_Float16 var16;
> +
> +void __attribute__ ((__noinline__)) foo32 (_Decimal32 param32)
> +{
> +  var16 = param32;
> +}
> +
> +void __attribute__ ((__noinline__)) foo64 (_Decimal64 param64)
> +{
> +  var16 = param64;
> +  var32 = param64;
> +}
> +
> +void __attribute__ ((__noinline__)) foo128 (_Decimal128 param128)
> +{
> +  var16 = param128;
> +  var32 = param128;
> +  var64 = param128;
> +}
> +
> +int main ()
> +{
> +  foo32 (var32);
> +  foo64 (var64);
> +  foo128 (var128);
> +  return 0;
> +}
> +
> +/* { dg-final { scan-assembler-times {\t__bid_truncsdhf} 2 { target { dfp_bid } } } } */
> +/* { dg-final { scan-assembler-times {\t__bid_truncddhf} 2 { target { dfp_bid } } } } */
> +/* { dg-final { scan-assembler-times {\t__bid_truncddsd2} 2 { target { dfp_bid } } } } */
> +/* { dg-final { scan-assembler-times {\t__bid_trunctdhf} 2 { target { dfp_bid } } } } */
> +/* { dg-final { scan-assembler-times {\t__bid_trunctdsd2} 2 { target { dfp_bid } } } } */
> +/* { dg-final { scan-assembler-times {\t__bid_trunctddd2} 2 { target { dfp_bid } } } } */
> diff --git a/gcc/testsuite/gcc.dg/torture/convert-dfp.c b/gcc/testsuite/gcc.dg/torture/convert-dfp.c
> new file mode 100644
> index 00000000000..ec136896ca7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/torture/convert-dfp.c
> @@ -0,0 +1,63 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target float16_runtime } */
> +/* { dg-require-effective-target dfprt } */
> +/* { dg-options "-save-temps" } */
> +/* { dg-add-options float16 } */
> +
> +/* Test conversions to/from DFP values.  */
> +
> +extern void abort ();
> +
> +_Decimal32 var32 = 1.2df;
> +
> +int __attribute__ ((__noinline__)) foo32 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16)
> +{
> +  return (param32 == var32)
> +    + (param64 == var32)
> +    + (param128 == var32)
> +    /* Small enough relative difference?  */
> +    + ((((_Decimal32)param16 - var32) / var32) < 0.002df);
> +}
> +
> +_Decimal64 var64 = 1.2dd;
> +
> +int __attribute__ ((__noinline__)) foo64 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16)
> +{
> +  return (param32 == var64)
> +    + (param64 == var64)
> +    + (param128 == var64)
> +    /* Small enough relative difference?  */
> +    + ((((_Decimal64)param16 - var64) / var64) < 0.002dd);
> +}
> +
> +_Decimal128 var128 = 1.2dl;
> +
> +int __attribute__ ((__noinline__)) foo128 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16)
> +{
> +  return (param32 == var128)
> +    + (param64 == var128)
> +    + (param128 == var128)
> +    /* Small enough relative difference?  */
> +    + ((((_Decimal128)param16 - var128) / var128) < 0.002dl);
> +}
> +
> +int main()
> +{
> +  if (foo32 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4)
> +    abort ();
> +
> +  if (foo64 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4)
> +    abort ();
> +
> +  if (foo128 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4)
> +    abort ();
> +
> +  return 0;
> +}
> +
> +/* { dg-final { scan-assembler-times {\t__bid_extendsddd2} 3 { target { dfp_bid } } } } */
> +/* { dg-final { scan-assembler-times {\t__bid_extendsdtd2} 3 { target { dfp_bid } } } } */
> +/* { dg-final { scan-assembler-times {\t__bid_extendddtd2} 3 { target { dfp_bid } } } } */
> +/* { dg-final { scan-assembler-times {\t__bid_extendhfsd} 2 { target { dfp_bid } } } } */
> +/* { dg-final { scan-assembler-times {\t__bid_extendhfdd} 2 { target { dfp_bid } } } } */
> +/* { dg-final { scan-assembler-times {\t__bid_extendhftd} 2 { target { dfp_bid } } } } */
> diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
> index 09b3ec8bc2e..1fe708a93f7 100644
> --- a/libgcc/Makefile.in
> +++ b/libgcc/Makefile.in
> @@ -677,7 +677,8 @@ D32PBIT_FUNCS = _addsub_sd _div_sd _mul_sd _plus_sd _minus_sd \
>   	_si_to_sd _di_to_sd _usi_to_sd _udi_to_sd \
>   	_sd_to_sf _sd_to_df _sd_to_xf _sd_to_tf \
>   	_sf_to_sd _df_to_sd _xf_to_sd _tf_to_sd \
> -	_sd_to_dd _sd_to_td _unord_sd _conv_sd
> +	_sd_to_dd _sd_to_td _unord_sd _conv_sd \
> +	_hf_to_sd _sd_to_hf
>   
>   D64PBIT_FUNCS = _addsub_dd _div_dd _mul_dd _plus_dd _minus_dd \
>   	_eq_dd _ne_dd _lt_dd _gt_dd _le_dd _ge_dd \
> @@ -685,7 +686,8 @@ D64PBIT_FUNCS = _addsub_dd _div_dd _mul_dd _plus_dd _minus_dd \
>   	_si_to_dd _di_to_dd _usi_to_dd _udi_to_dd \
>   	_dd_to_sf _dd_to_df _dd_to_xf _dd_to_tf \
>   	_sf_to_dd _df_to_dd _xf_to_dd _tf_to_dd \
> -	_dd_to_sd _dd_to_td _unord_dd _conv_dd
> +	_dd_to_sd _dd_to_td _unord_dd _conv_dd \
> +	_hf_to_dd _dd_to_hf
>   
>   D128PBIT_FUNCS = _addsub_td _div_td _mul_td _plus_td _minus_td \
>   	_eq_td _ne_td _lt_td _gt_td _le_td _ge_td \
> @@ -693,7 +695,8 @@ D128PBIT_FUNCS = _addsub_td _div_td _mul_td _plus_td _minus_td \
>   	_si_to_td _di_to_td _usi_to_td _udi_to_td \
>   	_td_to_sf _td_to_df _td_to_xf _td_to_tf \
>   	_sf_to_td _df_to_td _xf_to_td _tf_to_td \
> -	_td_to_sd _td_to_dd _unord_td _conv_td
> +	_td_to_sd _td_to_dd _unord_td _conv_td \
> +	_hf_to_td _td_to_hf
>   
>   ifeq ($(enable_decimal_float),bid)
>   ifneq ($(D32PBIT),)
> diff --git a/libgcc/config/libbid/_dd_to_hf.c b/libgcc/config/libbid/_dd_to_hf.c
> new file mode 100644
> index 00000000000..5e58288391e
> --- /dev/null
> +++ b/libgcc/config/libbid/_dd_to_hf.c
> @@ -0,0 +1,38 @@
> +/* Copyright (C) 2022 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/>.  */
> +
> +#include "bid_conf.h"
> +#include "bid_functions.h"
> +#include "bid_gcc_intrinsics.h"
> +
> +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
> +HFtype
> +__bid_truncddhf (_Decimal64 x) {
> +  HFtype res;
> +  union decimal64 ux;
> +
> +  ux.d = x;
> +  res = __bid64_to_binary32 (ux.i);
> +  return (res);
> +}
> +#endif
> diff --git a/libgcc/config/libbid/_hf_to_dd.c b/libgcc/config/libbid/_hf_to_dd.c
> new file mode 100644
> index 00000000000..f85100e24f8
> --- /dev/null
> +++ b/libgcc/config/libbid/_hf_to_dd.c
> @@ -0,0 +1,36 @@
> +/* Copyright (C) 2022 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/>.  */
> +
> +#include "bid_conf.h"
> +#include "bid_functions.h"
> +#include "bid_gcc_intrinsics.h"
> +
> +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
> +_Decimal64
> +__bid_extendhfdd (HFtype x) {
> +  union decimal64 res;
> +  SFtype xsf = x;
> +  res.i = __binary32_to_bid64 (xsf);
> +  return (res.d);
> +}
> +#endif
> diff --git a/libgcc/config/libbid/_hf_to_sd.c b/libgcc/config/libbid/_hf_to_sd.c
> new file mode 100644
> index 00000000000..285b80c6e05
> --- /dev/null
> +++ b/libgcc/config/libbid/_hf_to_sd.c
> @@ -0,0 +1,36 @@
> +/* Copyright (C) 2022 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/>.  */
> +
> +#include "bid_conf.h"
> +#include "bid_functions.h"
> +#include "bid_gcc_intrinsics.h"
> +
> +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
> +_Decimal32
> +__bid_extendhfsd (HFtype x) {
> +  union decimal32 res;
> +  SFtype xsf = x;
> +  res.i = __binary32_to_bid32 (xsf);
> +  return (res.d);
> +}
> +#endif
> diff --git a/libgcc/config/libbid/_hf_to_td.c b/libgcc/config/libbid/_hf_to_td.c
> new file mode 100644
> index 00000000000..99b661ec727
> --- /dev/null
> +++ b/libgcc/config/libbid/_hf_to_td.c
> @@ -0,0 +1,36 @@
> +/* Copyright (C) 2022 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/>.  */
> +
> +#include "bid_conf.h"
> +#include "bid_functions.h"
> +#include "bid_gcc_intrinsics.h"
> +
> +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
> +_Decimal128
> +__bid_extendhftd (HFtype x) {
> +  union decimal128 res;
> +  SFtype xsf = x;
> +  res.i = __binary32_to_bid128 (xsf);
> +  return (res.d);
> +}
> +#endif
> diff --git a/libgcc/config/libbid/_sd_to_hf.c b/libgcc/config/libbid/_sd_to_hf.c
> new file mode 100644
> index 00000000000..e4e3125d49b
> --- /dev/null
> +++ b/libgcc/config/libbid/_sd_to_hf.c
> @@ -0,0 +1,38 @@
> +/* Copyright (C) 2022 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/>.  */
> +
> +#include "bid_conf.h"
> +#include "bid_functions.h"
> +#include "bid_gcc_intrinsics.h"
> +
> +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
> +HFtype
> +__bid_truncsdhf (_Decimal32 x) {
> +  HFtype res;
> +  union decimal32 ux;
> +
> +  ux.d = x;
> +  res = __bid32_to_binary32 (ux.i);
> +  return (res);
> +}
> +#endif
> diff --git a/libgcc/config/libbid/_td_to_hf.c b/libgcc/config/libbid/_td_to_hf.c
> new file mode 100644
> index 00000000000..c4ebe586db0
> --- /dev/null
> +++ b/libgcc/config/libbid/_td_to_hf.c
> @@ -0,0 +1,38 @@
> +/* Copyright (C) 2022 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/>.  */
> +
> +#include "bid_conf.h"
> +#include "bid_functions.h"
> +#include "bid_gcc_intrinsics.h"
> +
> +#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
> +HFtype
> +__bid_trunctdhf (_Decimal128 x) {
> +  HFtype res;
> +  union decimal128 ux;
> +
> +  ux.d = x;
> +  res = __bid128_to_binary32 (ux.i);
> +  return (res);
> +}
> +#endif
> diff --git a/libgcc/config/libbid/bid_gcc_intrinsics.h b/libgcc/config/libbid/bid_gcc_intrinsics.h
> index b0a23debc15..15c050764ac 100644
> --- a/libgcc/config/libbid/bid_gcc_intrinsics.h
> +++ b/libgcc/config/libbid/bid_gcc_intrinsics.h
> @@ -31,6 +31,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>   #include "tm.h"
>   #include "libgcc_tm.h"
>   
> +#ifdef __LIBGCC_HAS_HF_MODE__
> +#define LIBGCC2_HAS_HF_MODE 1
> +#else
> +#define LIBGCC2_HAS_HF_MODE 0
> +#endif
> +
>   #ifdef __LIBGCC_HAS_XF_MODE__
>   #define LIBGCC2_HAS_XF_MODE 1
>   #else
> @@ -43,6 +49,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>   #define LIBGCC2_HAS_TF_MODE 0
>   #endif
>   
> +#ifndef BID_HAS_HF_MODE
> +#define BID_HAS_HF_MODE LIBGCC2_HAS_HF_MODE
> +#endif
> +
>   #ifndef BID_HAS_XF_MODE
>   #define BID_HAS_XF_MODE LIBGCC2_HAS_XF_MODE
>   #endif
> @@ -53,6 +63,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>   
>   /* Some handy typedefs.  */
>   
> +#if LIBGCC2_HAS_HF_MODE
> +typedef float HFtype __attribute__ ((mode (HF)));
> +#endif /* LIBGCC2_HAS_HF_MODE */
>   typedef float SFtype __attribute__ ((mode (SF)));
>   typedef float DFtype __attribute__ ((mode (DF)));
>   #if LIBGCC2_HAS_XF_MODE
> @@ -98,6 +111,12 @@ typedef __attribute__ ((aligned(16))) struct
>   #endif
>   #endif
>   
> +#if BID_HAS_HF_MODE
> +#ifndef HFtype
> +#define HFtype _Float16
> +#endif
> +#endif
> +
>   #ifndef SFtype
>   #define SFtype float
>   #endif
> @@ -110,8 +129,7 @@ typedef __attribute__ ((aligned(16))) struct
>   #ifndef XFtype
>   #define XFtype long double
>   #endif
> -
> -#endif   /* IN_LIBGCC2 */
> +#endif
>   
>   #if BID_HAS_TF_MODE
>   #ifndef TFtype
> @@ -249,6 +267,14 @@ extern _Decimal128 __bid_extendxftd (XFtype);
>   extern int isinfd32 (_Decimal32);
>   extern int isinfd64 (_Decimal64);
>   extern int isinfd128 (_Decimal128);
> +#if BID_HAS_HF_MODE
> +extern _Decimal32 __bid_extendhfsd (HFtype);
> +extern _Decimal64 __bid_extendhfdd (HFtype);
> +extern _Decimal128 __bid_extendhftd (HFtype);
> +extern HFtype __bid_truncsdhf (_Decimal32);
> +extern HFtype __bid_truncddhf (_Decimal64);
> +extern HFtype __bid_trunctdhf (_Decimal128);
> +#endif
>   #endif  /* BID_HAS_GCC_DECIMAL_INTRINSICS */
>   
>   extern void __dfp_set_round (int);
Joseph Myers May 19, 2022, 7:35 p.m. UTC | #2
On Thu, 19 May 2022, Christophe Lyon via Gcc-patches wrote:

> Hi Joseph,
> 
> May I ping you on this version? (I've moved the tests to gcc.dg/torture/ and
> checked they work on aarch64 and x86_64.

This version is OK, given a bug report filed in Bugzilla for the 
double-rounding issues with conversions from DFP modes to HFmode.
Christophe Lyon May 20, 2022, 7:47 a.m. UTC | #3
On 5/19/22 21:35, Joseph Myers wrote:
> On Thu, 19 May 2022, Christophe Lyon via Gcc-patches wrote:
> 
>> Hi Joseph,
>>
>> May I ping you on this version? (I've moved the tests to gcc.dg/torture/ and
>> checked they work on aarch64 and x86_64.
> 
> This version is OK, given a bug report filed in Bugzilla for the
> double-rounding issues with conversions from DFP modes to HFmode.
> 

Thanks!

I've filed PR 105669.

Christophe
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c b/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c
new file mode 100644
index 00000000000..3e4ecb57ba6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c
@@ -0,0 +1,45 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target float16_runtime } */
+/* { dg-require-effective-target dfprt } */
+/* { dg-options "-save-temps" } */
+/* { dg-add-options float16 } */
+
+/* Test conversions from DFP to smaller types.  */
+
+_Decimal32 var32;
+_Decimal64 var64;
+_Decimal128 var128;
+_Float16 var16;
+
+void __attribute__ ((__noinline__)) foo32 (_Decimal32 param32)
+{
+  var16 = param32;
+}
+
+void __attribute__ ((__noinline__)) foo64 (_Decimal64 param64)
+{
+  var16 = param64;
+  var32 = param64;
+}
+
+void __attribute__ ((__noinline__)) foo128 (_Decimal128 param128)
+{
+  var16 = param128;
+  var32 = param128;
+  var64 = param128;
+}
+
+int main ()
+{
+  foo32 (var32);
+  foo64 (var64);
+  foo128 (var128);
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times {\t__bid_truncsdhf} 2 { target { dfp_bid } } } } */
+/* { dg-final { scan-assembler-times {\t__bid_truncddhf} 2 { target { dfp_bid } } } } */
+/* { dg-final { scan-assembler-times {\t__bid_truncddsd2} 2 { target { dfp_bid } } } } */
+/* { dg-final { scan-assembler-times {\t__bid_trunctdhf} 2 { target { dfp_bid } } } } */
+/* { dg-final { scan-assembler-times {\t__bid_trunctdsd2} 2 { target { dfp_bid } } } } */
+/* { dg-final { scan-assembler-times {\t__bid_trunctddd2} 2 { target { dfp_bid } } } } */
diff --git a/gcc/testsuite/gcc.dg/torture/convert-dfp.c b/gcc/testsuite/gcc.dg/torture/convert-dfp.c
new file mode 100644
index 00000000000..ec136896ca7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/convert-dfp.c
@@ -0,0 +1,63 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target float16_runtime } */
+/* { dg-require-effective-target dfprt } */
+/* { dg-options "-save-temps" } */
+/* { dg-add-options float16 } */
+
+/* Test conversions to/from DFP values.  */
+
+extern void abort ();
+
+_Decimal32 var32 = 1.2df;
+
+int __attribute__ ((__noinline__)) foo32 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16)
+{
+  return (param32 == var32)
+    + (param64 == var32)
+    + (param128 == var32)
+    /* Small enough relative difference?  */
+    + ((((_Decimal32)param16 - var32) / var32) < 0.002df);
+}
+
+_Decimal64 var64 = 1.2dd;
+
+int __attribute__ ((__noinline__)) foo64 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16)
+{
+  return (param32 == var64)
+    + (param64 == var64)
+    + (param128 == var64)
+    /* Small enough relative difference?  */
+    + ((((_Decimal64)param16 - var64) / var64) < 0.002dd);
+}
+
+_Decimal128 var128 = 1.2dl;
+
+int __attribute__ ((__noinline__)) foo128 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16)
+{
+  return (param32 == var128)
+    + (param64 == var128)
+    + (param128 == var128)
+    /* Small enough relative difference?  */
+    + ((((_Decimal128)param16 - var128) / var128) < 0.002dl);
+}
+
+int main()
+{
+  if (foo32 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4)
+    abort ();
+
+  if (foo64 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4)
+    abort ();
+
+  if (foo128 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4)
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times {\t__bid_extendsddd2} 3 { target { dfp_bid } } } } */
+/* { dg-final { scan-assembler-times {\t__bid_extendsdtd2} 3 { target { dfp_bid } } } } */
+/* { dg-final { scan-assembler-times {\t__bid_extendddtd2} 3 { target { dfp_bid } } } } */
+/* { dg-final { scan-assembler-times {\t__bid_extendhfsd} 2 { target { dfp_bid } } } } */
+/* { dg-final { scan-assembler-times {\t__bid_extendhfdd} 2 { target { dfp_bid } } } } */
+/* { dg-final { scan-assembler-times {\t__bid_extendhftd} 2 { target { dfp_bid } } } } */
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 09b3ec8bc2e..1fe708a93f7 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -677,7 +677,8 @@  D32PBIT_FUNCS = _addsub_sd _div_sd _mul_sd _plus_sd _minus_sd \
 	_si_to_sd _di_to_sd _usi_to_sd _udi_to_sd \
 	_sd_to_sf _sd_to_df _sd_to_xf _sd_to_tf \
 	_sf_to_sd _df_to_sd _xf_to_sd _tf_to_sd \
-	_sd_to_dd _sd_to_td _unord_sd _conv_sd
+	_sd_to_dd _sd_to_td _unord_sd _conv_sd \
+	_hf_to_sd _sd_to_hf
 
 D64PBIT_FUNCS = _addsub_dd _div_dd _mul_dd _plus_dd _minus_dd \
 	_eq_dd _ne_dd _lt_dd _gt_dd _le_dd _ge_dd \
@@ -685,7 +686,8 @@  D64PBIT_FUNCS = _addsub_dd _div_dd _mul_dd _plus_dd _minus_dd \
 	_si_to_dd _di_to_dd _usi_to_dd _udi_to_dd \
 	_dd_to_sf _dd_to_df _dd_to_xf _dd_to_tf \
 	_sf_to_dd _df_to_dd _xf_to_dd _tf_to_dd \
-	_dd_to_sd _dd_to_td _unord_dd _conv_dd
+	_dd_to_sd _dd_to_td _unord_dd _conv_dd \
+	_hf_to_dd _dd_to_hf
 
 D128PBIT_FUNCS = _addsub_td _div_td _mul_td _plus_td _minus_td \
 	_eq_td _ne_td _lt_td _gt_td _le_td _ge_td \
@@ -693,7 +695,8 @@  D128PBIT_FUNCS = _addsub_td _div_td _mul_td _plus_td _minus_td \
 	_si_to_td _di_to_td _usi_to_td _udi_to_td \
 	_td_to_sf _td_to_df _td_to_xf _td_to_tf \
 	_sf_to_td _df_to_td _xf_to_td _tf_to_td \
-	_td_to_sd _td_to_dd _unord_td _conv_td
+	_td_to_sd _td_to_dd _unord_td _conv_td \
+	_hf_to_td _td_to_hf
 
 ifeq ($(enable_decimal_float),bid)
 ifneq ($(D32PBIT),)
diff --git a/libgcc/config/libbid/_dd_to_hf.c b/libgcc/config/libbid/_dd_to_hf.c
new file mode 100644
index 00000000000..5e58288391e
--- /dev/null
+++ b/libgcc/config/libbid/_dd_to_hf.c
@@ -0,0 +1,38 @@ 
+/* Copyright (C) 2022 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/>.  */
+
+#include "bid_conf.h"
+#include "bid_functions.h"
+#include "bid_gcc_intrinsics.h"
+
+#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
+HFtype
+__bid_truncddhf (_Decimal64 x) {
+  HFtype res;
+  union decimal64 ux;
+
+  ux.d = x;
+  res = __bid64_to_binary32 (ux.i);
+  return (res);
+}
+#endif
diff --git a/libgcc/config/libbid/_hf_to_dd.c b/libgcc/config/libbid/_hf_to_dd.c
new file mode 100644
index 00000000000..f85100e24f8
--- /dev/null
+++ b/libgcc/config/libbid/_hf_to_dd.c
@@ -0,0 +1,36 @@ 
+/* Copyright (C) 2022 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/>.  */
+
+#include "bid_conf.h"
+#include "bid_functions.h"
+#include "bid_gcc_intrinsics.h"
+
+#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
+_Decimal64
+__bid_extendhfdd (HFtype x) {
+  union decimal64 res;
+  SFtype xsf = x;
+  res.i = __binary32_to_bid64 (xsf);
+  return (res.d);
+}
+#endif
diff --git a/libgcc/config/libbid/_hf_to_sd.c b/libgcc/config/libbid/_hf_to_sd.c
new file mode 100644
index 00000000000..285b80c6e05
--- /dev/null
+++ b/libgcc/config/libbid/_hf_to_sd.c
@@ -0,0 +1,36 @@ 
+/* Copyright (C) 2022 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/>.  */
+
+#include "bid_conf.h"
+#include "bid_functions.h"
+#include "bid_gcc_intrinsics.h"
+
+#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
+_Decimal32
+__bid_extendhfsd (HFtype x) {
+  union decimal32 res;
+  SFtype xsf = x;
+  res.i = __binary32_to_bid32 (xsf);
+  return (res.d);
+}
+#endif
diff --git a/libgcc/config/libbid/_hf_to_td.c b/libgcc/config/libbid/_hf_to_td.c
new file mode 100644
index 00000000000..99b661ec727
--- /dev/null
+++ b/libgcc/config/libbid/_hf_to_td.c
@@ -0,0 +1,36 @@ 
+/* Copyright (C) 2022 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/>.  */
+
+#include "bid_conf.h"
+#include "bid_functions.h"
+#include "bid_gcc_intrinsics.h"
+
+#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
+_Decimal128
+__bid_extendhftd (HFtype x) {
+  union decimal128 res;
+  SFtype xsf = x;
+  res.i = __binary32_to_bid128 (xsf);
+  return (res.d);
+}
+#endif
diff --git a/libgcc/config/libbid/_sd_to_hf.c b/libgcc/config/libbid/_sd_to_hf.c
new file mode 100644
index 00000000000..e4e3125d49b
--- /dev/null
+++ b/libgcc/config/libbid/_sd_to_hf.c
@@ -0,0 +1,38 @@ 
+/* Copyright (C) 2022 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/>.  */
+
+#include "bid_conf.h"
+#include "bid_functions.h"
+#include "bid_gcc_intrinsics.h"
+
+#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
+HFtype
+__bid_truncsdhf (_Decimal32 x) {
+  HFtype res;
+  union decimal32 ux;
+
+  ux.d = x;
+  res = __bid32_to_binary32 (ux.i);
+  return (res);
+}
+#endif
diff --git a/libgcc/config/libbid/_td_to_hf.c b/libgcc/config/libbid/_td_to_hf.c
new file mode 100644
index 00000000000..c4ebe586db0
--- /dev/null
+++ b/libgcc/config/libbid/_td_to_hf.c
@@ -0,0 +1,38 @@ 
+/* Copyright (C) 2022 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/>.  */
+
+#include "bid_conf.h"
+#include "bid_functions.h"
+#include "bid_gcc_intrinsics.h"
+
+#if LIBGCC2_HAS_HF_MODE || BID_HAS_HF_MODE
+HFtype
+__bid_trunctdhf (_Decimal128 x) {
+  HFtype res;
+  union decimal128 ux;
+
+  ux.d = x;
+  res = __bid128_to_binary32 (ux.i);
+  return (res);
+}
+#endif
diff --git a/libgcc/config/libbid/bid_gcc_intrinsics.h b/libgcc/config/libbid/bid_gcc_intrinsics.h
index b0a23debc15..15c050764ac 100644
--- a/libgcc/config/libbid/bid_gcc_intrinsics.h
+++ b/libgcc/config/libbid/bid_gcc_intrinsics.h
@@ -31,6 +31,12 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include "tm.h"
 #include "libgcc_tm.h"
 
+#ifdef __LIBGCC_HAS_HF_MODE__
+#define LIBGCC2_HAS_HF_MODE 1
+#else
+#define LIBGCC2_HAS_HF_MODE 0
+#endif
+
 #ifdef __LIBGCC_HAS_XF_MODE__
 #define LIBGCC2_HAS_XF_MODE 1
 #else
@@ -43,6 +49,10 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define LIBGCC2_HAS_TF_MODE 0
 #endif
 
+#ifndef BID_HAS_HF_MODE
+#define BID_HAS_HF_MODE LIBGCC2_HAS_HF_MODE
+#endif
+
 #ifndef BID_HAS_XF_MODE
 #define BID_HAS_XF_MODE LIBGCC2_HAS_XF_MODE
 #endif
@@ -53,6 +63,9 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 /* Some handy typedefs.  */
 
+#if LIBGCC2_HAS_HF_MODE
+typedef float HFtype __attribute__ ((mode (HF)));
+#endif /* LIBGCC2_HAS_HF_MODE */
 typedef float SFtype __attribute__ ((mode (SF)));
 typedef float DFtype __attribute__ ((mode (DF)));
 #if LIBGCC2_HAS_XF_MODE
@@ -98,6 +111,12 @@  typedef __attribute__ ((aligned(16))) struct
 #endif
 #endif
 
+#if BID_HAS_HF_MODE
+#ifndef HFtype
+#define HFtype _Float16
+#endif
+#endif
+
 #ifndef SFtype
 #define SFtype float
 #endif
@@ -110,8 +129,7 @@  typedef __attribute__ ((aligned(16))) struct
 #ifndef XFtype
 #define XFtype long double
 #endif
-
-#endif   /* IN_LIBGCC2 */
+#endif
 
 #if BID_HAS_TF_MODE
 #ifndef TFtype
@@ -249,6 +267,14 @@  extern _Decimal128 __bid_extendxftd (XFtype);
 extern int isinfd32 (_Decimal32);
 extern int isinfd64 (_Decimal64);
 extern int isinfd128 (_Decimal128);
+#if BID_HAS_HF_MODE
+extern _Decimal32 __bid_extendhfsd (HFtype);
+extern _Decimal64 __bid_extendhfdd (HFtype);
+extern _Decimal128 __bid_extendhftd (HFtype);
+extern HFtype __bid_truncsdhf (_Decimal32);
+extern HFtype __bid_truncddhf (_Decimal64);
+extern HFtype __bid_trunctdhf (_Decimal128);
+#endif
 #endif  /* BID_HAS_GCC_DECIMAL_INTRINSICS */
 
 extern void __dfp_set_round (int);