aboutsummaryrefslogtreecommitdiff
path: root/target/hexagon
diff options
context:
space:
mode:
authorTaylor Simpson <tsimpson@quicinc.com>2021-04-08 20:07:34 -0500
committerRichard Henderson <richard.henderson@linaro.org>2021-05-01 08:31:43 -0700
commit6c677c60ae34bd2c7936781ee8969e41b1dac81e (patch)
tree21a5aceea887ffa203dfe343acc30ba15103f04d /target/hexagon
parent743debbc373ffcd8eb66dc388632c03f5e951bfc (diff)
Hexagon (target/hexagon) decide if pred has been written at TCG gen time
Multiple writes to the same preg are and'ed together. Rather than generating a runtime check, we can determine at TCG generation time if the predicate has previously been written in the packet. Test added to tests/tcg/hexagon/misc.c Suggested-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <1617930474-31979-7-git-send-email-tsimpson@quicinc.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/hexagon')
-rwxr-xr-xtarget/hexagon/gen_tcg_funcs.py2
-rw-r--r--target/hexagon/genptr.c22
-rw-r--r--target/hexagon/translate.c9
-rw-r--r--target/hexagon/translate.h2
4 files changed, 25 insertions, 10 deletions
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index db9f663a77..7ceb25b5f6 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -316,7 +316,7 @@ def genptr_dst_write(f, tag, regtype, regid):
print("Bad register parse: ", regtype, regid)
elif (regtype == "P"):
if (regid in {"d", "e", "x"}):
- f.write(" gen_log_pred_write(%s%sN, %s%sV);\n" % \
+ f.write(" gen_log_pred_write(ctx, %s%sN, %s%sV);\n" % \
(regtype, regid, regtype, regid))
f.write(" ctx_log_pred_write(ctx, %s%sN);\n" % \
(regtype, regid))
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 07d970fc6c..6b74344795 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -119,20 +119,28 @@ static void gen_log_reg_write_pair(int rnum, TCGv_i64 val)
#endif
}
-static inline void gen_log_pred_write(int pnum, TCGv val)
+static inline void gen_log_pred_write(DisasContext *ctx, int pnum, TCGv val)
{
TCGv zero = tcg_const_tl(0);
TCGv base_val = tcg_temp_new();
TCGv and_val = tcg_temp_new();
TCGv pred_written = tcg_temp_new();
- /* Multiple writes to the same preg are and'ed together */
tcg_gen_andi_tl(base_val, val, 0xff);
- tcg_gen_and_tl(and_val, base_val, hex_new_pred_value[pnum]);
- tcg_gen_andi_tl(pred_written, hex_pred_written, 1 << pnum);
- tcg_gen_movcond_tl(TCG_COND_NE, hex_new_pred_value[pnum],
- pred_written, zero,
- and_val, base_val);
+
+ /*
+ * Section 6.1.3 of the Hexagon V67 Programmer's Reference Manual
+ *
+ * Multiple writes to the same preg are and'ed together
+ * If this is the first predicate write in the packet, do a
+ * straight assignment. Otherwise, do an and.
+ */
+ if (!test_bit(pnum, ctx->pregs_written)) {
+ tcg_gen_mov_tl(hex_new_pred_value[pnum], base_val);
+ } else {
+ tcg_gen_and_tl(hex_new_pred_value[pnum],
+ hex_new_pred_value[pnum], base_val);
+ }
tcg_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << pnum);
tcg_temp_free(zero);
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 9f2a531969..49ec8b76ed 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -172,6 +172,7 @@ static void gen_start_packet(DisasContext *ctx, Packet *pkt)
ctx->reg_log_idx = 0;
bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
ctx->preg_log_idx = 0;
+ bitmap_zero(ctx->pregs_written, NUM_PREGS);
for (i = 0; i < STORES_MAX; i++) {
ctx->store_width[i] = 0;
}
@@ -226,7 +227,7 @@ static void mark_implicit_pred_write(DisasContext *ctx, Insn *insn,
}
}
-static void mark_implicit_writes(DisasContext *ctx, Insn *insn)
+static void mark_implicit_reg_writes(DisasContext *ctx, Insn *insn)
{
mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_FP, HEX_REG_FP);
mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SP, HEX_REG_SP);
@@ -235,7 +236,10 @@ static void mark_implicit_writes(DisasContext *ctx, Insn *insn)
mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SA0, HEX_REG_SA0);
mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_LC1, HEX_REG_LC1);
mark_implicit_reg_write(ctx, insn, A_IMPLICIT_WRITES_SA1, HEX_REG_SA1);
+}
+static void mark_implicit_pred_writes(DisasContext *ctx, Insn *insn)
+{
mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P0, 0);
mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P1, 1);
mark_implicit_pred_write(ctx, insn, A_IMPLICIT_WRITES_P2, 2);
@@ -246,8 +250,9 @@ static void gen_insn(CPUHexagonState *env, DisasContext *ctx,
Insn *insn, Packet *pkt)
{
if (insn->generate) {
- mark_implicit_writes(ctx, insn);
+ mark_implicit_reg_writes(ctx, insn);
insn->generate(env, ctx, insn, pkt);
+ mark_implicit_pred_writes(ctx, insn);
} else {
gen_exception_end_tb(ctx, HEX_EXCP_INVALID_OPCODE);
}
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 12506c8caf..0ecfbd7d52 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -34,6 +34,7 @@ typedef struct DisasContext {
DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS);
int preg_log[PRED_WRITES_MAX];
int preg_log_idx;
+ DECLARE_BITMAP(pregs_written, NUM_PREGS);
uint8_t store_width[STORES_MAX];
uint8_t s1_store_processed;
} DisasContext;
@@ -60,6 +61,7 @@ static inline void ctx_log_pred_write(DisasContext *ctx, int pnum)
{
ctx->preg_log[ctx->preg_log_idx] = pnum;
ctx->preg_log_idx++;
+ set_bit(pnum, ctx->pregs_written);
}
static inline bool is_preloaded(DisasContext *ctx, int num)