aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@arm.com>2022-05-04 16:13:35 +0100
committerChristophe Lyon <christophe.lyon@arm.com>2022-05-20 09:35:54 +0200
commit308a0af4f913243023ee52332f7cc513745c9203 (patch)
tree3aa44acaea135b1843150f55178c87208f9c3f54 /gcc
parent46c6976da146fbd52c088c1530f25e8b8f56c648 (diff)
downloadgcc-308a0af4f913243023ee52332f7cc513745c9203.zip
gcc-308a0af4f913243023ee52332f7cc513745c9203.tar.gz
gcc-308a0af4f913243023ee52332f7cc513745c9203.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/torture/convert-dfp-2.c45
-rw-r--r--gcc/testsuite/gcc.dg/torture/convert-dfp.c63
2 files changed, 108 insertions, 0 deletions
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 0000000..3e4ecb5
--- /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 0000000..ec13689
--- /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 } } } } */