(addsi3): Prefer add without carry instructions and flag input operands as commutativ...
authorRichard Kenner <kenner@gcc.gnu.org>
Thu, 28 Apr 1994 22:08:28 +0000 (18:08 -0400)
committerRichard Kenner <kenner@gcc.gnu.org>
Thu, 28 Apr 1994 22:08:28 +0000 (18:08 -0400)
(addsi3): Prefer add without carry instructions and
flag input operands as commutative for condition register variant.
(subsi3): Define PowerPC patterns using subtract without carry.
(numerous): Flag input operands as commutative for condition register variant.
(mov* matchers): Use mr instruction in ! TARGET_POWERPC case as well and
mr. in condition register variant.

From-SVN: r7166

gcc/config/rs6000/rs6000.md

index 0be372d..69c2a61 100644 (file)
   [(set_attr "type" "compare")])
 \f
 ;; Fixed-point arithmetic insns.
+
+;; Discourage ai/addic because of carry but provide it in an alternative
+;; allowing register zero as source.
 (define_insn "addsi3"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-       (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b")
-                (match_operand:SI 2 "add_operand" "rI,J")))]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,?r,r")
+       (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b,r,b")
+                (match_operand:SI 2 "add_operand" "r,I,I,J")))]
   ""
   "@
-   {a%I2|add%I2c} %0,%1,%2
+   {cax|add} %0,%1,%2
+   {cal %0,%2(%1)|addi %0,%1,%2}
+   {ai|addic} %0,%1,%2
    {cau|addis} %0,%1,%u2")
 
 (define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                            (match_operand:SI 2 "reg_or_short_operand" "rI"))
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
+       (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+                            (match_operand:SI 2 "reg_or_short_operand" "r,I"))
                    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r"))]
+   (clobber (match_scratch:SI 3 "=r,r"))]
   ""
-  "{a%I2.|add%I2c.} %3,%1,%2"
+  "@
+   {cax.|add.} %3,%1,%2
+   {ai.|addic.} %3,%1,%2"
   [(set_attr "type" "compare")])
    
 (define_insn ""
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
-                            (match_operand:SI 2 "reg_or_short_operand" "rI"))
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x")
+       (compare:CC (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
+                            (match_operand:SI 2 "reg_or_short_operand" "r,I"))
                    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
        (plus:SI (match_dup 1) (match_dup 2)))]
   ""
-  "{a%I2.|add%I2c.} %0,%1,%2"
+  "@
+   {cax.|add.} %0,%1,%2
+   {ai.|addic.} %0,%1,%2"
   [(set_attr "type" "compare")])
    
 ;; Split an add that we can't do in one insn into two insns, each of which
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (minus:SI (match_operand:SI 1 "reg_or_short_operand" "rI")
                  (match_operand:SI 2 "gpc_reg_operand" "r")))]
-  ""
+  "! TARGET_POWERPC"
   "{sf%I1|subf%I1c} %0,%2,%1")
 
 (define_insn ""
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+       (minus:SI (match_operand:SI 1 "reg_or_short_operand" "r,I")
+                 (match_operand:SI 2 "gpc_reg_operand" "r,r")))]
+  "TARGET_POWERPC"
+  "@
+   subf %0,%2,%1
+   subfic %0,%2,%1")
+
+(define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
        (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                              (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r"))]
-  ""
+  "! TARGET_POWERPC"
   "{sf.|subfc.} %3,%2,%1"
   [(set_attr "type" "compare")])
 
 (define_insn ""
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+       (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+                             (match_operand:SI 2 "gpc_reg_operand" "r"))
+                   (const_int 0)))
+   (clobber (match_scratch:SI 3 "=r"))]
+  "TARGET_POWERPC"
+  "subf. %3,%2,%1"
+  [(set_attr "type" "compare")])
+
+(define_insn ""
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
        (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
                              (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (minus:SI (match_dup 1) (match_dup 2)))]
-  ""
+  "! TARGET_POWERPC"
   "{sf.|subfc.} %0,%2,%1"
   [(set_attr "type" "compare")])
 
+(define_insn ""
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
+       (compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+                             (match_operand:SI 2 "gpc_reg_operand" "r"))
+                   (const_int 0)))
+   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+       (minus:SI (match_dup 1) (match_dup 2)))]
+  "TARGET_POWERPC"
+  "subf. %0,%2,%1"
+  [(set_attr "type" "compare")])
+
 (define_expand "subsi3"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
        (minus:SI (match_operand:SI 1 "reg_or_short_operand" "")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
                             (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r"))
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
                             (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r"))]
 
 (define_insn ""
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
                             (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 
 (define_insn ""
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+       (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
                             (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
       DONE;
     }
 }")
+
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
       DONE;
     }
 }")
+
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
         (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+       (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
                            (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r"))]
 
 (define_insn ""
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+       (compare:CC (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
                            (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+       (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
                            (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r"))]
 
 (define_insn ""
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+       (compare:CC (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
                            (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+       (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
                (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
   ""
   "nand %0,%1,%2")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+       (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
                            (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
                    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r"))]
 
 (define_insn ""
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+       (compare:CC (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
                            (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
                    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-       (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+       (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
                (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
   ""
   "nor %0,%1,%2")
 
 (define_insn ""
   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
-       (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+       (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
                            (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
                    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r"))]
 
 (define_insn ""
   [(set (match_operand:CC 3 "cc_reg_operand" "=x")
-       (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
+       (compare:CC (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
                            (not:SI (match_operand:SI 2 "gpc_reg_operand" "r")))
                    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
   "TARGET_POWER2 || TARGET_POWERPC"
   "{fcirz|fctiwz} %0,%1"
   [(set_attr "type" "fp")])
+
 (define_expand "fixuns_truncdfsi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
        (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
   DONE;
 }")
 
-
 (define_expand "trunc_call"
   [(parallel [(set (match_operand:SI 0 "" "")
                   (fix:SI (match_operand:DF 1 "" "")))
       DONE;
     }
 }")
+
 (define_insn "mulsidi3_mq"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
        (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
   "mul %0,%1,%2\;mfmq %L0"
   [(set_attr "type" "imul")
    (set_attr "length" "8")])
+
 (define_insn ""
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
        (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
   "mulhw %0,%1,%2\;mullw %L0,%1,%2"
   [(set_attr "type" "imul")
    (set_attr "length" "8")])
+
 (define_expand "smulsi3_highpart"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
        (truncate:SI
       DONE;
     }
 }")
+
 (define_insn "smulsi3_highpart_mq"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (truncate:SI
   "TARGET_POWER"
   "mul %0,%1,%2"
   [(set_attr "type" "imul")])
+
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (truncate:SI
   "TARGET_POWERPC"
   "mulhw %0,%1,%2"
   [(set_attr "type" "imul")])
+
 (define_insn "umulsi3_highpart"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
        (truncate:SI
   "TARGET_POWER && (gpc_reg_operand (operands[0], SImode)
    || gpc_reg_operand (operands[1], SImode))"
   "@
-   {ai|addic} %0,%1,0
+   mr %0,%1
    {l%U1%X1|lwz%U1%X1} %0,%1
    {st%U0%X0|stw%U0%X0} %1,%0
    {cal %0,%1(0)|li %0,%1}
                    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
   ""
-  "{ai.|addic.} %0,%1,0"
+  "mr. %0,%1"
   [(set_attr "type" "compare")])
 \f
 (define_expand "movhi"
   "TARGET_POWER && (gpc_reg_operand (operands[0], HImode)
    || gpc_reg_operand (operands[1], HImode))"
   "@
-   {oril|ori} %0,%1,0
+   mr %0,%1
    lhz%U1%X1 %0,%1
    sth%U0%X0 %1,%0
    {cal %0,%w1(0)|li %0,%w1}
   "! TARGET_POWER && (gpc_reg_operand (operands[0], HImode)
    || gpc_reg_operand (operands[1], HImode))"
   "@
-   ori %0,%1,0
+   mr %0,%1
    lhz%U1%X1 %0,%1
    sth%U0%X0 %1,%0
    li %0,%w1
   "TARGET_POWER && (gpc_reg_operand (operands[0], QImode)
    || gpc_reg_operand (operands[1], QImode))"
   "@
-   {oril|ori} %0,%1,0
+   mr %0,%1
    lbz%U1%X1 %0,%1
    stb%U0%X0 %1,%0
    {cal %0,%1(0)|li %0,%1}
    {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
    mfcr %0
    mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
-   {ai %0,%1,0|mr %0,%1}
+   mr %0,%1
    {l%U1%X1|lwz%U1%X1} %0,%1
    {st%U0%U1|stw%U0%U1} %1,%0"
   [(set_attr "type" "*,*,*,compare,*,*,load,*")
         the first register operand 0 is the same as the second register of
         operand 1, we must copy in the opposite order.  */
       if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
-       return \"{oril %L0,%L1,0|mr %L0,%L1}\;{oril %0,%1,0|mr %0,%1}\";
+       return \"mr %L0,%L1\;mr %0,%1\";
       else
-       return \"{oril %0,%1,0|mr %0,%1}\;{oril %L0,%L1,0|mr %L0,%L1}\";
+       return \"mr %0,%1\;mr %L0,%L1\";
     case 1:
       /* If the low-address word is used in the address, we must load it
         last.  Otherwise, load it first.  Note that we cannot have
         the first register operand 0 is the same as the second register of
         operand 1, we must copy in the opposite order.  */
       if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
-       return \"{oril %L0,%L1,0|mr %L0,%L1}\;{oril %0,%1,0|mr %0,%1}\";
+       return \"mr %L0,%L1\;mr %0,%1\";
       else
-       return \"{oril %0,%1,0|mr %0,%1}\;{oril %L0,%L1,0|mr %L0,%L1}\";
+       return \"mr %0,%1\;mr %L0,%L1\";
     case 1:
       /* If the low-address word is used in the address, we must load it
         last.  Otherwise, load it first.  Note that we cannot have
         is the second, third, or fourth register in the input.  */
       if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
          && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
-       return \"{oril %Z0,%Z1,0|mr %Z0,%Z1}\;{oril %Y0,%Y1,0|mr %Y0,%Y1}\;{oril %L0,%L1,0|mr %L0,%L1}\;{oril %0,%1,0|mr %0,%1}\";
+       return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
       else
-       return \"{oril %0,%1,0|mr %0,%1}\;{oril %L0,%L1,0|mr %L0,%L1}\;{oril %Y0,%Y1,0|mr %Y0,%Y1}\;{oril %Z0,%Z1,0|mr %Z0,%Z1}\";
+       return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
     case 3:
       /* If the address is not used in the output, we can use lsi.  Otherwise,
         fall through to generating four loads.  */
 
 (define_insn ""
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
-       (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r")
+       (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
                       (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))]
   ""
   "@