diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2024-03-26 14:48:36 -1000 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2024-05-06 12:55:50 -0700 |
commit | 19517b8397940955c2638700f9cad3dbdb90c4c0 (patch) | |
tree | 1458346f6ed34086124029e7af12be35ffd2fefb /tcg | |
parent | 2623ca6ac11dd1c15ec1c2e87aa2e7f22f0adec8 (diff) |
tcg/i386: Optimize setcond of TST{EQ,NE} with 0xffffffff
This may be treated as a 32-bit EQ/NE comparison against 0,
which is in turn treated as a LTU/GEU comparison against 1.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg')
-rw-r--r-- | tcg/i386/tcg-target.c.inc | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index 6837c519b0..59235b4f38 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1658,6 +1658,7 @@ static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond, TCGArg dest, TCGArg arg1, TCGArg arg2, int const_arg2, bool neg) { + int cmp_rexw = rexw; bool inv = false; bool cleared; int jcc; @@ -1674,6 +1675,18 @@ static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond, } break; + case TCG_COND_TSTNE: + inv = true; + /* fall through */ + case TCG_COND_TSTEQ: + /* If arg2 is -1, convert to LTU/GEU vs 1. */ + if (const_arg2 && arg2 == 0xffffffffu) { + arg2 = 1; + cmp_rexw = 0; + goto do_ltu; + } + break; + case TCG_COND_LEU: inv = true; /* fall through */ @@ -1697,7 +1710,7 @@ static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond, * We can then use NEG or INC to produce the desired result. * This is always smaller than the SETCC expansion. */ - tcg_out_cmp(s, TCG_COND_LTU, arg1, arg2, const_arg2, rexw); + tcg_out_cmp(s, TCG_COND_LTU, arg1, arg2, const_arg2, cmp_rexw); /* X - X - C = -C = (C ? -1 : 0) */ tgen_arithr(s, ARITH_SBB + (neg ? rexw : 0), dest, dest); @@ -1744,7 +1757,7 @@ static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond, cleared = true; } - jcc = tcg_out_cmp(s, cond, arg1, arg2, const_arg2, rexw); + jcc = tcg_out_cmp(s, cond, arg1, arg2, const_arg2, cmp_rexw); tcg_out_modrm(s, OPC_SETCC | jcc, 0, dest); if (!cleared) { |