@samitouri / QOSamiQemu / commits / dfa4c8810f

target/hexagon: use TCG_COND_TSTEQ/TSTNE for predicate branches

Replace TCG_COND_EQ/NE comparisons against 0 with TCG_COND_TSTEQ/TSTNE comparisons against 1 for all predicate-conditional branches. This tests bit 0 of the predicate register directly, eliminating redundant andi operations that previously extracted the LSB before the comparison. For predicate-conditional jumps (jumpt, jumpf, jumptnew, etc.) and jump-register variants (jumprt, jumprf, etc.), pass the raw predicate value directly instead of going through fLSBOLD/fLSBNEW extraction. For callers that produce a 0/1 result via setcond (compare-and-jump, jumprz, etc.), the TSTEQ/TSTNE test on bit 0 is equivalent to the previous EQ/NE test against 0. Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>

Brian Cain committed Mar 2, 2026 at 21:29 UTC dfa4c8810f0a3bcc47a54b0a8792b14208de1be6
3 files changed +50 -78
target/hexagon/gen_tcg.h
+37 -57
@@ -696,13 +696,13 @@
696 gen_callr(ctx, RsV)
697
698 #define fGEN_TCG_J2_callt(SHORTCODE) \
699 - gen_cond_call(ctx, PuV, TCG_COND_EQ, riV)
699 + gen_cond_call(ctx, PuV, TCG_COND_TSTEQ, riV)
700 #define fGEN_TCG_J2_callf(SHORTCODE) \
701 - gen_cond_call(ctx, PuV, TCG_COND_NE, riV)
701 + gen_cond_call(ctx, PuV, TCG_COND_TSTNE, riV)
702 #define fGEN_TCG_J2_callrt(SHORTCODE) \
703 - gen_cond_callr(ctx, TCG_COND_EQ, PuV, RsV)
703 + gen_cond_callr(ctx, TCG_COND_TSTEQ, PuV, RsV)
704 #define fGEN_TCG_J2_callrf(SHORTCODE) \
705 - gen_cond_callr(ctx, TCG_COND_NE, PuV, RsV)
705 + gen_cond_callr(ctx, TCG_COND_TSTNE, PuV, RsV)
706
707 #define fGEN_TCG_J2_loop0r(SHORTCODE) \
708 gen_loop0r(ctx, RsV, riV)
@@ -893,21 +893,21 @@
893 gen_cmpnd_cmp_n1_jmp_f(ctx, 1, TCG_COND_GT, RsV, riV)
894
895 #define fGEN_TCG_J4_tstbit0_tp0_jump_nt(SHORTCODE) \
896 - gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_EQ, riV)
896 + gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_TSTEQ, riV)
897 #define fGEN_TCG_J4_tstbit0_tp0_jump_t(SHORTCODE) \
898 - gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_EQ, riV)
898 + gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_TSTEQ, riV)
899 #define fGEN_TCG_J4_tstbit0_fp0_jump_nt(SHORTCODE) \
900 - gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_NE, riV)
900 + gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_TSTNE, riV)
901 #define fGEN_TCG_J4_tstbit0_fp0_jump_t(SHORTCODE) \
902 - gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_NE, riV)
902 + gen_cmpnd_tstbit0_jmp(ctx, 0, RsV, TCG_COND_TSTNE, riV)
903 #define fGEN_TCG_J4_tstbit0_tp1_jump_nt(SHORTCODE) \
904 - gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_EQ, riV)
904 + gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_TSTEQ, riV)
905 #define fGEN_TCG_J4_tstbit0_tp1_jump_t(SHORTCODE) \
906 - gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_EQ, riV)
906 + gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_TSTEQ, riV)
907 #define fGEN_TCG_J4_tstbit0_fp1_jump_nt(SHORTCODE) \
908 - gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_NE, riV)
908 + gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_TSTNE, riV)
909 #define fGEN_TCG_J4_tstbit0_fp1_jump_t(SHORTCODE) \
910 - gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_NE, riV)
910 + gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_TSTNE, riV)
911
912 /* p0 = cmp.eq(r0, #7) */
913 #define fGEN_TCG_SA1_cmpeqi(SHORTCODE) \
@@ -933,31 +933,24 @@
933 do { \
934 TCGv LSB = tcg_temp_new(); \
935 COND; \
936 - gen_cond_jump(ctx, TCG_COND_EQ, LSB, riV); \
936 + gen_cond_jump(ctx, TCG_COND_TSTEQ, LSB, riV); \
937 } while (0)
938 -#define fGEN_TCG_cond_jumpf(COND) \
939 - do { \
940 - TCGv LSB = tcg_temp_new(); \
941 - COND; \
942 - gen_cond_jump(ctx, TCG_COND_NE, LSB, riV); \
943 - } while (0)
944 -
938 #define fGEN_TCG_J2_jumpt(SHORTCODE) \
946 - fGEN_TCG_cond_jumpt(fLSBOLD(PuV))
939 + gen_cond_jump(ctx, TCG_COND_TSTEQ, PuV, riV)
940 #define fGEN_TCG_J2_jumptpt(SHORTCODE) \
948 - fGEN_TCG_cond_jumpt(fLSBOLD(PuV))
941 + gen_cond_jump(ctx, TCG_COND_TSTEQ, PuV, riV)
942 #define fGEN_TCG_J2_jumpf(SHORTCODE) \
950 - fGEN_TCG_cond_jumpf(fLSBOLD(PuV))
943 + gen_cond_jump(ctx, TCG_COND_TSTNE, PuV, riV)
944 #define fGEN_TCG_J2_jumpfpt(SHORTCODE) \
952 - fGEN_TCG_cond_jumpf(fLSBOLD(PuV))
945 + gen_cond_jump(ctx, TCG_COND_TSTNE, PuV, riV)
946 #define fGEN_TCG_J2_jumptnew(SHORTCODE) \
954 - fGEN_TCG_cond_jumpt(fLSBNEW(PuN))
947 + gen_cond_jump(ctx, TCG_COND_TSTEQ, PuN, riV)
948 #define fGEN_TCG_J2_jumptnewpt(SHORTCODE) \
956 - fGEN_TCG_cond_jumpt(fLSBNEW(PuN))
949 + gen_cond_jump(ctx, TCG_COND_TSTEQ, PuN, riV)
950 #define fGEN_TCG_J2_jumpfnewpt(SHORTCODE) \
958 - fGEN_TCG_cond_jumpf(fLSBNEW(PuN))
951 + gen_cond_jump(ctx, TCG_COND_TSTNE, PuN, riV)
952 #define fGEN_TCG_J2_jumpfnew(SHORTCODE) \
960 - fGEN_TCG_cond_jumpf(fLSBNEW(PuN))
953 + gen_cond_jump(ctx, TCG_COND_TSTNE, PuN, riV)
954 #define fGEN_TCG_J2_jumprz(SHORTCODE) \
955 fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_NE, LSB, RsV, 0))
956 #define fGEN_TCG_J2_jumprzpt(SHORTCODE) \
@@ -975,35 +968,22 @@
968 #define fGEN_TCG_J2_jumprltezpt(SHORTCODE) \
969 fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_LE, LSB, RsV, 0))
970
978 -#define fGEN_TCG_cond_jumprt(COND) \
979 - do { \
980 - TCGv LSB = tcg_temp_new(); \
981 - COND; \
982 - gen_cond_jumpr(ctx, RsV, TCG_COND_EQ, LSB); \
983 - } while (0)
984 -#define fGEN_TCG_cond_jumprf(COND) \
985 - do { \
986 - TCGv LSB = tcg_temp_new(); \
987 - COND; \
988 - gen_cond_jumpr(ctx, RsV, TCG_COND_NE, LSB); \
989 - } while (0)
990 -
971 #define fGEN_TCG_J2_jumprt(SHORTCODE) \
992 - fGEN_TCG_cond_jumprt(fLSBOLD(PuV))
972 + gen_cond_jumpr(ctx, RsV, TCG_COND_TSTEQ, PuV)
973 #define fGEN_TCG_J2_jumprtpt(SHORTCODE) \
994 - fGEN_TCG_cond_jumprt(fLSBOLD(PuV))
974 + gen_cond_jumpr(ctx, RsV, TCG_COND_TSTEQ, PuV)
975 #define fGEN_TCG_J2_jumprf(SHORTCODE) \
996 - fGEN_TCG_cond_jumprf(fLSBOLD(PuV))
976 + gen_cond_jumpr(ctx, RsV, TCG_COND_TSTNE, PuV)
977 #define fGEN_TCG_J2_jumprfpt(SHORTCODE) \
998 - fGEN_TCG_cond_jumprf(fLSBOLD(PuV))
978 + gen_cond_jumpr(ctx, RsV, TCG_COND_TSTNE, PuV)
979 #define fGEN_TCG_J2_jumprtnew(SHORTCODE) \
1000 - fGEN_TCG_cond_jumprt(fLSBNEW(PuN))
980 + gen_cond_jumpr(ctx, RsV, TCG_COND_TSTEQ, PuN)
981 #define fGEN_TCG_J2_jumprtnewpt(SHORTCODE) \
1002 - fGEN_TCG_cond_jumprt(fLSBNEW(PuN))
982 + gen_cond_jumpr(ctx, RsV, TCG_COND_TSTEQ, PuN)
983 #define fGEN_TCG_J2_jumprfnew(SHORTCODE) \
1004 - fGEN_TCG_cond_jumprf(fLSBNEW(PuN))
984 + gen_cond_jumpr(ctx, RsV, TCG_COND_TSTNE, PuN)
985 #define fGEN_TCG_J2_jumprfnewpt(SHORTCODE) \
1006 - fGEN_TCG_cond_jumprf(fLSBNEW(PuN))
986 + gen_cond_jumpr(ctx, RsV, TCG_COND_TSTNE, PuN)
987
988 /*
989 * New value compare & jump instructions
@@ -1101,13 +1081,13 @@
1081 gen_cmpi_jumpnv(ctx, TCG_COND_LE, NsN, -1, riV)
1082
1083 #define fGEN_TCG_J4_tstbit0_t_jumpnv_t(SHORTCODE) \
1104 - gen_testbit0_jumpnv(ctx, NsN, TCG_COND_EQ, riV)
1084 + gen_testbit0_jumpnv(ctx, NsN, TCG_COND_TSTEQ, riV)
1085 #define fGEN_TCG_J4_tstbit0_t_jumpnv_nt(SHORTCODE) \
1106 - gen_testbit0_jumpnv(ctx, NsN, TCG_COND_EQ, riV)
1086 + gen_testbit0_jumpnv(ctx, NsN, TCG_COND_TSTEQ, riV)
1087 #define fGEN_TCG_J4_tstbit0_f_jumpnv_t(SHORTCODE) \
1108 - gen_testbit0_jumpnv(ctx, NsN, TCG_COND_NE, riV)
1088 + gen_testbit0_jumpnv(ctx, NsN, TCG_COND_TSTNE, riV)
1089 #define fGEN_TCG_J4_tstbit0_f_jumpnv_nt(SHORTCODE) \
1110 - gen_testbit0_jumpnv(ctx, NsN, TCG_COND_NE, riV)
1090 + gen_testbit0_jumpnv(ctx, NsN, TCG_COND_TSTNE, riV)
1091
1092 /* r0 = r1 ; jump address */
1093 #define fGEN_TCG_J4_jumpsetr(SHORTCODE) \
@@ -1150,14 +1130,14 @@
1130 gen_jumpr(ctx, hex_gpr[HEX_REG_LR])
1131
1132 #define fGEN_TCG_SL2_jumpr31_t(SHORTCODE) \
1153 - gen_cond_jumpr31(ctx, TCG_COND_EQ, hex_pred[0])
1133 + gen_cond_jumpr31(ctx, TCG_COND_TSTEQ, hex_pred[0])
1134 #define fGEN_TCG_SL2_jumpr31_f(SHORTCODE) \
1155 - gen_cond_jumpr31(ctx, TCG_COND_NE, hex_pred[0])
1135 + gen_cond_jumpr31(ctx, TCG_COND_TSTNE, hex_pred[0])
1136
1137 #define fGEN_TCG_SL2_jumpr31_tnew(SHORTCODE) \
1158 - gen_cond_jumpr31(ctx, TCG_COND_EQ, ctx->new_pred_value[0])
1138 + gen_cond_jumpr31(ctx, TCG_COND_TSTEQ, ctx->new_pred_value[0])
1139 #define fGEN_TCG_SL2_jumpr31_fnew(SHORTCODE) \
1160 - gen_cond_jumpr31(ctx, TCG_COND_NE, ctx->new_pred_value[0])
1140 + gen_cond_jumpr31(ctx, TCG_COND_TSTNE, ctx->new_pred_value[0])
1141
1142 /* Count trailing zeros/ones */
1143 #define fGEN_TCG_S2_ct0(SHORTCODE) \
target/hexagon/genptr.c
+12 -20
@@ -455,7 +455,7 @@ static void gen_write_new_pc_addr(DisasContext *ctx, TCGv addr,
455 TCGLabel *pred_false = NULL;
456 if (cond != TCG_COND_ALWAYS) {
457 pred_false = gen_new_label();
458 - tcg_gen_brcondi_tl(cond, pred, 0, pred_false);
458 + tcg_gen_brcondi_tl(cond, pred, 1, pred_false);
459 }
460
461 if (ctx->pkt->pkt_has_multi_cof) {
@@ -579,9 +579,7 @@ static void gen_cond_jumpr(DisasContext *ctx, TCGv dst_pc,
579
580 static void gen_cond_jumpr31(DisasContext *ctx, TCGCond cond, TCGv pred)
581 {
582 - TCGv LSB = tcg_temp_new();
583 - tcg_gen_andi_tl(LSB, pred, 1);
584 - gen_cond_jumpr(ctx, hex_gpr[HEX_REG_LR], cond, LSB);
582 + gen_cond_jumpr(ctx, hex_gpr[HEX_REG_LR], cond, pred);
583 }
584
585 static void gen_cond_jump(DisasContext *ctx, TCGCond cond, TCGv pred,
@@ -609,14 +607,14 @@ static void gen_cmpnd_cmp_jmp_t(DisasContext *ctx,
607 int pnum, TCGCond cond, TCGv arg1, TCGv arg2,
608 int pc_off)
609 {
612 - gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, arg2, TCG_COND_EQ, pc_off);
610 + gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, arg2, TCG_COND_TSTEQ, pc_off);
611 }
612
613 static void gen_cmpnd_cmp_jmp_f(DisasContext *ctx,
614 int pnum, TCGCond cond, TCGv arg1, TCGv arg2,
615 int pc_off)
616 {
619 - gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, arg2, TCG_COND_NE, pc_off);
617 + gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, arg2, TCG_COND_TSTNE, pc_off);
618 }
619
620 static void gen_cmpnd_cmpi_jmp_t(DisasContext *ctx,
@@ -624,7 +622,7 @@ static void gen_cmpnd_cmpi_jmp_t(DisasContext *ctx,
622 int pc_off)
623 {
624 TCGv tmp = tcg_constant_tl(arg2);
627 - gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, tmp, TCG_COND_EQ, pc_off);
625 + gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, tmp, TCG_COND_TSTEQ, pc_off);
626 }
627
628 static void gen_cmpnd_cmpi_jmp_f(DisasContext *ctx,
@@ -632,7 +630,7 @@ static void gen_cmpnd_cmpi_jmp_f(DisasContext *ctx,
630 int pc_off)
631 {
632 TCGv tmp = tcg_constant_tl(arg2);
635 - gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, tmp, TCG_COND_NE, pc_off);
633 + gen_cmpnd_cmp_jmp(ctx, pnum, cond, arg1, tmp, TCG_COND_TSTNE, pc_off);
634 }
635
636 static void gen_cmpnd_cmp_n1_jmp_t(DisasContext *ctx, int pnum, TCGCond cond,
@@ -665,9 +663,7 @@ static void gen_cmpnd_tstbit0_jmp(DisasContext *ctx,
663 static void gen_testbit0_jumpnv(DisasContext *ctx,
664 TCGv arg, TCGCond cond, int pc_off)
665 {
668 - TCGv pred = tcg_temp_new();
669 - tcg_gen_andi_tl(pred, arg, 1);
670 - gen_cond_jump(ctx, cond, pred, pc_off);
666 + gen_cond_jump(ctx, cond, arg, pc_off);
667 }
668
669 static void gen_jump(DisasContext *ctx, int pc_off)
@@ -698,11 +694,9 @@ static void gen_cond_call(DisasContext *ctx, TCGv pred,
694 TCGCond cond, int pc_off)
695 {
696 TCGv lr = get_result_gpr(ctx, HEX_REG_LR);
701 - TCGv lsb = tcg_temp_new();
697 TCGLabel *skip = gen_new_label();
703 - tcg_gen_andi_tl(lsb, pred, 1);
704 - gen_write_new_pc_pcrel(ctx, pc_off, cond, lsb);
705 - tcg_gen_brcondi_tl(cond, lsb, 0, skip);
698 + gen_write_new_pc_pcrel(ctx, pc_off, cond, pred);
699 + tcg_gen_brcondi_tl(cond, pred, 1, skip);
700 tcg_gen_movi_tl(lr, ctx->next_PC);
701 gen_set_label(skip);
702 }
@@ -710,10 +704,8 @@ static void gen_cond_call(DisasContext *ctx, TCGv pred,
704 static void gen_cond_callr(DisasContext *ctx,
705 TCGCond cond, TCGv pred, TCGv new_pc)
706 {
713 - TCGv lsb = tcg_temp_new();
707 TCGLabel *skip = gen_new_label();
715 - tcg_gen_andi_tl(lsb, pred, 1);
716 - tcg_gen_brcondi_tl(cond, lsb, 0, skip);
708 + tcg_gen_brcondi_tl(cond, pred, 1, skip);
709 gen_callr(ctx, new_pc);
710 gen_set_label(skip);
711 }
@@ -955,7 +947,7 @@ static void gen_cmp_jumpnv(DisasContext *ctx,
947 {
948 TCGv pred = tcg_temp_new();
949 tcg_gen_setcond_tl(cond, pred, val, src);
958 - gen_cond_jump(ctx, TCG_COND_EQ, pred, pc_off);
950 + gen_cond_jump(ctx, TCG_COND_TSTEQ, pred, pc_off);
951 }
952
953 static void gen_cmpi_jumpnv(DisasContext *ctx,
@@ -963,7 +955,7 @@ static void gen_cmpi_jumpnv(DisasContext *ctx,
955 {
956 TCGv pred = tcg_temp_new();
957 tcg_gen_setcondi_tl(cond, pred, val, src);
966 - gen_cond_jump(ctx, TCG_COND_EQ, pred, pc_off);
958 + gen_cond_jump(ctx, TCG_COND_TSTEQ, pred, pc_off);
959 }
960
961 /* Shift left with saturation */
target/hexagon/translate.c
+1 -1
@@ -163,7 +163,7 @@ static void gen_end_tb(DisasContext *ctx)
163 if (ctx->branch_cond != TCG_COND_NEVER) {
164 if (ctx->branch_cond != TCG_COND_ALWAYS) {
165 TCGLabel *skip = gen_new_label();
166 - tcg_gen_brcondi_tl(ctx->branch_cond, ctx->branch_taken, 0, skip);
166 + tcg_gen_brcondi_tl(ctx->branch_cond, ctx->branch_taken, 1, skip);
167 gen_goto_tb(ctx, 0, ctx->branch_dest, true);
168 gen_set_label(skip);
169 gen_goto_tb(ctx, 1, ctx->next_PC, false);