From 6ab589e0c9e6e11768d5de1e6c83fdbc4e4c19e2 Mon Sep 17 00:00:00 2001 From: Jeffrey A Law Date: Sat, 23 Oct 1999 00:09:29 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 11 +++ gcc/config/arm/arm.c | 17 +++++ gcc/config/arm/arm.h | 2 + gcc/config/arm/arm.md | 191 ++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 208 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 128dadc416a..de9003a73fd 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 * genoutput.c (struct operand_data): New elt eliminable. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 27fc21d939a..5b8497e7de9 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 e5c89e78fbf..47df25d49e5 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 e51f9a5770f..30673bbb4bd 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" -- 2.11.4.GIT