aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorTaylor Simpson <tsimpson@quicinc.com>2022-11-08 08:28:57 -0800
committerTaylor Simpson <tsimpson@quicinc.com>2022-12-16 10:10:28 -0800
commit83853ea0efee80f8c39a73753a048a769a02a2c7 (patch)
treeafe2308fa30b2bad1190a513e5e148fb7a82aa8c /target
parent1e536334ccb0a1606f814a38a4996b3b818e9fab (diff)
downloadqemu-83853ea0efee80f8c39a73753a048a769a02a2c7.zip
qemu-83853ea0efee80f8c39a73753a048a769a02a2c7.tar.gz
qemu-83853ea0efee80f8c39a73753a048a769a02a2c7.tar.bz2
Hexagon (target/hexagon) Fix predicated assignment to .tmp and .cur
Here are example instructions with a predicated .tmp/.cur assignment if (p1) v12.tmp = vmem(r7 + #0) if (p0) v12.cur = vmem(r9 + #0) The .tmp/.cur indicates that references to v12 in the same packet take the result of the load. However, when the predicate is false, the value at the start of the packet should be used. After the packet commits, the .tmp value is dropped, but the .cur value is maintained. To fix this bug, we preload the original value from the HVX register into the temporary used for the result. Test cases added to tests/tcg/hexagon/hvx_misc.c Acked-by: Richard Henderson <richard.henderson@linaro.org> Co-authored-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com> Signed-off-by: Matheus Tavares Bernardino <quic_mathbern@quicinc.com> Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Message-Id: <20221108162906.3166-3-tsimpson@quicinc.com>
Diffstat (limited to 'target')
-rwxr-xr-xtarget/hexagon/gen_tcg_funcs.py12
-rw-r--r--target/hexagon/translate.h6
2 files changed, 18 insertions, 0 deletions
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index 02a6565..ca5fde9 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -173,6 +173,18 @@ def genptr_decl(f, tag, regtype, regid, regno):
f.write(" ctx_future_vreg_off(ctx, %s%sN," % \
(regtype, regid))
f.write(" 1, true);\n");
+ if 'A_CONDEXEC' in hex_common.attribdict[tag]:
+ f.write(" if (!is_vreg_preloaded(ctx, %s)) {\n" % (regN))
+ f.write(" intptr_t src_off =")
+ f.write(" offsetof(CPUHexagonState, VRegs[%s%sN]);\n"% \
+ (regtype, regid))
+ f.write(" tcg_gen_gvec_mov(MO_64, %s%sV_off,\n" % \
+ (regtype, regid))
+ f.write(" src_off,\n")
+ f.write(" sizeof(MMVector),\n")
+ f.write(" sizeof(MMVector));\n")
+ f.write(" }\n")
+
if (not hex_common.skip_qemu_helper(tag)):
f.write(" TCGv_ptr %s%sV = tcg_temp_new_ptr();\n" % \
(regtype, regid))
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 115e29b..b8fcf61 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -86,6 +86,12 @@ static inline bool is_preloaded(DisasContext *ctx, int num)
return test_bit(num, ctx->regs_written);
}
+static inline bool is_vreg_preloaded(DisasContext *ctx, int num)
+{
+ return test_bit(num, ctx->vregs_updated) ||
+ test_bit(num, ctx->vregs_updated_tmp);
+}
+
intptr_t ctx_future_vreg_off(DisasContext *ctx, int regnum,
int num, bool alloc_ok);
intptr_t ctx_tmp_vreg_off(DisasContext *ctx, int regnum,