From 5312546b4fd0c2dbca7dd7b4a2a4e865de2e418d Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Mon, 22 Jun 2026 15:28:46 -0700 Subject: [PATCH] target/hexagon: Add pkt_ends_tb to translation Reviewed-by: Taylor Simpson Signed-off-by: Brian Cain --- target/hexagon/translate.c | 102 ++++++++++++++++++++++++++++++++++++- target/hexagon/translate.h | 1 - 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index ce5bbe92d5..35e9036288 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -270,6 +270,16 @@ static bool check_for_attrib(Packet *pkt, int attrib) return false; } +static bool check_for_opcode(Packet *pkt, uint16_t opcode) +{ + for (int i = 0; i < pkt->num_insns; i++) { + if (pkt->insn[i].opcode == opcode) { + return true; + } + } + return false; +} + static bool need_slot_cancelled(Packet *pkt) { /* We only need slot_cancelled for conditional store instructions */ @@ -283,6 +293,90 @@ static bool need_slot_cancelled(Packet *pkt) return false; } +#ifndef CONFIG_USER_ONLY +static bool sreg_write_ends_tb(int reg_num) +{ + return reg_num == HEX_SREG_SSR || + reg_num == HEX_SREG_STID || + reg_num == HEX_SREG_IMASK || + reg_num == HEX_SREG_IPENDAD || + reg_num == HEX_SREG_BESTWAIT || + reg_num == HEX_SREG_SCHEDCFG; +} + +static bool has_sreg_write_ends_tb(Packet const *pkt) +{ + for (int i = 0; i < pkt->num_insns; i++) { + Insn const *insn = &pkt->insn[i]; + uint16_t opcode = insn->opcode; + if (opcode == Y2_tfrsrcr) { + /* Write to a single sreg */ + int reg_num = insn->regno[0]; + if (sreg_write_ends_tb(reg_num)) { + return true; + } + } else if (opcode == Y4_tfrspcp) { + /* Write to a sreg pair */ + int reg_num = insn->regno[0]; + if (sreg_write_ends_tb(reg_num)) { + return true; + } + if (sreg_write_ends_tb(reg_num + 1)) { + return true; + } + } + } + return false; +} +#endif + +static bool pkt_ends_tb(Packet *pkt) +{ + if (pkt->pkt_has_cof) { + return true; + } +#ifndef CONFIG_USER_ONLY + /* System mode instructions that end TLB */ + if (check_for_opcode(pkt, Y2_swi) || + check_for_opcode(pkt, Y2_cswi) || + check_for_opcode(pkt, Y2_ciad) || + check_for_opcode(pkt, Y4_siad) || + check_for_opcode(pkt, Y2_wait) || + check_for_opcode(pkt, Y2_resume) || + check_for_opcode(pkt, Y2_iassignw) || + check_for_opcode(pkt, Y2_setimask) || + check_for_opcode(pkt, Y4_nmi) || + check_for_opcode(pkt, Y2_setprio) || + check_for_opcode(pkt, Y2_start) || + check_for_opcode(pkt, Y2_stop) || + check_for_opcode(pkt, Y2_k0lock) || + check_for_opcode(pkt, Y2_k0unlock) || + check_for_opcode(pkt, Y2_tlblock) || + check_for_opcode(pkt, Y2_tlbunlock) || + check_for_opcode(pkt, Y2_break) || + check_for_opcode(pkt, Y2_isync) || + check_for_opcode(pkt, Y2_syncht) || + check_for_opcode(pkt, Y2_tlbp) || + check_for_opcode(pkt, Y2_tlbw) || + check_for_opcode(pkt, Y5_ctlbw) || + check_for_opcode(pkt, Y5_tlbasidi)) { + return true; + } + + /* + * Check for sreg writes that would end the TB + */ + if (check_for_attrib(pkt, A_IMPLICIT_WRITES_SSR)) { + return true; + } + if (has_sreg_write_ends_tb(pkt)) { + return true; + } +#endif + return false; +} + + static bool need_next_PC(DisasContext *ctx) { /* Check for conditional control flow or HW loop end */ @@ -439,7 +533,11 @@ static void analyze_packet(DisasContext *ctx) static void gen_start_packet(DisasContext *ctx) { - target_ulong next_PC = ctx->base.pc_next + ctx->pkt.encod_pkt_size_in_bytes; + Packet *pkt = &ctx->pkt; + target_ulong next_PC = (check_for_opcode(pkt, Y2_k0lock) || + check_for_opcode(pkt, Y2_tlblock)) ? + ctx->base.pc_next : + ctx->base.pc_next + pkt->encod_pkt_size_in_bytes; int i; /* Clear out the disassembly context */ @@ -944,7 +1042,7 @@ static void gen_commit_packet(DisasContext *ctx) ctx->pkt.vhist_insn->generate(ctx); } - if (ctx->pkt.pkt_has_cof) { + if (pkt_ends_tb(&ctx->pkt) || ctx->base.is_jmp == DISAS_NORETURN) { gen_end_tb(ctx); } } diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index f79bdedd7b..fea88cb2db 100644 --- a/target/hexagon/translate.h +++ b/target/hexagon/translate.h @@ -86,7 +86,6 @@ typedef struct DisasContext { TCGv branch_taken; TCGv dczero_addr; bool pcycle_enabled; - bool pkt_ends_tb; uint32_t num_cycles; } DisasContext;