summaryrefslogtreecommitdiff
path: root/gcc/config/sh/sh.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/sh/sh.c')
-rw-r--r--gcc/config/sh/sh.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 9d8bb536c4f..7b87c962140 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -298,6 +298,7 @@ static void sh_encode_section_info (tree, rtx, int);
static int sh2a_function_vector_p (tree);
static void sh_trampoline_init (rtx, tree, rtx);
static rtx sh_trampoline_adjust_address (rtx);
+static void sh_conditional_register_usage (void);
static const struct attribute_spec sh_attribute_table[] =
{
@@ -588,6 +589,9 @@ static const struct default_options sh_option_optimization_table[] =
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD sh_secondary_reload
+#undef TARGET_CONDITIONAL_REGISTER_USAGE
+#define TARGET_CONDITIONAL_REGISTER_USAGE sh_conditional_register_usage
+
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P sh_legitimate_address_p
@@ -12415,6 +12419,54 @@ sh_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
return NO_REGS;
}
+static void
+sh_conditional_register_usage (void)
+{
+ int regno;
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++)
+ if (! VALID_REGISTER_P (regno))
+ fixed_regs[regno] = call_used_regs[regno] = 1;
+ /* R8 and R9 are call-clobbered on SH5, but not on earlier SH ABIs. */
+ if (TARGET_SH5)
+ {
+ call_used_regs[FIRST_GENERAL_REG + 8]
+ = call_used_regs[FIRST_GENERAL_REG + 9] = 1;
+ call_really_used_regs[FIRST_GENERAL_REG + 8]
+ = call_really_used_regs[FIRST_GENERAL_REG + 9] = 1;
+ }
+ if (TARGET_SHMEDIA)
+ {
+ regno_reg_class[FIRST_GENERAL_REG] = GENERAL_REGS;
+ CLEAR_HARD_REG_SET (reg_class_contents[FP0_REGS]);
+ regno_reg_class[FIRST_FP_REG] = FP_REGS;
+ }
+ if (flag_pic)
+ {
+ fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
+ call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
+ }
+ /* Renesas saves and restores mac registers on call. */
+ if (TARGET_HITACHI && ! TARGET_NOMACSAVE)
+ {
+ call_really_used_regs[MACH_REG] = 0;
+ call_really_used_regs[MACL_REG] = 0;
+ }
+ for (regno = FIRST_FP_REG + (TARGET_LITTLE_ENDIAN != 0);
+ regno <= LAST_FP_REG; regno += 2)
+ SET_HARD_REG_BIT (reg_class_contents[DF_HI_REGS], regno);
+ if (TARGET_SHMEDIA)
+ {
+ for (regno = FIRST_TARGET_REG; regno <= LAST_TARGET_REG; regno ++)
+ if (! fixed_regs[regno] && call_really_used_regs[regno])
+ SET_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
+ }
+ else
+ for (regno = FIRST_GENERAL_REG; regno <= LAST_GENERAL_REG; regno++)
+ if (! fixed_regs[regno] && call_really_used_regs[regno])
+ SET_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
+}
+
+
enum sh_divide_strategy_e sh_div_strategy = SH_DIV_STRATEGY_DEFAULT;
#include "gt-sh.h"