On Tue, Mar 10, 2026 at 10:08 PM Brian Cain <[email protected]>
wrote:

> From: Brian Cain <[email protected]>
>
> Signed-off-by: Brian Cain <[email protected]>
> ---
>  target/hexagon/translate.c | 89 ++++++++++++++++++++++++++++++++++++--
>  1 file changed, 85 insertions(+), 4 deletions(-)
>
> diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
> index 953b34b7891..79027e8a327 100644
> --- a/target/hexagon/translate.c
> +++ b/target/hexagon/translate.c
> @@ -552,6 +552,10 @@ static void gen_start_packet(DisasContext *ctx)
>      ctx->reg_log_idx = 0;
>      bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
>      bitmap_zero(ctx->predicated_regs, TOTAL_PER_THREAD_REGS);
> +#ifndef CONFIG_USER_ONLY
> +    ctx->greg_log_idx = 0;
> +    ctx->sreg_log_idx = 0;
> +#endif
>      ctx->preg_log_idx = 0;
>      bitmap_zero(ctx->pregs_written, NUM_PREGS);
>      ctx->future_vregs_idx = 0;
> @@ -584,6 +588,25 @@ static void gen_start_packet(DisasContext *ctx)
>       * gen phase, so clear it again.
>       */
>      bitmap_zero(ctx->pregs_written, NUM_PREGS);
> +#ifndef CONFIG_USER_ONLY
> +    for (i = 0; i < NUM_SREGS; i++) {
>

Use HEX_SREG_GLB_START instead of NUM_SREGS.
Also, size the t_sreg_new_value array with HEX_SREG_GLB_START.


> +        ctx->t_sreg_new_value[i] = NULL;
> +    }
> +    for (i = 0; i < ctx->sreg_log_idx; i++) {
> +        int reg_num = ctx->sreg_log[i];
> +        if (reg_num < HEX_SREG_GLB_START) {
> +            ctx->t_sreg_new_value[reg_num] = tcg_temp_new();
> +            tcg_gen_mov_tl(ctx->t_sreg_new_value[reg_num],
> hex_t_sreg[reg_num]);
>

You only need this assignment if the writes can be predicated.


> +        }
> +    }
> +    for (i = 0; i < NUM_GREGS; i++) {
> +        ctx->greg_new_value[i] = NULL;
> +    }
> +    for (i = 0; i < ctx->greg_log_idx; i++) {
> +        int reg_num = ctx->greg_log[i];
> +        ctx->greg_new_value[reg_num] = tcg_temp_new();
> +    }
> +#endif
>
>      /* Initialize the runtime state for packet semantics */
>      if (need_slot_cancelled(pkt)) {
> @@ -744,6 +767,60 @@ static void gen_reg_writes(DisasContext *ctx)
>      }
>  }
>
> +#ifndef CONFIG_USER_ONLY
> +static void gen_greg_writes(DisasContext *ctx)
> +{
> +    int i;
> +
> +    for (i = 0; i < ctx->greg_log_idx; i++) {
> +        int reg_num = ctx->greg_log[i];
> +
> +        tcg_gen_mov_tl(hex_greg[reg_num], ctx->greg_new_value[reg_num]);
> +    }
> +}
> +
> +
> +static void gen_sreg_writes(DisasContext *ctx)
> +{
> +    int i;
> +
> +    TCGv_i32 old_reg = tcg_temp_new_i32();
> +    for (i = 0; i < ctx->sreg_log_idx; i++) {
> +        int reg_num = ctx->sreg_log[i];
> +
> +        if (reg_num == HEX_SREG_SSR) {
> +            tcg_gen_mov_tl(old_reg, hex_t_sreg[reg_num]);
> +            tcg_gen_mov_tl(hex_t_sreg[reg_num],
> ctx->t_sreg_new_value[reg_num]);
> +            gen_helper_modify_ssr(tcg_env, ctx->t_sreg_new_value[reg_num],
> +                                  old_reg);
> +            /* This can change processor state, so end the TB */
> +            ctx->base.is_jmp = DISAS_NORETURN;
>

Isn't this taken care of in pkt_ends_tb from earlier patch?


> +            continue;
> +        } else if ((reg_num == HEX_SREG_STID) ||
> +                   (reg_num == HEX_SREG_IMASK) ||
> +                   (reg_num == HEX_SREG_IPENDAD)) {
> +            if (reg_num < HEX_SREG_GLB_START) {
> +                tcg_gen_mov_tl(old_reg, hex_t_sreg[reg_num]);
>

Don't need to set old_reg here


> +                tcg_gen_mov_tl(hex_t_sreg[reg_num],
> +                               ctx->t_sreg_new_value[reg_num]);
> +            }
> +            /* This can change the interrupt state, so end the TB */
> +            gen_helper_pending_interrupt(tcg_env);
> +            ctx->base.is_jmp = DISAS_NORETURN;
>

Already taken care of.


> +        } else if ((reg_num == HEX_SREG_BESTWAIT) ||
> +                   (reg_num == HEX_SREG_SCHEDCFG)) {
> +            /* This can trigger resched interrupt, so end the TB */
> +            gen_helper_resched(tcg_env);
> +            ctx->base.is_jmp = DISAS_NORETURN;
>

Already taken care of.


> +        }
> +
> +        if (reg_num < HEX_SREG_GLB_START) {
> +            tcg_gen_mov_tl(hex_t_sreg[reg_num],
> ctx->t_sreg_new_value[reg_num]);
> +        }
>

Put this under an else as we've already done the assignment for specific
cases above


> +    }
> +}
> +#endif
> +
>  static void gen_pred_writes(DisasContext *ctx)
>  {
>      /* Early exit if not needed or the log is empty */
> @@ -1044,6 +1121,10 @@ static void gen_commit_packet(DisasContext *ctx)
>      process_store_log(ctx);
>
>      gen_reg_writes(ctx);
> +#if !defined(CONFIG_USER_ONLY)
> +    gen_greg_writes(ctx);
> +    gen_sreg_writes(ctx);
> +#endif
>      gen_pred_writes(ctx);
>      if (pkt->pkt_has_hvx) {
>          gen_commit_hvx(ctx);
> @@ -1255,6 +1336,10 @@ void hexagon_translate_init(void)
>          offsetof(CPUHexagonState, llsc_val_i64), "llsc_val_i64");
>      hex_cycle_count = tcg_global_mem_new_i64(tcg_env,
>              offsetof(CPUHexagonState, t_cycle_count), "t_cycle_count");
> +#ifndef CONFIG_USER_ONLY
> +    hex_cause_code = tcg_global_mem_new_i32(tcg_env,
> +        offsetof(CPUHexagonState, cause_code), "cause_code");
> +#endif
>

Seems strange to add this here and remove it below


>      for (i = 0; i < STORES_MAX; i++) {
>          snprintf(store_addr_names[i], NAME_LEN, "store_addr_%d", i);
>          hex_store_addr[i] = tcg_global_mem_new(tcg_env,
> @@ -1292,8 +1377,4 @@ void hexagon_translate_init(void)
>              offsetof(CPUHexagonState, vstore_pending[i]),
>              vstore_pending_names[i]);
>      }
> -#ifndef CONFIG_USER_ONLY
> -    hex_cause_code = tcg_global_mem_new(tcg_env,
> -        offsetof(CPUHexagonState, cause_code), "cause_code");
> -#endif
>  }
> --
> 2.34.1
>
>

Reply via email to