libgcc2.c (ia64_throw_helper): Use __builtin_return_address.
* libgcc2.c (ia64_throw_helper): Use __builtin_return_address. (__throw): Don't pass the address of a label. * config/ia64/ia64.c (ia64_compute_frame_size): Use current_function_is_leaf. (ia64_expand_prologue): Likewise. Modify return_address_pointer_rtx instead of reg_names[RETURN_ADDRESS_REGNUM]. (ia64_init_machine_status): Reset return_address_pointer_rtx. * config/ia64/ia64.h (RETURN_ADDRESS_POINTER_REGNUM): Rename from RETURN_ADDRESS_REGNUM. Update all uses. (RETURN_ADDR_RTX): Use return_address_pointer_rtx; return zero instead of null on failure. (ELIMINABLE_REGS): Add ra->b0 elimination. (CAN_ELIMINATE): Update accordingly. (INITIAL_ELIMINATION_OFFSET): Likewise. (REGISTER_NAMES): Use an illegal assembler name for RETURN_ADDRESS_POINTER_REGNUM. From-SVN: r34531
This commit is contained in:
parent
13da91fd23
commit
46327bc509
4 changed files with 52 additions and 38 deletions
|
@ -1,3 +1,23 @@
|
|||
2000-06-13 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* libgcc2.c (ia64_throw_helper): Use __builtin_return_address.
|
||||
(__throw): Don't pass the address of a label.
|
||||
|
||||
* config/ia64/ia64.c (ia64_compute_frame_size): Use
|
||||
current_function_is_leaf.
|
||||
(ia64_expand_prologue): Likewise. Modify return_address_pointer_rtx
|
||||
instead of reg_names[RETURN_ADDRESS_REGNUM].
|
||||
(ia64_init_machine_status): Reset return_address_pointer_rtx.
|
||||
* config/ia64/ia64.h (RETURN_ADDRESS_POINTER_REGNUM): Rename
|
||||
from RETURN_ADDRESS_REGNUM. Update all uses.
|
||||
(RETURN_ADDR_RTX): Use return_address_pointer_rtx; return
|
||||
zero instead of null on failure.
|
||||
(ELIMINABLE_REGS): Add ra->b0 elimination.
|
||||
(CAN_ELIMINATE): Update accordingly.
|
||||
(INITIAL_ELIMINATION_OFFSET): Likewise.
|
||||
(REGISTER_NAMES): Use an illegal assembler name for
|
||||
RETURN_ADDRESS_POINTER_REGNUM.
|
||||
|
||||
2000-06-13 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* config/ia64/ia64.h (enum reg_class): Remove FR_INT_REGS, FR_FP_REGS,
|
||||
|
|
|
@ -607,10 +607,9 @@ ia64_compute_frame_size (size)
|
|||
total_size = IA64_STACK_ALIGN (tmp);
|
||||
extra_size = total_size - tmp + 16;
|
||||
|
||||
/* If this is a leaf routine (BR_REG (0) is not live), and if there is no
|
||||
stack space needed for register saves, then don't allocate the 16 byte
|
||||
scratch area. */
|
||||
if (total_size == 16 && ! regs_ever_live[BR_REG (0)])
|
||||
/* If this is a leaf routine, and if there is no stack space needed for
|
||||
register saves, then don't allocate the 16 byte scratch area. */
|
||||
if (total_size == 16 && current_function_is_leaf)
|
||||
{
|
||||
total_size = 0;
|
||||
extra_size = 0;
|
||||
|
@ -812,18 +811,9 @@ ia64_expand_prologue ()
|
|||
rtx insn, offset;
|
||||
int i, locals, inputs, outputs, rotates;
|
||||
int frame_size = ia64_compute_frame_size (get_frame_size ());
|
||||
int leaf_function;
|
||||
int epilogue_p;
|
||||
edge e;
|
||||
|
||||
/* ??? This seems like a leaf_function_p bug. It calls get_insns which
|
||||
returns the first insn of the current sequence, not the first insn
|
||||
of the function. We work around this by pushing to the topmost
|
||||
sequence first. */
|
||||
push_topmost_sequence ();
|
||||
leaf_function = leaf_function_p ();
|
||||
pop_topmost_sequence ();
|
||||
|
||||
/* If there is no epilogue, then we don't need some prologue insns. We
|
||||
need to avoid emitting the dead prologue insns, because flow will complain
|
||||
about them. */
|
||||
|
@ -941,7 +931,7 @@ ia64_expand_prologue ()
|
|||
locals and outputs are both zero sized. Since we have already allocated
|
||||
two locals for rp and ar.pfs, we check for two locals. */
|
||||
/* Leaf functions can use output registers as call-clobbered temporaries. */
|
||||
if (locals == 2 && outputs == 0 && leaf_function)
|
||||
if (locals == 2 && outputs == 0 && current_function_is_leaf)
|
||||
{
|
||||
/* If there is no alloc, but there are input registers used, then we
|
||||
need a .regstk directive. */
|
||||
|
@ -966,13 +956,11 @@ ia64_expand_prologue ()
|
|||
/* Emit a save of BR_REG (0) if we call other functions.
|
||||
Do this even if this function doesn't return, as EH
|
||||
depends on this to be able to unwind the stack. */
|
||||
if (! leaf_function)
|
||||
if (! current_function_is_leaf)
|
||||
{
|
||||
rtx ia64_rp_reg;
|
||||
|
||||
ia64_rp_regno = LOC_REG (locals - 2);
|
||||
reg_names[RETURN_ADDRESS_REGNUM] = reg_names[ia64_rp_regno];
|
||||
|
||||
ia64_rp_reg = gen_rtx_REG (DImode, ia64_rp_regno);
|
||||
insn = emit_move_insn (ia64_rp_reg, gen_rtx_REG (DImode,
|
||||
BR_REG (0)));
|
||||
|
@ -984,6 +972,10 @@ ia64_expand_prologue ()
|
|||
appear dead and will elicit a warning from flow. */
|
||||
emit_insn (gen_rtx_USE (VOIDmode, ia64_rp_reg));
|
||||
}
|
||||
|
||||
/* Fix up the return address placeholder. */
|
||||
if (regs_ever_live[RETURN_ADDRESS_POINTER_REGNUM])
|
||||
XINT (return_address_pointer_rtx, 0) = ia64_rp_regno;
|
||||
}
|
||||
else
|
||||
ia64_rp_regno = 0;
|
||||
|
@ -2113,6 +2105,9 @@ ia64_init_machine_status (p)
|
|||
{
|
||||
p->machine =
|
||||
(struct machine_function *) xcalloc (1, sizeof (struct machine_function));
|
||||
|
||||
/* Reset from the previous function's potential modifications. */
|
||||
XINT (return_address_pointer_rtx, 0) = RETURN_ADDRESS_POINTER_REGNUM;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -551,7 +551,7 @@ while (0)
|
|||
#define GENERAL_REGNO_P(REGNO) \
|
||||
(GR_REGNO_P (REGNO) \
|
||||
|| (REGNO) == FRAME_POINTER_REGNUM \
|
||||
|| (REGNO) == RETURN_ADDRESS_REGNUM)
|
||||
|| (REGNO) == RETURN_ADDRESS_POINTER_REGNUM)
|
||||
|
||||
#define GR_REG(REGNO) ((REGNO) + 0)
|
||||
#define FR_REG(REGNO) ((REGNO) + 128)
|
||||
|
@ -788,7 +788,7 @@ while (0)
|
|||
/* Special branch registers. */ \
|
||||
R_BR (0), \
|
||||
/* Frame pointer. Return address. */ \
|
||||
FRAME_POINTER_REGNUM, RETURN_ADDRESS_REGNUM, \
|
||||
FRAME_POINTER_REGNUM, RETURN_ADDRESS_POINTER_REGNUM, \
|
||||
}
|
||||
|
||||
|
||||
|
@ -1110,13 +1110,8 @@ enum reg_class
|
|||
unwind info, so we don't try to support them. We would also need to define
|
||||
DYNAMIC_CHAIN_ADDRESS and SETUP_FRAME_ADDRESS (for the reg stack flush). */
|
||||
|
||||
/* ??? This only works for non-leaf functions. In a leaf function, the return
|
||||
address would be in b0 (rp). */
|
||||
|
||||
#define RETURN_ADDR_RTX(COUNT, FRAMEADDR) \
|
||||
(((COUNT) == 0) \
|
||||
? gen_rtx_REG (Pmode, RETURN_ADDRESS_REGNUM) \
|
||||
: (rtx) 0)
|
||||
#define RETURN_ADDR_RTX(COUNT, FRAME) \
|
||||
((COUNT) == 0 ? return_address_pointer_rtx : const0_rtx)
|
||||
|
||||
/* A C expression whose value is RTL representing the location of the incoming
|
||||
return address at the beginning of any function, before the prologue. This
|
||||
|
@ -1177,10 +1172,12 @@ extern int ia64_local_regs;
|
|||
in it. */
|
||||
#define ARG_POINTER_REGNUM R_GR(0)
|
||||
|
||||
/* The register number for the return address register. This is modified by
|
||||
ia64_expand_prologue to point to the real return address save register. */
|
||||
/* The register number for the return address register. This is not actually
|
||||
a pointer as the name suggests, but that's a name that gen_rtx_REG
|
||||
already takes care to keep unique. We modify return_address_pointer_rtx
|
||||
in ia64_expand_prologue to reference the final output regnum. */
|
||||
|
||||
#define RETURN_ADDRESS_REGNUM 329
|
||||
#define RETURN_ADDRESS_POINTER_REGNUM 329
|
||||
|
||||
/* Register numbers used for passing a function's static chain pointer. */
|
||||
|
||||
|
@ -1202,14 +1199,15 @@ extern int ia64_local_regs;
|
|||
{ \
|
||||
{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
|
||||
{ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
|
||||
{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
|
||||
{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
|
||||
{RETURN_ADDRESS_POINTER_REGNUM, BR_REG (0)} \
|
||||
}
|
||||
|
||||
/* A C expression that returns non-zero if the compiler is allowed to try to
|
||||
replace register number FROM with register number TO. There are no ia64
|
||||
specific restrictions. */
|
||||
replace register number FROM with register number TO. */
|
||||
|
||||
#define CAN_ELIMINATE(FROM, TO) 1
|
||||
#define CAN_ELIMINATE(FROM, TO) \
|
||||
(TO == BR_REG (0) ? current_function_is_leaf : 1)
|
||||
|
||||
/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
|
||||
initial difference between the specified pair of registers. This macro must
|
||||
|
@ -1238,6 +1236,8 @@ extern int ia64_local_regs;
|
|||
abort (); \
|
||||
} \
|
||||
} \
|
||||
else if ((TO) == BR_REG (0)) \
|
||||
(OFFSET) = 0; \
|
||||
else \
|
||||
abort (); \
|
||||
}
|
||||
|
@ -2324,7 +2324,7 @@ do { \
|
|||
/* Branch registers. */ \
|
||||
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", \
|
||||
/* Frame pointer. Return address. */ \
|
||||
"fp", "ra" \
|
||||
"sfp", "retaddr" \
|
||||
}
|
||||
|
||||
/* If defined, a C initializer for an array of structures containing a name and
|
||||
|
|
|
@ -4043,12 +4043,12 @@ __ia64_personality_v1 (void *pc, old_exception_table *table)
|
|||
}
|
||||
|
||||
static void
|
||||
ia64_throw_helper (throw_pc, throw_frame, caller, throw_bsp)
|
||||
void *throw_pc;
|
||||
ia64_throw_helper (throw_frame, caller, throw_bsp)
|
||||
ia64_frame_state *throw_frame;
|
||||
ia64_frame_state *caller;
|
||||
void *throw_bsp;
|
||||
{
|
||||
void *throw_pc = __builtin_return_address (0);
|
||||
unwind_info_ptr *info;
|
||||
void *pc, *handler = NULL;
|
||||
void *pc_base;
|
||||
|
@ -4146,7 +4146,6 @@ __throw ()
|
|||
__terminate ();
|
||||
|
||||
__builtin_unwind_init ();
|
||||
label_ia64:
|
||||
/* We have to call another routine to actually process the frame
|
||||
information, which will force all of __throw's local registers into
|
||||
backing store. */
|
||||
|
@ -4154,7 +4153,7 @@ label_ia64:
|
|||
/* Get the value of ar.bsp while we're here. */
|
||||
|
||||
bsp = __builtin_ia64_bsp ();
|
||||
ia64_throw_helper (&&label_ia64, &my_frame, &originator, bsp);
|
||||
ia64_throw_helper (&my_frame, &originator, bsp);
|
||||
|
||||
/* Now we have to fudge the bsp by the amount in our (__throw)
|
||||
frame marker, since the return is going to adjust it by that much. */
|
||||
|
|
Loading…
Add table
Reference in a new issue