rs6000.c (rs6000_register_move_cost): New function.
authorDavid Edelsohn <edelsohn@gnu.org>
Wed, 23 Oct 2002 15:20:38 +0000 (15:20 +0000)
committerDavid Edelsohn <dje@gcc.gnu.org>
Wed, 23 Oct 2002 15:20:38 +0000 (11:20 -0400)
        * config/rs6000/rs6000.c (rs6000_register_move_cost): New function.
        (rs6000_memory_move_cost): New function.
        * config/rs6000/rs6000-protos.h: Declare them.
        * config/rs6000/rs6000.h: Use them.

Co-Authored-By: Geoffrey Keating <geoffk@apple.com>
From-SVN: r58453

gcc/ChangeLog
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h

index 7091d226759a623060d0f4d888500f71e3345072..2fd44c8c2b50b741c5762c99453798df5c3c7d2f 100644 (file)
@@ -1,3 +1,11 @@
+2002-10-23  David Edelsohn  <edelsohn@gnu.org>
+           Geoff Keating  <geoffk@apple.com>
+
+       * config/rs6000/rs6000.c (rs6000_register_move_cost): New function.
+       (rs6000_memory_move_cost): New function.
+       * config/rs6000/rs6000-protos.h: Declare them.
+       * config/rs6000/rs6000.h: Use them.
+
 2002-10-23  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * libgcc2.c (__udiv_w_sdiv): Use attribute ((always_inline)) when 
index d0431545364de5bd5b4ada786bd32c0f482b8497..53d819202fe30b3b2600f673bfe74fd777f8e50f 100644 (file)
@@ -188,6 +188,10 @@ extern void rs6000_emit_epilogue PARAMS ((int));
 extern void debug_stack_info PARAMS ((rs6000_stack_t *));
 extern const char *output_isel PARAMS ((rtx *));
 extern int vrsave_operation PARAMS ((rtx, enum machine_mode));
+extern int rs6000_register_move_cost PARAMS ((enum machine_mode,
+                                             enum reg_class, enum reg_class));
+extern int rs6000_memory_move_cost PARAMS ((enum machine_mode,
+                                           enum reg_class, int));
 
 /* Declare functions in rs6000-c.c */
 
index eddd839875493f410c80056d996704feecdec485..fe74ffda10cd3a106073484cf5669c176bf301c8 100644 (file)
@@ -13236,3 +13236,61 @@ rs6000_binds_local_p (decl)
 {
   return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
 }
+
+/* A C expression returning the cost of moving data from a register of class
+   CLASS1 to one of CLASS2.  */
+
+int
+rs6000_register_move_cost (mode, from, to)
+     enum machine_mode mode;
+     enum reg_class from, to;
+{
+  /*  Moves from/to GENERAL_REGS.  */
+  if (reg_classes_intersect_p (to, GENERAL_REGS)
+      || reg_classes_intersect_p (from, GENERAL_REGS))
+    {
+      if (! reg_classes_intersect_p (to, GENERAL_REGS))
+       from = to;
+
+      if (from == FLOAT_REGS || from == ALTIVEC_REGS)
+       return (rs6000_memory_move_cost (mode, from, 0)
+               + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
+
+/* It's more expensive to move CR_REGS than CR0_REGS because of the shift...*/
+      else if (from == CR_REGS)
+       return 4;
+
+      else
+/* A move will cost one instruction per GPR moved.  */
+       return 2 * HARD_REGNO_NREGS (0, mode);
+    }
+
+/* Moving between two similar registers is just one instruction.  */
+  else if (reg_classes_intersect_p (to, from))
+    return mode == TFmode ? 4 : 2;
+
+/* Everything else has to go through GENERAL_REGS.  */
+  else
+    return (rs6000_register_move_cost (mode, GENERAL_REGS, to) 
+           + rs6000_register_move_cost (mode, from, GENERAL_REGS));
+}
+
+/* A C expressions returning the cost of moving data of MODE from a register to
+   or from memory.  */
+
+int
+rs6000_memory_move_cost (mode, class, in)
+  enum machine_mode mode;
+  enum reg_class class;
+  int in ATTRIBUTE_UNUSED;
+{
+  if (reg_classes_intersect_p (class, GENERAL_REGS))
+    return 4 * HARD_REGNO_NREGS (0, mode);
+  else if (reg_classes_intersect_p (class, FLOAT_REGS))
+    return 4 * HARD_REGNO_NREGS (32, mode);
+  else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
+    return 4 * HARD_REGNO_NREGS (FIRST_ALTIVEC_REGNO, mode);
+  else
+    return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
+}
+
index 40731b8126a39815f1d56a60b487375c6866fa5e..55805490d44ddc3eccdf991da0aa53aa3d790e88 100644 (file)
@@ -926,35 +926,14 @@ extern int rs6000_default_long_calls;
    : 1)
 
 /* A C expression returning the cost of moving data from a register of class
-   CLASS1 to one of CLASS2.
-
-   On the RS/6000, copying between floating-point and fixed-point
-   registers is expensive.  */
-
-#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)               \
-   ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2       \
-   : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10     \
-   : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10     \
-   : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20 \
-   : (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20 \
-   : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS         \
-       || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS                \
-       || (CLASS1) == LINK_OR_CTR_REGS)                                \
-      && ((CLASS2) == SPECIAL_REGS || (CLASS2) == MQ_REGS      \
-         || (CLASS2) == LINK_REGS || (CLASS2) == CTR_REGS      \
-         || (CLASS2) == LINK_OR_CTR_REGS)) ? 10                \
-   : 2)
+   CLASS1 to one of CLASS2.  */
 
-/* A C expressions returning the cost of moving data of MODE from a register to
-   or from memory.
+#define REGISTER_MOVE_COST rs6000_register_move_cost
 
-   On the RS/6000, bump this up a bit.  */
+/* A C expressions returning the cost of moving data of MODE from a register to
+   or from memory.  */
 
-#define MEMORY_MOVE_COST(MODE, CLASS, IN)      \
-  ((GET_MODE_CLASS (MODE) == MODE_FLOAT                \
-    && (rs6000_cpu == PROCESSOR_RIOS1 || rs6000_cpu == PROCESSOR_PPC601) \
-    ? 3 : 2) \
-   + 4)
+#define MEMORY_MOVE_COST rs6000_memory_move_cost
 
 /* Specify the cost of a branch insn; roughly the number of extra insns that
    should be added to avoid a branch.