aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/sh/sh.c59
-rw-r--r--gcc/config/sh/sh.h10
3 files changed, 62 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b8e54cf..dac47a6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+Mon Jun 10 18:02:24 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ Fix cfi generation for SH[1-4]:
+
+ * sh.c (frame_insn): New function.
+ (output_stack_adjust): Add parameter emit_fn. All callers changed.
+ (push): Now returns rtx. Use frame_insn.
+ (sh_expand_prologue): Clear RTX_FRAME_RELATED_P for second push
+ of a DF register.
+ * sh.h (INCOMING_RETURN_ADDR_RTX, DWARF_FRAME_RETURN_COLUMN): Define.
+
2002-06-10 Zack Weinberg <zack@codesourcery.com>
* Makefile.in (STAGESTUFF): Add s-gtype, gt-*.h, gtype-*.h,
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index c2b97b9..58824d8 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -180,8 +180,9 @@ static int mova_p PARAMS ((rtx));
static rtx find_barrier PARAMS ((int, rtx, rtx));
static int noncall_uses_reg PARAMS ((rtx, rtx, rtx *));
static rtx gen_block_redirect PARAMS ((rtx, int, int));
-static void output_stack_adjust PARAMS ((int, rtx, int));
-static void push PARAMS ((int));
+static void output_stack_adjust PARAMS ((int, rtx, int, rtx (*) (rtx)));
+static rtx frame_insn PARAMS ((rtx));
+static rtx push PARAMS ((int));
static void pop PARAMS ((int));
static void push_regs PARAMS ((HOST_WIDE_INT *));
static void calc_live_regs PARAMS ((int *, HOST_WIDE_INT *));
@@ -4204,10 +4205,11 @@ static int extra_push;
of a general register that we may clobber. */
static void
-output_stack_adjust (size, reg, temp)
+output_stack_adjust (size, reg, temp, emit_fn)
int size;
rtx reg;
int temp;
+ rtx (*emit_fn) PARAMS ((rtx));
{
if (size)
{
@@ -4217,19 +4219,20 @@ output_stack_adjust (size, reg, temp)
abort ();
if (CONST_OK_FOR_ADD (size))
- emit_insn (GEN_ADD3 (reg, reg, GEN_INT (size)));
+ emit_fn (GEN_ADD3 (reg, reg, GEN_INT (size)));
/* Try to do it with two partial adjustments; however, we must make
sure that the stack is properly aligned at all times, in case
an interrupt occurs between the two partial adjustments. */
else if (CONST_OK_FOR_ADD (size / 2 & -align)
&& CONST_OK_FOR_ADD (size - (size / 2 & -align)))
{
- emit_insn (GEN_ADD3 (reg, reg, GEN_INT (size / 2 & -align)));
- emit_insn (GEN_ADD3 (reg, reg, GEN_INT (size - (size / 2 & -align))));
+ emit_fn (GEN_ADD3 (reg, reg, GEN_INT (size / 2 & -align)));
+ emit_fn (GEN_ADD3 (reg, reg, GEN_INT (size - (size / 2 & -align))));
}
else
{
rtx const_reg;
+ rtx insn;
/* If TEMP is invalid, we could temporarily save a general
register to MACL. However, there is currently no need
@@ -4244,20 +4247,36 @@ output_stack_adjust (size, reg, temp)
if (size < 0)
{
emit_insn (GEN_MOV (const_reg, GEN_INT (-size)));
- emit_insn (GEN_SUB3 (reg, reg, const_reg));
+ insn = emit_fn (GEN_SUB3 (reg, reg, const_reg));
}
else
{
emit_insn (GEN_MOV (const_reg, GEN_INT (size)));
- emit_insn (GEN_ADD3 (reg, reg, const_reg));
+ insn = emit_fn (GEN_ADD3 (reg, reg, const_reg));
}
+ if (emit_fn == frame_insn)
+ REG_NOTES (insn)
+ = (gen_rtx_EXPR_LIST
+ (REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_PLUS (SImode, reg, GEN_INT (size))),
+ REG_NOTES (insn)));
}
}
}
+static rtx
+frame_insn (x)
+ rtx x;
+{
+ x = emit_insn (x);
+ RTX_FRAME_RELATED_P (x) = 1;
+ return x;
+}
+
/* Output RTL to push register RN onto the stack. */
-static void
+static rtx
push (rn)
int rn;
{
@@ -4276,10 +4295,11 @@ push (rn)
else
x = gen_push (gen_rtx_REG (SImode, rn));
- x = emit_insn (x);
+ x = frame_insn (x);
REG_NOTES (x)
= gen_rtx_EXPR_LIST (REG_INC,
gen_rtx_REG (SImode, STACK_POINTER_REGNUM), 0);
+ return x;
}
/* Output RTL to pop register RN from the stack. */
@@ -4473,7 +4493,7 @@ sh_expand_prologue ()
and partially on the stack, e.g. a large structure. */
output_stack_adjust (-current_function_pretend_args_size
- current_function_args_info.stack_regs * 8,
- stack_pointer_rtx, TARGET_SH5 ? 0 : 1);
+ stack_pointer_rtx, TARGET_SH5 ? 0 : 1, frame_insn);
extra_push = 0;
@@ -4537,11 +4557,14 @@ sh_expand_prologue ()
for (i = 0; i < NPARM_REGS(SImode); i++)
{
int rn = NPARM_REGS(SImode) + FIRST_PARM_REG - i - 1;
+ rtx insn;
+
if (i >= (NPARM_REGS(SImode)
- current_function_args_info.arg_count[(int) SH_ARG_INT]
))
break;
- push (rn);
+ insn = push (rn);
+ RTX_FRAME_RELATED_P (insn) = 0;
extra_push += 4;
}
}
@@ -4571,7 +4594,7 @@ sh_expand_prologue ()
- d % (STACK_BOUNDARY / BITS_PER_UNIT));
offset = d + d_rounding;
- output_stack_adjust (-offset, stack_pointer_rtx, 1);
+ output_stack_adjust (-offset, stack_pointer_rtx, 1, frame_insn);
/* We loop twice: first, we save 8-byte aligned registers in the
higher addresses, that are known to be aligned. Then, we
@@ -4757,10 +4780,10 @@ sh_expand_prologue ()
target_flags = save_flags;
output_stack_adjust (-rounded_frame_size (d) + d_rounding,
- stack_pointer_rtx, TARGET_SH5 ? 0 : 1);
+ stack_pointer_rtx, TARGET_SH5 ? 0 : 1, frame_insn);
if (frame_pointer_needed)
- emit_insn (GEN_MOV (frame_pointer_rtx, stack_pointer_rtx));
+ frame_insn (GEN_MOV (frame_pointer_rtx, stack_pointer_rtx));
if (TARGET_SHCOMPACT
&& (current_function_args_info.call_cookie & ~ CALL_COOKIE_RET_TRAMP(1)))
@@ -4794,7 +4817,7 @@ sh_expand_epilogue ()
if (frame_pointer_needed)
{
- output_stack_adjust (frame_size, frame_pointer_rtx, 7);
+ output_stack_adjust (frame_size, frame_pointer_rtx, 7, emit_insn);
/* We must avoid moving the stack pointer adjustment past code
which reads from the local frame, else an interrupt could
@@ -4810,7 +4833,7 @@ sh_expand_epilogue ()
occur after the SP adjustment and clobber data in the local
frame. */
emit_insn (gen_blockage ());
- output_stack_adjust (frame_size, stack_pointer_rtx, 7);
+ output_stack_adjust (frame_size, stack_pointer_rtx, 7, emit_insn);
}
if (SHMEDIA_REGS_STACK_ADJUST ())
@@ -4986,7 +5009,7 @@ sh_expand_epilogue ()
output_stack_adjust (extra_push + current_function_pretend_args_size
+ d + d_rounding
+ current_function_args_info.stack_regs * 8,
- stack_pointer_rtx, 7);
+ stack_pointer_rtx, 7, emit_insn);
/* Switch back to the normal stack if necessary. */
if (sp_switch)
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index dc6cc54..9e1b4b2 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -2095,6 +2095,14 @@ while (0)
(((COUNT) == 0) \
? get_hard_reg_initial_val (Pmode, TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG) \
: (rtx) 0)
+
+/* 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 RTL is either a REG, indicating that the return
+ value is saved in REG, or a MEM representing a location in
+ the stack. */
+#define INCOMING_RETURN_ADDR_RTX \
+ gen_rtx_REG (Pmode, TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG)
/* Generate necessary RTL for __builtin_saveregs(). */
#define EXPAND_BUILTIN_SAVEREGS() sh_builtin_saveregs ()
@@ -3230,6 +3238,8 @@ extern struct rtx_def *fpscr_rtx;
#define MD_CAN_REDIRECT_BRANCH(INSN, SEQ) \
sh_can_redirect_branch ((INSN), (SEQ))
+#define DWARF_FRAME_RETURN_COLUMN (TARGET_SH5 ? PR_MEDIA_REG : PR_REG)
+
#if (defined CRT_BEGIN || defined CRT_END) && ! __SHMEDIA__
/* SH constant pool breaks the devices in crtstuff.c to control section
in where code resides. We have to write it as asm code. */