aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorJ"orn Rennecke <amylaar@redhat.com>2001-09-21 00:53:28 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2001-09-21 01:53:28 +0100
commit3007d592bf05a6f1728f023c46207083cd24ca32 (patch)
tree75ea44ce54b6aea204eaf8c20fc7eb3b820a104e /gcc/config
parent385b6e2d89aafa6135634bf661b1b559dedc8de8 (diff)
downloadgcc-3007d592bf05a6f1728f023c46207083cd24ca32.zip
gcc-3007d592bf05a6f1728f023c46207083cd24ca32.tar.gz
gcc-3007d592bf05a6f1728f023c46207083cd24ca32.tar.bz2
sh-protos.h (sh_pr_n_sets): Declare.
* sh-protos.h (sh_pr_n_sets): Declare. * sh.c (calc_live_regs): If the initial value for PR has been copied, look at the copy to determine if PR needs to be saved. sh_pr_n_sets: New function. * sh.h (RETURN_ADDR_RTX): Use get_hard_reg_initial_val. (ALLOCATE_INITIAL_VALUE): Define. * sh.c (initial_elimination_offset): Fix RETURN_ADDRESS_POINTER_REGNUM case. From-SVN: r45717
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/sh/sh-protos.h1
-rw-r--r--gcc/config/sh/sh.c24
-rw-r--r--gcc/config/sh/sh.h9
3 files changed, 30 insertions, 4 deletions
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index ab00c53..a8507ae 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -119,6 +119,7 @@ extern void sh_expand_epilogue PARAMS ((void));
extern int sh_need_epilogue PARAMS ((void));
extern int initial_elimination_offset PARAMS ((int, int));
extern int fldi_ok PARAMS ((void));
+extern int sh_pr_n_sets PARAMS ((void));
#ifdef HARD_CONST
extern void fpscr_set_from_mem PARAMS ((int, HARD_REG_SET));
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 53f8b12..29a657b 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -3959,6 +3959,8 @@ calc_live_regs (count_ptr, live_regs_mask2)
int live_regs_mask = 0;
int count;
int interrupt_handler;
+ rtx pr_initial;
+ int pr_live;
if ((lookup_attribute
("interrupt_handler",
@@ -3979,14 +3981,20 @@ calc_live_regs (count_ptr, live_regs_mask2)
target_flags &= ~FPU_SINGLE_BIT;
break;
}
+ pr_initial = has_hard_reg_initial_val (Pmode, PR_REG);
+ pr_live = (pr_initial
+ ? REGNO (pr_initial) != PR_REG
+ : regs_ever_live[PR_REG]);
for (count = 0, reg = FIRST_PSEUDO_REGISTER - 1; reg >= 0; reg--)
{
- if ((interrupt_handler && ! pragma_trapa)
+ if (reg == PR_REG
+ ? pr_live
+ : (interrupt_handler && ! pragma_trapa)
? (/* Need to save all the regs ever live. */
(regs_ever_live[reg]
|| (call_used_regs[reg]
&& (! fixed_regs[reg] || reg == MACH_REG || reg == MACL_REG)
- && regs_ever_live[PR_REG]))
+ && pr_live))
&& reg != STACK_POINTER_REGNUM && reg != ARG_POINTER_REGNUM
&& reg != RETURN_ADDRESS_POINTER_REGNUM
&& reg != T_REG && reg != GBR_REG && reg != FPSCR_REG)
@@ -4598,7 +4606,7 @@ initial_elimination_offset (from, to)
if (from == RETURN_ADDRESS_POINTER_REGNUM
&& (to == FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM))
- return UNITS_PER_WORD + total_auto_space;
+ return total_auto_space;
abort ();
}
@@ -5638,3 +5646,13 @@ sh_adjust_cost (insn, link, dep_insn, cost)
return cost;
}
+
+/* For use by ALLOCATE_INITIAL_VALUE. Note that sh.md contains some
+ 'special function' patterns (type sfunc) that clobber pr, but that
+ do not look like function calls to leaf_function_p. Hence we must
+ do this extra check. */
+int
+sh_pr_n_sets ()
+{
+ return REG_N_SETS (PR_REG);
+}
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index b22684c3..5ca89e0 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1293,7 +1293,7 @@ extern int current_function_anonymous_args;
#define RETURN_ADDR_RTX(COUNT, FRAME) \
(((COUNT) == 0) \
- ? gen_rtx_MEM (Pmode, gen_rtx_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM)) \
+ ? get_hard_reg_initial_val (Pmode, PR_REG) \
: (rtx) 0)
/* Generate necessary RTL for __builtin_saveregs(). */
@@ -2369,4 +2369,11 @@ extern struct rtx_def *fpscr_rtx;
1: .long " USER_LABEL_PREFIX #func " - 0b\n\
2:")
+#define ALLOCATE_INITIAL_VALUE(hard_reg) \
+ (REGNO (hard_reg) == PR_REG \
+ ? (current_function_is_leaf && ! sh_pr_n_sets () \
+ ? (hard_reg) \
+ : gen_rtx_MEM (Pmode, arg_pointer_rtx)) \
+ : NULL_RTX)
+
#endif /* ! GCC_SH_H */