aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2003-05-10 13:10:47 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2003-05-10 13:10:47 +0000
commit03f1640c005e605b450b78713dc84c9f7c8860c5 (patch)
tree7aeb8d0b0c940516f2bf53921b2d2aa5e00060d3 /gcc
parent429d6300848372398c42e8c48aac076cef5405f3 (diff)
downloadgcc-03f1640c005e605b450b78713dc84c9f7c8860c5.zip
gcc-03f1640c005e605b450b78713dc84c9f7c8860c5.tar.gz
gcc-03f1640c005e605b450b78713dc84c9f7c8860c5.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/arm/arm-protos.h2
-rw-r--r--gcc/config/arm/arm.c43
-rw-r--r--gcc/config/arm/arm.md59
4 files changed, 94 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bb9ab35..6a4c6d6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2003-05-10 Richard Earnshaw <rearnsha@arm.com>
+
+ * 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 <roger@eyesopen.com>
* 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 1defdf0..7f6610a 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 8b002bd..41b49f8 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 8259bc1..85bd146 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"