Victor Do Nascimento <victor.donascime...@arm.com> writes:
> Add a build-time test to check whether system register data, as
> imported from `aarch64-sys-reg.def' has any duplicate entries.
>
> Duplicate entries are defined as any two SYSREG entries in the .def
> file which share the same encoding values (as specified by its `CPENC'
> field) and where the relationship amongst the two does not fit into
> one of the following categories:
>
>       * Simple aliasing: In some cases, it is observed that one
>       register name serves as an alias to another.  One example of
>       this is where TRCEXTINSELR aliases TRCEXTINSELR0.
>       * Expressing intent: It is possible that when a given register
>       serves two distinct functions depending on how it is used, it
>       is given two distinct names whose use should match the context
>       under which it is being used.  Example:  Debug Data Transfer
>       Register. When used to receive data, it should be accessed as
>       DBGDTRRX_EL0 while when transmitting data it should be
>       accessed via DBGDTRTX_EL0.
>       * Register depreciation: Some register names have been
>       deprecated and should no longer be used, but backwards-
>       compatibility requires that such names continue to be
>       recognized, as is the case for the SPSR_EL1 register, whose
>       access via the SPSR_SVC name is now deprecated.
>       * Same encoding different target: Some encodings are given
>       different meaning depending on the target architecture and, as
>       such, are given different names in each of theses contexts.
>       We see an example of this for CPENC(3,4,2,0,0), which
>       corresponds to TTBR0_EL2 for Armv8-A targets and VSCTLR_EL2
>       in Armv8-R targets.
>
> A consequence of these observations is that `CPENC' duplication is
> acceptable iff at least one of the `properties' or `arch_reqs' fields
> of the `sysreg_t' structs associated with the two registers in
> question differ and it's this condition that is checked by the new
> `aarch64_test_sysreg_encoding_clashes' function.
>
> gcc/ChangeLog:
>
>       * config/aarch64/aarch64.cc
>       (aarch64_test_sysreg_encoding_clashes): New.
>       (aarch64_run_selftests): add call to
>       aarch64_test_sysreg_encoding_clashes selftest.

OK, thanks.

Richard

> ---
>  gcc/config/aarch64/aarch64.cc | 44 +++++++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
>
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index eaeab0be436..c0d75f167be 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -22,6 +22,7 @@
>  
>  #define INCLUDE_STRING
>  #define INCLUDE_ALGORITHM
> +#define INCLUDE_VECTOR
>  #include "config.h"
>  #include "system.h"
>  #include "coretypes.h"
> @@ -28390,6 +28391,48 @@ aarch64_test_fractional_cost ()
>    ASSERT_EQ (cf (1, 2).as_double (), 0.5);
>  }
>  
> +/* Calculate whether our system register data, as imported from
> +   `aarch64-sys-reg.def' has any duplicate entries.  */
> +static void
> +aarch64_test_sysreg_encoding_clashes (void)
> +{
> +  using dup_instances_t = hash_map<nofree_string_hash,
> +                                std::vector<const sysreg_t*>>;
> +
> +  dup_instances_t duplicate_instances;
> +
> +  /* Every time an encoding is established to come up more than once
> +     we add it to a "clash-analysis queue", which is then used to extract
> +     necessary information from our hash map when establishing whether
> +     repeated encodings are valid.  */
> +
> +  /* 1) Collect recurrence information.  */
> +  for (unsigned i = 0; i < nsysreg; i++)
> +    {
> +      const sysreg_t *reg = sysreg_structs + i;
> +
> +      std::vector<const sysreg_t*> *tmp
> +     = &duplicate_instances.get_or_insert (reg->encoding);
> +
> +      tmp->push_back (reg);
> +    }
> +
> +  /* 2) Carry out analysis on collected data.  */
> +  for (auto instance : duplicate_instances)
> +    {
> +      unsigned nrep = instance.second.size ();
> +      if (nrep > 1)
> +     for (unsigned i = 0; i < nrep; i++)
> +       for (unsigned j = i + 1; j < nrep; j++)
> +         {
> +           const sysreg_t *a = instance.second[i];
> +           const sysreg_t *b = instance.second[j];
> +           ASSERT_TRUE ((a->properties != b->properties)
> +                        || (a->arch_reqs != b->arch_reqs));
> +         }
> +    }
> +}
> +
>  /* Run all target-specific selftests.  */
>  
>  static void
> @@ -28397,6 +28440,7 @@ aarch64_run_selftests (void)
>  {
>    aarch64_test_loading_full_dump ();
>    aarch64_test_fractional_cost ();
> +  aarch64_test_sysreg_encoding_clashes ();
>  }
>  
>  } // namespace selftest

Reply via email to