For now, assert the new method is a subset of the old method We'll remove the old method in a subsequent patch
Signed-off-by: Taylor Simpson <[email protected]> --- target/hexagon/translate.h | 6 ++++++ target/hexagon/translate.c | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index b37cb49238..54276fb9d0 100644 --- a/target/hexagon/translate.h +++ b/target/hexagon/translate.h @@ -39,6 +39,8 @@ typedef struct DisasContext { int reg_log_idx; DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS); DECLARE_BITMAP(predicated_regs, TOTAL_PER_THREAD_REGS); + DECLARE_BITMAP(gpr_multi_write, TOTAL_PER_THREAD_REGS); + DECLARE_BITMAP(gpr_uncond, TOTAL_PER_THREAD_REGS); bool implicit_usr_write; int preg_log[PRED_WRITES_MAX]; int preg_log_idx; @@ -113,9 +115,13 @@ static inline void ctx_log_reg_write(DisasContext *ctx, int rnum, ctx->reg_log[ctx->reg_log_idx] = rnum; ctx->reg_log_idx++; set_bit(rnum, ctx->regs_written); + } else { + set_bit(rnum, ctx->gpr_multi_write); } if (is_predicated) { set_bit(rnum, ctx->predicated_regs); + } else { + set_bit(rnum, ctx->gpr_uncond); } } } diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index 6e32805202..c5d161745e 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -417,6 +417,8 @@ static void clear_pkt_ctx(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); + bitmap_zero(ctx->gpr_multi_write, TOTAL_PER_THREAD_REGS); + bitmap_zero(ctx->gpr_uncond, TOTAL_PER_THREAD_REGS); ctx->preg_log_idx = 0; bitmap_zero(ctx->pregs_written, NUM_PREGS); ctx->future_vregs_idx = 0; @@ -443,6 +445,19 @@ static void clear_pkt_ctx(DisasContext *ctx) } } +static bool pkt_has_write_conflict(DisasContext *ctx) +{ + DECLARE_BITMAP(gpr_conflict, TOTAL_PER_THREAD_REGS); + + bitmap_and(gpr_conflict, ctx->gpr_multi_write, ctx->gpr_uncond, + TOTAL_PER_THREAD_REGS); + if (!bitmap_empty(gpr_conflict, TOTAL_PER_THREAD_REGS)) { + return true; + } + + return false; +} + static void analyze_packet(DisasContext *ctx) { Packet *pkt = ctx->pkt; @@ -965,7 +980,12 @@ static void decode_and_translate_packet(CPUHexagonState *env, DisasContext *ctx) clear_pkt_ctx(ctx); analyze_packet(ctx); - if (pkt.pkt_has_write_conflict) { + /* + * Check that the new method is a superset of the old methond + * Remove in a later patch + */ + g_assert(!pkt.pkt_has_write_conflict || pkt_has_write_conflict(ctx)); + if (pkt_has_write_conflict(ctx)) { gen_exception_decode_fail(ctx, words_read, HEX_CAUSE_REG_WRITE_CONFLICT); return; -- 2.43.0
