From 03f1640c005e605b450b78713dc84c9f7c8860c5 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Sat, 10 May 2003 13:10:47 +0000 Subject: [PATCH] arm.md (DOM_CC_X_AND_Y, [...]): New constants. * arm.md (DOM_CC_X_AND_Y, DOM_CC_NX_OR_Y, DOM_CC_X_OR_Y): New constants. (ior_scc_scc, and_scc_scc): New insn_and_split patterns. * arm.c (arm_select_dominance_cc_mode): Renamed from select_dominance_cc_mode, no-longer static. Use DOM_CC... constants. Callers updated. * arm-protos.h (arm_select_dominance_cc_mode): Add prototype. From-SVN: r66662 --- gcc/ChangeLog | 10 +++++++ gcc/config/arm/arm-protos.h | 2 ++ gcc/config/arm/arm.c | 43 ++++++++++++++------------- gcc/config/arm/arm.md | 59 +++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 20 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb9ab35d7d8..6a4c6d6188a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2003-05-10 Richard Earnshaw + + * arm.md (DOM_CC_X_AND_Y, DOM_CC_NX_OR_Y, DOM_CC_X_OR_Y): New + constants. + (ior_scc_scc, and_scc_scc): New insn_and_split patterns. + * arm.c (arm_select_dominance_cc_mode): Renamed from + select_dominance_cc_mode, no-longer static. Use DOM_CC... constants. + Callers updated. + * arm-protos.h (arm_select_dominance_cc_mode): Add prototype. + 2003-05-09 Roger Sayle * config/alpha/alpha.c (alpha_start_function): Declare frame_size diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 1defdf04728..7f6610a8297 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -117,6 +117,8 @@ extern rtx arm_gen_store_multiple PARAMS ((int, int, rtx, int, int, int, extern int arm_gen_movstrqi PARAMS ((rtx *)); extern rtx arm_gen_rotated_half_load PARAMS ((rtx)); extern enum machine_mode arm_select_cc_mode PARAMS ((RTX_CODE, rtx, rtx)); +extern enum machine_mode arm_select_dominance_cc_mode PARAMS ((rtx, rtx, + HOST_WIDE_INT)); extern rtx arm_gen_compare_reg PARAMS ((RTX_CODE, rtx, rtx)); extern rtx arm_gen_return_addr_mask PARAMS ((void)); extern void arm_reload_in_hi PARAMS ((rtx *)); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 8b002bd34ac..41b49f8d871 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -92,7 +92,6 @@ static Hint int_log2 PARAMS ((Hint)); static rtx is_jump_table PARAMS ((rtx)); static Ccstar output_multi_immediate PARAMS ((rtx *, Ccstar, Ccstar, int, Hint)); static void print_multi_reg PARAMS ((FILE *, Ccstar, int, int)); -static Mmode select_dominance_cc_mode PARAMS ((rtx, rtx, Hint)); static Ccstar shift_op PARAMS ((rtx, Hint *)); static struct machine_function * arm_init_machine_status PARAMS ((void)); static int number_of_first_bit_set PARAMS ((int)); @@ -5504,16 +5503,18 @@ 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 comparison we return CC mode. - This will then fail to match for the RTL expressions that generate this - call. */ +/* Select a dominance comparison mode if possible for a test of the general + form (OP (COND_OR (X) (Y)) (const_int 0)). We support three forms. + COND_OR == DOM_CC_X_AND_Y => (X && Y) + COND_OR == DOM_CC_NX_OR_Y => ((! X) || Y) + COND_OR == DOM_CC_X_OR_Y => (X || Y) + In all cases OP will be either EQ or NE, but we don't need to know which + here. If we are unable to support a dominance comparison 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) +enum machine_mode +arm_select_dominance_cc_mode (x, y, cond_or) rtx x; rtx y; HOST_WIDE_INT cond_or; @@ -5533,7 +5534,7 @@ select_dominance_cc_mode (x, y, 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) + if (cond_or == DOM_CC_NX_OR_Y) cond1 = reverse_condition (cond1); /* If the comparisons are not equal, and one doesn't dominate the other, @@ -5553,7 +5554,7 @@ select_dominance_cc_mode (x, y, cond_or) switch (cond1) { case EQ: - if (cond2 == EQ || !cond_or) + if (cond2 == EQ || cond_or == DOM_CC_X_AND_Y) return CC_DEQmode; switch (cond2) @@ -5568,7 +5569,7 @@ select_dominance_cc_mode (x, y, cond_or) break; case LT: - if (cond2 == LT || !cond_or) + if (cond2 == LT || cond_or == DOM_CC_X_AND_Y) return CC_DLTmode; if (cond2 == LE) return CC_DLEmode; @@ -5577,7 +5578,7 @@ select_dominance_cc_mode (x, y, cond_or) break; case GT: - if (cond2 == GT || !cond_or) + if (cond2 == GT || cond_or == DOM_CC_X_AND_Y) return CC_DGTmode; if (cond2 == GE) return CC_DGEmode; @@ -5586,7 +5587,7 @@ select_dominance_cc_mode (x, y, cond_or) break; case LTU: - if (cond2 == LTU || !cond_or) + if (cond2 == LTU || cond_or == DOM_CC_X_AND_Y) return CC_DLTUmode; if (cond2 == LEU) return CC_DLEUmode; @@ -5595,7 +5596,7 @@ select_dominance_cc_mode (x, y, cond_or) break; case GTU: - if (cond2 == GTU || !cond_or) + if (cond2 == GTU || cond_or == DOM_CC_X_AND_Y) return CC_DGTUmode; if (cond2 == GEU) return CC_DGEUmode; @@ -5696,19 +5697,21 @@ arm_select_cc_mode (op, x, y) || 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))); + return arm_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); + return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), + DOM_CC_X_AND_Y); 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); + return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), + DOM_CC_X_OR_Y); /* 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 diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 8259bc18cbb..85bd1462dd0 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -38,6 +38,13 @@ (LAST_ARM_REGNUM 15) ] ) +;; 3rd operand to select_dominance_cc_mode +(define_constants + [(DOM_CC_X_AND_Y 0) + (DOM_CC_NX_OR_Y 1) + (DOM_CC_X_OR_Y 2) + ] +) ;; UNSPEC Usage: ;; Note: sin and cos are no-longer used. @@ -6745,6 +6752,58 @@ (set_attr "length" "8")] ) +(define_insn_and_split "*ior_scc_scc" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (ior:SI (match_operator:SI 3 "arm_comparison_operator" + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "arm_add_operand" "rIL")]) + (match_operator:SI 6 "arm_comparison_operator" + [(match_operand:SI 4 "s_register_operand" "r") + (match_operand:SI 5 "arm_add_operand" "rIL")]))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_ARM + && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y) + != CCmode)" + "#" + "TARGET_ARM && reload_completed" + [(set (match_dup 7) + (compare + (ior:SI + (match_op_dup 3 [(match_dup 1) (match_dup 2)]) + (match_op_dup 6 [(match_dup 4) (match_dup 5)])) + (const_int 0))) + (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] + "operands[7] + = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], + DOM_CC_X_OR_Y), + CC_REGNUM);") + +(define_insn_and_split "*and_scc_scc" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (and:SI (match_operator:SI 3 "arm_comparison_operator" + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "arm_add_operand" "rIL")]) + (match_operator:SI 6 "arm_comparison_operator" + [(match_operand:SI 4 "s_register_operand" "r") + (match_operand:SI 5 "arm_add_operand" "rIL")]))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_ARM + && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) + != CCmode)" + "#" + "TARGET_ARM && reload_completed" + [(set (match_dup 7) + (compare + (and:SI + (match_op_dup 3 [(match_dup 1) (match_dup 2)]) + (match_op_dup 6 [(match_dup 4) (match_dup 5)])) + (const_int 0))) + (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] + "operands[7] + = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], + DOM_CC_X_AND_Y), + CC_REGNUM);") + (define_insn "*negscc" [(set (match_operand:SI 0 "s_register_operand" "=r") (neg:SI (match_operator 3 "arm_comparison_operator" -- 2.30.2