#include "except.h"
#include "function.h"
#include "toplev.h"
+#include "ggc.h"
/* External data. */
extern char *version_string;
rtx alpha_compare_op0, alpha_compare_op1;
int alpha_compare_fp_p;
-/* Define the information needed to modify the epilogue for EH. */
-
-rtx alpha_eh_epilogue_sp_ofs;
-
/* Non-zero if inside of a function, because the Alpha asm can't
handle .files inside of functions. */
static int inside_function = FALSE;
-/* If non-null, this rtx holds the return address for the function. */
-
-static rtx alpha_return_addr_rtx;
-
/* The number of cycles of latency we should assume on memory reads. */
int alpha_memory_latency = 3;
PROTO((unsigned long *imaskP, unsigned long *fmaskP));
static int alpha_does_function_need_gp
PROTO((void));
+static void alpha_init_machine_status
+ PROTO((struct function *p));
+static void alpha_mark_machine_status
+ PROTO((struct function *p));
/* Get the number of args of a function in one of two ways. */
/* Acquire a unique set number for our register saves and restores. */
alpha_sr_alias_set = new_alias_set ();
+
+ /* Set up function hooks. */
+ init_machine_status = alpha_init_machine_status;
+ mark_machine_status = alpha_mark_machine_status;
}
\f
/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
\f
/* Functions to save and restore alpha_return_addr_rtx. */
-struct machine_function
-{
- rtx ra_rtx;
-};
-
static void
-alpha_save_machine_status (p)
+alpha_init_machine_status (p)
struct function *p;
{
- struct machine_function *machine =
- (struct machine_function *) xmalloc (sizeof (struct machine_function));
-
- p->machine = machine;
- machine->ra_rtx = alpha_return_addr_rtx;
+ p->machine =
+ (struct machine_function *) xcalloc (1, sizeof (struct machine_function));
}
static void
-alpha_restore_machine_status (p)
+alpha_mark_machine_status (p)
struct function *p;
{
struct machine_function *machine = p->machine;
- alpha_return_addr_rtx = machine->ra_rtx;
-
- free (machine);
- p->machine = (struct machine_function *)0;
-}
-
-/* Do anything needed before RTL is emitted for each function. */
-
-void
-alpha_init_expanders ()
-{
- alpha_return_addr_rtx = NULL_RTX;
- alpha_eh_epilogue_sp_ofs = NULL_RTX;
-
- /* Arrange to save and restore machine status around nested functions. */
- save_machine_status = alpha_save_machine_status;
- restore_machine_status = alpha_restore_machine_status;
+ ggc_mark_rtx (machine->eh_epilogue_sp_ofs);
+ ggc_mark_rtx (machine->ra_rtx);
}
/* Start the ball rolling with RETURN_ADDR_RTX. */
int count;
rtx frame ATTRIBUTE_UNUSED;
{
- rtx init;
+ rtx init, reg;
if (count != 0)
return const0_rtx;
- if (alpha_return_addr_rtx)
- return alpha_return_addr_rtx;
-
- /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
- alpha_return_addr_rtx = gen_reg_rtx (Pmode);
- init = gen_rtx_SET (VOIDmode, alpha_return_addr_rtx,
- gen_rtx_REG (Pmode, REG_RA));
-
- /* Emit the insn to the prologue with the other argument copies. */
- push_topmost_sequence ();
- emit_insn_after (init, get_insns ());
- pop_topmost_sequence ();
+ reg = current_function->machine->ra_rtx;
+ if (reg == NULL)
+ {
+ /* No rtx yet. Invent one, and initialize it from $26 in
+ the prologue. */
+ reg = gen_reg_rtx (Pmode);
+ current_function->machine->ra_rtx = reg;
+ init = gen_rtx_SET (VOIDmode, reg, gen_rtx_REG (Pmode, REG_RA));
+
+ /* Emit the insn to the prologue with the other argument copies. */
+ push_topmost_sequence ();
+ emit_insn_after (init, get_insns ());
+ pop_topmost_sequence ();
+ }
- return alpha_return_addr_rtx;
+ return reg;
}
static int
if (current_function_is_thunk)
return 0;
#endif
- if (!alpha_return_addr_rtx)
+ if (!current_function->machine->ra_rtx)
return regs_ever_live[REG_RA];
push_topmost_sequence ();
int fp_is_frame_pointer, fp_offset;
rtx sa_reg, sa_reg_exp = NULL;
rtx sp_adj1, sp_adj2, mem;
+ rtx eh_ofs;
int i;
sa_size = alpha_sa_size ();
fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
|| (!TARGET_OPEN_VMS && frame_pointer_needed));
+ eh_ofs = current_function->machine->eh_epilogue_sp_ofs;
if (sa_size)
{
/* If we have a frame pointer, restore SP from it. */
/* Restore registers in order, excepting a true frame pointer. */
- if (! alpha_eh_epilogue_sp_ofs)
+ if (! eh_ofs)
{
mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
}
}
- if (frame_size || alpha_eh_epilogue_sp_ofs)
+ if (frame_size || eh_ofs)
{
sp_adj1 = stack_pointer_rtx;
- if (alpha_eh_epilogue_sp_ofs)
+ if (eh_ofs)
{
sp_adj1 = gen_rtx_REG (DImode, 23);
emit_move_insn (sp_adj1,
- gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- alpha_eh_epilogue_sp_ofs));
+ gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
}
/* If the stack size is large, begin computation into a temporary
extern struct rtx_def *alpha_compare_op0, *alpha_compare_op1;
extern int alpha_compare_fp_p;
-/* Define the information needed to modify the epilogue for EH. */
+/* Machine specific function data. */
-extern struct rtx_def *alpha_eh_epilogue_sp_ofs;
+struct machine_function
+{
+ /* An offset to apply to the stack pointer when unwinding from EH. */
+ struct rtx_def *eh_epilogue_sp_ofs;
+
+ /* If non-null, this rtx holds the return address for the function. */
+ struct rtx_def *ra_rtx;
+};
/* Make (or fake) .linkage entry for function call.
IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
/* Before the prologue, RA lives in $26. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 26)
-
-/* Initialize data used by insn expanders. This is called from insn_emit,
- once for every function before code is generated. */
-
-#define INIT_EXPANDERS alpha_init_expanders ()
-extern void alpha_init_expanders ();
\f
/* Addressing modes, and classification of registers for them. */