aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2000-11-27 16:01:29 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2000-11-27 16:01:29 +0000
commitbb6ae7836af19c230d1aae0aa0941790e3b741d8 (patch)
tree4778f5da0ed5d23f76932d836a28b9ac9a22fdb4
parent375de5b62f08e1a0cab0ea09d0113db75b4a8f9e (diff)
downloadgcc-bb6ae7836af19c230d1aae0aa0941790e3b741d8.zip
gcc-bb6ae7836af19c230d1aae0aa0941790e3b741d8.tar.gz
gcc-bb6ae7836af19c230d1aae0aa0941790e3b741d8.tar.bz2
arm.md (arm_adddi3, [...]): Merge with splitters to create define_insn_and_split patterns.
* arm.md (arm_adddi3, adddi_sesidi_di, adddi_zesidi_di, arm_addsi3, arm_subsi3_insn, anddi_zesidi_di, arm_andsi3_insn, anddi_notdi_di, anddi_notzesidi_di, anddi_notsesidi_di, arm_iorsi3, one_cmpldi2): Merge with splitters to create define_insn_and_split patterns. Remove redundant splits. (peephole2 for add:SI of invalid immediate): New. (peephole2 for minus:SI of invalid immediate): New. (peephole2 for ior:SI of invalid immediate): New. (peephole for merge of move and compare): Convert ot peephole2. (addsf3, adddf3): Mark as commutative. * arm.md (thumb peephole for merging stack adjustments): Convert to peephole2. From-SVN: r37796
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/arm/arm.md530
2 files changed, 225 insertions, 321 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0a7aeb6..a1970f7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2000-11-27 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (arm_adddi3, adddi_sesidi_di, adddi_zesidi_di, arm_addsi3,
+ arm_subsi3_insn, anddi_zesidi_di, arm_andsi3_insn, anddi_notdi_di,
+ anddi_notzesidi_di, anddi_notsesidi_di, arm_iorsi3,
+ one_cmpldi2): Merge with splitters to create define_insn_and_split
+ patterns. Remove redundant splits.
+ (peephole2 for add:SI of invalid immediate): New.
+ (peephole2 for minus:SI of invalid immediate): New.
+ (peephole2 for ior:SI of invalid immediate): New.
+ (peephole for merge of move and compare): Convert ot peephole2.
+ (addsf3, adddf3): Mark as commutative.
+
+ * arm.md (thumb peephole for merging stack adjustments): Convert to
+ peephole2.
+
2000-11-27 Bernd Schmidt <bernds@redhat.co.uk>
* haifa-sched.c (print_pattern): Prettier output for COND_EXEC.
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 793f1a4..ddb2640 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -335,97 +335,13 @@
(LAST_ARM_REGNUM 15)
(CC_REGNUM 24)]
)
-
-;;---------------------------------------------------------------------------
+
+;; Addition insns.
;; Note: For DImode insns, there is normally no reason why operands should
;; not be in the same register, what we don't want is for something being
;; written to partially overlap something that is an input.
-;; Split up 64bit addition so that the component insns can schedule
-;; independently.
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (plus:DI (match_operand:DI 1 "s_register_operand" "")
- (match_operand:DI 2 "s_register_operand" "")))
- (clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM && reload_completed
- "
- [(parallel [(set (reg:CC_C CC_REGNUM)
- (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
- (match_dup 1)))
- (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
- (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
- (plus:SI (match_dup 4) (match_dup 5))))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[5] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
-)
-
-;; The first insn created by this splitter must set the low part of
-;; operand0 as well as the carry bit in the CC register. The second
-;; insn must compute the sum of the carry bit, the sign extension of
-;; operand 2 from 32 to 64 bits and the high part of operand 1.
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (plus:DI (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")))
- (clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM && reload_completed
- "
- [(parallel [(set (reg:CC_C CC_REGNUM)
- (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
- (match_dup 1)))
- (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
- (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
- (plus:SI (ashiftrt:SI (match_dup 2)
- (const_int 31))
- (match_dup 4))))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
-)
-
-; The first insn created by this splitter must set the low part of
-; operand0 as well as the carry bit in the CC register. The second
-; insn must compute the sum of the carry bit and the high bits from
-; operand 1
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (plus:DI (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")))
- (clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM && reload_completed
- "
- [(parallel [(set (reg:CC_C CC_REGNUM)
- (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
- (match_dup 1)))
- (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
- (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
- (plus:SI (match_dup 4) (const_int 0))))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
-)
-
-;; Addition insns.
-
(define_expand "adddi3"
[(parallel
[(set (match_operand:DI 0 "s_register_operand" "")
@@ -455,41 +371,85 @@
[(set_attr "length" "4")]
)
-(define_insn "*arm_adddi3"
+(define_insn_and_split "*arm_adddi3"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
(match_operand:DI 2 "s_register_operand" "r, 0")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM
- "
+ "TARGET_ARM"
"#"
+ "TARGET_ARM && reload_completed"
+ [(parallel [(set (reg:CC_C CC_REGNUM)
+ (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
+ (match_dup 1)))
+ (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
+ (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
+ (plus:SI (match_dup 4) (match_dup 5))))]
+ "
+ {
+ operands[3] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[4] = gen_highpart (SImode, operands[1]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[5] = gen_highpart (SImode, operands[2]);
+ operands[2] = gen_lowpart (SImode, operands[2]);
+ }"
[(set_attr "conds" "clob")
(set_attr "length" "8")]
)
-(define_insn "*adddi_sesidi_di"
+(define_insn_and_split "*adddi_sesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(plus:DI (sign_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "r,0")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM
- "
+ "TARGET_ARM"
"#"
+ "TARGET_ARM && reload_completed"
+ [(parallel [(set (reg:CC_C CC_REGNUM)
+ (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
+ (match_dup 1)))
+ (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
+ (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
+ (plus:SI (ashiftrt:SI (match_dup 2)
+ (const_int 31))
+ (match_dup 4))))]
+ "
+ {
+ operands[3] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[4] = gen_highpart (SImode, operands[1]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_lowpart (SImode, operands[2]);
+ }"
[(set_attr "conds" "clob")
(set_attr "length" "8")]
)
-(define_insn "*adddi_zesidi_di"
+(define_insn_and_split "*adddi_zesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(plus:DI (zero_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "r,0")))
- (clobber (reg:CC CC_REGNUM))
- ]
- "TARGET_ARM
- "
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM"
"#"
+ "TARGET_ARM && reload_completed"
+ [(parallel [(set (reg:CC_C CC_REGNUM)
+ (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
+ (match_dup 1)))
+ (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
+ (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
+ (plus:SI (match_dup 4) (const_int 0))))]
+ "
+ {
+ operands[3] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[4] = gen_highpart (SImode, operands[1]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[2] = gen_lowpart (SImode, operands[2]);
+ }"
[(set_attr "conds" "clob")
(set_attr "length" "8")]
)
@@ -510,29 +470,41 @@
"
)
-(define_split
- [(set (match_operand:SI 0 "s_register_operand" "")
+; If there is a scratch available, this will be faster than synthesising the
+; addition.
+(define_peephole2
+ [(match_scratch:SI 3 "r")
+ (set (match_operand:SI 0 "s_register_operand" "")
(plus:SI (match_operand:SI 1 "s_register_operand" "")
(match_operand:SI 2 "const_int_operand" "")))]
"TARGET_ARM &&
- (!(const_ok_for_arm (INTVAL (operands[2]))
- || const_ok_for_arm (-INTVAL (operands[2]))))"
- [(clobber (const_int 0))]
- "
- arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
- operands[1], 0);
- DONE;
-")
+ !(const_ok_for_arm (INTVAL (operands[2]))
+ || const_ok_for_arm (-INTVAL (operands[2])))
+ && const_ok_for_arm (~INTVAL (operands[2]))"
+ [(set (match_dup 3) (match_dup 2))
+ (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
+ ""
+)
-(define_insn "*arm_addsi3"
+(define_insn_and_split "*arm_addsi3"
[(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
- (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
+ (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
(match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
"TARGET_ARM"
"@
add%?\\t%0, %1, %2
sub%?\\t%0, %1, #%n2
#"
+ "TARGET_ARM &&
+ GET_CODE (operands[2]) == CONST_INT
+ && !(const_ok_for_arm (INTVAL (operands[2]))
+ || const_ok_for_arm (-INTVAL (operands[2])))"
+ [(clobber (const_int 0))]
+ "
+ arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
+ operands[1], 0);
+ DONE;
+ "
[(set_attr "length" "4,4,16")
(set_attr "predicable" "yes")]
)
@@ -568,7 +540,7 @@
;; Reloading and elimination of the frame pointer can
;; sometimes cause this optimization to be missed.
-(define_peephole
+(define_peephole2
[(set (match_operand:SI 0 "register_operand" "=l")
(match_operand:SI 1 "const_int_operand" "M"))
(set (match_dup 0)
@@ -577,8 +549,8 @@
&& REGNO (operands[2]) == STACK_POINTER_REGNUM
&& (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
&& (INTVAL (operands[1]) & 3) == 0"
- "add\\t%0, %2, %1"
- [(set_attr "length" "2")]
+ [(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
+ ""
)
(define_insn "*addsi3_compare0"
@@ -764,73 +736,9 @@
(set_attr "length" "4,8")]
)
-; If a constant is too big to fit in a single instruction then the constant
-; will be pre-loaded into a register taking at least two insns, we might be
-; able to merge it with an add, but it depends on the exact value.
-
-(define_split
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (plus:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "const_int_operand" "n")))]
- "TARGET_ARM
- && (!(const_ok_for_arm (INTVAL (operands[2]))
- || const_ok_for_arm (-INTVAL (operands[2]))))"
- [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
- "
- {
- unsigned int val = (unsigned) INTVAL (operands[2]);
- int i;
- unsigned int temp;
-
- /* This code is similar to the approach followed in movsi,
- but it must generate exactly two insns. */
-
- for (i = 30; i >= 0; i -= 2)
- {
- if (val & (3 << i))
- {
- i -= 6;
- if (i < 0)
- i = 0;
-
- if (const_ok_for_arm (temp = (val & ~(255 << i))))
- {
- val &= 255 << i;
- break;
- }
-
- /* We might be able to do this as (larger number - small
- number). */
- temp = ((val >> i) & 255) + 1;
- if (temp > 255 && i < 24)
- {
- i += 2;
- temp = ((val >> i) & 255) + 1;
- }
-
- if (const_ok_for_arm ((temp << i) - val))
- {
- i = temp << i;
- temp = (unsigned) - (int) (i - val);
- val = i;
- break;
- }
-
- FAIL;
- }
- }
-
- /* If we got here, we have found a way of doing it in two
- instructions. the two constants are in val and temp. */
- operands[2] = GEN_INT ((int) val);
- operands[3] = GEN_INT ((int) temp);
- }"
-)
-
(define_insn "addsf3"
[(set (match_operand:SF 0 "s_register_operand" "=f,f")
- (plus:SF (match_operand:SF 1 "s_register_operand" "f,f")
+ (plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
(match_operand:SF 2 "fpu_add_operand" "fG,H")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"@
@@ -842,7 +750,7 @@
(define_insn "adddf3"
[(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (plus:DF (match_operand:DF 1 "s_register_operand" "f,f")
+ (plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
(match_operand:DF 2 "fpu_add_operand" "fG,H")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"@
@@ -1031,7 +939,7 @@
[(set_attr "length" "2")]
)
-(define_insn "*arm_subsi3_insn"
+(define_insn_and_split "*arm_subsi3_insn"
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
(minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
(match_operand:SI 2 "s_register_operand" "r,r")))]
@@ -1039,21 +947,30 @@
"@
rsb%?\\t%0, %2, %1
#"
- [(set_attr "length" "4,16")
- (set_attr "predicable" "yes")]
-)
-
-(define_split
- [(set (match_operand:SI 0 "s_register_operand" "")
- (minus:SI (match_operand:SI 1 "const_int_operand" "")
- (match_operand:SI 2 "s_register_operand" "")))]
- "TARGET_ARM && (!const_ok_for_arm (INTVAL (operands[1])))"
+ "TARGET_ARM
+ && GET_CODE (operands[1]) == CONST_INT
+ && !const_ok_for_arm (INTVAL (operands[1]))"
[(clobber (const_int 0))]
"
arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
operands[2], 0);
DONE;
"
+ [(set_attr "length" "4,16")
+ (set_attr "predicable" "yes")]
+)
+
+(define_peephole2
+ [(match_scratch:SI 3 "r")
+ (set (match_operand:SI 0 "s_register_operand" "")
+ (minus:SI (match_operand:SI 1 "const_int_operand" "")
+ (match_operand:SI 2 "s_register_operand" "")))]
+ "TARGET_ARM
+ && !const_ok_for_arm (INTVAL (operands[1]))
+ && const_ok_for_arm (~INTVAL (operands[1]))"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
+ ""
)
(define_insn "*subsi3_compare0"
@@ -1579,40 +1496,6 @@
(define_split
[(set (match_operand:DI 0 "s_register_operand" "")
- (not:DI (match_operand:DI 1 "s_register_operand" "")))]
- "TARGET_ARM && reload_completed"
- [(set (match_dup 0) (not:SI (match_dup 1)))
- (set (match_dup 2) (not:SI (match_dup 3)))]
- "
- {
- operands[2] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[3] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
-)
-
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (and:DI
- (not:DI (match_operand:DI 1 "s_register_operand" ""))
- (match_operand:DI 2 "s_register_operand" "")))]
- "TARGET_ARM && reload_completed"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
- (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[5] = gen_highpart (SImode, operands[2]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
-)
-
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
(match_operator:DI 6 "logical_binary_operator"
[(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
(match_operand:DI 1 "s_register_operand" "")]))]
@@ -1632,44 +1515,6 @@
}"
)
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (and:DI (not:DI (sign_extend:DI
- (match_operand:SI 2 "s_register_operand" "")))
- (match_operand:DI 1 "s_register_operand" "")))]
- "TARGET_ARM && reload_completed"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
- (set (match_dup 3) (and:SI (not:SI
- (ashiftrt:SI (match_dup 2) (const_int 31)))
- (match_dup 4)))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
-)
-
-;; The zero extend of operand 2 clears the high word of the output
-;; operand.
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (and:DI
- (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
- (match_operand:DI 1 "s_register_operand" "")))]
- "TARGET_ARM && reload_completed"
- [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 3) (const_int 0))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- }"
-)
-
;; The zero extend of operand 2 means we can just copy the high part of
;; operand1 into operand0.
(define_split
@@ -1708,26 +1553,6 @@
}"
)
-;; (not (zero_extend ...)) allows us to just copy the high word from
-;; operand1 to operand0.
-(define_split
- [(set (match_operand:DI 0 "s_register_operand" "")
- (and:DI (not:DI (zero_extend:DI
- (match_operand:SI 2 "s_register_operand" "")))
- (match_operand:DI 1 "s_register_operand" "")))]
- "TARGET_ARM && operands[0] != operands[1] && reload_completed"
- [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
- (set (match_dup 3) (match_dup 4))]
- "
- {
- operands[3] = gen_highpart (SImode, operands[0]);
- operands[0] = gen_lowpart (SImode, operands[0]);
- operands[4] = gen_highpart (SImode, operands[1]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_lowpart (SImode, operands[2]);
- }"
-)
-
(define_insn "anddi3"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
@@ -1737,13 +1562,24 @@
[(set_attr "length" "8")]
)
-(define_insn "*anddi_zesidi_di"
+(define_insn_and_split "*anddi_zesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (zero_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "?r,0")))]
"TARGET_ARM"
"#"
+ "TARGET_ARM && reload_completed"
+ ; The zero extend of operand 2 clears the high word of the output
+ ; operand.
+ [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 3) (const_int 0))]
+ "
+ {
+ operands[3] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ }"
[(set_attr "length" "8")]
)
@@ -1819,7 +1655,7 @@
"
)
-(define_insn "*arm_andsi3_insn"
+(define_insn_and_split "*arm_andsi3_insn"
[(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
(and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
(match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
@@ -1828,6 +1664,16 @@
and%?\\t%0, %1, %2
bic%?\\t%0, %1, #%B2
#"
+ "TARGET_ARM
+ && GET_CODE (operands[2]) == CONST_INT
+ && !(const_ok_for_arm (INTVAL (operands[2]))
+ || const_ok_for_arm (~INTVAL (operands[2])))"
+ [(clobber (const_int 0))]
+ "
+ arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
+ operands[1], 0);
+ DONE;
+ "
[(set_attr "length" "4,4,16")
(set_attr "predicable" "yes")]
)
@@ -1841,21 +1687,6 @@
[(set_attr "length" "2")]
)
-(define_split
- [(set (match_operand:SI 0 "s_register_operand" "")
- (and:SI (match_operand:SI 1 "s_register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))]
- "TARGET_ARM
- && (!(const_ok_for_arm (INTVAL (operands[2]))
- || const_ok_for_arm (~INTVAL (operands[2]))))"
- [(clobber (const_int 0))]
- "
- arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
- operands[1], 0);
- DONE;
- "
-)
-
(define_insn "*andsi3_compare0"
[(set (reg:CC_NOOV CC_REGNUM)
(compare:CC_NOOV
@@ -2073,17 +1904,29 @@
)
; constants for op 2 will never be given to these patterns.
-(define_insn "*anddi_notdi_di"
+(define_insn_and_split "*anddi_notdi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
- (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0"))
- (match_operand:DI 1 "s_register_operand" "0,r")))]
+ (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0"))
+ (match_operand:DI 2 "s_register_operand" "0,r")))]
"TARGET_ARM"
"#"
+ "TARGET_ARM && reload_completed"
+ [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
+ (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
+ "
+ {
+ operands[3] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[4] = gen_highpart (SImode, operands[1]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ operands[5] = gen_highpart (SImode, operands[2]);
+ operands[2] = gen_lowpart (SImode, operands[2]);
+ }"
[(set_attr "length" "8")
(set_attr "predicable" "yes")]
)
-(define_insn "*anddi_notzesidi_di"
+(define_insn_and_split "*anddi_notzesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (not:DI (zero_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r")))
@@ -2092,17 +1935,43 @@
"@
bic%?\\t%Q0, %Q1, %2
#"
+ ; (not (zero_extend ...)) allows us to just copy the high word from
+ ; operand1 to operand0.
+ "TARGET_ARM
+ && reload_completed
+ && operands[0] != operands[1]"
+ [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
+ (set (match_dup 3) (match_dup 4))]
+ "
+ {
+ operands[3] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[4] = gen_highpart (SImode, operands[1]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ }"
[(set_attr "length" "4,8")
(set_attr "predicable" "yes")]
)
-(define_insn "*anddi_notsesidi_di"
+(define_insn_and_split "*anddi_notsesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (not:DI (sign_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r")))
(match_operand:DI 1 "s_register_operand" "?r,0")))]
"TARGET_ARM"
"#"
+ "TARGET_ARM && reload_completed"
+ [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
+ (set (match_dup 3) (and:SI (not:SI
+ (ashiftrt:SI (match_dup 2) (const_int 31)))
+ (match_dup 4)))]
+ "
+ {
+ operands[3] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[4] = gen_highpart (SImode, operands[1]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ }"
[(set_attr "length" "8")
(set_attr "predicable" "yes")]
)
@@ -2218,7 +2087,7 @@
"
)
-(define_insn "*arm_iorsi3"
+(define_insn_and_split "*arm_iorsi3"
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
(ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
(match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
@@ -2226,6 +2095,15 @@
"@
orr%?\\t%0, %1, %2
#"
+ "TARGET_ARM
+ && GET_CODE (operands[2]) == CONST_INT
+ && !const_ok_for_arm (INTVAL (operands[2]))"
+ [(clobber (const_int 0))]
+ "
+ arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
+ operands[1], 0);
+ DONE;
+ "
[(set_attr "length" "4,16")
(set_attr "predicable" "yes")]
)
@@ -2239,19 +2117,19 @@
[(set_attr "length" "2")]
)
-(define_split
- [(set (match_operand:SI 0 "s_register_operand" "")
+(define_peephole2
+ [(match_scratch:SI 3 "r")
+ (set (match_operand:SI 0 "s_register_operand" "")
(ior:SI (match_operand:SI 1 "s_register_operand" "")
(match_operand:SI 2 "const_int_operand" "")))]
- "TARGET_ARM && (!const_ok_for_arm (INTVAL (operands[2])))"
- [(clobber (const_int 0))]
- "
- arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
- operands[1], 0);
- DONE;
- "
+ "TARGET_ARM
+ && !const_ok_for_arm (INTVAL (operands[2]))
+ && const_ok_for_arm (~INTVAL (operands[2]))"
+ [(set (match_dup 3) (match_dup 2))
+ (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
+ ""
)
-
+
(define_insn "*iorsi3_compare0"
[(set (reg:CC_NOOV CC_REGNUM)
(compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
@@ -2986,11 +2864,21 @@
; "cos%?e\\t%0, %1"
;[(set_attr "type" "float_em")])
-(define_insn "one_cmpldi2"
+(define_insn_and_split "one_cmpldi2"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
"TARGET_ARM"
"#"
+ "TARGET_ARM && reload_completed"
+ [(set (match_dup 0) (not:SI (match_dup 1)))
+ (set (match_dup 2) (not:SI (match_dup 3)))]
+ "
+ {
+ operands[2] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[3] = gen_highpart (SImode, operands[1]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ }"
[(set_attr "length" "8")
(set_attr "predicable" "yes")]
)
@@ -8417,15 +8305,15 @@
; This pattern is never tried by combine, so do it as a peephole
-(define_peephole
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (match_operand:SI 1 "s_register_operand" "r"))
+(define_peephole2
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operand:SI 1 "s_register_operand" ""))
(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (const_int 0)))]
- "TARGET_ARM
- "
- "sub%?s\\t%0, %1, #0"
- [(set_attr "conds" "set")]
+ "TARGET_ARM"
+ [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
+ (set (match_dup 0) (match_dup 1))])]
+ ""
)
; Peepholes to spot possible load- and store-multiples, if the ordering is