On Wed, Jun 5, 2024 at 2:32 PM <frank.ch...@sifive.com> wrote:

> From: Frank Chang <frank.ch...@sifive.com>
>
> Introduce helpers to enable the extensions based on the implied rules.
> The implied extensions are enabled recursively, so we don't have to
> expand all of them manually. This also eliminates the old-fashioned
> ordering requirement. For example, Zvksg implies Zvks, Zvks implies
> Zvksed, etc., removing the need to check the implied rules of Zvksg
> before Zvks.
>
> Signed-off-by: Frank Chang <frank.ch...@sifive.com>
> ---
>  target/riscv/tcg/tcg-cpu.c | 89 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 89 insertions(+)
>
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 683f604d9f..899d605d36 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -36,6 +36,9 @@
>  static GHashTable *multi_ext_user_opts;
>  static GHashTable *misa_ext_user_opts;
>
> +static GHashTable *misa_implied_rules;
> +static GHashTable *ext_implied_rules;
> +
>  static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
>  {
>      return g_hash_table_contains(multi_ext_user_opts,
> @@ -833,11 +836,95 @@ static void riscv_cpu_validate_profiles(RISCVCPU
> *cpu)
>      }
>  }
>
> +static void riscv_cpu_init_implied_exts_rules(void)
> +{
> +    RISCVCPUImpliedExtsRule *rule;
> +    int i;
> +
> +    for (i = 0; (rule = riscv_misa_implied_rules[i]); i++) {
> +        g_hash_table_insert(misa_implied_rules,
> GUINT_TO_POINTER(rule->ext),
> +                            (gpointer)rule);
> +    }
> +
> +    for (i = 0; (rule = riscv_ext_implied_rules[i]); i++) {
> +        g_hash_table_insert(ext_implied_rules,
> GUINT_TO_POINTER(rule->ext),
> +                            (gpointer)rule);
> +    }
> +}
> +
> +static void cpu_enable_implied_rule(RISCVCPU *cpu,
> +                                    RISCVCPUImpliedExtsRule *rule)
> +{
> +    CPURISCVState *env = &cpu->env;
> +    RISCVCPUImpliedExtsRule *ir;
> +    target_ulong hartid = 0;
> +    int i;
> +
> +#if !defined(CONFIG_USER_ONLY)
> +    hartid = env->mhartid;
> +#endif
> +
> +    if (!(rule->enabled & BIT_ULL(hartid))) {
> +        /* Enable the implied MISAs. */
> +        if (rule->implied_misas) {
> +            riscv_cpu_set_misa_ext(env, env->misa_ext |
> rule->implied_misas);
> +
> +            for (i = 0; misa_bits[i] != 0; i++) {
> +                if (rule->implied_misas & misa_bits[i]) {
> +                    ir = g_hash_table_lookup(misa_implied_rules,
> +
>  GUINT_TO_POINTER(misa_bits[i]));
> +
> +                    if (ir) {
> +                        cpu_enable_implied_rule(cpu, ir);
> +                    }
> +                }
> +            }
> +        }
> +
> +        /* Enable the implied extensions. */
> +        for (i = 0; rule->implied_exts[i] != RISCV_IMPLIED_EXTS_RULE_END;
> i++) {
> +            cpu_cfg_ext_auto_update(cpu, rule->implied_exts[i], true);
> +
> +            ir = g_hash_table_lookup(ext_implied_rules,
> +
>  GUINT_TO_POINTER(rule->implied_exts[i]));
> +
> +            if (ir) {
> +                cpu_enable_implied_rule(cpu, ir);
> +            }
> +        }
> +
> +        rule->enabled |= BIT_ULL(hartid);
>

Should I use the qatomic API here to set the enabled bitmask?

This wouldn't impact the results but it may cause the implied rules
to be traversed and re-enabled (which has no harm) if the enabled bit
of a hart is accidentally cleared by another harts.


> +    }
> +}
> +
> +static void riscv_cpu_enable_implied_rules(RISCVCPU *cpu)
> +{
> +    RISCVCPUImpliedExtsRule *rule;
> +    int i;
> +
> +    /* Enable the implied MISAs. */
> +    for (i = 0; (rule = riscv_misa_implied_rules[i]); i++) {
> +        if (riscv_has_ext(&cpu->env, rule->ext)) {
> +            cpu_enable_implied_rule(cpu, rule);
> +        }
> +    }
> +
> +    /* Enable the implied extensions. */
> +    for (i = 0; (rule = riscv_ext_implied_rules[i]); i++) {
> +        if (isa_ext_is_enabled(cpu, rule->ext)) {
> +            cpu_enable_implied_rule(cpu, rule);
> +        }
> +    }
> +}
> +
>  void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
>  {
>      CPURISCVState *env = &cpu->env;
>      Error *local_err = NULL;
>
> +    riscv_cpu_init_implied_exts_rules();
> +    riscv_cpu_enable_implied_rules(cpu);
> +
>      riscv_cpu_validate_misa_priv(env, &local_err);
>      if (local_err != NULL) {
>          error_propagate(errp, local_err);
> @@ -1343,6 +1430,8 @@ static void riscv_tcg_cpu_instance_init(CPUState *cs)
>
>      misa_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
>      multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
> +    misa_implied_rules = g_hash_table_new(NULL, g_direct_equal);
> +    ext_implied_rules = g_hash_table_new(NULL, g_direct_equal);
>      riscv_cpu_add_user_properties(obj);
>
>      if (riscv_cpu_has_max_extensions(obj)) {
> --
> 2.43.2
>
>

Reply via email to