@@ -2908,6 +2908,15 @@ noce_try_sign_mask (struct noce_if_info *if_info)
return true;
}
+static bool
+noce_cond_zero_binary_op_supported (enum rtx_code op)
+{
+ if (op == PLUS || op == MINUS || op == IOR || op == XOR)
+ return true;
+
+ return false;
+}
+
/* Convert x = c ? y + z : y or x = c ? y : y + z. */
static bool
@@ -2918,6 +2927,7 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info)
machine_mode mode = GET_MODE (if_info->x);
rtx common = NULL_RTX;
enum rtx_code czero_code = UNKNOWN;
+ enum rtx_code opcode = UNKNOWN;
rtx a = if_info->a;
rtx b = if_info->b;
rtx z = NULL_RTX;
@@ -2933,18 +2943,21 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info)
return false;
/* check y + z:y*/
- if (GET_CODE (a) == PLUS && REG_P (XEXP (a, 0)) && REG_P (XEXP (a, 1))
- && REG_P (b) && rtx_equal_p (XEXP (a, 0), b))
+ if (noce_cond_zero_binary_op_supported (GET_CODE (a)) && REG_P (XEXP (a, 0))
+ && REG_P (XEXP (a, 1)) && REG_P (b) && rtx_equal_p (XEXP (a, 0), b))
{
+ opcode = GET_CODE (a);
common = b;
z = XEXP (a, 1);
/* x = c ? y+z : y, cond = !c --> x = cond ? y : y+z */
czero_code = GET_CODE (cond);
}
/* check y : y+z */
- else if (GET_CODE (b) == PLUS && REG_P (XEXP (b, 0)) && REG_P (XEXP (b, 1))
- && REG_P (a) && rtx_equal_p (a, XEXP (b, 0)))
+ else if (noce_cond_zero_binary_op_supported (GET_CODE (b))
+ && REG_P (XEXP (b, 0)) && REG_P (XEXP (b, 1)) && REG_P (a)
+ && rtx_equal_p (a, XEXP (b, 0)))
{
+ opcode = GET_CODE (b);
common = a;
z = XEXP (b, 1);
/* x = c ? y : y+z, cond = !c --> x = !cond ? y : y+z */
@@ -2971,7 +2984,7 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info)
return false;
}
- target = expand_simple_binop (mode, PLUS, common, target, if_info->x, 0,
+ target = expand_simple_binop (mode, opcode, common, target, if_info->x, 0,
OPTAB_DIRECT);
if (!target)
{
@@ -128,3 +128,381 @@ long test_ADD_eqz_x_2(long x, long z, long c)
x = x + z;
return x;
}
+
+/*
+**test_SUB_ceqz:
+** czero\.eqz a3,a2,a3
+** sub a0,a1,a3
+** ret
+*/
+// x = c ? y-z : y
+long test_SUB_ceqz(long x, long y, long z, long c)
+{
+ if (c)
+ x = y - z;
+ else
+ x = y;
+ return x;
+}
+
+/*
+**test_SUB_ceqz_x:
+** czero\.eqz a2,a1,a2
+** sub a0,a0,a2
+** ret
+*/
+// x = c ? x-z : x
+long test_SUB_ceqz_x(long x, long z, long c)
+{
+ if (c)
+ x = x - z;
+
+ return x;
+}
+
+/*
+**test_SUB_nez:
+** czero\.nez a3,a2,a3
+** sub a0,a1,a3
+** ret
+*/
+// x = c ? y : y-z
+long test_SUB_nez(long x, long y, long z, long c)
+{
+ if (c)
+ x = y;
+ else
+ x = y - z;
+ return x;
+}
+
+/*
+**test_SUB_nez_x:
+** czero\.nez a2,a1,a2
+** sub a0,a0,a2
+** ret
+*/
+// x = c ? x : x-z
+long test_SUB_nez_x(long x, long z, long c)
+{
+ if (c)
+ {}
+ else
+ x = x - z;
+ return x;
+}
+
+/*
+**test_SUB_nez_2:
+** czero\.nez a3,a2,a3
+** sub a0,a1,a3
+** ret
+*/
+// x = !c ? y-z : y
+long test_SUB_nez_2(long x, long y, long z, long c)
+{
+ if (!c)
+ x = y - z;
+ else
+ x = y;
+ return x;
+}
+
+/*
+**test_SUB_nez_x_2:
+** czero\.nez a2,a1,a2
+** sub a0,a0,a2
+** ret
+*/
+// x = !c ? x-z : x
+long test_SUB_nez_x_2(long x, long z, long c)
+{
+ if (!c)
+ x = x - z;
+
+ return x;
+}
+
+/*
+**test_SUB_eqz_2:
+** czero\.eqz a3,a2,a3
+** sub a0,a1,a3
+** ret
+*/
+// x = !c ? y : y-z
+long test_SUB_eqz_2(long x, long y, long z, long c)
+{
+ if (!c)
+ x = y;
+ else
+ x = y - z;
+ return x;
+}
+
+/*
+**test_SUB_eqz_x_2:
+** czero\.eqz a2,a1,a2
+** sub a0,a0,a2
+** ret
+*/
+// x = !c ? x : x-z
+long test_SUB_eqz_x_2(long x, long z, long c)
+{
+ if (!c)
+ {}
+ else
+ x = x - z;
+ return x;
+}
+
+/*
+**test_IOR_ceqz:
+** czero\.eqz a3,a2,a3
+** or a0,a1,a3
+** ret
+*/
+// x = c ? y|z : y
+long test_IOR_ceqz(long x, long y, long z, long c)
+{
+ if (c)
+ x = y | z;
+ else
+ x = y;
+ return x;
+}
+
+/*
+**test_IOR_ceqz_x:
+** czero\.eqz a2,a1,a2
+** or a0,a0,a2
+** ret
+*/
+// x = c ? x|z : x
+long test_IOR_ceqz_x(long x, long z, long c)
+{
+ if (c)
+ x = x | z;
+
+ return x;
+}
+
+/*
+**test_IOR_nez:
+** czero\.nez a3,a2,a3
+** or a0,a1,a3
+** ret
+*/
+// x = c ? y : y|z
+long test_IOR_nez(long x, long y, long z, long c)
+{
+ if (c)
+ x = y;
+ else
+ x = y | z;
+ return x;
+}
+
+/*
+**test_IOR_nez_x:
+** czero\.nez a2,a1,a2
+** or a0,a0,a2
+** ret
+*/
+// x = c ? x : x|z
+long test_IOR_nez_x(long x, long z, long c)
+{
+ if (c)
+ {}
+ else
+ x = x | z;
+ return x;
+}
+
+/*
+**test_IOR_nez_2:
+** czero\.nez a3,a2,a3
+** or a0,a1,a3
+** ret
+*/
+// x = !c ? y|z : y
+long test_IOR_nez_2(long x, long y, long z, long c)
+{
+ if (!c)
+ x = y | z;
+ else
+ x = y;
+ return x;
+}
+
+/*
+**test_IOR_nez_x_2:
+** czero\.nez a2,a1,a2
+** or a0,a0,a2
+** ret
+*/
+// x = !c ? x|z : x
+long test_IOR_nez_x_2(long x, long z, long c)
+{
+ if (!c)
+ x = x | z;
+
+ return x;
+}
+
+/*
+**test_IOR_eqz_2:
+** czero\.eqz a3,a2,a3
+** or a0,a1,a3
+** ret
+*/
+// x = !c ? y : y|z
+long test_IOR_eqz_2(long x, long y, long z, long c)
+{
+ if (!c)
+ x = y;
+ else
+ x = y | z;
+ return x;
+}
+
+/*
+**test_IOR_eqz_x_2:
+** czero\.eqz a2,a1,a2
+** or a0,a0,a2
+** ret
+*/
+// x = !c ? x : x|z
+long test_IOR_eqz_x_2(long x, long z, long c)
+{
+ if (!c)
+ {}
+ else
+ x = x | z;
+ return x;
+}
+
+/*
+**test_XOR_ceqz:
+** czero\.eqz a3,a2,a3
+** xor a0,a1,a3
+** ret
+*/
+// x = c ? y^z : y
+long test_XOR_ceqz(long x, long y, long z, long c)
+{
+ if (c)
+ x = y ^ z;
+ else
+ x = y;
+ return x;
+}
+
+/*
+**test_XOR_ceqz_x:
+** czero\.eqz a2,a1,a2
+** xor a0,a0,a2
+** ret
+*/
+// x = c ? x^z : x
+long test_XOR_ceqz_x(long x, long z, long c)
+{
+ if (c)
+ x = x ^ z;
+
+ return x;
+}
+
+/*
+**test_XOR_nez:
+** czero\.nez a3,a2,a3
+** xor a0,a1,a3
+** ret
+*/
+// x = c ? y : y^z
+long test_XOR_nez(long x, long y, long z, long c)
+{
+ if (c)
+ x = y;
+ else
+ x = y ^ z;
+ return x;
+}
+
+/*
+**test_XOR_nez_x:
+** czero\.nez a2,a1,a2
+** xor a0,a0,a2
+** ret
+*/
+// x = c ? x : x^z
+long test_XOR_nez_x(long x, long z, long c)
+{
+ if (c)
+ {}
+ else
+ x = x ^ z;
+ return x;
+}
+
+/*
+**test_XOR_nez_2:
+** czero\.nez a3,a2,a3
+** xor a0,a1,a3
+** ret
+*/
+// x = !c ? y^z : y
+long test_XOR_nez_2(long x, long y, long z, long c)
+{
+ if (!c)
+ x = y ^ z;
+ else
+ x = y;
+ return x;
+}
+
+/*
+**test_XOR_nez_x_2:
+** czero\.nez a2,a1,a2
+** xor a0,a0,a2
+** ret
+*/
+// x = !c ? x^z : x
+long test_XOR_nez_x_2(long x, long z, long c)
+{
+ if (!c)
+ x = x ^ z;
+
+ return x;
+}
+
+/*
+**test_XOR_eqz_2:
+** czero\.eqz a3,a2,a3
+** xor a0,a1,a3
+** ret
+*/
+// x = !c ? y : y^z
+long test_XOR_eqz_2(long x, long y, long z, long c)
+{
+ if (!c)
+ x = y;
+ else
+ x = y ^ z;
+ return x;
+}
+
+/*
+**test_XOR_eqz_x_2:
+** czero\.eqz a2,a1,a2
+** xor a0,a0,a2
+** ret
+*/
+// x = !c ? x : x^z
+long test_XOR_eqz_x_2(long x, long z, long c)
+{
+ if (!c)
+ {}
+ else
+ x = x ^ z;
+ return x;
+}