PR target/53250
authorolegendo <olegendo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 6 May 2012 22:38:57 +0000 (22:38 +0000)
committerolegendo <olegendo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 6 May 2012 22:38:57 +0000 (22:38 +0000)
* config/sh/sh.c (sh_rtx_costs): Handle SET.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187218 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sh/sh.c

index eab0576..aa909e3 100644 (file)
@@ -1,3 +1,8 @@
+2012-05-07  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/53250
+       * config/sh/sh.c (sh_rtx_costs): Handle SET.
+
 2012-05-06  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/53227
index d863474..08ee5b4 100644 (file)
@@ -2999,6 +2999,27 @@ sh_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
 {
   switch (code)
     {
+      /* The lower-subreg pass decides whether to split multi-word regs
+        into individual regs by looking at the cost for a SET of certain
+        modes with the following patterns:
+          (set (reg) (reg)) 
+          (set (reg) (const_int 0))
+        On machines that support vector-move operations a multi-word move
+        is the same cost as individual reg move.  On SH there is no
+        vector-move, so we have to provide the correct cost in the number
+        of move insns to load/store the reg of the mode in question.  */
+    case SET:
+      if (register_operand (SET_DEST (x), VOIDmode)
+           && (register_operand (SET_SRC (x), VOIDmode)
+               || satisfies_constraint_Z (SET_SRC (x))))
+       {
+         const enum machine_mode mode = GET_MODE (SET_DEST (x));
+         *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
+                                 / mov_insn_size (mode, TARGET_SH2A));
+         return true;
+        }
+      return false;
+
     case CONST_INT:
       if (TARGET_SHMEDIA)
         {