@samitouri / QOSamiQemu / commits / 5312546b4f

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>

Brian Cain committed Jun 22, 2026 at 15:28 UTC 5312546b4fd0c2dbca7dd7b4a2a4e865de2e418d
2 files changed +100 -3
target/hexagon/translate.c
+100 -2
@@ -270,6 +270,16 @@ static bool check_for_attrib(Packet *pkt, int attrib)
270 return false;
271 }
272
273 +static bool check_for_opcode(Packet *pkt, uint16_t opcode)
274 +{
275 + for (int i = 0; i < pkt->num_insns; i++) {
276 + if (pkt->insn[i].opcode == opcode) {
277 + return true;
278 + }
279 + }
280 + return false;
281 +}
282 +
283 static bool need_slot_cancelled(Packet *pkt)
284 {
285 /* We only need slot_cancelled for conditional store instructions */
@@ -283,6 +293,90 @@ static bool need_slot_cancelled(Packet *pkt)
293 return false;
294 }
295
296 +#ifndef CONFIG_USER_ONLY
297 +static bool sreg_write_ends_tb(int reg_num)
298 +{
299 + return reg_num == HEX_SREG_SSR ||
300 + reg_num == HEX_SREG_STID ||
301 + reg_num == HEX_SREG_IMASK ||
302 + reg_num == HEX_SREG_IPENDAD ||
303 + reg_num == HEX_SREG_BESTWAIT ||
304 + reg_num == HEX_SREG_SCHEDCFG;
305 +}
306 +
307 +static bool has_sreg_write_ends_tb(Packet const *pkt)
308 +{
309 + for (int i = 0; i < pkt->num_insns; i++) {
310 + Insn const *insn = &pkt->insn[i];
311 + uint16_t opcode = insn->opcode;
312 + if (opcode == Y2_tfrsrcr) {
313 + /* Write to a single sreg */
314 + int reg_num = insn->regno[0];
315 + if (sreg_write_ends_tb(reg_num)) {
316 + return true;
317 + }
318 + } else if (opcode == Y4_tfrspcp) {
319 + /* Write to a sreg pair */
320 + int reg_num = insn->regno[0];
321 + if (sreg_write_ends_tb(reg_num)) {
322 + return true;
323 + }
324 + if (sreg_write_ends_tb(reg_num + 1)) {
325 + return true;
326 + }
327 + }
328 + }
329 + return false;
330 +}
331 +#endif
332 +
333 +static bool pkt_ends_tb(Packet *pkt)
334 +{
335 + if (pkt->pkt_has_cof) {
336 + return true;
337 + }
338 +#ifndef CONFIG_USER_ONLY
339 + /* System mode instructions that end TLB */
340 + if (check_for_opcode(pkt, Y2_swi) ||
341 + check_for_opcode(pkt, Y2_cswi) ||
342 + check_for_opcode(pkt, Y2_ciad) ||
343 + check_for_opcode(pkt, Y4_siad) ||
344 + check_for_opcode(pkt, Y2_wait) ||
345 + check_for_opcode(pkt, Y2_resume) ||
346 + check_for_opcode(pkt, Y2_iassignw) ||
347 + check_for_opcode(pkt, Y2_setimask) ||
348 + check_for_opcode(pkt, Y4_nmi) ||
349 + check_for_opcode(pkt, Y2_setprio) ||
350 + check_for_opcode(pkt, Y2_start) ||
351 + check_for_opcode(pkt, Y2_stop) ||
352 + check_for_opcode(pkt, Y2_k0lock) ||
353 + check_for_opcode(pkt, Y2_k0unlock) ||
354 + check_for_opcode(pkt, Y2_tlblock) ||
355 + check_for_opcode(pkt, Y2_tlbunlock) ||
356 + check_for_opcode(pkt, Y2_break) ||
357 + check_for_opcode(pkt, Y2_isync) ||
358 + check_for_opcode(pkt, Y2_syncht) ||
359 + check_for_opcode(pkt, Y2_tlbp) ||
360 + check_for_opcode(pkt, Y2_tlbw) ||
361 + check_for_opcode(pkt, Y5_ctlbw) ||
362 + check_for_opcode(pkt, Y5_tlbasidi)) {
363 + return true;
364 + }
365 +
366 + /*
367 + * Check for sreg writes that would end the TB
368 + */
369 + if (check_for_attrib(pkt, A_IMPLICIT_WRITES_SSR)) {
370 + return true;
371 + }
372 + if (has_sreg_write_ends_tb(pkt)) {
373 + return true;
374 + }
375 +#endif
376 + return false;
377 +}
378 +
379 +
380 static bool need_next_PC(DisasContext *ctx)
381 {
382 /* Check for conditional control flow or HW loop end */
@@ -439,7 +533,11 @@ static void analyze_packet(DisasContext *ctx)
533
534 static void gen_start_packet(DisasContext *ctx)
535 {
442 - target_ulong next_PC = ctx->base.pc_next + ctx->pkt.encod_pkt_size_in_bytes;
536 + Packet *pkt = &ctx->pkt;
537 + target_ulong next_PC = (check_for_opcode(pkt, Y2_k0lock) ||
538 + check_for_opcode(pkt, Y2_tlblock)) ?
539 + ctx->base.pc_next :
540 + ctx->base.pc_next + pkt->encod_pkt_size_in_bytes;
541 int i;
542
543 /* Clear out the disassembly context */
@@ -944,7 +1042,7 @@ static void gen_commit_packet(DisasContext *ctx)
1042 ctx->pkt.vhist_insn->generate(ctx);
1043 }
1044
947 - if (ctx->pkt.pkt_has_cof) {
1045 + if (pkt_ends_tb(&ctx->pkt) || ctx->base.is_jmp == DISAS_NORETURN) {
1046 gen_end_tb(ctx);
1047 }
1048 }
target/hexagon/translate.h
-1
@@ -86,7 +86,6 @@ typedef struct DisasContext {
86 TCGv branch_taken;
87 TCGv dczero_addr;
88 bool pcycle_enabled;
89 - bool pkt_ends_tb;
89 uint32_t num_cycles;
90 } DisasContext;
91