Commit bb6ae783 by Richard Earnshaw Committed by Richard Earnshaw

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
parent 375de5b6
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> 2000-11-27 Bernd Schmidt <bernds@redhat.co.uk>
* haifa-sched.c (print_pattern): Prettier output for COND_EXEC. * haifa-sched.c (print_pattern): Prettier output for COND_EXEC.
......
...@@ -335,97 +335,13 @@ ...@@ -335,97 +335,13 @@
(LAST_ARM_REGNUM 15) (LAST_ARM_REGNUM 15)
(CC_REGNUM 24)] (CC_REGNUM 24)]
) )
;;--------------------------------------------------------------------------- ;; Addition insns.
;; Note: For DImode insns, there is normally no reason why operands should ;; 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 ;; not be in the same register, what we don't want is for something being
;; written to partially overlap something that is an input. ;; 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" (define_expand "adddi3"
[(parallel [(parallel
[(set (match_operand:DI 0 "s_register_operand" "") [(set (match_operand:DI 0 "s_register_operand" "")
...@@ -455,41 +371,85 @@ ...@@ -455,41 +371,85 @@
[(set_attr "length" "4")] [(set_attr "length" "4")]
) )
(define_insn "*arm_adddi3" (define_insn_and_split "*arm_adddi3"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0") (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
(match_operand:DI 2 "s_register_operand" "r, 0"))) (match_operand:DI 2 "s_register_operand" "r, 0")))
(clobber (reg:CC CC_REGNUM))] (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 "conds" "clob")
(set_attr "length" "8")] (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") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(plus:DI (sign_extend:DI (plus:DI (sign_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r")) (match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "r,0"))) (match_operand:DI 1 "s_register_operand" "r,0")))
(clobber (reg:CC CC_REGNUM))] (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 "conds" "clob")
(set_attr "length" "8")] (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") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(plus:DI (zero_extend:DI (plus:DI (zero_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r")) (match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "r,0"))) (match_operand:DI 1 "s_register_operand" "r,0")))
(clobber (reg:CC CC_REGNUM)) (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) (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 "conds" "clob")
(set_attr "length" "8")] (set_attr "length" "8")]
) )
...@@ -510,29 +470,41 @@ ...@@ -510,29 +470,41 @@
" "
) )
(define_split ; If there is a scratch available, this will be faster than synthesising the
[(set (match_operand:SI 0 "s_register_operand" "") ; 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" "") (plus:SI (match_operand:SI 1 "s_register_operand" "")
(match_operand:SI 2 "const_int_operand" "")))] (match_operand:SI 2 "const_int_operand" "")))]
"TARGET_ARM && "TARGET_ARM &&
(!(const_ok_for_arm (INTVAL (operands[2])) !(const_ok_for_arm (INTVAL (operands[2]))
|| const_ok_for_arm (-INTVAL (operands[2]))))" || const_ok_for_arm (-INTVAL (operands[2])))
[(clobber (const_int 0))] && const_ok_for_arm (~INTVAL (operands[2]))"
" [(set (match_dup 3) (match_dup 2))
arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0], (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
operands[1], 0); ""
DONE; )
")
(define_insn "*arm_addsi3" (define_insn_and_split "*arm_addsi3"
[(set (match_operand:SI 0 "s_register_operand" "=r,r,r") [(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")))] (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))]
"TARGET_ARM" "TARGET_ARM"
"@ "@
add%?\\t%0, %1, %2 add%?\\t%0, %1, %2
sub%?\\t%0, %1, #%n2 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 "length" "4,4,16")
(set_attr "predicable" "yes")] (set_attr "predicable" "yes")]
) )
...@@ -568,7 +540,7 @@ ...@@ -568,7 +540,7 @@
;; Reloading and elimination of the frame pointer can ;; Reloading and elimination of the frame pointer can
;; sometimes cause this optimization to be missed. ;; sometimes cause this optimization to be missed.
(define_peephole (define_peephole2
[(set (match_operand:SI 0 "register_operand" "=l") [(set (match_operand:SI 0 "register_operand" "=l")
(match_operand:SI 1 "const_int_operand" "M")) (match_operand:SI 1 "const_int_operand" "M"))
(set (match_dup 0) (set (match_dup 0)
...@@ -577,8 +549,8 @@ ...@@ -577,8 +549,8 @@
&& REGNO (operands[2]) == STACK_POINTER_REGNUM && REGNO (operands[2]) == STACK_POINTER_REGNUM
&& (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
&& (INTVAL (operands[1]) & 3) == 0" && (INTVAL (operands[1]) & 3) == 0"
"add\\t%0, %2, %1" [(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
[(set_attr "length" "2")] ""
) )
(define_insn "*addsi3_compare0" (define_insn "*addsi3_compare0"
...@@ -764,73 +736,9 @@ ...@@ -764,73 +736,9 @@
(set_attr "length" "4,8")] (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" (define_insn "addsf3"
[(set (match_operand:SF 0 "s_register_operand" "=f,f") [(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")))] (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
"TARGET_ARM && TARGET_HARD_FLOAT" "TARGET_ARM && TARGET_HARD_FLOAT"
"@ "@
...@@ -842,7 +750,7 @@ ...@@ -842,7 +750,7 @@
(define_insn "adddf3" (define_insn "adddf3"
[(set (match_operand:DF 0 "s_register_operand" "=f,f") [(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")))] (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
"TARGET_ARM && TARGET_HARD_FLOAT" "TARGET_ARM && TARGET_HARD_FLOAT"
"@ "@
...@@ -1031,7 +939,7 @@ ...@@ -1031,7 +939,7 @@
[(set_attr "length" "2")] [(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") [(set (match_operand:SI 0 "s_register_operand" "=r,r")
(minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n") (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n")
(match_operand:SI 2 "s_register_operand" "r,r")))] (match_operand:SI 2 "s_register_operand" "r,r")))]
...@@ -1039,21 +947,30 @@ ...@@ -1039,21 +947,30 @@
"@ "@
rsb%?\\t%0, %2, %1 rsb%?\\t%0, %2, %1
#" #"
[(set_attr "length" "4,16") "TARGET_ARM
(set_attr "predicable" "yes")] && GET_CODE (operands[1]) == CONST_INT
) && !const_ok_for_arm (INTVAL (operands[1]))"
(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])))"
[(clobber (const_int 0))] [(clobber (const_int 0))]
" "
arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0], arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
operands[2], 0); operands[2], 0);
DONE; 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" (define_insn "*subsi3_compare0"
...@@ -1579,40 +1496,6 @@ ...@@ -1579,40 +1496,6 @@
(define_split (define_split
[(set (match_operand:DI 0 "s_register_operand" "") [(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" (match_operator:DI 6 "logical_binary_operator"
[(sign_extend:DI (match_operand:SI 2 "s_register_operand" "")) [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
(match_operand:DI 1 "s_register_operand" "")]))] (match_operand:DI 1 "s_register_operand" "")]))]
...@@ -1632,44 +1515,6 @@ ...@@ -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 ;; The zero extend of operand 2 means we can just copy the high part of
;; operand1 into operand0. ;; operand1 into operand0.
(define_split (define_split
...@@ -1708,26 +1553,6 @@ ...@@ -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" (define_insn "anddi3"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (match_operand:DI 1 "s_register_operand" "%0,r") (and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
...@@ -1737,13 +1562,24 @@ ...@@ -1737,13 +1562,24 @@
[(set_attr "length" "8")] [(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") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (zero_extend:DI (and:DI (zero_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r")) (match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "?r,0")))] (match_operand:DI 1 "s_register_operand" "?r,0")))]
"TARGET_ARM" "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")] [(set_attr "length" "8")]
) )
...@@ -1819,7 +1655,7 @@ ...@@ -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") [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
(and:SI (match_operand:SI 1 "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")))] (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
...@@ -1828,6 +1664,16 @@ ...@@ -1828,6 +1664,16 @@
and%?\\t%0, %1, %2 and%?\\t%0, %1, %2
bic%?\\t%0, %1, #%B2 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 "length" "4,4,16")
(set_attr "predicable" "yes")] (set_attr "predicable" "yes")]
) )
...@@ -1841,21 +1687,6 @@ ...@@ -1841,21 +1687,6 @@
[(set_attr "length" "2")] [(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" (define_insn "*andsi3_compare0"
[(set (reg:CC_NOOV CC_REGNUM) [(set (reg:CC_NOOV CC_REGNUM)
(compare:CC_NOOV (compare:CC_NOOV
...@@ -2073,17 +1904,29 @@ ...@@ -2073,17 +1904,29 @@
) )
; constants for op 2 will never be given to these patterns. ; 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") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0")) (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0"))
(match_operand:DI 1 "s_register_operand" "0,r")))] (match_operand:DI 2 "s_register_operand" "0,r")))]
"TARGET_ARM" "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 "length" "8")
(set_attr "predicable" "yes")] (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") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (not:DI (zero_extend:DI (and:DI (not:DI (zero_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r"))) (match_operand:SI 2 "s_register_operand" "r,r")))
...@@ -2092,17 +1935,43 @@ ...@@ -2092,17 +1935,43 @@
"@ "@
bic%?\\t%Q0, %Q1, %2 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 "length" "4,8")
(set_attr "predicable" "yes")] (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") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (not:DI (sign_extend:DI (and:DI (not:DI (sign_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r"))) (match_operand:SI 2 "s_register_operand" "r,r")))
(match_operand:DI 1 "s_register_operand" "?r,0")))] (match_operand:DI 1 "s_register_operand" "?r,0")))]
"TARGET_ARM" "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 "length" "8")
(set_attr "predicable" "yes")] (set_attr "predicable" "yes")]
) )
...@@ -2218,7 +2087,7 @@ ...@@ -2218,7 +2087,7 @@
" "
) )
(define_insn "*arm_iorsi3" (define_insn_and_split "*arm_iorsi3"
[(set (match_operand:SI 0 "s_register_operand" "=r,r") [(set (match_operand:SI 0 "s_register_operand" "=r,r")
(ior:SI (match_operand:SI 1 "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")))] (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
...@@ -2226,6 +2095,15 @@ ...@@ -2226,6 +2095,15 @@
"@ "@
orr%?\\t%0, %1, %2 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 "length" "4,16")
(set_attr "predicable" "yes")] (set_attr "predicable" "yes")]
) )
...@@ -2239,19 +2117,19 @@ ...@@ -2239,19 +2117,19 @@
[(set_attr "length" "2")] [(set_attr "length" "2")]
) )
(define_split (define_peephole2
[(set (match_operand:SI 0 "s_register_operand" "") [(match_scratch:SI 3 "r")
(set (match_operand:SI 0 "s_register_operand" "")
(ior:SI (match_operand:SI 1 "s_register_operand" "") (ior:SI (match_operand:SI 1 "s_register_operand" "")
(match_operand:SI 2 "const_int_operand" "")))] (match_operand:SI 2 "const_int_operand" "")))]
"TARGET_ARM && (!const_ok_for_arm (INTVAL (operands[2])))" "TARGET_ARM
[(clobber (const_int 0))] && !const_ok_for_arm (INTVAL (operands[2]))
" && const_ok_for_arm (~INTVAL (operands[2]))"
arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0], [(set (match_dup 3) (match_dup 2))
operands[1], 0); (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
DONE; ""
"
) )
(define_insn "*iorsi3_compare0" (define_insn "*iorsi3_compare0"
[(set (reg:CC_NOOV CC_REGNUM) [(set (reg:CC_NOOV CC_REGNUM)
(compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r") (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
...@@ -2986,11 +2864,21 @@ ...@@ -2986,11 +2864,21 @@
; "cos%?e\\t%0, %1" ; "cos%?e\\t%0, %1"
;[(set_attr "type" "float_em")]) ;[(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") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))] (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))]
"TARGET_ARM" "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 "length" "8")
(set_attr "predicable" "yes")] (set_attr "predicable" "yes")]
) )
...@@ -8417,15 +8305,15 @@ ...@@ -8417,15 +8305,15 @@
; This pattern is never tried by combine, so do it as a peephole ; This pattern is never tried by combine, so do it as a peephole
(define_peephole (define_peephole2
[(set (match_operand:SI 0 "s_register_operand" "=r") [(set (match_operand:SI 0 "s_register_operand" "")
(match_operand:SI 1 "s_register_operand" "r")) (match_operand:SI 1 "s_register_operand" ""))
(set (reg:CC CC_REGNUM) (set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (const_int 0)))] (compare:CC (match_dup 1) (const_int 0)))]
"TARGET_ARM "TARGET_ARM"
" [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
"sub%?s\\t%0, %1, #0" (set (match_dup 0) (match_dup 1))])]
[(set_attr "conds" "set")] ""
) )
; Peepholes to spot possible load- and store-multiples, if the ordering is ; Peepholes to spot possible load- and store-multiples, if the ordering is
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment