diff options
author | Dennis Zhang <dennis.zh@live.com> | 2020-04-08 15:33:40 +0100 |
---|---|---|
committer | Dennis Zhang <dennis.zh@live.com> | 2020-04-08 15:33:40 +0100 |
commit | 07b9bfd02b88cad2f6b3f50ad610dd75cb989ed3 (patch) | |
tree | b8016cd1f03e89314d31b0c56e49b2b87548eb2e /gcc/testsuite/gcc.target | |
parent | 12f55e030ed068d5c7b14c65a74d102db925dab2 (diff) | |
download | gcc-07b9bfd02b88cad2f6b3f50ad610dd75cb989ed3.zip gcc-07b9bfd02b88cad2f6b3f50ad610dd75cb989ed3.tar.gz gcc-07b9bfd02b88cad2f6b3f50ad610dd75cb989ed3.tar.bz2 |
arm: CDE intrinsics using FPU/MVE S/D registers
This patch enables the ACLE intrinsics calling VCX1<A>,
VCX2<A>, and VCX3<A> instructions who work with FPU/MVE
32-bit/64-bit registers. This patch also enables DImode for VFP
to support CDE with FPU.
gcc/ChangeLog:
2020-04-08 Dennis Zhang <dennis.zhang@arm.com>
Matthew Malcomson <matthew.malcomson@arm.com>
* config/arm/arm-builtins.c (CX_IMM_QUALIFIERS): New macro.
(CX_UNARY_QUALIFIERS, CX_BINARY_QUALIFIERS): Likewise.
(CX_TERNARY_QUALIFIERS): Likewise.
(ARM_BUILTIN_CDE_PATTERN_START): Likewise.
(ARM_BUILTIN_CDE_PATTERN_END): Likewise.
(arm_init_acle_builtins): Initialize CDE builtins.
(arm_expand_acle_builtin): Check CDE constant operands.
* config/arm/arm.h (ARM_CDE_CONST_COPROC): New macro to set the range
of CDE constant operand.
* config/arm/arm.c (arm_hard_regno_mode_ok): Support DImode for
TARGET_VFP_BASE.
(ARM_VCDE_CONST_1, ARM_VCDE_CONST_2, ARM_VCDE_CONST_3): Likewise.
* config/arm/arm_cde.h (__arm_vcx1_u32): New macro of ACLE interface.
(__arm_vcx1a_u32, __arm_vcx2_u32, __arm_vcx2a_u32): Likewise.
(__arm_vcx3_u32, __arm_vcx3a_u32, __arm_vcx1d_u64): Likewise.
(__arm_vcx1da_u64, __arm_vcx2d_u64, __arm_vcx2da_u64): Likewise.
(__arm_vcx3d_u64, __arm_vcx3da_u64): Likewise.
* config/arm/arm_cde_builtins.def: New file.
* config/arm/iterators.md (V_reg): New attribute of SI.
* config/arm/predicates.md (const_int_coproc_operand): New.
(const_int_vcde1_operand, const_int_vcde2_operand): New.
(const_int_vcde3_operand): New.
* config/arm/unspecs.md (UNSPEC_VCDE, UNSPEC_VCDEA): New.
* config/arm/vfp.md (arm_vcx1<mode>): New entry.
(arm_vcx1a<mode>, arm_vcx2<mode>, arm_vcx2a<mode>): Likewise.
(arm_vcx3<mode>, arm_vcx3a<mode>): Likewise.
gcc/testsuite/ChangeLog:
2020-04-08 Dennis Zhang <dennis.zhang@arm.com>
* gcc.target/arm/acle/cde_v_1.c: New test.
* gcc.target/arm/acle/cde_v_1_err.c: New test.
* gcc.target/arm/acle/cde_v_1_mve.c: New test.
Diffstat (limited to 'gcc/testsuite/gcc.target')
-rw-r--r-- | gcc/testsuite/gcc.target/arm/acle/cde_v_1.c | 94 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/acle/cde_v_1_err.c | 127 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/acle/cde_v_1_mve.c | 56 |
3 files changed, 277 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.target/arm/acle/cde_v_1.c b/gcc/testsuite/gcc.target/arm/acle/cde_v_1.c new file mode 100644 index 0000000..3104db4 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/acle/cde_v_1.c @@ -0,0 +1,94 @@ +/* Test the CDE ACLE intrinsic. */ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_v8m_main_cde_fp_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_v8m_main_cde_fp } */ + +#include "arm_cde.h" + +#define TEST0(T, N, C, I) \ +T test_arm_##N##_##C##_##I () { \ + return __arm_##N (C, I); \ +} + +#define TEST1(T, N, C, I) \ +T test_arm_##N##_##C##_##I (T a) { \ + return __arm_##N (C, a, I); \ +} + +#define TEST2(T, N, C, I) \ +T test_arm_##N##_##C##_##I (T a) { \ + return __arm_##N (C, a, a, I); \ +} + +#define TEST3(T, N, C, I) \ +T test_arm_##N##_##C##_##I (T a) { \ + return __arm_##N (C, a, a, a, I); \ +} + +#define TEST_ALL(C) \ +TEST0 (uint32_t, vcx1_u32, C, 0) \ +TEST1 (uint32_t, vcx1a_u32, C, 0) \ +TEST1 (uint32_t, vcx2_u32, C, 0) \ +TEST2 (uint32_t, vcx2a_u32, C, 0) \ +TEST2 (uint32_t, vcx3_u32, C, 0) \ +TEST3 (uint32_t, vcx3a_u32, C, 0) \ +TEST0 (uint64_t, vcx1d_u64, C, 0) \ +TEST1 (uint64_t, vcx1da_u64, C, 0) \ +TEST1 (uint64_t, vcx2d_u64, C, 0) \ +TEST2 (uint64_t, vcx2da_u64, C, 0) \ +TEST2 (uint64_t, vcx3d_u64, C, 0) \ +TEST3 (uint64_t, vcx3da_u64, C, 0) \ +TEST0 (uint32_t, vcx1_u32, C, 2047) \ +TEST1 (uint32_t, vcx1a_u32, C, 2047) \ +TEST1 (uint32_t, vcx2_u32, C, 63) \ +TEST2 (uint32_t, vcx2a_u32, C, 63) \ +TEST2 (uint32_t, vcx3_u32, C, 7) \ +TEST3 (uint32_t, vcx3a_u32, C, 7) \ +TEST0 (uint64_t, vcx1d_u64, C, 2047) \ +TEST1 (uint64_t, vcx1da_u64, C, 2047) \ +TEST1 (uint64_t, vcx2d_u64, C, 63) \ +TEST2 (uint64_t, vcx2da_u64, C, 63) \ +TEST2 (uint64_t, vcx3d_u64, C, 7) \ +TEST3 (uint64_t, vcx3da_u64, C, 7) + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-m.main+cdecp0+fp") +TEST_ALL (0) +#pragma GCC pop_options + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-m.main+cdecp1+fp") +TEST_ALL (1) +#pragma GCC pop_options + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-m.main+cdecp2+cdecp3+cdecp4+cdecp5+cdecp6+cdecp7+fp") +TEST_ALL (2) +TEST_ALL (3) +TEST_ALL (4) +TEST_ALL (5) +TEST_ALL (6) +TEST_ALL (7) +#pragma GCC pop_options + +/* { dg-final { scan-assembler-times {\tvcx1\tp0, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx1\tp1, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx1\tp2, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx1\tp3, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx1\tp4, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx1\tp5, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx1\tp6, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx1\tp7, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx1\tp[0-7], s[0-9]+, #2047} 8 } } */ +/* { dg-final { scan-assembler-times {\tvcx1a\tp[0-7], s[0-9]+, #[0,2047]} 16 } } */ +/* { dg-final { scan-assembler-times {\tvcx2\tp[0-7], s[0-9]+, s[0-9]+, #[0,63]} 16 } } */ +/* { dg-final { scan-assembler-times {\tvcx2a\tp[0-7], s[0-9]+, s[0-9]+, #[0,63]} 16 } } */ +/* { dg-final { scan-assembler-times {\tvcx3\tp[0-7], s[0-9]+, s[0-9]+, s[0-9]+, #[0,7]} 16 } } */ +/* { dg-final { scan-assembler-times {\tvcx3a\tp[0-7], s[0-9]+, s[0-9]+, s[0-9]+, #[0,7]} 16 } } */ +/* { dg-final { scan-assembler-times {\tvcx1\tp[0-7], d[0-9]+, #[0,2047]} 16 } } */ +/* { dg-final { scan-assembler-times {\tvcx1a\tp[0-7], d[0-9]+, #[0,2047]} 16 } } */ +/* { dg-final { scan-assembler-times {\tvcx2\tp[0-7], d[0-9]+, d[0-9]+, #[0,63]} 16 } } */ +/* { dg-final { scan-assembler-times {\tvcx2a\tp[0-7], d[0-9]+, d[0-9]+, #[0,63]} 16 } } */ +/* { dg-final { scan-assembler-times {\tvcx3\tp[0-7], d[0-9]+, d[0-9]+, d[0-9]+, #[0,7]} 16 } } */ +/* { dg-final { scan-assembler-times {\tvcx3a\tp[0-7], d[0-9]+, d[0-9]+, d[0-9]+, #[0,7]} 16 } } */ diff --git a/gcc/testsuite/gcc.target/arm/acle/cde_v_1_err.c b/gcc/testsuite/gcc.target/arm/acle/cde_v_1_err.c new file mode 100644 index 0000000..023fab4 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/acle/cde_v_1_err.c @@ -0,0 +1,127 @@ +/* Test the CDE ACLE intrinsic. */ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_v8m_main_cde_fp_ok } */ +/* { dg-add-options arm_v8m_main_cde_fp } */ + +#include "arm_cde.h" + +uint64_t test_coproc_range (uint32_t a, uint64_t b) +{ + uint64_t res = 0; + res += __arm_vcx1_u32 (8, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx1a_u32 (8, a, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx2_u32 (8, a, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx2a_u32 (8, a, a, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx3_u32 (8, a, a, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx3a_u32 (8, a, a, a, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx1d_u64 (8, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx1da_u64 (8, a, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx2d_u64 (8, a, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx2da_u64 (8, a, a, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx3d_u64 (8, a, a, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx3da_u64 (8, a, a, a, 0); /* { dg-error {coproc must be a constant immediate in range \[0-7\]} } */ + return res; +} + +uint64_t test_imm_range (uint32_t a, uint64_t b) +{ + uint64_t res = 0; + res += __arm_vcx1_u32 (0, 2048); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-2047\]} } */ + res += __arm_vcx1a_u32 (0, a, 2048); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-2047\]} } */ + res += __arm_vcx2_u32 (0, a, 64); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-63\]} } */ + res += __arm_vcx2a_u32 (0, a, a, 64); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-63\]} } */ + res += __arm_vcx3_u32 (0, a, a, 8); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx3a_u32 (0, a, a, a, 8); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx1d_u64 (0, 2048); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-2047\]} } */ + res += __arm_vcx1da_u64 (0, a, 2048); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-2047\]} } */ + res += __arm_vcx2d_u64 (0, a, 64); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-63\]} } */ + res += __arm_vcx2da_u64 (0, a, a, 64); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-63\]} } */ + res += __arm_vcx3d_u64 (0, a, a, 8); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-7\]} } */ + res += __arm_vcx3da_u64 (0, a, a, a, 8); /* { dg-error {argument [2-5] must be a constant immediate in range \[0-7\]} } */ + return res; +} + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-m.main+cdecp1+fp") +uint64_t test_coproc_match_1 (uint32_t a, uint64_t b) +{ + uint64_t res = 0; + res += __arm_vcx1_u32 (0, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + res += __arm_vcx1a_u32 (0, a, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + res += __arm_vcx2_u32 (0, a, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + res += __arm_vcx2a_u32 (0, a, a, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + res += __arm_vcx3_u32 (0, a, a, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + res += __arm_vcx3a_u32 (0, a, a, a, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + res += __arm_vcx1d_u64 (0, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + res += __arm_vcx1da_u64 (0, a, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + res += __arm_vcx2d_u64 (0, a, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + res += __arm_vcx2da_u64 (0, a, a, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + res += __arm_vcx3d_u64 (0, a, a, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + res += __arm_vcx3da_u64 (0, a, a, a, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ + return res; +} +#pragma GCC pop_options + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-m.main+cdecp2+fp") +uint32_t test_coproc_match_2 () +{ + return __arm_vcx1_u32 (0, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ +} +#pragma GCC pop_options + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-m.main+cdecp3+fp") +uint32_t test_coproc_match_3 () +{ + return __arm_vcx1_u32 (0, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ +} +#pragma GCC pop_options + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-m.main+cdecp4+fp") +uint32_t test_coproc_match_4 () +{ + return __arm_vcx1_u32 (0, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ +} +#pragma GCC pop_options + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-m.main+cdecp5+fp") +uint32_t test_coproc_match_5 () +{ + return __arm_vcx1_u32 (0, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ +} +#pragma GCC pop_options + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-m.main+cdecp6+fp") +uint32_t test_coproc_match_6 () +{ + return __arm_vcx1_u32 (0, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ +} +#pragma GCC pop_options + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-m.main+cdecp7+fp") +uint32_t test_coproc_match_7 () +{ + return __arm_vcx1_u32 (0, 0); /* { dg-error {coprocessor 0 is not enabled with \+cdecp0} } */ +} +#pragma GCC pop_options + +#pragma GCC push_options +#pragma GCC target ("arch=armv8-m.main+cdecp0+fp") +uint32_t test_coproc_match_0 () +{ + uint64_t res = 0; + res += __arm_vcx1_u32 (1, 0); /* { dg-error {coprocessor 1 is not enabled with \+cdecp1} } */ + res += __arm_vcx1_u32 (2, 0); /* { dg-error {coprocessor 2 is not enabled with \+cdecp2} } */ + res += __arm_vcx1_u32 (3, 0); /* { dg-error {coprocessor 3 is not enabled with \+cdecp3} } */ + res += __arm_vcx1_u32 (4, 0); /* { dg-error {coprocessor 4 is not enabled with \+cdecp4} } */ + res += __arm_vcx1_u32 (5, 0); /* { dg-error {coprocessor 5 is not enabled with \+cdecp5} } */ + res += __arm_vcx1_u32 (6, 0); /* { dg-error {coprocessor 6 is not enabled with \+cdecp6} } */ + res += __arm_vcx1_u32 (7, 0); /* { dg-error {coprocessor 7 is not enabled with \+cdecp7} } */ + return res; +} +#pragma GCC pop_options diff --git a/gcc/testsuite/gcc.target/arm/acle/cde_v_1_mve.c b/gcc/testsuite/gcc.target/arm/acle/cde_v_1_mve.c new file mode 100644 index 0000000..5140c3f --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/acle/cde_v_1_mve.c @@ -0,0 +1,56 @@ +/* Test the CDE ACLE intrinsic. */ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_v8_1m_main_cde_mve_ok } */ +/* { dg-options "-save-temps -O2" } */ +/* { dg-add-options arm_v8_1m_main_cde_mve } */ + +#include "arm_cde.h" + +#define TEST0(T, N, C, I) \ +T test_arm_##N##_##C##_##I () { \ + return __arm_##N (C, I); \ +} + +#define TEST1(T, N, C, I) \ +T test_arm_##N##_##C##_##I (T a) { \ + return __arm_##N (C, a, I); \ +} + +#define TEST2(T, N, C, I) \ +T test_arm_##N##_##C##_##I (T a) { \ + return __arm_##N (C, a, a, I); \ +} + +#define TEST3(T, N, C, I) \ +T test_arm_##N##_##C##_##I (T a) { \ + return __arm_##N (C, a, a, a, I); \ +} + +#define TEST_ALL(C) \ +TEST0 (uint32_t, vcx1_u32, C, 0) \ +TEST1 (uint32_t, vcx1a_u32, C, 0) \ +TEST1 (uint32_t, vcx2_u32, C, 0) \ +TEST2 (uint32_t, vcx2a_u32, C, 0) \ +TEST2 (uint32_t, vcx3_u32, C, 0) \ +TEST3 (uint32_t, vcx3a_u32, C, 0) \ +TEST0 (uint64_t, vcx1d_u64, C, 0) \ +TEST1 (uint64_t, vcx1da_u64, C, 0) \ +TEST1 (uint64_t, vcx2d_u64, C, 0) \ +TEST2 (uint64_t, vcx2da_u64, C, 0) \ +TEST2 (uint64_t, vcx3d_u64, C, 0) \ +TEST3 (uint64_t, vcx3da_u64, C, 0) + +TEST_ALL (0) + +/* { dg-final { scan-assembler-times {\tvcx1\tp0, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx1a\tp0, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx2\tp0, s[0-9]+, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx2a\tp0, s[0-9]+, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx3\tp0, s[0-9]+, s[0-9]+, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx3a\tp0, s[0-9]+, s[0-9]+, s[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx1\tp0, d[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx1a\tp0, d[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx2\tp0, d[0-9]+, d[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx2a\tp0, d[0-9]+, d[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx3\tp0, d[0-9]+, d[0-9]+, d[0-9]+, #0} 1 } } */ +/* { dg-final { scan-assembler-times {\tvcx3a\tp0, d[0-9]+, d[0-9]+, d[0-9]+, #0} 1 } } */ |