Hello Kyrill,

> What is the point of repeating the scan-assembler directives here? The
> first scan-assembler should be redundant given the scan-assembler-times ?

> Otherwise ok.

In this patch testcases are modified by removing the redundant
scan-assembler directive.

Please commit to trunk on my behalf.

Regards,
SRI.

####

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://developer.arm.com/docs/ddi0553/latest

Regression tested on target arm-none-eabi and armeb-none-eabi and found no 
regressions.

Ok for trunk?

Thanks,
Srinath.

gcc/ChangeLog:

2020-03-06  Andre Vieira  <andre.simoesdiasvie...@arm.com>
            Srinath Parvathaneni  <srinath.parvathan...@arm.com>

        * config/arm/arm.c (arm_libcall_uses_aapcs_base): Modify function to add
        emulator calls for dobule precision arithmetic operations for MVE.

2020-03-06  Srinath Parvathaneni  <srinath.parvathan...@arm.com>

        * gcc.target/arm/mve/intrinsics/mve_libcall1.c: New test.
        * gcc.target/arm/mve/intrinsics/mve_libcall2.c: Likewise.


###############     Attachment also inlined for ease of reply    ###############


diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 
b40904a40e0979af4285fdbd85bfae55abea25dd..b3dfa285f016268714002b0217964c81e0a4840e
 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 
0000000000000000000000000000000000000000..7c38d3102d26d8d7f6358258018a993df8298b4d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall1.c
@@ -0,0 +1,67 @@
+/* { dg-do compile  } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-additional-options "-march=armv8.1-m.main+mve -mfloat-abi=hard -mthumb 
-mfpu=auto" } */
+
+float
+foo (float a, float b, float c)
+{
+  return a + b + c;
+}
+
+/* { 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-times "bl\\t__aeabi_fsub" 2 } } */
+
+float
+foo2 (float a, float b, float c)
+{
+  return a * b * c;
+}
+
+/* { 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 
0000000000000000000000000000000000000000..773c8449edbe467dcdfcee260a9a04e2d4a5b0e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall2.c
@@ -0,0 +1,67 @@
+/* { dg-do compile  } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-additional-options "-march=armv8.1-m.main+mve -mfloat-abi=hard -mthumb 
-mfpu=auto" } */
+
+double
+foo (double a, double b, double c)
+{
+  return a + b + c;
+}
+
+/* { 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-times "bl\\t__aeabi_dsub" 2 } } */
+
+double
+foo2 (double a, double b, double c)
+{
+  return a * b * c;
+}
+
+/* { 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 } } */

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 
b40904a40e0979af4285fdbd85bfae55abea25dd..b3dfa285f016268714002b0217964c81e0a4840e
 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 
0000000000000000000000000000000000000000..7c38d3102d26d8d7f6358258018a993df8298b4d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall1.c
@@ -0,0 +1,67 @@
+/* { dg-do compile  } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-additional-options "-march=armv8.1-m.main+mve -mfloat-abi=hard -mthumb 
-mfpu=auto" } */
+
+float
+foo (float a, float b, float c)
+{
+  return a + b + c;
+}
+
+/* { 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-times "bl\\t__aeabi_fsub" 2 } } */
+
+float
+foo2 (float a, float b, float c)
+{
+  return a * b * c;
+}
+
+/* { 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 
0000000000000000000000000000000000000000..773c8449edbe467dcdfcee260a9a04e2d4a5b0e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_libcall2.c
@@ -0,0 +1,67 @@
+/* { dg-do compile  } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-additional-options "-march=armv8.1-m.main+mve -mfloat-abi=hard -mthumb 
-mfpu=auto" } */
+
+double
+foo (double a, double b, double c)
+{
+  return a + b + c;
+}
+
+/* { 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-times "bl\\t__aeabi_dsub" 2 } } */
+
+double
+foo2 (double a, double b, double c)
+{
+  return a * b * c;
+}
+
+/* { 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 } } */

Reply via email to