From: Taylor Simpson Date: Wed, 5 Nov 2025 21:25:53 +0000 (-0700) Subject: Hexagon (target/hexagon) Implicit writes to USR don't force packet commit X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e98496691edc73a2d79e43c6ac348bb8e72298f;p=thirdparty%2Fqemu.git Hexagon (target/hexagon) Implicit writes to USR don't force packet commit Implicit writes to USR are only to specific fields of USR to indicate side effects (e.g., saturation overflow, floating point status). In these cases, we don't force a packet commit. This will allow more packets to be short-circuited (avoid writing the results to temporaries). When there is a packet commit with an implicit write to USR, we initialize new_value_usr during gen_start_packet and write to USR in gen_reg_writes. Reviewed-by: Brian Cain Signed-off-by: Taylor Simpson Signed-off-by: Brian Cain --- diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index 8fce219c0d..f3240953b5 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -272,12 +272,7 @@ static void mark_implicit_reg_write(DisasContext *ctx, int attrib, int rnum) { uint16_t opcode = ctx->insn->opcode; if (GET_ATTRIB(opcode, attrib)) { - /* - * USR is used to set overflow and FP exceptions, - * so treat it as conditional - */ - bool is_predicated = GET_ATTRIB(opcode, A_CONDEXEC) || - rnum == HEX_REG_USR; + bool is_predicated = GET_ATTRIB(opcode, A_CONDEXEC); /* LC0/LC1 is conditionally written by endloop instructions */ if ((rnum == HEX_REG_LC0 || rnum == HEX_REG_LC1) && @@ -291,6 +286,14 @@ static void mark_implicit_reg_write(DisasContext *ctx, int attrib, int rnum) } } +static void mark_implicit_usr_write(DisasContext *ctx, int attrib) +{ + uint16_t opcode = ctx->insn->opcode; + if (GET_ATTRIB(opcode, attrib)) { + ctx->implicit_usr_write = true; + } +} + static void mark_implicit_reg_writes(DisasContext *ctx) { mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_FP, HEX_REG_FP); @@ -300,8 +303,9 @@ static void mark_implicit_reg_writes(DisasContext *ctx) mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_SA0, HEX_REG_SA0); mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_LC1, HEX_REG_LC1); mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_SA1, HEX_REG_SA1); - mark_implicit_reg_write(ctx, A_IMPLICIT_WRITES_USR, HEX_REG_USR); - mark_implicit_reg_write(ctx, A_FPOP, HEX_REG_USR); + + mark_implicit_usr_write(ctx, A_IMPLICIT_WRITES_USR); + mark_implicit_usr_write(ctx, A_FPOP); } static void mark_implicit_pred_write(DisasContext *ctx, int attrib, int pnum) @@ -351,11 +355,6 @@ static bool need_commit(DisasContext *ctx) } } - /* Floating point instructions are hard-coded to use new_value */ - if (check_for_attrib(pkt, A_FPOP)) { - return true; - } - if (ctx->read_after_write || ctx->has_hvx_overlap) { return true; } @@ -467,6 +466,12 @@ static void gen_start_packet(DisasContext *ctx) } } + /* Preload usr to new_value_usr */ + if (ctx->need_commit && ctx->implicit_usr_write && + !test_bit(HEX_REG_USR, ctx->regs_written)) { + tcg_gen_mov_tl(hex_new_value_usr, hex_gpr[HEX_REG_USR]); + } + /* * Preload the predicated pred registers into ctx->new_pred_value[pred_num] * Only endloop instructions conditionally write to pred registers @@ -587,6 +592,10 @@ static void gen_reg_writes(DisasContext *ctx) ctx->is_tight_loop = false; } } + + if (ctx->implicit_usr_write && !test_bit(HEX_REG_USR, ctx->regs_written)) { + tcg_gen_mov_tl(hex_gpr[HEX_REG_USR], hex_new_value_usr); + } } static void gen_pred_writes(DisasContext *ctx) diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index d251e2233f..a0102b6cbd 100644 --- a/target/hexagon/translate.h +++ b/target/hexagon/translate.h @@ -39,6 +39,7 @@ typedef struct DisasContext { int reg_log_idx; DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS); DECLARE_BITMAP(predicated_regs, TOTAL_PER_THREAD_REGS); + bool implicit_usr_write; int preg_log[PRED_WRITES_MAX]; int preg_log_idx; DECLARE_BITMAP(pregs_written, NUM_PREGS);