Hexagon (target/hexagon) Remove old way of detecting register multiwrites

We now detect register multiwrites in packet analysis instead of
packet decoding

Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Marco Liebel <marco.liebel@oss.qualcomm.com>
Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
This commit is contained in:
Taylor Simpson authored and Brian Cain committed 2026-09-24 17:22:45 -07:00
1 parent b8dc562cd8
commit 6ed3e12599
4 files changed
-74

No files matched your search

-54
View File
@@ -691,55 +691,6 @@ bool opcode_supported(uint16_t opcode, const HexagonCPUDef *hex_def)
return true;
}
/*
* Check for GPR write conflicts in the packet.
* A conflict exists when a register is written by more than one instruction
* and at least one of those writes is unconditional.
*
* TODO: handle the more general case of any
* packet w/multiple-register-write operands.
*/
static bool pkt_has_write_conflict(Packet *pkt)
{
DECLARE_BITMAP(all_dest_gprs, 32) = { 0 };
DECLARE_BITMAP(wreg_mult_gprs, 32) = { 0 };
DECLARE_BITMAP(uncond_wreg_gprs, 32) = { 0 };
DECLARE_BITMAP(conflict, 32);
for (int i = 0; i < pkt->num_insns; i++) {
Insn *insn = &pkt->insn[i];
int dest = insn->dest_idx;
if (dest < 0 || !insn->dest_is_gpr) {
continue;
}
int rnum = insn->regno[dest];
bool is_uncond = !GET_ATTRIB(insn->opcode, A_CONDEXEC);
if (test_bit(rnum, all_dest_gprs)) {
set_bit(rnum, wreg_mult_gprs);
}
set_bit(rnum, all_dest_gprs);
if (is_uncond) {
set_bit(rnum, uncond_wreg_gprs);
}
if (insn->dest_is_pair) {
if (test_bit(rnum + 1, all_dest_gprs)) {
set_bit(rnum + 1, wreg_mult_gprs);
}
set_bit(rnum + 1, all_dest_gprs);
if (is_uncond) {
set_bit(rnum + 1, uncond_wreg_gprs);
}
}
}
bitmap_and(conflict, wreg_mult_gprs, uncond_wreg_gprs, 32);
return !bitmap_empty(conflict, 32);
}
/*
* decode_packet
* Decodes packet with given words
@@ -759,10 +710,6 @@ int decode_packet(DisasContext *ctx, int max_words, const uint32_t *words,
/* Initialize */
memset(pkt, 0, sizeof(*pkt));
for (i = 0; i < INSTRUCTIONS_MAX; i++) {
pkt->insn[i].dest_idx = -1;
pkt->insn[i].new_read_idx = -1;
}
/* Try to build packet */
while (!end_of_packet && (words_read < max_words)) {
Insn *insn = &pkt->insn[num_insns];
@@ -837,7 +784,6 @@ int decode_packet(DisasContext *ctx, int max_words, const uint32_t *words,
/* Invalid packet */
return 0;
}
pkt->pkt_has_write_conflict = pkt_has_write_conflict(pkt);
}
decode_fill_newvalue_regno(pkt);
-10
View File
@@ -91,8 +91,6 @@ def gen_trans_funcs(f):
new_read_idx = -1
dest_idx = -1
dest_idx_reg_id = None
dest_is_pair = "false"
dest_is_gpr = "false"
has_pred_dest = "false"
for regno, (reg_type, reg_id, *_) in enumerate(regs):
reg = hex_common.get_register(tag, reg_type, reg_id)
@@ -106,12 +104,6 @@ def gen_trans_funcs(f):
if dest_idx_reg_id is None or reg_id < dest_idx_reg_id:
dest_idx = regno
dest_idx_reg_id = reg_id
dest_is_pair = ("true"
if isinstance(reg, hex_common.Pair)
else "false")
dest_is_gpr = ("true"
if reg_type == "R"
else "false")
if reg_type == "P" and reg.is_written() and not reg.is_read():
has_pred_dest = "true"
@@ -137,8 +129,6 @@ def gen_trans_funcs(f):
f.write(code_fmt(f"""\
insn->new_read_idx = {new_read_idx};
insn->dest_idx = {dest_idx};
insn->dest_is_pair = {dest_is_pair};
insn->dest_is_gpr = {dest_is_gpr};
insn->has_pred_dest = {has_pred_dest};
"""))
f.write(textwrap.dedent(f"""\
-4
View File
@@ -41,8 +41,6 @@ struct Instruction {
uint32_t new_value_producer_slot:4;
int32_t new_read_idx;
int32_t dest_idx;
bool dest_is_pair;
bool dest_is_gpr;
bool has_pred_dest;
bool part1; /*
@@ -74,8 +72,6 @@ struct Packet {
bool pkt_has_hvx;
Insn *vhist_insn;
bool pkt_has_write_conflict;
Insn insn[INSTRUCTIONS_MAX];
};
-6
View File
@@ -1253,12 +1253,6 @@ static void decode_and_translate_packet(CPUHexagonState *env, DisasContext *ctx)
clear_pkt_ctx(ctx);
analyze_packet(ctx);
/*
* Check that the new method is a superset of the old methond
* Remove in a later patch
*/
g_assert(!ctx->pkt.pkt_has_write_conflict ||
pkt_has_write_conflict(ctx));
if (pkt_has_write_conflict(ctx)) {
gen_exception_decode_fail(ctx, words_read,
HEX_CAUSE_REG_WRITE_CONFLICT);