* config/rs6000/rs6000.md (*isel_reversed_signed_<mode>): New.
(*isel_reversed_unsigned_<mode>): New.
* config/rs6000/rs6000.c (output_isel): Accept GE/GEU/LE/LEU/NE
as valid comparisons and adjust operands and output appropriately.
(rs6000_rtx_costs) <CONST_INT>: Accept NE as a cost-0 outer_code.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165395
138bc75d-0d04-0410-961f-
82ee72b054a4
+2010-10-12 Nathan Froyd <froydnj@codesourcery.com>
+
+ * config/rs6000/predicates.md (scc_rev_comparison_operator): New.
+ * config/rs6000/rs6000.md (*isel_reversed_signed_<mode>): New.
+ (*isel_reversed_unsigned_<mode>): New.
+ * config/rs6000/rs6000.c (output_isel): Accept GE/GEU/LE/LEU/NE
+ as valid comparisons and adjust operands and output appropriately.
+ (rs6000_rtx_costs) <CONST_INT>: Accept NE as a cost-0 outer_code.
+
2010-10-12 Chung-Lin Tang <cltang@codesourcery.com>
* config/arm/arm.h (ARM_EXPAND_ALIGNMENT): Rename from
(and (match_operand 0 "branch_comparison_operator")
(match_code "eq,lt,gt,ltu,gtu,unordered")))
+;; Return 1 if OP is a comparison operation whose inverse would be valid for
+;; an SCC insn.
+(define_predicate "scc_rev_comparison_operator"
+ (and (match_operand 0 "branch_comparison_operator")
+ (match_code "ne,le,ge,leu,geu,ordered")))
+
;; Return 1 if OP is a comparison operation that is valid for a branch
;; insn, which is true if the corresponding bit in the CC register is set.
(define_predicate "branch_positive_comparison_operator"
code = GET_CODE (operands[1]);
- gcc_assert (!(code == GE || code == GEU || code == LE || code == LEU || code == NE));
+ if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
+ {
+ gcc_assert (GET_CODE (operands[2]) == REG
+ && GET_CODE (operands[3]) == REG);
+ PUT_CODE (operands[1], reverse_condition (code));
+ return "isel %0,%3,%2,%j1";
+ }
return "isel %0,%2,%3,%j1";
}
|| (outer_code == COMPARE
&& (satisfies_constraint_I (x)
|| satisfies_constraint_K (x)))
- || (outer_code == EQ
+ || ((outer_code == EQ || outer_code == NE)
&& (satisfies_constraint_I (x)
|| satisfies_constraint_K (x)
|| (mode == SImode
[(set_attr "type" "isel")
(set_attr "length" "4")])
+;; These patterns can be useful for combine; they let combine know that
+;; isel can handle reversed comparisons so long as the operands are
+;; registers.
+
+(define_insn "*isel_reversed_signed_<mode>"
+ [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+ (if_then_else:GPR
+ (match_operator 1 "scc_rev_comparison_operator"
+ [(match_operand:CC 4 "cc_reg_operand" "y")
+ (const_int 0)])
+ (match_operand:GPR 2 "gpc_reg_operand" "b")
+ (match_operand:GPR 3 "gpc_reg_operand" "b")))]
+ "TARGET_ISEL<sel>"
+ "*
+{ return output_isel (operands); }"
+ [(set_attr "type" "isel")
+ (set_attr "length" "4")])
+
+(define_insn "*isel_reversed_unsigned_<mode>"
+ [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+ (if_then_else:GPR
+ (match_operator 1 "scc_rev_comparison_operator"
+ [(match_operand:CCUNS 4 "cc_reg_operand" "y")
+ (const_int 0)])
+ (match_operand:GPR 2 "gpc_reg_operand" "b")
+ (match_operand:GPR 3 "gpc_reg_operand" "b")))]
+ "TARGET_ISEL<sel>"
+ "*
+{ return output_isel (operands); }"
+ [(set_attr "type" "isel")
+ (set_attr "length" "4")])
+
(define_expand "movsfcc"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(if_then_else:SF (match_operand 1 "comparison_operator" "")