target/hexagon: Add pkt_ends_tb to translation
Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user