This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix for frame note handling under hppa-linux
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 4 Feb 2002 17:59:35 -0500 (EST)
- Subject: Fix for frame note handling under hppa-linux
This patch fixes a number of problems with the frame note code used only
under hppa-linux. It is needed to bootstrap with the current main branch.
The first problem fixed is a temporary register was used for the floating
spills. The insn setting the temporary register previously had a frame
note. This insn would get scheduled before some of the general register
saves and this confused dwarf2out. I solved this by not adding a note
to the temporary register copy and appending an expression list to each
floating point spill indicating what was being saved and where.
A different but related problem occured with large frames. Here I found
that dwarf2out couldn't track the HIGH/LO_SUM insns needed for large frames.
So, again an expression list was needed to handle the situation. This
required a rewrite to store_reg.
Finally, the stuff in hppa_expand_epilogue although disabled clearly
didn't work. I removed notes from register restores. The only remaining
note is the final stack adjust.
Tested under hppa-linux and hppa2.0w-hp-hpux11.11. No regressions were
noted under hppa2.0w-hp-hpux11.11. There is no previous benchmark for
hppa-linux test results as it didn't bootstrap before.
Dave
--
J. David Anglin dave.anglin@nrc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6605)
2002-02-04 John David Anglin <dave@hiauly1.hia.nrc.ca>
* pa.c (DO_FRAME_NOTES): Move forward.
(store_reg): Revise handling of frame notes.
(load_reg): Likewise.
(set_reg_plus_d): Likewise.
(hppa_expand_prologue): Likewise.
(hppa_expand_epilogue): Likewise.
--- pa.c.orig Tue Jan 22 01:23:17 2002
+++ pa.c Sat Jan 26 02:52:49 2002
@@ -55,6 +55,18 @@
#endif
#endif
+#if DO_FRAME_NOTES
+#define FRP(INSN) \
+ do \
+ { \
+ rtx insn = INSN; \
+ RTX_FRAME_RELATED_P (insn) = 1; \
+ } \
+ while (0)
+#else
+#define FRP(INSN) INSN
+#endif
+
#ifndef FUNC_BEGIN_PROLOG_LABEL
#define FUNC_BEGIN_PROLOG_LABEL "LFBP"
#endif
@@ -70,9 +82,9 @@
static int compute_movstrsi_length PARAMS ((rtx));
static bool pa_assemble_integer PARAMS ((rtx, unsigned int, int));
static void remove_useless_addtr_insns PARAMS ((rtx, int));
-static rtx store_reg PARAMS ((int, int, int));
-static rtx load_reg PARAMS ((int, int, int));
-static rtx set_reg_plus_d PARAMS ((int, int, int));
+static void store_reg PARAMS ((int, int, int));
+static void load_reg PARAMS ((int, int, int));
+static void set_reg_plus_d PARAMS ((int, int, int));
static void pa_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static int pa_adjust_cost PARAMS ((rtx, rtx, rtx, int));
static int pa_adjust_priority PARAMS ((rtx, int));
@@ -2879,18 +2891,18 @@
Note in DISP > 8k case, we will leave the high part of the address
in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
-static rtx
+static void
store_reg (reg, disp, base)
int reg, disp, base;
{
- rtx i, dest, src, basereg;
+ rtx insn, dest, src, basereg;
src = gen_rtx_REG (word_mode, reg);
basereg = gen_rtx_REG (Pmode, base);
if (VAL_14_BITS_P (disp))
{
dest = gen_rtx_MEM (word_mode, plus_constant (basereg, disp));
- i = emit_move_insn (dest, src);
+ insn = emit_move_insn (dest, src);
}
else
{
@@ -2899,9 +2911,22 @@
rtx tmpreg = gen_rtx_REG (Pmode, 1);
emit_move_insn (tmpreg, high);
dest = gen_rtx_MEM (word_mode, gen_rtx_LO_SUM (Pmode, tmpreg, delta));
- i = emit_move_insn (dest, src);
+ insn = emit_move_insn (dest, src);
+ if (DO_FRAME_NOTES)
+ {
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode,
+ gen_rtx_MEM (word_mode,
+ gen_rtx_PLUS (word_mode, basereg,
+ delta)),
+ src),
+ REG_NOTES (insn));
+ }
}
- return i;
+
+ if (DO_FRAME_NOTES)
+ RTX_FRAME_RELATED_P (insn) = 1;
}
/* Emit RTL to set REG to the value specified by BASE+DISP.
@@ -2910,28 +2935,32 @@
Note in DISP > 8k case, we will leave the high part of the address
in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
-static rtx
+static void
set_reg_plus_d (reg, base, disp)
int reg, base, disp;
{
- rtx i;
+ rtx insn;
if (VAL_14_BITS_P (disp))
{
- i = emit_move_insn (gen_rtx_REG (Pmode, reg),
- plus_constant (gen_rtx_REG (Pmode, base), disp));
+ insn = emit_move_insn (gen_rtx_REG (Pmode, reg),
+ plus_constant (gen_rtx_REG (Pmode, base), disp));
}
else
{
+ rtx basereg = gen_rtx_REG (Pmode, base);
rtx delta = GEN_INT (disp);
+
emit_move_insn (gen_rtx_REG (Pmode, 1),
- gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, base),
+ gen_rtx_PLUS (Pmode, basereg,
gen_rtx_HIGH (Pmode, delta)));
- i = emit_move_insn (gen_rtx_REG (Pmode, reg),
- gen_rtx_LO_SUM (Pmode, gen_rtx_REG (Pmode, 1),
- delta));
+ insn = emit_move_insn (gen_rtx_REG (Pmode, reg),
+ gen_rtx_LO_SUM (Pmode, gen_rtx_REG (Pmode, 1),
+ delta));
}
- return i;
+
+ if (DO_FRAME_NOTES && reg == STACK_POINTER_REGNUM)
+ RTX_FRAME_RELATED_P (insn) = 1;
}
int
@@ -3069,18 +3098,6 @@
remove_useless_addtr_insns (get_insns (), 0);
}
-#if DO_FRAME_NOTES
-#define FRP(INSN) \
- do \
- { \
- rtx insn = INSN; \
- RTX_FRAME_RELATED_P (insn) = 1; \
- } \
- while (0)
-#else
-#define FRP(INSN) INSN
-#endif
-
void
hppa_expand_prologue ()
{
@@ -3111,7 +3128,7 @@
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])
- FRP (store_reg (2, TARGET_64BIT ? -16 : -20, STACK_POINTER_REGNUM));
+ 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)
@@ -3183,9 +3200,8 @@
REG_NOTES (insn));
}
- FRP (set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- adjust2));
+ 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
@@ -3205,9 +3221,8 @@
/* Can not optimize. Adjust the stack frame by actual_fsize
bytes. */
else
- FRP (set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- actual_fsize));
+ set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM,
+ actual_fsize);
}
}
@@ -3220,7 +3235,7 @@
for (i = 18, offset = local_fsize; i >= 4; i--)
if (regs_ever_live[i] && ! call_used_regs[i])
{
- FRP (store_reg (i, offset, FRAME_POINTER_REGNUM));
+ store_reg (i, offset, FRAME_POINTER_REGNUM);
offset += UNITS_PER_WORD;
gr_saved++;
}
@@ -3244,7 +3259,7 @@
delta)));
}
else
- FRP (store_reg (i, offset, STACK_POINTER_REGNUM));
+ store_reg (i, offset, STACK_POINTER_REGNUM);
offset += UNITS_PER_WORD;
gr_saved++;
}
@@ -3252,9 +3267,8 @@
/* If we wanted to merge the SP adjustment with a GR save, but we never
did any GR saves, then just emit the adjustment here. */
if (merge_sp_adjust_with_store)
- FRP (set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- actual_fsize));
+ set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM,
+ actual_fsize);
}
/* The hppa calling conventions say that %r19, the pic offset
@@ -3275,9 +3289,9 @@
/* First get the frame or stack pointer to the start of the FP register
save area. */
if (frame_pointer_needed)
- FRP (set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset));
+ set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
else
- FRP (set_reg_plus_d (1, STACK_POINTER_REGNUM, offset));
+ set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
/* Now actually save the FP registers. */
for (i = FP_SAVED_REG_LAST; i >= FP_SAVED_REG_FIRST; i -= FP_REG_STEP)
@@ -3285,37 +3299,44 @@
if (regs_ever_live[i]
|| (! TARGET_64BIT && regs_ever_live[i + 1]))
{
- rtx addr, reg;
+ rtx addr, insn, reg;
addr = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (DFmode, tmpreg));
reg = gen_rtx_REG (DFmode, i);
- FRP (emit_move_insn (addr, reg));
+ insn = emit_move_insn (addr, reg);
+ if (DO_FRAME_NOTES)
+ {
+ RTX_FRAME_RELATED_P (insn) = 1;
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode,
+ gen_rtx_MEM (DFmode,
+ plus_constant (stack_pointer_rtx,
+ offset)),
+ reg),
+ REG_NOTES (insn));
+ }
+ offset += GET_MODE_SIZE (DFmode);
fr_saved++;
}
}
}
}
-/* ?!? Do we want frame notes in the epilogue yet? */
-#undef DO_FRAME_NOTES
-#define DO_FRAME_NOTES 0
-#undef FRP
-#define FRP(INSN) INSN
-
/* Emit RTL to load REG from the memory location specified by BASE+DISP.
Handle case where DISP > 8k by using the add_high_const patterns. */
-static rtx
+static void
load_reg (reg, disp, base)
int reg, disp, base;
{
- rtx i, src, dest, basereg;
+ rtx src, dest, basereg;
dest = gen_rtx_REG (word_mode, reg);
basereg = gen_rtx_REG (Pmode, base);
if (VAL_14_BITS_P (disp))
{
src = gen_rtx_MEM (word_mode, plus_constant (basereg, disp));
- i = emit_move_insn (dest, src);
+ emit_move_insn (dest, src);
}
else
{
@@ -3324,9 +3345,8 @@
rtx tmpreg = gen_rtx_REG (Pmode, 1);
emit_move_insn (tmpreg, high);
src = gen_rtx_MEM (word_mode, gen_rtx_LO_SUM (Pmode, tmpreg, delta));
- i = emit_move_insn (dest, src);
+ emit_move_insn (dest, src);
}
- return i;
}
/* This function generates the assembly code for function exit.
@@ -3388,7 +3408,7 @@
ret_off = TARGET_64BIT ? -16 : -20;
if (frame_pointer_needed)
{
- FRP (load_reg (2, ret_off, FRAME_POINTER_REGNUM));
+ load_reg (2, ret_off, FRAME_POINTER_REGNUM);
ret_off = 0;
}
else
@@ -3396,7 +3416,7 @@
/* No frame pointer, and stack is smaller than 8k. */
if (VAL_14_BITS_P (ret_off - actual_fsize))
{
- FRP (load_reg (2, ret_off - actual_fsize, STACK_POINTER_REGNUM));
+ load_reg (2, ret_off - actual_fsize, STACK_POINTER_REGNUM);
ret_off = 0;
}
}
@@ -3408,7 +3428,7 @@
for (i = 18, offset = local_fsize; i >= 4; i--)
if (regs_ever_live[i] && ! call_used_regs[i])
{
- FRP (load_reg (i, offset, FRAME_POINTER_REGNUM));
+ load_reg (i, offset, FRAME_POINTER_REGNUM);
offset += UNITS_PER_WORD;
}
}
@@ -3426,7 +3446,7 @@
&& VAL_14_BITS_P (-actual_fsize))
merge_sp_adjust_with_load = i;
else
- FRP (load_reg (i, offset, STACK_POINTER_REGNUM));
+ load_reg (i, offset, STACK_POINTER_REGNUM);
offset += UNITS_PER_WORD;
}
}
@@ -3440,9 +3460,9 @@
{
/* Adjust the register to index off of. */
if (frame_pointer_needed)
- FRP (set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset));
+ set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
else
- FRP (set_reg_plus_d (1, STACK_POINTER_REGNUM, offset));
+ set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
/* Actually do the restores now. */
for (i = FP_SAVED_REG_LAST; i >= FP_SAVED_REG_FIRST; i -= FP_REG_STEP)
@@ -3451,7 +3471,7 @@
{
rtx src = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (DFmode, tmpreg));
rtx dest = gen_rtx_REG (DFmode, i);
- FRP (emit_move_insn (dest, src));
+ emit_move_insn (dest, src);
}
}
@@ -3467,27 +3487,45 @@
if (frame_pointer_needed)
{
rtx delta = GEN_INT (-64);
- FRP (set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64));
- FRP (emit_insn (gen_pre_load (frame_pointer_rtx,
- stack_pointer_rtx,
- delta)));
+ rtx insn;
+ set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
+ insn = emit_insn (gen_pre_load (frame_pointer_rtx, stack_pointer_rtx,
+ delta));
+ if (DO_FRAME_NOTES)
+ {
+ RTX_FRAME_RELATED_P (insn) = 1;
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ gen_rtx_PLUS (word_mode, stack_pointer_rtx,
+ delta)),
+ REG_NOTES (insn));
+ }
}
/* If we were deferring a callee register restore, do it now. */
else if (merge_sp_adjust_with_load)
{
rtx delta = GEN_INT (-actual_fsize);
rtx dest = gen_rtx_REG (word_mode, merge_sp_adjust_with_load);
- FRP (emit_insn (gen_pre_load (dest, stack_pointer_rtx, delta)));
+ rtx insn = emit_insn (gen_pre_load (dest, stack_pointer_rtx, delta));
+ if (DO_FRAME_NOTES)
+ {
+ RTX_FRAME_RELATED_P (insn) = 1;
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ gen_rtx_PLUS (word_mode, stack_pointer_rtx,
+ delta)),
+ REG_NOTES (insn));
+ }
}
else if (actual_fsize != 0)
- FRP (set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- - actual_fsize));
+ 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)
- FRP (load_reg (2, ret_off, STACK_POINTER_REGNUM));
+ load_reg (2, ret_off, STACK_POINTER_REGNUM);
}
rtx