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 *));
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)
{
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
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;
{
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. */
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;
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;
}
}
- 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
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)))
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
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 ())
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)