Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Hexagon (target/hexagon) Mark registers as read during packet analysis
Have gen_analyze_funcs mark the registers that are read by the
instruction.  We also mark the implicit reads using instruction
attributes.

Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230427230012.3800327-11-tsimpson@quicinc.com>
  • Loading branch information
taylorsimpson committed May 18, 2023
1 parent 71ed369 commit b9f0326
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 15 deletions.
6 changes: 5 additions & 1 deletion target/hexagon/attribs_def.h.inc
@@ -1,5 +1,5 @@
/*
* Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -112,6 +112,10 @@ DEF_ATTRIB(IMPLICIT_WRITES_P1, "Writes Predicate 1", "", "UREG.P1")
DEF_ATTRIB(IMPLICIT_WRITES_P2, "Writes Predicate 1", "", "UREG.P2")
DEF_ATTRIB(IMPLICIT_WRITES_P3, "May write Predicate 3", "", "UREG.P3")
DEF_ATTRIB(IMPLICIT_READS_PC, "Reads the PC register", "", "")
DEF_ATTRIB(IMPLICIT_READS_P0, "Reads the P0 register", "", "")
DEF_ATTRIB(IMPLICIT_READS_P1, "Reads the P1 register", "", "")
DEF_ATTRIB(IMPLICIT_READS_P2, "Reads the P2 register", "", "")
DEF_ATTRIB(IMPLICIT_READS_P3, "Reads the P3 register", "", "")
DEF_ATTRIB(IMPLICIT_WRITES_USR, "May write USR", "", "")
DEF_ATTRIB(WRITES_PRED_REG, "Writes a predicate register", "", "")
DEF_ATTRIB(COMMUTES, "The operation is communitive", "", "")
Expand Down
44 changes: 30 additions & 14 deletions target/hexagon/gen_analyze_funcs.py
Expand Up @@ -35,20 +35,23 @@ def analyze_opn_old(f, tag, regtype, regid, regno):
predicated = "true" if is_predicated(tag) else "false"
if regtype == "R":
if regid in {"ss", "tt"}:
f.write(f"// const int {regN} = insn->regno[{regno}];\n")
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_reg_read_pair(ctx, {regN});\n")
elif regid in {"dd", "ee", "xx", "yy"}:
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_reg_write_pair(ctx, {regN}, {predicated});\n")
elif regid in {"s", "t", "u", "v"}:
f.write(f"// const int {regN} = insn->regno[{regno}];\n")
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_reg_read(ctx, {regN});\n")
elif regid in {"d", "e", "x", "y"}:
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_reg_write(ctx, {regN}, {predicated});\n")
else:
print("Bad register parse: ", regtype, regid)
elif regtype == "P":
if regid in {"s", "t", "u", "v"}:
f.write(f"// const int {regN} = insn->regno[{regno}];\n")
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_pred_read(ctx, {regN});\n")
elif regid in {"d", "e", "x"}:
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_pred_write(ctx, {regN});\n")
Expand All @@ -57,23 +60,28 @@ def analyze_opn_old(f, tag, regtype, regid, regno):
elif regtype == "C":
if regid == "ss":
f.write(
f"// const int {regN} = insn->regno[{regno}] " "+ HEX_REG_SA0;\n"
f" const int {regN} = insn->regno[{regno}] "
"+ HEX_REG_SA0;\n"
)
f.write(f" ctx_log_reg_read_pair(ctx, {regN});\n")
elif regid == "dd":
f.write(f" const int {regN} = insn->regno[{regno}] " "+ HEX_REG_SA0;\n")
f.write(f" ctx_log_reg_write_pair(ctx, {regN}, {predicated});\n")
elif regid == "s":
f.write(
f"// const int {regN} = insn->regno[{regno}] " "+ HEX_REG_SA0;\n"
f" const int {regN} = insn->regno[{regno}] "
"+ HEX_REG_SA0;\n"
)
f.write(f" ctx_log_reg_read(ctx, {regN});\n")
elif regid == "d":
f.write(f" const int {regN} = insn->regno[{regno}] " "+ HEX_REG_SA0;\n")
f.write(f" ctx_log_reg_write(ctx, {regN}, {predicated});\n")
else:
print("Bad register parse: ", regtype, regid)
elif regtype == "M":
if regid == "u":
f.write(f"// const int {regN} = insn->regno[{regno}];\n")
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_reg_read(ctx, {regN});\n")
else:
print("Bad register parse: ", regtype, regid)
elif regtype == "V":
Expand All @@ -88,9 +96,11 @@ def analyze_opn_old(f, tag, regtype, regid, regno):
f" ctx_log_vreg_write_pair(ctx, {regN}, {newv}, " f"{predicated});\n"
)
elif regid in {"uu", "vv"}:
f.write(f"// const int {regN} = insn->regno[{regno}];\n")
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_vreg_read_pair(ctx, {regN});\n")
elif regid in {"s", "u", "v", "w"}:
f.write(f"// const int {regN} = insn->regno[{regno}];\n")
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_vreg_read(ctx, {regN});\n")
elif regid in {"d", "x", "y"}:
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_vreg_write(ctx, {regN}, {newv}, " f"{predicated});\n")
Expand All @@ -101,7 +111,8 @@ def analyze_opn_old(f, tag, regtype, regid, regno):
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_qreg_write(ctx, {regN});\n")
elif regid in {"s", "t", "u", "v"}:
f.write(f"// const int {regN} = insn->regno[{regno}];\n")
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_qreg_read(ctx, {regN});\n")
else:
print("Bad register parse: ", regtype, regid)
elif regtype == "G":
Expand Down Expand Up @@ -134,17 +145,20 @@ def analyze_opn_new(f, tag, regtype, regid, regno):
regN = f"{regtype}{regid}N"
if regtype == "N":
if regid in {"s", "t"}:
f.write(f"// const int {regN} = insn->regno[{regno}];\n")
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_reg_read(ctx, {regN});\n")
else:
print("Bad register parse: ", regtype, regid)
elif regtype == "P":
if regid in {"t", "u", "v"}:
f.write(f"// const int {regN} = insn->regno[{regno}];\n")
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_pred_read(ctx, {regN});\n")
else:
print("Bad register parse: ", regtype, regid)
elif regtype == "O":
if regid == "s":
f.write(f"// const int {regN} = insn->regno[{regno}];\n")
f.write(f" const int {regN} = insn->regno[{regno}];\n")
f.write(f" ctx_log_vreg_read(ctx, {regN});\n")
else:
print("Bad register parse: ", regtype, regid)
else:
Expand Down Expand Up @@ -174,8 +188,10 @@ def analyze_opn(f, tag, regtype, regid, toss, numregs, i):
## Insn *insn G_GNUC_UNUSED = ctx->insn;
## const int RdN = insn->regno[0];
## ctx_log_reg_write(ctx, RdN, false);
## // const int RsN = insn->regno[1];
## // const int RtN = insn->regno[2];
## const int RsN = insn->regno[1];
## ctx_log_reg_read(ctx, RsN);
## const int RtN = insn->regno[2];
## ctx_log_reg_read(ctx, RtN);
## }
##
def gen_analyze_func(f, tag, regs, imms):
Expand Down
6 changes: 6 additions & 0 deletions target/hexagon/hex_common.py
Expand Up @@ -97,6 +97,12 @@ def calculate_attribs():
add_qemu_macro_attrib("fSET_LPCFG", "A_IMPLICIT_WRITES_USR")
add_qemu_macro_attrib("fLOAD", "A_SCALAR_LOAD")
add_qemu_macro_attrib("fSTORE", "A_SCALAR_STORE")
add_qemu_macro_attrib('fLSBNEW0', 'A_IMPLICIT_READS_P0')
add_qemu_macro_attrib('fLSBNEW0NOT', 'A_IMPLICIT_READS_P0')
add_qemu_macro_attrib('fREAD_P0', 'A_IMPLICIT_READS_P0')
add_qemu_macro_attrib('fLSBNEW1', 'A_IMPLICIT_READS_P1')
add_qemu_macro_attrib('fLSBNEW1NOT', 'A_IMPLICIT_READS_P1')
add_qemu_macro_attrib('fREAD_P3', 'A_IMPLICIT_READS_P3')

# Recurse down macros, find attributes from sub-macros
macroValues = list(macros.values())
Expand Down
20 changes: 20 additions & 0 deletions target/hexagon/translate.c
Expand Up @@ -336,6 +336,21 @@ static void mark_implicit_pred_writes(DisasContext *ctx)
mark_implicit_pred_write(ctx, A_IMPLICIT_WRITES_P3, 3);
}

static void mark_implicit_pred_read(DisasContext *ctx, int attrib, int pnum)
{
if (GET_ATTRIB(ctx->insn->opcode, attrib)) {
ctx_log_pred_read(ctx, pnum);
}
}

static void mark_implicit_pred_reads(DisasContext *ctx)
{
mark_implicit_pred_read(ctx, A_IMPLICIT_READS_P0, 0);
mark_implicit_pred_read(ctx, A_IMPLICIT_READS_P1, 1);
mark_implicit_pred_read(ctx, A_IMPLICIT_READS_P3, 2);
mark_implicit_pred_read(ctx, A_IMPLICIT_READS_P3, 3);
}

static void analyze_packet(DisasContext *ctx)
{
Packet *pkt = ctx->pkt;
Expand All @@ -348,6 +363,7 @@ static void analyze_packet(DisasContext *ctx)
}
mark_implicit_reg_writes(ctx);
mark_implicit_pred_writes(ctx);
mark_implicit_pred_reads(ctx);
}
}

Expand All @@ -361,9 +377,11 @@ static void gen_start_packet(DisasContext *ctx)
ctx->next_PC = next_PC;
ctx->reg_log_idx = 0;
bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
bitmap_zero(ctx->regs_read, TOTAL_PER_THREAD_REGS);
bitmap_zero(ctx->predicated_regs, TOTAL_PER_THREAD_REGS);
ctx->preg_log_idx = 0;
bitmap_zero(ctx->pregs_written, NUM_PREGS);
bitmap_zero(ctx->pregs_read, NUM_PREGS);
ctx->future_vregs_idx = 0;
ctx->tmp_vregs_idx = 0;
ctx->vreg_log_idx = 0;
Expand All @@ -372,6 +390,8 @@ static void gen_start_packet(DisasContext *ctx)
bitmap_zero(ctx->vregs_select, NUM_VREGS);
bitmap_zero(ctx->predicated_future_vregs, NUM_VREGS);
bitmap_zero(ctx->predicated_tmp_vregs, NUM_VREGS);
bitmap_zero(ctx->vregs_read, NUM_VREGS);
bitmap_zero(ctx->qregs_read, NUM_QREGS);
ctx->qreg_log_idx = 0;
for (i = 0; i < STORES_MAX; i++) {
ctx->store_width[i] = 0;
Expand Down
36 changes: 36 additions & 0 deletions target/hexagon/translate.h
Expand Up @@ -38,10 +38,12 @@ typedef struct DisasContext {
int reg_log[REG_WRITES_MAX];
int reg_log_idx;
DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS);
DECLARE_BITMAP(regs_read, TOTAL_PER_THREAD_REGS);
DECLARE_BITMAP(predicated_regs, TOTAL_PER_THREAD_REGS);
int preg_log[PRED_WRITES_MAX];
int preg_log_idx;
DECLARE_BITMAP(pregs_written, NUM_PREGS);
DECLARE_BITMAP(pregs_read, NUM_PREGS);
uint8_t store_width[STORES_MAX];
bool s1_store_processed;
int future_vregs_idx;
Expand All @@ -55,8 +57,10 @@ typedef struct DisasContext {
DECLARE_BITMAP(vregs_select, NUM_VREGS);
DECLARE_BITMAP(predicated_future_vregs, NUM_VREGS);
DECLARE_BITMAP(predicated_tmp_vregs, NUM_VREGS);
DECLARE_BITMAP(vregs_read, NUM_VREGS);
int qreg_log[NUM_QREGS];
int qreg_log_idx;
DECLARE_BITMAP(qregs_read, NUM_QREGS);
bool pre_commit;
TCGCond branch_cond;
target_ulong branch_dest;
Expand All @@ -73,6 +77,11 @@ static inline void ctx_log_pred_write(DisasContext *ctx, int pnum)
}
}

static inline void ctx_log_pred_read(DisasContext *ctx, int pnum)
{
set_bit(pnum, ctx->pregs_read);
}

static inline void ctx_log_reg_write(DisasContext *ctx, int rnum,
bool is_predicated)
{
Expand All @@ -99,6 +108,17 @@ static inline void ctx_log_reg_write_pair(DisasContext *ctx, int rnum,
ctx_log_reg_write(ctx, rnum + 1, is_predicated);
}

static inline void ctx_log_reg_read(DisasContext *ctx, int rnum)
{
set_bit(rnum, ctx->regs_read);
}

static inline void ctx_log_reg_read_pair(DisasContext *ctx, int rnum)
{
ctx_log_reg_read(ctx, rnum);
ctx_log_reg_read(ctx, rnum + 1);
}

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,
Expand Down Expand Up @@ -139,13 +159,29 @@ static inline void ctx_log_vreg_write_pair(DisasContext *ctx,
ctx_log_vreg_write(ctx, rnum ^ 1, type, is_predicated);
}

static inline void ctx_log_vreg_read(DisasContext *ctx, int rnum)
{
set_bit(rnum, ctx->vregs_read);
}

static inline void ctx_log_vreg_read_pair(DisasContext *ctx, int rnum)
{
ctx_log_vreg_read(ctx, rnum ^ 0);
ctx_log_vreg_read(ctx, rnum ^ 1);
}

static inline void ctx_log_qreg_write(DisasContext *ctx,
int rnum)
{
ctx->qreg_log[ctx->qreg_log_idx] = rnum;
ctx->qreg_log_idx++;
}

static inline void ctx_log_qreg_read(DisasContext *ctx, int qnum)
{
set_bit(qnum, ctx->qregs_read);
}

extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
extern TCGv hex_pred[NUM_PREGS];
extern TCGv hex_this_PC;
Expand Down

0 comments on commit b9f0326

Please sign in to comment.