target/i386: use TSTEQ/TSTNE to check flags

The new conditions obviously come in handy when testing individual bits
of EFLAGS, and they make it possible to remove the .mask field of
CCPrepare.

Lowering to shift+and is done by the optimizer if necessary.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2023-10-27 04:17:09 +02:00
parent 15957eb9ef
commit 9309b53e83

View file

@ -996,8 +996,8 @@ static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
case CC_OP_EFLAGS:
case CC_OP_SARB ... CC_OP_SARQ:
/* CC_SRC & 1 */
return (CCPrepare) { .cond = TCG_COND_NE,
.reg = cpu_cc_src, .mask = CC_C };
return (CCPrepare) { .cond = TCG_COND_TSTNE,
.reg = cpu_cc_src, .mask = -1, .imm = CC_C };
default:
/* The need to compute only C from CC_OP_DYNAMIC is important
@ -1014,8 +1014,8 @@ static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
static CCPrepare gen_prepare_eflags_p(DisasContext *s, TCGv reg)
{
gen_compute_eflags(s);
return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
.mask = CC_P };
return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src,
.mask = -1, .imm = CC_P };
}
/* compute eflags.S to reg */
@ -1029,8 +1029,8 @@ static CCPrepare gen_prepare_eflags_s(DisasContext *s, TCGv reg)
case CC_OP_ADCX:
case CC_OP_ADOX:
case CC_OP_ADCOX:
return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
.mask = CC_S };
return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src,
.mask = -1, .imm = CC_S };
case CC_OP_CLR:
case CC_OP_POPCNT:
return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };
@ -1058,8 +1058,8 @@ static CCPrepare gen_prepare_eflags_o(DisasContext *s, TCGv reg)
.reg = cpu_cc_src, .mask = -1 };
default:
gen_compute_eflags(s);
return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
.mask = CC_O };
return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src,
.mask = -1, .imm = CC_O };
}
}
@ -1074,8 +1074,8 @@ static CCPrepare gen_prepare_eflags_z(DisasContext *s, TCGv reg)
case CC_OP_ADCX:
case CC_OP_ADOX:
case CC_OP_ADCOX:
return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
.mask = CC_Z };
return (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src,
.mask = -1, .imm = CC_Z };
case CC_OP_CLR:
return (CCPrepare) { .cond = TCG_COND_ALWAYS, .mask = -1 };
case CC_OP_POPCNT:
@ -1153,8 +1153,8 @@ static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
break;
case JCC_BE:
gen_compute_eflags(s);
cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,
.mask = CC_Z | CC_C };
cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = cpu_cc_src,
.mask = -1, .imm = CC_Z | CC_C };
break;
case JCC_S:
cc = gen_prepare_eflags_s(s, reg);
@ -1168,8 +1168,8 @@ static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
reg = s->tmp0;
}
tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S);
cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
.mask = CC_O };
cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg,
.mask = -1, .imm = CC_O };
break;
default:
case JCC_LE:
@ -1178,8 +1178,8 @@ static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
reg = s->tmp0;
}
tcg_gen_addi_tl(reg, cpu_cc_src, CC_O - CC_S);
cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
.mask = CC_O | CC_Z };
cc = (CCPrepare) { .cond = TCG_COND_TSTNE, .reg = reg,
.mask = -1, .imm = CC_O | CC_Z };
break;
}
break;