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 <ltaylorsimpson@gmail.com>
---
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