rs6000.h (INIT_EXPANDERS): Delete.
2001-01-22 Franz Sirl <Franz.Sirl-kernel@lauterbach.com> * rs6000.h (INIT_EXPANDERS): Delete. (RETURN_ADDR_RTX): Call rs6000_return_addr(). * rs6000.c (rs6000_override_options): Call *_machine_status from here... (rs6000_init_expanders): ...instead of here. Delete. (rs6000_mark_machine_status): New function. (rs6000_init_machine_status): Use xcalloc. (rs6000_return_addr): Generate RTX for the return address. (rs6000_ra_ever_killed): New, check if LR was ever destroyed. (rs6000_stack_info): Use it. From-SVN: r39188
This commit is contained in:
parent
5dab7f92ce
commit
71f123ca19
3 changed files with 103 additions and 32 deletions
|
@ -1,3 +1,16 @@
|
|||
2001-01-22 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
|
||||
* rs6000.h (INIT_EXPANDERS): Delete.
|
||||
(RETURN_ADDR_RTX): Call rs6000_return_addr().
|
||||
* rs6000.c (rs6000_override_options): Call *_machine_status from
|
||||
here...
|
||||
(rs6000_init_expanders): ...instead of here. Delete.
|
||||
(rs6000_mark_machine_status): New function.
|
||||
(rs6000_init_machine_status): Use xcalloc.
|
||||
(rs6000_return_addr): Generate RTX for the return address.
|
||||
(rs6000_ra_ever_killed): New, check if LR was ever destroyed.
|
||||
(rs6000_stack_info): Use it.
|
||||
|
||||
2001-01-22 Thomas Pfaff <tpfaff@gmx.net>
|
||||
|
||||
* gthr-win32.h: Include errno.h to get a declaration for
|
||||
|
|
|
@ -122,6 +122,8 @@ static void toc_hash_mark_table PARAMS ((void *));
|
|||
static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
|
||||
static void rs6000_free_machine_status PARAMS ((struct function *));
|
||||
static void rs6000_init_machine_status PARAMS ((struct function *));
|
||||
static void rs6000_mark_machine_status PARAMS ((struct function *));
|
||||
static int rs6000_ra_ever_killed PARAMS ((void));
|
||||
|
||||
/* Default register names. */
|
||||
char rs6000_reg_names[][8] =
|
||||
|
@ -399,6 +401,11 @@ rs6000_override_options (default_cpu)
|
|||
|
||||
if (TARGET_TOC)
|
||||
ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
|
||||
|
||||
/* Arrange to save and restore machine status around nested functions. */
|
||||
init_machine_status = rs6000_init_machine_status;
|
||||
mark_machine_status = rs6000_mark_machine_status;
|
||||
free_machine_status = rs6000_free_machine_status;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3619,7 +3626,7 @@ rs6000_got_register (value)
|
|||
return pic_offset_table_rtx;
|
||||
}
|
||||
|
||||
/* Functions to save and restore sysv_varargs_p.
|
||||
/* Functions to init, mark and free struct machine_function.
|
||||
These will be called, via pointer variables,
|
||||
from push_function_context and pop_function_context. */
|
||||
|
||||
|
@ -3627,9 +3634,15 @@ static void
|
|||
rs6000_init_machine_status (p)
|
||||
struct function *p;
|
||||
{
|
||||
p->machine = (machine_function *) xmalloc (sizeof (machine_function));
|
||||
p->machine = (machine_function *) xcalloc (1, sizeof (machine_function));
|
||||
}
|
||||
|
||||
p->machine->sysv_varargs_p = 0;
|
||||
static void
|
||||
rs6000_mark_machine_status (p)
|
||||
struct function *p;
|
||||
{
|
||||
if (p->machine)
|
||||
ggc_mark_rtx (p->machine->ra_rtx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3643,17 +3656,6 @@ rs6000_free_machine_status (p)
|
|||
p->machine = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Do anything needed before RTL is emitted for each function. */
|
||||
|
||||
void
|
||||
rs6000_init_expanders ()
|
||||
{
|
||||
/* Arrange to save and restore machine status around nested functions. */
|
||||
init_machine_status = rs6000_init_machine_status;
|
||||
free_machine_status = rs6000_free_machine_status;
|
||||
}
|
||||
|
||||
|
||||
/* Print an operand. Recognize special options, documented below. */
|
||||
|
||||
|
@ -4824,10 +4826,11 @@ rs6000_stack_info ()
|
|||
info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
|
||||
|
||||
/* Does this function call anything? */
|
||||
info_ptr->calls_p = ! current_function_is_leaf;
|
||||
info_ptr->calls_p = (! current_function_is_leaf
|
||||
|| cfun->machine->ra_needs_full_frame);
|
||||
|
||||
/* Determine if we need to save the link register */
|
||||
if (regs_ever_live[LINK_REGISTER_REGNUM]
|
||||
if (rs6000_ra_ever_killed ()
|
||||
|| (DEFAULT_ABI == ABI_AIX && profile_flag)
|
||||
#ifdef TARGET_RELOCATABLE
|
||||
|| (TARGET_RELOCATABLE && (get_pool_size () != 0))
|
||||
|
@ -5043,6 +5046,66 @@ debug_stack_info (info)
|
|||
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
rtx
|
||||
rs6000_return_addr (count, frame)
|
||||
int count;
|
||||
rtx frame;
|
||||
{
|
||||
rtx init, reg;
|
||||
|
||||
/* Currently we don't optimize very well between prolog and body code and
|
||||
for PIC code the code can be actually quite bad, so don't try to be
|
||||
too clever here. */
|
||||
if (count != 0 || flag_pic != 0)
|
||||
{
|
||||
cfun->machine->ra_needs_full_frame = 1;
|
||||
return
|
||||
gen_rtx_MEM (Pmode,
|
||||
memory_address (Pmode,
|
||||
plus_constant (copy_to_reg (gen_rtx_MEM (Pmode,
|
||||
memory_address (Pmode, frame))),
|
||||
RETURN_ADDRESS_OFFSET)));
|
||||
}
|
||||
|
||||
reg = cfun->machine->ra_rtx;
|
||||
if (reg == NULL)
|
||||
{
|
||||
/* No rtx yet. Invent one, and initialize it from LR in
|
||||
the prologue. */
|
||||
reg = gen_reg_rtx (Pmode);
|
||||
cfun->machine->ra_rtx = reg;
|
||||
init = gen_rtx_SET (VOIDmode, reg,
|
||||
gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
|
||||
|
||||
/* Emit the insn to the prologue with the other argument copies. */
|
||||
push_topmost_sequence ();
|
||||
emit_insn_after (init, get_insns ());
|
||||
pop_topmost_sequence ();
|
||||
}
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
static int
|
||||
rs6000_ra_ever_killed ()
|
||||
{
|
||||
rtx top;
|
||||
|
||||
#ifdef ASM_OUTPUT_MI_THUNK
|
||||
if (current_function_is_thunk)
|
||||
return 0;
|
||||
#endif
|
||||
if (!cfun->machine->ra_rtx || cfun->machine->ra_needs_full_frame)
|
||||
return regs_ever_live[LINK_REGISTER_REGNUM];
|
||||
|
||||
push_topmost_sequence ();
|
||||
top = get_insns ();
|
||||
pop_topmost_sequence ();
|
||||
|
||||
return reg_set_between_p (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
|
||||
top, NULL_RTX);
|
||||
}
|
||||
|
||||
/* Add a REG_MAYBE_DEAD note to the insn. */
|
||||
static void
|
||||
|
@ -5553,7 +5616,7 @@ rs6000_emit_prologue()
|
|||
|
||||
/* If we use the link register, get it into r0. */
|
||||
if (info->lr_save_p)
|
||||
emit_move_insn (gen_rtx_REG (Pmode, 0),
|
||||
emit_move_insn (gen_rtx_REG (Pmode, 0),
|
||||
gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
|
||||
|
||||
/* If we need to save CR, put it into r12. */
|
||||
|
|
|
@ -1229,10 +1229,6 @@ typedef struct rs6000_stack {
|
|||
/* Align an address */
|
||||
#define RS6000_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1))
|
||||
|
||||
/* Initialize data used by insn expanders. This is called from
|
||||
init_emit, once for each function, before code is generated. */
|
||||
#define INIT_EXPANDERS rs6000_init_expanders ()
|
||||
|
||||
/* Size of V.4 varargs area in bytes */
|
||||
#define RS6000_VARARGS_SIZE \
|
||||
((GP_ARG_NUM_REG * (TARGET_32BIT ? 4 : 8)) + (FP_ARG_NUM_REG * 8) + 8)
|
||||
|
@ -1388,6 +1384,10 @@ typedef struct machine_function
|
|||
{
|
||||
/* Whether a System V.4 varargs area was created. */
|
||||
int sysv_varargs_p;
|
||||
/* Set if a return address rtx for loading from LR was created. */
|
||||
struct rtx_def *ra_rtx;
|
||||
/* Flags if __builtin_return_address (n) with n >= 1 was used. */
|
||||
int ra_needs_full_frame;
|
||||
} machine_function;
|
||||
|
||||
/* Define a data type for recording info about an argument list
|
||||
|
@ -1649,17 +1649,12 @@ typedef struct rs6000_args
|
|||
/* The current return address is in link register (65). The return address
|
||||
of anything farther back is accessed normally at an offset of 8 from the
|
||||
frame pointer. */
|
||||
#define RETURN_ADDR_RTX(COUNT, FRAME) \
|
||||
(((COUNT) == -1) \
|
||||
? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) \
|
||||
: gen_rtx_MEM (Pmode, \
|
||||
memory_address \
|
||||
(Pmode, \
|
||||
plus_constant (copy_to_reg \
|
||||
(gen_rtx_MEM (Pmode, \
|
||||
memory_address (Pmode, \
|
||||
(FRAME)))), \
|
||||
RETURN_ADDRESS_OFFSET))))
|
||||
#define RETURN_ADDR_RTX(COUNT, FRAME) \
|
||||
(rs6000_return_addr (COUNT, FRAME))
|
||||
|
||||
extern struct rtx_def* rs6000_return_addr (int, struct rtx_def *rtx);
|
||||
|
||||
|
||||
|
||||
/* Definitions for register eliminations.
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue