diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 09ae1118371f82ca63146fceb953eb9e820d05a4..c333fb1f72725992bb304c560f1245a242d5192d 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -2043,7 +2043,7 @@ (define_expand "add3" (define_insn "*add3_aarch64" [(set - (match_operand:GPI 0 "register_operand" "=rk,rk,w,rk,r,r,rk") + (match_operand:GPI 0 "register_operand" "=rk,!rk,w,rk,r,r,rk") (plus:GPI (match_operand:GPI 1 "register_operand" "%rk,rk,w,rk,rk,0,rk") (match_operand:GPI 2 "aarch64_pluslong_operand" "I,r,w,J,Uaa,Uai,Uav")))] diff --git a/gcc/testsuite/gcc.target/aarch64/simd/scalar_addp.c b/gcc/testsuite/gcc.target/aarch64/simd/scalar_addp.c new file mode 100644 index 0000000000000000000000000000000000000000..5b8d40f19884fc7b4e7decd80758bc36fa76d058 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/scalar_addp.c @@ -0,0 +1,70 @@ +/* { dg-do assemble } */ +/* { dg-additional-options "-save-temps -O1 -std=c99" } */ +/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ + +typedef long long v2di __attribute__((vector_size (16))); +typedef unsigned long long v2udi __attribute__((vector_size (16))); +typedef int v2si __attribute__((vector_size (16))); +typedef unsigned int v2usi __attribute__((vector_size (16))); + +/* +** foo: +** addp d0, v0.2d +** fmov x0, d0 +** ret +*/ +long long +foo (v2di x) +{ + return x[1] + x[0]; +} + +/* +** foo1: +** saddlp v0.1d, v0.2s +** fmov x0, d0 +** ret +*/ +long long +foo1 (v2si x) +{ + return x[1] + x[0]; +} + +/* +** foo2: +** uaddlp v0.1d, v0.2s +** fmov x0, d0 +** ret +*/ +unsigned long long +foo2 (v2usi x) +{ + return x[1] + x[0]; +} + +/* +** foo3: +** uaddlp v0.1d, v0.2s +** add d0, d0, d1 +** fmov x0, d0 +** ret +*/ +unsigned long long +foo3 (v2usi x, v2udi y) +{ + return (x[1] + x[0]) + y[0]; +} + +/* +** foo4: +** saddlp v0.1d, v0.2s +** add d0, d0, d1 +** fmov x0, d0 +** ret +*/ +long long +foo4 (v2si x, v2di y) +{ + return (x[1] + x[0]) + y[0]; +} diff --git a/gcc/testsuite/gcc.target/aarch64/simd/scalar_faddp.c b/gcc/testsuite/gcc.target/aarch64/simd/scalar_faddp.c new file mode 100644 index 0000000000000000000000000000000000000000..ff455e060fc833b2f63e89c467b91a76fbe31aff --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/scalar_faddp.c @@ -0,0 +1,66 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_2a_fp16_scalar_ok } */ +/* { dg-add-options arm_v8_2a_fp16_scalar } */ +/* { dg-additional-options "-save-temps -O1" } */ +/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ + +typedef double v2df __attribute__((vector_size (16))); +typedef float v4sf __attribute__((vector_size (16))); +typedef __fp16 v8hf __attribute__((vector_size (16))); + +/* +** foo: +** faddp d0, v0.2d +** ret +*/ +double +foo (v2df x) +{ + return x[1] + x[0]; +} + +/* +** foo1: +** faddp s0, v0.2s +** ret +*/ +float +foo1 (v4sf x) +{ + return x[0] + x[1]; +} + +/* +** foo2: +** faddp h0, v0.2h +** ret +*/ +__fp16 +foo2 (v8hf x) +{ + return x[0] + x[1]; +} + +/* +** foo3: +** ext v0.16b, v0.16b, v0.16b, #4 +** faddp s0, v0.2s +** ret +*/ +float +foo3 (v4sf x) +{ + return x[1] + x[2]; +} + +/* +** foo4: +** dup s0, v0.s\[3\] +** faddp h0, v0.2h +** ret +*/ +__fp16 +foo4 (v8hf x) +{ + return x[6] + x[7]; +} diff --git a/gcc/testsuite/gcc.target/aarch64/simd/scalar_faddp2.c b/gcc/testsuite/gcc.target/aarch64/simd/scalar_faddp2.c new file mode 100644 index 0000000000000000000000000000000000000000..04412c3b45c51648e46ff20f730b1213e940391a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/scalar_faddp2.c @@ -0,0 +1,14 @@ +/* { dg-do assemble } */ +/* { dg-additional-options "-save-temps -O1 -w" } */ + +typedef __m128i __attribute__((__vector_size__(2 * sizeof(long)))); +double a[]; +*b; +fn1() { + __m128i c; + *(__m128i *)a = c; + *b = a[0] + a[1]; +} + +/* { dg-final { scan-assembler-times {faddp\td0, v0\.2d} 1 } } */ + diff --git a/gcc/testsuite/gcc.target/aarch64/simd/scalar_fmaxp.c b/gcc/testsuite/gcc.target/aarch64/simd/scalar_fmaxp.c new file mode 100644 index 0000000000000000000000000000000000000000..aa1d2bf17cd707b74d8f7c574506610ab4fd7299 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/scalar_fmaxp.c @@ -0,0 +1,56 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_2a_fp16_scalar_ok } */ +/* { dg-add-options arm_v8_2a_fp16_scalar } */ +/* { dg-additional-options "-save-temps -O1" } */ +/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ + +typedef double v2df __attribute__((vector_size (16))); +typedef float v4sf __attribute__((vector_size (16))); +typedef __fp16 v8hf __attribute__((vector_size (16))); + +/* +** foo: +** fmaxnmp d0, v0.2d +** ret +*/ +double +foo (v2df x) +{ + return x[0] > x[1] ? x[0] : x[1]; +} + +/* +** foo1: +** fmaxnmp s0, v0.2s +** ret +*/ +float +foo1 (v4sf x) +{ + return x[0] > x[1] ? x[0] : x[1]; +} + +/* +** foo2: +** fmaxnmp h0, v0.2h +** ret +*/ +__fp16 +foo2 (v8hf x) +{ + return x[0] > x[1] ? x[0] : x[1]; +} + +/* +** foo3: +** fmaxnmp s0, v0.2s +** fcvt d0, s0 +** fadd d0, d0, d1 +** ret +*/ +double +foo3 (v4sf x, v2df y) +{ + return (x[0] > x[1] ? x[0] : x[1]) + y[0]; +} + diff --git a/gcc/testsuite/gcc.target/aarch64/simd/scalar_fminp.c b/gcc/testsuite/gcc.target/aarch64/simd/scalar_fminp.c new file mode 100644 index 0000000000000000000000000000000000000000..6136c5272069c4d86f09951cdff25f1494e839f0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/scalar_fminp.c @@ -0,0 +1,55 @@ +/* { dg-do assemble } */ +/* { dg-require-effective-target arm_v8_2a_fp16_scalar_ok } */ +/* { dg-add-options arm_v8_2a_fp16_scalar } */ +/* { dg-additional-options "-save-temps -O1" } */ +/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ + +typedef double v2df __attribute__((vector_size (16))); +typedef float v4sf __attribute__((vector_size (16))); +typedef __fp16 v8hf __attribute__((vector_size (16))); + +/* +** foo: +** fminnmp d0, v0.2d +** ret +*/ +double +foo (v2df x) +{ + return x[0] < x[1] ? x[0] : x[1]; +} + +/* +** foo1: +** fminnmp s0, v0.2s +** ret +*/ +float +foo1 (v4sf x) +{ + return x[0] < x[1] ? x[0] : x[1]; +} + +/* +** foo2: +** fminnmp h0, v0.2h +** ret +*/ +__fp16 +foo2 (v8hf x) +{ + return x[0] < x[1] ? x[0] : x[1]; +} + +/* +** foo3: +** fminnmp s0, v0.2s +** fcvt d0, s0 +** fadd d0, d0, d1 +** ret +*/ +double +foo3 (v4sf x, v2df y) +{ + return (x[0] < x[1] ? x[0] : x[1]) + y[0]; +} diff --git a/gcc/testsuite/gcc.target/aarch64/simd/scalar_maxp.c b/gcc/testsuite/gcc.target/aarch64/simd/scalar_maxp.c new file mode 100644 index 0000000000000000000000000000000000000000..e219a13abc745b83dca58633fd2d812e276d6b2d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/scalar_maxp.c @@ -0,0 +1,74 @@ +/* { dg-do assemble } */ +/* { dg-additional-options "-save-temps -O1 -std=c99" } */ +/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ + +typedef long long v2di __attribute__((vector_size (16))); +typedef unsigned long long v2udi __attribute__((vector_size (16))); +typedef int v2si __attribute__((vector_size (16))); +typedef unsigned int v2usi __attribute__((vector_size (16))); + +/* +** foo: +** umov x0, v0.d\[1\] +** fmov x1, d0 +** cmp x0, x1 +** csel x0, x0, x1, ge +** ret +*/ +long long +foo (v2di x) +{ + return x[0] > x[1] ? x[0] : x[1]; +} + +/* +** foo1: +** smaxp v0.2s, v0.2s, v0.2s +** smov x0, v0.s\[0\] +** ret +*/ +long long +foo1 (v2si x) +{ + return x[0] > x[1] ? x[0] : x[1]; +} + +/* +** foo2: +** umaxp v0.2s, v0.2s, v0.2s +** fmov w0, s0 +** ret +*/ +unsigned long long +foo2 (v2usi x) +{ + return x[0] > x[1] ? x[0] : x[1]; +} + +/* +** foo3: +** umaxp v0.2s, v0.2s, v0.2s +** fmov w0, s0 +** fmov x1, d1 +** add x0, x1, w0, uxtw +** ret +*/ +unsigned long long +foo3 (v2usi x, v2udi y) +{ + return (x[0] > x[1] ? x[0] : x[1]) + y[0]; +} + +/* +** foo4: +** smaxp v0.2s, v0.2s, v0.2s +** fmov w0, s0 +** fmov x1, d1 +** add x0, x1, w0, sxtw +** ret +*/ +long long +foo4 (v2si x, v2di y) +{ + return (x[0] > x[1] ? x[0] : x[1]) + y[0]; +} diff --git a/gcc/testsuite/gcc.target/aarch64/simd/scalar_minp.c b/gcc/testsuite/gcc.target/aarch64/simd/scalar_minp.c new file mode 100644 index 0000000000000000000000000000000000000000..2a32fb4ea3edaa4c547a7a481c3ddca6b477430e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/simd/scalar_minp.c @@ -0,0 +1,74 @@ +/* { dg-do assemble } */ +/* { dg-additional-options "-save-temps -O1 -std=c99" } */ +/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ + +typedef long long v2di __attribute__((vector_size (16))); +typedef unsigned long long v2udi __attribute__((vector_size (16))); +typedef int v2si __attribute__((vector_size (16))); +typedef unsigned int v2usi __attribute__((vector_size (16))); + +/* +** foo: +** umov x0, v0.d\[1\] +** fmov x1, d0 +** cmp x0, x1 +** csel x0, x0, x1, le +** ret +*/ +long long +foo (v2di x) +{ + return x[0] < x[1] ? x[0] : x[1]; +} + +/* +** foo1: +** sminp v0.2s, v0.2s, v0.2s +** smov x0, v0.s\[0\] +** ret +*/ +long long +foo1 (v2si x) +{ + return x[0] < x[1] ? x[0] : x[1]; +} + +/* +** foo2: +** uminp v0.2s, v0.2s, v0.2s +** fmov w0, s0 +** ret +*/ +unsigned long long +foo2 (v2usi x) +{ + return x[0] < x[1] ? x[0] : x[1]; +} + +/* +** foo3: +** uminp v0.2s, v0.2s, v0.2s +** fmov w0, s0 +** fmov x1, d1 +** add x0, x1, w0, uxtw +** ret +*/ +unsigned long long +foo3 (v2usi x, v2udi y) +{ + return (x[0] < x[1] ? x[0] : x[1]) + y[0]; +} + +/* +** foo4: +** sminp v0.2s, v0.2s, v0.2s +** fmov w0, s0 +** fmov x1, d1 +** add x0, x1, w0, sxtw +** ret +*/ +long long +foo4 (v2si x, v2di y) +{ + return (x[0] < x[1] ? x[0] : x[1]) + y[0]; +}