aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatoly Sokolov <aesok@post.ru>2010-06-27 15:40:42 +0400
committerAnatoly Sokolov <aesok@gcc.gnu.org>2010-06-27 15:40:42 +0400
commitde8f4b07c03ffb0db0562f462be066684af2f0b7 (patch)
tree851a7e8964d45a63937f1e17d192d74a42b4e143
parent533e50f6ac9ee21fe5bcb223e8d6693466836d80 (diff)
downloadgcc-de8f4b07c03ffb0db0562f462be066684af2f0b7.zip
gcc-de8f4b07c03ffb0db0562f462be066684af2f0b7.tar.gz
gcc-de8f4b07c03ffb0db0562f462be066684af2f0b7.tar.bz2
target.h (struct gcc_target): Add register_move_cost field.
* target.h (struct gcc_target): Add register_move_cost field. * target-def.h (TARGET_REGISTER_MOVE_COST): New. (TARGET_INITIALIZER): Use TARGET_REGISTER_MOVE_COST. * targhooks.c (default_register_move_cost): New function. * targhooks.h (default_register_move_cost): Declare function. * defaults.h (REGISTER_MOVE_COST): Delete. * ira-int.h (ira_register_move_cost): Update comment. * ira.c: (ira_register_move_cost): Update comment. * reload.h (register_move_cost): Declare. * reginfo.c (register_move_cost): New function. (move_cost): Update comment. (init_move_cost, memory_move_secondary_cost): Replace REGISTER_MOVE_COST with register_move_cost. * postreload.c (reload_cse_simplify_set): (Ditto.). * reload.c (find_valid_class, find_reloads): (Ditto.). * reload1.c (choose_reload_regs): (Ditto.). * doc/tm.texi (TARGET_REGISTER_MOVE_COST): New. (REGISTER_MOVE_COST, TARGET_MEMORY_MOVE_COST): Update documentation. * doc/md.texi (can_create_pseudo_p): Update documentation. * config/i386/i386.h (MEMORY_MOVE_COST): Remove macro. * config/i386/i386-protos.h (int ix86_memory_move_cost): Remove. * config/i386/i386.h (ix86_memory_move_cost): Make static. (TARGET_MEMORY_MOVE_COST): Define. * config/ia64/ia64.h (MEMORY_MOVE_COST): Remove macro. * config/ia64/ia64-protos.h (int ia64_memory_move_cost): Remove. * config/ia64/ia64.h (ia64_memory_move_cost): Make static. (TARGET_MEMORY_MOVE_COST): Define. From-SVN: r161470
-rw-r--r--gcc/ChangeLog32
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/i386.c4
-rw-r--r--gcc/config/i386/i386.h11
-rw-r--r--gcc/config/ia64/ia64-protos.h2
-rw-r--r--gcc/config/ia64/ia64.c6
-rw-r--r--gcc/config/ia64/ia64.h5
-rw-r--r--gcc/defaults.h4
-rw-r--r--gcc/doc/md.texi3
-rw-r--r--gcc/doc/tm.texi30
-rw-r--r--gcc/ira-int.h2
-rw-r--r--gcc/ira.c2
-rw-r--r--gcc/postreload.c4
-rw-r--r--gcc/reginfo.c19
-rw-r--r--gcc/reload.c6
-rw-r--r--gcc/reload.h2
-rw-r--r--gcc/reload1.c2
-rw-r--r--gcc/target-def.h5
-rw-r--r--gcc/target.h5
-rw-r--r--gcc/targhooks.c15
-rw-r--r--gcc/targhooks.h3
21 files changed, 122 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5a6908c..4a1fe90 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,35 @@
+2010-06-27 Anatoly Sokolov <aesok@post.ru>
+
+ * target.h (struct gcc_target): Add register_move_cost field.
+ * target-def.h (TARGET_REGISTER_MOVE_COST): New.
+ (TARGET_INITIALIZER): Use TARGET_REGISTER_MOVE_COST.
+ * targhooks.c (default_register_move_cost): New function.
+ * targhooks.h (default_register_move_cost): Declare function.
+ * defaults.h (REGISTER_MOVE_COST): Delete.
+ * ira-int.h (ira_register_move_cost): Update comment.
+ * ira.c: (ira_register_move_cost): Update comment.
+ * reload.h (register_move_cost): Declare.
+ * reginfo.c (register_move_cost): New function.
+ (move_cost): Update comment.
+ (init_move_cost, memory_move_secondary_cost): Replace
+ REGISTER_MOVE_COST with register_move_cost.
+ * postreload.c (reload_cse_simplify_set): (Ditto.).
+ * reload.c (find_valid_class, find_reloads): (Ditto.).
+ * reload1.c (choose_reload_regs): (Ditto.).
+ * doc/tm.texi (TARGET_REGISTER_MOVE_COST): New.
+ (REGISTER_MOVE_COST, TARGET_MEMORY_MOVE_COST): Update documentation.
+ * doc/md.texi (can_create_pseudo_p): Update documentation.
+
+ * config/i386/i386.h (MEMORY_MOVE_COST): Remove macro.
+ * config/i386/i386-protos.h (int ix86_memory_move_cost): Remove.
+ * config/i386/i386.h (ix86_memory_move_cost): Make static.
+ (TARGET_MEMORY_MOVE_COST): Define.
+
+ * config/ia64/ia64.h (MEMORY_MOVE_COST): Remove macro.
+ * config/ia64/ia64-protos.h (int ia64_memory_move_cost): Remove.
+ * config/ia64/ia64.h (ia64_memory_move_cost): Make static.
+ (TARGET_MEMORY_MOVE_COST): Define.
+
2010-06-27 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44683
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 5bd8749..308f9ee 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -149,8 +149,6 @@ extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
rtx, rtx, rtx, rtx);
extern bool ix86_hard_regno_mode_ok (int, enum machine_mode);
extern bool ix86_modes_tieable_p (enum machine_mode, enum machine_mode);
-extern int ix86_register_move_cost (enum machine_mode, enum reg_class,
- enum reg_class);
extern int ix86_secondary_memory_needed (enum reg_class, enum reg_class,
enum machine_mode, int);
extern bool ix86_cannot_change_mode_class (enum machine_mode,
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e0d8dc4..bd1cc05 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -25656,7 +25656,7 @@ ix86_memory_move_cost (enum machine_mode mode, enum reg_class regclass,
on some machines it is expensive to move between registers if they are not
general registers. */
-int
+static int
ix86_register_move_cost (enum machine_mode mode, enum reg_class class1,
enum reg_class class2)
{
@@ -30828,6 +30828,8 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree)
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION ix86_handle_option
+#undef TARGET_REGISTER_MOVE_COST
+#define TARGET_REGISTER_MOVE_COST ix86_register_move_cost
#undef TARGET_MEMORY_MOVE_COST
#define TARGET_MEMORY_MOVE_COST ix86_memory_move_cost
#undef TARGET_RTX_COSTS
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 226f784..67f1f60 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1891,17 +1891,6 @@ do { \
so give the MEM rtx a byte's mode. */
#define FUNCTION_MODE QImode
-/* A C expression for the cost of moving data from a register in class FROM to
- one in class TO. The classes are expressed using the enumeration values
- such as `GENERAL_REGS'. A value of 2 is the default; other values are
- interpreted relative to that.
-
- It is not required that the cost always equal 2 when FROM is the same as TO;
- on some machines it is expensive to move between registers if they are not
- general registers. */
-
-#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
- ix86_register_move_cost ((MODE), (CLASS1), (CLASS2))
/* A C expression for the cost of a branch instruction. A value of 1
is the default; other values are interpreted relative to that. */
diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h
index cd89e7c..a5914b1 100644
--- a/gcc/config/ia64/ia64-protos.h
+++ b/gcc/config/ia64/ia64-protos.h
@@ -82,8 +82,6 @@ extern void ia64_vms_elf_asm_named_section (const char *, unsigned int, tree);
extern void ia64_start_function (FILE *, const char *, tree);
#endif /* TREE_CODE */
-extern int ia64_register_move_cost (enum machine_mode, enum reg_class,
- enum reg_class);
extern int ia64_epilogue_uses (int);
extern int ia64_eh_uses (int);
extern void emit_safe_across_calls (void);
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 4d6dbde..d40747a 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -210,6 +210,8 @@ static bool ia64_return_in_memory (const_tree, const_tree);
static rtx ia64_function_value (const_tree, const_tree, bool);
static rtx ia64_libcall_value (enum machine_mode, const_rtx);
static bool ia64_function_value_regno_p (const unsigned int);
+static int ia64_register_move_cost (enum machine_mode, enum reg_class,
+ enum reg_class);
static bool ia64_rtx_costs (rtx, int, int, int *, bool);
static int ia64_unspec_may_trap_p (const_rtx, unsigned);
static void fix_range (const char *);
@@ -454,6 +456,8 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_ASM_GLOBALIZE_DECL_NAME
#define TARGET_ASM_GLOBALIZE_DECL_NAME ia64_globalize_decl_name
+#undef TARGET_REGISTER_MOVE_COST
+#define TARGET_REGISTER_MOVE_COST ia64_register_move_cost
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS ia64_rtx_costs
#undef TARGET_ADDRESS_COST
@@ -5202,7 +5206,7 @@ ia64_rtx_costs (rtx x, int code, int outer_code, int *total,
/* Calculate the cost of moving data from a register in class FROM to
one in class TO, using MODE. */
-int
+static int
ia64_register_move_cost (enum machine_mode mode, enum reg_class from,
enum reg_class to)
{
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 8192b9f..bf24f73 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -1310,11 +1310,6 @@ do { \
/* Describing Relative Costs of Operations */
-/* A C expression for the cost of moving data from a register in class FROM to
- one in class TO, using MODE. */
-
-#define REGISTER_MOVE_COST ia64_register_move_cost
-
/* A C expression for the cost of moving data of mode M between a
register and memory. */
#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
diff --git a/gcc/defaults.h b/gcc/defaults.h
index c4809c9..eb74033 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -981,10 +981,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#endif /* old constraint mechanism in use */
-#ifndef REGISTER_MOVE_COST
-#define REGISTER_MOVE_COST(m, x, y) 2
-#endif
-
/* Determine whether the entire c99 runtime
is present in the runtime library. */
#ifndef TARGET_C99_FUNCTIONS
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 46bd4f6..211fdcb 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -3763,7 +3763,8 @@ it is unsafe to call @code{gen_reg_rtx} to allocate a new pseudo.
The constraints on a @samp{mov@var{m}} must permit moving any hard
register to any other hard register provided that
@code{HARD_REGNO_MODE_OK} permits mode @var{m} in both registers and
-@code{REGISTER_MOVE_COST} applied to their classes returns a value of 2.
+@code{TARGET_REGISTER_MOVE_COST} applied to their classes returns a value
+of 2.
It is obligatory to support floating point @samp{mov@var{m}}
instructions into and out of any registers that can hold fixed point
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index c001c8b..637dd50 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -6116,8 +6116,32 @@ classes returns a value of 2, reload does not check to ensure that the
constraints of the insn are met. Setting a cost of other than 2 will
allow reload to verify that the constraints are met. You should do this
if the @samp{mov@var{m}} pattern's constraints do not allow such copying.
+
+These macros are obsolete, new ports should use the target hook
+@code{TARGET_REGISTER_MOVE_COST} instead.
@end defmac
+@deftypefn {Target Hook} int TARGET_REGISTER_MOVE_COST (enum machine_mode @var{mode}, enum reg_class @var{from}, enum reg_class @var{to})
+This target hook should return the cost of moving data of mode @var{mode}
+from a register in class @var{from} to one in class @var{to}. The classes
+are expressed using the enumeration values such as @code{GENERAL_REGS}.
+A value of 2 is the default; other values are interpreted relative to
+that.
+
+It is not required that the cost always equal 2 when @var{from} is the
+same as @var{to}; on some machines it is expensive to move between
+registers if they are not general registers.
+
+If reload sees an insn consisting of a single @code{set} between two
+hard registers, and if @code{TARGET_REGISTER_MOVE_COST} applied to their
+classes returns a value of 2, reload does not check to ensure that the
+constraints of the insn are met. Setting a cost of other than 2 will
+allow reload to verify that the constraints are met. You should do this
+if the @samp{mov@var{m}} pattern's constraints do not allow such copying.
+
+The default version of this function returns 2.
+@end deftypefn
+
@defmac MEMORY_MOVE_COST (@var{mode}, @var{class}, @var{in})
A C expression for the cost of moving data of mode @var{mode} between a
register of class @var{class} and memory; @var{in} is zero if the value
@@ -6149,9 +6173,9 @@ These macros are obsolete, new ports should use the target hook
This target hook should return the cost of moving data of mode @var{mode}
between a register of class @var{class} and memory; @var{in} is @code{false}
if the value is to be written to memory, @code{true} if it is to be read in.
-This cost is relative to those in @code{REGISTER_MOVE_COST}. If moving
-between registers and memory is more expensive than between two registers,
-you should add this target hook to express the relative cost.
+This cost is relative to those in @code{TARGET_REGISTER_MOVE_COST}.
+If moving between registers and memory is more expensive than between two
+registers, you should add this target hook to express the relative cost.
If you do not add this target hook, GCC uses a default cost of 4 plus
the cost of copying via a secondary reload register, if one is
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index fd5ffb8..1da087c 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -724,7 +724,7 @@ minmax_set_iter_next (minmax_set_iterator *i)
extern HARD_REG_SET ira_reg_mode_hard_regset
[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES];
-/* Array analogous to macro REGISTER_MOVE_COST. Don't use
+/* Array based on TARGET_REGISTER_MOVE_COST. Don't use
ira_register_move_cost directly. Use function of
ira_get_may_move_cost instead. */
extern move_table *ira_register_move_cost[MAX_MACHINE_MODE];
diff --git a/gcc/ira.c b/gcc/ira.c
index a2e8c38..7f4c8d8 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -358,7 +358,7 @@ HARD_REG_SET ira_reg_mode_hard_regset[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES];
/* Array analogous to target hook TARGET_MEMORY_MOVE_COST. */
short int ira_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2];
-/* Array analogous to macro REGISTER_MOVE_COST. */
+/* Array based on TARGET_REGISTER_MOVE_COST. */
move_table *ira_register_move_cost[MAX_MACHINE_MODE];
/* Similar to may_move_in_cost but it is calculated in IRA instead of
diff --git a/gcc/postreload.c b/gcc/postreload.c
index c165b52..3882719 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -264,7 +264,7 @@ reload_cse_simplify_set (rtx set, rtx insn)
if (MEM_P (src))
old_cost = memory_move_cost (GET_MODE (src), dclass, true);
else if (REG_P (src))
- old_cost = REGISTER_MOVE_COST (GET_MODE (src),
+ old_cost = register_move_cost (GET_MODE (src),
REGNO_REG_CLASS (REGNO (src)), dclass);
else
old_cost = rtx_cost (src, SET, speed);
@@ -314,7 +314,7 @@ reload_cse_simplify_set (rtx set, rtx insn)
}
else
#endif
- this_cost = REGISTER_MOVE_COST (GET_MODE (this_rtx),
+ this_cost = register_move_cost (GET_MODE (this_rtx),
REGNO_REG_CLASS (REGNO (this_rtx)),
dclass);
}
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index 66e774a..b868c37 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -183,7 +183,7 @@ bool have_regs_of_mode [MAX_MACHINE_MODE];
char contains_reg_of_mode [N_REG_CLASSES] [MAX_MACHINE_MODE];
/* Maximum cost of moving from a register in one class to a register in
- another class. Based on REGISTER_MOVE_COST. */
+ another class. Based on TARGET_REGISTER_MOVE_COST. */
move_table *move_cost[MAX_MACHINE_MODE];
/* Similar, but here we don't have to move if the first index is a subset
@@ -274,7 +274,7 @@ init_move_cost (enum machine_mode m)
cost = 65535;
else
{
- cost = REGISTER_MOVE_COST (m, (enum reg_class) i,
+ cost = register_move_cost (m, (enum reg_class) i,
(enum reg_class) j);
gcc_assert (cost < 65535);
}
@@ -681,6 +681,17 @@ init_fake_stack_mems (void)
top_of_stack[i] = gen_rtx_MEM ((enum machine_mode) i, stack_pointer_rtx);
}
+
+/* Compute cost of moving data from a register of class FROM to one of
+ TO, using MODE. */
+
+int
+register_move_cost (enum machine_mode mode, enum reg_class from,
+ enum reg_class to)
+{
+ return targetm.register_move_cost (mode, from, to);
+}
+
/* Compute cost of moving registers to/from memory. */
int
memory_move_cost (enum machine_mode mode, enum reg_class rclass, bool in)
@@ -706,9 +717,9 @@ memory_move_secondary_cost (enum machine_mode mode, enum reg_class rclass,
return 0;
if (in)
- partial_cost = REGISTER_MOVE_COST (mode, altclass, rclass);
+ partial_cost = register_move_cost (mode, altclass, rclass);
else
- partial_cost = REGISTER_MOVE_COST (mode, rclass, altclass);
+ partial_cost = register_move_cost (mode, rclass, altclass);
if (rclass == altclass)
/* This isn't simply a copy-to-temporary situation. Can't guess
diff --git a/gcc/reload.c b/gcc/reload.c
index d4b7982..30bee6d 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -688,7 +688,7 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
if (bad || !good)
continue;
- cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass, dest_class);
+ cost = register_move_cost (outer, (enum reg_class) rclass, dest_class);
if ((reg_class_size[rclass] > best_size
&& (best_cost < 0 || best_cost >= cost))
@@ -696,7 +696,7 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
{
best_class = (enum reg_class) rclass;
best_size = reg_class_size[rclass];
- best_cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass,
+ best_cost = register_move_cost (outer, (enum reg_class) rclass,
dest_class);
}
}
@@ -2651,7 +2651,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
&& REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
&& REG_P (SET_SRC (body))
&& REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
- && REGISTER_MOVE_COST (GET_MODE (SET_SRC (body)),
+ && register_move_cost (GET_MODE (SET_SRC (body)),
REGNO_REG_CLASS (REGNO (SET_SRC (body))),
REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
return 0;
diff --git a/gcc/reload.h b/gcc/reload.h
index 4625bf7..a3c1f07 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see
SECONDARY_RELOAD_CLASS (CLASS, MODE, X)
#endif
+extern int register_move_cost (enum machine_mode, enum reg_class,
+ enum reg_class);
extern int memory_move_cost (enum machine_mode, enum reg_class, bool);
extern int memory_move_secondary_cost (enum machine_mode, enum reg_class,
bool);
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 00d4c99..a0b61f5 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -6496,7 +6496,7 @@ choose_reload_regs (struct insn_chain *chain)
register, we might use it for reload_override_in,
if copying it to the desired class is cheap
enough. */
- || ((REGISTER_MOVE_COST (mode, last_class, rclass)
+ || ((register_move_cost (mode, last_class, rclass)
< memory_move_cost (mode, rclass, true))
&& (secondary_reload_class (1, rclass, mode,
last_reg)
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 1aaf38c..27b7fa8 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -474,6 +474,10 @@
#define TARGET_ADDRESS_COST default_address_cost
#define TARGET_CONST_ANCHOR 0
+#ifndef TARGET_REGISTER_MOVE_COST
+#define TARGET_REGISTER_MOVE_COST default_register_move_cost
+#endif
+
#ifndef TARGET_MEMORY_MOVE_COST
#define TARGET_MEMORY_MOVE_COST default_memory_move_cost
#endif
@@ -1027,6 +1031,7 @@
TARGET_ADDR_SPACE_HOOKS, \
TARGET_SCALAR_MODE_SUPPORTED_P, \
TARGET_VECTOR_MODE_SUPPORTED_P, \
+ TARGET_REGISTER_MOVE_COST, \
TARGET_MEMORY_MOVE_COST, \
TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P, \
TARGET_RTX_COSTS, \
diff --git a/gcc/target.h b/gcc/target.h
index 2f181eb..5a857d7 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -812,6 +812,11 @@ struct gcc_target
for further details. */
bool (* vector_mode_supported_p) (enum machine_mode mode);
+ /* Compute cost of moving data from a register of class FROM to one of
+ TO, using MODE. */
+ int (* register_move_cost) (enum machine_mode, enum reg_class,
+ enum reg_class);
+
/* Compute cost of moving registers to/from memory. */
int (* memory_move_cost) (enum machine_mode, enum reg_class, bool);
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 6c1d258..62e3577 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1127,4 +1127,19 @@ default_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
#endif
}
+/* Compute cost of moving data from a register of class FROM to one of
+ TO, using MODE. */
+
+int
+default_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
+ enum reg_class from ATTRIBUTE_UNUSED,
+ enum reg_class to ATTRIBUTE_UNUSED)
+{
+#ifndef REGISTER_MOVE_COST
+ return 2;
+#else
+ return REGISTER_MOVE_COST (mode, from, to);
+#endif
+}
+
#include "gt-targhooks.h"
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 6e71445..fdd0e4a 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -140,3 +140,6 @@ extern rtx default_addr_space_convert (rtx, tree, tree);
extern unsigned int default_case_values_threshold (void);
extern bool default_have_conditional_execution (void);
extern int default_memory_move_cost (enum machine_mode, enum reg_class, bool);
+extern int default_register_move_cost (enum machine_mode, enum reg_class,
+ enum reg_class);
+