@@ -1348,7 +1348,7 @@ (define_predicate "branch_comparison_operator"
(match_test "GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_CC")
(if_then_else (match_test "GET_MODE (XEXP (op, 0)) == CCFPmode")
(if_then_else (match_test "flag_finite_math_only")
- (match_code "lt,le,gt,ge,eq,ne,unordered,ordered")
+ (match_code "lt,le,gt,ge,eq,ne")
(match_code "lt,gt,eq,unordered,unge,unle,ne,ordered"))
(if_then_else (match_test "GET_MODE (XEXP (op, 0)) == CCBCDmode")
(match_code "lt,le,gt,ge,eq,ne,unordered,ordered")
@@ -1397,7 +1397,7 @@ (define_predicate "scc_comparison_operator"
;; an SCC insn.
(define_predicate "scc_rev_comparison_operator"
(and (match_operand 0 "branch_comparison_operator")
- (match_code "ne,le,ge,leu,geu,ordered")))
+ (match_code "ne,le,ge,leu,geu,ordered,unle,unge")))
;; Return 1 if OP is a comparison operator suitable for floating point
;; vector/scalar comparisons that generate a -1/0 mask.
@@ -5509,7 +5509,7 @@ (define_expand "mov<mode>cc"
;; leave out the mode in operand 4 and use one pattern, but reload can
;; change the mode underneath our feet and then gets confused trying
;; to reload the value.
-(define_mode_iterator CCANY [CC CCUNS])
+(define_mode_iterator CCANY [CC CCUNS CCFP CCBCD CCLTEQ CCEQ])
(define_insn "isel_<CCANY:mode>_<GPR:mode>"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
(if_then_else:GPR
@@ -5536,7 +5536,8 @@ (define_insn "*isel_reversed_<CCANY:mode>_<GPR:mode>"
(match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
"TARGET_ISEL"
{
- PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
+ PUT_CODE (operands[1], rs6000_reverse_condition (<CCANY:MODE>mode,
+ GET_CODE (operands[1])));
return "isel %0,%3,%2,%j1";
}
[(set_attr "type" "isel")])
@@ -12764,6 +12765,27 @@ (define_insn "set<mode>_cc"
(const_string "mfcr")))
(set_attr "length" "8")])
+(define_insn_and_split "*set<GPR:mode><CCANY:mode>_rev"
+ [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+ (match_operator:GPR 1 "scc_rev_comparison_operator"
+ [(match_operand:CCANY 2 "cc_reg_operand" "y")
+ (const_int 0)]))]
+ "TARGET_ISEL
+ && !TARGET_POWER10"
+ "#"
+ "&& 1"
+ [(set (match_dup 2)
+ (const_int 1))
+ (set (match_dup 0)
+ (if_then_else:GPR
+ (match_dup 1)
+ (match_dup 2)
+ (const_int 0)))]
+{
+ operands[2] = can_create_pseudo_p ()
+ ? operands[0] : gen_reg_rtx (<GPR:MODE>mode);
+}
+ [(set_attr "type" "isel")])
(define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
(define_code_attr UNS [(eq "CC")
@@ -13243,42 +13265,25 @@ (define_insn_and_split "*nesi3_ext<mode>"
(const_string "16")))])
-(define_code_iterator fp_rev [ordered ne unle unge])
(define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
-(define_code_iterator ccbcd_rev [ordered ne le ge])
-(define_insn_and_split "*<code><mode>_cc"
+(define_insn_and_split "*set<GPR:mode><CCANY:mode>_rev"
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
- (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
- (const_int 0)))]
- "!flag_finite_math_only"
- "#"
- "&& 1"
- [(pc)]
-{
- rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
- rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
- rtx tmp = gen_reg_rtx (<MODE>mode);
- emit_move_insn (tmp, eq);
- emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
- DONE;
-}
- [(set_attr "length" "12")])
-
-(define_insn_and_split "*<code><mode>_cc"
- [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
- (ccbcd_rev:GPR (match_operand:CCBCD 1 "cc_reg_operand" "y")
- (const_int 0)))]
- ""
+ (match_operator:GPR 1 "scc_rev_comparison_operator"
+ [(match_operand:CCANY 2 "cc_reg_operand" "y")
+ (const_int 0)]))]
+ "!TARGET_ISEL
+ && !TARGET_POWER10"
"#"
"&& 1"
[(pc)]
{
- rtx_code revcode = reverse_condition (<CODE>);
- rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
- rtx tmp = gen_reg_rtx (<MODE>mode);
+ rtx_code revcode = rs6000_reverse_condition (<CCANY:MODE>mode,
+ GET_CODE (operands[1]));
+ rtx eq = gen_rtx_fmt_ee (revcode, <GPR:MODE>mode, operands[2], const0_rtx);
+ rtx tmp = gen_reg_rtx (<GPR:MODE>mode);
emit_move_insn (tmp, eq);
- emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
+ emit_insn (gen_xor<GPR:mode>3 (operands[0], tmp, const1_rtx));
DONE;
}
[(set_attr "length" "12")])
new file mode 100644
@@ -0,0 +1,11 @@
+#include <altivec.h>
+
+int test1 (vector unsigned char a, vector unsigned char b)
+{
+ return __builtin_bcdcmpge (a, b);
+}
+
+int test2 (vector unsigned char a, vector unsigned char b)
+{
+ return __builtin_bcdcmple (a, b);
+}
new file mode 100644
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
+/* { dg-final { scan-assembler-times {\mmfcr\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxori\M} 2 } } */
+
+#include "cc_rev.h"
new file mode 100644
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -O2" } */
+/* { dg-final { scan-assembler-times {\misel\M} 2 } } */
+
+#include "cc_rev.h"
new file mode 100644
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+/* { dg-final { scan-assembler-times {\msetbcr\M} 2 } } */
+
+#include "cc_rev.h"