[Arm] Implement CDE intrinsics for MVE registers.
authorMatthew Malcomson <matthew.malcomson@arm.com>
Wed, 8 Apr 2020 15:06:47 +0000 (16:06 +0100)
committerMatthew Malcomson <matthew.malcomson@arm.com>
Wed, 8 Apr 2020 15:06:47 +0000 (16:06 +0100)
commit78bf9163764aba15bb0c254cd38c985713924380
tree5a00501550511635d0f75ea594231486d697c101
parenta5f3c89e1b78dbb69d3c7a47d2c9fd7ad93fe136
[Arm] Implement CDE intrinsics for MVE registers.

Implement CDE intrinsics on MVE registers.

Other than the basics required for adding intrinsics this patch consists
of three changes.

** We separate out the MVE types and casts from the arm_mve.h header.

This is so that the types can be used in arm_cde.h without the need to include
the entire arm_mve.h header.
The only type that arm_cde.h needs is `uint8x16_t`, so this separation could be
avoided by using a `typedef` in this file.
Since the introduced intrinsics are all defined to act on the full range of MVE
types, declaring all such types seems intuitive since it will provide their
declaration to the user too.

This arm_mve_types.h header not only includes the MVE types, but also
the conversion intrinsics between them.
Some of the conversion intrinsics are needed for arm_cde.h, but most are
not.  We include all conversion intrinsics to keep the definition of
such conversion functions all in one place, on the understanding that
extra conversion functions being defined when including `arm_cde.h` is
not a problem.

** We define the TARGET_RESOLVE_OVERLOADED_BUILTIN hook for the Arm backend.

This is needed to implement the polymorphism for the required intrinsics.
The intrinsics have no specialised version, and the resulting assembly
instruction for all different types should be exactly the same.
Due to this we have implemented these intrinsics via one builtin on one type.
All other calls to the intrinsic with different types are implicitly cast to
the one type that is defined, and hence are all expanded to the same RTL
pattern that is only defined for one machine mode.

** We seperate the initialisation of the CDE intrinsics from others.

This allows us to ensure that the CDE intrinsics acting on MVE registers
are only created when both CDE and MVE are available.
Only initialising these builtins when both features are available is
especially important since they require a type that is only initialised
when the target supports hard float.  Hence trying to initialise these
builtins on a soft float target would cause an ICE.

Testing done:
  Full bootstrap and regtest on arm-none-linux-gnueabihf
  Regression test on arm-none-eabi

Ok for trunk?

gcc/ChangeLog:

2020-03-10  Matthew Malcomson  <matthew.malcomson@arm.com>

* config.gcc (arm_mve_types.h): New extra_header for arm.
* config/arm/arm-builtins.c (arm_resolve_overloaded_builtin): New.
(arm_init_cde_builtins): New.
(arm_init_acle_builtins): Remove initialisation of CDE builtins.
(arm_init_builtins): Call arm_init_cde_builtins when target
supports CDE.
* config/arm/arm-c.c (arm_resolve_overloaded_builtin): New declaration.
(arm_register_target_pragmas): Initialise resolve_overloaded_builtin
hook to the implementation for the arm backend.
* config/arm/arm.h (ARM_MVE_CDE_CONST_1): New.
(ARM_MVE_CDE_CONST_2): New.
(ARM_MVE_CDE_CONST_3): New.
* config/arm/arm_cde.h (__arm_vcx1q_u8): New.
(__arm_vcx1qa): New.
(__arm_vcx2q): New.
(__arm_vcx2q_u8): New.
(__arm_vcx2qa): New.
(__arm_vcx3q): New.
(__arm_vcx3q_u8): New.
(__arm_vcx3qa): New.
* config/arm/arm_cde_builtins.def (vcx1q, vcx1qa, vcx2q, vcx2qa, vcx3q,
vcx3qa): New builtins defined.
* config/arm/arm_mve.h: Move typedefs and conversion intrinsics
to arm_mve_types.h header.
* config/arm/arm_mve_types.h: New file.
* config/arm/mve.md (arm_vcx1qv16qi, arm_vcx1qav16qi, arm_vcx2qv16qi,
arm_vcx2qav16qi, arm_vcx3qv16qi, arm_vcx3qav16qi): New patterns.
* config/arm/predicates.md (const_int_mve_cde1_operand,
const_int_mve_cde2_operand, const_int_mve_cde3_operand): New.

gcc/testsuite/ChangeLog:

2020-03-23  Matthew Malcomson  <matthew.malcomson@arm.com>
    Dennis Zhang  <dennis.zhang@arm.com>

* gcc.target/arm/acle/cde-mve-error-1.c: New test.
* gcc.target/arm/acle/cde-mve-error-2.c: New test.
* gcc.target/arm/acle/cde-mve-error-3.c: New test.
* gcc.target/arm/acle/cde-mve-full-assembly.c: New test.
* gcc.target/arm/acle/cde-mve-tests.c: New test.
* lib/target-supports.exp (arm_v8_1m_main_cde_mve_fp): New check
effective.
(arm_v8_1m_main_cde_mve, arm_v8m_main_cde_fp): Use -mfpu=auto
so we only check configurations that make sense.
16 files changed:
gcc/config.gcc
gcc/config/arm/arm-builtins.c
gcc/config/arm/arm-c.c
gcc/config/arm/arm.h
gcc/config/arm/arm_cde.h
gcc/config/arm/arm_cde_builtins.def
gcc/config/arm/arm_mve.h
gcc/config/arm/arm_mve_types.h [new file with mode: 0644]
gcc/config/arm/mve.md
gcc/config/arm/predicates.md
gcc/testsuite/gcc.target/arm/acle/cde-mve-error-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/acle/cde-mve-error-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/acle/cde-mve-error-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/acle/cde-mve-full-assembly.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/acle/cde-mve-tests.c [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp