All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE}
@ 2023-10-28 19:44 Richard Henderson
  2023-10-28 19:44 ` [PATCH v2 01/35] " Richard Henderson
                   ` (36 more replies)
  0 siblings, 37 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Expose a pair of comparison operators that map to the "test"
comparison that is available on many architectures.

Changes for v2:
  * Add TCGCond to tcg_target_const_match.
    This fixes a long-standing issue with ppc and s390x backends,
    in that CMPI for signed comparisons has signed immediate and
    CMPLI for unsigned comparisons has unsigned immediate.
    But now allows different immediates for the TST comparisons.
  * tcg/i386: Generate TEST x,x for power-of-two in {7,15,31,63}.
  * tcg/i386: Generate BT n,x for other power-of-two.
  * tcg/ppc: tcg_target_const_match improvements
  * tcg/s390x: tcg_target_const_match improvements
  * target/m68k: Use TST{EQ,NE} for gen_fcc_cond.

I wanted more testing, so I went looking for low-hanging fruit.
I didn't see any within target/arm, probably due to how we represent NZCV,
and I didn't want to overlap anything that Paolo might be doing with
target/i386, so I landed on trget/m68k.  Tested via our float_convd.


r~


Richard Henderson (35):
  tcg: Introduce TCG_COND_TST{EQ,NE}
  tcg/optimize: Split out arg_is_const_val
  tcg/optimize: Split out do_constant_folding_cond1
  tcg/optimize: Do swap_commutative2 in do_constant_folding_cond2
  tcg/optimize: Split out arg_new_constant
  tcg/optimize: Handle TCG_COND_TST{EQ,NE}
  tcg: Add TCGConst argument to tcg_target_const_match
  tcg/aarch64: Support TCG_COND_TST{EQ,NE}
  tcg/aarch64: Generate TBZ, TBNZ
  tcg/aarch64: Generate CBNZ for TSTNE of UINT32_MAX
  tcg/arm: Support TCG_COND_TST{EQ,NE}
  tcg/i386: Pass x86 condition codes to tcg_out_cmov
  tcg/i386: Move tcg_cond_to_jcc[] into tcg_out_cmp
  tcg/i386: Support TCG_COND_TST{EQ,NE}
  tcg/i386: Improve TSTNE/TESTEQ vs powers of two
  tcg/loongarch64: Support TCG_COND_TST{EQ,NE}
  tcg/mips: Support TCG_COND_TST{EQ,NE}
  tcg/riscv: Support TCG_COND_TST{EQ,NE}
  tcg/sparc64: Implement tcg_out_extrl_i64_i32
  tcg/sparc64: Hoist read of tcg_cond_to_rcond
  tcg/sparc64: Pass TCGCond to tcg_out_cmp
  tcg/sparc64: Support TCG_COND_TST{EQ,NE}
  tcg/ppc: Sink tcg_to_bc usage into tcg_out_bc
  tcg/ppc: Use cr0 in tcg_to_bc and tcg_to_isel
  tcg/ppc: Tidy up tcg_target_const_match
  tcg/ppc: Add TCG_CT_CONST_CMP
  tcg/ppc: Support TCG_COND_TST{EQ,NE}
  tcg/s390x: Split constraint A into J+U
  tcg/s390x: Add TCG_CT_CONST_CMP
  tcg/s390x: Support TCG_COND_TST{EQ,NE}
  tcg/tci: Support TCG_COND_TST{EQ,NE}
  target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S}
  target/alpha: Use TCG_COND_TST{EQ,NE} for CMOVLB{C,S}
  target/alpha: Use TCG_COND_TSTNE for gen_fold_mzero
  target/m68k: Use TCG_COND_TST{EQ,NE} in gen_fcc_cond

 docs/devel/tcg-ops.rst           |   2 +
 include/tcg/tcg-cond.h           |  49 +++-
 tcg/aarch64/tcg-target-con-set.h |   5 +-
 tcg/aarch64/tcg-target-con-str.h |   1 +
 tcg/i386/tcg-target-con-set.h    |   6 +-
 tcg/i386/tcg-target-con-str.h    |   1 +
 tcg/ppc/tcg-target-con-set.h     |   5 +-
 tcg/ppc/tcg-target-con-str.h     |   1 +
 tcg/s390x/tcg-target-con-set.h   |   8 +-
 tcg/s390x/tcg-target-con-str.h   |   3 +-
 target/alpha/translate.c         |  94 +++----
 target/m68k/translate.c          |  74 +++--
 tcg/optimize.c                   | 464 +++++++++++++++++++++++--------
 tcg/tcg.c                        |  38 ++-
 tcg/tci.c                        |  14 +
 tcg/aarch64/tcg-target.c.inc     | 165 ++++++++---
 tcg/arm/tcg-target.c.inc         |  62 +++--
 tcg/i386/tcg-target.c.inc        | 178 ++++++++----
 tcg/loongarch64/tcg-target.c.inc |  59 ++--
 tcg/mips/tcg-target.c.inc        |  44 ++-
 tcg/ppc/tcg-target.c.inc         | 277 +++++++++++++-----
 tcg/riscv/tcg-target.c.inc       |  23 +-
 tcg/s390x/tcg-target.c.inc       | 246 ++++++++++------
 tcg/sparc64/tcg-target.c.inc     |  70 +++--
 tcg/tci/tcg-target.c.inc         |   3 +-
 25 files changed, 1342 insertions(+), 550 deletions(-)

-- 
2.34.1



^ permalink raw reply	[flat|nested] 78+ messages in thread

* [PATCH v2 01/35] tcg: Introduce TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-11-06 15:26   ` Philippe Mathieu-Daudé
  2023-10-28 19:44 ` [PATCH v2 02/35] tcg/optimize: Split out arg_is_const_val Richard Henderson
                   ` (35 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Add the enumerators, adjust the helpers to match, and dump.
Not supported anywhere else just yet.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 docs/devel/tcg-ops.rst |  2 ++
 include/tcg/tcg-cond.h | 49 ++++++++++++++++++++++++++++++++----------
 tcg/tcg.c              |  4 +++-
 3 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/docs/devel/tcg-ops.rst b/docs/devel/tcg-ops.rst
index 8ae59ea02b..d46b625e0e 100644
--- a/docs/devel/tcg-ops.rst
+++ b/docs/devel/tcg-ops.rst
@@ -253,6 +253,8 @@ Jumps/Labels
        |   ``TCG_COND_GEU /* unsigned */``
        |   ``TCG_COND_LEU /* unsigned */``
        |   ``TCG_COND_GTU /* unsigned */``
+       |   ``TCG_COND_TSTEQ /* t1 & t2 == 0 */``
+       |   ``TCG_COND_TSTNE /* t1 & t2 != 0 */``
 
 Arithmetic
 ----------
diff --git a/include/tcg/tcg-cond.h b/include/tcg/tcg-cond.h
index 2a38a386d4..bf3fcf5968 100644
--- a/include/tcg/tcg-cond.h
+++ b/include/tcg/tcg-cond.h
@@ -49,6 +49,9 @@ typedef enum {
     TCG_COND_GEU    = 0 | 4 | 0 | 1,
     TCG_COND_LEU    = 8 | 4 | 0 | 0,
     TCG_COND_GTU    = 8 | 4 | 0 | 1,
+    /* "test" i.e. and then compare vs 0 */
+    TCG_COND_TSTEQ  = 8 | 4 | 2 | 0,
+    TCG_COND_TSTNE  = 8 | 4 | 2 | 1,
 } TCGCond;
 
 /* Invert the sense of the comparison.  */
@@ -60,25 +63,49 @@ static inline TCGCond tcg_invert_cond(TCGCond c)
 /* Swap the operands in a comparison.  */
 static inline TCGCond tcg_swap_cond(TCGCond c)
 {
-    return c & 6 ? (TCGCond)(c ^ 9) : c;
+    return (c + 2) & 4 ? (TCGCond)(c ^ 9) : c;
 }
 
-/* Create an "unsigned" version of a "signed" comparison.  */
-static inline TCGCond tcg_unsigned_cond(TCGCond c)
+/* Must a comparison be considered signed?  */
+static inline bool is_signed_cond(TCGCond c)
 {
-    return c & 2 ? (TCGCond)(c ^ 6) : c;
-}
-
-/* Create a "signed" version of an "unsigned" comparison.  */
-static inline TCGCond tcg_signed_cond(TCGCond c)
-{
-    return c & 4 ? (TCGCond)(c ^ 6) : c;
+    return (c & 6) == 2;
 }
 
 /* Must a comparison be considered unsigned?  */
 static inline bool is_unsigned_cond(TCGCond c)
 {
-    return (c & 4) != 0;
+    return (c & 6) == 4;
+}
+
+/* Must a comparison be considered a test?  */
+static inline bool is_tst_cond(TCGCond c)
+{
+    return (c | 1) == 0xf;
+}
+
+/* Create an "unsigned" version of a "signed" comparison.  */
+static inline TCGCond tcg_unsigned_cond(TCGCond c)
+{
+    return is_signed_cond(c) ? (TCGCond)(c ^ 6) : c;
+}
+
+/* Create a "signed" version of an "unsigned" comparison.  */
+static inline TCGCond tcg_signed_cond(TCGCond c)
+{
+    return is_unsigned_cond(c) ? (TCGCond)(c ^ 6) : c;
+}
+
+/* Create the eq/ne version of a tsteq/tstne comparison.  */
+static inline TCGCond tcg_tst_eqne_cond(TCGCond c)
+{
+    return is_tst_cond(c) ? (TCGCond)(c ^ 6) : c;
+}
+
+/* Create the lt/ge version of a tstne/tsteq comparison of the sign.  */
+static inline TCGCond tcg_tst_ltge_cond(TCGCond c)
+{
+    return is_tst_cond(c) ? (TCGCond)(c ^ (8 | 4 | 1)) : c;
 }
 
 /*
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 35158a0846..57d0583fe7 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2378,7 +2378,9 @@ static const char * const cond_name[] =
     [TCG_COND_LTU] = "ltu",
     [TCG_COND_GEU] = "geu",
     [TCG_COND_LEU] = "leu",
-    [TCG_COND_GTU] = "gtu"
+    [TCG_COND_GTU] = "gtu",
+    [TCG_COND_TSTEQ] = "tsteq",
+    [TCG_COND_TSTNE] = "tstne",
 };
 
 static const char * const ldst_name[(MO_BSWAP | MO_SSIZE) + 1] =
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 02/35] tcg/optimize: Split out arg_is_const_val
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
  2023-10-28 19:44 ` [PATCH v2 01/35] " Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-11-06 15:28   ` Philippe Mathieu-Daudé
  2023-10-28 19:44 ` [PATCH v2 03/35] tcg/optimize: Split out do_constant_folding_cond1 Richard Henderson
                   ` (34 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/optimize.c | 38 +++++++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 2db5177c32..e8a13fedb5 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -112,11 +112,22 @@ static inline bool ts_is_const(TCGTemp *ts)
     return ts_info(ts)->is_const;
 }
 
+static inline bool ts_is_const_val(TCGTemp *ts, uint64_t val)
+{
+    TempOptInfo *ti = ts_info(ts);
+    return ti->is_const && ti->val == val;
+}
+
 static inline bool arg_is_const(TCGArg arg)
 {
     return ts_is_const(arg_temp(arg));
 }
 
+static inline bool arg_is_const_val(TCGArg arg, uint64_t val)
+{
+    return ts_is_const_val(arg_temp(arg), val);
+}
+
 static inline bool ts_is_copy(TCGTemp *ts)
 {
     return ts_info(ts)->next_copy != ts;
@@ -565,7 +576,7 @@ static int do_constant_folding_cond(TCGType type, TCGArg x,
         }
     } else if (args_are_copies(x, y)) {
         return do_constant_folding_cond_eq(c);
-    } else if (arg_is_const(y) && arg_info(y)->val == 0) {
+    } else if (arg_is_const_val(y, 0)) {
         switch (c) {
         case TCG_COND_LTU:
             return 0;
@@ -831,7 +842,7 @@ static bool fold_to_not(OptContext *ctx, TCGOp *op, int idx)
 /* If the binary operation has first argument @i, fold to @i. */
 static bool fold_ix_to_i(OptContext *ctx, TCGOp *op, uint64_t i)
 {
-    if (arg_is_const(op->args[1]) && arg_info(op->args[1])->val == i) {
+    if (arg_is_const_val(op->args[1], i)) {
         return tcg_opt_gen_movi(ctx, op, op->args[0], i);
     }
     return false;
@@ -840,7 +851,7 @@ static bool fold_ix_to_i(OptContext *ctx, TCGOp *op, uint64_t i)
 /* If the binary operation has first argument @i, fold to NOT. */
 static bool fold_ix_to_not(OptContext *ctx, TCGOp *op, uint64_t i)
 {
-    if (arg_is_const(op->args[1]) && arg_info(op->args[1])->val == i) {
+    if (arg_is_const_val(op->args[1], i)) {
         return fold_to_not(ctx, op, 2);
     }
     return false;
@@ -849,7 +860,7 @@ static bool fold_ix_to_not(OptContext *ctx, TCGOp *op, uint64_t i)
 /* If the binary operation has second argument @i, fold to @i. */
 static bool fold_xi_to_i(OptContext *ctx, TCGOp *op, uint64_t i)
 {
-    if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == i) {
+    if (arg_is_const_val(op->args[2], i)) {
         return tcg_opt_gen_movi(ctx, op, op->args[0], i);
     }
     return false;
@@ -858,7 +869,7 @@ static bool fold_xi_to_i(OptContext *ctx, TCGOp *op, uint64_t i)
 /* If the binary operation has second argument @i, fold to identity. */
 static bool fold_xi_to_x(OptContext *ctx, TCGOp *op, uint64_t i)
 {
-    if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == i) {
+    if (arg_is_const_val(op->args[2], i)) {
         return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[1]);
     }
     return false;
@@ -867,7 +878,7 @@ static bool fold_xi_to_x(OptContext *ctx, TCGOp *op, uint64_t i)
 /* If the binary operation has second argument @i, fold to NOT. */
 static bool fold_xi_to_not(OptContext *ctx, TCGOp *op, uint64_t i)
 {
-    if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == i) {
+    if (arg_is_const_val(op->args[2], i)) {
         return fold_to_not(ctx, op, 1);
     }
     return false;
@@ -1083,8 +1094,8 @@ static bool fold_brcond2(OptContext *ctx, TCGOp *op)
          * Simplify LT/GE comparisons vs zero to a single compare
          * vs the high word of the input.
          */
-        if (arg_is_const(op->args[2]) && arg_info(op->args[2])->val == 0 &&
-            arg_is_const(op->args[3]) && arg_info(op->args[3])->val == 0) {
+        if (arg_is_const_val(op->args[2], 0) &&
+            arg_is_const_val(op->args[3], 0)) {
             goto do_brcond_high;
         }
         break;
@@ -1303,9 +1314,7 @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
     }
 
     /* Inserting a value into zero at offset 0. */
-    if (arg_is_const(op->args[1])
-        && arg_info(op->args[1])->val == 0
-        && op->args[3] == 0) {
+    if (arg_is_const_val(op->args[1], 0) && op->args[3] == 0) {
         uint64_t mask = MAKE_64BIT_MASK(0, op->args[4]);
 
         op->opc = and_opc;
@@ -1316,8 +1325,7 @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
     }
 
     /* Inserting zero into a value. */
-    if (arg_is_const(op->args[2])
-        && arg_info(op->args[2])->val == 0) {
+    if (arg_is_const_val(op->args[2], 0)) {
         uint64_t mask = deposit64(-1, op->args[3], op->args[4], 0);
 
         op->opc = and_opc;
@@ -1855,8 +1863,8 @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
          * Simplify LT/GE comparisons vs zero to a single compare
          * vs the high word of the input.
          */
-        if (arg_is_const(op->args[3]) && arg_info(op->args[3])->val == 0 &&
-            arg_is_const(op->args[4]) && arg_info(op->args[4])->val == 0) {
+        if (arg_is_const_val(op->args[3], 0) &&
+            arg_is_const_val(op->args[4], 0)) {
             goto do_setcond_high;
         }
         break;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 03/35] tcg/optimize: Split out do_constant_folding_cond1
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
  2023-10-28 19:44 ` [PATCH v2 01/35] " Richard Henderson
  2023-10-28 19:44 ` [PATCH v2 02/35] tcg/optimize: Split out arg_is_const_val Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-11-06 15:33   ` Philippe Mathieu-Daudé
  2023-10-28 19:44 ` [PATCH v2 04/35] tcg/optimize: Do swap_commutative2 in do_constant_folding_cond2 Richard Henderson
                   ` (33 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Handle modifications to the arguments and condition
in a single place.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/optimize.c | 57 ++++++++++++++++++++++++--------------------------
 1 file changed, 27 insertions(+), 30 deletions(-)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index e8a13fedb5..89cc794d24 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -672,6 +672,23 @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
     return false;
 }
 
+static int do_constant_folding_cond1(OptContext *ctx, TCGArg dest,
+                                     TCGArg *p1, TCGArg *p2, TCGArg *pcond)
+{
+    TCGCond cond;
+    bool swap;
+    int r;
+
+    swap = swap_commutative(dest, p1, p2);
+    cond = *pcond;
+    if (swap) {
+        *pcond = cond = tcg_swap_cond(cond);
+    }
+
+    r = do_constant_folding_cond(ctx->type, *p1, *p2, cond);
+    return r;
+}
+
 static void init_arguments(OptContext *ctx, TCGOp *op, int nb_args)
 {
     for (int i = 0; i < nb_args; i++) {
@@ -1053,14 +1070,8 @@ static bool fold_andc(OptContext *ctx, TCGOp *op)
 
 static bool fold_brcond(OptContext *ctx, TCGOp *op)
 {
-    TCGCond cond = op->args[2];
-    int i;
-
-    if (swap_commutative(NO_DEST, &op->args[0], &op->args[1])) {
-        op->args[2] = cond = tcg_swap_cond(cond);
-    }
-
-    i = do_constant_folding_cond(ctx->type, op->args[0], op->args[1], cond);
+    int i = do_constant_folding_cond1(ctx, NO_DEST, &op->args[0],
+                                      &op->args[1], &op->args[2]);
     if (i == 0) {
         tcg_op_remove(ctx->tcg, op);
         return true;
@@ -1550,21 +1561,18 @@ static bool fold_mov(OptContext *ctx, TCGOp *op)
 
 static bool fold_movcond(OptContext *ctx, TCGOp *op)
 {
-    TCGCond cond = op->args[5];
     int i;
 
-    if (swap_commutative(NO_DEST, &op->args[1], &op->args[2])) {
-        op->args[5] = cond = tcg_swap_cond(cond);
-    }
     /*
      * Canonicalize the "false" input reg to match the destination reg so
      * that the tcg backend can implement a "move if true" operation.
      */
     if (swap_commutative(op->args[0], &op->args[4], &op->args[3])) {
-        op->args[5] = cond = tcg_invert_cond(cond);
+        op->args[5] = tcg_invert_cond(op->args[5]);
     }
 
-    i = do_constant_folding_cond(ctx->type, op->args[1], op->args[2], cond);
+    i = do_constant_folding_cond1(ctx, NO_DEST, &op->args[1],
+                                  &op->args[2], &op->args[5]);
     if (i >= 0) {
         return tcg_opt_gen_mov(ctx, op, op->args[0], op->args[4 - i]);
     }
@@ -1578,6 +1586,7 @@ static bool fold_movcond(OptContext *ctx, TCGOp *op)
         uint64_t tv = arg_info(op->args[3])->val;
         uint64_t fv = arg_info(op->args[4])->val;
         TCGOpcode opc, negopc = 0;
+        TCGCond cond = op->args[5];
 
         switch (ctx->type) {
         case TCG_TYPE_I32:
@@ -1805,14 +1814,8 @@ static bool fold_remainder(OptContext *ctx, TCGOp *op)
 
 static bool fold_setcond(OptContext *ctx, TCGOp *op)
 {
-    TCGCond cond = op->args[3];
-    int i;
-
-    if (swap_commutative(op->args[0], &op->args[1], &op->args[2])) {
-        op->args[3] = cond = tcg_swap_cond(cond);
-    }
-
-    i = do_constant_folding_cond(ctx->type, op->args[1], op->args[2], cond);
+    int i = do_constant_folding_cond1(ctx, op->args[0], &op->args[1],
+                                      &op->args[2], &op->args[3]);
     if (i >= 0) {
         return tcg_opt_gen_movi(ctx, op, op->args[0], i);
     }
@@ -1824,14 +1827,8 @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
 
 static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
 {
-    TCGCond cond = op->args[3];
-    int i;
-
-    if (swap_commutative(op->args[0], &op->args[1], &op->args[2])) {
-        op->args[3] = cond = tcg_swap_cond(cond);
-    }
-
-    i = do_constant_folding_cond(ctx->type, op->args[1], op->args[2], cond);
+    int i = do_constant_folding_cond1(ctx, op->args[0], &op->args[1],
+                                      &op->args[2], &op->args[3]);
     if (i >= 0) {
         return tcg_opt_gen_movi(ctx, op, op->args[0], -i);
     }
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 04/35] tcg/optimize: Do swap_commutative2 in do_constant_folding_cond2
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (2 preceding siblings ...)
  2023-10-28 19:44 ` [PATCH v2 03/35] tcg/optimize: Split out do_constant_folding_cond1 Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-11-06 21:27   ` Philippe Mathieu-Daudé
  2023-10-28 19:44 ` [PATCH v2 05/35] tcg/optimize: Split out arg_new_constant Richard Henderson
                   ` (32 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Mirror the new do_constant_folding_cond1 by doing all
argument and condition adjustment within one helper.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/optimize.c | 107 ++++++++++++++++++++++++++-----------------------
 1 file changed, 57 insertions(+), 50 deletions(-)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 89cc794d24..76be0fc337 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -589,43 +589,6 @@ static int do_constant_folding_cond(TCGType type, TCGArg x,
     return -1;
 }
 
-/*
- * Return -1 if the condition can't be simplified,
- * and the result of the condition (0 or 1) if it can.
- */
-static int do_constant_folding_cond2(TCGArg *p1, TCGArg *p2, TCGCond c)
-{
-    TCGArg al = p1[0], ah = p1[1];
-    TCGArg bl = p2[0], bh = p2[1];
-
-    if (arg_is_const(bl) && arg_is_const(bh)) {
-        tcg_target_ulong blv = arg_info(bl)->val;
-        tcg_target_ulong bhv = arg_info(bh)->val;
-        uint64_t b = deposit64(blv, 32, 32, bhv);
-
-        if (arg_is_const(al) && arg_is_const(ah)) {
-            tcg_target_ulong alv = arg_info(al)->val;
-            tcg_target_ulong ahv = arg_info(ah)->val;
-            uint64_t a = deposit64(alv, 32, 32, ahv);
-            return do_constant_folding_cond_64(a, b, c);
-        }
-        if (b == 0) {
-            switch (c) {
-            case TCG_COND_LTU:
-                return 0;
-            case TCG_COND_GEU:
-                return 1;
-            default:
-                break;
-            }
-        }
-    }
-    if (args_are_copies(al, bl) && args_are_copies(ah, bh)) {
-        return do_constant_folding_cond_eq(c);
-    }
-    return -1;
-}
-
 /**
  * swap_commutative:
  * @dest: TCGArg of the destination argument, or NO_DEST.
@@ -672,6 +635,10 @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
     return false;
 }
 
+/*
+ * Return -1 if the condition can't be simplified,
+ * and the result of the condition (0 or 1) if it can.
+ */
 static int do_constant_folding_cond1(OptContext *ctx, TCGArg dest,
                                      TCGArg *p1, TCGArg *p2, TCGArg *pcond)
 {
@@ -689,6 +656,51 @@ static int do_constant_folding_cond1(OptContext *ctx, TCGArg dest,
     return r;
 }
 
+static int do_constant_folding_cond2(OptContext *ctx, TCGArg *args)
+{
+    TCGArg al, ah, bl, bh;
+    TCGCond c;
+    bool swap;
+
+    swap = swap_commutative2(args, args + 2);
+    c = args[4];
+    if (swap) {
+        args[4] = c = tcg_swap_cond(c);
+    }
+
+    al = args[0];
+    ah = args[1];
+    bl = args[2];
+    bh = args[3];
+
+    if (arg_is_const(bl) && arg_is_const(bh)) {
+        tcg_target_ulong blv = arg_info(bl)->val;
+        tcg_target_ulong bhv = arg_info(bh)->val;
+        uint64_t b = deposit64(blv, 32, 32, bhv);
+
+        if (arg_is_const(al) && arg_is_const(ah)) {
+            tcg_target_ulong alv = arg_info(al)->val;
+            tcg_target_ulong ahv = arg_info(ah)->val;
+            uint64_t a = deposit64(alv, 32, 32, ahv);
+            return do_constant_folding_cond_64(a, b, c);
+        }
+        if (b == 0) {
+            switch (c) {
+            case TCG_COND_LTU:
+                return 0;
+            case TCG_COND_GEU:
+                return 1;
+            default:
+                break;
+            }
+        }
+    }
+    if (args_are_copies(al, bl) && args_are_copies(ah, bh)) {
+        return do_constant_folding_cond_eq(c);
+    }
+    return -1;
+}
+
 static void init_arguments(OptContext *ctx, TCGOp *op, int nb_args)
 {
     for (int i = 0; i < nb_args; i++) {
@@ -1085,15 +1097,13 @@ static bool fold_brcond(OptContext *ctx, TCGOp *op)
 
 static bool fold_brcond2(OptContext *ctx, TCGOp *op)
 {
-    TCGCond cond = op->args[4];
-    TCGArg label = op->args[5];
+    TCGCond cond;
+    TCGArg label;
     int i, inv = 0;
 
-    if (swap_commutative2(&op->args[0], &op->args[2])) {
-        op->args[4] = cond = tcg_swap_cond(cond);
-    }
-
-    i = do_constant_folding_cond2(&op->args[0], &op->args[2], cond);
+    i = do_constant_folding_cond2(ctx, &op->args[0]);
+    cond = op->args[4];
+    label = op->args[5];
     if (i >= 0) {
         goto do_brcond_const;
     }
@@ -1841,14 +1851,11 @@ static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
 
 static bool fold_setcond2(OptContext *ctx, TCGOp *op)
 {
-    TCGCond cond = op->args[5];
+    TCGCond cond;
     int i, inv = 0;
 
-    if (swap_commutative2(&op->args[1], &op->args[3])) {
-        op->args[5] = cond = tcg_swap_cond(cond);
-    }
-
-    i = do_constant_folding_cond2(&op->args[1], &op->args[3], cond);
+    i = do_constant_folding_cond2(ctx, &op->args[1]);
+    cond = op->args[5];
     if (i >= 0) {
         goto do_setcond_const;
     }
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 05/35] tcg/optimize: Split out arg_new_constant
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (3 preceding siblings ...)
  2023-10-28 19:44 ` [PATCH v2 04/35] tcg/optimize: Do swap_commutative2 in do_constant_folding_cond2 Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-11-06 15:34   ` Philippe Mathieu-Daudé
  2023-10-28 19:44 ` [PATCH v2 06/35] tcg/optimize: Handle TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (31 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Fixes a bug wherein raw uses of tcg_constant_internal
do not have their TempOptInfo initialized.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/optimize.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 76be0fc337..2f2d1c3001 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -237,6 +237,21 @@ static bool args_are_copies(TCGArg arg1, TCGArg arg2)
     return ts_are_copies(arg_temp(arg1), arg_temp(arg2));
 }
 
+static TCGArg arg_new_constant(OptContext *ctx, uint64_t val)
+{
+    TCGType type = ctx->type;
+    TCGTemp *ts;
+
+    if (type == TCG_TYPE_I32) {
+        val = (int32_t)val;
+    }
+
+    ts = tcg_constant_internal(type, val);
+    init_ts_info(ctx, ts);
+
+    return temp_arg(ts);
+}
+
 static bool tcg_opt_gen_mov(OptContext *ctx, TCGOp *op, TCGArg dst, TCGArg src)
 {
     TCGTemp *dst_ts = arg_temp(dst);
@@ -293,16 +308,8 @@ static bool tcg_opt_gen_mov(OptContext *ctx, TCGOp *op, TCGArg dst, TCGArg src)
 static bool tcg_opt_gen_movi(OptContext *ctx, TCGOp *op,
                              TCGArg dst, uint64_t val)
 {
-    TCGTemp *tv;
-
-    if (ctx->type == TCG_TYPE_I32) {
-        val = (int32_t)val;
-    }
-
     /* Convert movi to mov with constant temp. */
-    tv = tcg_constant_internal(ctx->type, val);
-    init_ts_info(ctx, tv);
-    return tcg_opt_gen_mov(ctx, op, dst, temp_arg(tv));
+    return tcg_opt_gen_mov(ctx, op, dst, arg_new_constant(ctx, val));
 }
 
 static uint64_t do_constant_folding_2(TCGOpcode op, uint64_t x, uint64_t y)
@@ -1340,7 +1347,7 @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
 
         op->opc = and_opc;
         op->args[1] = op->args[2];
-        op->args[2] = temp_arg(tcg_constant_internal(ctx->type, mask));
+        op->args[2] = arg_new_constant(ctx, mask);
         ctx->z_mask = mask & arg_info(op->args[1])->z_mask;
         return false;
     }
@@ -1350,7 +1357,7 @@ static bool fold_deposit(OptContext *ctx, TCGOp *op)
         uint64_t mask = deposit64(-1, op->args[3], op->args[4], 0);
 
         op->opc = and_opc;
-        op->args[2] = temp_arg(tcg_constant_internal(ctx->type, mask));
+        op->args[2] = arg_new_constant(ctx, mask);
         ctx->z_mask = mask & arg_info(op->args[1])->z_mask;
         return false;
     }
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 06/35] tcg/optimize: Handle TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (4 preceding siblings ...)
  2023-10-28 19:44 ` [PATCH v2 05/35] tcg/optimize: Split out arg_new_constant Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-11-06 21:20   ` Philippe Mathieu-Daudé
  2023-10-28 19:44 ` [PATCH v2 07/35] tcg: Add TCGConst argument to tcg_target_const_match Richard Henderson
                   ` (30 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Fold constant comparisons.
Canonicalize "tst x,x" to equality vs zero.
Canonicalize "tst x,sign" to sign test vs zero.
Fold double-word comparisons with zero parts.
Fold setcond of "tst x,pow2" to a bit extract.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/optimize.c | 245 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 223 insertions(+), 22 deletions(-)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 2f2d1c3001..891c28acef 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -508,9 +508,15 @@ static bool do_constant_folding_cond_32(uint32_t x, uint32_t y, TCGCond c)
         return x <= y;
     case TCG_COND_GTU:
         return x > y;
-    default:
-        g_assert_not_reached();
+    case TCG_COND_TSTEQ:
+        return (x & y) == 0;
+    case TCG_COND_TSTNE:
+        return (x & y) != 0;
+    case TCG_COND_ALWAYS:
+    case TCG_COND_NEVER:
+        break;
     }
+    g_assert_not_reached();
 }
 
 static bool do_constant_folding_cond_64(uint64_t x, uint64_t y, TCGCond c)
@@ -536,12 +542,18 @@ static bool do_constant_folding_cond_64(uint64_t x, uint64_t y, TCGCond c)
         return x <= y;
     case TCG_COND_GTU:
         return x > y;
-    default:
-        g_assert_not_reached();
+    case TCG_COND_TSTEQ:
+        return (x & y) == 0;
+    case TCG_COND_TSTNE:
+        return (x & y) != 0;
+    case TCG_COND_ALWAYS:
+    case TCG_COND_NEVER:
+        break;
     }
+    g_assert_not_reached();
 }
 
-static bool do_constant_folding_cond_eq(TCGCond c)
+static int do_constant_folding_cond_eq(TCGCond c)
 {
     switch (c) {
     case TCG_COND_GT:
@@ -556,9 +568,14 @@ static bool do_constant_folding_cond_eq(TCGCond c)
     case TCG_COND_LEU:
     case TCG_COND_EQ:
         return 1;
-    default:
-        g_assert_not_reached();
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        return -1;
+    case TCG_COND_ALWAYS:
+    case TCG_COND_NEVER:
+        break;
     }
+    g_assert_not_reached();
 }
 
 /*
@@ -586,8 +603,10 @@ static int do_constant_folding_cond(TCGType type, TCGArg x,
     } else if (arg_is_const_val(y, 0)) {
         switch (c) {
         case TCG_COND_LTU:
+        case TCG_COND_TSTNE:
             return 0;
         case TCG_COND_GEU:
+        case TCG_COND_TSTEQ:
             return 1;
         default:
             return -1;
@@ -660,7 +679,30 @@ static int do_constant_folding_cond1(OptContext *ctx, TCGArg dest,
     }
 
     r = do_constant_folding_cond(ctx->type, *p1, *p2, cond);
-    return r;
+    if (r >= 0) {
+        return r;
+    }
+    if (!is_tst_cond(cond)) {
+        return -1;
+    }
+
+    /*
+     * TSTNE x,x -> NE x,0
+     * TSTNE x,-1 -> NE x,0
+     */
+    if (args_are_copies(*p1, *p2) || arg_is_const_val(*p2, -1)) {
+        *p2 = arg_new_constant(ctx, 0);
+        *pcond = tcg_tst_eqne_cond(cond);
+        return -1;
+    }
+
+    /* TSTNE x,sign -> LT x,0 */
+    if (arg_is_const_val(*p2, (ctx->type == TCG_TYPE_I32
+                               ? INT32_MIN : INT64_MIN))) {
+        *p2 = arg_new_constant(ctx, 0);
+        *pcond = tcg_tst_ltge_cond(cond);
+    }
+    return -1;
 }
 
 static int do_constant_folding_cond2(OptContext *ctx, TCGArg *args)
@@ -668,6 +710,7 @@ static int do_constant_folding_cond2(OptContext *ctx, TCGArg *args)
     TCGArg al, ah, bl, bh;
     TCGCond c;
     bool swap;
+    int r;
 
     swap = swap_commutative2(args, args + 2);
     c = args[4];
@@ -689,21 +732,54 @@ static int do_constant_folding_cond2(OptContext *ctx, TCGArg *args)
             tcg_target_ulong alv = arg_info(al)->val;
             tcg_target_ulong ahv = arg_info(ah)->val;
             uint64_t a = deposit64(alv, 32, 32, ahv);
-            return do_constant_folding_cond_64(a, b, c);
+
+            r = do_constant_folding_cond_64(a, b, c);
+            if (r >= 0) {
+                return r;
+            }
         }
+
         if (b == 0) {
             switch (c) {
             case TCG_COND_LTU:
+            case TCG_COND_TSTNE:
                 return 0;
             case TCG_COND_GEU:
+            case TCG_COND_TSTEQ:
                 return 1;
             default:
                 break;
             }
         }
+
+        /* TSTNE x,-1 -> NE x,0 */
+        if (b == -1 && is_tst_cond(c)) {
+            args[3] = args[2] = arg_new_constant(ctx, 0);
+            args[4] = tcg_tst_eqne_cond(c);
+            return -1;
+        }
+
+        /* TSTNE x,sign -> LT x,0 */
+        if (b == INT64_MIN && is_tst_cond(c)) {
+            /* bl must be 0, so copy that to bh */
+            args[3] = bl;
+            args[4] = tcg_tst_ltge_cond(c);
+            return -1;
+        }
     }
+
     if (args_are_copies(al, bl) && args_are_copies(ah, bh)) {
-        return do_constant_folding_cond_eq(c);
+        r = do_constant_folding_cond_eq(c);
+        if (r >= 0) {
+            return r;
+        }
+
+        /* TSTNE x,x -> NE x,0 */
+        if (is_tst_cond(c)) {
+            args[3] = args[2] = arg_new_constant(ctx, 0);
+            args[4] = tcg_tst_eqne_cond(c);
+            return -1;
+        }
     }
     return -1;
 }
@@ -1151,24 +1227,37 @@ static bool fold_brcond2(OptContext *ctx, TCGOp *op)
         case 0:
             goto do_brcond_const;
         case 1:
-            op->opc = INDEX_op_brcond_i32;
-            op->args[1] = op->args[2];
-            op->args[2] = cond;
-            op->args[3] = label;
-            break;
+            goto do_brcond_low;
+        }
+        break;
+
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        if (arg_is_const_val(op->args[2], 0)) {
+            goto do_brcond_high;
+        }
+        if (arg_is_const_val(op->args[3], 0)) {
+            goto do_brcond_low;
         }
         break;
 
     default:
         break;
 
+    do_brcond_low:
+        op->opc = INDEX_op_brcond_i32;
+        op->args[1] = op->args[2];
+        op->args[2] = cond;
+        op->args[3] = label;
+        return fold_brcond(ctx, op);
+
     do_brcond_high:
         op->opc = INDEX_op_brcond_i32;
         op->args[0] = op->args[1];
         op->args[1] = op->args[3];
         op->args[2] = cond;
         op->args[3] = label;
-        break;
+        return fold_brcond(ctx, op);
 
     do_brcond_const:
         if (i == 0) {
@@ -1829,6 +1918,104 @@ static bool fold_remainder(OptContext *ctx, TCGOp *op)
     return false;
 }
 
+static void fold_setcond_tst_pow2(OptContext *ctx, TCGOp *op, bool neg)
+{
+    TCGOpcode and_opc, sub_opc, xor_opc, neg_opc, shr_opc, uext_opc, sext_opc;
+    TCGCond cond = op->args[3];
+    TCGArg ret, src1, src2;
+    TCGOp *op2;
+    uint64_t val;
+    int sh;
+    bool inv;
+
+    if (!is_tst_cond(cond) || !arg_is_const(op->args[2])) {
+        return;
+    }
+
+    src2 = op->args[2];
+    val = arg_info(src2)->val;
+    if (!is_power_of_2(val)) {
+        return;
+    }
+    sh = ctz64(val);
+
+    switch (ctx->type) {
+    case TCG_TYPE_I32:
+        and_opc = INDEX_op_and_i32;
+        sub_opc = INDEX_op_sub_i32;
+        xor_opc = INDEX_op_xor_i32;
+        shr_opc = INDEX_op_shr_i32;
+        neg_opc = TCG_TARGET_HAS_neg_i32 ? INDEX_op_neg_i32 : 0;
+        if (TCG_TARGET_extract_i32_valid(sh, 1)) {
+            uext_opc = TCG_TARGET_HAS_extract_i32 ? INDEX_op_extract_i32 : 0;
+            sext_opc = TCG_TARGET_HAS_sextract_i32 ? INDEX_op_sextract_i32 : 0;
+        }
+        break;
+    case TCG_TYPE_I64:
+        and_opc = INDEX_op_and_i64;
+        sub_opc = INDEX_op_sub_i64;
+        xor_opc = INDEX_op_xor_i64;
+        shr_opc = INDEX_op_shr_i64;
+        neg_opc = TCG_TARGET_HAS_neg_i64 ? INDEX_op_neg_i64 : 0;
+        if (TCG_TARGET_extract_i64_valid(sh, 1)) {
+            uext_opc = TCG_TARGET_HAS_extract_i64 ? INDEX_op_extract_i64 : 0;
+            sext_opc = TCG_TARGET_HAS_sextract_i64 ? INDEX_op_sextract_i64 : 0;
+        }
+        break;
+    default:
+        g_assert_not_reached();
+    }
+
+    ret = op->args[0];
+    src1 = op->args[1];
+    inv = cond == TCG_COND_TSTEQ;
+
+    if (sh && sext_opc && neg && !inv) {
+        op->opc = sext_opc;
+        op->args[1] = src1;
+        op->args[2] = sh;
+        op->args[3] = 1;
+        return;
+    } else if (sh && uext_opc) {
+        op->opc = uext_opc;
+        op->args[1] = src1;
+        op->args[2] = sh;
+        op->args[3] = 1;
+    } else {
+        if (sh) {
+            op2 = tcg_op_insert_before(ctx->tcg, op, shr_opc, 3);
+            op2->args[0] = ret;
+            op2->args[1] = src1;
+            op2->args[2] = arg_new_constant(ctx, sh);
+            src1 = ret;
+        }
+        op->opc = and_opc;
+        op->args[1] = src1;
+        op->args[2] = arg_new_constant(ctx, 1);
+    }
+
+    if (neg && inv) {
+        op2 = tcg_op_insert_after(ctx->tcg, op, sub_opc, 3);
+        op2->args[0] = ret;
+        op2->args[1] = ret;
+        op2->args[2] = arg_new_constant(ctx, 1);
+    } else if (inv) {
+        op2 = tcg_op_insert_after(ctx->tcg, op, xor_opc, 3);
+        op2->args[0] = ret;
+        op2->args[1] = ret;
+        op2->args[2] = arg_new_constant(ctx, 1);
+    } else if (neg && neg_opc) {
+        op2 = tcg_op_insert_after(ctx->tcg, op, neg_opc, 2);
+        op2->args[0] = ret;
+        op2->args[1] = ret;
+    } else if (neg) {
+        op2 = tcg_op_insert_after(ctx->tcg, op, sub_opc, 3);
+        op2->args[0] = ret;
+        op2->args[1] = arg_new_constant(ctx, 0);
+        op2->args[2] = ret;
+    }
+}
+
 static bool fold_setcond(OptContext *ctx, TCGOp *op)
 {
     int i = do_constant_folding_cond1(ctx, op->args[0], &op->args[1],
@@ -1836,6 +2023,7 @@ static bool fold_setcond(OptContext *ctx, TCGOp *op)
     if (i >= 0) {
         return tcg_opt_gen_movi(ctx, op, op->args[0], i);
     }
+    fold_setcond_tst_pow2(ctx, op, false);
 
     ctx->z_mask = 1;
     ctx->s_mask = smask_from_zmask(1);
@@ -1849,13 +2037,13 @@ static bool fold_negsetcond(OptContext *ctx, TCGOp *op)
     if (i >= 0) {
         return tcg_opt_gen_movi(ctx, op, op->args[0], -i);
     }
+    fold_setcond_tst_pow2(ctx, op, true);
 
     /* Value is {0,-1} so all bits are repetitions of the sign. */
     ctx->s_mask = -1;
     return false;
 }
 
-
 static bool fold_setcond2(OptContext *ctx, TCGOp *op)
 {
     TCGCond cond;
@@ -1903,22 +2091,35 @@ static bool fold_setcond2(OptContext *ctx, TCGOp *op)
         case 0:
             goto do_setcond_const;
         case 1:
-            op->args[2] = op->args[3];
-            op->args[3] = cond;
-            op->opc = INDEX_op_setcond_i32;
-            break;
+            goto do_setcond_low;
+        }
+        break;
+
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        if (arg_is_const_val(op->args[2], 0)) {
+            goto do_setcond_high;
+        }
+        if (arg_is_const_val(op->args[4], 0)) {
+            goto do_setcond_low;
         }
         break;
 
     default:
         break;
 
+    do_setcond_low:
+        op->args[2] = op->args[3];
+        op->args[3] = cond;
+        op->opc = INDEX_op_setcond_i32;
+        return fold_setcond(ctx, op);
+
     do_setcond_high:
         op->args[1] = op->args[2];
         op->args[2] = op->args[4];
         op->args[3] = cond;
         op->opc = INDEX_op_setcond_i32;
-        break;
+        return fold_setcond(ctx, op);
     }
 
     ctx->z_mask = 1;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 07/35] tcg: Add TCGConst argument to tcg_target_const_match
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (5 preceding siblings ...)
  2023-10-28 19:44 ` [PATCH v2 06/35] tcg/optimize: Handle TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-11-06 18:47   ` Philippe Mathieu-Daudé
  2023-10-28 19:44 ` [PATCH v2 08/35] tcg/aarch64: Support TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (29 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Fill the new argument from any condition within the opcode.
Not yet used within any backend.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/tcg.c                        | 34 ++++++++++++++++++++++++++++++--
 tcg/aarch64/tcg-target.c.inc     |  3 ++-
 tcg/arm/tcg-target.c.inc         |  3 ++-
 tcg/i386/tcg-target.c.inc        |  3 ++-
 tcg/loongarch64/tcg-target.c.inc |  3 ++-
 tcg/mips/tcg-target.c.inc        |  3 ++-
 tcg/ppc/tcg-target.c.inc         |  3 ++-
 tcg/riscv/tcg-target.c.inc       |  3 ++-
 tcg/s390x/tcg-target.c.inc       |  3 ++-
 tcg/sparc64/tcg-target.c.inc     |  3 ++-
 tcg/tci/tcg-target.c.inc         |  3 ++-
 11 files changed, 52 insertions(+), 12 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 57d0583fe7..58b431b579 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -173,7 +173,8 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
 static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target,
                          const TCGHelperInfo *info);
 static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot);
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece);
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece);
 #ifdef TCG_TARGET_NEED_LDST_LABELS
 static int tcg_out_ldst_finalize(TCGContext *s);
 #endif
@@ -4680,6 +4681,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
     TCGTemp *ts;
     TCGArg new_args[TCG_MAX_OP_ARGS];
     int const_args[TCG_MAX_OP_ARGS];
+    TCGCond op_cond;
 
     nb_oargs = def->nb_oargs;
     nb_iargs = def->nb_iargs;
@@ -4692,6 +4694,33 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
     i_allocated_regs = s->reserved_regs;
     o_allocated_regs = s->reserved_regs;
 
+    switch (op->opc) {
+    case INDEX_op_brcond_i32:
+    case INDEX_op_brcond_i64:
+        op_cond = op->args[2];
+        break;
+    case INDEX_op_setcond_i32:
+    case INDEX_op_setcond_i64:
+    case INDEX_op_negsetcond_i32:
+    case INDEX_op_negsetcond_i64:
+    case INDEX_op_cmp_vec:
+        op_cond = op->args[3];
+        break;
+    case INDEX_op_brcond2_i32:
+        op_cond = op->args[4];
+        break;
+    case INDEX_op_movcond_i32:
+    case INDEX_op_movcond_i64:
+    case INDEX_op_setcond2_i32:
+    case INDEX_op_cmpsel_vec:
+        op_cond = op->args[5];
+        break;
+    default:
+        /* No condition within opcode. */
+        op_cond = TCG_COND_ALWAYS;
+        break;
+    }
+
     /* satisfy input constraints */
     for (k = 0; k < nb_iargs; k++) {
         TCGRegSet i_preferred_regs, i_required_regs;
@@ -4705,7 +4734,8 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
         ts = arg_temp(arg);
 
         if (ts->val_type == TEMP_VAL_CONST
-            && tcg_target_const_match(ts->val, ts->type, arg_ct->ct, TCGOP_VECE(op))) {
+            && tcg_target_const_match(ts->val, arg_ct->ct, ts->type,
+                                      op_cond, TCGOP_VECE(op))) {
             /* constant is OK for instruction */
             const_args[i] = 1;
             new_args[i] = ts->val;
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index a3efa1e67a..420e4a35ea 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -270,7 +270,8 @@ static bool is_shimm1632(uint32_t v32, int *cmode, int *imm8)
     }
 }
 
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece)
 {
     if (ct & TCG_CT_CONST) {
         return 1;
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index fc78566494..0c29a3929b 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -501,7 +501,8 @@ static bool is_shimm1632(uint32_t v32, int *cmode, int *imm8)
  * mov operand2:     values represented with x << (2 * y), x < 0x100
  * add, sub, eor...: ditto
  */
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece)
 {
     if (ct & TCG_CT_CONST) {
         return 1;
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index a83f8aab30..eeb23d3fca 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -195,7 +195,8 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 }
 
 /* test if a constant matches the constraint */
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece)
 {
     if (ct & TCG_CT_CONST) {
         return 1;
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index ccf133db4b..384d2ba342 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -185,7 +185,8 @@ static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len)
 }
 
 /* test if a constant matches the constraint */
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece)
 {
     if (ct & TCG_CT_CONST) {
         return true;
diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
index 328984ccff..35eff82bb3 100644
--- a/tcg/mips/tcg-target.c.inc
+++ b/tcg/mips/tcg-target.c.inc
@@ -188,7 +188,8 @@ static bool is_p2m1(tcg_target_long val)
 }
 
 /* test if a constant matches the constraint */
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece)
 {
     if (ct & TCG_CT_CONST) {
         return 1;
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index 856c3b18f5..a5871f55b1 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -282,7 +282,8 @@ static bool reloc_pc34(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
 }
 
 /* test if a constant matches the constraint */
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece)
 {
     if (ct & TCG_CT_CONST) {
         return 1;
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 34e10e77d9..639363039b 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -145,7 +145,8 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
 #define sextreg  sextract64
 
 /* test if a constant matches the constraint */
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece)
 {
     if (ct & TCG_CT_CONST) {
         return 1;
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
index fbee43d3b0..08fe00a392 100644
--- a/tcg/s390x/tcg-target.c.inc
+++ b/tcg/s390x/tcg-target.c.inc
@@ -538,7 +538,8 @@ static bool risbg_mask(uint64_t c)
 }
 
 /* Test if a constant matches the constraint. */
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece)
 {
     if (ct & TCG_CT_CONST) {
         return 1;
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index 19d9df4a09..386f51f29e 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -322,7 +322,8 @@ static bool patch_reloc(tcg_insn_unit *src_rw, int type,
 }
 
 /* test if a constant matches the constraint */
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece)
 {
     if (ct & TCG_CT_CONST) {
         return 1;
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index 461f4b47ff..c740864b96 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -913,7 +913,8 @@ static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
 }
 
 /* Test if a constant matches the constraint. */
-static bool tcg_target_const_match(int64_t val, TCGType type, int ct, int vece)
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece)
 {
     return ct & TCG_CT_CONST;
 }
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 08/35] tcg/aarch64: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (6 preceding siblings ...)
  2023-10-28 19:44 ` [PATCH v2 07/35] tcg: Add TCGConst argument to tcg_target_const_match Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-10-28 19:44 ` [PATCH v2 09/35] tcg/aarch64: Generate TBZ, TBNZ Richard Henderson
                   ` (28 subsequent siblings)
  36 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/aarch64/tcg-target-con-set.h |  5 +--
 tcg/aarch64/tcg-target-con-str.h |  1 +
 tcg/aarch64/tcg-target.c.inc     | 56 ++++++++++++++++++++++----------
 3 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/tcg/aarch64/tcg-target-con-set.h b/tcg/aarch64/tcg-target-con-set.h
index 3fdee26a3d..44fcc1206e 100644
--- a/tcg/aarch64/tcg-target-con-set.h
+++ b/tcg/aarch64/tcg-target-con-set.h
@@ -10,7 +10,7 @@
  * tcg-target-con-str.h; the constraint combination is inclusive or.
  */
 C_O0_I1(r)
-C_O0_I2(r, rA)
+C_O0_I2(r, rC)
 C_O0_I2(rZ, r)
 C_O0_I2(w, r)
 C_O0_I3(rZ, rZ, r)
@@ -22,6 +22,7 @@ C_O1_I2(r, 0, rZ)
 C_O1_I2(r, r, r)
 C_O1_I2(r, r, rA)
 C_O1_I2(r, r, rAL)
+C_O1_I2(r, r, rC)
 C_O1_I2(r, r, ri)
 C_O1_I2(r, r, rL)
 C_O1_I2(r, rZ, rZ)
@@ -31,6 +32,6 @@ C_O1_I2(w, w, wN)
 C_O1_I2(w, w, wO)
 C_O1_I2(w, w, wZ)
 C_O1_I3(w, w, w, w)
-C_O1_I4(r, r, rA, rZ, rZ)
+C_O1_I4(r, r, rC, rZ, rZ)
 C_O2_I1(r, r, r)
 C_O2_I4(r, r, rZ, rZ, rA, rMZ)
diff --git a/tcg/aarch64/tcg-target-con-str.h b/tcg/aarch64/tcg-target-con-str.h
index fb1a845b4f..48e1722c68 100644
--- a/tcg/aarch64/tcg-target-con-str.h
+++ b/tcg/aarch64/tcg-target-con-str.h
@@ -16,6 +16,7 @@ REGS('w', ALL_VECTOR_REGS)
  * CONST(letter, TCG_CT_CONST_* bit set)
  */
 CONST('A', TCG_CT_CONST_AIMM)
+CONST('C', TCG_CT_CONST_CMP)
 CONST('L', TCG_CT_CONST_LIMM)
 CONST('M', TCG_CT_CONST_MONE)
 CONST('O', TCG_CT_CONST_ORRI)
diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index 420e4a35ea..70df250c04 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -126,6 +126,7 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 #define TCG_CT_CONST_MONE 0x800
 #define TCG_CT_CONST_ORRI 0x1000
 #define TCG_CT_CONST_ANDI 0x2000
+#define TCG_CT_CONST_CMP  0x4000
 
 #define ALL_GENERAL_REGS  0xffffffffu
 #define ALL_VECTOR_REGS   0xffffffff00000000ull
@@ -279,6 +280,15 @@ static bool tcg_target_const_match(int64_t val, int ct,
     if (type == TCG_TYPE_I32) {
         val = (int32_t)val;
     }
+
+    if (ct & TCG_CT_CONST_CMP) {
+        if (is_tst_cond(cond)) {
+            ct |= TCG_CT_CONST_LIMM;
+        } else {
+            ct |= TCG_CT_CONST_AIMM;
+        }
+    }
+
     if ((ct & TCG_CT_CONST_AIMM) && (is_aimm(val) || is_aimm(-val))) {
         return 1;
     }
@@ -345,6 +355,9 @@ static const enum aarch64_cond_code tcg_cond_to_aarch64[] = {
     [TCG_COND_GTU] = COND_HI,
     [TCG_COND_GEU] = COND_HS,
     [TCG_COND_LEU] = COND_LS,
+    /* bit test */
+    [TCG_COND_TSTEQ] = COND_EQ,
+    [TCG_COND_TSTNE] = COND_NE,
 };
 
 typedef enum {
@@ -1342,19 +1355,26 @@ static inline void tcg_out_dep(TCGContext *s, TCGType ext, TCGReg rd,
     tcg_out_bfm(s, ext, rd, rn, a, b);
 }
 
-static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg a,
+static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGCond cond, TCGReg a,
                         tcg_target_long b, bool const_b)
 {
-    if (const_b) {
-        /* Using CMP or CMN aliases.  */
-        if (b >= 0) {
-            tcg_out_insn(s, 3401, SUBSI, ext, TCG_REG_XZR, a, b);
+    if (is_tst_cond(cond)) {
+        if (!const_b) {
+            tcg_out_insn(s, 3510, ANDS, ext, TCG_REG_XZR, a, b);
         } else {
-            tcg_out_insn(s, 3401, ADDSI, ext, TCG_REG_XZR, a, -b);
+            tcg_debug_assert(is_limm(b));
+            tcg_out_logicali(s, I3404_ANDSI, 0, TCG_REG_XZR, a, b);
         }
     } else {
-        /* Using CMP alias SUBS wzr, Wn, Wm */
-        tcg_out_insn(s, 3502, SUBS, ext, TCG_REG_XZR, a, b);
+        if (!const_b) {
+            tcg_out_insn(s, 3502, SUBS, ext, TCG_REG_XZR, a, b);
+        } else if (b >= 0) {
+            tcg_debug_assert(is_aimm(b));
+            tcg_out_insn(s, 3401, SUBSI, ext, TCG_REG_XZR, a, b);
+        } else {
+            tcg_debug_assert(is_aimm(-b));
+            tcg_out_insn(s, 3401, ADDSI, ext, TCG_REG_XZR, a, -b);
+        }
     }
 }
 
@@ -1402,7 +1422,7 @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
         need_cmp = false;
     } else {
         need_cmp = true;
-        tcg_out_cmp(s, ext, a, b, b_const);
+        tcg_out_cmp(s, ext, c, a, b, b_const);
     }
 
     if (!l->has_value) {
@@ -1575,7 +1595,7 @@ static void tcg_out_cltz(TCGContext *s, TCGType ext, TCGReg d,
     } else {
         AArch64Insn sel = I3506_CSEL;
 
-        tcg_out_cmp(s, ext, a0, 0, 1);
+        tcg_out_cmp(s, ext, TCG_COND_NE, a0, 0, 1);
         tcg_out_insn(s, 3507, CLZ, ext, TCG_REG_TMP0, a1);
 
         if (const_b) {
@@ -1720,7 +1740,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
                          addr_adj, compare_mask);
 
         /* Perform the address comparison. */
-        tcg_out_cmp(s, addr_type, TCG_REG_TMP0, TCG_REG_TMP2, 0);
+        tcg_out_cmp(s, addr_type, TCG_COND_NE, TCG_REG_TMP0, TCG_REG_TMP2, 0);
 
         /* If not equal, we jump to the slow path. */
         ldst->label_ptr[0] = s->code_ptr;
@@ -2276,7 +2296,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         a2 = (int32_t)a2;
         /* FALLTHRU */
     case INDEX_op_setcond_i64:
-        tcg_out_cmp(s, ext, a1, a2, c2);
+        tcg_out_cmp(s, ext, args[3], a1, a2, c2);
         /* Use CSET alias of CSINC Wd, WZR, WZR, invert(cond).  */
         tcg_out_insn(s, 3506, CSINC, TCG_TYPE_I32, a0, TCG_REG_XZR,
                      TCG_REG_XZR, tcg_invert_cond(args[3]));
@@ -2286,7 +2306,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         a2 = (int32_t)a2;
         /* FALLTHRU */
     case INDEX_op_negsetcond_i64:
-        tcg_out_cmp(s, ext, a1, a2, c2);
+        tcg_out_cmp(s, ext, args[3], a1, a2, c2);
         /* Use CSETM alias of CSINV Wd, WZR, WZR, invert(cond).  */
         tcg_out_insn(s, 3506, CSINV, ext, a0, TCG_REG_XZR,
                      TCG_REG_XZR, tcg_invert_cond(args[3]));
@@ -2296,7 +2316,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         a2 = (int32_t)a2;
         /* FALLTHRU */
     case INDEX_op_movcond_i64:
-        tcg_out_cmp(s, ext, a1, a2, c2);
+        tcg_out_cmp(s, ext, args[5], a1, a2, c2);
         tcg_out_insn(s, 3506, CSEL, ext, a0, REG0(3), REG0(4), args[5]);
         break;
 
@@ -2896,11 +2916,13 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_add_i64:
     case INDEX_op_sub_i32:
     case INDEX_op_sub_i64:
+        return C_O1_I2(r, r, rA);
+
     case INDEX_op_setcond_i32:
     case INDEX_op_setcond_i64:
     case INDEX_op_negsetcond_i32:
     case INDEX_op_negsetcond_i64:
-        return C_O1_I2(r, r, rA);
+        return C_O1_I2(r, r, rC);
 
     case INDEX_op_mul_i32:
     case INDEX_op_mul_i64:
@@ -2950,11 +2972,11 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 
     case INDEX_op_brcond_i32:
     case INDEX_op_brcond_i64:
-        return C_O0_I2(r, rA);
+        return C_O0_I2(r, rC);
 
     case INDEX_op_movcond_i32:
     case INDEX_op_movcond_i64:
-        return C_O1_I4(r, r, rA, rZ, rZ);
+        return C_O1_I4(r, r, rC, rZ, rZ);
 
     case INDEX_op_qemu_ld_a32_i32:
     case INDEX_op_qemu_ld_a64_i32:
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 09/35] tcg/aarch64: Generate TBZ, TBNZ
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (7 preceding siblings ...)
  2023-10-28 19:44 ` [PATCH v2 08/35] tcg/aarch64: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-10-28 19:44 ` [PATCH v2 10/35] tcg/aarch64: Generate CBNZ for TSTNE of UINT32_MAX Richard Henderson
                   ` (27 subsequent siblings)
  36 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Test the sign bit for LT/GE vs 0, and TSTNE/EQ vs a power of 2.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/aarch64/tcg-target.c.inc | 100 ++++++++++++++++++++++++++++-------
 1 file changed, 81 insertions(+), 19 deletions(-)

diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index 70df250c04..55225313ad 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -105,6 +105,18 @@ static bool reloc_pc19(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
     return false;
 }
 
+static bool reloc_pc14(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
+{
+    const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
+    ptrdiff_t offset = target - src_rx;
+
+    if (offset == sextract64(offset, 0, 14)) {
+        *src_rw = deposit32(*src_rw, 5, 14, offset);
+        return true;
+    }
+    return false;
+}
+
 static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
                         intptr_t value, intptr_t addend)
 {
@@ -115,6 +127,8 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
         return reloc_pc26(code_ptr, (const tcg_insn_unit *)value);
     case R_AARCH64_CONDBR19:
         return reloc_pc19(code_ptr, (const tcg_insn_unit *)value);
+    case R_AARCH64_TSTBR14:
+        return reloc_pc14(code_ptr, (const tcg_insn_unit *)value);
     default:
         g_assert_not_reached();
     }
@@ -380,6 +394,10 @@ typedef enum {
     /* Conditional branch (immediate).  */
     I3202_B_C       = 0x54000000,
 
+    /* Test and branch (immediate).  */
+    I3205_TBZ       = 0x36000000,
+    I3205_TBNZ      = 0x37000000,
+
     /* Unconditional branch (immediate).  */
     I3206_B         = 0x14000000,
     I3206_BL        = 0x94000000,
@@ -660,6 +678,14 @@ static void tcg_out_insn_3202(TCGContext *s, AArch64Insn insn,
     tcg_out32(s, insn | tcg_cond_to_aarch64[c] | (imm19 & 0x7ffff) << 5);
 }
 
+static void tcg_out_insn_3205(TCGContext *s, AArch64Insn insn,
+                              TCGReg rt, int imm6, int imm14)
+{
+    insn |= (imm6 & 0x20) << (31 - 5);
+    insn |= (imm6 & 0x1f) << 19;
+    tcg_out32(s, insn | (imm14 & 0x3fff) << 5 | rt);
+}
+
 static void tcg_out_insn_3206(TCGContext *s, AArch64Insn insn, int imm26)
 {
     tcg_out32(s, insn | (imm26 & 0x03ffffff));
@@ -1415,30 +1441,66 @@ static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l)
 static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
                            TCGArg b, bool b_const, TCGLabel *l)
 {
-    intptr_t offset;
-    bool need_cmp;
+    int tbit = -1;
+    bool need_cmp = true;
 
-    if (b_const && b == 0 && (c == TCG_COND_EQ || c == TCG_COND_NE)) {
-        need_cmp = false;
-    } else {
-        need_cmp = true;
-        tcg_out_cmp(s, ext, c, a, b, b_const);
-    }
-
-    if (!l->has_value) {
-        tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, l, 0);
-        offset = tcg_in32(s) >> 5;
-    } else {
-        offset = tcg_pcrel_diff(s, l->u.value_ptr) >> 2;
-        tcg_debug_assert(offset == sextract64(offset, 0, 19));
+    switch (c) {
+    case TCG_COND_EQ:
+    case TCG_COND_NE:
+        if (b_const && b == 0) {
+            need_cmp = false;
+        }
+        break;
+    case TCG_COND_LT:
+    case TCG_COND_GE:
+        if (b_const && b == 0) {
+            c = (c == TCG_COND_LT ? TCG_COND_TSTNE : TCG_COND_TSTEQ);
+            tbit = ext ? 63 : 31;
+            need_cmp = false;
+        }
+        break;
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        if (b_const && is_power_of_2(b)) {
+            tbit = ctz64(b);
+            need_cmp = false;
+        }
+        break;
+    default:
+        break;
     }
 
     if (need_cmp) {
-        tcg_out_insn(s, 3202, B_C, c, offset);
-    } else if (c == TCG_COND_EQ) {
-        tcg_out_insn(s, 3201, CBZ, ext, a, offset);
+        tcg_out_cmp(s, ext, c, a, b, b_const);
+        tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, l, 0);
+        tcg_out_insn(s, 3202, B_C, c, 0);
+        return;
+    }
+
+    if (tbit >= 0) {
+        tcg_out_reloc(s, s->code_ptr, R_AARCH64_TSTBR14, l, 0);
+        switch (c) {
+        case TCG_COND_TSTEQ:
+            tcg_out_insn(s, 3205, TBZ, a, tbit, 0);
+            break;
+        case TCG_COND_TSTNE:
+            tcg_out_insn(s, 3205, TBNZ, a, tbit, 0);
+            break;
+        default:
+            g_assert_not_reached();
+        }
     } else {
-        tcg_out_insn(s, 3201, CBNZ, ext, a, offset);
+        tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, l, 0);
+        switch (c) {
+        case TCG_COND_EQ:
+            tcg_out_insn(s, 3201, CBZ, ext, a, 0);
+            break;
+        case TCG_COND_NE:
+            tcg_out_insn(s, 3201, CBNZ, ext, a, 0);
+            break;
+        default:
+            g_assert_not_reached();
+        }
     }
 }
 
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 10/35] tcg/aarch64: Generate CBNZ for TSTNE of UINT32_MAX
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (8 preceding siblings ...)
  2023-10-28 19:44 ` [PATCH v2 09/35] tcg/aarch64: Generate TBZ, TBNZ Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-10-28 19:44 ` [PATCH v2 11/35] tcg/arm: Support TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (26 subsequent siblings)
  36 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

... and the inverse, CBZ for TSTEQ.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/aarch64/tcg-target.c.inc | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index 55225313ad..0c98c48f68 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -1453,6 +1453,7 @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
         break;
     case TCG_COND_LT:
     case TCG_COND_GE:
+        /* cmp xN,0; b.mi L -> tbnz xN,63,L */
         if (b_const && b == 0) {
             c = (c == TCG_COND_LT ? TCG_COND_TSTNE : TCG_COND_TSTEQ);
             tbit = ext ? 63 : 31;
@@ -1461,6 +1462,13 @@ static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond c, TCGArg a,
         break;
     case TCG_COND_TSTEQ:
     case TCG_COND_TSTNE:
+        /* tst xN,0xffffffff; b.ne L -> cbnz wN,L */
+        if (b_const && b == UINT32_MAX) {
+            ext = TCG_TYPE_I32;
+            need_cmp = false;
+            break;
+        }
+        /* tst xN,1<<B; b.ne L -> tbnz xN,B,L */
         if (b_const && is_power_of_2(b)) {
             tbit = ctz64(b);
             need_cmp = false;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 11/35] tcg/arm: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (9 preceding siblings ...)
  2023-10-28 19:44 ` [PATCH v2 10/35] tcg/aarch64: Generate CBNZ for TSTNE of UINT32_MAX Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-11-08 14:52   ` [PATCH v2 11/35 1/2] tcg/arm: Factor tcg_out_cmp() out Philippe Mathieu-Daudé
  2023-11-08 14:52   ` [PATCH v2 11/35 2/2] tcg/arm: Support TCG_COND_TST{EQ,NE} Philippe Mathieu-Daudé
  2023-10-28 19:44 ` [PATCH v2 12/35] tcg/i386: Pass x86 condition codes to tcg_out_cmov Richard Henderson
                   ` (25 subsequent siblings)
  36 siblings, 2 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/arm/tcg-target.c.inc | 59 ++++++++++++++++++++++++++++++----------
 1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index 0c29a3929b..0fc7273b16 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -1191,6 +1191,33 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
     }
 }
 
+static TCGCond tcg_out_cmp(TCGContext *s, TCGCond cond, TCGReg a,
+                           TCGArg b, int b_const)
+{
+    if (!is_tst_cond(cond)) {
+        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0, a, b, b_const);
+        return cond;
+    }
+
+    cond = tcg_tst_eqne_cond(cond);
+    if (b_const) {
+        int imm12 = encode_imm(b);
+
+        /*
+         * The compare constraints allow rIN, but TST does not support N.
+         * Be prepared to load the constant into a scratch register.
+         */
+        if (imm12 >= 0) {
+            tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, a, imm12);
+            return cond;
+        }
+        tcg_out_movi32(s, COND_AL, TCG_REG_TMP, b);
+        b = TCG_REG_TMP;
+    }
+    tcg_out_dat_reg(s, COND_AL, ARITH_TST, 0, a, b, SHIFT_IMM_LSL(0));
+    return cond;
+}
+
 static TCGCond tcg_out_cmp2(TCGContext *s, const TCGArg *args,
                             const int *const_args)
 {
@@ -1218,6 +1245,13 @@ static TCGCond tcg_out_cmp2(TCGContext *s, const TCGArg *args,
         tcg_out_dat_rI(s, COND_EQ, ARITH_CMP, 0, al, bl, const_bl);
         return cond;
 
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        /* Similar, but with TST instead of CMP. */
+        tcg_out_dat_rI(s, COND_AL, ARITH_TST, 0, ah, bh, const_bh);
+        tcg_out_dat_rI(s, COND_EQ, ARITH_TST, 0, al, bl, const_bl);
+        return tcg_tst_eqne_cond(cond);
+
     case TCG_COND_LT:
     case TCG_COND_GE:
         /* We perform a double-word subtraction and examine the result.
@@ -1806,9 +1840,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         /* Constraints mean that v2 is always in the same register as dest,
          * so we only need to do "if condition passed, move v1 to dest".
          */
-        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
-                        args[1], args[2], const_args[2]);
-        tcg_out_dat_rIK(s, tcg_cond_to_arm_cond[args[5]], ARITH_MOV,
+        c = tcg_out_cmp(s, args[5], args[1], args[2], const_args[2]);
+        tcg_out_dat_rIK(s, tcg_cond_to_arm_cond[c], ARITH_MOV,
                         ARITH_MVN, args[0], 0, args[3], const_args[3]);
         break;
     case INDEX_op_add_i32:
@@ -1958,25 +1991,21 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         break;
 
     case INDEX_op_brcond_i32:
-        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
-                       args[0], args[1], const_args[1]);
-        tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]],
-                           arg_label(args[3]));
+        c = tcg_out_cmp(s, args[2], args[0], args[1], const_args[1]);
+        tcg_out_goto_label(s, tcg_cond_to_arm_cond[c], arg_label(args[3]));
         break;
     case INDEX_op_setcond_i32:
-        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
-                        args[1], args[2], const_args[2]);
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
+        c = tcg_out_cmp(s, args[3], args[1], args[2], const_args[2]);
+        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[c],
                         ARITH_MOV, args[0], 0, 1);
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
+        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(c)],
                         ARITH_MOV, args[0], 0, 0);
         break;
     case INDEX_op_negsetcond_i32:
-        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
-                        args[1], args[2], const_args[2]);
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
+        c = tcg_out_cmp(s, args[3], args[1], args[2], const_args[2]);
+        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[c],
                         ARITH_MVN, args[0], 0, 0);
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
+        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(c)],
                         ARITH_MOV, args[0], 0, 0);
         break;
 
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 12/35] tcg/i386: Pass x86 condition codes to tcg_out_cmov
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (10 preceding siblings ...)
  2023-10-28 19:44 ` [PATCH v2 11/35] tcg/arm: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-10-28 19:44 ` Richard Henderson
  2023-11-06 20:55   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 13/35] tcg/i386: Move tcg_cond_to_jcc[] into tcg_out_cmp Richard Henderson
                   ` (24 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Hoist the tcg_cond_to_jcc index outside the function.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/i386/tcg-target.c.inc | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index eeb23d3fca..8b1baa8206 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -1669,14 +1669,14 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
 }
 #endif
 
-static void tcg_out_cmov(TCGContext *s, TCGCond cond, int rexw,
+static void tcg_out_cmov(TCGContext *s, int jcc, int rexw,
                          TCGReg dest, TCGReg v1)
 {
     if (have_cmov) {
-        tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond] | rexw, dest, v1);
+        tcg_out_modrm(s, OPC_CMOVCC | jcc | rexw, dest, v1);
     } else {
         TCGLabel *over = gen_new_label();
-        tcg_out_jxx(s, tcg_cond_to_jcc[tcg_invert_cond(cond)], over, 1);
+        tcg_out_jxx(s, jcc ^ 1, over, 1);
         tcg_out_mov(s, TCG_TYPE_I32, dest, v1);
         tcg_out_label(s, over);
     }
@@ -1687,7 +1687,7 @@ static void tcg_out_movcond(TCGContext *s, int rexw, TCGCond cond,
                             TCGReg v1)
 {
     tcg_out_cmp(s, c1, c2, const_c2, rexw);
-    tcg_out_cmov(s, cond, rexw, dest, v1);
+    tcg_out_cmov(s, tcg_cond_to_jcc[cond], rexw, dest, v1);
 }
 
 static void tcg_out_ctz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
@@ -1699,12 +1699,12 @@ static void tcg_out_ctz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
             tcg_debug_assert(arg2 == (rexw ? 64 : 32));
         } else {
             tcg_debug_assert(dest != arg2);
-            tcg_out_cmov(s, TCG_COND_LTU, rexw, dest, arg2);
+            tcg_out_cmov(s, JCC_JB, rexw, dest, arg2);
         }
     } else {
         tcg_debug_assert(dest != arg2);
         tcg_out_modrm(s, OPC_BSF + rexw, dest, arg1);
-        tcg_out_cmov(s, TCG_COND_EQ, rexw, dest, arg2);
+        tcg_out_cmov(s, JCC_JE, rexw, dest, arg2);
     }
 }
 
@@ -1717,7 +1717,7 @@ static void tcg_out_clz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
             tcg_debug_assert(arg2 == (rexw ? 64 : 32));
         } else {
             tcg_debug_assert(dest != arg2);
-            tcg_out_cmov(s, TCG_COND_LTU, rexw, dest, arg2);
+            tcg_out_cmov(s, JCC_JB, rexw, dest, arg2);
         }
     } else {
         tcg_debug_assert(!const_a2);
@@ -1730,7 +1730,7 @@ static void tcg_out_clz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
 
         /* Since we have destroyed the flags from BSR, we have to re-test.  */
         tcg_out_cmp(s, arg1, 0, 1, rexw);
-        tcg_out_cmov(s, TCG_COND_EQ, rexw, dest, arg2);
+        tcg_out_cmov(s, JCC_JE, rexw, dest, arg2);
     }
 }
 
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 13/35] tcg/i386: Move tcg_cond_to_jcc[] into tcg_out_cmp
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (11 preceding siblings ...)
  2023-10-28 19:44 ` [PATCH v2 12/35] tcg/i386: Pass x86 condition codes to tcg_out_cmov Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-06 19:46   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 14/35] tcg/i386: Support TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (23 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Return the x86 condition codes to use after the compare.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/i386/tcg-target.c.inc | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index 8b1baa8206..7d5ed0d045 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -1419,8 +1419,8 @@ static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, bool small)
     }
 }
 
-static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
-                        int const_arg2, int rexw)
+static int tcg_out_cmp(TCGContext *s, TCGCond cond, TCGArg arg1,
+                       TCGArg arg2, int const_arg2, int rexw)
 {
     if (const_arg2) {
         if (arg2 == 0) {
@@ -1432,14 +1432,15 @@ static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
     } else {
         tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
     }
+    return tcg_cond_to_jcc[cond];
 }
 
 static void tcg_out_brcond(TCGContext *s, int rexw, TCGCond cond,
                            TCGArg arg1, TCGArg arg2, int const_arg2,
                            TCGLabel *label, bool small)
 {
-    tcg_out_cmp(s, arg1, arg2, const_arg2, rexw);
-    tcg_out_jxx(s, tcg_cond_to_jcc[cond], label, small);
+    int jcc = tcg_out_cmp(s, cond, arg1, arg2, const_arg2, rexw);
+    tcg_out_jxx(s, jcc, label, small);
 }
 
 #if TCG_TARGET_REG_BITS == 32
@@ -1531,6 +1532,7 @@ static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond,
 {
     bool inv = false;
     bool cleared;
+    int jcc;
 
     switch (cond) {
     case TCG_COND_NE:
@@ -1567,7 +1569,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, arg1, arg2, const_arg2, rexw);
+        tcg_out_cmp(s, TCG_COND_LTU, arg1, arg2, const_arg2, rexw);
 
         /* X - X - C = -C = (C ? -1 : 0) */
         tgen_arithr(s, ARITH_SBB + (neg ? rexw : 0), dest, dest);
@@ -1614,8 +1616,8 @@ static void tcg_out_setcond(TCGContext *s, int rexw, TCGCond cond,
         cleared = true;
     }
 
-    tcg_out_cmp(s, arg1, arg2, const_arg2, rexw);
-    tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
+    jcc = tcg_out_cmp(s, cond, arg1, arg2, const_arg2, rexw);
+    tcg_out_modrm(s, OPC_SETCC | jcc, 0, dest);
 
     if (!cleared) {
         tcg_out_ext8u(s, dest, dest);
@@ -1686,8 +1688,8 @@ static void tcg_out_movcond(TCGContext *s, int rexw, TCGCond cond,
                             TCGReg dest, TCGReg c1, TCGArg c2, int const_c2,
                             TCGReg v1)
 {
-    tcg_out_cmp(s, c1, c2, const_c2, rexw);
-    tcg_out_cmov(s, tcg_cond_to_jcc[cond], rexw, dest, v1);
+    int jcc = tcg_out_cmp(s, cond, c1, c2, const_c2, rexw);
+    tcg_out_cmov(s, jcc, rexw, dest, v1);
 }
 
 static void tcg_out_ctz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
@@ -1729,8 +1731,8 @@ static void tcg_out_clz(TCGContext *s, int rexw, TCGReg dest, TCGReg arg1,
         tgen_arithi(s, ARITH_XOR + rexw, dest, rexw ? 63 : 31, 0);
 
         /* Since we have destroyed the flags from BSR, we have to re-test.  */
-        tcg_out_cmp(s, arg1, 0, 1, rexw);
-        tcg_out_cmov(s, JCC_JE, rexw, dest, arg2);
+        int jcc = tcg_out_cmp(s, TCG_COND_EQ, arg1, 0, 1, rexw);
+        tcg_out_cmov(s, jcc, rexw, dest, arg2);
     }
 }
 
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 14/35] tcg/i386: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (12 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 13/35] tcg/i386: Move tcg_cond_to_jcc[] into tcg_out_cmp Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-08 18:16   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 15/35] tcg/i386: Improve TSTNE/TESTEQ vs powers of two Richard Henderson
                   ` (22 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Merge tcg_out_testi into tcg_out_cmp and adjust the two uses.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/i386/tcg-target.c.inc | 83 ++++++++++++++++++++++-----------------
 1 file changed, 47 insertions(+), 36 deletions(-)

diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index 7d5ed0d045..17b250f16f 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -505,6 +505,8 @@ static const uint8_t tcg_cond_to_jcc[] = {
     [TCG_COND_GEU] = JCC_JAE,
     [TCG_COND_LEU] = JCC_JBE,
     [TCG_COND_GTU] = JCC_JA,
+    [TCG_COND_TSTEQ] = JCC_JE,
+    [TCG_COND_TSTNE] = JCC_JNE,
 };
 
 #if TCG_TARGET_REG_BITS == 64
@@ -1422,15 +1424,35 @@ static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, bool small)
 static int tcg_out_cmp(TCGContext *s, TCGCond cond, TCGArg arg1,
                        TCGArg arg2, int const_arg2, int rexw)
 {
-    if (const_arg2) {
-        if (arg2 == 0) {
-            /* test r, r */
-            tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg1);
+    if (is_tst_cond(cond)) {
+        if (!const_arg2) {
+            tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg2);
+        } else if (arg2 <= 0xff && (TCG_TARGET_REG_BITS == 64 || arg1 < 4)) {
+            tcg_out_modrm(s, OPC_GRP3_Eb | P_REXB_RM, EXT3_TESTi, arg1);
+            tcg_out8(s, arg2);
+        } else if ((arg2 & ~0xff00) == 0 && arg1 < 4) {
+            tcg_out_modrm(s, OPC_GRP3_Eb, EXT3_TESTi, arg1 + 4);
+            tcg_out8(s, arg2 >> 8);
         } else {
-            tgen_arithi(s, ARITH_CMP + rexw, arg1, arg2, 0);
+            if (rexw) {
+                if (arg2 == (uint32_t)arg2) {
+                    rexw = 0;
+                } else {
+                    tcg_debug_assert(arg2 == (int32_t)arg2);
+                }
+            }
+            tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_TESTi, arg1);
+            tcg_out32(s, arg2);
         }
     } else {
-        tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
+        if (!const_arg2) {
+            tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
+        } else if (arg2 == 0) {
+            tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg1);
+        } else {
+            tcg_debug_assert(!rexw || arg2 == (int32_t)arg2);
+            tgen_arithi(s, ARITH_CMP + rexw, arg1, arg2, 0);
+        }
     }
     return tcg_cond_to_jcc[cond];
 }
@@ -1449,18 +1471,21 @@ static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
 {
     TCGLabel *label_next = gen_new_label();
     TCGLabel *label_this = arg_label(args[5]);
+    TCGCond cond = args[4];
 
-    switch(args[4]) {
+    switch (cond) {
     case TCG_COND_EQ:
-        tcg_out_brcond(s, 0, TCG_COND_NE, args[0], args[2], const_args[2],
-                       label_next, 1);
-        tcg_out_brcond(s, 0, TCG_COND_EQ, args[1], args[3], const_args[3],
+    case TCG_COND_TSTEQ:
+        tcg_out_brcond(s, 0, tcg_invert_cond(cond),
+                       args[0], args[2], const_args[2], label_next, 1);
+        tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
                        label_this, small);
         break;
     case TCG_COND_NE:
-        tcg_out_brcond(s, 0, TCG_COND_NE, args[0], args[2], const_args[2],
+    case TCG_COND_TSTNE:
+        tcg_out_brcond(s, 0, cond, args[0], args[2], const_args[2],
                        label_this, small);
-        tcg_out_brcond(s, 0, TCG_COND_NE, args[1], args[3], const_args[3],
+        tcg_out_brcond(s, 0, cond, args[1], args[3], const_args[3],
                        label_this, small);
         break;
     case TCG_COND_LT:
@@ -1797,23 +1822,6 @@ static void tcg_out_nopn(TCGContext *s, int n)
     tcg_out8(s, 0x90);
 }
 
-/* Test register R vs immediate bits I, setting Z flag for EQ/NE. */
-static void __attribute__((unused))
-tcg_out_testi(TCGContext *s, TCGReg r, uint32_t i)
-{
-    /*
-     * This is used for testing alignment, so we can usually use testb.
-     * For i686, we have to use testl for %esi/%edi.
-     */
-    if (i <= 0xff && (TCG_TARGET_REG_BITS == 64 || r < 4)) {
-        tcg_out_modrm(s, OPC_GRP3_Eb | P_REXB_RM, EXT3_TESTi, r);
-        tcg_out8(s, i);
-    } else {
-        tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_TESTi, r);
-        tcg_out32(s, i);
-    }
-}
-
 typedef struct {
     TCGReg base;
     int index;
@@ -2074,16 +2082,17 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
         tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_L0, TCG_REG_L0,
                    offsetof(CPUTLBEntry, addend));
     } else if (a_mask) {
-        ldst = new_ldst_label(s);
+        int jcc;
 
+        ldst = new_ldst_label(s);
         ldst->is_ld = is_ld;
         ldst->oi = oi;
         ldst->addrlo_reg = addrlo;
         ldst->addrhi_reg = addrhi;
 
-        tcg_out_testi(s, addrlo, a_mask);
         /* jne slow_path */
-        tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0);
+        jcc = tcg_out_cmp(s, TCG_COND_TSTNE, addrlo, a_mask, true, false);
+        tcg_out_opc(s, OPC_JCC_long + jcc, 0, 0, 0);
         ldst->label_ptr[0] = s->code_ptr;
         s->code_ptr += 4;
     }
@@ -2229,9 +2238,10 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
         } else {
             TCGLabel *l1 = gen_new_label();
             TCGLabel *l2 = gen_new_label();
+            int jcc;
 
-            tcg_out_testi(s, h.base, 15);
-            tcg_out_jxx(s, JCC_JNE, l1, true);
+            jcc = tcg_out_cmp(s, TCG_COND_TSTNE, h.base, 15, true, false);
+            tcg_out_jxx(s, jcc, l1, true);
 
             tcg_out_vex_modrm_sib_offset(s, OPC_MOVDQA_VxWx + h.seg,
                                          TCG_TMP_VEC, 0,
@@ -2357,9 +2367,10 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
         } else {
             TCGLabel *l1 = gen_new_label();
             TCGLabel *l2 = gen_new_label();
+            int jcc;
 
-            tcg_out_testi(s, h.base, 15);
-            tcg_out_jxx(s, JCC_JNE, l1, true);
+            jcc = tcg_out_cmp(s, TCG_COND_TSTNE, h.base, 15, true, false);
+            tcg_out_jxx(s, jcc, l1, true);
 
             tcg_out_vex_modrm_sib_offset(s, OPC_MOVDQA_WxVx + h.seg,
                                          TCG_TMP_VEC, 0,
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 15/35] tcg/i386: Improve TSTNE/TESTEQ vs powers of two
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (13 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 14/35] tcg/i386: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-10-28 19:45 ` [PATCH v2 16/35] tcg/loongarch64: Support TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (21 subsequent siblings)
  36 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Use "test x,x" when the bit is one of the 4 sign bits.
Use "bt imm,x" otherwise.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/i386/tcg-target-con-set.h |  6 ++--
 tcg/i386/tcg-target-con-str.h |  1 +
 tcg/i386/tcg-target.c.inc     | 56 ++++++++++++++++++++++++++++++++---
 3 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/tcg/i386/tcg-target-con-set.h b/tcg/i386/tcg-target-con-set.h
index 7d00a7dde8..e24241cfa2 100644
--- a/tcg/i386/tcg-target-con-set.h
+++ b/tcg/i386/tcg-target-con-set.h
@@ -20,7 +20,7 @@ C_O0_I2(L, L)
 C_O0_I2(qi, r)
 C_O0_I2(re, r)
 C_O0_I2(ri, r)
-C_O0_I2(r, re)
+C_O0_I2(r, reT)
 C_O0_I2(s, L)
 C_O0_I2(x, r)
 C_O0_I3(L, L, L)
@@ -34,7 +34,7 @@ C_O1_I1(r, r)
 C_O1_I1(x, r)
 C_O1_I1(x, x)
 C_O1_I2(q, 0, qi)
-C_O1_I2(q, r, re)
+C_O1_I2(q, r, reT)
 C_O1_I2(r, 0, ci)
 C_O1_I2(r, 0, r)
 C_O1_I2(r, 0, re)
@@ -50,7 +50,7 @@ C_N1_I2(r, r, r)
 C_N1_I2(r, r, rW)
 C_O1_I3(x, 0, x, x)
 C_O1_I3(x, x, x, x)
-C_O1_I4(r, r, re, r, 0)
+C_O1_I4(r, r, reT, r, 0)
 C_O1_I4(r, r, r, ri, ri)
 C_O2_I1(r, r, L)
 C_O2_I2(a, d, a, r)
diff --git a/tcg/i386/tcg-target-con-str.h b/tcg/i386/tcg-target-con-str.h
index 95a30e58cd..cc22db227b 100644
--- a/tcg/i386/tcg-target-con-str.h
+++ b/tcg/i386/tcg-target-con-str.h
@@ -28,5 +28,6 @@ REGS('s', ALL_BYTEL_REGS & ~SOFTMMU_RESERVE_REGS)    /* qemu_st8_i32 data */
  */
 CONST('e', TCG_CT_CONST_S32)
 CONST('I', TCG_CT_CONST_I32)
+CONST('T', TCG_CT_CONST_TST)
 CONST('W', TCG_CT_CONST_WSZ)
 CONST('Z', TCG_CT_CONST_U32)
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index 17b250f16f..3d7306b341 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -132,6 +132,7 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
 #define TCG_CT_CONST_U32 0x200
 #define TCG_CT_CONST_I32 0x400
 #define TCG_CT_CONST_WSZ 0x800
+#define TCG_CT_CONST_TST 0x1000
 
 /* Registers used with L constraint, which are the first argument
    registers on x86_64, and two random call clobbered registers on
@@ -202,7 +203,8 @@ static bool tcg_target_const_match(int64_t val, int ct,
         return 1;
     }
     if (type == TCG_TYPE_I32) {
-        if (ct & (TCG_CT_CONST_S32 | TCG_CT_CONST_U32 | TCG_CT_CONST_I32)) {
+        if (ct & (TCG_CT_CONST_S32 | TCG_CT_CONST_U32 |
+                  TCG_CT_CONST_I32 | TCG_CT_CONST_TST)) {
             return 1;
         }
     } else {
@@ -215,6 +217,17 @@ static bool tcg_target_const_match(int64_t val, int ct,
         if ((ct & TCG_CT_CONST_I32) && ~val == (int32_t)~val) {
             return 1;
         }
+        /*
+         * This will be used in combination with TCG_CT_CONST_S32,
+         * so "normal" TESTQ is already matched.  Also accept:
+         *    TESTQ -> TESTL   (uint32_t)
+         *    TESTQ -> BT      (is_power_of_2)
+         */
+        if ((ct & TCG_CT_CONST_TST)
+            && is_tst_cond(cond)
+            && (val == (uint32_t)val || is_power_of_2(val))) {
+            return 1;
+        }
     }
     if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
         return 1;
@@ -395,6 +408,7 @@ static bool tcg_target_const_match(int64_t val, int ct,
 #define OPC_SHLX        (0xf7 | P_EXT38 | P_DATA16)
 #define OPC_SHRX        (0xf7 | P_EXT38 | P_SIMDF2)
 #define OPC_SHRD_Ib     (0xac | P_EXT)
+#define OPC_TESTB	(0x84)
 #define OPC_TESTL	(0x85)
 #define OPC_TZCNT       (0xbc | P_EXT | P_SIMDF3)
 #define OPC_UD2         (0x0b | P_EXT)
@@ -441,6 +455,12 @@ static bool tcg_target_const_match(int64_t val, int ct,
 #define OPC_GRP3_Ev     (0xf7)
 #define OPC_GRP5        (0xff)
 #define OPC_GRP14       (0x73 | P_EXT | P_DATA16)
+#define OPC_GRPBT       (0xba | P_EXT)
+
+#define OPC_GRPBT_BT    4
+#define OPC_GRPBT_BTS   5
+#define OPC_GRPBT_BTR   6
+#define OPC_GRPBT_BTC   7
 
 /* Group 1 opcode extensions for 0x80-0x83.
    These are also used as modifiers for OPC_ARITH.  */
@@ -1433,6 +1453,34 @@ static int tcg_out_cmp(TCGContext *s, TCGCond cond, TCGArg arg1,
         } else if ((arg2 & ~0xff00) == 0 && arg1 < 4) {
             tcg_out_modrm(s, OPC_GRP3_Eb, EXT3_TESTi, arg1 + 4);
             tcg_out8(s, arg2 >> 8);
+        } else if (is_power_of_2(rexw ? arg2 : (uint32_t)arg2)) {
+            int js = (cond == TCG_COND_TSTNE ? JCC_JS : JCC_JNS);
+            int sh = ctz64(arg2);
+
+            switch (sh) {
+            case 7:
+                if (TCG_TARGET_REG_BITS == 64 || arg1 < 4) {
+                    tcg_out_modrm(s, OPC_TESTB | P_REXB_R, arg1, arg1);
+                    return js;
+                }
+                break;
+            case 15:
+                if (arg1 < 4) {
+                    tcg_out_modrm(s, OPC_TESTB, arg1 + 4, arg1 + 4);
+                } else {
+                    tcg_out_modrm(s, OPC_TESTL | P_DATA16, arg1, arg1);
+                }
+                return js;
+            case 31:
+                tcg_out_modrm(s, OPC_TESTL | P_DATA16, arg1, arg1);
+                return js;
+            case 63:
+                tcg_out_modrm(s, OPC_TESTL | P_REXW, arg1, arg1);
+                return js;
+            }
+            rexw = sh >= 32;
+            tcg_out_modrm(s, OPC_GRPBT + rexw, OPC_GRPBT_BT, arg1);
+            tcg_out8(s, sh);
         } else {
             if (rexw) {
                 if (arg2 == (uint32_t)arg2) {
@@ -3357,7 +3405,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 
     case INDEX_op_brcond_i32:
     case INDEX_op_brcond_i64:
-        return C_O0_I2(r, re);
+        return C_O0_I2(r, reT);
 
     case INDEX_op_bswap16_i32:
     case INDEX_op_bswap16_i64:
@@ -3405,11 +3453,11 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_setcond_i64:
     case INDEX_op_negsetcond_i32:
     case INDEX_op_negsetcond_i64:
-        return C_O1_I2(q, r, re);
+        return C_O1_I2(q, r, reT);
 
     case INDEX_op_movcond_i32:
     case INDEX_op_movcond_i64:
-        return C_O1_I4(r, r, re, r, 0);
+        return C_O1_I4(r, r, reT, r, 0);
 
     case INDEX_op_div2_i32:
     case INDEX_op_div2_i64:
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 16/35] tcg/loongarch64: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (14 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 15/35] tcg/i386: Improve TSTNE/TESTEQ vs powers of two Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-17  7:48   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 17/35] tcg/mips: " Richard Henderson
                   ` (20 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/loongarch64/tcg-target.c.inc | 56 ++++++++++++++++++++++----------
 1 file changed, 38 insertions(+), 18 deletions(-)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 384d2ba342..7770e1bfa0 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -556,6 +556,7 @@ static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
     case TCG_COND_GEU:   /* -> LTU */
     case TCG_COND_GT:    /* -> LE  */
     case TCG_COND_GTU:   /* -> LEU */
+    case TCG_COND_TSTEQ: /* -> TSTNE */
         cond = tcg_invert_cond(cond);
         flags ^= SETCOND_INV;
         break;
@@ -612,6 +613,18 @@ static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
         }
         break;
 
+    case TCG_COND_TSTNE:
+        flags |= SETCOND_NEZ;
+        if (!c2) {
+            tcg_out_opc_and(s, ret, arg1, arg2);
+        } else if (arg2 >= 0 && arg2 <= 0xfff) {
+            tcg_out_opc_andi(s, ret, arg1, arg2);
+        } else {
+            tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_TMP0, arg2);
+            tcg_out_opc_and(s, ret, arg1, TCG_REG_TMP0);
+        }
+        break;
+
     case TCG_COND_LT:
     case TCG_COND_LTU:
         if (c2) {
@@ -696,29 +709,36 @@ static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
  * Branch helpers
  */
 
-static const struct {
-    LoongArchInsn op;
-    bool swap;
-} tcg_brcond_to_loongarch[] = {
-    [TCG_COND_EQ] =  { OPC_BEQ,  false },
-    [TCG_COND_NE] =  { OPC_BNE,  false },
-    [TCG_COND_LT] =  { OPC_BGT,  true  },
-    [TCG_COND_GE] =  { OPC_BLE,  true  },
-    [TCG_COND_LE] =  { OPC_BLE,  false },
-    [TCG_COND_GT] =  { OPC_BGT,  false },
-    [TCG_COND_LTU] = { OPC_BGTU, true  },
-    [TCG_COND_GEU] = { OPC_BLEU, true  },
-    [TCG_COND_LEU] = { OPC_BLEU, false },
-    [TCG_COND_GTU] = { OPC_BGTU, false }
-};
-
 static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
                            TCGReg arg2, TCGLabel *l)
 {
-    LoongArchInsn op = tcg_brcond_to_loongarch[cond].op;
+    static const struct {
+        LoongArchInsn op;
+        bool swap;
+    } tcg_brcond_to_loongarch[16] = {
+        [TCG_COND_EQ] =  { OPC_BEQ,  false },
+        [TCG_COND_NE] =  { OPC_BNE,  false },
+        [TCG_COND_LT] =  { OPC_BGT,  true  },
+        [TCG_COND_GE] =  { OPC_BLE,  true  },
+        [TCG_COND_LE] =  { OPC_BLE,  false },
+        [TCG_COND_GT] =  { OPC_BGT,  false },
+        [TCG_COND_LTU] = { OPC_BGTU, true  },
+        [TCG_COND_GEU] = { OPC_BLEU, true  },
+        [TCG_COND_LEU] = { OPC_BLEU, false },
+        [TCG_COND_GTU] = { OPC_BGTU, false }
+    };
 
+    LoongArchInsn op;
+
+    if (is_tst_cond(cond)) {
+        tcg_out_opc_and(s, TCG_REG_TMP0, arg1, arg2);
+        arg1 = TCG_REG_TMP0;
+        arg2 = TCG_REG_ZERO;
+        cond = tcg_tst_eqne_cond(cond);
+    }
+
+    op = tcg_brcond_to_loongarch[cond].op
     tcg_debug_assert(op != 0);
-
     if (tcg_brcond_to_loongarch[cond].swap) {
         TCGReg t = arg1;
         arg1 = arg2;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 17/35] tcg/mips: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (15 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 16/35] tcg/loongarch64: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-17  7:46   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 18/35] tcg/riscv: " Richard Henderson
                   ` (19 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/mips/tcg-target.c.inc | 41 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc
index 35eff82bb3..f5680d7b89 100644
--- a/tcg/mips/tcg-target.c.inc
+++ b/tcg/mips/tcg-target.c.inc
@@ -910,6 +910,16 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
         tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
         break;
 
+    case TCG_COND_TSTEQ:
+        tcg_out_opc_reg(s, OPC_AND, ret, arg1, arg2);
+        tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
+        break;
+
+    case TCG_COND_TSTNE:
+        tcg_out_opc_reg(s, OPC_AND, ret, arg1, arg2);
+        tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
+        break;
+
     case TCG_COND_LT:
     case TCG_COND_GE:
     case TCG_COND_LE:
@@ -990,6 +1000,14 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
         arg2 = TCG_REG_ZERO;
         break;
 
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        tcg_out_opc_reg(s, OPC_AND, TCG_TMP0, arg1, arg2);
+        arg1 = TCG_TMP0;
+        arg2 = TCG_REG_ZERO;
+        b_opc = cond == TCG_COND_TSTEQ ? OPC_BEQ : OPC_BNE;
+        break;
+
     default:
         g_assert_not_reached();
         break;
@@ -1053,6 +1071,14 @@ static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
         tcg_out_setcond(s, cond, ret, tmp1, TCG_REG_ZERO);
         break;
 
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        tcg_out_opc_reg(s, OPC_AND, TCG_TMP0, al, bl);
+        tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, ah, bh);
+        tcg_out_opc_reg(s, OPC_OR, ret, TCG_TMP0, TCG_TMP1);
+        tcg_out_setcond(s, tcg_eqne_cond(cond), ret, tmp1, TCG_REG_ZERO);
+        break;
+
     default:
         tcg_out_setcond(s, TCG_COND_EQ, tmp0, ah, bh);
         tcg_out_setcond(s, tcg_unsigned_cond(cond), tmp1, al, bl);
@@ -1079,6 +1105,13 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
         tmp = tcg_out_reduce_eq2(s, TCG_TMP0, TCG_TMP1, al, ah, bl, bh);
         break;
 
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        tcg_out_opc_reg(s, OPC_AND, TCG_TMP0, al, bl);
+        tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, ah, bh);
+        tcg_out_opc_reg(s, OPC_OR, TCG_TMP1, TCG_TMP1, TCG_TMP0);
+        break;
+
     default:
         /* Minimize code size by preferring a compare not requiring INV.  */
         if (mips_cmp_map[cond] & MIPS_CMP_INV) {
@@ -1115,6 +1148,14 @@ static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
         }
         break;
 
+    case TCG_COND_TSTEQ:
+        eqz = true;
+        /* FALLTHRU */
+    case TCG_COND_TSTNE:
+        tcg_out_opc_reg(s, OPC_AND, TCG_TMP0, c1, c2);
+        c1 = TCG_TMP0;
+        break;
+
     default:
         /* Minimize code size by preferring a compare not requiring INV.  */
         if (mips_cmp_map[cond] & MIPS_CMP_INV) {
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 18/35] tcg/riscv: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (16 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 17/35] tcg/mips: " Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-06 20:59   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 19/35] tcg/sparc64: Implement tcg_out_extrl_i64_i32 Richard Henderson
                   ` (18 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/riscv/tcg-target.c.inc | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 639363039b..358579b3fd 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -799,8 +799,14 @@ static const struct {
 static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
                            TCGReg arg2, TCGLabel *l)
 {
-    RISCVInsn op = tcg_brcond_to_riscv[cond].op;
+    RISCVInsn op;
 
+    if (is_tst_cond(cond)) {
+        tcg_out_opc_reg(s, OPC_AND, TCG_REG_TMP0, arg1, arg2);
+        cond = tcg_tst_eqne_cond(cond);
+    }
+
+    op = tcg_brcond_to_riscv[cond].op;
     tcg_debug_assert(op != 0);
 
     if (tcg_brcond_to_riscv[cond].swap) {
@@ -828,6 +834,7 @@ static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
     case TCG_COND_GEU:   /* -> LTU */
     case TCG_COND_GT:    /* -> LE  */
     case TCG_COND_GTU:   /* -> LEU */
+    case TCG_COND_TSTEQ: /* -> TSTNE */
         cond = tcg_invert_cond(cond);
         flags ^= SETCOND_INV;
         break;
@@ -887,6 +894,15 @@ static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
         }
         break;
 
+    case TCG_COND_TSTNE:
+        flags |= SETCOND_NEZ;
+        if (c2) {
+            tcg_out_opc_imm(s, OPC_ANDI, ret, arg1, arg2);
+        } else {
+            tcg_out_opc_reg(s, OPC_AND, ret, arg1, arg2);
+        }
+        break;
+
     case TCG_COND_LT:
         if (c2) {
             tcg_out_opc_imm(s, OPC_SLTI, ret, arg1, arg2);
@@ -1080,7 +1096,7 @@ static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
     int tmpflags;
     TCGReg t;
 
-    if (!have_zicond && (!c_cmp2 || cmp2 == 0)) {
+    if (!have_zicond && (!c_cmp2 || cmp2 == 0) && !is_tst_cond(cond)) {
         tcg_out_movcond_br2(s, cond, ret, cmp1, cmp2,
                             val1, c_val1, val2, c_val2);
         return;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 19/35] tcg/sparc64: Implement tcg_out_extrl_i64_i32
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (17 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 18/35] tcg/riscv: " Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-06 15:05   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 20/35] tcg/sparc64: Hoist read of tcg_cond_to_rcond Richard Henderson
                   ` (17 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini, qemu-stable

Build fix for missing symbol.

Cc: qemu-stable@nongnu.org
Fixes: b8b94ac6753 ("tcg: Split out tcg_out_extrl_i64_i32")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/sparc64/tcg-target.c.inc | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index 386f51f29e..ac86b92b75 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -530,6 +530,11 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
     tcg_out_ext32u(s, rd, rs);
 }
 
+static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
+{
+    tcg_out_ext32u(s, rd, rs);
+}
+
 static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
 {
     return false;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 20/35] tcg/sparc64: Hoist read of tcg_cond_to_rcond
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (18 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 19/35] tcg/sparc64: Implement tcg_out_extrl_i64_i32 Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-06 21:02   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 21/35] tcg/sparc64: Pass TCGCond to tcg_out_cmp Richard Henderson
                   ` (16 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Use a non-zero value here (an illegal encoding) as a better
condition than is_unsigned_cond for when MOVR/BPR is usable.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/sparc64/tcg-target.c.inc | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index ac86b92b75..e16b25e309 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -620,7 +620,7 @@ static const uint8_t tcg_cond_to_bcond[] = {
     [TCG_COND_GTU] = COND_GU,
 };
 
-static const uint8_t tcg_cond_to_rcond[] = {
+static const uint8_t tcg_cond_to_rcond[16] = {
     [TCG_COND_EQ] = RCOND_Z,
     [TCG_COND_NE] = RCOND_NZ,
     [TCG_COND_LT] = RCOND_LZ,
@@ -679,7 +679,8 @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
                                int32_t arg2, int const_arg2, TCGLabel *l)
 {
     /* For 64-bit signed comparisons vs zero, we can avoid the compare.  */
-    if (arg2 == 0 && !is_unsigned_cond(cond)) {
+    int rcond = tcg_cond_to_rcond[cond];
+    if (arg2 == 0 && rcond) {
         int off16 = 0;
 
         if (l->has_value) {
@@ -688,7 +689,7 @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
             tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, l, 0);
         }
         tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
-                  | INSN_COND(tcg_cond_to_rcond[cond]) | off16);
+                  | INSN_COND(rcond) | off16);
     } else {
         tcg_out_cmp(s, arg1, arg2, const_arg2);
         tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, l);
@@ -696,11 +697,10 @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
     tcg_out_nop(s);
 }
 
-static void tcg_out_movr(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg c1,
+static void tcg_out_movr(TCGContext *s, int rcond, TCGReg ret, TCGReg c1,
                          int32_t v1, int v1const)
 {
-    tcg_out32(s, ARITH_MOVR | INSN_RD(ret) | INSN_RS1(c1)
-              | (tcg_cond_to_rcond[cond] << 10)
+    tcg_out32(s, ARITH_MOVR | INSN_RD(ret) | INSN_RS1(c1) | (rcond << 10)
               | (v1const ? INSN_IMM10(v1) : INSN_RS2(v1)));
 }
 
@@ -711,9 +711,9 @@ static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
     /* For 64-bit signed comparisons vs zero, we can avoid the compare.
        Note that the immediate range is one bit smaller, so we must check
        for that as well.  */
-    if (c2 == 0 && !is_unsigned_cond(cond)
-        && (!v1const || check_fit_i32(v1, 10))) {
-        tcg_out_movr(s, cond, ret, c1, v1, v1const);
+    int rcond = tcg_cond_to_rcond[cond];
+    if (c2 == 0 && rcond && (!v1const || check_fit_i32(v1, 10))) {
+        tcg_out_movr(s, rcond, ret, c1, v1, v1const);
     } else {
         tcg_out_cmp(s, c1, c2, c2const);
         tcg_out_movcc(s, cond, MOVCC_XCC, ret, v1, v1const);
@@ -788,6 +788,8 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
 static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
                                 TCGReg c1, int32_t c2, int c2const, bool neg)
 {
+    int rcond;
+
     if (use_vis3_instructions && !neg) {
         switch (cond) {
         case TCG_COND_NE:
@@ -807,9 +809,10 @@ static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
 
     /* For 64-bit signed comparisons vs zero, we can avoid the compare
        if the input does not overlap the output.  */
-    if (c2 == 0 && !is_unsigned_cond(cond) && c1 != ret) {
+    rcond = tcg_cond_to_rcond[cond];
+    if (c2 == 0 && rcond && c1 != ret) {
         tcg_out_movi_s13(s, ret, 0);
-        tcg_out_movr(s, cond, ret, c1, neg ? -1 : 1, 1);
+        tcg_out_movr(s, rcond, ret, c1, neg ? -1 : 1, 1);
     } else {
         tcg_out_cmp(s, c1, c2, c2const);
         tcg_out_movi_s13(s, ret, 0);
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 21/35] tcg/sparc64: Pass TCGCond to tcg_out_cmp
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (19 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 20/35] tcg/sparc64: Hoist read of tcg_cond_to_rcond Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-09 11:29   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 22/35] tcg/sparc64: Support TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (15 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/sparc64/tcg-target.c.inc | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index e16b25e309..10fb8a1a0d 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -646,7 +646,8 @@ static void tcg_out_bpcc(TCGContext *s, int scond, int flags, TCGLabel *l)
     tcg_out_bpcc0(s, scond, flags, off19);
 }
 
-static void tcg_out_cmp(TCGContext *s, TCGReg c1, int32_t c2, int c2const)
+static void tcg_out_cmp(TCGContext *s, TCGCond cond,
+                        TCGReg c1, int32_t c2, int c2const)
 {
     tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
 }
@@ -654,7 +655,7 @@ static void tcg_out_cmp(TCGContext *s, TCGReg c1, int32_t c2, int c2const)
 static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGReg arg1,
                                int32_t arg2, int const_arg2, TCGLabel *l)
 {
-    tcg_out_cmp(s, arg1, arg2, const_arg2);
+    tcg_out_cmp(s, cond, arg1, arg2, const_arg2);
     tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_ICC | BPCC_PT, l);
     tcg_out_nop(s);
 }
@@ -671,7 +672,7 @@ static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
                                 TCGReg c1, int32_t c2, int c2const,
                                 int32_t v1, int v1const)
 {
-    tcg_out_cmp(s, c1, c2, c2const);
+    tcg_out_cmp(s, cond, c1, c2, c2const);
     tcg_out_movcc(s, cond, MOVCC_ICC, ret, v1, v1const);
 }
 
@@ -691,7 +692,7 @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
         tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
                   | INSN_COND(rcond) | off16);
     } else {
-        tcg_out_cmp(s, arg1, arg2, const_arg2);
+        tcg_out_cmp(s, cond, arg1, arg2, const_arg2);
         tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, l);
     }
     tcg_out_nop(s);
@@ -715,7 +716,7 @@ static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
     if (c2 == 0 && rcond && (!v1const || check_fit_i32(v1, 10))) {
         tcg_out_movr(s, rcond, ret, c1, v1, v1const);
     } else {
-        tcg_out_cmp(s, c1, c2, c2const);
+        tcg_out_cmp(s, cond, c1, c2, c2const);
         tcg_out_movcc(s, cond, MOVCC_XCC, ret, v1, v1const);
     }
 }
@@ -759,13 +760,13 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
         /* FALLTHRU */
 
     default:
-        tcg_out_cmp(s, c1, c2, c2const);
+        tcg_out_cmp(s, cond, c1, c2, c2const);
         tcg_out_movi_s13(s, ret, 0);
         tcg_out_movcc(s, cond, MOVCC_ICC, ret, neg ? -1 : 1, 1);
         return;
     }
 
-    tcg_out_cmp(s, c1, c2, c2const);
+    tcg_out_cmp(s, cond, c1, c2, c2const);
     if (cond == TCG_COND_LTU) {
         if (neg) {
             /* 0 - 0 - C = -C = (C ? -1 : 0) */
@@ -799,7 +800,7 @@ static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
             c2 = c1, c2const = 0, c1 = TCG_REG_G0;
             /* FALLTHRU */
         case TCG_COND_LTU:
-            tcg_out_cmp(s, c1, c2, c2const);
+            tcg_out_cmp(s, cond, c1, c2, c2const);
             tcg_out_arith(s, ret, TCG_REG_G0, TCG_REG_G0, ARITH_ADDXC);
             return;
         default:
@@ -814,7 +815,7 @@ static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
         tcg_out_movi_s13(s, ret, 0);
         tcg_out_movr(s, rcond, ret, c1, neg ? -1 : 1, 1);
     } else {
-        tcg_out_cmp(s, c1, c2, c2const);
+        tcg_out_cmp(s, cond, c1, c2, c2const);
         tcg_out_movi_s13(s, ret, 0);
         tcg_out_movcc(s, cond, MOVCC_XCC, ret, neg ? -1 : 1, 1);
     }
@@ -1102,7 +1103,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
         tcg_out_movi_s32(s, TCG_REG_T3, compare_mask);
         tcg_out_arith(s, TCG_REG_T3, addr_reg, TCG_REG_T3, ARITH_AND);
     }
-    tcg_out_cmp(s, TCG_REG_T2, TCG_REG_T3, 0);
+    tcg_out_cmp(s, TCG_COND_NE, TCG_REG_T2, TCG_REG_T3, 0);
 
     ldst = new_ldst_label(s);
     ldst->is_ld = is_ld;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 22/35] tcg/sparc64: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (20 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 21/35] tcg/sparc64: Pass TCGCond to tcg_out_cmp Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-06 21:07   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 23/35] tcg/ppc: Sink tcg_to_bc usage into tcg_out_bc Richard Henderson
                   ` (14 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/sparc64/tcg-target.c.inc | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index 10fb8a1a0d..176c98740b 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -607,9 +607,11 @@ static void tcg_out_div32(TCGContext *s, TCGReg rd, TCGReg rs1,
                    uns ? ARITH_UDIV : ARITH_SDIV);
 }
 
-static const uint8_t tcg_cond_to_bcond[] = {
+static const uint8_t tcg_cond_to_bcond[16] = {
     [TCG_COND_EQ] = COND_E,
     [TCG_COND_NE] = COND_NE,
+    [TCG_COND_TSTEQ] = COND_E,
+    [TCG_COND_TSTNE] = COND_NE,
     [TCG_COND_LT] = COND_L,
     [TCG_COND_GE] = COND_GE,
     [TCG_COND_LE] = COND_LE,
@@ -649,7 +651,8 @@ static void tcg_out_bpcc(TCGContext *s, int scond, int flags, TCGLabel *l)
 static void tcg_out_cmp(TCGContext *s, TCGCond cond,
                         TCGReg c1, int32_t c2, int c2const)
 {
-    tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
+    tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const,
+                   is_tst_cond(cond) ? ARITH_ANDCC : ARITH_SUBCC);
 }
 
 static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGReg arg1,
@@ -744,6 +747,15 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
         cond = (cond == TCG_COND_EQ ? TCG_COND_GEU : TCG_COND_LTU);
 	break;
 
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        /* Transform to inequality vs zero.  */
+        tcg_out_arithc(s, TCG_REG_T1, c1, c2, c2const, ARITH_AND);
+        c1 = TCG_REG_G0;
+        c2 = TCG_REG_T1, c2const = 0;
+        cond = (cond == TCG_COND_TSTEQ ? TCG_COND_GEU : TCG_COND_LTU);
+	break;
+
     case TCG_COND_GTU:
     case TCG_COND_LEU:
         /* If we don't need to load a constant into a register, we can
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 23/35] tcg/ppc: Sink tcg_to_bc usage into tcg_out_bc
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (21 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 22/35] tcg/sparc64: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-06 18:54   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 24/35] tcg/ppc: Use cr0 in tcg_to_bc and tcg_to_isel Richard Henderson
                   ` (13 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Rename the current tcg_out_bc function to tcg_out_bc_lab, and
create a new function that takes an integer displacement + link.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/ppc/tcg-target.c.inc | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index a5871f55b1..ca281dd33e 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -1946,14 +1946,20 @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
     }
 }
 
-static void tcg_out_bc(TCGContext *s, int bc, TCGLabel *l)
+static void tcg_out_bc(TCGContext *s, TCGCond cond, int bd)
 {
+    tcg_out32(s, tcg_to_bc[cond] | bd);
+}
+
+static void tcg_out_bc_lab(TCGContext *s, TCGCond cond, TCGLabel *l)
+{
+    int bd = 0;
     if (l->has_value) {
-        bc |= reloc_pc14_val(tcg_splitwx_to_rx(s->code_ptr), l->u.value_ptr);
+        bd = reloc_pc14_val(tcg_splitwx_to_rx(s->code_ptr), l->u.value_ptr);
     } else {
         tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, l, 0);
     }
-    tcg_out32(s, bc);
+    tcg_out_bc(s, cond, bd);
 }
 
 static void tcg_out_brcond(TCGContext *s, TCGCond cond,
@@ -1961,7 +1967,7 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond,
                            TCGLabel *l, TCGType type)
 {
     tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
-    tcg_out_bc(s, tcg_to_bc[cond], l);
+    tcg_out_bc_lab(s, cond, l);
 }
 
 static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
@@ -2003,7 +2009,7 @@ static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
             }
         }
         /* Branch forward over one insn */
-        tcg_out32(s, tcg_to_bc[cond] | 8);
+        tcg_out_bc(s, cond, 8);
         if (v2 == 0) {
             tcg_out_movi(s, type, dest, 0);
         } else {
@@ -2024,11 +2030,11 @@ static void tcg_out_cntxz(TCGContext *s, TCGType type, uint32_t opc,
             tcg_out32(s, opc | RA(TCG_REG_R0) | RS(a1));
             tcg_out32(s, tcg_to_isel[TCG_COND_EQ] | TAB(a0, a2, TCG_REG_R0));
         } else if (!const_a2 && a0 == a2) {
-            tcg_out32(s, tcg_to_bc[TCG_COND_EQ] | 8);
+            tcg_out_bc(s, TCG_COND_EQ, 8);
             tcg_out32(s, opc | RA(a0) | RS(a1));
         } else {
             tcg_out32(s, opc | RA(a0) | RS(a1));
-            tcg_out32(s, tcg_to_bc[TCG_COND_NE] | 8);
+            tcg_out_bc(s, TCG_COND_NE, 8);
             if (const_a2) {
                 tcg_out_movi(s, type, a0, 0);
             } else {
@@ -2108,11 +2114,11 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
     tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, 31, 31, 31);
 }
 
-static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
-                             const int *const_args)
+static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
+                            const int *const_args)
 {
     tcg_out_cmp2(s, args, const_args);
-    tcg_out_bc(s, BC | BI(7, CR_EQ) | BO_COND_TRUE, arg_label(args[5]));
+    tcg_out_bc_lab(s, TCG_COND_EQ, arg_label(args[5]));
 }
 
 static void tcg_out_mb(TCGContext *s, TCGArg a0)
@@ -2446,7 +2452,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
 
         /* Load a pointer into the current opcode w/conditional branch-link. */
         ldst->label_ptr[0] = s->code_ptr;
-        tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
+        tcg_out_bc(s, TCG_COND_NE, LK);
 
         h->base = TCG_REG_TMP1;
     } else {
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 24/35] tcg/ppc: Use cr0 in tcg_to_bc and tcg_to_isel
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (22 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 23/35] tcg/ppc: Sink tcg_to_bc usage into tcg_out_bc Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-10-28 19:45 ` [PATCH v2 25/35] tcg/ppc: Tidy up tcg_target_const_match Richard Henderson
                   ` (12 subsequent siblings)
  36 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Using cr0 means we could choose to use rc=1 to compute the condition.
Adjust the tables and tcg_out_cmp that feeds them.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/ppc/tcg-target.c.inc | 68 ++++++++++++++++++++--------------------
 1 file changed, 34 insertions(+), 34 deletions(-)

diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index ca281dd33e..1ac11acc7c 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -671,30 +671,30 @@ enum {
 };
 
 static const uint32_t tcg_to_bc[] = {
-    [TCG_COND_EQ]  = BC | BI(7, CR_EQ) | BO_COND_TRUE,
-    [TCG_COND_NE]  = BC | BI(7, CR_EQ) | BO_COND_FALSE,
-    [TCG_COND_LT]  = BC | BI(7, CR_LT) | BO_COND_TRUE,
-    [TCG_COND_GE]  = BC | BI(7, CR_LT) | BO_COND_FALSE,
-    [TCG_COND_LE]  = BC | BI(7, CR_GT) | BO_COND_FALSE,
-    [TCG_COND_GT]  = BC | BI(7, CR_GT) | BO_COND_TRUE,
-    [TCG_COND_LTU] = BC | BI(7, CR_LT) | BO_COND_TRUE,
-    [TCG_COND_GEU] = BC | BI(7, CR_LT) | BO_COND_FALSE,
-    [TCG_COND_LEU] = BC | BI(7, CR_GT) | BO_COND_FALSE,
-    [TCG_COND_GTU] = BC | BI(7, CR_GT) | BO_COND_TRUE,
+    [TCG_COND_EQ]  = BC | BI(0, CR_EQ) | BO_COND_TRUE,
+    [TCG_COND_NE]  = BC | BI(0, CR_EQ) | BO_COND_FALSE,
+    [TCG_COND_LT]  = BC | BI(0, CR_LT) | BO_COND_TRUE,
+    [TCG_COND_GE]  = BC | BI(0, CR_LT) | BO_COND_FALSE,
+    [TCG_COND_LE]  = BC | BI(0, CR_GT) | BO_COND_FALSE,
+    [TCG_COND_GT]  = BC | BI(0, CR_GT) | BO_COND_TRUE,
+    [TCG_COND_LTU] = BC | BI(0, CR_LT) | BO_COND_TRUE,
+    [TCG_COND_GEU] = BC | BI(0, CR_LT) | BO_COND_FALSE,
+    [TCG_COND_LEU] = BC | BI(0, CR_GT) | BO_COND_FALSE,
+    [TCG_COND_GTU] = BC | BI(0, CR_GT) | BO_COND_TRUE,
 };
 
 /* The low bit here is set if the RA and RB fields must be inverted.  */
 static const uint32_t tcg_to_isel[] = {
-    [TCG_COND_EQ]  = ISEL | BC_(7, CR_EQ),
-    [TCG_COND_NE]  = ISEL | BC_(7, CR_EQ) | 1,
-    [TCG_COND_LT]  = ISEL | BC_(7, CR_LT),
-    [TCG_COND_GE]  = ISEL | BC_(7, CR_LT) | 1,
-    [TCG_COND_LE]  = ISEL | BC_(7, CR_GT) | 1,
-    [TCG_COND_GT]  = ISEL | BC_(7, CR_GT),
-    [TCG_COND_LTU] = ISEL | BC_(7, CR_LT),
-    [TCG_COND_GEU] = ISEL | BC_(7, CR_LT) | 1,
-    [TCG_COND_LEU] = ISEL | BC_(7, CR_GT) | 1,
-    [TCG_COND_GTU] = ISEL | BC_(7, CR_GT),
+    [TCG_COND_EQ]  = ISEL | BC_(0, CR_EQ),
+    [TCG_COND_NE]  = ISEL | BC_(0, CR_EQ) | 1,
+    [TCG_COND_LT]  = ISEL | BC_(0, CR_LT),
+    [TCG_COND_GE]  = ISEL | BC_(0, CR_LT) | 1,
+    [TCG_COND_LE]  = ISEL | BC_(0, CR_GT) | 1,
+    [TCG_COND_GT]  = ISEL | BC_(0, CR_GT),
+    [TCG_COND_LTU] = ISEL | BC_(0, CR_LT),
+    [TCG_COND_GEU] = ISEL | BC_(0, CR_LT) | 1,
+    [TCG_COND_LEU] = ISEL | BC_(0, CR_GT) | 1,
+    [TCG_COND_GTU] = ISEL | BC_(0, CR_GT),
 };
 
 static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
@@ -1827,7 +1827,7 @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
     if (have_isa_3_10) {
         tcg_insn_unit bi, opc;
 
-        tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
+        tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 0, type);
 
         /* Re-use tcg_to_bc for BI and BO_COND_{TRUE,FALSE}. */
         bi = tcg_to_bc[cond] & (0x1f << 16);
@@ -1880,7 +1880,7 @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
     if (have_isel) {
         int isel, tab;
 
-        tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
+        tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 0, type);
 
         isel = tcg_to_isel[cond];
 
@@ -1966,7 +1966,7 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond,
                            TCGArg arg1, TCGArg arg2, int const_arg2,
                            TCGLabel *l, TCGType type)
 {
-    tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
+    tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 0, type);
     tcg_out_bc_lab(s, cond, l);
 }
 
@@ -1980,7 +1980,7 @@ static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
         return;
     }
 
-    tcg_out_cmp(s, cond, c1, c2, const_c2, 7, type);
+    tcg_out_cmp(s, cond, c1, c2, const_c2, 0, type);
 
     if (have_isel) {
         int isel = tcg_to_isel[cond];
@@ -2024,7 +2024,7 @@ static void tcg_out_cntxz(TCGContext *s, TCGType type, uint32_t opc,
     if (const_a2 && a2 == (type == TCG_TYPE_I32 ? 32 : 64)) {
         tcg_out32(s, opc | RA(a0) | RS(a1));
     } else {
-        tcg_out_cmp(s, TCG_COND_EQ, a1, 0, 1, 7, type);
+        tcg_out_cmp(s, TCG_COND_EQ, a1, 0, 1, 0, type);
         /* Note that the only other valid constant for a2 is 0.  */
         if (have_isel) {
             tcg_out32(s, opc | RA(TCG_REG_R0) | RS(a1));
@@ -2079,7 +2079,7 @@ static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
     do_equality:
         tcg_out_cmp(s, cond, al, bl, blconst, 6, TCG_TYPE_I32);
         tcg_out_cmp(s, cond, ah, bh, bhconst, 7, TCG_TYPE_I32);
-        tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
+        tcg_out32(s, op | BT(0, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
         break;
 
     case TCG_COND_LT:
@@ -2097,8 +2097,8 @@ static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
 
         tcg_out_cmp(s, cond, ah, bh, bhconst, 6, TCG_TYPE_I32);
         tcg_out_cmp(s, cond2, al, bl, blconst, 7, TCG_TYPE_I32);
-        tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, bit2));
-        tcg_out32(s, CROR | BT(7, CR_EQ) | BA(6, bit1) | BB(7, CR_EQ));
+        tcg_out32(s, op | BT(0, CR_EQ) | BA(6, CR_EQ) | BB(7, bit2));
+        tcg_out32(s, CROR | BT(0, CR_EQ) | BA(6, bit1) | BB(0, CR_EQ));
         break;
 
     default:
@@ -2110,8 +2110,8 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
                              const int *const_args)
 {
     tcg_out_cmp2(s, args + 1, const_args + 1);
-    tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
-    tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, 31, 31, 31);
+    tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(0));
+    tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, CR_EQ + 0*4 + 1, 31, 31);
 }
 
 static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
@@ -2442,12 +2442,12 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
             tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_TMP2,
                         0, 6, TCG_TYPE_I32);
 
-            /* Combine comparisons into cr7. */
-            tcg_out32(s, CRAND | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
+            /* Combine comparisons into cr0. */
+            tcg_out32(s, CRAND | BT(0, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
         } else {
-            /* Full comparison into cr7. */
+            /* Full comparison into cr0. */
             tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP2,
-                        0, 7, addr_type);
+                        0, 0, addr_type);
         }
 
         /* Load a pointer into the current opcode w/conditional branch-link. */
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 25/35] tcg/ppc: Tidy up tcg_target_const_match
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (23 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 24/35] tcg/ppc: Use cr0 in tcg_to_bc and tcg_to_isel Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-06 21:08   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 26/35] tcg/ppc: Add TCG_CT_CONST_CMP Richard Henderson
                   ` (11 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/ppc/tcg-target.c.inc | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index 1ac11acc7c..13d43ef9ba 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -282,31 +282,36 @@ static bool reloc_pc34(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
 }
 
 /* test if a constant matches the constraint */
-static bool tcg_target_const_match(int64_t val, int ct,
+static bool tcg_target_const_match(int64_t sval, int ct,
                                    TCGType type, TCGCond cond, int vece)
 {
+    uint64_t uval = sval;
+
     if (ct & TCG_CT_CONST) {
         return 1;
     }
 
-    /* The only 32-bit constraint we use aside from
-       TCG_CT_CONST is TCG_CT_CONST_S16.  */
     if (type == TCG_TYPE_I32) {
-        val = (int32_t)val;
+        uval = (uint32_t)sval;
+        sval = (int32_t)sval;
     }
 
-    if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
+    if ((ct & TCG_CT_CONST_S16) && sval == (int16_t)sval) {
         return 1;
-    } else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
+    }
+    if ((ct & TCG_CT_CONST_S32) && sval == (int32_t)sval) {
         return 1;
-    } else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
+    }
+    if ((ct & TCG_CT_CONST_U32) && uval == (uint32_t)uval) {
         return 1;
-    } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
+    }
+    if ((ct & TCG_CT_CONST_ZERO) && sval == 0) {
         return 1;
-    } else if ((ct & TCG_CT_CONST_MONE) && val == -1) {
+    }
+    if ((ct & TCG_CT_CONST_MONE) && sval == -1) {
         return 1;
-    } else if ((ct & TCG_CT_CONST_WSZ)
-               && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
+    }
+    if ((ct & TCG_CT_CONST_WSZ) && sval == (type == TCG_TYPE_I32 ? 32 : 64)) {
         return 1;
     }
     return 0;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 26/35] tcg/ppc: Add TCG_CT_CONST_CMP
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (24 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 25/35] tcg/ppc: Tidy up tcg_target_const_match Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-10-28 19:45 ` [PATCH v2 27/35] tcg/ppc: Support TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (10 subsequent siblings)
  36 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Better constraint for tcg_out_cmp, based on the comparison.
We can't yet remove the fallback to load constants into a
scratch because of tcg_out_cmp2, but that path should not
be as frequent.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/ppc/tcg-target-con-set.h |  5 ++--
 tcg/ppc/tcg-target-con-str.h |  1 +
 tcg/ppc/tcg-target.c.inc     | 48 ++++++++++++++++++++++++++++++------
 3 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/tcg/ppc/tcg-target-con-set.h b/tcg/ppc/tcg-target-con-set.h
index bbd7b21247..aa1dac8740 100644
--- a/tcg/ppc/tcg-target-con-set.h
+++ b/tcg/ppc/tcg-target-con-set.h
@@ -11,7 +11,7 @@
  */
 C_O0_I1(r)
 C_O0_I2(r, r)
-C_O0_I2(r, ri)
+C_O0_I2(r, rC)
 C_O0_I2(v, r)
 C_O0_I3(r, r, r)
 C_O0_I3(o, m, r)
@@ -26,13 +26,14 @@ C_O1_I2(r, rI, ri)
 C_O1_I2(r, rI, rT)
 C_O1_I2(r, r, r)
 C_O1_I2(r, r, ri)
+C_O1_I2(r, r, rC)
 C_O1_I2(r, r, rI)
 C_O1_I2(r, r, rT)
 C_O1_I2(r, r, rU)
 C_O1_I2(r, r, rZW)
 C_O1_I2(v, v, v)
 C_O1_I3(v, v, v, v)
-C_O1_I4(r, r, ri, rZ, rZ)
+C_O1_I4(r, r, rC, rZ, rZ)
 C_O1_I4(r, r, r, ri, ri)
 C_O2_I1(r, r, r)
 C_O2_I1(o, m, r)
diff --git a/tcg/ppc/tcg-target-con-str.h b/tcg/ppc/tcg-target-con-str.h
index 20846901de..16b687216e 100644
--- a/tcg/ppc/tcg-target-con-str.h
+++ b/tcg/ppc/tcg-target-con-str.h
@@ -16,6 +16,7 @@ REGS('v', ALL_VECTOR_REGS)
  * Define constraint letters for constants:
  * CONST(letter, TCG_CT_CONST_* bit set)
  */
+CONST('C', TCG_CT_CONST_CMP)
 CONST('I', TCG_CT_CONST_S16)
 CONST('M', TCG_CT_CONST_MONE)
 CONST('T', TCG_CT_CONST_S32)
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index 13d43ef9ba..b20dbe036d 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -92,11 +92,13 @@
 #define SZR  (TCG_TARGET_REG_BITS / 8)
 
 #define TCG_CT_CONST_S16  0x100
+#define TCG_CT_CONST_U16  0x200
 #define TCG_CT_CONST_S32  0x400
 #define TCG_CT_CONST_U32  0x800
 #define TCG_CT_CONST_ZERO 0x1000
 #define TCG_CT_CONST_MONE 0x2000
 #define TCG_CT_CONST_WSZ  0x4000
+#define TCG_CT_CONST_CMP  0x8000
 
 #define ALL_GENERAL_REGS  0xffffffffu
 #define ALL_VECTOR_REGS   0xffffffff00000000ull
@@ -296,9 +298,35 @@ static bool tcg_target_const_match(int64_t sval, int ct,
         sval = (int32_t)sval;
     }
 
+    if (ct & TCG_CT_CONST_CMP) {
+        switch (cond) {
+        case TCG_COND_EQ:
+        case TCG_COND_NE:
+            ct |= TCG_CT_CONST_S16 | TCG_CT_CONST_U16;
+            break;
+        case TCG_COND_LT:
+        case TCG_COND_GE:
+        case TCG_COND_LE:
+        case TCG_COND_GT:
+            ct |= TCG_CT_CONST_S16;
+            break;
+        case TCG_COND_LTU:
+        case TCG_COND_GEU:
+        case TCG_COND_LEU:
+        case TCG_COND_GTU:
+            ct |= TCG_CT_CONST_U16;
+            break;
+        default:
+            g_assert_not_reached();
+        }
+    }
+
     if ((ct & TCG_CT_CONST_S16) && sval == (int16_t)sval) {
         return 1;
     }
+    if ((ct & TCG_CT_CONST_U16) && uval == (uint16_t)uval) {
+        return 1;
+    }
     if ((ct & TCG_CT_CONST_S32) && sval == (int32_t)sval) {
         return 1;
     }
@@ -1682,7 +1710,10 @@ static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
 
     tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
 
-    /* Simplify the comparisons below wrt CMPI.  */
+    /*
+     * Simplify the comparisons below wrt CMPI.
+     * All of the tests are 16-bit, so a 32-bit sign extend always works.
+     */
     if (type == TCG_TYPE_I32) {
         arg2 = (int32_t)arg2;
     }
@@ -3990,8 +4021,6 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_sar_i32:
     case INDEX_op_rotl_i32:
     case INDEX_op_rotr_i32:
-    case INDEX_op_setcond_i32:
-    case INDEX_op_negsetcond_i32:
     case INDEX_op_and_i64:
     case INDEX_op_andc_i64:
     case INDEX_op_shl_i64:
@@ -3999,8 +4028,6 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_sar_i64:
     case INDEX_op_rotl_i64:
     case INDEX_op_rotr_i64:
-    case INDEX_op_setcond_i64:
-    case INDEX_op_negsetcond_i64:
         return C_O1_I2(r, r, ri);
 
     case INDEX_op_mul_i32:
@@ -4044,11 +4071,16 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 
     case INDEX_op_brcond_i32:
     case INDEX_op_brcond_i64:
-        return C_O0_I2(r, ri);
-
+        return C_O0_I2(r, rC);
+    case INDEX_op_setcond_i32:
+    case INDEX_op_setcond_i64:
+    case INDEX_op_negsetcond_i32:
+    case INDEX_op_negsetcond_i64:
+        return C_O1_I2(r, r, rC);
     case INDEX_op_movcond_i32:
     case INDEX_op_movcond_i64:
-        return C_O1_I4(r, r, ri, rZ, rZ);
+        return C_O1_I4(r, r, rC, rZ, rZ);
+
     case INDEX_op_deposit_i32:
     case INDEX_op_deposit_i64:
         return C_O1_I2(r, 0, rZ);
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 27/35] tcg/ppc: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (25 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 26/35] tcg/ppc: Add TCG_CT_CONST_CMP Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-08 20:40   ` Philippe Mathieu-Daudé
  2023-11-09  8:42   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 28/35] tcg/s390x: Split constraint A into J+U Richard Henderson
                   ` (9 subsequent siblings)
  36 siblings, 2 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/ppc/tcg-target.c.inc | 105 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 98 insertions(+), 7 deletions(-)

diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index b20dbe036d..ef1d959892 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -703,9 +703,11 @@ enum {
     CR_SO
 };
 
-static const uint32_t tcg_to_bc[] = {
+static const uint32_t tcg_to_bc[16] = {
     [TCG_COND_EQ]  = BC | BI(0, CR_EQ) | BO_COND_TRUE,
     [TCG_COND_NE]  = BC | BI(0, CR_EQ) | BO_COND_FALSE,
+    [TCG_COND_TSTEQ]  = BC | BI(0, CR_EQ) | BO_COND_TRUE,
+    [TCG_COND_TSTNE]  = BC | BI(0, CR_EQ) | BO_COND_FALSE,
     [TCG_COND_LT]  = BC | BI(0, CR_LT) | BO_COND_TRUE,
     [TCG_COND_GE]  = BC | BI(0, CR_LT) | BO_COND_FALSE,
     [TCG_COND_LE]  = BC | BI(0, CR_GT) | BO_COND_FALSE,
@@ -717,9 +719,11 @@ static const uint32_t tcg_to_bc[] = {
 };
 
 /* The low bit here is set if the RA and RB fields must be inverted.  */
-static const uint32_t tcg_to_isel[] = {
+static const uint32_t tcg_to_isel[16] = {
     [TCG_COND_EQ]  = ISEL | BC_(0, CR_EQ),
     [TCG_COND_NE]  = ISEL | BC_(0, CR_EQ) | 1,
+    [TCG_COND_TSTEQ] = ISEL | BC_(0, CR_EQ),
+    [TCG_COND_TSTNE] = ISEL | BC_(0, CR_EQ) | 1,
     [TCG_COND_LT]  = ISEL | BC_(0, CR_LT),
     [TCG_COND_GE]  = ISEL | BC_(0, CR_LT) | 1,
     [TCG_COND_LE]  = ISEL | BC_(0, CR_GT) | 1,
@@ -872,21 +876,33 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
     return true;
 }
 
-static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
-                               int sh, int mb)
+static void tcg_out_rld_rc(TCGContext *s, int op, TCGReg ra, TCGReg rs,
+                           int sh, int mb, bool rc)
 {
     tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
     sh = SH(sh & 0x1f) | (((sh >> 5) & 1) << 1);
     mb = MB64((mb >> 5) | ((mb << 1) & 0x3f));
-    tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb);
+    tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb | rc);
 }
 
-static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
-                               int sh, int mb, int me)
+static void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
+                        int sh, int mb)
+{
+    tcg_out_rld_rc(s, op, ra, rs, sh, mb, false);
+}
+
+static void tcg_out_rlw_rc(TCGContext *s, int op, TCGReg ra, TCGReg rs,
+                           int sh, int mb, int me, bool rc)
 {
     tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
 }
 
+static void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
+                        int sh, int mb, int me)
+{
+    tcg_out_rlw_rc(s, op, ra, rs, sh, mb, me, false);
+}
+
 static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
 {
     tcg_out32(s, EXTSB | RA(dst) | RS(src));
@@ -1702,6 +1718,50 @@ static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
     return false;
 }
 
+/*
+ * Set dest non-zero if and only if (arg1 & arg2) is non-zero.
+ * If RC, then also set RC0.
+ */
+static void tcg_out_test(TCGContext *s, TCGReg dest, TCGReg arg1, TCGArg arg2,
+                         bool const_arg2, TCGType type, bool rc)
+{
+    int mb, me;
+
+    if (!const_arg2) {
+        tcg_out32(s, AND | SAB(arg1, dest, arg2) | rc);
+        return;
+    }
+
+    if (type == TCG_TYPE_I32) {
+        arg2 = (uint32_t)arg2;
+    } else if (arg2 == (uint32_t)arg2) {
+        type = TCG_TYPE_I32;
+    }
+
+    if ((arg2 & ~0xffff) == 0) {
+        tcg_out32(s, ANDI | SAI(arg1, dest, arg2));
+        return;
+    }
+    if ((arg2 & ~0xffff0000ull) == 0) {
+        tcg_out32(s, ANDI | SAI(arg1, dest, arg2));
+        return;
+    }
+    if (type == TCG_TYPE_I32) {
+        if (mask_operand(arg2, &mb, &me)) {
+            tcg_out_rlw_rc(s, RLWINM, dest, arg1, 0, mb, me, rc);
+            return;
+        }
+    } else {
+        int sh = clz64(arg2);
+        if (mask64_operand(arg2 << sh, &mb, &me)) {
+            tcg_out_rld_rc(s, RLDICR, dest, arg1, sh, me, rc);
+            return;
+        }
+    }
+    /* Constraints should satisfy this. */
+    g_assert_not_reached();
+}
+
 static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
                         int const_arg2, int cr, TCGType type)
 {
@@ -1736,6 +1796,12 @@ static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
         imm = 0;
         break;
 
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        tcg_debug_assert(cr == 0);
+        tcg_out_test(s, TCG_REG_R0, arg1, arg2, const_arg2, type, true);
+        return;
+
     case TCG_COND_LT:
     case TCG_COND_GE:
     case TCG_COND_LE:
@@ -1946,6 +2012,16 @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
         tcg_out_setcond_ne0(s, type, arg0, arg1, neg);
         break;
 
+    case TCG_COND_TSTEQ:
+        tcg_out_test(s, TCG_REG_R0, arg1, arg2, const_arg2, type, false);
+        tcg_out_setcond_eq0(s, type, arg0, TCG_REG_R0, neg);
+        break;
+
+    case TCG_COND_TSTNE:
+        tcg_out_test(s, TCG_REG_R0, arg1, arg2, const_arg2, type, false);
+        tcg_out_setcond_ne0(s, type, arg0, TCG_REG_R0, neg);
+        break;
+
     case TCG_COND_LE:
     case TCG_COND_LEU:
         inv = true;
@@ -2118,6 +2194,21 @@ static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
         tcg_out32(s, op | BT(0, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
         break;
 
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        if (blconst) {
+            tcg_out_andi32(s, TCG_REG_R0, al, bl);
+        } else {
+            tcg_out32(s, AND | SAB(al, TCG_REG_R0, bl));
+        }
+        if (bhconst) {
+            tcg_out_andi32(s, TCG_REG_TMP1, ah, bh);
+        } else {
+            tcg_out32(s, AND | SAB(ah, TCG_REG_TMP1, bh));
+        }
+        tcg_out32(s, OR | SAB(TCG_REG_R0, TCG_REG_R0, TCG_REG_TMP1) | 1);
+        break;
+
     case TCG_COND_LT:
     case TCG_COND_LE:
     case TCG_COND_GT:
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 28/35] tcg/s390x: Split constraint A into J+U
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (26 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 27/35] tcg/ppc: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-10-28 19:45 ` [PATCH v2 29/35] tcg/s390x: Add TCG_CT_CONST_CMP Richard Henderson
                   ` (8 subsequent siblings)
  36 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed 33-bit == signed 32-bit + unsigned 32-bit.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/s390x/tcg-target-con-set.h |  8 ++++----
 tcg/s390x/tcg-target-con-str.h |  2 +-
 tcg/s390x/tcg-target.c.inc     | 36 +++++++++++++++++-----------------
 3 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/tcg/s390x/tcg-target-con-set.h b/tcg/s390x/tcg-target-con-set.h
index 9a42037499..665851d84a 100644
--- a/tcg/s390x/tcg-target-con-set.h
+++ b/tcg/s390x/tcg-target-con-set.h
@@ -15,7 +15,7 @@
 C_O0_I1(r)
 C_O0_I2(r, r)
 C_O0_I2(r, ri)
-C_O0_I2(r, rA)
+C_O0_I2(r, rJU)
 C_O0_I2(v, r)
 C_O0_I3(o, m, r)
 C_O1_I1(r, r)
@@ -27,7 +27,7 @@ C_O1_I2(r, 0, rI)
 C_O1_I2(r, 0, rJ)
 C_O1_I2(r, r, r)
 C_O1_I2(r, r, ri)
-C_O1_I2(r, r, rA)
+C_O1_I2(r, r, rJU)
 C_O1_I2(r, r, rI)
 C_O1_I2(r, r, rJ)
 C_O1_I2(r, r, rK)
@@ -39,10 +39,10 @@ C_O1_I2(v, v, r)
 C_O1_I2(v, v, v)
 C_O1_I3(v, v, v, v)
 C_O1_I4(r, r, ri, rI, r)
-C_O1_I4(r, r, rA, rI, r)
+C_O1_I4(r, r, rJU, rI, r)
 C_O2_I1(o, m, r)
 C_O2_I2(o, m, 0, r)
 C_O2_I2(o, m, r, r)
 C_O2_I3(o, m, 0, 1, r)
 C_N1_O1_I4(r, r, 0, 1, ri, r)
-C_N1_O1_I4(r, r, 0, 1, rA, r)
+C_N1_O1_I4(r, r, 0, 1, rJU, r)
diff --git a/tcg/s390x/tcg-target-con-str.h b/tcg/s390x/tcg-target-con-str.h
index 25675b449e..9d2cb775dc 100644
--- a/tcg/s390x/tcg-target-con-str.h
+++ b/tcg/s390x/tcg-target-con-str.h
@@ -16,10 +16,10 @@ REGS('o', 0xaaaa) /* odd numbered general regs */
  * Define constraint letters for constants:
  * CONST(letter, TCG_CT_CONST_* bit set)
  */
-CONST('A', TCG_CT_CONST_S33)
 CONST('I', TCG_CT_CONST_S16)
 CONST('J', TCG_CT_CONST_S32)
 CONST('K', TCG_CT_CONST_P32)
 CONST('N', TCG_CT_CONST_INV)
 CONST('R', TCG_CT_CONST_INVRISBG)
+CONST('U', TCG_CT_CONST_U32)
 CONST('Z', TCG_CT_CONST_ZERO)
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
index 08fe00a392..a317ccd3a5 100644
--- a/tcg/s390x/tcg-target.c.inc
+++ b/tcg/s390x/tcg-target.c.inc
@@ -30,7 +30,7 @@
 
 #define TCG_CT_CONST_S16        (1 << 8)
 #define TCG_CT_CONST_S32        (1 << 9)
-#define TCG_CT_CONST_S33        (1 << 10)
+#define TCG_CT_CONST_U32        (1 << 10)
 #define TCG_CT_CONST_ZERO       (1 << 11)
 #define TCG_CT_CONST_P32        (1 << 12)
 #define TCG_CT_CONST_INV        (1 << 13)
@@ -542,22 +542,23 @@ static bool tcg_target_const_match(int64_t val, int ct,
                                    TCGType type, TCGCond cond, int vece)
 {
     if (ct & TCG_CT_CONST) {
-        return 1;
+        return true;
     }
-
     if (type == TCG_TYPE_I32) {
         val = (int32_t)val;
     }
 
-    /* The following are mutually exclusive.  */
-    if (ct & TCG_CT_CONST_S16) {
-        return val == (int16_t)val;
-    } else if (ct & TCG_CT_CONST_S32) {
-        return val == (int32_t)val;
-    } else if (ct & TCG_CT_CONST_S33) {
-        return val >= -0xffffffffll && val <= 0xffffffffll;
-    } else if (ct & TCG_CT_CONST_ZERO) {
-        return val == 0;
+    if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
+        return true;
+    }
+    if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
+        return true;
+    }
+    if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
+        return true;
+    }
+    if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
+        return true;
     }
 
     if (ct & TCG_CT_CONST_INV) {
@@ -573,8 +574,7 @@ static bool tcg_target_const_match(int64_t val, int ct,
     if ((ct & TCG_CT_CONST_INVRISBG) && risbg_mask(~val)) {
         return true;
     }
-
-    return 0;
+    return false;
 }
 
 /* Emit instructions according to the given instruction format.  */
@@ -3137,7 +3137,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
         return C_O1_I2(r, r, ri);
     case INDEX_op_setcond_i64:
     case INDEX_op_negsetcond_i64:
-        return C_O1_I2(r, r, rA);
+        return C_O1_I2(r, r, rJU);
 
     case INDEX_op_clz_i64:
         return C_O1_I2(r, r, rI);
@@ -3187,7 +3187,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_brcond_i32:
         return C_O0_I2(r, ri);
     case INDEX_op_brcond_i64:
-        return C_O0_I2(r, rA);
+        return C_O0_I2(r, rJU);
 
     case INDEX_op_bswap16_i32:
     case INDEX_op_bswap16_i64:
@@ -3240,7 +3240,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_movcond_i32:
         return C_O1_I4(r, r, ri, rI, r);
     case INDEX_op_movcond_i64:
-        return C_O1_I4(r, r, rA, rI, r);
+        return C_O1_I4(r, r, rJU, rI, r);
 
     case INDEX_op_div2_i32:
     case INDEX_op_div2_i64:
@@ -3259,7 +3259,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 
     case INDEX_op_add2_i64:
     case INDEX_op_sub2_i64:
-        return C_N1_O1_I4(r, r, 0, 1, rA, r);
+        return C_N1_O1_I4(r, r, 0, 1, rJU, r);
 
     case INDEX_op_st_vec:
         return C_O0_I2(v, r);
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 29/35] tcg/s390x: Add TCG_CT_CONST_CMP
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (27 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 28/35] tcg/s390x: Split constraint A into J+U Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-10-28 19:45 ` [PATCH v2 30/35] tcg/s390x: Support TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (7 subsequent siblings)
  36 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Better constraint for tcg_out_cmp, based on the comparison.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/s390x/tcg-target-con-set.h |  6 +--
 tcg/s390x/tcg-target-con-str.h |  1 +
 tcg/s390x/tcg-target.c.inc     | 72 +++++++++++++++++++++++++---------
 3 files changed, 58 insertions(+), 21 deletions(-)

diff --git a/tcg/s390x/tcg-target-con-set.h b/tcg/s390x/tcg-target-con-set.h
index 665851d84a..f75955eaa8 100644
--- a/tcg/s390x/tcg-target-con-set.h
+++ b/tcg/s390x/tcg-target-con-set.h
@@ -15,7 +15,7 @@
 C_O0_I1(r)
 C_O0_I2(r, r)
 C_O0_I2(r, ri)
-C_O0_I2(r, rJU)
+C_O0_I2(r, rC)
 C_O0_I2(v, r)
 C_O0_I3(o, m, r)
 C_O1_I1(r, r)
@@ -27,7 +27,7 @@ C_O1_I2(r, 0, rI)
 C_O1_I2(r, 0, rJ)
 C_O1_I2(r, r, r)
 C_O1_I2(r, r, ri)
-C_O1_I2(r, r, rJU)
+C_O1_I2(r, r, rC)
 C_O1_I2(r, r, rI)
 C_O1_I2(r, r, rJ)
 C_O1_I2(r, r, rK)
@@ -39,7 +39,7 @@ C_O1_I2(v, v, r)
 C_O1_I2(v, v, v)
 C_O1_I3(v, v, v, v)
 C_O1_I4(r, r, ri, rI, r)
-C_O1_I4(r, r, rJU, rI, r)
+C_O1_I4(r, r, rC, rI, r)
 C_O2_I1(o, m, r)
 C_O2_I2(o, m, 0, r)
 C_O2_I2(o, m, r, r)
diff --git a/tcg/s390x/tcg-target-con-str.h b/tcg/s390x/tcg-target-con-str.h
index 9d2cb775dc..745f6c0df5 100644
--- a/tcg/s390x/tcg-target-con-str.h
+++ b/tcg/s390x/tcg-target-con-str.h
@@ -16,6 +16,7 @@ REGS('o', 0xaaaa) /* odd numbered general regs */
  * Define constraint letters for constants:
  * CONST(letter, TCG_CT_CONST_* bit set)
  */
+CONST('C', TCG_CT_CONST_CMP)
 CONST('I', TCG_CT_CONST_S16)
 CONST('J', TCG_CT_CONST_S32)
 CONST('K', TCG_CT_CONST_P32)
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
index a317ccd3a5..86ec737768 100644
--- a/tcg/s390x/tcg-target.c.inc
+++ b/tcg/s390x/tcg-target.c.inc
@@ -35,6 +35,7 @@
 #define TCG_CT_CONST_P32        (1 << 12)
 #define TCG_CT_CONST_INV        (1 << 13)
 #define TCG_CT_CONST_INVRISBG   (1 << 14)
+#define TCG_CT_CONST_CMP        (1 << 15)
 
 #define ALL_GENERAL_REGS     MAKE_64BIT_MASK(0, 16)
 #define ALL_VECTOR_REGS      MAKE_64BIT_MASK(32, 32)
@@ -548,6 +549,29 @@ static bool tcg_target_const_match(int64_t val, int ct,
         val = (int32_t)val;
     }
 
+    if (ct & TCG_CT_CONST_CMP) {
+        switch (cond) {
+        case TCG_COND_EQ:
+        case TCG_COND_NE:
+            ct |= TCG_CT_CONST_S32 | TCG_CT_CONST_U32;  /* CGFI or CLGFI */
+            break;
+        case TCG_COND_LT:
+        case TCG_COND_GE:
+        case TCG_COND_LE:
+        case TCG_COND_GT:
+            ct |= TCG_CT_CONST_S32;  /* CGFI */
+            break;
+        case TCG_COND_LTU:
+        case TCG_COND_GEU:
+        case TCG_COND_LEU:
+        case TCG_COND_GTU:
+            ct |= TCG_CT_CONST_U32;  /* CLGFI */
+            break;
+        default:
+            g_assert_not_reached();
+        }
+    }
+
     if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
         return true;
     }
@@ -1229,22 +1253,34 @@ static int tgen_cmp2(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
             goto exit;
         }
 
-        /*
-         * Constraints are for a signed 33-bit operand, which is a
-         * convenient superset of this signed/unsigned test.
-         */
-        if (c2 == (is_unsigned ? (TCGArg)(uint32_t)c2 : (TCGArg)(int32_t)c2)) {
-            op = (is_unsigned ? RIL_CLGFI : RIL_CGFI);
-            tcg_out_insn_RIL(s, op, r1, c2);
-            goto exit;
+        /* Should match TCG_CT_CONST_CMP. */
+        switch (c) {
+        case TCG_COND_LT:
+        case TCG_COND_GE:
+        case TCG_COND_LE:
+        case TCG_COND_GT:
+            tcg_debug_assert(c2 == (int32_t)c2);
+            op = RIL_CGFI;
+            break;
+        case TCG_COND_EQ:
+        case TCG_COND_NE:
+            if (c2 == (int32_t)c2) {
+                op = RIL_CGFI;
+                break;
+            }
+            /* fall through */
+        case TCG_COND_LTU:
+        case TCG_COND_GEU:
+        case TCG_COND_LEU:
+        case TCG_COND_GTU:
+            tcg_debug_assert(c2 == (uint32_t)c2);
+            op = RIL_CLGFI;
+            break;
+        default:
+            g_assert_not_reached();
         }
-
-        /* Load everything else into a register. */
-        tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, c2);
-        c2 = TCG_TMP0;
-    }
-
-    if (type == TCG_TYPE_I32) {
+        tcg_out_insn_RIL(s, op, r1, c2);
+    } else if (type == TCG_TYPE_I32) {
         op = (is_unsigned ? RR_CLR : RR_CR);
         tcg_out_insn_RR(s, op, r1, c2);
     } else {
@@ -3137,7 +3173,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
         return C_O1_I2(r, r, ri);
     case INDEX_op_setcond_i64:
     case INDEX_op_negsetcond_i64:
-        return C_O1_I2(r, r, rJU);
+        return C_O1_I2(r, r, rC);
 
     case INDEX_op_clz_i64:
         return C_O1_I2(r, r, rI);
@@ -3187,7 +3223,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_brcond_i32:
         return C_O0_I2(r, ri);
     case INDEX_op_brcond_i64:
-        return C_O0_I2(r, rJU);
+        return C_O0_I2(r, rC);
 
     case INDEX_op_bswap16_i32:
     case INDEX_op_bswap16_i64:
@@ -3240,7 +3276,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_movcond_i32:
         return C_O1_I4(r, r, ri, rI, r);
     case INDEX_op_movcond_i64:
-        return C_O1_I4(r, r, rJU, rI, r);
+        return C_O1_I4(r, r, rC, rI, r);
 
     case INDEX_op_div2_i32:
     case INDEX_op_div2_i64:
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 30/35] tcg/s390x: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (28 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 29/35] tcg/s390x: Add TCG_CT_CONST_CMP Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-10-28 19:45 ` [PATCH v2 31/35] tcg/tci: " Richard Henderson
                   ` (6 subsequent siblings)
  36 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/s390x/tcg-target.c.inc | 139 +++++++++++++++++++++++++------------
 1 file changed, 96 insertions(+), 43 deletions(-)

diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
index 86ec737768..cb1693c9cf 100644
--- a/tcg/s390x/tcg-target.c.inc
+++ b/tcg/s390x/tcg-target.c.inc
@@ -112,6 +112,9 @@ typedef enum S390Opcode {
     RI_OILH     = 0xa50a,
     RI_OILL     = 0xa50b,
     RI_TMLL     = 0xa701,
+    RI_TMLH     = 0xa700,
+    RI_TMHL     = 0xa703,
+    RI_TMHH     = 0xa702,
 
     RIEb_CGRJ    = 0xec64,
     RIEb_CLGRJ   = 0xec65,
@@ -404,10 +407,15 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
 #define S390_CC_NEVER   0
 #define S390_CC_ALWAYS  15
 
+#define S390_TM_EQ      8  /* CC == 0 */
+#define S390_TM_NE      7  /* CC in {1,2,3} */
+
 /* Condition codes that result from a COMPARE and COMPARE LOGICAL.  */
-static const uint8_t tcg_cond_to_s390_cond[] = {
+static const uint8_t tcg_cond_to_s390_cond[16] = {
     [TCG_COND_EQ]  = S390_CC_EQ,
     [TCG_COND_NE]  = S390_CC_NE,
+    [TCG_COND_TSTEQ] = S390_CC_EQ,
+    [TCG_COND_TSTNE] = S390_CC_NE,
     [TCG_COND_LT]  = S390_CC_LT,
     [TCG_COND_LE]  = S390_CC_LE,
     [TCG_COND_GT]  = S390_CC_GT,
@@ -421,9 +429,11 @@ static const uint8_t tcg_cond_to_s390_cond[] = {
 /* Condition codes that result from a LOAD AND TEST.  Here, we have no
    unsigned instruction variation, however since the test is vs zero we
    can re-map the outcomes appropriately.  */
-static const uint8_t tcg_cond_to_ltr_cond[] = {
+static const uint8_t tcg_cond_to_ltr_cond[16] = {
     [TCG_COND_EQ]  = S390_CC_EQ,
     [TCG_COND_NE]  = S390_CC_NE,
+    [TCG_COND_TSTEQ] = S390_CC_ALWAYS,
+    [TCG_COND_TSTNE] = S390_CC_NEVER,
     [TCG_COND_LT]  = S390_CC_LT,
     [TCG_COND_LE]  = S390_CC_LE,
     [TCG_COND_GT]  = S390_CC_GT,
@@ -542,10 +552,13 @@ static bool risbg_mask(uint64_t c)
 static bool tcg_target_const_match(int64_t val, int ct,
                                    TCGType type, TCGCond cond, int vece)
 {
+    uint64_t uval = val;
+
     if (ct & TCG_CT_CONST) {
         return true;
     }
     if (type == TCG_TYPE_I32) {
+        uval = (uint32_t)val;
         val = (int32_t)val;
     }
 
@@ -567,6 +580,15 @@ static bool tcg_target_const_match(int64_t val, int ct,
         case TCG_COND_GTU:
             ct |= TCG_CT_CONST_U32;  /* CLGFI */
             break;
+        case TCG_COND_TSTNE:
+        case TCG_COND_TSTEQ:
+            if (is_const_p16(uval) >= 0) {
+                return true;  /* TMxx */
+            }
+            if (risbg_mask(uval)) {
+                return true;  /* RISBG */
+            }
+            break;
         default:
             g_assert_not_reached();
         }
@@ -588,10 +610,6 @@ static bool tcg_target_const_match(int64_t val, int ct,
     if (ct & TCG_CT_CONST_INV) {
         val = ~val;
     }
-    /*
-     * Note that is_const_p16 is a subset of is_const_p32,
-     * so we don't need both constraints.
-     */
     if ((ct & TCG_CT_CONST_P32) && is_const_p32(val) >= 0) {
         return true;
     }
@@ -868,6 +886,9 @@ static const S390Opcode oi_insns[4] = {
 static const S390Opcode lif_insns[2] = {
     RIL_LLILF, RIL_LLIHF,
 };
+static const S390Opcode tm_insns[4] = {
+    RI_TMLL, RI_TMLH, RI_TMHL, RI_TMHH
+};
 
 /* load a register with an immediate value */
 static void tcg_out_movi(TCGContext *s, TCGType type,
@@ -1228,6 +1249,36 @@ static int tgen_cmp2(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
     TCGCond inv_c = tcg_invert_cond(c);
     S390Opcode op;
 
+    if (is_tst_cond(c)) {
+        tcg_debug_assert(!need_carry);
+
+        if (!c2const) {
+            if (type == TCG_TYPE_I32) {
+                tcg_out_insn(s, RRFa, NRK, TCG_REG_R0, r1, c2);
+            } else {
+                tcg_out_insn(s, RRFa, NGRK, TCG_REG_R0, r1, c2);
+            }
+            goto exit;
+        }
+
+        if (type == TCG_TYPE_I32) {
+            c2 = (uint32_t)c2;
+        }
+
+        int i = is_const_p16(c2);
+        if (i >= 0) {
+            tcg_out_insn_RI(s, tm_insns[i], r1, c2 >> (i * 16));
+            *inv_cc = TCG_COND_TSTEQ ? S390_TM_NE : S390_TM_EQ;
+            return *inv_cc ^ 15;
+        }
+
+        if (risbg_mask(c2)) {
+            tgen_andi_risbg(s, TCG_REG_R0, r1, c2);
+            goto exit;
+        }
+        g_assert_not_reached();
+    }
+
     if (c2const) {
         if (c2 == 0) {
             if (!(is_unsigned && need_carry)) {
@@ -1553,46 +1604,49 @@ static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
                         TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
 {
     int cc;
-    bool is_unsigned = is_unsigned_cond(c);
-    bool in_range;
-    S390Opcode opc;
 
-    cc = tcg_cond_to_s390_cond[c];
+    if (!is_tst_cond(c)) {
+        bool is_unsigned = is_unsigned_cond(c);
+        bool in_range;
+        S390Opcode opc;
 
-    if (!c2const) {
-        opc = (type == TCG_TYPE_I32
-               ? (is_unsigned ? RIEb_CLRJ : RIEb_CRJ)
-               : (is_unsigned ? RIEb_CLGRJ : RIEb_CGRJ));
-        tgen_compare_branch(s, opc, cc, r1, c2, l);
-        return;
-    }
+        cc = tcg_cond_to_s390_cond[c];
 
-    /*
-     * COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
-     * If the immediate we've been given does not fit that range, we'll
-     * fall back to separate compare and branch instructions using the
-     * larger comparison range afforded by COMPARE IMMEDIATE.
-     */
-    if (type == TCG_TYPE_I32) {
-        if (is_unsigned) {
-            opc = RIEc_CLIJ;
-            in_range = (uint32_t)c2 == (uint8_t)c2;
-        } else {
-            opc = RIEc_CIJ;
-            in_range = (int32_t)c2 == (int8_t)c2;
+        if (!c2const) {
+            opc = (type == TCG_TYPE_I32
+                   ? (is_unsigned ? RIEb_CLRJ : RIEb_CRJ)
+                   : (is_unsigned ? RIEb_CLGRJ : RIEb_CGRJ));
+            tgen_compare_branch(s, opc, cc, r1, c2, l);
+            return;
         }
-    } else {
-        if (is_unsigned) {
-            opc = RIEc_CLGIJ;
-            in_range = (uint64_t)c2 == (uint8_t)c2;
+
+        /*
+         * COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
+         * If the immediate we've been given does not fit that range, we'll
+         * fall back to separate compare and branch instructions using the
+         * larger comparison range afforded by COMPARE IMMEDIATE.
+         */
+        if (type == TCG_TYPE_I32) {
+            if (is_unsigned) {
+                opc = RIEc_CLIJ;
+                in_range = (uint32_t)c2 == (uint8_t)c2;
+            } else {
+                opc = RIEc_CIJ;
+                in_range = (int32_t)c2 == (int8_t)c2;
+            }
         } else {
-            opc = RIEc_CGIJ;
-            in_range = (int64_t)c2 == (int8_t)c2;
+            if (is_unsigned) {
+                opc = RIEc_CLGIJ;
+                in_range = (uint64_t)c2 == (uint8_t)c2;
+            } else {
+                opc = RIEc_CGIJ;
+                in_range = (int64_t)c2 == (int8_t)c2;
+            }
+        }
+        if (in_range) {
+            tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
+            return;
         }
-    }
-    if (in_range) {
-        tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
-        return;
     }
 
     cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
@@ -1871,11 +1925,10 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
             ldst->oi = oi;
             ldst->addrlo_reg = addr_reg;
 
-            /* We are expecting a_bits to max out at 7, much lower than TMLL. */
             tcg_debug_assert(a_mask <= 0xffff);
             tcg_out_insn(s, RI, TMLL, addr_reg, a_mask);
 
-            tcg_out16(s, RI_BRC | (7 << 4)); /* CC in {1,2,3} */
+            tcg_out16(s, RI_BRC | (S390_TM_NE << 4));
             ldst->label_ptr[0] = s->code_ptr++;
         }
 
@@ -1956,7 +2009,7 @@ static void tcg_out_qemu_ldst_i128(TCGContext *s, TCGReg datalo, TCGReg datahi,
             l2 = gen_new_label();
 
             tcg_out_insn(s, RI, TMLL, addr_reg, 15);
-            tgen_branch(s, 7, l1); /* CC in {1,2,3} */
+            tgen_branch(s, S390_TM_NE, l1);
         }
 
         tcg_debug_assert(!need_bswap);
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 31/35] tcg/tci: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (29 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 30/35] tcg/s390x: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-06 18:48   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 32/35] target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S} Richard Henderson
                   ` (5 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/tci.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/tcg/tci.c b/tcg/tci.c
index 4640902c88..5e1c4a491d 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -228,6 +228,12 @@ static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
     case TCG_COND_GTU:
         result = (u0 > u1);
         break;
+    case TCG_COND_TSTEQ:
+        result = (u0 & u1) == 0;
+        break;
+    case TCG_COND_TSTNE:
+        result = (u0 & u1) != 0;
+        break;
     default:
         g_assert_not_reached();
     }
@@ -270,6 +276,12 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
     case TCG_COND_GTU:
         result = (u0 > u1);
         break;
+    case TCG_COND_TSTEQ:
+        result = (u0 & u1) == 0;
+        break;
+    case TCG_COND_TSTNE:
+        result = (u0 & u1) != 0;
+        break;
     default:
         g_assert_not_reached();
     }
@@ -1043,6 +1055,8 @@ static const char *str_c(TCGCond c)
         [TCG_COND_GEU] = "geu",
         [TCG_COND_LEU] = "leu",
         [TCG_COND_GTU] = "gtu",
+        [TCG_COND_TSTEQ] = "tsteq",
+        [TCG_COND_TSTNE] = "tstne",
     };
 
     assert((unsigned)c < ARRAY_SIZE(cond));
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 32/35] target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (30 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 31/35] tcg/tci: " Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-08 20:52   ` [PATCH v2 32/35 1/2] target/alpha: Pass immediate value to gen_bcond_internal() Philippe Mathieu-Daudé
                     ` (2 more replies)
  2023-10-28 19:45 ` [PATCH v2 33/35] target/alpha: Use TCG_COND_TST{EQ, NE} for CMOVLB{C, S} Richard Henderson
                   ` (4 subsequent siblings)
  36 siblings, 3 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/alpha/translate.c | 39 ++++++++++++++++-----------------------
 1 file changed, 16 insertions(+), 23 deletions(-)

diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 32333081d8..49e6a7b62d 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -453,13 +453,13 @@ static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
 }
 
 static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
-                                        TCGv cmp, int32_t disp)
+                                        TCGv cmp, uint64_t imm, int32_t disp)
 {
     uint64_t dest = ctx->base.pc_next + (disp << 2);
     TCGLabel *lab_true = gen_new_label();
 
     if (use_goto_tb(ctx, dest)) {
-        tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
+        tcg_gen_brcondi_i64(cond, cmp, imm, lab_true);
 
         tcg_gen_goto_tb(0);
         tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
@@ -472,27 +472,20 @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
 
         return DISAS_NORETURN;
     } else {
-        TCGv_i64 z = load_zero(ctx);
+        TCGv_i64 i = tcg_constant_i64(imm);
         TCGv_i64 d = tcg_constant_i64(dest);
         TCGv_i64 p = tcg_constant_i64(ctx->base.pc_next);
 
-        tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
+        tcg_gen_movcond_i64(cond, cpu_pc, cmp, i, d, p);
         return DISAS_PC_UPDATED;
     }
 }
 
 static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
-                               int32_t disp, int mask)
+                               int32_t disp)
 {
-    if (mask) {
-        TCGv tmp = tcg_temp_new();
-        DisasJumpType ret;
-
-        tcg_gen_andi_i64(tmp, load_gpr(ctx, ra), 1);
-        ret = gen_bcond_internal(ctx, cond, tmp, disp);
-        return ret;
-    }
-    return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra), disp);
+    return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra),
+                              is_tst_cond(cond), disp);
 }
 
 /* Fold -0.0 for comparison with COND.  */
@@ -533,7 +526,7 @@ static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
     DisasJumpType ret;
 
     gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra));
-    ret = gen_bcond_internal(ctx, cond, cmp_tmp, disp);
+    ret = gen_bcond_internal(ctx, cond, cmp_tmp, 0, disp);
     return ret;
 }
 
@@ -2827,35 +2820,35 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
         break;
     case 0x38:
         /* BLBC */
-        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
+        ret = gen_bcond(ctx, TCG_COND_TSTEQ, ra, disp21);
         break;
     case 0x39:
         /* BEQ */
-        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21);
         break;
     case 0x3A:
         /* BLT */
-        ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21);
         break;
     case 0x3B:
         /* BLE */
-        ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21);
         break;
     case 0x3C:
         /* BLBS */
-        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
+        ret = gen_bcond(ctx, TCG_COND_TSTNE, ra, disp21);
         break;
     case 0x3D:
         /* BNE */
-        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21);
         break;
     case 0x3E:
         /* BGE */
-        ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21);
         break;
     case 0x3F:
         /* BGT */
-        ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21);
         break;
     invalid_opc:
         ret = gen_invalid(ctx);
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 33/35] target/alpha: Use TCG_COND_TST{EQ, NE} for CMOVLB{C, S}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (31 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 32/35] target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S} Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-08 20:54   ` [PATCH v2 33/35] target/alpha: Use TCG_COND_TST{EQ,NE} for CMOVLB{C,S} Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 34/35] target/alpha: Use TCG_COND_TSTNE for gen_fold_mzero Richard Henderson
                   ` (3 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/alpha/translate.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 49e6a7b62d..c7daf46de7 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -1676,16 +1676,12 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
             break;
         case 0x14:
             /* CMOVLBS */
-            tmp = tcg_temp_new();
-            tcg_gen_andi_i64(tmp, va, 1);
-            tcg_gen_movcond_i64(TCG_COND_NE, vc, tmp, load_zero(ctx),
+            tcg_gen_movcond_i64(TCG_COND_TSTNE, vc, va, tcg_constant_i64(1),
                                 vb, load_gpr(ctx, rc));
             break;
         case 0x16:
             /* CMOVLBC */
-            tmp = tcg_temp_new();
-            tcg_gen_andi_i64(tmp, va, 1);
-            tcg_gen_movcond_i64(TCG_COND_EQ, vc, tmp, load_zero(ctx),
+            tcg_gen_movcond_i64(TCG_COND_TSTEQ, vc, va, tcg_constant_i64(1),
                                 vb, load_gpr(ctx, rc));
             break;
         case 0x20:
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 34/35] target/alpha: Use TCG_COND_TSTNE for gen_fold_mzero
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (32 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 33/35] target/alpha: Use TCG_COND_TST{EQ, NE} for CMOVLB{C, S} Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-08 21:03   ` Philippe Mathieu-Daudé
  2023-10-28 19:45 ` [PATCH v2 35/35] target/m68k: Use TCG_COND_TST{EQ, NE} in gen_fcc_cond Richard Henderson
                   ` (2 subsequent siblings)
  36 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/alpha/translate.c | 49 +++++++++++++++++++---------------------
 1 file changed, 23 insertions(+), 26 deletions(-)

diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index c7daf46de7..c68c2bcd21 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -490,56 +490,53 @@ static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
 
 /* Fold -0.0 for comparison with COND.  */
 
-static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
+static TCGv_i64 gen_fold_mzero(TCGCond *pcond, uint64_t *pimm, TCGv_i64 src)
 {
-    uint64_t mzero = 1ull << 63;
+    TCGv_i64 tmp;
 
-    switch (cond) {
+    *pimm = 0;
+    switch (*pcond) {
     case TCG_COND_LE:
     case TCG_COND_GT:
         /* For <= or >, the -0.0 value directly compares the way we want.  */
-        tcg_gen_mov_i64(dest, src);
-        break;
+        return src;
 
     case TCG_COND_EQ:
     case TCG_COND_NE:
-        /* For == or !=, we can simply mask off the sign bit and compare.  */
-        tcg_gen_andi_i64(dest, src, mzero - 1);
-        break;
+        /* For == or !=, we can compare without the sign bit. */
+        *pcond = *pcond == TCG_COND_EQ ? TCG_COND_TSTEQ : TCG_COND_TSTNE;
+        *pimm = INT64_MAX;
+        return src;
 
     case TCG_COND_GE:
     case TCG_COND_LT:
         /* For >= or <, map -0.0 to +0.0. */
-        tcg_gen_movcond_i64(TCG_COND_NE, dest, src, tcg_constant_i64(mzero),
-                            src, tcg_constant_i64(0));
-        break;
+        tmp = tcg_temp_new_i64();
+        tcg_gen_movcond_i64(TCG_COND_EQ, tmp,
+                            src, tcg_constant_i64(INT64_MIN),
+                            tcg_constant_i64(0), src);
+        return tmp;
 
     default:
-        abort();
+        g_assert_not_reached();
     }
 }
 
 static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
                                 int32_t disp)
 {
-    TCGv cmp_tmp = tcg_temp_new();
-    DisasJumpType ret;
-
-    gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra));
-    ret = gen_bcond_internal(ctx, cond, cmp_tmp, 0, disp);
-    return ret;
+    uint64_t imm;
+    TCGv_i64 tmp = gen_fold_mzero(&cond, &imm, load_fpr(ctx, ra));
+    return gen_bcond_internal(ctx, cond, tmp, imm, disp);
 }
 
 static void gen_fcmov(DisasContext *ctx, TCGCond cond, int ra, int rb, int rc)
 {
-    TCGv_i64 va, vb, z;
-
-    z = load_zero(ctx);
-    vb = load_fpr(ctx, rb);
-    va = tcg_temp_new();
-    gen_fold_mzero(cond, va, load_fpr(ctx, ra));
-
-    tcg_gen_movcond_i64(cond, dest_fpr(ctx, rc), va, z, vb, load_fpr(ctx, rc));
+    uint64_t imm;
+    TCGv_i64 tmp = gen_fold_mzero(&cond, &imm, load_fpr(ctx, ra));
+    tcg_gen_movcond_i64(cond, dest_fpr(ctx, rc),
+                        tmp, tcg_constant_i64(imm),
+                        load_fpr(ctx, rb), load_fpr(ctx, rc));
 }
 
 #define QUAL_RM_N       0x080   /* Round mode nearest even */
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 35/35] target/m68k: Use TCG_COND_TST{EQ, NE} in gen_fcc_cond
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (33 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 34/35] target/alpha: Use TCG_COND_TSTNE for gen_fold_mzero Richard Henderson
@ 2023-10-28 19:45 ` Richard Henderson
  2023-11-02 22:17 ` [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
  2024-01-06 17:43 ` Paolo Bonzini
  36 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-10-28 19:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/m68k/translate.c | 74 ++++++++++++++++++-----------------------
 1 file changed, 33 insertions(+), 41 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 4a0b0b2703..f30b92f2d4 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -5129,46 +5129,44 @@ undef:
 static void gen_fcc_cond(DisasCompare *c, DisasContext *s, int cond)
 {
     TCGv fpsr;
+    int imm = 0;
 
-    c->v2 = tcg_constant_i32(0);
     /* TODO: Raise BSUN exception.  */
     fpsr = tcg_temp_new();
     gen_load_fcr(s, fpsr, M68K_FPSR);
+    c->v1 = fpsr;
+
     switch (cond) {
     case 0:  /* False */
     case 16: /* Signaling False */
-        c->v1 = c->v2;
         c->tcond = TCG_COND_NEVER;
         break;
     case 1:  /* EQual Z */
     case 17: /* Signaling EQual Z */
-        c->v1 = tcg_temp_new();
-        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
-        c->tcond = TCG_COND_NE;
+        imm = FPSR_CC_Z;
+        c->tcond = TCG_COND_TSTNE;
         break;
     case 2:  /* Ordered Greater Than !(A || Z || N) */
     case 18: /* Greater Than !(A || Z || N) */
-        c->v1 = tcg_temp_new();
-        tcg_gen_andi_i32(c->v1, fpsr,
-                         FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
-        c->tcond = TCG_COND_EQ;
+        imm = FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N;
+        c->tcond = TCG_COND_TSTEQ;
         break;
     case 3:  /* Ordered Greater than or Equal Z || !(A || N) */
     case 19: /* Greater than or Equal Z || !(A || N) */
         c->v1 = tcg_temp_new();
         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A));
-        tcg_gen_andi_i32(fpsr, fpsr, FPSR_CC_Z | FPSR_CC_N);
         tcg_gen_or_i32(c->v1, c->v1, fpsr);
         tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
-        c->tcond = TCG_COND_NE;
+        imm = FPSR_CC_Z | FPSR_CC_N;
+        c->tcond = TCG_COND_TSTNE;
         break;
     case 4:  /* Ordered Less Than !(!N || A || Z); */
     case 20: /* Less Than !(!N || A || Z); */
         c->v1 = tcg_temp_new();
         tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_N);
-        tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z);
-        c->tcond = TCG_COND_EQ;
+        imm = FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z;
+        c->tcond = TCG_COND_TSTEQ;
         break;
     case 5:  /* Ordered Less than or Equal Z || (N && !A) */
     case 21: /* Less than or Equal Z || (N && !A) */
@@ -5176,49 +5174,45 @@ static void gen_fcc_cond(DisasCompare *c, DisasContext *s, int cond)
         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_A));
         tcg_gen_andc_i32(c->v1, fpsr, c->v1);
-        tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_Z | FPSR_CC_N);
-        c->tcond = TCG_COND_NE;
+        imm = FPSR_CC_Z | FPSR_CC_N;
+        c->tcond = TCG_COND_TSTNE;
         break;
     case 6:  /* Ordered Greater or Less than !(A || Z) */
     case 22: /* Greater or Less than !(A || Z) */
-        c->v1 = tcg_temp_new();
-        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
-        c->tcond = TCG_COND_EQ;
+        imm = FPSR_CC_A | FPSR_CC_Z;
+        c->tcond = TCG_COND_TSTEQ;
         break;
     case 7:  /* Ordered !A */
     case 23: /* Greater, Less or Equal !A */
-        c->v1 = tcg_temp_new();
-        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
-        c->tcond = TCG_COND_EQ;
+        imm = FPSR_CC_A;
+        c->tcond = TCG_COND_TSTEQ;
         break;
     case 8:  /* Unordered A */
     case 24: /* Not Greater, Less or Equal A */
-        c->v1 = tcg_temp_new();
-        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
-        c->tcond = TCG_COND_NE;
+        imm = FPSR_CC_A;
+        c->tcond = TCG_COND_TSTNE;
         break;
     case 9:  /* Unordered or Equal A || Z */
     case 25: /* Not Greater or Less then A || Z */
-        c->v1 = tcg_temp_new();
-        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
-        c->tcond = TCG_COND_NE;
+        imm = FPSR_CC_A | FPSR_CC_Z;
+        c->tcond = TCG_COND_TSTNE;
         break;
     case 10: /* Unordered or Greater Than A || !(N || Z)) */
     case 26: /* Not Less or Equal A || !(N || Z)) */
         c->v1 = tcg_temp_new();
         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z));
-        tcg_gen_andi_i32(fpsr, fpsr, FPSR_CC_A | FPSR_CC_N);
         tcg_gen_or_i32(c->v1, c->v1, fpsr);
         tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
-        c->tcond = TCG_COND_NE;
+        imm = FPSR_CC_A | FPSR_CC_N;
+        c->tcond = TCG_COND_TSTNE;
         break;
     case 11: /* Unordered or Greater or Equal A || Z || !N */
     case 27: /* Not Less Than A || Z || !N */
         c->v1 = tcg_temp_new();
-        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
-        tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
-        c->tcond = TCG_COND_NE;
+        tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_N);
+        imm = FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N;
+        c->tcond = TCG_COND_TSTNE;
         break;
     case 12: /* Unordered or Less Than A || (N && !Z) */
     case 28: /* Not Greater than or Equal A || (N && !Z) */
@@ -5226,27 +5220,25 @@ static void gen_fcc_cond(DisasCompare *c, DisasContext *s, int cond)
         tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
         tcg_gen_shli_i32(c->v1, c->v1, ctz32(FPSR_CC_N) - ctz32(FPSR_CC_Z));
         tcg_gen_andc_i32(c->v1, fpsr, c->v1);
-        tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_A | FPSR_CC_N);
-        c->tcond = TCG_COND_NE;
+        imm = FPSR_CC_A | FPSR_CC_N;
+        c->tcond = TCG_COND_TSTNE;
         break;
     case 13: /* Unordered or Less or Equal A || Z || N */
     case 29: /* Not Greater Than A || Z || N */
-        c->v1 = tcg_temp_new();
-        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
-        c->tcond = TCG_COND_NE;
+        imm = FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N;
+        c->tcond = TCG_COND_TSTNE;
         break;
     case 14: /* Not Equal !Z */
     case 30: /* Signaling Not Equal !Z */
-        c->v1 = tcg_temp_new();
-        tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
-        c->tcond = TCG_COND_EQ;
+        imm = FPSR_CC_Z;
+        c->tcond = TCG_COND_TSTEQ;
         break;
     case 15: /* True */
     case 31: /* Signaling True */
-        c->v1 = c->v2;
         c->tcond = TCG_COND_ALWAYS;
         break;
     }
+    c->v2 = tcg_constant_i32(imm);
 }
 
 static void gen_fjmpcc(DisasContext *s, int cond, TCGLabel *l1)
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (34 preceding siblings ...)
  2023-10-28 19:45 ` [PATCH v2 35/35] target/m68k: Use TCG_COND_TST{EQ, NE} in gen_fcc_cond Richard Henderson
@ 2023-11-02 22:17 ` Richard Henderson
  2024-01-06 17:43 ` Paolo Bonzini
  36 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-11-02 22:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: philmd, pbonzini

Ping.  Running out of days before soft-freeze.  :-)

r~

On 10/28/23 12:44, Richard Henderson wrote:
> Expose a pair of comparison operators that map to the "test"
> comparison that is available on many architectures.
> 
> Changes for v2:
>    * Add TCGCond to tcg_target_const_match.
>      This fixes a long-standing issue with ppc and s390x backends,
>      in that CMPI for signed comparisons has signed immediate and
>      CMPLI for unsigned comparisons has unsigned immediate.
>      But now allows different immediates for the TST comparisons.
>    * tcg/i386: Generate TEST x,x for power-of-two in {7,15,31,63}.
>    * tcg/i386: Generate BT n,x for other power-of-two.
>    * tcg/ppc: tcg_target_const_match improvements
>    * tcg/s390x: tcg_target_const_match improvements
>    * target/m68k: Use TST{EQ,NE} for gen_fcc_cond.
> 
> I wanted more testing, so I went looking for low-hanging fruit.
> I didn't see any within target/arm, probably due to how we represent NZCV,
> and I didn't want to overlap anything that Paolo might be doing with
> target/i386, so I landed on trget/m68k.  Tested via our float_convd.
> 
> 
> r~
> 
> 
> Richard Henderson (35):
>    tcg: Introduce TCG_COND_TST{EQ,NE}
>    tcg/optimize: Split out arg_is_const_val
>    tcg/optimize: Split out do_constant_folding_cond1
>    tcg/optimize: Do swap_commutative2 in do_constant_folding_cond2
>    tcg/optimize: Split out arg_new_constant
>    tcg/optimize: Handle TCG_COND_TST{EQ,NE}
>    tcg: Add TCGConst argument to tcg_target_const_match
>    tcg/aarch64: Support TCG_COND_TST{EQ,NE}
>    tcg/aarch64: Generate TBZ, TBNZ
>    tcg/aarch64: Generate CBNZ for TSTNE of UINT32_MAX
>    tcg/arm: Support TCG_COND_TST{EQ,NE}
>    tcg/i386: Pass x86 condition codes to tcg_out_cmov
>    tcg/i386: Move tcg_cond_to_jcc[] into tcg_out_cmp
>    tcg/i386: Support TCG_COND_TST{EQ,NE}
>    tcg/i386: Improve TSTNE/TESTEQ vs powers of two
>    tcg/loongarch64: Support TCG_COND_TST{EQ,NE}
>    tcg/mips: Support TCG_COND_TST{EQ,NE}
>    tcg/riscv: Support TCG_COND_TST{EQ,NE}
>    tcg/sparc64: Implement tcg_out_extrl_i64_i32
>    tcg/sparc64: Hoist read of tcg_cond_to_rcond
>    tcg/sparc64: Pass TCGCond to tcg_out_cmp
>    tcg/sparc64: Support TCG_COND_TST{EQ,NE}
>    tcg/ppc: Sink tcg_to_bc usage into tcg_out_bc
>    tcg/ppc: Use cr0 in tcg_to_bc and tcg_to_isel
>    tcg/ppc: Tidy up tcg_target_const_match
>    tcg/ppc: Add TCG_CT_CONST_CMP
>    tcg/ppc: Support TCG_COND_TST{EQ,NE}
>    tcg/s390x: Split constraint A into J+U
>    tcg/s390x: Add TCG_CT_CONST_CMP
>    tcg/s390x: Support TCG_COND_TST{EQ,NE}
>    tcg/tci: Support TCG_COND_TST{EQ,NE}
>    target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S}
>    target/alpha: Use TCG_COND_TST{EQ,NE} for CMOVLB{C,S}
>    target/alpha: Use TCG_COND_TSTNE for gen_fold_mzero
>    target/m68k: Use TCG_COND_TST{EQ,NE} in gen_fcc_cond
> 
>   docs/devel/tcg-ops.rst           |   2 +
>   include/tcg/tcg-cond.h           |  49 +++-
>   tcg/aarch64/tcg-target-con-set.h |   5 +-
>   tcg/aarch64/tcg-target-con-str.h |   1 +
>   tcg/i386/tcg-target-con-set.h    |   6 +-
>   tcg/i386/tcg-target-con-str.h    |   1 +
>   tcg/ppc/tcg-target-con-set.h     |   5 +-
>   tcg/ppc/tcg-target-con-str.h     |   1 +
>   tcg/s390x/tcg-target-con-set.h   |   8 +-
>   tcg/s390x/tcg-target-con-str.h   |   3 +-
>   target/alpha/translate.c         |  94 +++----
>   target/m68k/translate.c          |  74 +++--
>   tcg/optimize.c                   | 464 +++++++++++++++++++++++--------
>   tcg/tcg.c                        |  38 ++-
>   tcg/tci.c                        |  14 +
>   tcg/aarch64/tcg-target.c.inc     | 165 ++++++++---
>   tcg/arm/tcg-target.c.inc         |  62 +++--
>   tcg/i386/tcg-target.c.inc        | 178 ++++++++----
>   tcg/loongarch64/tcg-target.c.inc |  59 ++--
>   tcg/mips/tcg-target.c.inc        |  44 ++-
>   tcg/ppc/tcg-target.c.inc         | 277 +++++++++++++-----
>   tcg/riscv/tcg-target.c.inc       |  23 +-
>   tcg/s390x/tcg-target.c.inc       | 246 ++++++++++------
>   tcg/sparc64/tcg-target.c.inc     |  70 +++--
>   tcg/tci/tcg-target.c.inc         |   3 +-
>   25 files changed, 1342 insertions(+), 550 deletions(-)
> 



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 19/35] tcg/sparc64: Implement tcg_out_extrl_i64_i32
  2023-10-28 19:45 ` [PATCH v2 19/35] tcg/sparc64: Implement tcg_out_extrl_i64_i32 Richard Henderson
@ 2023-11-06 15:05   ` Philippe Mathieu-Daudé
  2023-11-06 18:07     ` Richard Henderson
  0 siblings, 1 reply; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 15:05 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini, qemu-stable

On 28/10/23 21:45, Richard Henderson wrote:
> Build fix for missing symbol.
> 
> Cc: qemu-stable@nongnu.org
> Fixes: b8b94ac6753 ("tcg: Split out tcg_out_extrl_i64_i32")

Commit b8b94ac6753 looks correct, don't we want:
Fixes: dad2f2f5af ("tcg/sparc64: Disable TCG_TARGET_HAS_extr_i64_i32")
?

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/sparc64/tcg-target.c.inc | 5 +++++
>   1 file changed, 5 insertions(+)
> 
> diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
> index 386f51f29e..ac86b92b75 100644
> --- a/tcg/sparc64/tcg-target.c.inc
> +++ b/tcg/sparc64/tcg-target.c.inc
> @@ -530,6 +530,11 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
>       tcg_out_ext32u(s, rd, rs);
>   }
>   
> +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
> +{
> +    tcg_out_ext32u(s, rd, rs);
> +}
> +
>   static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
>   {
>       return false;



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 01/35] tcg: Introduce TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 ` [PATCH v2 01/35] " Richard Henderson
@ 2023-11-06 15:26   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 15:26 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:44, Richard Henderson wrote:
> Add the enumerators, adjust the helpers to match, and dump.
> Not supported anywhere else just yet.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   docs/devel/tcg-ops.rst |  2 ++
>   include/tcg/tcg-cond.h | 49 ++++++++++++++++++++++++++++++++----------
>   tcg/tcg.c              |  4 +++-
>   3 files changed, 43 insertions(+), 12 deletions(-)


> diff --git a/include/tcg/tcg-cond.h b/include/tcg/tcg-cond.h
> index 2a38a386d4..bf3fcf5968 100644
> --- a/include/tcg/tcg-cond.h
> +++ b/include/tcg/tcg-cond.h
> @@ -49,6 +49,9 @@ typedef enum {

Maybe update the enum comment, otherwise:

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

>       TCG_COND_GEU    = 0 | 4 | 0 | 1,
>       TCG_COND_LEU    = 8 | 4 | 0 | 0,
>       TCG_COND_GTU    = 8 | 4 | 0 | 1,
> +    /* "test" i.e. and then compare vs 0 */
> +    TCG_COND_TSTEQ  = 8 | 4 | 2 | 0,
> +    TCG_COND_TSTNE  = 8 | 4 | 2 | 1,
>   } TCGCond;



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 02/35] tcg/optimize: Split out arg_is_const_val
  2023-10-28 19:44 ` [PATCH v2 02/35] tcg/optimize: Split out arg_is_const_val Richard Henderson
@ 2023-11-06 15:28   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 15:28 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:44, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/optimize.c | 38 +++++++++++++++++++++++---------------
>   1 file changed, 23 insertions(+), 15 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 03/35] tcg/optimize: Split out do_constant_folding_cond1
  2023-10-28 19:44 ` [PATCH v2 03/35] tcg/optimize: Split out do_constant_folding_cond1 Richard Henderson
@ 2023-11-06 15:33   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 15:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:44, Richard Henderson wrote:
> Handle modifications to the arguments and condition
> in a single place.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/optimize.c | 57 ++++++++++++++++++++++++--------------------------
>   1 file changed, 27 insertions(+), 30 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 05/35] tcg/optimize: Split out arg_new_constant
  2023-10-28 19:44 ` [PATCH v2 05/35] tcg/optimize: Split out arg_new_constant Richard Henderson
@ 2023-11-06 15:34   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 15:34 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:44, Richard Henderson wrote:
> Fixes a bug wherein raw uses of tcg_constant_internal
> do not have their TempOptInfo initialized.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/optimize.c | 29 ++++++++++++++++++-----------
>   1 file changed, 18 insertions(+), 11 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 19/35] tcg/sparc64: Implement tcg_out_extrl_i64_i32
  2023-11-06 15:05   ` Philippe Mathieu-Daudé
@ 2023-11-06 18:07     ` Richard Henderson
  0 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-11-06 18:07 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: pbonzini, qemu-stable

On 11/6/23 07:05, Philippe Mathieu-Daudé wrote:
> On 28/10/23 21:45, Richard Henderson wrote:
>> Build fix for missing symbol.
>>
>> Cc: qemu-stable@nongnu.org
>> Fixes: b8b94ac6753 ("tcg: Split out tcg_out_extrl_i64_i32")
> 
> Commit b8b94ac6753 looks correct, don't we want:
> Fixes: dad2f2f5af ("tcg/sparc64: Disable TCG_TARGET_HAS_extr_i64_i32")
> ?

You're right -- I thought the TCG_TARGET_HAS_extr_i64_i32 cleanup came first, but not so.


r~


^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 07/35] tcg: Add TCGConst argument to tcg_target_const_match
  2023-10-28 19:44 ` [PATCH v2 07/35] tcg: Add TCGConst argument to tcg_target_const_match Richard Henderson
@ 2023-11-06 18:47   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 18:47 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:44, Richard Henderson wrote:
> Fill the new argument from any condition within the opcode.
> Not yet used within any backend.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/tcg.c                        | 34 ++++++++++++++++++++++++++++++--
>   tcg/aarch64/tcg-target.c.inc     |  3 ++-
>   tcg/arm/tcg-target.c.inc         |  3 ++-
>   tcg/i386/tcg-target.c.inc        |  3 ++-
>   tcg/loongarch64/tcg-target.c.inc |  3 ++-
>   tcg/mips/tcg-target.c.inc        |  3 ++-
>   tcg/ppc/tcg-target.c.inc         |  3 ++-
>   tcg/riscv/tcg-target.c.inc       |  3 ++-
>   tcg/s390x/tcg-target.c.inc       |  3 ++-
>   tcg/sparc64/tcg-target.c.inc     |  3 ++-
>   tcg/tci/tcg-target.c.inc         |  3 ++-
>   11 files changed, 52 insertions(+), 12 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 31/35] tcg/tci: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:45 ` [PATCH v2 31/35] tcg/tci: " Richard Henderson
@ 2023-11-06 18:48   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 18:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/tci.c | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 23/35] tcg/ppc: Sink tcg_to_bc usage into tcg_out_bc
  2023-10-28 19:45 ` [PATCH v2 23/35] tcg/ppc: Sink tcg_to_bc usage into tcg_out_bc Richard Henderson
@ 2023-11-06 18:54   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 18:54 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Rename the current tcg_out_bc function to tcg_out_bc_lab, and
> create a new function that takes an integer displacement + link.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/ppc/tcg-target.c.inc | 28 +++++++++++++++++-----------
>   1 file changed, 17 insertions(+), 11 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 13/35] tcg/i386: Move tcg_cond_to_jcc[] into tcg_out_cmp
  2023-10-28 19:45 ` [PATCH v2 13/35] tcg/i386: Move tcg_cond_to_jcc[] into tcg_out_cmp Richard Henderson
@ 2023-11-06 19:46   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 19:46 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Return the x86 condition codes to use after the compare.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/i386/tcg-target.c.inc | 24 +++++++++++++-----------
>   1 file changed, 13 insertions(+), 11 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 12/35] tcg/i386: Pass x86 condition codes to tcg_out_cmov
  2023-10-28 19:44 ` [PATCH v2 12/35] tcg/i386: Pass x86 condition codes to tcg_out_cmov Richard Henderson
@ 2023-11-06 20:55   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 20:55 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:44, Richard Henderson wrote:
> Hoist the tcg_cond_to_jcc index outside the function.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/i386/tcg-target.c.inc | 16 ++++++++--------
>   1 file changed, 8 insertions(+), 8 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 18/35] tcg/riscv: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:45 ` [PATCH v2 18/35] tcg/riscv: " Richard Henderson
@ 2023-11-06 20:59   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 20:59 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/riscv/tcg-target.c.inc | 20 ++++++++++++++++++--
>   1 file changed, 18 insertions(+), 2 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 20/35] tcg/sparc64: Hoist read of tcg_cond_to_rcond
  2023-10-28 19:45 ` [PATCH v2 20/35] tcg/sparc64: Hoist read of tcg_cond_to_rcond Richard Henderson
@ 2023-11-06 21:02   ` Philippe Mathieu-Daudé
  2023-11-08 20:57     ` Richard Henderson
  0 siblings, 1 reply; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 21:02 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Use a non-zero value here (an illegal encoding) as a better
> condition than is_unsigned_cond for when MOVR/BPR is usable.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/sparc64/tcg-target.c.inc | 25 ++++++++++++++-----------
>   1 file changed, 14 insertions(+), 11 deletions(-)
> 
> diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
> index ac86b92b75..e16b25e309 100644
> --- a/tcg/sparc64/tcg-target.c.inc
> +++ b/tcg/sparc64/tcg-target.c.inc
> @@ -620,7 +620,7 @@ static const uint8_t tcg_cond_to_bcond[] = {
>       [TCG_COND_GTU] = COND_GU,
>   };
>   
> -static const uint8_t tcg_cond_to_rcond[] = {
> +static const uint8_t tcg_cond_to_rcond[16] = {


> -static void tcg_out_movr(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg c1,
> +static void tcg_out_movr(TCGContext *s, int rcond, TCGReg ret, TCGReg c1,

Isn't rcond unsigned?

Regardless,
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

>                            int32_t v1, int v1const)
>   {
> -    tcg_out32(s, ARITH_MOVR | INSN_RD(ret) | INSN_RS1(c1)
> -              | (tcg_cond_to_rcond[cond] << 10)
> +    tcg_out32(s, ARITH_MOVR | INSN_RD(ret) | INSN_RS1(c1) | (rcond << 10)
>                 | (v1const ? INSN_IMM10(v1) : INSN_RS2(v1)));
>   }



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 22/35] tcg/sparc64: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:45 ` [PATCH v2 22/35] tcg/sparc64: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-11-06 21:07   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 21:07 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/sparc64/tcg-target.c.inc | 16 ++++++++++++++--
>   1 file changed, 14 insertions(+), 2 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 25/35] tcg/ppc: Tidy up tcg_target_const_match
  2023-10-28 19:45 ` [PATCH v2 25/35] tcg/ppc: Tidy up tcg_target_const_match Richard Henderson
@ 2023-11-06 21:08   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 21:08 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/ppc/tcg-target.c.inc | 27 ++++++++++++++++-----------
>   1 file changed, 16 insertions(+), 11 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 06/35] tcg/optimize: Handle TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 ` [PATCH v2 06/35] tcg/optimize: Handle TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-11-06 21:20   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 21:20 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:44, Richard Henderson wrote:
> Fold constant comparisons.
> Canonicalize "tst x,x" to equality vs zero.
> Canonicalize "tst x,sign" to sign test vs zero.
> Fold double-word comparisons with zero parts.
> Fold setcond of "tst x,pow2" to a bit extract.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/optimize.c | 245 ++++++++++++++++++++++++++++++++++++++++++++-----
>   1 file changed, 223 insertions(+), 22 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 04/35] tcg/optimize: Do swap_commutative2 in do_constant_folding_cond2
  2023-10-28 19:44 ` [PATCH v2 04/35] tcg/optimize: Do swap_commutative2 in do_constant_folding_cond2 Richard Henderson
@ 2023-11-06 21:27   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-06 21:27 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:44, Richard Henderson wrote:
> Mirror the new do_constant_folding_cond1 by doing all
> argument and condition adjustment within one helper.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/optimize.c | 107 ++++++++++++++++++++++++++-----------------------
>   1 file changed, 57 insertions(+), 50 deletions(-)

Easier to review with a preliminary code move patch:

-- >8 --
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 89cc794d24..ae8debf6f2 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -589,43 +589,6 @@ static int do_constant_folding_cond(TCGType type, 
TCGArg x,
      return -1;
  }

-/*
- * Return -1 if the condition can't be simplified,
- * and the result of the condition (0 or 1) if it can.
- */
-static int do_constant_folding_cond2(TCGArg *p1, TCGArg *p2, TCGCond c)
-{
-    TCGArg al = p1[0], ah = p1[1];
-    TCGArg bl = p2[0], bh = p2[1];
-
-    if (arg_is_const(bl) && arg_is_const(bh)) {
-        tcg_target_ulong blv = arg_info(bl)->val;
-        tcg_target_ulong bhv = arg_info(bh)->val;
-        uint64_t b = deposit64(blv, 32, 32, bhv);
-
-        if (arg_is_const(al) && arg_is_const(ah)) {
-            tcg_target_ulong alv = arg_info(al)->val;
-            tcg_target_ulong ahv = arg_info(ah)->val;
-            uint64_t a = deposit64(alv, 32, 32, ahv);
-            return do_constant_folding_cond_64(a, b, c);
-        }
-        if (b == 0) {
-            switch (c) {
-            case TCG_COND_LTU:
-                return 0;
-            case TCG_COND_GEU:
-                return 1;
-            default:
-                break;
-            }
-        }
-    }
-    if (args_are_copies(al, bl) && args_are_copies(ah, bh)) {
-        return do_constant_folding_cond_eq(c);
-    }
-    return -1;
-}
-
  /**
   * swap_commutative:
   * @dest: TCGArg of the destination argument, or NO_DEST.
@@ -672,6 +635,10 @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
      return false;
  }

+/*
+ * Return -1 if the condition can't be simplified,
+ * and the result of the condition (0 or 1) if it can.
+ */
  static int do_constant_folding_cond1(OptContext *ctx, TCGArg dest,
                                       TCGArg *p1, TCGArg *p2, TCGArg 
*pcond)
  {
@@ -689,6 +656,39 @@ static int do_constant_folding_cond1(OptContext 
*ctx, TCGArg dest,
      return r;
  }

+static int do_constant_folding_cond2(TCGArg *p1, TCGArg *p2, TCGCond c)
+{
+    TCGArg al = p1[0], ah = p1[1];
+    TCGArg bl = p2[0], bh = p2[1];
+
+    if (arg_is_const(bl) && arg_is_const(bh)) {
+        tcg_target_ulong blv = arg_info(bl)->val;
+        tcg_target_ulong bhv = arg_info(bh)->val;
+        uint64_t b = deposit64(blv, 32, 32, bhv);
+
+        if (arg_is_const(al) && arg_is_const(ah)) {
+            tcg_target_ulong alv = arg_info(al)->val;
+            tcg_target_ulong ahv = arg_info(ah)->val;
+            uint64_t a = deposit64(alv, 32, 32, ahv);
+            return do_constant_folding_cond_64(a, b, c);
+        }
+        if (b == 0) {
+            switch (c) {
+            case TCG_COND_LTU:
+                return 0;
+            case TCG_COND_GEU:
+                return 1;
+            default:
+                break;
+            }
+        }
+    }
+    if (args_are_copies(al, bl) && args_are_copies(ah, bh)) {
+        return do_constant_folding_cond_eq(c);
+    }
+    return -1;
+}
+
  static void init_arguments(OptContext *ctx, TCGOp *op, int nb_args)
  {
      for (int i = 0; i < nb_args; i++) {
---

To the best of my knowledge:

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 11/35 1/2] tcg/arm: Factor tcg_out_cmp() out
  2023-10-28 19:44 ` [PATCH v2 11/35] tcg/arm: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-11-08 14:52   ` Philippe Mathieu-Daudé
  2023-11-08 14:52   ` [PATCH v2 11/35 2/2] tcg/arm: Support TCG_COND_TST{EQ,NE} Philippe Mathieu-Daudé
  1 sibling, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-08 14:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, qemu-arm, Philippe Mathieu-Daudé

From: Richard Henderson <richard.henderson@linaro.org>

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20231028194522.245170-12-richard.henderson@linaro.org>
[PMD: Split from bigger patch, part 1/2]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 tcg/arm/tcg-target.c.inc | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index 0c29a3929b..66d71af8bf 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -1191,6 +1191,13 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
     }
 }
 
+static TCGCond tcg_out_cmp(TCGContext *s, TCGCond cond, TCGReg a,
+                           TCGArg b, int b_const)
+{
+    tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0, a, b, b_const);
+    return cond;
+}
+
 static TCGCond tcg_out_cmp2(TCGContext *s, const TCGArg *args,
                             const int *const_args)
 {
@@ -1806,9 +1813,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         /* Constraints mean that v2 is always in the same register as dest,
          * so we only need to do "if condition passed, move v1 to dest".
          */
-        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
-                        args[1], args[2], const_args[2]);
-        tcg_out_dat_rIK(s, tcg_cond_to_arm_cond[args[5]], ARITH_MOV,
+        c = tcg_out_cmp(s, args[5], args[1], args[2], const_args[2]);
+        tcg_out_dat_rIK(s, tcg_cond_to_arm_cond[c], ARITH_MOV,
                         ARITH_MVN, args[0], 0, args[3], const_args[3]);
         break;
     case INDEX_op_add_i32:
@@ -1958,25 +1964,21 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         break;
 
     case INDEX_op_brcond_i32:
-        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
-                       args[0], args[1], const_args[1]);
-        tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]],
-                           arg_label(args[3]));
+        c = tcg_out_cmp(s, args[2], args[0], args[1], const_args[1]);
+        tcg_out_goto_label(s, tcg_cond_to_arm_cond[c], arg_label(args[3]));
         break;
     case INDEX_op_setcond_i32:
-        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
-                        args[1], args[2], const_args[2]);
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
+        c = tcg_out_cmp(s, args[3], args[1], args[2], const_args[2]);
+        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[c],
                         ARITH_MOV, args[0], 0, 1);
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
+        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(c)],
                         ARITH_MOV, args[0], 0, 0);
         break;
     case INDEX_op_negsetcond_i32:
-        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
-                        args[1], args[2], const_args[2]);
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
+        c = tcg_out_cmp(s, args[3], args[1], args[2], const_args[2]);
+        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[c],
                         ARITH_MVN, args[0], 0, 0);
-        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
+        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(c)],
                         ARITH_MOV, args[0], 0, 0);
         break;
 
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 11/35 2/2] tcg/arm: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 ` [PATCH v2 11/35] tcg/arm: Support TCG_COND_TST{EQ,NE} Richard Henderson
  2023-11-08 14:52   ` [PATCH v2 11/35 1/2] tcg/arm: Factor tcg_out_cmp() out Philippe Mathieu-Daudé
@ 2023-11-08 14:52   ` Philippe Mathieu-Daudé
  2023-11-08 17:59     ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-08 14:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, qemu-arm, Philippe Mathieu-Daudé

From: Richard Henderson <richard.henderson@linaro.org>

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20231028194522.245170-12-richard.henderson@linaro.org>
[PMD: Split from bigger patch, part 2/2]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 tcg/arm/tcg-target.c.inc | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
index 66d71af8bf..0fc7273b16 100644
--- a/tcg/arm/tcg-target.c.inc
+++ b/tcg/arm/tcg-target.c.inc
@@ -1194,7 +1194,27 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
 static TCGCond tcg_out_cmp(TCGContext *s, TCGCond cond, TCGReg a,
                            TCGArg b, int b_const)
 {
-    tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0, a, b, b_const);
+    if (!is_tst_cond(cond)) {
+        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0, a, b, b_const);
+        return cond;
+    }
+
+    cond = tcg_tst_eqne_cond(cond);
+    if (b_const) {
+        int imm12 = encode_imm(b);
+
+        /*
+         * The compare constraints allow rIN, but TST does not support N.
+         * Be prepared to load the constant into a scratch register.
+         */
+        if (imm12 >= 0) {
+            tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, a, imm12);
+            return cond;
+        }
+        tcg_out_movi32(s, COND_AL, TCG_REG_TMP, b);
+        b = TCG_REG_TMP;
+    }
+    tcg_out_dat_reg(s, COND_AL, ARITH_TST, 0, a, b, SHIFT_IMM_LSL(0));
     return cond;
 }
 
@@ -1225,6 +1245,13 @@ static TCGCond tcg_out_cmp2(TCGContext *s, const TCGArg *args,
         tcg_out_dat_rI(s, COND_EQ, ARITH_CMP, 0, al, bl, const_bl);
         return cond;
 
+    case TCG_COND_TSTEQ:
+    case TCG_COND_TSTNE:
+        /* Similar, but with TST instead of CMP. */
+        tcg_out_dat_rI(s, COND_AL, ARITH_TST, 0, ah, bh, const_bh);
+        tcg_out_dat_rI(s, COND_EQ, ARITH_TST, 0, al, bl, const_bl);
+        return tcg_tst_eqne_cond(cond);
+
     case TCG_COND_LT:
     case TCG_COND_GE:
         /* We perform a double-word subtraction and examine the result.
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 11/35 2/2] tcg/arm: Support TCG_COND_TST{EQ,NE}
  2023-11-08 14:52   ` [PATCH v2 11/35 2/2] tcg/arm: Support TCG_COND_TST{EQ,NE} Philippe Mathieu-Daudé
@ 2023-11-08 17:59     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-08 17:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, qemu-arm

On 8/11/23 15:52, Philippe Mathieu-Daudé wrote:
> From: Richard Henderson <richard.henderson@linaro.org>
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> Message-Id: <20231028194522.245170-12-richard.henderson@linaro.org>
> [PMD: Split from bigger patch, part 2/2]
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>   tcg/arm/tcg-target.c.inc | 29 ++++++++++++++++++++++++++++-
>   1 file changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc
> index 66d71af8bf..0fc7273b16 100644
> --- a/tcg/arm/tcg-target.c.inc
> +++ b/tcg/arm/tcg-target.c.inc
> @@ -1194,7 +1194,27 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
>   static TCGCond tcg_out_cmp(TCGContext *s, TCGCond cond, TCGReg a,
>                              TCGArg b, int b_const)
>   {
> -    tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0, a, b, b_const);
> +    if (!is_tst_cond(cond)) {
> +        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0, a, b, b_const);
> +        return cond;
> +    }
> +
> +    cond = tcg_tst_eqne_cond(cond);
> +    if (b_const) {
> +        int imm12 = encode_imm(b);
> +
> +        /*
> +         * The compare constraints allow rIN, but TST does not support N.
> +         * Be prepared to load the constant into a scratch register.
> +         */
> +        if (imm12 >= 0) {
> +            tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, a, imm12);
> +            return cond;
> +        }
> +        tcg_out_movi32(s, COND_AL, TCG_REG_TMP, b);
> +        b = TCG_REG_TMP;
> +    }
> +    tcg_out_dat_reg(s, COND_AL, ARITH_TST, 0, a, b, SHIFT_IMM_LSL(0));
>       return cond;
>   }

To the best of my knowledge,

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 14/35] tcg/i386: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:45 ` [PATCH v2 14/35] tcg/i386: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-11-08 18:16   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-08 18:16 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Merge tcg_out_testi into tcg_out_cmp and adjust the two uses.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/i386/tcg-target.c.inc | 83 ++++++++++++++++++++++-----------------
>   1 file changed, 47 insertions(+), 36 deletions(-)


>   #if TCG_TARGET_REG_BITS == 64
> @@ -1422,15 +1424,35 @@ static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, bool small)
>   static int tcg_out_cmp(TCGContext *s, TCGCond cond, TCGArg arg1,
>                          TCGArg arg2, int const_arg2, int rexw)
>   {
> -    if (const_arg2) {
> -        if (arg2 == 0) {
> -            /* test r, r */
> -            tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg1);
> +    if (is_tst_cond(cond)) {
> +        if (!const_arg2) {
> +            tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg2);
> +        } else if (arg2 <= 0xff && (TCG_TARGET_REG_BITS == 64 || arg1 < 4)) {
> +            tcg_out_modrm(s, OPC_GRP3_Eb | P_REXB_RM, EXT3_TESTi, arg1);
> +            tcg_out8(s, arg2);
> +        } else if ((arg2 & ~0xff00) == 0 && arg1 < 4) {
> +            tcg_out_modrm(s, OPC_GRP3_Eb, EXT3_TESTi, arg1 + 4);
> +            tcg_out8(s, arg2 >> 8);
>           } else {

For this part, a double-review from x86 developer is welcomed,

> -            tgen_arithi(s, ARITH_CMP + rexw, arg1, arg2, 0);
> +            if (rexw) {
> +                if (arg2 == (uint32_t)arg2) {
> +                    rexw = 0;
> +                } else {
> +                    tcg_debug_assert(arg2 == (int32_t)arg2);
> +                }
> +            }
> +            tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_TESTi, arg1);
> +            tcg_out32(s, arg2);
>           }
>       } else {

then the rest is OK.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 27/35] tcg/ppc: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:45 ` [PATCH v2 27/35] tcg/ppc: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-11-08 20:40   ` Philippe Mathieu-Daudé
  2023-11-08 21:27     ` Richard Henderson
  2023-11-09  8:42   ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-08 20:40 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

Hi Richard,

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/ppc/tcg-target.c.inc | 105 ++++++++++++++++++++++++++++++++++++---
>   1 file changed, 98 insertions(+), 7 deletions(-)


> -static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
> -                               int sh, int mb)
> +static void tcg_out_rld_rc(TCGContext *s, int op, TCGReg ra, TCGReg rs,
> +                           int sh, int mb, bool rc)
>   {
>       tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
>       sh = SH(sh & 0x1f) | (((sh >> 5) & 1) << 1);
>       mb = MB64((mb >> 5) | ((mb << 1) & 0x3f));
> -    tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb);
> +    tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb | rc);
>   }
>   
> -static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
> -                               int sh, int mb, int me)
> +static void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
> +                        int sh, int mb)
> +{
> +    tcg_out_rld_rc(s, op, ra, rs, sh, mb, false);
> +}
> +
> +static void tcg_out_rlw_rc(TCGContext *s, int op, TCGReg ra, TCGReg rs,
> +                           int sh, int mb, int me, bool rc)
>   {
>       tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));

Here I'm a bit confused because 'rc' is not used. Shouldn't we OR it
to tcg_out32()' second argument?

>   }
>   
> +static void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
> +                        int sh, int mb, int me)
> +{
> +    tcg_out_rlw_rc(s, op, ra, rs, sh, mb, me, false);
> +}



^ permalink raw reply	[flat|nested] 78+ messages in thread

* [PATCH v2 32/35 1/2] target/alpha: Pass immediate value to gen_bcond_internal()
  2023-10-28 19:45 ` [PATCH v2 32/35] target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S} Richard Henderson
@ 2023-11-08 20:52   ` Philippe Mathieu-Daudé
  2023-11-08 20:55     ` Philippe Mathieu-Daudé
  2023-11-08 20:52   ` [PATCH v2 32/35 2/2] target/alpha: Use TCG_COND_TST{EQ, NE} for BLB{C, S} Philippe Mathieu-Daudé
  2023-11-08 20:56   ` [PATCH v2 32/35] target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S} Philippe Mathieu-Daudé
  2 siblings, 1 reply; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-08 20:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Philippe Mathieu-Daudé

From: Richard Henderson <richard.henderson@linaro.org>

Simplify gen_bcond() by passing an immediate value.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20231028194522.245170-33-richard.henderson@linaro.org>
[PMD: Split from bigger patch, part 1/2]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/alpha/translate.c | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 32333081d8..46efe1df7c 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -453,13 +453,13 @@ static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
 }
 
 static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
-                                        TCGv cmp, int32_t disp)
+                                        TCGv cmp, uint64_t imm, int32_t disp)
 {
     uint64_t dest = ctx->base.pc_next + (disp << 2);
     TCGLabel *lab_true = gen_new_label();
 
     if (use_goto_tb(ctx, dest)) {
-        tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
+        tcg_gen_brcondi_i64(cond, cmp, imm, lab_true);
 
         tcg_gen_goto_tb(0);
         tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
@@ -472,11 +472,11 @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
 
         return DISAS_NORETURN;
     } else {
-        TCGv_i64 z = load_zero(ctx);
+        TCGv_i64 i = tcg_constant_i64(imm);
         TCGv_i64 d = tcg_constant_i64(dest);
         TCGv_i64 p = tcg_constant_i64(ctx->base.pc_next);
 
-        tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
+        tcg_gen_movcond_i64(cond, cpu_pc, cmp, i, d, p);
         return DISAS_PC_UPDATED;
     }
 }
@@ -484,15 +484,8 @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
 static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
                                int32_t disp, int mask)
 {
-    if (mask) {
-        TCGv tmp = tcg_temp_new();
-        DisasJumpType ret;
-
-        tcg_gen_andi_i64(tmp, load_gpr(ctx, ra), 1);
-        ret = gen_bcond_internal(ctx, cond, tmp, disp);
-        return ret;
-    }
-    return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra), disp);
+    return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra),
+                              !!mask, disp);
 }
 
 /* Fold -0.0 for comparison with COND.  */
@@ -533,7 +526,7 @@ static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
     DisasJumpType ret;
 
     gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra));
-    ret = gen_bcond_internal(ctx, cond, cmp_tmp, disp);
+    ret = gen_bcond_internal(ctx, cond, cmp_tmp, 0, disp);
     return ret;
 }
 
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* [PATCH v2 32/35 2/2] target/alpha: Use TCG_COND_TST{EQ, NE} for BLB{C, S}
  2023-10-28 19:45 ` [PATCH v2 32/35] target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S} Richard Henderson
  2023-11-08 20:52   ` [PATCH v2 32/35 1/2] target/alpha: Pass immediate value to gen_bcond_internal() Philippe Mathieu-Daudé
@ 2023-11-08 20:52   ` Philippe Mathieu-Daudé
  2023-11-08 20:56   ` [PATCH v2 32/35] target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S} Philippe Mathieu-Daudé
  2 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-08 20:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Philippe Mathieu-Daudé

From: Richard Henderson <richard.henderson@linaro.org>

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20231028194522.245170-33-richard.henderson@linaro.org>
[PMD: Split from bigger patch, part 2/2]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/alpha/translate.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 46efe1df7c..49e6a7b62d 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -482,10 +482,10 @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
 }
 
 static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
-                               int32_t disp, int mask)
+                               int32_t disp)
 {
     return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra),
-                              !!mask, disp);
+                              is_tst_cond(cond), disp);
 }
 
 /* Fold -0.0 for comparison with COND.  */
@@ -2820,35 +2820,35 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
         break;
     case 0x38:
         /* BLBC */
-        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
+        ret = gen_bcond(ctx, TCG_COND_TSTEQ, ra, disp21);
         break;
     case 0x39:
         /* BEQ */
-        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21);
         break;
     case 0x3A:
         /* BLT */
-        ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21);
         break;
     case 0x3B:
         /* BLE */
-        ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21);
         break;
     case 0x3C:
         /* BLBS */
-        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
+        ret = gen_bcond(ctx, TCG_COND_TSTNE, ra, disp21);
         break;
     case 0x3D:
         /* BNE */
-        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21);
         break;
     case 0x3E:
         /* BGE */
-        ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21);
         break;
     case 0x3F:
         /* BGT */
-        ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
+        ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21);
         break;
     invalid_opc:
         ret = gen_invalid(ctx);
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 33/35] target/alpha: Use TCG_COND_TST{EQ,NE} for CMOVLB{C,S}
  2023-10-28 19:45 ` [PATCH v2 33/35] target/alpha: Use TCG_COND_TST{EQ, NE} for CMOVLB{C, S} Richard Henderson
@ 2023-11-08 20:54   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-08 20:54 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/alpha/translate.c | 8 ++------
>   1 file changed, 2 insertions(+), 6 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 32/35 1/2] target/alpha: Pass immediate value to gen_bcond_internal()
  2023-11-08 20:52   ` [PATCH v2 32/35 1/2] target/alpha: Pass immediate value to gen_bcond_internal() Philippe Mathieu-Daudé
@ 2023-11-08 20:55     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-08 20:55 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson

On 8/11/23 21:52, Philippe Mathieu-Daudé wrote:
> From: Richard Henderson <richard.henderson@linaro.org>
> 
> Simplify gen_bcond() by passing an immediate value.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> Message-Id: <20231028194522.245170-33-richard.henderson@linaro.org>
> [PMD: Split from bigger patch, part 1/2]
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>   target/alpha/translate.c | 21 +++++++--------------
>   1 file changed, 7 insertions(+), 14 deletions(-)
> 
> diff --git a/target/alpha/translate.c b/target/alpha/translate.c
> index 32333081d8..46efe1df7c 100644
> --- a/target/alpha/translate.c
> +++ b/target/alpha/translate.c
> @@ -453,13 +453,13 @@ static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
>   }
>   
>   static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
> -                                        TCGv cmp, int32_t disp)
> +                                        TCGv cmp, uint64_t imm, int32_t disp)
>   {
>       uint64_t dest = ctx->base.pc_next + (disp << 2);
>       TCGLabel *lab_true = gen_new_label();
>   
>       if (use_goto_tb(ctx, dest)) {
> -        tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
> +        tcg_gen_brcondi_i64(cond, cmp, imm, lab_true);
>   
>           tcg_gen_goto_tb(0);
>           tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
> @@ -472,11 +472,11 @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
>   
>           return DISAS_NORETURN;
>       } else {
> -        TCGv_i64 z = load_zero(ctx);
> +        TCGv_i64 i = tcg_constant_i64(imm);
>           TCGv_i64 d = tcg_constant_i64(dest);
>           TCGv_i64 p = tcg_constant_i64(ctx->base.pc_next);
>   
> -        tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
> +        tcg_gen_movcond_i64(cond, cpu_pc, cmp, i, d, p);
>           return DISAS_PC_UPDATED;
>       }
>   }
> @@ -484,15 +484,8 @@ static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
>   static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
>                                  int32_t disp, int mask)
>   {
> -    if (mask) {
> -        TCGv tmp = tcg_temp_new();
> -        DisasJumpType ret;
> -
> -        tcg_gen_andi_i64(tmp, load_gpr(ctx, ra), 1);
> -        ret = gen_bcond_internal(ctx, cond, tmp, disp);
> -        return ret;
> -    }
> -    return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra), disp);
> +    return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra),
> +                              !!mask, disp);

Hmm we can pass 'mask' directly.

>   }
>   
>   /* Fold -0.0 for comparison with COND.  */
> @@ -533,7 +526,7 @@ static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
>       DisasJumpType ret;
>   
>       gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra));
> -    ret = gen_bcond_internal(ctx, cond, cmp_tmp, disp);
> +    ret = gen_bcond_internal(ctx, cond, cmp_tmp, 0, disp);
>       return ret;
>   }
>   



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 32/35] target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S}
  2023-10-28 19:45 ` [PATCH v2 32/35] target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S} Richard Henderson
  2023-11-08 20:52   ` [PATCH v2 32/35 1/2] target/alpha: Pass immediate value to gen_bcond_internal() Philippe Mathieu-Daudé
  2023-11-08 20:52   ` [PATCH v2 32/35 2/2] target/alpha: Use TCG_COND_TST{EQ, NE} for BLB{C, S} Philippe Mathieu-Daudé
@ 2023-11-08 20:56   ` Philippe Mathieu-Daudé
  2 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-08 20:56 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/alpha/translate.c | 39 ++++++++++++++++-----------------------
>   1 file changed, 16 insertions(+), 23 deletions(-)

Preferably split:
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 20/35] tcg/sparc64: Hoist read of tcg_cond_to_rcond
  2023-11-06 21:02   ` Philippe Mathieu-Daudé
@ 2023-11-08 20:57     ` Richard Henderson
  2023-11-09  8:35       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-11-08 20:57 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: pbonzini

On 11/6/23 13:02, Philippe Mathieu-Daudé wrote:
> On 28/10/23 21:45, Richard Henderson wrote:
>> Use a non-zero value here (an illegal encoding) as a better
>> condition than is_unsigned_cond for when MOVR/BPR is usable.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>   tcg/sparc64/tcg-target.c.inc | 25 ++++++++++++++-----------
>>   1 file changed, 14 insertions(+), 11 deletions(-)
>>
>> diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
>> index ac86b92b75..e16b25e309 100644
>> --- a/tcg/sparc64/tcg-target.c.inc
>> +++ b/tcg/sparc64/tcg-target.c.inc
>> @@ -620,7 +620,7 @@ static const uint8_t tcg_cond_to_bcond[] = {
>>       [TCG_COND_GTU] = COND_GU,
>>   };
>> -static const uint8_t tcg_cond_to_rcond[] = {
>> +static const uint8_t tcg_cond_to_rcond[16] = {
> 
> 
>> -static void tcg_out_movr(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg c1,
>> +static void tcg_out_movr(TCGContext *s, int rcond, TCGReg ret, TCGReg c1,
> 
> Isn't rcond unsigned?

Yes, though it is in [0-7], so it doesn't matter.


r~


^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 34/35] target/alpha: Use TCG_COND_TSTNE for gen_fold_mzero
  2023-10-28 19:45 ` [PATCH v2 34/35] target/alpha: Use TCG_COND_TSTNE for gen_fold_mzero Richard Henderson
@ 2023-11-08 21:03   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-08 21:03 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/alpha/translate.c | 49 +++++++++++++++++++---------------------
>   1 file changed, 23 insertions(+), 26 deletions(-)
> 
> diff --git a/target/alpha/translate.c b/target/alpha/translate.c
> index c7daf46de7..c68c2bcd21 100644
> --- a/target/alpha/translate.c
> +++ b/target/alpha/translate.c
> @@ -490,56 +490,53 @@ static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
>   
>   /* Fold -0.0 for comparison with COND.  */
>   
> -static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
> +static TCGv_i64 gen_fold_mzero(TCGCond *pcond, uint64_t *pimm, TCGv_i64 src)
>   {
> -    uint64_t mzero = 1ull << 63;
> +    TCGv_i64 tmp;
>   
> -    switch (cond) {
> +    *pimm = 0;
> +    switch (*pcond) {
>       case TCG_COND_LE:
>       case TCG_COND_GT:
>           /* For <= or >, the -0.0 value directly compares the way we want.  */
> -        tcg_gen_mov_i64(dest, src);
> -        break;
> +        return src;
>   
>       case TCG_COND_EQ:
>       case TCG_COND_NE:
> -        /* For == or !=, we can simply mask off the sign bit and compare.  */
> -        tcg_gen_andi_i64(dest, src, mzero - 1);
> -        break;
> +        /* For == or !=, we can compare without the sign bit. */

> +        *pcond = *pcond == TCG_COND_EQ ? TCG_COND_TSTEQ : TCG_COND_TSTNE;

OK, $subject is only this line, the rest is purely refactoring.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

> +        *pimm = INT64_MAX;
> +        return src;
>   
>       case TCG_COND_GE:
>       case TCG_COND_LT:
>           /* For >= or <, map -0.0 to +0.0. */
> -        tcg_gen_movcond_i64(TCG_COND_NE, dest, src, tcg_constant_i64(mzero),
> -                            src, tcg_constant_i64(0));
> -        break;
> +        tmp = tcg_temp_new_i64();
> +        tcg_gen_movcond_i64(TCG_COND_EQ, tmp,
> +                            src, tcg_constant_i64(INT64_MIN),
> +                            tcg_constant_i64(0), src);
> +        return tmp;
>   
>       default:
> -        abort();
> +        g_assert_not_reached();
>       }
>   }



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 27/35] tcg/ppc: Support TCG_COND_TST{EQ,NE}
  2023-11-08 20:40   ` Philippe Mathieu-Daudé
@ 2023-11-08 21:27     ` Richard Henderson
  0 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2023-11-08 21:27 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: pbonzini

On 11/8/23 12:40, Philippe Mathieu-Daudé wrote:
> Hi Richard,
> 
> On 28/10/23 21:45, Richard Henderson wrote:
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>   tcg/ppc/tcg-target.c.inc | 105 ++++++++++++++++++++++++++++++++++++---
>>   1 file changed, 98 insertions(+), 7 deletions(-)
> 
> 
>> -static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
>> -                               int sh, int mb)
>> +static void tcg_out_rld_rc(TCGContext *s, int op, TCGReg ra, TCGReg rs,
>> +                           int sh, int mb, bool rc)
>>   {
>>       tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
>>       sh = SH(sh & 0x1f) | (((sh >> 5) & 1) << 1);
>>       mb = MB64((mb >> 5) | ((mb << 1) & 0x3f));
>> -    tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb);
>> +    tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb | rc);
>>   }
>> -static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
>> -                               int sh, int mb, int me)
>> +static void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
>> +                        int sh, int mb)
>> +{
>> +    tcg_out_rld_rc(s, op, ra, rs, sh, mb, false);
>> +}
>> +
>> +static void tcg_out_rlw_rc(TCGContext *s, int op, TCGReg ra, TCGReg rs,
>> +                           int sh, int mb, int me, bool rc)
>>   {
>>       tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
> 
> Here I'm a bit confused because 'rc' is not used. Shouldn't we OR it
> to tcg_out32()' second argument?

Yep, should be just like rld_rc above.


r~


^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 20/35] tcg/sparc64: Hoist read of tcg_cond_to_rcond
  2023-11-08 20:57     ` Richard Henderson
@ 2023-11-09  8:35       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-09  8:35 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 8/11/23 21:57, Richard Henderson wrote:
> On 11/6/23 13:02, Philippe Mathieu-Daudé wrote:
>> On 28/10/23 21:45, Richard Henderson wrote:
>>> Use a non-zero value here (an illegal encoding) as a better
>>> condition than is_unsigned_cond for when MOVR/BPR is usable.
>>>
>>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>>> ---
>>>   tcg/sparc64/tcg-target.c.inc | 25 ++++++++++++++-----------
>>>   1 file changed, 14 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
>>> index ac86b92b75..e16b25e309 100644
>>> --- a/tcg/sparc64/tcg-target.c.inc
>>> +++ b/tcg/sparc64/tcg-target.c.inc
>>> @@ -620,7 +620,7 @@ static const uint8_t tcg_cond_to_bcond[] = {
>>>       [TCG_COND_GTU] = COND_GU,
>>>   };
>>> -static const uint8_t tcg_cond_to_rcond[] = {
>>> +static const uint8_t tcg_cond_to_rcond[16] = {
>>
>>
>>> -static void tcg_out_movr(TCGContext *s, TCGCond cond, TCGReg ret, 
>>> TCGReg c1,
>>> +static void tcg_out_movr(TCGContext *s, int rcond, TCGReg ret, 
>>> TCGReg c1,
>>
>> Isn't rcond unsigned?
> 
> Yes, though it is in [0-7], so it doesn't matter.

Maybe using 'uint8_t' would be clearer. Just suggesting, not a blocker.



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 27/35] tcg/ppc: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:45 ` [PATCH v2 27/35] tcg/ppc: Support TCG_COND_TST{EQ,NE} Richard Henderson
  2023-11-08 20:40   ` Philippe Mathieu-Daudé
@ 2023-11-09  8:42   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-09  8:42 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

Hi Richard,

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/ppc/tcg-target.c.inc | 105 ++++++++++++++++++++++++++++++++++++---
>   1 file changed, 98 insertions(+), 7 deletions(-)


> +/*
> + * Set dest non-zero if and only if (arg1 & arg2) is non-zero.
> + * If RC, then also set RC0.
> + */
> +static void tcg_out_test(TCGContext *s, TCGReg dest, TCGReg arg1, TCGArg arg2,
> +                         bool const_arg2, TCGType type, bool rc)
> +{
> +    int mb, me;
> +
> +    if (!const_arg2) {
> +        tcg_out32(s, AND | SAB(arg1, dest, arg2) | rc);
> +        return;
> +    }
> +
> +    if (type == TCG_TYPE_I32) {
> +        arg2 = (uint32_t)arg2;
> +    } else if (arg2 == (uint32_t)arg2) {
> +        type = TCG_TYPE_I32;
> +    }
> +
> +    if ((arg2 & ~0xffff) == 0) {
> +        tcg_out32(s, ANDI | SAI(arg1, dest, arg2));

Is it SAI() we want here, since arg2 bits are all masked?

> +        return;
> +    }
> +    if ((arg2 & ~0xffff0000ull) == 0) {
> +        tcg_out32(s, ANDI | SAI(arg1, dest, arg2));
> +        return;
> +    }
> +    if (type == TCG_TYPE_I32) {
> +        if (mask_operand(arg2, &mb, &me)) {
> +            tcg_out_rlw_rc(s, RLWINM, dest, arg1, 0, mb, me, rc);
> +            return;
> +        }
> +    } else {
> +        int sh = clz64(arg2);
> +        if (mask64_operand(arg2 << sh, &mb, &me)) {
> +            tcg_out_rld_rc(s, RLDICR, dest, arg1, sh, me, rc);
> +            return;
> +        }
> +    }
> +    /* Constraints should satisfy this. */
> +    g_assert_not_reached();
> +}



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 21/35] tcg/sparc64: Pass TCGCond to tcg_out_cmp
  2023-10-28 19:45 ` [PATCH v2 21/35] tcg/sparc64: Pass TCGCond to tcg_out_cmp Richard Henderson
@ 2023-11-09 11:29   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-09 11:29 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/sparc64/tcg-target.c.inc | 21 +++++++++++----------
>   1 file changed, 11 insertions(+), 10 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 17/35] tcg/mips: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:45 ` [PATCH v2 17/35] tcg/mips: " Richard Henderson
@ 2023-11-17  7:46   ` Philippe Mathieu-Daudé
  2023-11-17 16:36     ` Richard Henderson
  0 siblings, 1 reply; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-17  7:46 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

Hi Richard,

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/mips/tcg-target.c.inc | 41 +++++++++++++++++++++++++++++++++++++++
>   1 file changed, 41 insertions(+)


> @@ -1053,6 +1071,14 @@ static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
>           tcg_out_setcond(s, cond, ret, tmp1, TCG_REG_ZERO);
>           break;
>   
> +    case TCG_COND_TSTEQ:
> +    case TCG_COND_TSTNE:
> +        tcg_out_opc_reg(s, OPC_AND, TCG_TMP0, al, bl);
> +        tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, ah, bh);
> +        tcg_out_opc_reg(s, OPC_OR, ret, TCG_TMP0, TCG_TMP1);
> +        tcg_out_setcond(s, tcg_eqne_cond(cond), ret, tmp1, TCG_REG_ZERO);

Where is tcg_eqne_cond() declared?

> +        break;



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 16/35] tcg/loongarch64: Support TCG_COND_TST{EQ,NE}
  2023-10-28 19:45 ` [PATCH v2 16/35] tcg/loongarch64: Support TCG_COND_TST{EQ,NE} Richard Henderson
@ 2023-11-17  7:48   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-17  7:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

On 28/10/23 21:45, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/loongarch64/tcg-target.c.inc | 56 ++++++++++++++++++++++----------
>   1 file changed, 38 insertions(+), 18 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 17/35] tcg/mips: Support TCG_COND_TST{EQ,NE}
  2023-11-17  7:46   ` Philippe Mathieu-Daudé
@ 2023-11-17 16:36     ` Richard Henderson
  2023-12-13 14:06       ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2023-11-17 16:36 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel; +Cc: pbonzini

On 11/16/23 23:46, Philippe Mathieu-Daudé wrote:
> Hi Richard,
> 
> On 28/10/23 21:45, Richard Henderson wrote:
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>   tcg/mips/tcg-target.c.inc | 41 +++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 41 insertions(+)
> 
> 
>> @@ -1053,6 +1071,14 @@ static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg 
>> ret,
>>           tcg_out_setcond(s, cond, ret, tmp1, TCG_REG_ZERO);
>>           break;
>> +    case TCG_COND_TSTEQ:
>> +    case TCG_COND_TSTNE:
>> +        tcg_out_opc_reg(s, OPC_AND, TCG_TMP0, al, bl);
>> +        tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, ah, bh);
>> +        tcg_out_opc_reg(s, OPC_OR, ret, TCG_TMP0, TCG_TMP1);
>> +        tcg_out_setcond(s, tcg_eqne_cond(cond), ret, tmp1, TCG_REG_ZERO);
> 
> Where is tcg_eqne_cond() declared?

tcg_tst_eqne_cond() is in tcg/tcg-cond.h.
This is a rebase error when I renamed it; I have fixed it since.


r~



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 17/35] tcg/mips: Support TCG_COND_TST{EQ,NE}
  2023-11-17 16:36     ` Richard Henderson
@ 2023-12-13 14:06       ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 78+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-12-13 14:06 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: pbonzini

Hi Richard,

On 17/11/23 17:36, Richard Henderson wrote:
> On 11/16/23 23:46, Philippe Mathieu-Daudé wrote:
>> Hi Richard,
>>
>> On 28/10/23 21:45, Richard Henderson wrote:
>>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>>> ---
>>>   tcg/mips/tcg-target.c.inc | 41 +++++++++++++++++++++++++++++++++++++++
>>>   1 file changed, 41 insertions(+)
>>
>>
>>> @@ -1053,6 +1071,14 @@ static void tcg_out_setcond2(TCGContext *s, 
>>> TCGCond cond, TCGReg ret,
>>>           tcg_out_setcond(s, cond, ret, tmp1, TCG_REG_ZERO);
>>>           break;
>>> +    case TCG_COND_TSTEQ:
>>> +    case TCG_COND_TSTNE:
>>> +        tcg_out_opc_reg(s, OPC_AND, TCG_TMP0, al, bl);
>>> +        tcg_out_opc_reg(s, OPC_AND, TCG_TMP1, ah, bh);
>>> +        tcg_out_opc_reg(s, OPC_OR, ret, TCG_TMP0, TCG_TMP1);
>>> +        tcg_out_setcond(s, tcg_eqne_cond(cond), ret, tmp1, 
>>> TCG_REG_ZERO);
>>
>> Where is tcg_eqne_cond() declared?
> 
> tcg_tst_eqne_cond() is in tcg/tcg-cond.h.
> This is a rebase error when I renamed it; I have fixed it since.

Looking at https://gitlab.com/rth7680/qemu/-/commits/tcg-test/
commits the patch is now quite different. I suppose you plan to
post a v3, so will wait for it to finish what isn't reviewed.

Regards,

Phil.


^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE}
  2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
                   ` (35 preceding siblings ...)
  2023-11-02 22:17 ` [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
@ 2024-01-06 17:43 ` Paolo Bonzini
  2024-01-08 21:45   ` Richard Henderson
  36 siblings, 1 reply; 78+ messages in thread
From: Paolo Bonzini @ 2024-01-06 17:43 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, philmd

On Sat, Oct 28, 2023 at 9:45 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Expose a pair of comparison operators that map to the "test"
> comparison that is available on many architectures.
>
> Changes for v2:
>   * Add TCGCond to tcg_target_const_match.
>     This fixes a long-standing issue with ppc and s390x backends,
>     in that CMPI for signed comparisons has signed immediate and
>     CMPLI for unsigned comparisons has unsigned immediate.
>     But now allows different immediates for the TST comparisons.
>   * tcg/i386: Generate TEST x,x for power-of-two in {7,15,31,63}.
>   * tcg/i386: Generate BT n,x for other power-of-two.
>   * tcg/ppc: tcg_target_const_match improvements
>   * tcg/s390x: tcg_target_const_match improvements
>   * target/m68k: Use TST{EQ,NE} for gen_fcc_cond.

I updated the MIPS backend (untested though) and pushed the result to
branch i386 of https://gitlab.com/bonzini/qemu/.

However I was thinking: a lot of RISC targets simply do AND/ANDI
followed by the sequence used for TCG_COND_NE.  Would it make sense to
have a TCG_TARGET_SUPPORTS_TST bit and, if absent, lower TSTEQ/TSTNE
to AND+EQ/NE directly in the optimizer?  And for brcond2/setcond2,
always using AND/AND/OR may work just as well as any backend-specific
trick, and will give more freedom to the register allocator.

This also would allow to reorder the target patches before the TCG
patches, thus: 1) providing more exposure to the lowering code 2)
making the "minimum viable series" smaller. (2) is not a huge deal
since you have already written the backend code, but (1) is
interesting.

Paolo



^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE}
  2024-01-06 17:43 ` Paolo Bonzini
@ 2024-01-08 21:45   ` Richard Henderson
  2024-01-08 22:55     ` Paolo Bonzini
  0 siblings, 1 reply; 78+ messages in thread
From: Richard Henderson @ 2024-01-08 21:45 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel, philmd

On 1/7/24 04:43, Paolo Bonzini wrote:
> On Sat, Oct 28, 2023 at 9:45 PM Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> Expose a pair of comparison operators that map to the "test"
>> comparison that is available on many architectures.
>>
>> Changes for v2:
>>    * Add TCGCond to tcg_target_const_match.
>>      This fixes a long-standing issue with ppc and s390x backends,
>>      in that CMPI for signed comparisons has signed immediate and
>>      CMPLI for unsigned comparisons has unsigned immediate.
>>      But now allows different immediates for the TST comparisons.
>>    * tcg/i386: Generate TEST x,x for power-of-two in {7,15,31,63}.
>>    * tcg/i386: Generate BT n,x for other power-of-two.
>>    * tcg/ppc: tcg_target_const_match improvements
>>    * tcg/s390x: tcg_target_const_match improvements
>>    * target/m68k: Use TST{EQ,NE} for gen_fcc_cond.
> 
> I updated the MIPS backend (untested though) and pushed the result to
> branch i386 of https://gitlab.com/bonzini/qemu/.

Thanks.

> 
> However I was thinking: a lot of RISC targets simply do AND/ANDI
> followed by the sequence used for TCG_COND_NE.  Would it make sense to
> have a TCG_TARGET_SUPPORTS_TST bit and, if absent, lower TSTEQ/TSTNE
> to AND+EQ/NE directly in the optimizer?

Probably best, yes.

> And for brcond2/setcond2,
> always using AND/AND/OR may work just as well as any backend-specific
> trick, and will give more freedom to the register allocator.

   test   a,b
   testeq c,e

for Arm32.  So I'll leave it to the backends.


r~


^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE}
  2024-01-08 21:45   ` Richard Henderson
@ 2024-01-08 22:55     ` Paolo Bonzini
  2024-01-09  8:36       ` Richard Henderson
  0 siblings, 1 reply; 78+ messages in thread
From: Paolo Bonzini @ 2024-01-08 22:55 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, Philippe Mathieu-Daudé

[-- Attachment #1: Type: text/plain, Size: 678 bytes --]

Il lun 8 gen 2024, 22:45 Richard Henderson <richard.henderson@linaro.org>
ha scritto:

> > I was thinking: a lot of RISC targets simply do AND/ANDI
> > followed by the sequence used for TCG_COND_NE.  Would it make sense to
> > have a TCG_TARGET_SUPPORTS_TST bit and, if absent, lower TSTEQ/TSTNE
> > to AND+EQ/NE directly in the optimizer?
>
> Probably best, yes.
>

Ok, I will give it a shot.

> And for brcond2/setcond2,
> > always using AND/AND/OR may work just as well as any backend-specific
> > trick, and will give more freedom to the register allocator.
>
>    test   a,b
>    testeq c,e
>
> for Arm32.  So I'll leave it to the backends.
>

Nice. :)

Paolo


>
> r~
>
>

[-- Attachment #2: Type: text/html, Size: 1579 bytes --]

^ permalink raw reply	[flat|nested] 78+ messages in thread

* Re: [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE}
  2024-01-08 22:55     ` Paolo Bonzini
@ 2024-01-09  8:36       ` Richard Henderson
  0 siblings, 0 replies; 78+ messages in thread
From: Richard Henderson @ 2024-01-09  8:36 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel, Philippe Mathieu-Daudé

On 1/9/24 09:55, Paolo Bonzini wrote:
> 
> 
> Il lun 8 gen 2024, 22:45 Richard Henderson <richard.henderson@linaro.org 
> <mailto:richard.henderson@linaro.org>> ha scritto:
> 
>      > I was thinking: a lot of RISC targets simply do AND/ANDI
>      > followed by the sequence used for TCG_COND_NE.  Would it make sense to
>      > have a TCG_TARGET_SUPPORTS_TST bit and, if absent, lower TSTEQ/TSTNE
>      > to AND+EQ/NE directly in the optimizer?
> 
>     Probably best, yes.
> 
> 
> Ok, I will give it a shot.

I'm in the process now...


r~


^ permalink raw reply	[flat|nested] 78+ messages in thread

end of thread, other threads:[~2024-01-09  8:36 UTC | newest]

Thread overview: 78+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-28 19:44 [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
2023-10-28 19:44 ` [PATCH v2 01/35] " Richard Henderson
2023-11-06 15:26   ` Philippe Mathieu-Daudé
2023-10-28 19:44 ` [PATCH v2 02/35] tcg/optimize: Split out arg_is_const_val Richard Henderson
2023-11-06 15:28   ` Philippe Mathieu-Daudé
2023-10-28 19:44 ` [PATCH v2 03/35] tcg/optimize: Split out do_constant_folding_cond1 Richard Henderson
2023-11-06 15:33   ` Philippe Mathieu-Daudé
2023-10-28 19:44 ` [PATCH v2 04/35] tcg/optimize: Do swap_commutative2 in do_constant_folding_cond2 Richard Henderson
2023-11-06 21:27   ` Philippe Mathieu-Daudé
2023-10-28 19:44 ` [PATCH v2 05/35] tcg/optimize: Split out arg_new_constant Richard Henderson
2023-11-06 15:34   ` Philippe Mathieu-Daudé
2023-10-28 19:44 ` [PATCH v2 06/35] tcg/optimize: Handle TCG_COND_TST{EQ,NE} Richard Henderson
2023-11-06 21:20   ` Philippe Mathieu-Daudé
2023-10-28 19:44 ` [PATCH v2 07/35] tcg: Add TCGConst argument to tcg_target_const_match Richard Henderson
2023-11-06 18:47   ` Philippe Mathieu-Daudé
2023-10-28 19:44 ` [PATCH v2 08/35] tcg/aarch64: Support TCG_COND_TST{EQ,NE} Richard Henderson
2023-10-28 19:44 ` [PATCH v2 09/35] tcg/aarch64: Generate TBZ, TBNZ Richard Henderson
2023-10-28 19:44 ` [PATCH v2 10/35] tcg/aarch64: Generate CBNZ for TSTNE of UINT32_MAX Richard Henderson
2023-10-28 19:44 ` [PATCH v2 11/35] tcg/arm: Support TCG_COND_TST{EQ,NE} Richard Henderson
2023-11-08 14:52   ` [PATCH v2 11/35 1/2] tcg/arm: Factor tcg_out_cmp() out Philippe Mathieu-Daudé
2023-11-08 14:52   ` [PATCH v2 11/35 2/2] tcg/arm: Support TCG_COND_TST{EQ,NE} Philippe Mathieu-Daudé
2023-11-08 17:59     ` Philippe Mathieu-Daudé
2023-10-28 19:44 ` [PATCH v2 12/35] tcg/i386: Pass x86 condition codes to tcg_out_cmov Richard Henderson
2023-11-06 20:55   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 13/35] tcg/i386: Move tcg_cond_to_jcc[] into tcg_out_cmp Richard Henderson
2023-11-06 19:46   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 14/35] tcg/i386: Support TCG_COND_TST{EQ,NE} Richard Henderson
2023-11-08 18:16   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 15/35] tcg/i386: Improve TSTNE/TESTEQ vs powers of two Richard Henderson
2023-10-28 19:45 ` [PATCH v2 16/35] tcg/loongarch64: Support TCG_COND_TST{EQ,NE} Richard Henderson
2023-11-17  7:48   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 17/35] tcg/mips: " Richard Henderson
2023-11-17  7:46   ` Philippe Mathieu-Daudé
2023-11-17 16:36     ` Richard Henderson
2023-12-13 14:06       ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 18/35] tcg/riscv: " Richard Henderson
2023-11-06 20:59   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 19/35] tcg/sparc64: Implement tcg_out_extrl_i64_i32 Richard Henderson
2023-11-06 15:05   ` Philippe Mathieu-Daudé
2023-11-06 18:07     ` Richard Henderson
2023-10-28 19:45 ` [PATCH v2 20/35] tcg/sparc64: Hoist read of tcg_cond_to_rcond Richard Henderson
2023-11-06 21:02   ` Philippe Mathieu-Daudé
2023-11-08 20:57     ` Richard Henderson
2023-11-09  8:35       ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 21/35] tcg/sparc64: Pass TCGCond to tcg_out_cmp Richard Henderson
2023-11-09 11:29   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 22/35] tcg/sparc64: Support TCG_COND_TST{EQ,NE} Richard Henderson
2023-11-06 21:07   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 23/35] tcg/ppc: Sink tcg_to_bc usage into tcg_out_bc Richard Henderson
2023-11-06 18:54   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 24/35] tcg/ppc: Use cr0 in tcg_to_bc and tcg_to_isel Richard Henderson
2023-10-28 19:45 ` [PATCH v2 25/35] tcg/ppc: Tidy up tcg_target_const_match Richard Henderson
2023-11-06 21:08   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 26/35] tcg/ppc: Add TCG_CT_CONST_CMP Richard Henderson
2023-10-28 19:45 ` [PATCH v2 27/35] tcg/ppc: Support TCG_COND_TST{EQ,NE} Richard Henderson
2023-11-08 20:40   ` Philippe Mathieu-Daudé
2023-11-08 21:27     ` Richard Henderson
2023-11-09  8:42   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 28/35] tcg/s390x: Split constraint A into J+U Richard Henderson
2023-10-28 19:45 ` [PATCH v2 29/35] tcg/s390x: Add TCG_CT_CONST_CMP Richard Henderson
2023-10-28 19:45 ` [PATCH v2 30/35] tcg/s390x: Support TCG_COND_TST{EQ,NE} Richard Henderson
2023-10-28 19:45 ` [PATCH v2 31/35] tcg/tci: " Richard Henderson
2023-11-06 18:48   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 32/35] target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S} Richard Henderson
2023-11-08 20:52   ` [PATCH v2 32/35 1/2] target/alpha: Pass immediate value to gen_bcond_internal() Philippe Mathieu-Daudé
2023-11-08 20:55     ` Philippe Mathieu-Daudé
2023-11-08 20:52   ` [PATCH v2 32/35 2/2] target/alpha: Use TCG_COND_TST{EQ, NE} for BLB{C, S} Philippe Mathieu-Daudé
2023-11-08 20:56   ` [PATCH v2 32/35] target/alpha: Use TCG_COND_TST{EQ,NE} for BLB{C,S} Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 33/35] target/alpha: Use TCG_COND_TST{EQ, NE} for CMOVLB{C, S} Richard Henderson
2023-11-08 20:54   ` [PATCH v2 33/35] target/alpha: Use TCG_COND_TST{EQ,NE} for CMOVLB{C,S} Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 34/35] target/alpha: Use TCG_COND_TSTNE for gen_fold_mzero Richard Henderson
2023-11-08 21:03   ` Philippe Mathieu-Daudé
2023-10-28 19:45 ` [PATCH v2 35/35] target/m68k: Use TCG_COND_TST{EQ, NE} in gen_fcc_cond Richard Henderson
2023-11-02 22:17 ` [PATCH v2 00/35] tcg: Introduce TCG_COND_TST{EQ,NE} Richard Henderson
2024-01-06 17:43 ` Paolo Bonzini
2024-01-08 21:45   ` Richard Henderson
2024-01-08 22:55     ` Paolo Bonzini
2024-01-09  8:36       ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.