Skip to content

Commit

Permalink
Hexagon (target/hexagon) decide if pred has been written at TCG gen time
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
taylorsimpson authored and rth7680 committed May 1, 2021
1 parent 743debb commit 6c677c6
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 10 deletions.
2 changes: 1 addition & 1 deletion target/hexagon/gen_tcg_funcs.py
Expand Up @@ -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))
Expand Down
22 changes: 15 additions & 7 deletions target/hexagon/genptr.c
Expand Up @@ -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);
Expand Down
9 changes: 7 additions & 2 deletions target/hexagon/translate.c
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
}
Expand Down
2 changes: 2 additions & 0 deletions target/hexagon/translate.h
Expand Up @@ -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;
Expand All @@ -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)
Expand Down
19 changes: 19 additions & 0 deletions tests/tcg/hexagon/misc.c
Expand Up @@ -264,6 +264,22 @@ static long long creg_pair(int x, int y)
return retval;
}

/* Check that predicates are auto-and'ed in a packet */
static int auto_and(void)
{
int retval;
asm ("r5 = #1\n\t"
"{\n\t"
" p0 = cmp.eq(r1, #1)\n\t"
" p0 = cmp.eq(r1, #2)\n\t"
"}\n\t"
"%0 = p0\n\t"
: "=r"(retval)
:
: "r5", "p0");
return retval;
}

int main()
{

Expand Down Expand Up @@ -375,6 +391,9 @@ int main()
res = test_clrtnew(2, 7);
check(res, 7);

res = auto_and();
check(res, 0);

puts(err ? "FAIL" : "PASS");
return err;
}

0 comments on commit 6c677c6

Please sign in to comment.