Message ID | DBBPR08MB4775D447702E437029F573BB9B150@DBBPR08MB4775.eurprd08.prod.outlook.com |
---|---|
State | New |
Headers | show |
Series | [v2,ARM,3/x] : MVE ACLE intrinsics framework patch. | expand |
On 2/14/20 4:34 PM, Srinath Parvathaneni wrote: > Hello Kyrill, > > In this patch (v2) all the review comments mentioned in previous patch > (v1) are > addressed. > > (v1) https://gcc.gnu.org/ml/gcc-patches/2019-12/msg01401.html > > ##################### > > Hello, > > This patch is part of MVE ACLE intrinsics framework. > > The patch supports the use of emulation for the single-precision > arithmetic > operations for MVE. This changes are to support the MVE ACLE > intrinsics which > operates on vector floating point arithmetic operations. > > Please refer to Arm reference manual [1] for more details. > [1] > https://static.docs.arm.com/ddi0553/bh/DDI0553B_h_armv8m_arm.pdf?_ga=2.102521798.659307368.1572453718-1501600630.1548848914 > > Regression tested on arm-none-eabi and found no regressions. > > Ok for trunk? > Ok. Thanks, Kyrill > Thanks, > Srinath. > > gcc/ChangeLog: > > 2019-11-11 Andre Vieira <andre.simoesdiasvieira@arm.com> > Srinath Parvathaneni <srinath.parvathaneni@arm.com> > > * config/arm/arm.c (arm_libcall_uses_aapcs_base): Modify > function to add > emulator calls for dobule precision arithmetic operations for MVE. > > > ############### Attachment also inlined for ease of reply > ############### > > > >From af9d1eb4470c26564b69518bbec3fce297501fdd Mon Sep 17 00:00:00 2001 > From: Srinath Parvathaneni <srinath.parvathaneni@arm.com> > Date: Tue, 11 Feb 2020 18:42:20 +0000 > Subject: [PATCH] [PATCH][ARM][GCC][3/x]: MVE ACLE intrinsics framework > patch. > > --- > gcc/config/arm/arm.c | 22 ++++++- > .../gcc.target/arm/mve/intrinsics/mve_libcall1.c | 70 > ++++++++++++++++++++++ > .../gcc.target/arm/mve/intrinsics/mve_libcall2.c | 70 > ++++++++++++++++++++++ > 3 files changed, 159 insertions(+), 3 deletions(-) > create mode 100644 > gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall1.c > create mode 100644 > gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall2.c > > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c > index 037f298..e00024b 100644 > --- a/gcc/config/arm/arm.c > +++ b/gcc/config/arm/arm.c > @@ -5754,9 +5754,25 @@ arm_libcall_uses_aapcs_base (const_rtx libcall) > /* Values from double-precision helper functions are returned > in core > registers if the selected core only supports single-precision > arithmetic, even if we are using the hard-float ABI. The > same is > - true for single-precision helpers, but we will never be using the > - hard-float ABI on a CPU which doesn't support single-precision > - operations in hardware. */ > + true for single-precision helpers except in case of MVE, > because in > + MVE we will be using the hard-float ABI on a CPU which > doesn't support > + single-precision operations in hardware. In MVE the > following check > + enables use of emulation for the single-precision arithmetic > + operations. */ > + if (TARGET_HAVE_MVE) > + { > + add_libcall (libcall_htab, optab_libfunc (add_optab, SFmode)); > + add_libcall (libcall_htab, optab_libfunc (sdiv_optab, SFmode)); > + add_libcall (libcall_htab, optab_libfunc (smul_optab, SFmode)); > + add_libcall (libcall_htab, optab_libfunc (neg_optab, SFmode)); > + add_libcall (libcall_htab, optab_libfunc (sub_optab, SFmode)); > + add_libcall (libcall_htab, optab_libfunc (eq_optab, SFmode)); > + add_libcall (libcall_htab, optab_libfunc (lt_optab, SFmode)); > + add_libcall (libcall_htab, optab_libfunc (le_optab, SFmode)); > + add_libcall (libcall_htab, optab_libfunc (ge_optab, SFmode)); > + add_libcall (libcall_htab, optab_libfunc (gt_optab, SFmode)); > + add_libcall (libcall_htab, optab_libfunc (unord_optab, SFmode)); > + } > add_libcall (libcall_htab, optab_libfunc (add_optab, DFmode)); > add_libcall (libcall_htab, optab_libfunc (sdiv_optab, DFmode)); > add_libcall (libcall_htab, optab_libfunc (smul_optab, DFmode)); > diff --git > a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall1.c > b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall1.c > new file mode 100644 > index 0000000..45f46b1 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall1.c > @@ -0,0 +1,70 @@ > +/* { dg-do compile } */ > +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ > +/* { dg-add-options arm_v8_1m_mve } */ > + > +float > +foo (float a, float b, float c) > +{ > + return a + b + c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_fadd" } } */ > +/* { dg-final { scan-assembler-times "bl\\t__aeabi_fadd" 2 } } */ > + > +float > +foo1 (float a, float b, float c) > +{ > + return a - b - c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_fsub" } } */ > +/* { dg-final { scan-assembler-times "bl\\t__aeabi_fsub" 2 } } */ > + > +float > +foo2 (float a, float b, float c) > +{ > + return a * b * c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_fmul" } } */ > +/* { dg-final { scan-assembler-times "bl\\t__aeabi_fmul" 2 } } */ > + > +float > +foo3 (float b, float c) > +{ > + return b / c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_fdiv" } } */ > + > +int > +foo4 (float b, float c) > +{ > + return b < c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_fcmplt" } } */ > + > +int > +foo5 (float b, float c) > +{ > + return b > c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_fcmpgt" } } */ > + > +int > +foo6 (float b, float c) > +{ > + return b != c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_fcmpeq" } } */ > + > +int > +foo7 (float b, float c) > +{ > + return b == c; > +} > + > +/* { dg-final { scan-assembler-times "bl\\t__aeabi_fcmpeq" 2 } } */ > diff --git > a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall2.c > b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall2.c > new file mode 100644 > index 0000000..45216d12 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall2.c > @@ -0,0 +1,70 @@ > +/* { dg-do compile } */ > +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ > +/* { dg-add-options arm_v8_1m_mve } */ > + > +double > +foo (double a, double b, double c) > +{ > + return a + b + c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_dadd" } } */ > +/* { dg-final { scan-assembler-times "bl\\t__aeabi_dadd" 2 } } */ > + > +double > +foo1 (double a, double b, double c) > +{ > + return a - b - c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_dsub" } } */ > +/* { dg-final { scan-assembler-times "bl\\t__aeabi_dsub" 2 } } */ > + > +double > +foo2 (double a, double b, double c) > +{ > + return a * b * c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_dmul" } } */ > +/* { dg-final { scan-assembler-times "bl\\t__aeabi_dmul" 2 } } */ > + > +double > +foo3 (double b, double c) > +{ > + return b / c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_ddiv" } } */ > + > +int > +foo4 (double b, double c) > +{ > + return b < c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_dcmplt" } } */ > + > +int > +foo5 (double b, double c) > +{ > + return b > c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_dcmpgt" } } */ > + > +int > +foo6 (double b, double c) > +{ > + return b != c; > +} > + > +/* { dg-final { scan-assembler "bl\\t__aeabi_dcmpeq" } } */ > + > +int > +foo7 (double b, double c) > +{ > + return b == c; > +} > + > +/* { dg-final { scan-assembler-times "bl\\t__aeabi_dcmpeq" 2 } } */ > -- > 2.7.4 > >
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 037f298..e00024b 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -5754,9 +5754,25 @@ arm_libcall_uses_aapcs_base (const_rtx libcall) /* Values from double-precision helper functions are returned in core registers if the selected core only supports single-precision arithmetic, even if we are using the hard-float ABI. The same is - true for single-precision helpers, but we will never be using the - hard-float ABI on a CPU which doesn't support single-precision - operations in hardware. */ + true for single-precision helpers except in case of MVE, because in + MVE we will be using the hard-float ABI on a CPU which doesn't support + single-precision operations in hardware. In MVE the following check + enables use of emulation for the single-precision arithmetic + operations. */ + if (TARGET_HAVE_MVE) + { + add_libcall (libcall_htab, optab_libfunc (add_optab, SFmode)); + add_libcall (libcall_htab, optab_libfunc (sdiv_optab, SFmode)); + add_libcall (libcall_htab, optab_libfunc (smul_optab, SFmode)); + add_libcall (libcall_htab, optab_libfunc (neg_optab, SFmode)); + add_libcall (libcall_htab, optab_libfunc (sub_optab, SFmode)); + add_libcall (libcall_htab, optab_libfunc (eq_optab, SFmode)); + add_libcall (libcall_htab, optab_libfunc (lt_optab, SFmode)); + add_libcall (libcall_htab, optab_libfunc (le_optab, SFmode)); + add_libcall (libcall_htab, optab_libfunc (ge_optab, SFmode)); + add_libcall (libcall_htab, optab_libfunc (gt_optab, SFmode)); + add_libcall (libcall_htab, optab_libfunc (unord_optab, SFmode)); + } add_libcall (libcall_htab, optab_libfunc (add_optab, DFmode)); add_libcall (libcall_htab, optab_libfunc (sdiv_optab, DFmode)); add_libcall (libcall_htab, optab_libfunc (smul_optab, DFmode)); diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall1.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall1.c new file mode 100644 index 0000000..45f46b1 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall1.c @@ -0,0 +1,70 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ + +float +foo (float a, float b, float c) +{ + return a + b + c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_fadd" } } */ +/* { dg-final { scan-assembler-times "bl\\t__aeabi_fadd" 2 } } */ + +float +foo1 (float a, float b, float c) +{ + return a - b - c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_fsub" } } */ +/* { dg-final { scan-assembler-times "bl\\t__aeabi_fsub" 2 } } */ + +float +foo2 (float a, float b, float c) +{ + return a * b * c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_fmul" } } */ +/* { dg-final { scan-assembler-times "bl\\t__aeabi_fmul" 2 } } */ + +float +foo3 (float b, float c) +{ + return b / c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_fdiv" } } */ + +int +foo4 (float b, float c) +{ + return b < c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_fcmplt" } } */ + +int +foo5 (float b, float c) +{ + return b > c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_fcmpgt" } } */ + +int +foo6 (float b, float c) +{ + return b != c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_fcmpeq" } } */ + +int +foo7 (float b, float c) +{ + return b == c; +} + +/* { dg-final { scan-assembler-times "bl\\t__aeabi_fcmpeq" 2 } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall2.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall2.c new file mode 100644 index 0000000..45216d12 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall2.c @@ -0,0 +1,70 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ + +double +foo (double a, double b, double c) +{ + return a + b + c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_dadd" } } */ +/* { dg-final { scan-assembler-times "bl\\t__aeabi_dadd" 2 } } */ + +double +foo1 (double a, double b, double c) +{ + return a - b - c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_dsub" } } */ +/* { dg-final { scan-assembler-times "bl\\t__aeabi_dsub" 2 } } */ + +double +foo2 (double a, double b, double c) +{ + return a * b * c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_dmul" } } */ +/* { dg-final { scan-assembler-times "bl\\t__aeabi_dmul" 2 } } */ + +double +foo3 (double b, double c) +{ + return b / c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_ddiv" } } */ + +int +foo4 (double b, double c) +{ + return b < c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_dcmplt" } } */ + +int +foo5 (double b, double c) +{ + return b > c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_dcmpgt" } } */ + +int +foo6 (double b, double c) +{ + return b != c; +} + +/* { dg-final { scan-assembler "bl\\t__aeabi_dcmpeq" } } */ + +int +foo7 (double b, double c) +{ + return b == c; +} + +/* { dg-final { scan-assembler-times "bl\\t__aeabi_dcmpeq" 2 } } */