rx.md (movsicc): Allow register to register transfers.
authorKazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
Thu, 11 Aug 2011 12:34:30 +0000 (12:34 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Thu, 11 Aug 2011 12:34:30 +0000 (12:34 +0000)
* config/rx/rx.md (movsicc): Allow register to register
transfers.
(*movsicc): Likewise.
(*stcc): Restrict this pattern to EQ and NE compares.
(*stcc_reg): New pattern.  Works for any comparison but only for
register transfers.

From-SVN: r177665

gcc/ChangeLog
gcc/config/rx/rx.md

index 6bce3427b987efd12f9030d7c825c7c6c9e96cd2..678b880c24a8116ee4483a441049446c534772f1 100644 (file)
@@ -1,3 +1,12 @@
+2011-08-11   Kazuhiro Inaoka  <kazuhiro.inaoka.ud@renesas.com>
+
+       * config/rx/rx.md (movsicc): Allow register to register
+       transfers.
+       (*movsicc): Likewise.
+       (*stcc): Restrict this pattern to EQ and NE compares.
+       (*stcc_reg): New pattern.  Works for any comparison but only for
+       register transfers.
+
 2011-08-11   Diego Novillo  <dnovillo@google.com>
 
        * tree-streamer-out.c (lto_output_ts_decl_with_vis_tree_pointers):
        (process_decls): Use process_bypass.  Update after field name changes.
 
 2011-08-11  Georg-Johann Lay  <avr@gjlay.de>
-       
+
        PR target/49687
        * config/avr/avr.md (smulqi3_highpart): New insn.
        (umulqi3_highpart): New insn.
index 544880a74adab42680cd09a4243450580abfab67..f7b8e16eb9155a1d2b44f6e50b95abca8e3ea445 100644 (file)
      (clobber (reg:CC CC_REG))])]
   ""
 {
-  /* ??? Support other conditions via cstore into a temporary?  */
-  if (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE)
-    FAIL;
-  /* One operand must be a constant.  */
-  if (!CONSTANT_P (operands[2]) && !CONSTANT_P (operands[3]))
+  /* One operand must be a constant or a register, the other must be a register.  */
+  if (   ! CONSTANT_P (operands[2])
+      && ! CONSTANT_P (operands[3])
+      && ! (REG_P (operands[2]) && REG_P (operands[3])))
     FAIL;
 })
 
 (define_insn_and_split "*movsicc"
-  [(set (match_operand:SI     0 "register_operand" "=r,r")
+  [(set (match_operand:SI     0 "register_operand" "=r,r,r")
        (if_then_else:SI
-         (match_operator 5 "rx_z_comparison_operator"
-          [(match_operand:SI 3 "register_operand"  "r,r")
-           (match_operand:SI 4 "rx_source_operand" "riQ,riQ")])
-         (match_operand:SI   1 "nonmemory_operand" "i,ri")
-         (match_operand:SI   2 "nonmemory_operand" "ri,i")))
+         (match_operator     5 "comparison_operator"
+          [(match_operand:SI 3 "register_operand"  "r,r,r")
+           (match_operand:SI 4 "rx_source_operand" "riQ,riQ,riQ")])
+         (match_operand:SI   1 "nonmemory_operand" "i,ri,r")
+         (match_operand:SI   2 "nonmemory_operand" "ri,i,r")))
    (clobber (reg:CC CC_REG))]
-  "CONSTANT_P (operands[1]) || CONSTANT_P (operands[2])"
+  "(CONSTANT_P (operands[1]) || CONSTANT_P (operands[2]))
+    || (REG_P (operands[1]) && REG_P (operands[2]))"
   "#"
   "&& reload_completed"
   [(const_int 0)]
   op1 = operands[1];
   op2 = operands[2];
 
-  /* If OP2 is the constant, reverse the sense of the move.  */
-  if (!CONSTANT_P (operands[1]))
+  /* If OP2 is the constant, reverse the sense of the move.
+     Likewise if both operands are registers but OP1 == OP0.  */
+  if ((! CONSTANT_P (operands[1]) && CONSTANT_P (operands[2]))
+      || (REG_P (operands[1]) && REG_P (operands[2])
+          && rtx_equal_p (op0, op1)))
     {
       x = op1, op1 = op2, op2 = x;
       cmp_code = reverse_condition (cmp_code);
   /* If OP2 does not match the output, copy it into place.  We have allowed
      these alternatives so that the destination can legitimately be one of
      the comparison operands without increasing register pressure.  */
-  if (!rtx_equal_p (op0, op2))
+  if (! rtx_equal_p (op0, op2))
     emit_move_insn (op0, op2);
 
   x = gen_rtx_fmt_ee (cmp_code, VOIDmode, flags, const0_rtx);
            [(reg CC_REG) (const_int 0)])
          (match_operand:SI 1 "immediate_operand" "Sint08,Sint16,Sint24,i")
          (match_dup 0)))]
-  "reload_completed"
-{
-  if (GET_CODE (operands[2]) == EQ)
-    return "stz\t%1, %0";
-  else
-    return "stnz\t%1, %0";
-}
+  "reload_completed
+   && ((GET_CODE (operands[2]) == EQ) || (GET_CODE (operands[2]) == NE))"
+  {
+    if (GET_CODE (operands[2]) == EQ)
+      return "stz\t%1, %0";
+    else
+     return "stnz\t%1, %0";
+  }
   [(set_attr "length" "4,5,6,7")]
 )
 
+(define_insn "*stcc_reg"
+  [(set (match_operand:SI 0 "register_operand" "+r,r,r,r,r,r")
+       (if_then_else:SI
+         (match_operator 2 "comparison_operator"
+           [(reg CC_REG) (const_int 0)])
+         (match_operand:SI 1 "nonmemory_operand"
+                             "r,Uint04,Sint08,Sint16,Sint24,i")
+         (match_dup 0)))]
+  "reload_completed"
+  {
+    PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
+    return "b%B2 1f\n\tmov %1, %0\n1:";
+  }
+  [(set_attr "length" "3,3,4,5,6,7")]
+)
+
 ;; Arithmetic Instructions
 
 (define_insn "abssi2"