This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: pa.c clean-up
- To: Jeffrey A Law <law at redhat dot com>
- Subject: Re: pa.c clean-up
- From: Alan Modra <alan at linuxcare dot com dot au>
- Date: Thu, 1 Feb 2001 22:41:57 +1100 (EST)
- cc: gcc-patches at gcc dot gnu dot org
On Wed, 31 Jan 2001, Jeffrey A Law wrote:
> The stuff for compiler warnings and formatting fixes should be a separate
> patch.
OK, that's gone. I've also removed the unnecessary blockages in
hppa_expand_prologue, just keeping the vital one for stores via fp.
* pa.c (hppa_expand_prologue): Simplify code storing return
pointer. For large (>=8k) frames with a post_store, adjust stack
pointer by 8k-64 first rather than by 64. When testing with
VAL_14_BITS_P, always use the actual value rather than the value
negated. Add blockage to prevent scheduling of spills before
stack frame has been created.
(hppa_expand_epilogue): Simplify code loading return pointer.
Allow a slightly larger range for merge_sp_adjust_with_load case.
When testing with VAL_14_BITS_P, always use the actual value.
Alan Modra
--
Linuxcare.
diff -crp -xCVS -x*~ egcs/gcc/config/pa/pa.c newegcs/gcc/config/pa/pa.c
*** egcs/gcc/config/pa/pa.c Thu Feb 1 15:33:49 2001
--- newegcs/gcc/config/pa/pa.c Thu Feb 1 21:59:55 2001
*************** hppa_expand_prologue()
*** 2988,3057 ****
/* Save RP first. The calling conventions manual states RP will
always be stored into the caller's frame at sp-20 or sp - 16
depending on which ABI is in use. */
! if ((regs_ever_live[2] || profile_flag) && TARGET_64BIT)
! store_reg (2, -16, STACK_POINTER_REGNUM);
!
! if ((regs_ever_live[2] || profile_flag) && ! TARGET_64BIT)
! store_reg (2, -20, STACK_POINTER_REGNUM);
/* Allocate the local frame and set up the frame pointer if needed. */
! if (actual_fsize)
! {
! if (frame_pointer_needed)
! {
! /* Copy the old frame pointer temporarily into %r1. Set up the
! new stack pointer, then store away the saved old frame pointer
! into the stack at sp+actual_fsize and at the same time update
! the stack pointer by actual_fsize bytes. Two versions, first
! handles small (<8k) frames. The second handles large (>8k)
! frames. */
! emit_move_insn (tmpreg, frame_pointer_rtx);
! emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
! if (VAL_14_BITS_P (actual_fsize))
! emit_insn (gen_post_store (stack_pointer_rtx, tmpreg, size_rtx));
! else
! {
! /* It is incorrect to store the saved frame pointer at *sp,
! then increment sp (writes beyond the current stack boundary).
! So instead use stwm to store at *sp and post-increment the
! stack pointer as an atomic operation. Then increment sp to
! finish allocating the new frame. */
! emit_insn (gen_post_store (stack_pointer_rtx, tmpreg,
! GEN_INT (64)));
set_reg_plus_d (STACK_POINTER_REGNUM,
STACK_POINTER_REGNUM,
! actual_fsize - 64);
! }
! }
! /* no frame pointer needed. */
! else
! {
! /* In some cases we can perform the first callee register save
! and allocating the stack frame at the same time. If so, just
! make a note of it and defer allocating the frame until saving
! the callee registers. */
! if (VAL_14_BITS_P (-actual_fsize)
! && local_fsize == 0
! && ! profile_flag
! && ! flag_pic)
! merge_sp_adjust_with_store = 1;
! /* Can not optimize. Adjust the stack frame by actual_fsize bytes. */
! else if (actual_fsize != 0)
! set_reg_plus_d (STACK_POINTER_REGNUM,
! STACK_POINTER_REGNUM,
! actual_fsize);
! }
! }
!
! /* The hppa calling conventions say that %r19, the pic offset
! register, is saved at sp - 32 (in this function's frame) when
! generating PIC code. FIXME: What is the correct thing to do
! for functions which make no calls and allocate no frame? Do
! we need to allocate a frame, or can we just omit the save? For
! now we'll just omit the save. */
! if (actual_fsize != 0 && flag_pic && !TARGET_64BIT)
! store_reg (PIC_OFFSET_TABLE_REGNUM, -32, STACK_POINTER_REGNUM);
/* Profiling code.
--- 2988,3062 ----
/* Save RP first. The calling conventions manual states RP will
always be stored into the caller's frame at sp-20 or sp - 16
depending on which ABI is in use. */
! if (regs_ever_live[2] || profile_flag)
! store_reg (2, TARGET_64BIT ? -16 : -20, STACK_POINTER_REGNUM);
/* Allocate the local frame and set up the frame pointer if needed. */
! if (actual_fsize != 0)
! {
! if (frame_pointer_needed)
! {
! /* Copy the old frame pointer temporarily into %r1. Set up the
! new stack pointer, then store away the saved old frame pointer
! into the stack at sp+actual_fsize and at the same time update
! the stack pointer by actual_fsize bytes. Two versions, first
! handles small (<8k) frames. The second handles large (>=8k)
! frames. */
! emit_move_insn (tmpreg, frame_pointer_rtx);
! emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
! if (VAL_14_BITS_P (actual_fsize))
! emit_insn (gen_post_store (stack_pointer_rtx, tmpreg, size_rtx));
! else
! {
! /* It is incorrect to store the saved frame pointer at *sp,
! then increment sp (writes beyond the current stack boundary).
! So instead use stwm to store at *sp and post-increment the
! stack pointer as an atomic operation. Then increment sp to
! finish allocating the new frame. */
! int adjust1 = 8192 - 64;
! int adjust2 = actual_fsize - adjust1;
! rtx delta = GEN_INT (adjust1);
! emit_insn (gen_post_store (stack_pointer_rtx, tmpreg, delta));
! set_reg_plus_d (STACK_POINTER_REGNUM,
! STACK_POINTER_REGNUM,
! adjust2);
! }
! /* Prevent register spills from being scheduled before the
! stack pointer is raised. Necessary as we will be storing
! registers using the frame pointer as a base register, and
! we happen to set fp before raising sp. */
! emit_insn (gen_blockage ());
! }
! /* no frame pointer needed. */
! else
! {
! /* In some cases we can perform the first callee register save
! and allocating the stack frame at the same time. If so, just
! make a note of it and defer allocating the frame until saving
! the callee registers. */
! if (VAL_14_BITS_P (actual_fsize)
! && local_fsize == 0
! && ! profile_flag
! && ! flag_pic)
! merge_sp_adjust_with_store = 1;
! /* Can not optimize. Adjust the stack frame by actual_fsize
! bytes. */
! else
set_reg_plus_d (STACK_POINTER_REGNUM,
STACK_POINTER_REGNUM,
! actual_fsize);
! }
!
! /* The hppa calling conventions say that %r19, the pic offset
! register, is saved at sp - 32 (in this function's frame)
! when generating PIC code. FIXME: What is the correct thing
! to do for functions which make no calls and allocate no
! frame? Do we need to allocate a frame, or can we just omit
! the save? For now we'll just omit the save. */
! if (flag_pic && !TARGET_64BIT)
! store_reg (PIC_OFFSET_TABLE_REGNUM, -32, STACK_POINTER_REGNUM);
! }
/* Profiling code.
*************** void
*** 3225,3232 ****
hppa_expand_epilogue ()
{
rtx tmpreg;
! int offset,i;
! int merge_sp_adjust_with_load = 0;
/* We will use this often. */
tmpreg = gen_rtx_REG (word_mode, 1);
--- 3230,3238 ----
hppa_expand_epilogue ()
{
rtx tmpreg;
! int offset, i;
! int merge_sp_adjust_with_load = 0;
! int ret_off = 0;
/* We will use this often. */
tmpreg = gen_rtx_REG (word_mode, 1);
*************** hppa_expand_epilogue ()
*** 3234,3256 ****
/* 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 (frame_pointer_needed
! && !TARGET_64BIT
! && (regs_ever_live [2] || profile_flag))
! load_reg (2, -20, FRAME_POINTER_REGNUM);
! else if (TARGET_64BIT && frame_pointer_needed
! && (regs_ever_live[2] || profile_flag))
! load_reg (2, -16, FRAME_POINTER_REGNUM);
! else if (TARGET_64BIT
! && ! frame_pointer_needed
! && (regs_ever_live[2] || profile_flag)
! && VAL_14_BITS_P (actual_fsize + 20))
! load_reg (2, - (actual_fsize + 16), STACK_POINTER_REGNUM);
! /* No frame pointer, and stack is smaller than 8k. */
! else if (! frame_pointer_needed
! && VAL_14_BITS_P (actual_fsize + 20)
! && (regs_ever_live[2] || profile_flag))
! load_reg (2, - (actual_fsize + 20), STACK_POINTER_REGNUM);
/* General register restores. */
if (frame_pointer_needed)
--- 3240,3263 ----
/* 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 (regs_ever_live [2] || profile_flag)
! {
! ret_off = TARGET_64BIT ? -16 : -20;
! if (frame_pointer_needed)
! {
! load_reg (2, ret_off, FRAME_POINTER_REGNUM);
! ret_off = 0;
! }
! else
! {
! /* No frame pointer, and stack is smaller than 8k. */
! if (VAL_14_BITS_P (ret_off - actual_fsize))
! {
! load_reg (2, ret_off - actual_fsize, STACK_POINTER_REGNUM);
! ret_off = 0;
! }
! }
! }
/* General register restores. */
if (frame_pointer_needed)
*************** hppa_expand_epilogue ()
*** 3271,3279 ****
/* Only for the first load.
merge_sp_adjust_with_load holds the register load
with which we will merge the sp adjustment. */
! if (VAL_14_BITS_P (actual_fsize + 20)
&& local_fsize == 0
! && ! merge_sp_adjust_with_load)
merge_sp_adjust_with_load = i;
else
load_reg (i, offset, STACK_POINTER_REGNUM);
--- 3278,3286 ----
/* Only for the first load.
merge_sp_adjust_with_load holds the register load
with which we will merge the sp adjustment. */
! if (merge_sp_adjust_with_load == 0
&& local_fsize == 0
! && VAL_14_BITS_P (-actual_fsize))
merge_sp_adjust_with_load = i;
else
load_reg (i, offset, STACK_POINTER_REGNUM);
*************** hppa_expand_epilogue ()
*** 3313,3359 ****
This is necessary as we must not cut the stack back before all the
restores are finished. */
emit_insn (gen_blockage ());
- /* No frame pointer, but we have a stack greater than 8k. We restore
- %r2 very late in this case. (All other cases are restored as early
- as possible.) */
- if (! frame_pointer_needed
- && ! VAL_14_BITS_P (actual_fsize + 20)
- && ! TARGET_64BIT
- && (regs_ever_live[2] || profile_flag))
- {
- set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- - actual_fsize);
-
- /* This used to try and be clever by not depending on the value in
- %r30 and instead use the value held in %r1 (so that the 2nd insn
- which sets %r30 could be put in the delay slot of the return insn).
-
- That won't work since if the stack is exactly 8k set_reg_plus_d
- doesn't set %r1, just %r30. */
- load_reg (2, - 20, STACK_POINTER_REGNUM);
- }
- else if (! frame_pointer_needed
- && ! VAL_14_BITS_P (actual_fsize + 20)
- && TARGET_64BIT
- && (regs_ever_live[2] || profile_flag))
- {
- set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- - actual_fsize);
-
- /* This used to try and be clever by not depending on the value in
- %r30 and instead use the value held in %r1 (so that the 2nd insn
- which sets %r30 could be put in the delay slot of the return insn).
-
- That won't work since if the stack is exactly 8k set_reg_plus_d
- doesn't set %r1, just %r30. */
- load_reg (2, - 16, STACK_POINTER_REGNUM);
- }
/* Reset stack pointer (and possibly frame pointer). The stack
pointer is initially set to fp + 64 to avoid a race condition. */
! else if (frame_pointer_needed)
{
set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
emit_insn (gen_pre_load (frame_pointer_rtx,
--- 3320,3329 ----
This is necessary as we must not cut the stack back before all the
restores are finished. */
emit_insn (gen_blockage ());
/* Reset stack pointer (and possibly frame pointer). The stack
pointer is initially set to fp + 64 to avoid a race condition. */
! if (frame_pointer_needed)
{
set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
emit_insn (gen_pre_load (frame_pointer_rtx,
*************** hppa_expand_epilogue ()
*** 3361,3374 ****
GEN_INT (-64)));
}
/* If we were deferring a callee register restore, do it now. */
! else if (! frame_pointer_needed && merge_sp_adjust_with_load)
! emit_insn (gen_pre_load (gen_rtx_REG (word_mode, merge_sp_adjust_with_load),
! stack_pointer_rtx,
! GEN_INT (- actual_fsize)));
else if (actual_fsize != 0)
! set_reg_plus_d (STACK_POINTER_REGNUM,
! STACK_POINTER_REGNUM,
! - actual_fsize);
}
/* Set up a callee saved register for the pic offset table register. */
--- 3331,3355 ----
GEN_INT (-64)));
}
/* If we were deferring a callee register restore, do it now. */
! else if (merge_sp_adjust_with_load)
! {
! rtx delta = GEN_INT (-actual_fsize);
! emit_insn (gen_pre_load (gen_rtx_REG (word_mode,
! merge_sp_adjust_with_load),
! stack_pointer_rtx,
! delta));
! }
else if (actual_fsize != 0)
! {
! set_reg_plus_d (STACK_POINTER_REGNUM,
! STACK_POINTER_REGNUM,
! - actual_fsize);
! }
!
! /* If we haven't restored %r2 yet (no frame pointer, and a stack
! frame greater than 8k), do so now. */
! if (ret_off != 0)
! load_reg (2, ret_off, STACK_POINTER_REGNUM);
}
/* Set up a callee saved register for the pic offset table register. */