libgcc: Add support for HF mode (aka _Float16) in libbid
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_64. 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.
This commit is contained in:
parent
46c6976da1
commit
308a0af4f9
|
@ -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 } } } } */
|
|
@ -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 } } } } */
|
|
@ -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),)
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue