diff options
author | David Edelsohn <edelsohn@gnu.org> | 2002-10-23 15:20:38 +0000 |
---|---|---|
committer | David Edelsohn <dje@gcc.gnu.org> | 2002-10-23 11:20:38 -0400 |
commit | 34bb030a5679ed534d99333f45bceb8bfdff348f (patch) | |
tree | 4d40dadda3427c34b5d4cc20c0482b2a2c61eed3 | |
parent | 1ab9ba628672d778d1ad8ee3e704a9b2db6f5ffb (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-protos.h | 4 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 58 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 31 |
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. |