Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
tcg/ppc/tcg-target.c.inc | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index fe141a26f9..5a316f364d 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -669,9 +669,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,
@@ -683,9 +685,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,
@@ -1699,6 +1703,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_and_rc(s, type, TCG_REG_R0, arg1, arg2, const_arg2, true);
+ return;
+
case TCG_COND_LT:
case TCG_COND_GE:
case TCG_COND_LE:
@@ -1909,6 +1919,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_and_rc(s, type, TCG_REG_R0, arg1, arg2, const_arg2, false);
+ tcg_out_setcond_eq0(s, type, arg0, TCG_REG_R0, neg);
+ break;
+
+ case TCG_COND_TSTNE:
+ tcg_out_and_rc(s, type, TCG_REG_R0, arg1, arg2, const_arg2, false);
+ tcg_out_setcond_ne0(s, type, arg0, TCG_REG_R0, neg);
+ break;
+
case TCG_COND_LE:
case TCG_COND_LEU:
inv = true;
@@ -2081,6 +2101,13 @@ 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:
+ tcg_out_and_rc(s, TCG_TYPE_I32, TCG_REG_R0, al, bl, blconst, false);
+ tcg_out_and_rc(s, TCG_TYPE_I32, TCG_REG_TMP1, ah, bh, bhconst, false);
+ 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