diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index 5025e172cf..82a3408eb4 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -1104,7 +1104,11 @@ static void gen_log_vreg_write_pair(DisasContext *ctx, intptr_t srcoff, int num, static intptr_t get_result_qreg(DisasContext *ctx, int qnum) { - return offsetof(CPUHexagonState, future_QRegs[qnum]); + if (ctx->need_commit) { + return offsetof(CPUHexagonState, future_QRegs[qnum]); + } else { + return offsetof(CPUHexagonState, QRegs[qnum]); + } } static void gen_vreg_load(DisasContext *ctx, intptr_t dstoff, TCGv src, diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index bcf64f725a..8e7a4377c8 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -70,6 +70,10 @@ intptr_t ctx_future_vreg_off(DisasContext *ctx, int regnum, { intptr_t offset; + if (!ctx->need_commit) { + return offsetof(CPUHexagonState, VRegs[regnum]); + } + /* See if it is already allocated */ for (int i = 0; i < ctx->future_vregs_idx; i++) { if (ctx->future_vregs_num[i] == regnum) { @@ -374,7 +378,7 @@ static bool need_commit(DisasContext *ctx) return true; } - if (pkt->num_insns == 1) { + if (pkt->num_insns == 1 && !pkt->pkt_has_hvx) { return false; } @@ -394,6 +398,40 @@ static bool need_commit(DisasContext *ctx) } } + /* Check for overlap between HVX reads and writes */ + for (int i = 0; i < ctx->vreg_log_idx; i++) { + int vnum = ctx->vreg_log[i]; + if (test_bit(vnum, ctx->vregs_read)) { + return true; + } + } + if (!bitmap_empty(ctx->vregs_updated_tmp, NUM_VREGS)) { + int i = find_first_bit(ctx->vregs_updated_tmp, NUM_VREGS); + while (i < NUM_VREGS) { + if (test_bit(i, ctx->vregs_read)) { + return true; + } + i = find_next_bit(ctx->vregs_updated_tmp, NUM_VREGS, i + 1); + } + } + if (!bitmap_empty(ctx->vregs_select, NUM_VREGS)) { + int i = find_first_bit(ctx->vregs_select, NUM_VREGS); + while (i < NUM_VREGS) { + if (test_bit(i, ctx->vregs_read)) { + return true; + } + i = find_next_bit(ctx->vregs_select, NUM_VREGS, i + 1); + } + } + + /* Check for overlap between HVX predicate reads and writes */ + for (int i = 0; i < ctx->qreg_log_idx; i++) { + int qnum = ctx->qreg_log[i]; + if (test_bit(qnum, ctx->qregs_read)) { + return true; + } + } + return false; } @@ -790,6 +828,12 @@ static void gen_commit_hvx(DisasContext *ctx) { int i; + /* Early exit if not needed */ + if (!ctx->need_commit) { + g_assert(!pkt_has_hvx_store(ctx->pkt)); + return; + } + /* * for (i = 0; i < ctx->vreg_log_idx; i++) { * int rnum = ctx->vreg_log[i];