@samitouri / QOSamiQemu / commits / 1345fa46fb

target/i386/tcg: simplify return value of gen_prepare_cc

Always make reg2 valid, unify .use_reg2 and .no_setcond now that .use_reg2 is a misnomer. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo Bonzini committed Jul 22, 2026 at 09:54 UTC 1345fa46fba1abe721e9d7d5daf7061a6ead59ef
1 file changed +27 -36
target/i386/tcg/translate.c
+27 -36
@@ -828,13 +828,21 @@ static void gen_compute_eflags(DisasContext *s)
828 set_cc_op(s, CC_OP_EFLAGS);
829 }
830
831 +typedef enum {
832 + /* imm is valid and reg2 is a constant */
833 + CC_PREPARE_IMM,
834 + /* imm is invalid */
835 + CC_PREPARE_REG,
836 + /* imm and reg2 are 0, and reg is known to be 0/1 */
837 + CC_PREPARE_DIRECT,
838 +} CCPrepareRHS;
839 +
840 typedef struct CCPrepare {
841 TCGCond cond;
842 TCGv reg;
843 TCGv reg2;
844 target_ulong imm;
836 - bool use_reg2;
837 - bool no_setcond;
845 + CCPrepareRHS rhs_type;
846 } CCPrepare;
847
848 static CCPrepare gen_prepare_sign_nz(TCGv src, MemOp size)
@@ -871,7 +879,7 @@ static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
879 tcg_gen_ext_tl(s->cc_srcT, s->cc_srcT, size);
880 tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size);
881 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = s->cc_srcT,
874 - .reg2 = cpu_cc_src, .use_reg2 = true };
882 + .reg2 = cpu_cc_src, .rhs_type = CC_PREPARE_REG };
883
884 case CC_OP_ADDB ... CC_OP_ADDQ:
885 /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */
@@ -879,7 +887,7 @@ static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
887 tcg_gen_ext_tl(cpu_cc_dst, cpu_cc_dst, size);
888 tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size);
889 return (CCPrepare) { .cond = TCG_COND_LTU, .reg = cpu_cc_dst,
882 - .reg2 = cpu_cc_src, .use_reg2 = true };
890 + .reg2 = cpu_cc_src, .rhs_type = CC_PREPARE_REG };
891
892 case CC_OP_LOGICB ... CC_OP_LOGICQ:
893 case CC_OP_POPCNT:
@@ -888,7 +896,7 @@ static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
896 case CC_OP_INCB ... CC_OP_INCQ:
897 case CC_OP_DECB ... CC_OP_DECQ:
898 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
891 - .no_setcond = true };
899 + .rhs_type = CC_PREPARE_DIRECT };
900
901 case CC_OP_SHLB ... CC_OP_SHLQ:
902 /* (CC_SRC >> (DATA_BITS - 1)) & 1 */
@@ -913,7 +921,7 @@ static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
921 case CC_OP_ADCX:
922 case CC_OP_ADCOX:
923 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_dst,
916 - .no_setcond = true };
924 + .rhs_type = CC_PREPARE_DIRECT };
925
926 case CC_OP_EFLAGS:
927 case CC_OP_SARB ... CC_OP_SARQ:
@@ -931,7 +939,7 @@ static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
939 gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src,
940 cpu_cc_src2, cpu_cc_op);
941 return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
934 - .no_setcond = true };
942 + .rhs_type = CC_PREPARE_DIRECT };
943 }
944 }
945
@@ -970,7 +978,7 @@ static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
978 case CC_OP_ADOX:
979 case CC_OP_ADCOX:
980 return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src2,
973 - .no_setcond = true };
981 + .rhs_type = CC_PREPARE_DIRECT };
982 case CC_OP_SBB_SELF:
983 case CC_OP_LOGICB ... CC_OP_LOGICQ:
984 case CC_OP_POPCNT:
@@ -1032,7 +1040,7 @@ static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
1040 tcg_gen_ext_tl(s->cc_srcT, s->cc_srcT, size);
1041 tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size);
1042 cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = s->cc_srcT,
1035 - .reg2 = cpu_cc_src, .use_reg2 = true };
1043 + .reg2 = cpu_cc_src, .rhs_type = CC_PREPARE_REG };
1044 break;
1045 case JCC_L:
1046 cond = TCG_COND_LT;
@@ -1043,7 +1051,7 @@ static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
1051 tcg_gen_ext_tl(s->cc_srcT, s->cc_srcT, size | MO_SIGN);
1052 tcg_gen_ext_tl(cpu_cc_src, cpu_cc_src, size | MO_SIGN);
1053 cc = (CCPrepare) { .cond = cond, .reg = s->cc_srcT,
1046 - .reg2 = cpu_cc_src, .use_reg2 = true };
1054 + .reg2 = cpu_cc_src, .rhs_type = CC_PREPARE_REG };
1055 break;
1056
1057 default:
@@ -1128,6 +1136,9 @@ static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
1136 break;
1137 }
1138
1139 + if (cc.rhs_type != CC_PREPARE_REG) {
1140 + cc.reg2 = tcg_constant_tl(cc.imm);
1141 + }
1142 if (inv) {
1143 cc.cond = tcg_invert_cond(cc.cond);
1144 }
@@ -1138,7 +1149,7 @@ static void gen_neg_setcc(DisasContext *s, int b, TCGv reg)
1149 {
1150 CCPrepare cc = gen_prepare_cc(s, b, reg);
1151
1141 - if (cc.no_setcond) {
1152 + if (cc.rhs_type == CC_PREPARE_DIRECT) {
1153 if (cc.cond == TCG_COND_EQ) {
1154 tcg_gen_addi_tl(reg, cc.reg, -1);
1155 } else {
@@ -1147,18 +1158,14 @@ static void gen_neg_setcc(DisasContext *s, int b, TCGv reg)
1158 return;
1159 }
1160
1150 - if (cc.use_reg2) {
1151 - tcg_gen_negsetcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1152 - } else {
1153 - tcg_gen_negsetcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1154 - }
1161 + tcg_gen_negsetcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1162 }
1163
1164 static void gen_setcc(DisasContext *s, int b, TCGv reg)
1165 {
1166 CCPrepare cc = gen_prepare_cc(s, b, reg);
1167
1161 - if (cc.no_setcond) {
1168 + if (cc.rhs_type == CC_PREPARE_DIRECT) {
1169 if (cc.cond == TCG_COND_EQ) {
1170 tcg_gen_xori_tl(reg, cc.reg, 1);
1171 } else {
@@ -1167,11 +1174,7 @@ static void gen_setcc(DisasContext *s, int b, TCGv reg)
1174 return;
1175 }
1176
1170 - if (cc.use_reg2) {
1171 - tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1172 - } else {
1173 - tcg_gen_setcondi_tl(cc.cond, reg, cc.reg, cc.imm);
1174 - }
1177 + tcg_gen_setcond_tl(cc.cond, reg, cc.reg, cc.reg2);
1178 }
1179
1180 static inline void gen_compute_eflags_c(DisasContext *s, TCGv reg)
@@ -1185,11 +1188,7 @@ static inline void gen_jcc_noeob(DisasContext *s, int b, TCGLabel *l1)
1188 {
1189 CCPrepare cc = gen_prepare_cc(s, b, NULL);
1190
1188 - if (cc.use_reg2) {
1189 - tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1190 - } else {
1191 - tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1192 - }
1191 + tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1192 }
1193
1194 /* Generate a conditional jump to label 'l1' according to jump opcode
@@ -1206,11 +1205,7 @@ static inline void gen_jcc(DisasContext *s, int b, TCGLabel *l1)
1205 * it's cheaper to just compute the flags)!
1206 */
1207 gen_update_cc_op(s);
1209 - if (cc.use_reg2) {
1210 - tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1211 - } else {
1212 - tcg_gen_brcondi_tl(cc.cond, cc.reg, cc.imm, l1);
1213 - }
1208 + tcg_gen_brcond_tl(cc.cond, cc.reg, cc.reg2, l1);
1209 }
1210
1211 static void gen_stos(DisasContext *s, MemOp ot, TCGv dshift)
@@ -1717,10 +1712,6 @@ static void gen_cmovcc(DisasContext *s, int b, TCGv dest, TCGv src)
1712 {
1713 CCPrepare cc = gen_prepare_cc(s, b, NULL);
1714
1720 - if (!cc.use_reg2) {
1721 - cc.reg2 = tcg_constant_tl(cc.imm);
1722 - }
1723 -
1715 tcg_gen_movcond_tl(cc.cond, dest, cc.reg, cc.reg2, src, dest);
1716 }
1717