arm.c (logical_binary_operator): New fucntion.
authorJeffrey A Law <law@cygnus.com>
Sat, 23 Oct 1999 00:09:29 +0000 (00:09 +0000)
committerJeff Law <law@gcc.gnu.org>
Sat, 23 Oct 1999 00:09:29 +0000 (18:09 -0600)
        * 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
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/arm/arm.md

index 128dadc416a3e8c30b56cf84590f33a1cb3bb1f4..de9003a73fd1cf3e5104ef9393f72bc416752711 100644 (file)
@@ -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.
index 27fc21d939a7436839700af05cca187071bf77ed..5b8497e7de95daca6a4d9288528c9566a12846a5 100644 (file)
@@ -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
index e5c89e78fbfca54ad0bf2bf98a154a2f7c83097a..47df25d49e5fb166b66156c4506893cda8c0795c 100644 (file)
@@ -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}},
 
 \f
@@ -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));
index e51f9a5770f4f88c4433533485527f2497df73af..30673bbb4bd0435262c791ab7ae2fd2b8b2128a3 100644 (file)
 \f
 ;; 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"
                 (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"
                 (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"
        (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"
   ""
   "@
    bic%?\\t%Q0, %Q1, %2
-   bic%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
+   #"
 [(set_attr "length" "4,8")])
   
 (define_insn "*anddi_notsesidi_di"
                         (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"
        (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"
   ""
   "@
    orr%?\\t%Q0, %Q1, %2
-   orr%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
+   #"
 [(set_attr "length" "4,8")])
 
 (define_insn "*iordi_sesidi_di"
                 (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"
        (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"
   ""
   "@
    eor%?\\t%Q0, %Q1, %2
-   eor%?\\t%Q0, %Q1, %2\;mov%?\\t%R0, %R1"
+   #"
 [(set_attr "length" "4,8")])
 
 (define_insn "*xordi_sesidi_di"
                 (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"
   [(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"