[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/8] Hexagon (target/hexagon) Only use branch_taken when packet h
From: |
Taylor Simpson |
Subject: |
[PATCH 1/8] Hexagon (target/hexagon) Only use branch_taken when packet has multi cof |
Date: |
Wed, 19 Oct 2022 15:37:32 -0700 |
When a packet has more than one change-of-flow instruction, only the first
one to branch is considered. We use the branch_taken variable to keep
track of this.
However, when there is a single cof instruction, we don't need the same
amount of bookkeeping.
We add the pkt_has_multi_cof member to the Packet structure, and pass this
information to the needed functions.
When there is a generated helper function with cof, the generator will
pass this pkt_has_multi_cof as a runtime value.
Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
---
target/hexagon/insn.h | 1 +
target/hexagon/macros.h | 2 +-
target/hexagon/decode.c | 15 +++++++++++++--
target/hexagon/op_helper.c | 24 +++++++++++++++---------
target/hexagon/translate.c | 4 +++-
target/hexagon/gen_helper_funcs.py | 3 +++
target/hexagon/gen_helper_protos.py | 6 +++++-
target/hexagon/gen_tcg_funcs.py | 5 +++++
target/hexagon/hex_common.py | 8 ++++++++
9 files changed, 54 insertions(+), 14 deletions(-)
diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h
index aa26389147..857a7ceb75 100644
--- a/target/hexagon/insn.h
+++ b/target/hexagon/insn.h
@@ -60,6 +60,7 @@ struct Packet {
/* Pre-decodes about COF */
bool pkt_has_cof; /* Has any change-of-flow */
+ bool pkt_has_multi_cof; /* Has more than one change-of-flow */
bool pkt_has_endloop;
bool pkt_has_dczeroa;
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index c8805bdaeb..e908405d82 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -407,7 +407,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int
shift)
#define fCHECK_PCALIGN(A)
-#define fWRITE_NPC(A) write_new_pc(env, A)
+#define fWRITE_NPC(A) write_new_pc(env, pkt_has_multi_cof != 0, A)
#define fBRANCH(LOC, TYPE) fWRITE_NPC(LOC)
#define fJUMPR(REGNO, TARGET, TYPE) fBRANCH(TARGET, COF_TYPE_JUMPR)
diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index 6b73b5c60c..041c8de751 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -388,6 +388,7 @@ static void decode_set_insn_attr_fields(Packet *pkt)
uint16_t opcode;
pkt->pkt_has_cof = false;
+ pkt->pkt_has_multi_cof = false;
pkt->pkt_has_endloop = false;
pkt->pkt_has_dczeroa = false;
@@ -412,13 +413,23 @@ static void decode_set_insn_attr_fields(Packet *pkt)
}
}
- pkt->pkt_has_cof |= decode_opcode_can_jump(opcode);
+ if (decode_opcode_can_jump(opcode)) {
+ if (pkt->pkt_has_cof) {
+ pkt->pkt_has_multi_cof = true;
+ }
+ pkt->pkt_has_cof = true;
+ }
pkt->insn[i].is_endloop = decode_opcode_ends_loop(opcode);
pkt->pkt_has_endloop |= pkt->insn[i].is_endloop;
- pkt->pkt_has_cof |= pkt->pkt_has_endloop;
+ if (pkt->pkt_has_endloop) {
+ if (pkt->pkt_has_cof) {
+ pkt->pkt_has_multi_cof = true;
+ }
+ pkt->pkt_has_cof = true;
+ }
}
}
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 085afc3274..84391e25eb 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -104,20 +104,26 @@ static void log_store64(CPUHexagonState *env,
target_ulong addr,
env->mem_log_stores[slot].data64 = val;
}
-static void write_new_pc(CPUHexagonState *env, target_ulong addr)
+static void write_new_pc(CPUHexagonState *env, bool pkt_has_multi_cof,
+ target_ulong addr)
{
HEX_DEBUG_LOG("write_new_pc(0x" TARGET_FMT_lx ")\n", addr);
- /*
- * If more than one branch is taken in a packet, only the first one
- * is actually done.
- */
- if (env->branch_taken) {
- HEX_DEBUG_LOG("INFO: multiple branches taken in same packet, "
- "ignoring the second one\n");
+ if (pkt_has_multi_cof) {
+ /*
+ * If more than one branch is taken in a packet, only the first one
+ * is actually done.
+ */
+ if (env->branch_taken) {
+ HEX_DEBUG_LOG("INFO: multiple branches taken in same packet, "
+ "ignoring the second one\n");
+ } else {
+ fCHECK_PCALIGN(addr);
+ env->next_PC = addr;
+ env->branch_taken = 1;
+ }
} else {
fCHECK_PCALIGN(addr);
- env->branch_taken = 1;
env->next_PC = addr;
}
}
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 2329177537..2e46cc0680 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -247,7 +247,9 @@ static void gen_start_packet(DisasContext *ctx, Packet *pkt)
tcg_gen_movi_tl(hex_slot_cancelled, 0);
}
if (pkt->pkt_has_cof) {
- tcg_gen_movi_tl(hex_branch_taken, 0);
+ if (pkt->pkt_has_multi_cof) {
+ tcg_gen_movi_tl(hex_branch_taken, 0);
+ }
tcg_gen_movi_tl(hex_next_PC, next_PC);
}
if (need_pred_written(pkt)) {
diff --git a/target/hexagon/gen_helper_funcs.py
b/target/hexagon/gen_helper_funcs.py
index a446c45384..f7c1a82e9f 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -238,6 +238,9 @@ def gen_helper_function(f, tag, tagregs, tagimms):
gen_helper_arg_imm(f,immlett)
i += 1
+ if (hex_common.need_pkt_has_multi_cof(tag)):
+ f.write(", uint32_t pkt_has_multi_cof")
+
if hex_common.need_slot(tag):
if i > 0: f.write(", ")
f.write("uint32_t slot")
diff --git a/target/hexagon/gen_helper_protos.py
b/target/hexagon/gen_helper_protos.py
index 3b4e993fd1..4530d7ba8d 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -82,6 +82,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
## Figure out how many arguments the helper will take
if (numscalarresults == 0):
def_helper_size = len(regs)+len(imms)+numscalarreadwrite+1
+ if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += 1
if hex_common.need_part1(tag): def_helper_size += 1
if hex_common.need_slot(tag): def_helper_size += 1
f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag))
@@ -89,6 +90,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
f.write(', void' )
else:
def_helper_size = len(regs)+len(imms)+numscalarreadwrite
+ if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += 1
if hex_common.need_part1(tag): def_helper_size += 1
if hex_common.need_slot(tag): def_helper_size += 1
f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag))
@@ -126,7 +128,9 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
for immlett,bits,immshift in imms:
f.write(", s32")
- ## Add the arguments for the instruction slot and part1 (if needed)
+ ## Add the arguments for the instruction pkt_has_multi_cof, slot and
+ ## part1 (if needed)
+ if hex_common.need_pkt_has_multi_cof(tag): f.write(', i32')
if hex_common.need_slot(tag): f.write(', i32' )
if hex_common.need_part1(tag): f.write(' , i32' )
f.write(')\n')
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index 6dea02b0b9..67045c80bb 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -615,6 +615,9 @@ def gen_tcg_func(f, tag, regs, imms):
## Generate the call to the helper
for immlett,bits,immshift in imms:
gen_helper_decl_imm(f,immlett)
+ if hex_common.need_pkt_has_multi_cof(tag):
+ f.write(" TCGv pkt_has_multi_cof = ")
+ f.write("tcg_constant_tl(pkt->pkt_has_multi_cof);\n")
if hex_common.need_part1(tag):
f.write(" TCGv part1 = tcg_constant_tl(insn->part1);\n")
if hex_common.need_slot(tag):
@@ -647,6 +650,8 @@ def gen_tcg_func(f, tag, regs, imms):
for immlett,bits,immshift in imms:
gen_helper_call_imm(f,immlett)
+ if hex_common.need_pkt_has_multi_cof(tag):
+ f.write(", pkt_has_multi_cof")
if hex_common.need_slot(tag): f.write(", slot")
if hex_common.need_part1(tag): f.write(", part1" )
f.write(");\n")
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index d9ba7df786..6a6bee7551 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -207,6 +207,14 @@ def need_part1(tag):
def need_ea(tag):
return re.compile(r"\bEA\b").search(semdict[tag])
+def need_pkt_has_multi_cof(tag):
+ if ('A_JUMP' in attribdict[tag] or
+ 'A_CALL' in attribdict[tag] or
+ 'A_HWLOOP0_END' in attribdict[tag] or
+ 'A_HWLOOP1_END' in attribdict[tag]):
+ return True
+ return False
+
def skip_qemu_helper(tag):
return tag in overrides.keys()
--
2.17.1
- [PATCH 0/8] Hexagon (target/hexagon) Improve change-of-flow, Taylor Simpson, 2022/10/19
- [PATCH 6/8] Hexagon (target/hexagon) Add overrides for various forms of jump, Taylor Simpson, 2022/10/19
- [PATCH 2/8] Hexagon (target/hexagon) Remove PC from the runtime state, Taylor Simpson, 2022/10/19
- [PATCH 1/8] Hexagon (target/hexagon) Only use branch_taken when packet has multi cof,
Taylor Simpson <=
- [PATCH 4/8] Hexagon (target/hexagon) Add overrides for direct call instructions, Taylor Simpson, 2022/10/19
- [PATCH 3/8] Hexagon (target/hexagon) Remove next_PC from runtime state, Taylor Simpson, 2022/10/19
- [PATCH 5/8] Hexagon (target/hexagon) Add overrides for compound compare and jump, Taylor Simpson, 2022/10/19
- [PATCH 7/8] Hexagon (target/hexagon) Use direct block chaining for direct jump/branch, Taylor Simpson, 2022/10/19
- [PATCH 8/8] Hexagon (target/hexagon) Use direct block chaining for tight loops, Taylor Simpson, 2022/10/19