+2007-07-15 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR middle-end/32398
+ PR middle-end/32769
+ * pa-protos.h (pa_eh_return_handler_rtx): Declare.
+ * pa.c (pa_extra_live_on_entry, rp_saved): Declare.
+ (TARGET_EXTRA_LIVE_ON_ENTRY): Define.
+ (pa_output_function_prologue): Use rp_saved and current_function_is_leaf
+ to generate .CALLINFO statement.
+ (hppa_expand_prologue): Set rp_saved.
+ (hppa_expand_epilogue): Use rp_saved.
+ (pa_extra_live_on_entry, pa_eh_return_handler_rtx): New functions.
+ * pa.h (EH_RETURN_HANDLER_RTX): Use pa_eh_return_handler_rtx.
+
2007-07-14 Dirk Mueller <dmueller@suse.de>
* omega.c (coalesce): Fix memory leak on early exit.
static enum reg_class pa_secondary_reload (bool, rtx, enum reg_class,
enum machine_mode,
secondary_reload_info *);
-
+static void pa_extra_live_on_entry (bitmap);
/* The following extra sections are only used for SOM. */
static GTY(()) section *som_readonly_data_section;
registers which were saved by the current function's prologue. */
static int gr_saved, fr_saved;
+/* Boolean indicating whether the return pointer was saved by the
+ current function's prologue. */
+static bool rp_saved;
+
static rtx find_addr_reg (rtx);
/* Keep track of the number of bytes we have output in the CODE subspace
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD pa_secondary_reload
+#undef TARGET_EXTRA_LIVE_ON_ENTRY
+#define TARGET_EXTRA_LIVE_ON_ENTRY pa_extra_live_on_entry
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Parse the -mfixed-range= option string. */
to output the assembler directives which denote the start
of a function. */
fprintf (file, "\t.CALLINFO FRAME=" HOST_WIDE_INT_PRINT_DEC, actual_fsize);
- if (df_regs_ever_live_p (2))
- fputs (",CALLS,SAVE_RP", file);
- else
+ if (current_function_is_leaf)
fputs (",NO_CALLS", file);
+ else
+ fputs (",CALLS", file);
+ if (rp_saved)
+ fputs (",SAVE_RP", file);
/* The SAVE_SP flag is used to indicate that register %r3 is stored
at the beginning of the frame and that it is used as the frame
always be stored into the caller's frame at sp - 20 or sp - 16
depending on which ABI is in use. */
if (df_regs_ever_live_p (2) || current_function_calls_eh_return)
- store_reg (2, TARGET_64BIT ? -16 : -20, STACK_POINTER_REGNUM);
+ {
+ store_reg (2, TARGET_64BIT ? -16 : -20, STACK_POINTER_REGNUM);
+ rp_saved = true;
+ }
+ else
+ rp_saved = false;
/* Allocate the local frame and set up the frame pointer if needed. */
if (actual_fsize != 0)
/* Try to restore RP early to avoid load/use interlocks when
RP gets used in the return (bv) instruction. This appears to still
be necessary even when we schedule the prologue and epilogue. */
- if (df_regs_ever_live_p (2) || current_function_calls_eh_return)
+ if (rp_saved)
{
ret_off = TARGET_64BIT ? -16 : -20;
if (frame_pointer_needed)
return NO_REGS;
}
+/* Implement TARGET_EXTRA_LIVE_ON_ENTRY. The argument pointer
+ is only marked as live on entry by df-scan when it is a fixed
+ register. It isn't a fixed register in the 64-bit runtime,
+ so we need to mark it here. */
+
+static void
+pa_extra_live_on_entry (bitmap regs)
+{
+ if (TARGET_64BIT)
+ bitmap_set_bit (regs, ARG_POINTER_REGNUM);
+}
+
+/* Implement EH_RETURN_HANDLER_RTX. The MEM needs to be volatile
+ to prevent it from being deleted. */
+
+rtx
+pa_eh_return_handler_rtx (void)
+{
+ rtx tmp;
+
+ tmp = gen_rtx_PLUS (word_mode, frame_pointer_rtx,
+ TARGET_64BIT ? GEN_INT (-16) : GEN_INT (-20));
+ tmp = gen_rtx_MEM (word_mode, tmp);
+ tmp->volatil = 1;
+ return tmp;
+}
+
/* In the 32-bit runtime, arguments larger than eight bytes are passed
by invisible reference. As a GCC extension, we also pass anything
with a zero or variable size by reference.