aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2024-06-20 11:31:33 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2024-10-31 18:28:33 +0100
commit37df7c4d577124e01f087f598842b253aa2c9eca (patch)
treee903506b7a1d7800983ffdc82fa30c2fd4d8c5f2 /target
parentae14b33de8d329d5497db5446bdc0b0cb6ba756b (diff)
target/i386: optimize TEST+Jxx sequences
Mostly used for TEST+JG and TEST+JLE, but it is easy to cover also JBE/JA and JL/JGE; shaves about 0.5% TCG ops. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target')
-rw-r--r--target/i386/tcg/translate.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 5e326ab1af..d3bbcf7317 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -1069,6 +1069,28 @@ static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)
}
break;
+ case CC_OP_LOGICB ... CC_OP_LOGICQ:
+ /* Mostly used for test+jump */
+ size = s->cc_op - CC_OP_LOGICB;
+ switch (jcc_op) {
+ case JCC_BE:
+ /* CF = 0, becomes jz/je */
+ jcc_op = JCC_Z;
+ goto slow_jcc;
+ case JCC_L:
+ /* OF = 0, becomes js/jns */
+ jcc_op = JCC_S;
+ goto slow_jcc;
+ case JCC_LE:
+ /* SF or ZF, becomes signed <= 0 */
+ tcg_gen_ext_tl(cpu_cc_dst, cpu_cc_dst, size | MO_SIGN);
+ cc = (CCPrepare) { .cond = TCG_COND_LE, .reg = cpu_cc_dst };
+ break;
+ default:
+ goto slow_jcc;
+ }
+ break;
+
default:
slow_jcc:
/* This actually generates good code for JC, JZ and JS. */