From: Richard Earnshaw Date: Mon, 27 Nov 2000 16:29:52 +0000 (+0000) Subject: ChangeLog X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1646cf412a23488ad7a4a21606ded84800240dc8;p=gcc.git ChangeLog From-SVN: r37798 --- diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index ac339dddab5..5fc13defe98 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -4126,6 +4126,13 @@ arm_gen_rotated_half_load (memref) return gen_rtx_ROTATE (SImode, base, GEN_INT (16)); } +/* Select a dominance comparison mode if possible. We support three forms. + COND_OR == 0 => (X && Y) + COND_OR == 1 => ((! X( || Y) + COND_OR == 2 => (X || Y) + If we are unable to support a dominance comparsison we return CC mode. + This will then fail to match for the RTL expressions that generate this + call. */ static enum machine_mode select_dominance_cc_mode (x, y, cond_or) rtx x; @@ -4144,7 +4151,10 @@ select_dominance_cc_mode (x, y, cond_or) != CCmode)) return CCmode; - if (cond_or) + /* The if_then_else variant of this tests the second condition if the + first passes, but is true if the first fails. Reverse the first + condition to get a true "inclusive-or" expression. */ + if (cond_or == 1) cond1 = reverse_condition (cond1); /* If the comparisons are not equal, and one doesn't dominate the other, @@ -4296,6 +4306,29 @@ arm_select_cc_mode (op, x, y) && GET_CODE (y) == CONST_INT) return CC_Zmode; + /* A construct for a conditional compare, if the false arm contains + 0, then both conditions must be true, otherwise either condition + must be true. Not all conditions are possible, so CCmode is + returned if it can't be done. */ + if (GET_CODE (x) == IF_THEN_ELSE + && (XEXP (x, 2) == const0_rtx + || XEXP (x, 2) == const1_rtx) + && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' + && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<') + return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), + INTVAL (XEXP (x, 2))); + + /* Alternate canonicalizations of the above. These are somewhat cleaner. */ + if (GET_CODE (x) == AND + && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' + && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<') + return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 0); + + if (GET_CODE (x) == IOR + && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' + && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<') + return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 2); + /* An operation that sets the condition codes as a side-effect, the V flag is not set correctly, so we can only use comparisons where this doesn't matter. (For LT and GE we can use "mi" and "pl" @@ -4312,18 +4345,6 @@ arm_select_cc_mode (op, x, y) || GET_CODE (x) == ROTATERT || GET_CODE (x) == ZERO_EXTRACT)) return CC_NOOVmode; - /* A construct for a conditional compare, if the false arm contains - 0, then both conditions must be true, otherwise either condition - must be true. Not all conditions are possible, so CCmode is - returned if it can't be done. */ - if (GET_CODE (x) == IF_THEN_ELSE - && (XEXP (x, 2) == const0_rtx - || XEXP (x, 2) == const1_rtx) - && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<' - && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<') - return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), - INTVAL (XEXP (x, 2))); - if (GET_MODE (x) == QImode && (op == EQ || op == NE)) return CC_Zmode; diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index ddb26408690..15c2cd9df6f 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -7130,6 +7130,76 @@ (set_attr "length" "8")] ) +(define_insn "*cmp_and" + [(set (match_operand 6 "dominant_cc_register" "") + (compare + (and:SI + (match_operator 4 "arm_comparison_operator" + [(match_operand:SI 0 "s_register_operand" "r,r,r,r") + (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) + (match_operator:SI 5 "arm_comparison_operator" + [(match_operand:SI 2 "s_register_operand" "r,r,r,r") + (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])) + (const_int 0)))] + "TARGET_ARM" + "* + { + const char * opcodes[4][2] = + { + {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\", + \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"}, + {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", + \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"}, + {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", + \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"}, + {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\", + \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"} + }; + int swap = + comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); + + return opcodes[which_alternative][swap]; + }" + [(set_attr "conds" "set") + (set_attr "predicable" "no") + (set_attr "length" "8")] +) + +(define_insn "*cmp_ior" + [(set (match_operand 6 "dominant_cc_register" "") + (compare + (ior:SI + (match_operator 4 "arm_comparison_operator" + [(match_operand:SI 0 "s_register_operand" "r,r,r,r") + (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) + (match_operator:SI 5 "arm_comparison_operator" + [(match_operand:SI 2 "s_register_operand" "r,r,r,r") + (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])) + (const_int 0)))] + "TARGET_ARM" + "* +{ + const char * opcodes[4][2] = + { + {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\", + \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"}, + {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\", + \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"}, + {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\", + \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"}, + {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\", + \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"} + }; + int swap = + comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); + + return opcodes[which_alternative][swap]; +} +" + [(set_attr "conds" "set") + (set_attr "length" "8")] +) + (define_insn "*negscc" [(set (match_operand:SI 0 "s_register_operand" "=r") (neg:SI (match_operator 3 "arm_comparison_operator" @@ -8595,29 +8665,6 @@ }" ) -(define_split - [(set (match_operand:SI 0 "s_register_operand" "") - (if_then_else:SI (match_operator 1 "arm_comparison_operator" - [(match_operand 2 "" "") (match_operand 3 "" "")]) - (match_operand 4 "" "") - (match_operand 5 "" ""))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_ARM && reload_completed && 0" - [(set (match_dup 6) (match_dup 7)) - (set (match_dup 0) - (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)]) - (match_dup 4) - (match_dup 5)))] - " - { - enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), - operands[2], operands[3]); - - operands[6] = gen_rtx_REG (mode, CC_REGNUM); - operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); - }" -) - (define_split [(set (match_operand:SI 0 "s_register_operand" "") (if_then_else:SI (match_operator 1 "arm_comparison_operator" @@ -8629,17 +8676,24 @@ (clobber (reg:CC CC_REGNUM))] "TARGET_ARM && reload_completed" [(set (match_dup 6) (match_dup 7)) - (set (match_dup 0) - (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)]) - (match_dup 4) - (not:SI (match_dup 5))))] + (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) + (set (match_dup 0) (match_dup 4))) + (cond_exec (match_dup 8) + (set (match_dup 0) (not:SI (match_dup 5))))] " { enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), operands[2], operands[3]); + enum rtx_code rc = GET_CODE (operands[1]); operands[6] = gen_rtx_REG (mode, CC_REGNUM); operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]); + if (mode == CCFPmode || mode == CCFPEmode) + rc = reverse_condition_maybe_unordered (rc); + else + rc = reverse_condition (rc); + + operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); }" )