On 5/29/2026 2:57 PM, Brian Cain wrote:
> From: Brian Cain <[email protected]>
>
> Signed-off-by: Brian Cain <[email protected]>
> ---
> target/hexagon/translate.h | 2 +-
> target/hexagon/translate.c | 77 ++++++++++++++++++++++++++++++++++++--
> 2 files changed, 74 insertions(+), 5 deletions(-)
>
> diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
> index fea88cb2db7..0a7f37d5842 100644
> --- a/target/hexagon/translate.h
> +++ b/target/hexagon/translate.h
> @@ -46,7 +46,7 @@ typedef struct DisasContext {
> int greg_log_idx;
> int sreg_log[SREG_WRITES_MAX];
> int sreg_log_idx;
> - TCGv_i32 t_sreg_new_value[NUM_SREGS];
> + TCGv_i32 t_sreg_new_value[HEX_SREG_GLB_START];
> TCGv_i32 greg_new_value[NUM_GREGS];
> #endif
> int preg_log[PRED_WRITES_MAX];
> diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
> index 35e90362880..325c1a9e8fb 100644
> --- a/target/hexagon/translate.c
> +++ b/target/hexagon/translate.c
> @@ -545,6 +545,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;
> @@ -577,6 +581,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 < HEX_SREG_GLB_START; i++) {
> + 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->need_commit || reg_num == HEX_SREG_SSR)) {
> + ctx->t_sreg_new_value[reg_num] = tcg_temp_new();
> + }
> + }
> + 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(&ctx->pkt)) {
> @@ -734,6 +757,50 @@ 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);
> + } else if ((reg_num == HEX_SREG_STID) ||
> + (reg_num == HEX_SREG_IMASK) ||
> + (reg_num == HEX_SREG_IPENDAD)) {
> + if (ctx->need_commit && reg_num < HEX_SREG_GLB_START) {
> + tcg_gen_mov_tl(hex_t_sreg[reg_num],
> + ctx->t_sreg_new_value[reg_num]);
> + }
> + gen_helper_pending_interrupt(tcg_env);
> + } else if ((reg_num == HEX_SREG_BESTWAIT) ||
> + (reg_num == HEX_SREG_SCHEDCFG)) {
> + gen_helper_resched(tcg_env);
> + } else if (ctx->need_commit && reg_num < HEX_SREG_GLB_START) {
> + tcg_gen_mov_tl(hex_t_sreg[reg_num],
> ctx->t_sreg_new_value[reg_num]);
> + }
> + }
> +}
> +#endif
> +
> static void gen_pred_writes(DisasContext *ctx)
> {
> /* Early exit if not needed or the log is empty */
> @@ -1030,6 +1097,10 @@ static void gen_commit_packet(DisasContext *ctx)
> process_store_log(ctx);
>
> gen_reg_writes(ctx);
> +#if !defined(CONFIG_USER_ONLY)
ifndef
> + gen_greg_writes(ctx);
> + gen_sreg_writes(ctx);
> +#endif
> gen_pred_writes(ctx);
> if (ctx->pkt.pkt_has_hvx) {
> gen_commit_hvx(ctx);
> @@ -1242,6 +1313,8 @@ void hexagon_translate_init(void)
> hex_llsc_val_i64 = tcg_global_mem_new_i64(tcg_env,
> offsetof(CPUHexagonState, llsc_val_i64), "llsc_val_i64");
> #ifndef CONFIG_USER_ONLY
> + hex_cause_code = tcg_global_mem_new_i32(tcg_env,
> + offsetof(CPUHexagonState, cause_code), "cause_code");
> hex_cycle_count = tcg_global_mem_new_i64(tcg_env,
> offsetof(CPUHexagonState, t_cycle_count), "t_cycle_count");
> #endif
> @@ -1282,8 +1355,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
> }
In general, we should use sized tcg op instead of rely on *_tl, but it
can be cleaned up later.
Reviewed-by: Pierrick Bouvier <[email protected]>