diff options
author | Jeffrey A Law <law@cygnus.com> | 1999-10-23 00:09:29 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1999-10-22 18:09:29 -0600 |
commit | 6ab589e0c9e6e11768d5de1e6c83fdbc4e4c19e2 (patch) | |
tree | 27be171368390d81204ad970ab1069c4306579a5 | |
parent | dfac187e9f168cad1dbc73ebe9757589c6bebb58 (diff) | |
download | gcc-6ab589e0c9e6e11768d5de1e6c83fdbc4e4c19e2.zip gcc-6ab589e0c9e6e11768d5de1e6c83fdbc4e4c19e2.tar.gz gcc-6ab589e0c9e6e11768d5de1e6c83fdbc4e4c19e2.tar.bz2 |
arm.c (logical_binary_operator): New fucntion.
* arm.c (logical_binary_operator): New fucntion.
* arm.h (logical_binary_operator): Declare it.
(PREDICATE_CODES): Handle logical_binary_operator.
* arm.md (anddi3, anddi_zesidi_di, anddi_sesdi_di): Use "#" for
output constraints. Add appropriate splitters.
(anddi_notdi_di, anddi_notzesidi_di, anddi_notsesidi_di): Likewise.
(iordi3, iordi_zesidi_di, iordi_sesidi_di): Likewise.
(xordi3, xordi_zesidi_di, xordi_sesidi_di): Likewise.
From-SVN: r30135
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 17 | ||||
-rw-r--r-- | gcc/config/arm/arm.h | 2 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 191 |
4 files changed, 208 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 128dadc..de9003a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +Fri Oct 22 18:05:43 1999 Jeffrey A Law (law@cygnus.com) + + * arm.c (logical_binary_operator): New fucntion. + * arm.h (logical_binary_operator): Declare it. + (PREDICATE_CODES): Handle logical_binary_operator. + * arm.md (anddi3, anddi_zesidi_di, anddi_sesdi_di): Use "#" for + output constraints. Add appropriate splitters. + (anddi_notdi_di, anddi_notzesidi_di, anddi_notsesidi_di): Likewise. + (iordi3, iordi_zesidi_di, iordi_sesidi_di): Likewise. + (xordi3, xordi_zesidi_di, xordi_sesidi_di): Likewise. + Fri Oct 22 23:46:50 1999 Bernd Schmidt <bernds@cygnus.co.uk> * genoutput.c (struct operand_data): New elt eliminable. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 27fc21d..5b8497e 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2366,6 +2366,23 @@ shiftable_operator (x, mode) } } +/* Return TRUE for binary logical operators. */ + +int +logical_binary_operator (x, mode) + rtx x; + enum machine_mode mode; +{ + if (GET_MODE (x) != mode) + return FALSE; + else + { + enum rtx_code code = GET_CODE (x); + + return (code == IOR || code == XOR || code == AND); + } +} + /* Return TRUE for shift operators. */ int diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index e5c89e7..47df25d 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1960,6 +1960,7 @@ extern struct rtx_def * arm_compare_op1; {"reg_or_int_operand", {SUBREG, REG, CONST_INT}}, \ {"multi_register_push", {PARALLEL}}, \ {"cc_register", {REG}}, \ + {"logical_binary_operator", {AND, IOR, XOR}}, \ {"dominant_cc_register", {REG}}, @@ -2262,6 +2263,7 @@ int soft_df_operand PROTO ((Rtx, Mmode)); int index_operand PROTO ((Rtx, Mmode)); int const_shift_operand PROTO ((Rtx, Mmode)); int shiftable_operator PROTO ((Rtx, Mmode)); +int logical_binary_operator PROTO ((Rtx, Mmode)); int shift_operator PROTO ((Rtx, Mmode)); int equality_operator PROTO ((Rtx, Mmode)); int minmax_operator PROTO ((Rtx, Mmode)); diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index e51f9a5..30673bb 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1090,12 +1090,177 @@ ;; Boolean and,ior,xor insns +;; Split up double word logical operations + +;; Split up simple DImode logical operations. Simply perform the logical +;; operation on the upper and lower halves of the registers. +(define_split + [(set (match_operand:DI 0 "s_register_operand" "") + (match_operator:DI 6 "logical_binary_operator" + [(match_operand:DI 1 "s_register_operand" "") + (match_operand:DI 2 "s_register_operand" "")]))] + "reload_completed" + [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) + (set (match_dup 3) (match_op_dup:SI 6 [(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" "") + (not:DI (match_operand:DI 1 "s_register_operand" "")))] + "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" "")))] + "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" "")]))] + "reload_completed" + [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) + (set (match_dup 3) (match_op_dup:SI 6 + [(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[5] = gen_highpart (SImode, operands[2]); + operands[2] = gen_lowpart (SImode, operands[2]); +}") + +(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" "")))] + "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" "")))] + "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 + [(set (match_operand:DI 0 "s_register_operand" "") + (ior:DI + (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")) + (match_operand:DI 1 "s_register_operand" "")))] + "operands[0] != operands[1] && reload_completed" + [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) (match_dup 4))] + " +{ + operands[4] = gen_highpart (SImode, operands[1]); + 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 + [(set (match_operand:DI 0 "s_register_operand" "") + (xor:DI + (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")) + (match_operand:DI 1 "s_register_operand" "")))] + "operands[0] != operands[1] && reload_completed" + [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2))) + (set (match_dup 3) (match_dup 4))] + " +{ + operands[4] = gen_highpart (SImode, operands[1]); + operands[3] = gen_highpart (SImode, operands[0]); + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); +}") + +;; (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" "")))] + "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,0") (match_operand:DI 2 "s_register_operand" "r,0")))] "" - "and%?\\t%Q0, %Q1, %Q2\;and%?\\t%R0, %R1, %R2" + "#" [(set_attr "length" "8")]) (define_insn "*anddi_zesidi_di" @@ -1104,7 +1269,7 @@ (match_operand:SI 2 "s_register_operand" "r,r")) (match_operand:DI 1 "s_register_operand" "?r,0")))] "" - "and%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, #0" + "#" [(set_attr "length" "8")]) (define_insn "*anddi_sesdi_di" @@ -1113,7 +1278,7 @@ (match_operand:SI 2 "s_register_operand" "r,r")) (match_operand:DI 1 "s_register_operand" "?r,0")))] "" - "and%?\\t%Q0, %Q1, %2\;and%?\\t%R0, %R1, %2, asr #31" + "#" [(set_attr "length" "8")]) (define_expand "andsi3" @@ -1374,7 +1539,7 @@ (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r,0")) (match_operand:DI 1 "s_register_operand" "0,r")))] "" - "bic%?\\t%Q0, %Q1, %Q2\;bic%?\\t%R0, %R1, %R2" + "#" [(set_attr "length" "8")]) (define_insn "*anddi_notzesidi_di" @@ -1385,7 +1550,7 @@ "" "@ bic%?\\t%Q0, %Q1, %2 - bic%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1" + #" [(set_attr "length" "4,8")]) (define_insn "*anddi_notsesidi_di" @@ -1394,7 +1559,7 @@ (match_operand:SI 2 "s_register_operand" "r,r"))) (match_operand:DI 1 "s_register_operand" "?r,0")))] "" - "bic%?\\t%Q0, %Q1, %2\;bic%?\\t%R0, %R1, %2, asr #31" + "#" [(set_attr "length" "8")]) (define_insn "andsi_notsi_si" @@ -1441,7 +1606,7 @@ (ior:DI (match_operand:DI 1 "s_register_operand" "%0") (match_operand:DI 2 "s_register_operand" "r")))] "" - "orr%?\\t%Q0, %Q1, %Q2\;orr%?\\t%R0, %R1, %R2" + "#" [(set_attr "length" "8")]) (define_insn "*iordi_zesidi_di" @@ -1452,7 +1617,7 @@ "" "@ orr%?\\t%Q0, %Q1, %2 - orr%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1" + #" [(set_attr "length" "4,8")]) (define_insn "*iordi_sesidi_di" @@ -1461,7 +1626,7 @@ (match_operand:SI 2 "s_register_operand" "r,r")) (match_operand:DI 1 "s_register_operand" "?r,0")))] "" - "orr%?\\t%Q0, %Q1, %2\;orr%?\\t%R0, %R1, %2, asr #31" + "#" [(set_attr "length" "8")]) (define_expand "iorsi3" @@ -1528,7 +1693,7 @@ (xor:DI (match_operand:DI 1 "s_register_operand" "%0,0") (match_operand:DI 2 "s_register_operand" "r,0")))] "" - "eor%?\\t%Q0, %Q1, %Q2\;eor%?\\t%R0, %R1, %R2" + "#" [(set_attr "length" "8")]) (define_insn "*xordi_zesidi_di" @@ -1539,7 +1704,7 @@ "" "@ eor%?\\t%Q0, %Q1, %2 - eor%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1" + #" [(set_attr "length" "4,8")]) (define_insn "*xordi_sesidi_di" @@ -1548,7 +1713,7 @@ (match_operand:SI 2 "s_register_operand" "r,r")) (match_operand:DI 1 "s_register_operand" "?r,0")))] "" - "eor%?\\t%Q0, %Q1, %2\;eor%?\\t%R0, %R1, %2, asr #31" + "#" [(set_attr "length" "8")]) (define_insn "xorsi3" @@ -2035,7 +2200,7 @@ [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))] "" - "mvn%?\\t%Q0, %Q1\;mvn%?\\t%R0, %R1" + "#" [(set_attr "length" "8")]) (define_insn "one_cmplsi2" |