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. Signed-off-by: Taylor Simpson <[email protected]> --- target/hexagon/translate.h | 1 + target/hexagon/translate.c | 35 ++++++++++++++++++++++------------- 2 files changed, 23 insertions(+), 13 deletions(-) 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); 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) -- 2.43.0
