For now, assert the new method is a superset 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 | 23 ++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index d8628383f1..964e6ce0b7 100644 --- a/target/hexagon/translate.h +++ b/target/hexagon/translate.h @@ -41,6 +41,8 @@ typedef struct DisasContext { DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS); DECLARE_BITMAP(predicated_regs, TOTAL_PER_THREAD_REGS); bool pkt_ends_tb; + DECLARE_BITMAP(gpr_multi_write, TOTAL_PER_THREAD_REGS); + DECLARE_BITMAP(gpr_uncond, TOTAL_PER_THREAD_REGS); bool implicit_usr_write; #ifndef CONFIG_USER_ONLY int greg_log[GREG_WRITES_MAX]; @@ -157,9 +159,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 52dd1f0266..60441dc309 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -577,6 +577,8 @@ static void clear_pkt_ctx(DisasContext *ctx) ctx->greg_log_idx = 0; ctx->sreg_log_idx = 0; #endif + 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; @@ -603,6 +605,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) { ctx->read_after_write = false; @@ -1206,7 +1221,13 @@ static void decode_and_translate_packet(CPUHexagonState *env, DisasContext *ctx) clear_pkt_ctx(ctx); analyze_packet(ctx); - if (ctx->pkt.pkt_has_write_conflict) { + /* + * Check that the new method is a superset of the old methond + * Remove in a later patch + */ + g_assert(!ctx->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
