Yury Khrustalev <yury.khrusta...@arm.com> writes:
> From: Szabolcs Nagy <szabolcs.n...@arm.com>
>
> gcc/testsuite/ChangeLog:
>
>       * gcc.target/aarch64/gcspopm-1.c: New test.
>       * gcc.target/aarch64/gcspr-1.c: New test.
>       * gcc.target/aarch64/gcsss-1.c: New test.
> ---
>  gcc/testsuite/gcc.target/aarch64/gcspopm-1.c | 69 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/aarch64/gcspr-1.c   | 31 +++++++++
>  gcc/testsuite/gcc.target/aarch64/gcsss-1.c   | 49 ++++++++++++++
>  3 files changed, 149 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/gcspopm-1.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/gcspr-1.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/gcsss-1.c
>
> diff --git a/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c 
> b/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c
> new file mode 100644
> index 00000000000..6e6add39cf7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c
> @@ -0,0 +1,69 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mbranch-protection=none" } */
> +/* { dg-final { check-function-bodies "**" "" "" } } */
> +
> +/*
> +**foo1:
> +**   sysl    xzr, #3, c7, c7, #1 // gcspopm
> +**   ret
> +*/
> +void
> +foo1 (void)
> +{
> +  __builtin_aarch64_gcspopm ();
> +}
> +
> +/*
> +**foo2:
> +**   mov     x0, 0
> +**   sysl    x0, #3, c7, c7, #1 // gcspopm
> +**   ret
> +*/
> +unsigned long long
> +foo2 (void)
> +{
> +  return __builtin_aarch64_gcspopm ();
> +}
> +
> +/*
> +**foo3:
> +**   mov     x16, 1
> +** (
> +**   mov     x0, 0
> +**   hint    40 // chkfeat x16
> +** |
> +**   hint    40 // chkfeat x16
> +**   mov     x0, 0
> +** )

The mov could also happen first, before the mov x16, 1.  It would
probably be easier to use...

> +**   cbz     x16, .*
> +**   ret
> +**   mov     x0, 0
> +**   sysl    x0, #3, c7, c7, #1 // gcspopm
> +**   ret
> +*/
> +unsigned long long
> +foo3 (void)
> +{
> +  if (__builtin_aarch64_chkfeat (1) == 0)
> +    return __builtin_aarch64_gcspopm ();
> +  return 0;
> +}

unsigned long long
foo3 (unsigned long long x)
{
  if (__builtin_aarch64_chkfeat (1) == 0)
    return __builtin_aarch64_gcspopm ();
  return x;
}

so that x0 is returned unmodified if the chkfeat returns nonzero.

FWIW, if we do remove the embedded moves from the .md define_insns,
we should also be able to get rid of the redundant zeroing of x0
on the gcspopm path.

> +
> +/*
> +**foo4:
> +**   sysl    xzr, #3, c7, c7, #1 // gcspopm
> +**   mov     x0, 0
> +**   sysl    x0, #3, c7, c7, #1 // gcspopm
> +**   sysl    xzr, #3, c7, c7, #1 // gcspopm
> +**   ret
> +*/
> +unsigned long long
> +foo4 (void)
> +{
> +  unsigned long long a = __builtin_aarch64_gcspopm ();
> +  unsigned long long b = __builtin_aarch64_gcspopm ();
> +  unsigned long long c = __builtin_aarch64_gcspopm ();
> +  (void) a;
> +  (void) c;
> +  return b;
> +}

Nice test :)

> diff --git a/gcc/testsuite/gcc.target/aarch64/gcspr-1.c 
> b/gcc/testsuite/gcc.target/aarch64/gcspr-1.c
> new file mode 100644
> index 00000000000..0e651979551
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/gcspr-1.c
> @@ -0,0 +1,31 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mbranch-protection=none" } */
> +/* { dg-final { check-function-bodies "**" "" "" } } */
> +
> +/*
> +**foo1:
> +**   mrs     x0, s3_3_c2_c5_1 // gcspr_el0
> +**   ret
> +*/
> +void *
> +foo1 (void)
> +{
> +  return __builtin_aarch64_gcspr ();
> +}
> +
> +/*
> +**foo2:
> +**   mrs     x[0-9]*, s3_3_c2_c5_1 // gcspr_el0
> +**   sysl    xzr, #3, c7, c7, #1 // gcspopm
> +**   mrs     x[0-9]*, s3_3_c2_c5_1 // gcspr_el0
> +**   sub     x0, x[0-9]*, x[0-9]*
> +**   ret
> +*/
> +long
> +foo2 (void)
> +{
> +  const char *p = __builtin_aarch64_gcspr ();
> +  __builtin_aarch64_gcspopm ();
> +  const char *q = __builtin_aarch64_gcspr ();
> +  return p - q;
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/gcsss-1.c 
> b/gcc/testsuite/gcc.target/aarch64/gcsss-1.c
> new file mode 100644
> index 00000000000..025c7fee647
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/gcsss-1.c
> @@ -0,0 +1,49 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mbranch-protection=none" } */
> +/* { dg-final { check-function-bodies "**" "" "" } } */
> +
> +/*
> +**foo1:
> +**   sys     #3, c7, c7, #2, x0 // gcsss1
> +**   mov     x[0-9]*, 0
> +**   sysl    x[0-9]*, #3, c7, c7, #3 // gcsss2

Might as well make this:

**      mov     (x[0-9]+), 0
**      sysl    \1, #3, c7, c7, #3 // gcsss2


> +**   ret
> +*/
> +void
> +foo1 (void *p)
> +{
> +  __builtin_aarch64_gcsss (p);
> +}
> +
> +/*
> +**foo2:
> +**   sys     #3, c7, c7, #2, x0 // gcsss1
> +**   mov     x0, 0
> +**   sysl    x0, #3, c7, c7, #3 // gcsss2
> +**   ret
> +*/
> +void *
> +foo2 (void *p)
> +{
> +  return __builtin_aarch64_gcsss (p);
> +}
> +
> +/*
> +**foo3:
> +**   mov     x16, 1
> +**   hint    40 // chkfeat x16
> +**   cbnz    x16, .*
> +**   sys     #3, c7, c7, #2, x0 // gcsss1
> +**   mov     x0, 0
> +**   sysl    x0, #3, c7, c7, #3 // gcsss2
> +**   ret
> +**   mov     x0, 0
> +**   ret
> +*/
> +void *
> +foo3 (void *p)
> +{
> +  if (__builtin_aarch64_chkfeat (1) == 0)
> +    return __builtin_aarch64_gcsss (p);
> +  return 0;
> +}

Similarly to the above, it would probably be good to return p instead
of 0 here, to avoid awkwardness with the positioning of the return 0 path.

Thanks,
Richard

Reply via email to