cris.md: Tweak formatting.
authorHans-Peter Nilsson <hp@axis.com>
Thu, 22 Jul 2004 10:10:56 +0000 (10:10 +0000)
committerHans-Peter Nilsson <hp@gcc.gnu.org>
Thu, 22 Jul 2004 10:10:56 +0000 (10:10 +0000)
* config/cris/cris.md: Tweak formatting.
(asrandb, asrandw, lsrandb, lsrandw, moversideqi, movemsideqi)
(mover2side, moverside, movemside, movei, op3, andu): Replace
live define_peephole:s with define_peephole2 near-equivalents.
Delete the rest.
  ("*mov_sidesisf_biap"): Rename from "*mov_sidesi_biap".  Match all
word-size modes.
("*mov_sidesisf", "*mov_sidesisf_biap_mem", "*mov_sidesisf_mem"):
Similar for "*mov_sidesi", "*mov_sidesi_biap_mem" and
"*mov_sidesi_mem" respectively.

From-SVN: r85041

gcc/ChangeLog
gcc/config/cris/cris.md

index cdd99137bc89c94cf8ddf49d5cb6a9bb8fe80636..05e5884e225dda3a4d309d4f4f539891d9384d00 100644 (file)
@@ -1,3 +1,16 @@
+2004-07-22  Hans-Peter Nilsson  <hp@axis.com>
+
+       * config/cris/cris.md: Tweak formatting.
+       (asrandb, asrandw, lsrandb, lsrandw, moversideqi, movemsideqi)
+       (mover2side, moverside, movemside, movei, op3, andu): Replace
+       live define_peephole:s with define_peephole2 near-equivalents.
+       Delete the rest.
+       ("*mov_sidesisf_biap"): Rename from "*mov_sidesi_biap".  Match all
+       word-size modes.
+       ("*mov_sidesisf", "*mov_sidesisf_biap_mem", "*mov_sidesisf_mem"):
+       Similar for "*mov_sidesi", "*mov_sidesi_biap_mem" and
+       "*mov_sidesi_mem" respectively.
+
 2004-07-22  Paolo Bonzini  <bonzini@gnu.org>
 
        * tree-cfg.c (gimplify_val): Move from tree-complex.c.
index dd251e790df78dab5d6c481e33ce5215e3bd1196..4001a2a3b31d55777342991f3ab45ecc311090f7 100644 (file)
 
 ;; SImode
 
-(define_insn "*mov_sidesi_biap"
-  [(set (match_operand:SI 0 "register_operand" "=r,r")
-       (mem:SI (plus:SI
-                (mult:SI (match_operand:SI 1 "register_operand" "r,r")
-                         (match_operand:SI 2 "const_int_operand" "n,n"))
-                (match_operand:SI 3 "register_operand" "r,r"))))
+(define_insn "*mov_sidesisf_biap"
+  [(set (match_operand 0 "register_operand" "=r,r")
+       (mem (plus:SI
+             (mult:SI (match_operand:SI 1 "register_operand" "r,r")
+                      (match_operand:SI 2 "const_int_operand" "n,n"))
+             (match_operand:SI 3 "register_operand" "r,r"))))
    (set (match_operand:SI 4 "register_operand" "=*3,r")
        (plus:SI (mult:SI (match_dup 1)
                          (match_dup 2))
                 (match_dup 3)))]
-  "cris_side_effect_mode_ok (MULT, operands, 4, 3, 1, 2, 0)"
+  "GET_MODE_SIZE (GET_MODE (operands[0])) == UNITS_PER_WORD
+   && cris_side_effect_mode_ok (MULT, operands, 4, 3, 1, 2, 0)"
   "@
    #
    move.%s0 [%4=%3+%1%T2],%0")
 
 ;; SImode
 
-(define_insn "*mov_sidesi"
-  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
-       (mem:SI
+(define_insn "*mov_sidesisf"
+  [(set (match_operand 0 "register_operand" "=r,r,r")
+       (mem
         (plus:SI (match_operand:SI 1 "cris_bdap_operand" "%r,r,r")
                  (match_operand:SI 2 "cris_bdap_operand" "r>Rn,r,>Rn"))))
    (set (match_operand:SI 3 "register_operand" "=*1,r,r")
        (plus:SI (match_dup 1)
                 (match_dup 2)))]
-  "cris_side_effect_mode_ok (PLUS, operands, 3, 1, 2, -1, 0)"
+  "GET_MODE_SIZE (GET_MODE (operands[0])) == UNITS_PER_WORD
+   && cris_side_effect_mode_ok (PLUS, operands, 3, 1, 2, -1, 0)"
   "*
 {
   if (which_alternative == 0
 
 ;; SImode
 
-(define_insn "*mov_sidesi_biap_mem"
-  [(set (mem:SI (plus:SI
-                (mult:SI (match_operand:SI 0 "register_operand" "r,r,r")
-                         (match_operand:SI 1 "const_int_operand" "n,n,n"))
-                (match_operand:SI 2 "register_operand" "r,r,r")))
-       (match_operand:SI 3 "register_operand" "r,r,r"))
+(define_insn "*mov_sidesisf_biap_mem"
+  [(set (mem (plus:SI
+             (mult:SI (match_operand:SI 0 "register_operand" "r,r,r")
+                      (match_operand:SI 1 "const_int_operand" "n,n,n"))
+             (match_operand:SI 2 "register_operand" "r,r,r")))
+       (match_operand 3 "register_operand" "r,r,r"))
    (set (match_operand:SI 4 "register_operand" "=*2,!3,r")
        (plus:SI (mult:SI (match_dup 0)
                          (match_dup 1))
                 (match_dup 2)))]
-  "cris_side_effect_mode_ok (MULT, operands, 4, 2, 0, 1, 3)"
+  "GET_MODE_SIZE (GET_MODE (operands[3])) == UNITS_PER_WORD
+   && cris_side_effect_mode_ok (MULT, operands, 4, 2, 0, 1, 3)"
   "@
    #
    #
 
 ;; SImode
 
-(define_insn "*mov_sidesi_mem"
-  [(set (mem:SI
+(define_insn "*mov_sidesisf_mem"
+  [(set (mem
         (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,r,r,r")
                  (match_operand:SI 1 "cris_bdap_operand" "r>Rn,r>Rn,r,>Rn")))
-       (match_operand:SI 2 "register_operand" "r,r,r,r"))
+       (match_operand 2 "register_operand" "r,r,r,r"))
    (set (match_operand:SI 3 "register_operand" "=*0,!2,r,r")
        (plus:SI (match_dup 0)
                 (match_dup 1)))]
-  "cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
+  "GET_MODE_SIZE (GET_MODE (operands[2])) == UNITS_PER_WORD
+   && cris_side_effect_mode_ok (PLUS, operands, 3, 0, 1, -1, 2)"
   "*
 {
   if (which_alternative == 0
                      (match_operand:SI 2 "const_int_operand" ""))
             (match_operand:SI 3 "register_operand" ""))]))
      (set (match_operand:SI 4 "register_operand" "")
-          (plus:SI (mult:SI (match_dup 1)
-                            (match_dup 2))
+         (plus:SI (mult:SI (match_dup 1)
+                           (match_dup 2))
                    (match_dup 3)))])]
   "REG_P (operands[3]) && REG_P (operands[4])
    && REGNO (operands[3]) == REGNO (operands[4])"
   [(set (match_dup 4) (plus:SI (mult:SI (match_dup 1) (match_dup 2))
-                               (match_dup 3)))
+                              (match_dup 3)))
    (set (match_dup 0) (match_dup 5))]
   "operands[5] = replace_equiv_address (operands[6], operands[3]);")
 
 ;; We have trouble with and:s and shifts.  Maybe something is broken in
 ;; gcc?  Or it could just be that bit-field insn expansion is a bit
 ;; suboptimal when not having extzv insns.
+;; Testcase for the following four peepholes: gcc.dg/cris-peep2-xsrand.c
 
-(define_peephole
-  [(set (match_operand 0 "register_operand" "=r")
+(define_peephole2 ; asrandb (peephole casesi+31)
+  [(set (match_operand:SI 0 "register_operand" "")
        (ashiftrt:SI (match_dup 0)
-                    (match_operand:SI 1 "const_int_operand" "n")))
+                    (match_operand:SI 1 "const_int_operand" "")))
    (set (match_dup 0)
        (and:SI (match_dup 0)
-               (match_operand 2 "const_int_operand" "n")))]
+               (match_operand 2 "const_int_operand" "")))]
   "INTVAL (operands[2]) > 31
    && INTVAL (operands[2]) < 255
-   && INTVAL (operands[1]) > 23"
-
-;; The m flag should be ignored, because this will be a *byte* "and"
-;; operation.
-
-  "*
-{
-  cc_status.flags |= CC_NOT_NEGATIVE;
-
-  return \"lsrq %1,%0\;and.b %2,%0\";
-}")
-
-(define_peephole
-  [(set (match_operand 0 "register_operand" "=r")
+   && INTVAL (operands[1]) > 23
+   /* Check that the and-operation enables us to use logical-shift.  */
+   && (INTVAL (operands[2])
+         & ((HOST_WIDE_INT) -1 << (32 - INTVAL (operands[1])))) == 0"
+  [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
+   (set (match_dup 3) (and:QI (match_dup 3) (match_dup 2)))]
+  ;; FIXME: CC0 is valid except for the M bit.
+  "operands[3] = gen_rtx_REG (QImode, REGNO (operands[0]));")
+
+(define_peephole2 ; asrandw (peephole casesi+32)
+  [(set (match_operand:SI 0 "register_operand" "")
        (ashiftrt:SI (match_dup 0)
-                    (match_operand:SI 1 "const_int_operand" "n")))
+                    (match_operand:SI 1 "const_int_operand" "")))
    (set (match_dup 0)
-       (and:SI (match_dup 0)
-               (match_operand 2 "const_int_operand" "n")))]
+       (and:SI (match_dup 0) (match_operand 2 "const_int_operand" "")))]
   "INTVAL (operands[2]) > 31
    && INTVAL (operands[2]) < 65535
    && INTVAL (operands[2]) != 255
-   && INTVAL (operands[1]) > 15"
-
-;; The m flag should be ignored, because this will be a *word* "and"
-;; operation.
-
-  "*
-{
-  cc_status.flags |= CC_NOT_NEGATIVE;
-
-  return \"lsrq %1,%0\;and.w %2,%0\";
-}")
-
-(define_peephole
-  [(set (match_operand 0 "register_operand" "=r")
+   && INTVAL (operands[1]) > 15
+   /* Check that the and-operation enables us to use logical-shift.  */
+   && (INTVAL (operands[2])
+       & ((HOST_WIDE_INT) -1 << (32 - INTVAL (operands[1])))) == 0"
+  [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
+   (set (match_dup 3) (and:HI (match_dup 3) (match_dup 2)))]
+  ;; FIXME: CC0 is valid except for the M bit.
+  "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));")
+
+(define_peephole2 ; lsrandb (peephole casesi+33)
+  [(set (match_operand:SI 0 "register_operand" "")
        (lshiftrt:SI (match_dup 0)
-                    (match_operand:SI 1 "const_int_operand" "n")))
+                    (match_operand:SI 1 "const_int_operand" "")))
    (set (match_dup 0)
-       (and:SI (match_dup 0)
-               (match_operand 2 "const_int_operand" "n")))]
+       (and:SI (match_dup 0) (match_operand 2 "const_int_operand" "")))]
   "INTVAL (operands[2]) > 31
    && INTVAL (operands[2]) < 255
    && INTVAL (operands[1]) > 23"
+  [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
+   (set (match_dup 3) (and:QI (match_dup 3) (match_dup 2)))]
+  ;; FIXME: CC0 is valid except for the M bit.
+  "operands[3] = gen_rtx_REG (QImode, REGNO (operands[0]));")
 
-;; The m flag should be ignored, because this will be a *byte* "and"
-;; operation.
-
-  "*
-{
-  cc_status.flags |= CC_NOT_NEGATIVE;
-
-  return \"lsrq %1,%0\;and.b %2,%0\";
-}")
-
-(define_peephole
-  [(set (match_operand 0 "register_operand" "=r")
+(define_peephole2 ; lsrandw (peephole casesi+34)
+  [(set (match_operand:SI 0 "register_operand" "")
        (lshiftrt:SI (match_dup 0)
-                    (match_operand:SI 1 "const_int_operand" "n")))
+                    (match_operand:SI 1 "const_int_operand" "")))
    (set (match_dup 0)
-       (and:SI (match_dup 0)
-               (match_operand 2 "const_int_operand" "n")))]
+       (and:SI (match_dup 0) (match_operand 2 "const_int_operand" "")))]
   "INTVAL (operands[2]) > 31 && INTVAL (operands[2]) < 65535
    && INTVAL (operands[2]) != 255
    && INTVAL (operands[1]) > 15"
-
-;; The m flag should be ignored, because this will be a *word* "and"
-;; operation.
-
-  "*
-{
-  cc_status.flags |= CC_NOT_NEGATIVE;
-
-  return \"lsrq %1,%0\;and.w %2,%0\";
-}")
+  [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1)))
+   (set (match_dup 3) (and:HI (match_dup 3) (match_dup 2)))]
+  ;; FIXME: CC0 is valid except for the M bit.
+  "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));")
 \f
 
 ;; Change
 ;;  move [rx=rx+n],ry
 ;; when -128 <= n <= 127.
 ;; This will reduce the size of the assembler code for n = [-128..127],
-;; and speed up accordingly.
-
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (plus:SI (match_operand:SI 1 "register_operand" "0")
-                (match_operand:SI 2 "const_int_operand" "n")))
-   (set (match_operand 3 "register_operand" "=r")
-       (mem (match_dup 0)))]
-  "GET_MODE (operands[3]) != DImode
-    && REGNO (operands[3]) != REGNO (operands[0])
-    && (BASE_P (operands[1]) || BASE_P (operands[2]))
-    && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
-    && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
-    && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)"
-  "move.%s3 [%0=%1%S2],%3")
+;; and speed up accordingly.  Don't match if the previous insn is
+;; (set rx rz) because that combination is matched by another peephole.
+;; No stable test-case.
+
+(define_peephole2 ; moversideqi (peephole casesi+35)
+  [(set (match_operand:SI 0 "register_operand" "")
+       (plus:SI (match_operand:SI 1 "register_operand" "")
+                (match_operand:SI 2 "const_int_operand" "")))
+   (set (match_operand 3 "register_operand" "")
+       (match_operator 4 "cris_mem_op" [(match_dup 0)]))]
+  "GET_MODE_SIZE (GET_MODE (operands[4])) <= UNITS_PER_WORD
+   && REGNO (operands[3]) != REGNO (operands[0])
+   && (BASE_P (operands[1]) || BASE_P (operands[2]))
+   && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
+   && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
+   && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)"
+  [(parallel
+    [(set (match_dup 3) (match_dup 5))
+     (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])]
+  ;; Checking the previous insn is a bit too awkward for the condition.
+{
+  rtx prev = prev_nonnote_insn (curr_insn);
+  if (prev != NULL_RTX)
+    {
+      rtx set = single_set (prev);
+      if (set != NULL_RTX
+         && REG_S_P (SET_DEST (set))
+         && REGNO (SET_DEST (set)) == REGNO (operands[0])
+         && REG_S_P (SET_SRC (set)))
+       FAIL;
+    }
+  operands[5]
+    = replace_equiv_address (operands[4],
+                            gen_rtx_PLUS (SImode,
+                                          operands[1], operands[2]));
+})
 
 ;; Vice versa: move ry,[rx=rx+n]
 
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (plus:SI (match_operand:SI 1 "register_operand" "0")
-                (match_operand:SI 2 "const_int_operand" "n")))
-   (set (mem (match_dup 0))
-       (match_operand 3 "register_operand" "=r"))]
-  "GET_MODE (operands[3]) != DImode
-    && REGNO (operands[3]) != REGNO (operands[0])
-    && (BASE_P (operands[1]) || BASE_P (operands[2]))
-    && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
-    && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
-    && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)"
-  "move.%s3 %3,[%0=%1%S2]"
-  [(set_attr "cc" "none")])
+(define_peephole2 ; movemsideqi (peephole casesi+36)
+  [(set (match_operand:SI 0 "register_operand" "")
+       (plus:SI (match_operand:SI 1 "register_operand" "")
+                (match_operand:SI 2 "const_int_operand" "")))
+   (set (match_operator 3 "cris_mem_op" [(match_dup 0)])
+       (match_operand 4 "register_operand" ""))]
+  "GET_MODE_SIZE (GET_MODE (operands[4])) <= UNITS_PER_WORD
+   && REGNO (operands[4]) != REGNO (operands[0])
+   && (BASE_P (operands[1]) || BASE_P (operands[2]))
+   && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
+   && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
+   && (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)"
+  [(parallel
+    [(set (match_dup 5) (match_dup 4))
+     (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])]
+  "operands[5]
+     = replace_equiv_address (operands[3],
+                             gen_rtx_PLUS (SImode,
+                                           operands[1], operands[2]));")
 \f
 ;; As above, change:
 ;;  add.d n,rx
 ;; out of hand.  They probably will not save the time they take typing in,
 ;; not to mention the bugs that creep in.  FIXME: Get rid of as many of
 ;; the splits and peepholes as possible.
-
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (plus:SI (match_operand:SI 1 "register_operand" "0")
-                (match_operand:SI 2 "const_int_operand" "n")))
-   (set (match_operand 3 "register_operand" "=r")
-       (match_operator 4 "cris_orthogonal_operator"
-                          [(match_dup 3)
-                           (mem (match_dup 0))]))]
+;; No stable test-case.
+
+(define_peephole2 ; mover2side (peephole casesi+37)
+  [(set (match_operand:SI 0 "register_operand" "")
+       (plus:SI (match_operand:SI 1 "register_operand" "")
+                (match_operand:SI 2 "const_int_operand" "")))
+   (set (match_operand 3 "register_operand" "")
+         (match_operator 4 "cris_orthogonal_operator"
+                         [(match_dup 3)
+                          (match_operator
+                           5 "cris_mem_op" [(match_dup 0)])]))]
   "GET_MODE (operands[3]) != DImode
-    && REGNO (operands[0]) != REGNO (operands[3])
-    && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
-    && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
-    && INTVAL (operands[2]) >= -128
-    && INTVAL (operands[2]) <= 127"
-  "%x4.%s3 [%0=%1%S2],%3")
+   && REGNO (operands[0]) != REGNO (operands[3])
+   && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
+   && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
+   && INTVAL (operands[2]) >= -128
+   && INTVAL (operands[2]) <= 127"
+  [(parallel
+    [(set (match_dup 3) (match_op_dup 4 [(match_dup 3) (match_dup 6)]))
+     (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])]
+  "operands[6]
+     = replace_equiv_address (operands[5],
+                             gen_rtx_PLUS (SImode,
+                                           operands[1], operands[2]));")
 
 ;; Sometimes, for some reason the pattern
 ;;  move x,rx
 ;;  add y,rx
 ;;  move [rx],rz
 ;; will occur.  Solve this, and likewise for to-memory.
+;; No stable test-case.
 
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
-       (match_operand:SI 1 "cris_bdap_biap_operand" "r,>Rn,r,>Rn"))
+(define_peephole2 ; moverside (peephole casesi+38)
+  [(set (match_operand:SI 0 "register_operand" "")
+       (match_operand:SI 1 "cris_bdap_biap_operand" ""))
    (set (match_dup 0)
-       (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "0,0,r>Rn,r")
-                (match_operand:SI 3 "cris_bdap_biap_operand" "r>Rn,r,0,0")))
-   (set (match_operand 4 "register_operand" "=r,r,r,r")
-       (mem (match_dup 0)))]
+       (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "")
+                (match_operand:SI 3 "cris_bdap_biap_operand" "")))
+   (set (match_operand 4 "register_operand" "")
+       (match_operator 5 "cris_mem_op" [(match_dup 0)]))]
   "(rtx_equal_p (operands[2], operands[0])
     || rtx_equal_p (operands[3], operands[0]))
    && cris_side_effect_mode_ok (PLUS, operands, 0,
-                                (REG_S_P (operands[1])
-                                 ? 1
-                                 : (rtx_equal_p (operands[2], operands[0])
-                                    ? 3 : 2)),
-                                (! REG_S_P (operands[1])
-                                 ? 1
-                                 : (rtx_equal_p (operands[2], operands[0])
-                                    ? 3 : 2)),
-                                -1, 4)"
-  "@
-   move.%s4 [%0=%1%S3],%4
-   move.%s4 [%0=%3%S1],%4
-   move.%s4 [%0=%1%S2],%4
-   move.%s4 [%0=%2%S1],%4")
+                               (REG_S_P (operands[1])
+                                ? 1
+                                : (rtx_equal_p (operands[2], operands[0])
+                                   ? 3 : 2)),
+                               (! REG_S_P (operands[1])
+                                ? 1
+                                : (rtx_equal_p (operands[2], operands[0])
+                                   ? 3 : 2)),
+                               -1, 4)"
+  [(parallel
+    [(set (match_dup 4) (match_dup 6))
+     (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 8)))])]
+{
+  rtx reg
+    = rtx_equal_p (operands[2], operands[0]) ? operands[3] : operands[2];
+
+  if (REG_S_P (operands[1]))
+    {
+      operands[7] = operands[1];
+      operands[8] = reg;
+    }
+  else
+    {
+      operands[7] = reg;
+      operands[8] = operands[1];
+    }
+  operands[6]
+    = replace_equiv_address (operands[5],
+                            gen_rtx_PLUS (SImode,
+                                          operands[7], operands[8]));
+})
 
 ;; As above but to memory.
+;; FIXME: Split movemside and moverside into variants and prune
+;; the ones that don't trig.
+;; No stable test-case.
 
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
-       (match_operand:SI 1 "cris_bdap_biap_operand" "r,>Rn,r,>Rn"))
+(define_peephole2 ; movemside (peephole casesi+39)
+  [(set (match_operand:SI 0 "register_operand" "")
+       (match_operand:SI 1 "cris_bdap_biap_operand" ""))
    (set (match_dup 0)
-       (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "0,0,r>Rn,r")
-                (match_operand:SI 3 "cris_bdap_biap_operand" "r>Rn,r,0,0")))
-   (set (mem (match_dup 0))
-       (match_operand 4 "register_operand" "=r,r,r,r"))]
+       (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "")
+                (match_operand:SI 3 "cris_bdap_biap_operand" "")))
+   (set (match_operator 4 "cris_mem_op" [(match_dup 0)])
+       (match_operand 5 "register_operand" ""))]
   "(rtx_equal_p (operands[2], operands[0])
     || rtx_equal_p (operands[3], operands[0]))
    && cris_side_effect_mode_ok (PLUS, operands, 0,
-                                (REG_S_P (operands[1])
-                                 ? 1
-                                 : (rtx_equal_p (operands[2], operands[0])
-                                    ? 3 : 2)),
-                                (! REG_S_P (operands[1])
-                                   ? 1
-                                 : (rtx_equal_p (operands[2], operands[0])
-                                    ? 3 : 2)),
-                                -1, 4)"
-  "@
-   move.%s4 %4,[%0=%1%S3]
-   move.%s4 %4,[%0=%3%S1]
-   move.%s4 %4,[%0=%1%S2]
-   move.%s4 %4,[%0=%2%S1]"
-  [(set_attr "cc" "none")])
-
-
-;; As the move from-memory above, but with an operation.
-
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
-       (match_operand:SI 1 "cris_bdap_biap_operand" "r,>Rn,r,>Rn"))
-   (set (match_dup 0)
-       (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "0,0,r>Rn,r")
-                (match_operand:SI 3 "cris_bdap_biap_operand" "r>Rn,r,0,0")))
-   (set (match_operand 4 "register_operand" "=r,r,r,r")
-       (match_operator 5 "cris_orthogonal_operator"
-                       [(match_dup 3)
-                        (mem (match_dup 0))]))]
-  "(rtx_equal_p (operands[2], operands[0])
-    || rtx_equal_p (operands[3], operands[0]))
-   && cris_side_effect_mode_ok (PLUS, operands, 0,
-                                (REG_S_P (operands[1])
-                                 ? 1
-                                 : (rtx_equal_p (operands[2], operands[0])
-                                    ? 3 : 2)),
-                                (! REG_S_P (operands[1])
-                                 ? 1
-                                 : (rtx_equal_p (operands[2], operands[0])
-                                    ? 3 : 2)),
-                                -1, 4)"
-  "@
-   %x5.%s4 [%0=%1%S3],%4
-   %x5.%s4 [%0=%3%S1],%4
-   %x5.%s4 [%0=%1%S2],%4
-   %x5.%s4 [%0=%2%S1],%4")
-
-;; Same, but with swapped operands (and commutative operation).
+                               (REG_S_P (operands[1])
+                                ? 1
+                                : (rtx_equal_p (operands[2], operands[0])
+                                   ? 3 : 2)),
+                               (! REG_S_P (operands[1])
+                                  ? 1
+                                : (rtx_equal_p (operands[2], operands[0])
+                                   ? 3 : 2)),
+                               -1, 5)"
+  [(parallel
+    [(set (match_dup 6) (match_dup 5))
+     (set (match_dup 0) (plus:SI (match_dup 7) (match_dup 8)))])]
+{
+  rtx reg
+    = rtx_equal_p (operands[2], operands[0]) ? operands[3] : operands[2];
 
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
-       (match_operand:SI 1 "cris_bdap_biap_operand" "r,>Rn,r,>Rn"))
-   (set (match_dup 0)
-       (plus:SI (match_operand:SI 2 "cris_bdap_biap_operand" "0,0,r>Rn,r")
-                (match_operand:SI 3 "cris_bdap_biap_operand" "r>Rn,r,0,0")))
-   (set (match_operand 4 "register_operand" "=r,r,r,r")
-       (match_operator 5 "cris_commutative_orth_op"
-                       [(mem (match_dup 0))
-                        (match_dup 3)]))]
-  "(rtx_equal_p (operands[2], operands[0])
-    || rtx_equal_p (operands[3], operands[0]))
-   && cris_side_effect_mode_ok (PLUS, operands, 0,
-                          (REG_S_P (operands[1])
-                           ? 1
-                           : (rtx_equal_p (operands[2], operands[0])
-                              ? 3 : 2)),
-                          (! REG_S_P (operands[1])
-                           ? 1
-                           : (rtx_equal_p (operands[2], operands[0])
-                              ? 3 : 2)),
-                          -1, 4)"
-  "@
-   %x5.%s4 [%0=%1%S3],%4
-   %x5.%s4 [%0=%3%S1],%4
-   %x5.%s4 [%0=%1%S2],%4
-   %x5.%s4 [%0=%2%S1],%4")
+  if (REG_S_P (operands[1]))
+    {
+      operands[7] = operands[1];
+      operands[8] = reg;
+    }
+  else
+    {
+      operands[7] = reg;
+      operands[8] = operands[1];
+    }
+  operands[6]
+    = replace_equiv_address (operands[4],
+                            gen_rtx_PLUS (SImode,
+                                          operands[7], operands[8]));
+})
 
 ;; Another spotted bad code:
 ;;   move rx,ry
 ;;   move [ry],ry
+;; No stable test-case.
 
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (match_operand:SI 1 "register_operand" "r"))
-   (set (match_operand 2 "register_operand" "=r")
-       (mem (match_dup 0)))]
+(define_peephole2 ; movei (peephole casesi+42)
+  [(set (match_operand:SI 0 "register_operand" "")
+       (match_operand:SI 1 "register_operand" ""))
+   (set (match_operand 2 "register_operand" "")
+       (match_operator 3 "cris_mem_op" [(match_dup 0)]))]
   "REGNO (operands[0]) == REGNO (operands[2])
    && GET_MODE_SIZE (GET_MODE (operands[2])) <= UNITS_PER_WORD"
-  "move.%s2 [%1],%0"
-  [(set_attr "slottable" "yes")])
+  [(set (match_dup 2) (match_dup 4))]
+  "operands[4] = replace_equiv_address (operands[3], operands[1]);")
 
-;; And a simple variant with extended operand.
-
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (match_operand:SI 1 "register_operand" "r"))
-   (set (match_operand 2 "register_operand" "=r")
-       (match_operator 3 "cris_extend_operator" [(mem (match_dup 0))]))]
-  "REGNO (operands[0]) == REGNO (operands[2])
-   && GET_MODE_SIZE (GET_MODE (operands[2])) <= UNITS_PER_WORD"
-  "mov%e3.%m3 [%1],%0"
-  [(set_attr "slottable" "yes")])
-\f
-;; Here are all peepholes that have a saved testcase.
-;; Do not add new peepholes without testcases.
-
-;; peep-1:
 ;;   move.d [r10+16],r9
 ;;   and.d r12,r9
 ;; change to
 ;; register pressure.
 ;;  Note that adding the noncommutative variant did not show any matches
 ;; in ipps and cc1, so it's not here.
+;; No stable test-case.
 
-(define_peephole
-  [(set (match_operand 0 "register_operand" "=r,r,r,r")
-       (mem (plus:SI
-             (match_operand:SI 1 "cris_bdap_biap_operand" "r,r>Rn,r,r>Rn")
-             (match_operand:SI 2 "cris_bdap_biap_operand" "r>Rn,r,r>Rn,r"))))
+(define_peephole2 ; op3 (peephole casesi+44)
+  [(set (match_operand 0 "register_operand" "")
+       (match_operator
+        6 "cris_mem_op"
+        [(plus:SI
+          (match_operand:SI 1 "cris_bdap_biap_operand" "")
+          (match_operand:SI 2 "cris_bdap_biap_operand" ""))]))
    (set (match_dup 0)
-       (match_operator 5 "cris_commutative_orth_op"
-                       [(match_operand 3 "register_operand" "0,0,r,r")
-                        (match_operand 4 "register_operand" "r,r,0,0")]))]
+       (match_operator
+        5 "cris_commutative_orth_op"
+        [(match_operand 3 "register_operand" "")
+         (match_operand 4 "register_operand" "")]))]
   "(rtx_equal_p (operands[3], operands[0])
     || rtx_equal_p (operands[4], operands[0]))
    && ! rtx_equal_p (operands[3], operands[4])
    && (REG_S_P (operands[1]) || REG_S_P (operands[2]))
    && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD"
-  "@
-   %x5.%s0 [%1%S2],%4,%0
-   %x5.%s0 [%2%S1],%4,%0
-   %x5.%s0 [%1%S2],%3,%0
-   %x5.%s0 [%2%S1],%3,%0")
+  [(set (match_dup 0) (match_op_dup 5 [(match_dup 7) (match_dup 6)]))]
+  "operands[7]
+     = rtx_equal_p (operands[3], operands[0]) ? operands[4] : operands[3];")
 
-;; peep-2:
 ;;  I cannot tell GCC (2.1, 2.7.2) how to correctly reload an instruction
 ;; that looks like
 ;;   and.b some_byte,const,reg_32
 ;;   move.b some_byte,reg_32
 ;;   and.d const,reg_32
 ;; Fix it here.
+;; Testcases: gcc.dg/cris-peep2-andu1.c gcc.dg/cris-peep2-andu2.c
 
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (match_operand:SI 1 "nonimmediate_operand" "rm"))
-   (set (match_operand:SI 2 "register_operand" "=0")
+(define_peephole2 ; andu (casesi+45)
+  [(set (match_operand:SI 0 "register_operand" "")
+       (match_operand:SI 1 "nonimmediate_operand" ""))
+   (set (match_operand:SI 2 "register_operand" "")
        (and:SI (match_dup 0)
-               (match_operand:SI 3 "const_int_operand" "n")))]
-
+               (match_operand:SI 3 "const_int_operand" "")))]
    ;; Since the size of the memory access could be made different here,
    ;; don't do this for a mem-volatile access.
-
   "REGNO (operands[2]) == REGNO (operands[0])
    && INTVAL (operands[3]) <= 65535 && INTVAL (operands[3]) >= 0
    && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'I')
    && (GET_CODE (operands[1]) != MEM || ! MEM_VOLATILE_P (operands[1]))"
-  "*
-{
-  if (CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'O'))
-    return \"movu.%z3 %1,%0\;andq %b3,%0\";
-
-  cc_status.flags |= CC_NOT_NEGATIVE;
-
-  return \"movu.%z3 %1,%0\;and.%z3 %3,%0\";
-}")
-
-;; peep-3
-
-(define_peephole
-  [(set (match_operand 0 "register_operand" "=r")
-       (match_operand 1 "nonimmediate_operand" "rm"))
-   (set (match_operand:SI 2 "register_operand" "=r")
-       (and:SI (subreg:SI (match_dup 0) 0)
-               (match_operand 3 "const_int_operand" "n")))]
-
-   ;; Since the size of the memory access could be made different here,
-   ;; don't do this for a mem-volatile access.
-
-  "REGNO (operands[0]) == REGNO (operands[2])
-   && INTVAL (operands[3]) > 0
-   && INTVAL (operands[3]) <= 65535
-   && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'I')
-   && (GET_CODE (operands[1]) != MEM || ! MEM_VOLATILE_P (operands[1]))"
-  "*
+  ;; FIXME: CC0 valid except for M (i.e. CC_NOT_NEGATIVE).
+  [(set (match_dup 0) (match_dup 4))
+   (set (match_dup 5) (match_dup 6))]
 {
-  if (CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'O'))
-    return \"movu.%z3 %1,%0\;andq %b3,%0\";
-
-  cc_status.flags |= CC_NOT_NEGATIVE;
-
-  return \"movu.%z3 %1,%0\;and.%z3 %3,%0\";
-}")
+  enum machine_mode zmode = INTVAL (operands[3]) <= 255 ? QImode : HImode;
+  enum machine_mode amode
+    = CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'O') ? SImode : zmode;
+  rtx op1
+    = (REG_S_P (operands[1])
+       ? gen_rtx_REG (zmode, REGNO (operands[1]))
+       : adjust_address (operands[1], zmode, 0));
+  operands[4]
+    = gen_rtx_ZERO_EXTEND (SImode, op1);
+  operands[5] = gen_rtx_REG (amode, REGNO (operands[0]));
+  operands[6]
+    = gen_rtx_AND (amode, gen_rtx_REG (amode, REGNO (operands[0])),
+                  GEN_INT (trunc_int_for_mode (INTVAL (operands[3]),
+                                               amode == SImode
+                                               ? QImode : amode)));
+})
 \f
 ;; Local variables:
 ;; mode:emacs-lisp