mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-10-28 14:04:39 +08:00
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:
1 parent
b8dc562cd8
commit
6ed3e12599
4 files changed
-74
No files matched your search
@@ -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);
|
||||
|
||||
|
||||
@@ -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"""\
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user