aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Edelsohn <edelsohn@gnu.org>2002-10-23 15:20:38 +0000
committerDavid Edelsohn <dje@gcc.gnu.org>2002-10-23 11:20:38 -0400
commit34bb030a5679ed534d99333f45bceb8bfdff348f (patch)
tree4d40dadda3427c34b5d4cc20c0482b2a2c61eed3
parent1ab9ba628672d778d1ad8ee3e704a9b2db6f5ffb (diff)
downloadgcc-34bb030a5679ed534d99333f45bceb8bfdff348f.zip
gcc-34bb030a5679ed534d99333f45bceb8bfdff348f.tar.gz
gcc-34bb030a5679ed534d99333f45bceb8bfdff348f.tar.bz2
rs6000.c (rs6000_register_move_cost): New function.
* 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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/rs6000/rs6000-protos.h4
-rw-r--r--gcc/config/rs6000/rs6000.c58
-rw-r--r--gcc/config/rs6000/rs6000.h31
4 files changed, 75 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7091d22..2fd44c8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index d043154..53d8192 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -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 */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index eddd839..fe74ffd 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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);
+}
+
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 40731b8..5580549 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -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.