diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.c | 29 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.h | 34 | ||||
-rw-r--r-- | gcc/libgcc2.c | 7 |
4 files changed, 52 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 299ffd6..54b253d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,25 @@ 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, GR_AND_FR_INT_REGS, GR_AND_FR_FP_REGS. (REG_CLASS_NAMES): Likewise. diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 8357e2c..88aa7d2 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -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 diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 08a2c8b..0dadc51 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -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 diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c index 305d7f0..06c6fdd 100644 --- a/gcc/libgcc2.c +++ b/gcc/libgcc2.c @@ -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. */ |