Commit ede34dfc by Eric Botcazou

arm.c (arm_expand_prologue): In a nested APCS frame with arguments to push onto…

arm.c (arm_expand_prologue): In a nested APCS frame with arguments to push onto the stack and no varargs...

	* config/arm/arm.c (arm_expand_prologue): In a nested APCS frame with
	arguments to push onto the stack and no varargs, save ip into the last
	stack slot if r3 isn't available on entry.

From-SVN: r206154
parent abdd0cfa
2013-12-20 Eric Botcazou <ebotcazou@adacore.com>
* config/arm/arm.c (arm_expand_prologue): In a nested APCS frame with
arguments to push onto the stack and no varargs, save ip into the last
stack slot if r3 isn't available on entry.
2013-12-20 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/neon.ml (crypto_intrinsics): Add vceq_64 and vtst_p64.
......@@ -18679,8 +18679,7 @@ arm_r3_live_at_start_p (void)
/* Just look at cfg info, which is still close enough to correct at this
point. This gives false positives for broken functions that might use
uninitialized data that happens to be allocated in r3, but who cares? */
return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
3);
return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)), 3);
}
/* Compute the number of bytes used to store the static chain register on the
......@@ -20706,11 +20705,13 @@ arm_expand_prologue (void)
whilst the frame is being created. We try the following
places in order:
1. The last argument register r3.
2. A slot on the stack above the frame. (This only
works if the function is not a varargs function).
1. The last argument register r3 if it is available.
2. A slot on the stack above the frame if there are no
arguments to push onto the stack.
3. Register r3 again, after pushing the argument registers
onto the stack.
onto the stack, if this is a varargs function.
4. The last slot on the stack created for the arguments to
push, if this isn't a varargs function.
Note - we only need to tell the dwarf2 backend about the SP
adjustment in the second variant; the static chain register
......@@ -20721,13 +20722,13 @@ arm_expand_prologue (void)
insn = emit_set_insn (gen_rtx_REG (SImode, 3), ip_rtx);
else if (args_to_push == 0)
{
rtx dwarf;
rtx addr, dwarf;
gcc_assert(arm_compute_static_chain_stack_bytes() == 4);
saved_regs += 4;
insn = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx);
insn = emit_set_insn (gen_frame_mem (SImode, insn), ip_rtx);
addr = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
insn = emit_set_insn (gen_frame_mem (SImode, addr), ip_rtx);
fp_offset = 4;
/* Just tell the dwarf backend that we adjusted SP. */
......@@ -20741,21 +20742,38 @@ arm_expand_prologue (void)
{
/* Store the args on the stack. */
if (cfun->machine->uses_anonymous_args)
insn = emit_multi_reg_push
((0xf0 >> (args_to_push / 4)) & 0xf);
{
insn
= emit_multi_reg_push ((0xf0 >> (args_to_push / 4)) & 0xf);
emit_set_insn (gen_rtx_REG (SImode, 3), ip_rtx);
saved_pretend_args = 1;
}
else
insn = emit_insn
(gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (- args_to_push)));
{
rtx addr, dwarf;
RTX_FRAME_RELATED_P (insn) = 1;
if (args_to_push == 4)
addr = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
else
addr
= gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
plus_constant (Pmode,
stack_pointer_rtx,
-args_to_push));
insn = emit_set_insn (gen_frame_mem (SImode, addr), ip_rtx);
saved_pretend_args = 1;
/* Just tell the dwarf backend that we adjusted SP. */
dwarf
= gen_rtx_SET (VOIDmode, stack_pointer_rtx,
plus_constant (Pmode, stack_pointer_rtx,
-args_to_push));
add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
}
RTX_FRAME_RELATED_P (insn) = 1;
fp_offset = args_to_push;
args_to_push = 0;
/* Now reuse r3 to preserve IP. */
emit_set_insn (gen_rtx_REG (SImode, 3), ip_rtx);
}
}
......@@ -20861,7 +20879,7 @@ arm_expand_prologue (void)
/* Recover the static chain register. */
if (!arm_r3_live_at_start_p () || saved_pretend_args)
insn = gen_rtx_REG (SImode, 3);
else /* if (crtl->args.pretend_args_size == 0) */
else
{
insn = plus_constant (Pmode, hard_frame_pointer_rtx, 4);
insn = gen_frame_mem (SImode, insn);
......
2013-12-20 Richard Earnshaw <rearnsha@arm.com>
* gcc.target/arm/nested-apcs.c: New test.
2013-12-20 Jakub Jelinek <jakub@redhat.com>
PR c++/59255
......
/* { dg-do run } */
/* { dg-options "-fno-omit-frame-pointer -mapcs-frame -O" } */
extern void abort (void);
struct x
{
int y;
int z;
};
int __attribute__((noinline)) f (int c, int d, int e, int h, int i)
{
int a;
struct x b;
int __attribute__((noinline)) g (int p, int q, int r, struct x s)
{
return a + p + q + r + s.y + s.z;
}
a = 5;
b.y = h;
b.z = i;
return g(c, d, e, b);
}
int main(void)
{
if (f (1, 2, 3, 4, 5) != 20)
abort();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment