This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Frame notes for pa.c
- To: gcc-patches at gcc dot gnu dot org
- Subject: Frame notes for pa.c
- From: Alan Modra <alan at linuxcare dot com dot au>
- Date: Fri, 30 Mar 2001 20:09:19 +1000 (EST)
First step towards having dwarf2 debugging on hppa. This won't do
anything yet, as INCOMING_RETURN_ADDR_RTX insn't yet defined in pa.h.
Patch is othogonal to my last patch for profiling, but may not apply
cleanly as that one hasn't yet gone in.
* config/pa/pa.c: (set_reg_plus_d): Return last insn.
(actual_fsize, local_fsize, save_fregs): Move for store_reg to see.
(DO_FRAME_NOTES): Define to control the following..
(store_reg): Set RTX_FRAME_RELATED_P on insns, and
REG_FRAME_RELATED_EXPR notes as necessary.
(hppa_expand_prologue): Likewise.
(hppa_expand_epilogue): Likewise.
Alan Modra
--
Linuxcare
--- gcc-current/gcc/config/pa/pa.c Mon Mar 26 17:21:56 2001
+++ gcc-new/gcc/config/pa/pa.c Fri Mar 30 18:07:49 2001
@@ -42,6 +42,14 @@ Boston, MA 02111-1307, USA. */
#include "recog.h"
#include "tm_p.h"
+#ifndef DO_FRAME_NOTES
+#ifdef INCOMING_RETURN_ADDR_RTX
+#define DO_FRAME_NOTES 1
+#else
+#define DO_FRAME_NOTES 0
+#endif
+#endif
+
static void pa_init_machine_status PARAMS ((struct function *));
static void pa_mark_machine_status PARAMS ((struct function *));
static void pa_free_machine_status PARAMS ((struct function *));
@@ -56,7 +64,7 @@ static int compute_movstrsi_length PAR
static void remove_useless_addtr_insns PARAMS ((rtx, 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 rtx set_reg_plus_d PARAMS ((int, int, int));
/* Save the operands last given to a compare for use when we
generate a scc or bcc insn. */
@@ -2743,6 +2751,12 @@ remove_useless_addtr_insns (insns, check
*/
+/* Global variables set by FUNCTION_PROLOGUE. */
+/* Size of frame. Need to know this to emit return insns from
+ leaf procedures. */
+static int actual_fsize;
+static int local_fsize, save_fregs;
+
/* Emit RTL to store REG at the memory location specified by BASE+DISP.
Handle case where DISP > 8k by using the add_high_const patterns.
@@ -2753,21 +2767,36 @@ static void
store_reg (reg, disp, base)
int reg, disp, base;
{
+ rtx i, dest, src, basereg;
+
+ src = gen_rtx_REG (word_mode, reg);
+ basereg = gen_rtx_REG (Pmode, base);
if (VAL_14_BITS_P (disp))
- emit_move_insn (gen_rtx_MEM (word_mode,
- plus_constant (gen_rtx_REG (Pmode, base),
- disp)),
- gen_rtx_REG (word_mode, reg));
+ {
+ dest = gen_rtx_MEM (word_mode, plus_constant (basereg, disp));
+ i = emit_move_insn (dest, src);
+ }
else
{
- emit_move_insn (gen_rtx_REG (Pmode, 1),
- gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, base),
- gen_rtx_HIGH (Pmode, GEN_INT (disp))));
- emit_move_insn (gen_rtx_MEM (word_mode,
- gen_rtx_LO_SUM (Pmode,
- gen_rtx_REG (Pmode, 1),
- GEN_INT (disp))),
- gen_rtx_REG (word_mode, reg));
+ rtx delta = GEN_INT (disp);
+ rtx high = gen_rtx_PLUS (Pmode, basereg, gen_rtx_HIGH (Pmode, delta));
+ 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);
+ }
+ if (DO_FRAME_NOTES)
+ {
+ RTX_FRAME_RELATED_P (i) = 1;
+ if (base != STACK_POINTER_REGNUM)
+ {
+ rtx addr = plus_constant (stack_pointer_rtx, disp - actual_fsize);
+ dest = gen_rtx_MEM (word_mode, addr);
+ REG_NOTES (i)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode, dest, src),
+ REG_NOTES (i));
+ }
}
}
@@ -2805,31 +2834,30 @@ load_reg (reg, disp, base)
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 void
+static rtx
set_reg_plus_d (reg, base, disp)
int reg, base, disp;
{
+ rtx i;
+
if (VAL_14_BITS_P (disp))
- emit_move_insn (gen_rtx_REG (Pmode, reg),
- plus_constant (gen_rtx_REG (Pmode, base), disp));
+ {
+ i = emit_move_insn (gen_rtx_REG (Pmode, reg),
+ plus_constant (gen_rtx_REG (Pmode, base), disp));
+ }
else
{
+ rtx delta = GEN_INT (disp);
emit_move_insn (gen_rtx_REG (Pmode, 1),
gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, base),
- gen_rtx_HIGH (Pmode, GEN_INT (disp))));
- emit_move_insn (gen_rtx_REG (Pmode, reg),
- gen_rtx_LO_SUM (Pmode,
- gen_rtx_REG (Pmode, 1),
- GEN_INT (disp)));
+ 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));
}
+ return i;
}
-/* Global variables set by FUNCTION_PROLOGUE. */
-/* Size of frame. Need to know this to emit return insns from
- leaf procedures. */
-static int actual_fsize;
-static int local_fsize, save_fregs;
-
int
compute_frame_size (size, fregs_live)
int size;
@@ -2945,6 +2973,7 @@ hppa_expand_prologue()
int merge_sp_adjust_with_store = 0;
int i, offset;
rtx tmpreg, size_rtx;
+ rtx insn;
gr_saved = 0;
fr_saved = 0;
@@ -2982,9 +3011,31 @@ hppa_expand_prologue()
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);
+ insn = 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));
+ {
+ insn = emit_insn (gen_post_store (stack_pointer_rtx, tmpreg,
+ size_rtx));
+ if (DO_FRAME_NOTES)
+ {
+ rtvec vec;
+ RTX_FRAME_RELATED_P (insn) = 1;
+ vec = gen_rtvec (2,
+ gen_rtx_SET (VOIDmode,
+ gen_rtx_MEM (word_mode,
+ stack_pointer_rtx),
+ frame_pointer_rtx),
+ gen_rtx_SET (VOIDmode,
+ stack_pointer_rtx,
+ gen_rtx_PLUS (word_mode,
+ stack_pointer_rtx,
+ size_rtx)));
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SEQUENCE (VOIDmode, vec),
+ REG_NOTES (insn));
+ }
+ }
else
{
/* It is incorrect to store the saved frame pointer at *sp,
@@ -2996,10 +3047,46 @@ hppa_expand_prologue()
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);
+ insn = emit_insn (gen_post_store (stack_pointer_rtx, tmpreg,
+ delta));
+ if (DO_FRAME_NOTES)
+ {
+ rtvec vec;
+ RTX_FRAME_RELATED_P (insn) = 1;
+ vec = gen_rtvec (2,
+ gen_rtx_SET (VOIDmode,
+ gen_rtx_MEM (word_mode,
+ stack_pointer_rtx),
+ frame_pointer_rtx),
+ gen_rtx_SET (VOIDmode,
+ stack_pointer_rtx,
+ gen_rtx_PLUS (word_mode,
+ stack_pointer_rtx,
+ delta)));
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SEQUENCE (VOIDmode, vec),
+ REG_NOTES (insn));
+ }
+
+ insn = set_reg_plus_d (STACK_POINTER_REGNUM,
+ STACK_POINTER_REGNUM,
+ adjust2);
+ if (DO_FRAME_NOTES)
+ {
+ RTX_FRAME_RELATED_P (insn) = 1;
+ if (! VAL_14_BITS_P (adjust2))
+ {
+ rtx addr = plus_constant (stack_pointer_rtx, adjust2);
+
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode,
+ stack_pointer_rtx,
+ addr),
+ REG_NOTES (insn));
+ }
+ }
}
/* Prevent register spills from being scheduled before the
stack pointer is raised. Necessary as we will be storing
@@ -3019,9 +3106,26 @@ hppa_expand_prologue()
/* Can not optimize. Adjust the stack frame by actual_fsize
bytes. */
else
- set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- actual_fsize);
+ {
+ insn = set_reg_plus_d (STACK_POINTER_REGNUM,
+ STACK_POINTER_REGNUM,
+ actual_fsize);
+ if (DO_FRAME_NOTES)
+ {
+ RTX_FRAME_RELATED_P (insn) = 1;
+ if (! VAL_14_BITS_P (actual_fsize))
+ {
+ rtx addr;
+ addr = plus_constant (stack_pointer_rtx, actual_fsize);
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode,
+ stack_pointer_rtx,
+ addr),
+ REG_NOTES (insn));
+ }
+ }
+ }
}
}
@@ -3051,10 +3155,25 @@ hppa_expand_prologue()
optimize the first GR save. */
if (merge_sp_adjust_with_store)
{
+ rtx delta = GEN_INT (-offset);
merge_sp_adjust_with_store = 0;
- emit_insn (gen_post_store (stack_pointer_rtx,
- gen_rtx_REG (word_mode, i),
- GEN_INT (-offset)));
+ insn = emit_insn (gen_post_store (stack_pointer_rtx,
+ gen_rtx_REG (word_mode, i),
+ delta));
+ if (DO_FRAME_NOTES)
+ {
+ rtx set;
+ RTX_FRAME_RELATED_P (insn) = 1;
+ set = gen_rtx_SET (VOIDmode,
+ stack_pointer_rtx,
+ gen_rtx_PLUS (word_mode,
+ stack_pointer_rtx,
+ delta));
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ set,
+ REG_NOTES (insn));
+ }
}
else
store_reg (i, offset, STACK_POINTER_REGNUM);
@@ -3065,9 +3184,13 @@ hppa_expand_prologue()
/* 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)
- set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- actual_fsize);
+ {
+ insn = set_reg_plus_d (STACK_POINTER_REGNUM,
+ STACK_POINTER_REGNUM,
+ actual_fsize);
+ if (DO_FRAME_NOTES)
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
}
/* The hppa calling conventions say that %r19, the pic offset
@@ -3098,9 +3221,26 @@ hppa_expand_prologue()
if (regs_ever_live[i]
|| (! TARGET_64BIT && regs_ever_live[i + 1]))
{
- emit_move_insn (gen_rtx_MEM (DFmode,
- gen_rtx_POST_INC (DFmode, tmpreg)),
- gen_rtx_REG (DFmode, i));
+ rtx addr, reg;
+ addr = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (DFmode, tmpreg));
+ reg = gen_rtx_REG (DFmode, i);
+ insn = emit_move_insn (addr, reg);
+ if (DO_FRAME_NOTES)
+ {
+ rtx stackoff;
+ RTX_FRAME_RELATED_P (insn) = 1;
+ stackoff = GEN_INT (offset + (frame_pointer_needed
+ ? -actual_fsize : 0));
+ addr = gen_rtx_MEM (DFmode,
+ gen_rtx_PLUS (DFmode,
+ stack_pointer_rtx,
+ stackoff));
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode, addr, reg),
+ REG_NOTES (insn));
+ offset += 8;
+ }
fr_saved++;
}
}
@@ -3147,6 +3287,7 @@ hppa_expand_epilogue ()
int offset, i;
int merge_sp_adjust_with_load = 0;
int ret_off = 0;
+ rtx insn;
/* We will use this often. */
tmpreg = gen_rtx_REG (word_mode, 1);
@@ -3239,25 +3380,83 @@ hppa_expand_epilogue ()
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,
- stack_pointer_rtx,
- GEN_INT (-64)));
+ rtx delta = GEN_INT (-64);
+ insn = set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
+ 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,
+ plus_constant (stack_pointer_rtx,
+ 64 - actual_fsize)),
+ REG_NOTES (insn));
+ }
+ insn = emit_insn (gen_pre_load (frame_pointer_rtx,
+ stack_pointer_rtx,
+ delta));
+ if (DO_FRAME_NOTES)
+ {
+ rtvec vec;
+ RTX_FRAME_RELATED_P (insn) = 1;
+ vec = gen_rtvec (2,
+ gen_rtx_SET (VOIDmode,
+ stack_pointer_rtx,
+ gen_rtx_PLUS (word_mode,
+ stack_pointer_rtx,
+ delta)),
+ gen_rtx_SET (VOIDmode,
+ frame_pointer_rtx,
+ gen_rtx_MEM (word_mode,
+ stack_pointer_rtx)));
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SEQUENCE (VOIDmode, vec),
+ 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);
- emit_insn (gen_pre_load (gen_rtx_REG (word_mode,
- merge_sp_adjust_with_load),
- stack_pointer_rtx,
- delta));
+ insn = emit_insn (gen_pre_load (gen_rtx_REG (word_mode,
+ merge_sp_adjust_with_load),
+ 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)
{
- set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- - actual_fsize);
+ insn = set_reg_plus_d (STACK_POINTER_REGNUM,
+ STACK_POINTER_REGNUM,
+ - actual_fsize);
+ if (DO_FRAME_NOTES)
+ {
+ RTX_FRAME_RELATED_P (insn) = 1;
+ if (! VAL_14_BITS_P (- actual_fsize))
+ {
+ rtx addr = plus_constant (stack_pointer_rtx, - actual_fsize);
+
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode,
+ stack_pointer_rtx,
+ addr),
+ REG_NOTES (insn));
+ }
+ }
}
/* If we haven't restored %r2 yet (no frame pointer, and a stack