[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 35/48] tcg/i386: Use CMP+SBB in tcg_out_setcond
From: |
Richard Henderson |
Subject: |
[PULL 35/48] tcg/i386: Use CMP+SBB in tcg_out_setcond |
Date: |
Wed, 23 Aug 2023 13:23:13 -0700 |
Use the carry bit to optimize some forms of setcond.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/i386/tcg-target.c.inc | 50 +++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index 1542afd94d..4d7b745a52 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -1531,6 +1531,56 @@ static void tcg_out_setcond(TCGContext *s, int rexw,
TCGCond cond,
TCGArg dest, TCGArg arg1, TCGArg arg2,
int const_arg2)
{
+ bool inv = false;
+
+ switch (cond) {
+ case TCG_COND_NE:
+ inv = true;
+ /* fall through */
+ case TCG_COND_EQ:
+ /* If arg2 is 0, convert to LTU/GEU vs 1. */
+ if (const_arg2 && arg2 == 0) {
+ arg2 = 1;
+ goto do_ltu;
+ }
+ break;
+
+ case TCG_COND_LEU:
+ inv = true;
+ /* fall through */
+ case TCG_COND_GTU:
+ /* If arg2 is a register, swap for LTU/GEU. */
+ if (!const_arg2) {
+ TCGReg t = arg1;
+ arg1 = arg2;
+ arg2 = t;
+ goto do_ltu;
+ }
+ break;
+
+ case TCG_COND_GEU:
+ inv = true;
+ /* fall through */
+ case TCG_COND_LTU:
+ do_ltu:
+ /*
+ * Relying on the carry bit, use SBB to produce -1 if LTU, 0 if GEU.
+ * We can then use NEG or INC to produce the desired result.
+ * This is always smaller than the SETCC expansion.
+ */
+ tcg_out_cmp(s, arg1, arg2, const_arg2, rexw);
+ tgen_arithr(s, ARITH_SBB, dest, dest); /* T:-1 F:0 */
+ if (inv) {
+ tgen_arithi(s, ARITH_ADD, dest, 1, 0); /* T:0 F:1 */
+ } else {
+ tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_NEG, dest); /* T:1 F:0 */
+ }
+ return;
+
+ default:
+ break;
+ }
+
tcg_out_cmp(s, arg1, arg2, const_arg2, rexw);
tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
tcg_out_ext8u(s, dest, dest);
--
2.34.1
- [PULL 05/48] include/exec: Replace target_ulong with abi_ptr in cpu_[st|ld]*(), (continued)
- [PULL 05/48] include/exec: Replace target_ulong with abi_ptr in cpu_[st|ld]*(), Richard Henderson, 2023/08/23
- [PULL 34/48] tcg/i386: Merge tcg_out_movcond{32,64}, Richard Henderson, 2023/08/23
- [PULL 39/48] tcg/tcg-op: Document bswap16_i32() byte pattern, Richard Henderson, 2023/08/23
- [PULL 06/48] include/exec: typedef abi_ptr to vaddr in softmmu, Richard Henderson, 2023/08/23
- [PULL 01/48] accel/kvm: Widen pc/saved_insn for kvm_sw_breakpoint, Richard Henderson, 2023/08/23
- [PULL 32/48] tcg/i386: Merge tcg_out_brcond{32,64}, Richard Henderson, 2023/08/23
- [PULL 27/48] tcg/aarch64: Implement negsetcond_*, Richard Henderson, 2023/08/23
- [PULL 24/48] target/tricore: Replace gen_cond_w with tcg_gen_negsetcond_tl, Richard Henderson, 2023/08/23
- [PULL 31/48] tcg/sparc64: Implement negsetcond_*, Richard Henderson, 2023/08/23
- [PULL 33/48] tcg/i386: Merge tcg_out_setcond{32,64}, Richard Henderson, 2023/08/23
- [PULL 35/48] tcg/i386: Use CMP+SBB in tcg_out_setcond,
Richard Henderson <=
- [PULL 20/48] target/m68k: Use tcg_gen_negsetcond_*, Richard Henderson, 2023/08/23
- [PULL 19/48] target/arm: Use tcg_gen_negsetcond_*, Richard Henderson, 2023/08/23
- [PULL 37/48] tcg/i386: Use shift in tcg_out_setcond, Richard Henderson, 2023/08/23
- [PULL 36/48] tcg/i386: Clear dest first in tcg_out_setcond if possible, Richard Henderson, 2023/08/23
- [PULL 13/48] tcg/i386: Allow immediate as input to deposit_*, Richard Henderson, 2023/08/23
- [PULL 14/48] docs/devel/tcg-ops: Bury mentions of trunc_shr_i64_i32(), Richard Henderson, 2023/08/23
- [PULL 07/48] include/exec: Widen tlb_hit/tlb_hit_page(), Richard Henderson, 2023/08/23
- [PULL 09/48] accel/tcg: Update run_on_cpu_data static assert, Richard Henderson, 2023/08/23
- [PULL 15/48] tcg: Unify TCG_TARGET_HAS_extr[lh]_i64_i32, Richard Henderson, 2023/08/23
- [PULL 23/48] target/sparc: Use tcg_gen_movcond_i64 in gen_edge, Richard Henderson, 2023/08/23