Commit b034930f by Ian Lance Taylor Committed by Ian Lance Taylor

arm.c (output_return_instruction): Only restore IP into SP if frame_pointer_needed.

	* config/arm/arm.c (output_return_instruction): Only restore IP
	into SP if frame_pointer_needed.

	* gcc.dg/arm-mmx-1.c: New test.

From-SVN: r76710
parent be446dfc
2004-01-27 Ian Lance Taylor <ian@wasabisystems.com>
* config/arm/arm.c (output_return_instruction): Only restore IP
into SP if frame_pointer_needed.
2004-01-27 Eric Botcazou <ebotcazou@libertysurf.fr> 2004-01-27 Eric Botcazou <ebotcazou@libertysurf.fr>
* config/sparc/sparc.c (function_arg_pass_by_reference): Return 1 * config/sparc/sparc.c (function_arg_pass_by_reference): Return 1
......
...@@ -8260,15 +8260,25 @@ output_return_instruction (rtx operand, int really_return, int reverse) ...@@ -8260,15 +8260,25 @@ output_return_instruction (rtx operand, int really_return, int reverse)
return_reg = reg_names[LR_REGNUM]; return_reg = reg_names[LR_REGNUM];
if ((live_regs_mask & (1 << IP_REGNUM)) == (1 << IP_REGNUM)) if ((live_regs_mask & (1 << IP_REGNUM)) == (1 << IP_REGNUM))
/* There are two possible reasons for the IP register being saved. {
Either a stack frame was created, in which case IP contains the /* There are three possible reasons for the IP register
old stack pointer, or an ISR routine corrupted it. If this in an being saved. 1) a stack frame was created, in which case
ISR routine then just restore IP, otherwise restore IP into SP. */ IP contains the old stack pointer, or 2) an ISR routine
if (! IS_INTERRUPT (func_type)) corrupted it, or 3) it was saved to align the stack on
{ iWMMXt. In case 1, restore IP into SP, otherwise just
live_regs_mask &= ~ (1 << IP_REGNUM); restore IP. */
live_regs_mask |= (1 << SP_REGNUM); if (frame_pointer_needed)
} {
live_regs_mask &= ~ (1 << IP_REGNUM);
live_regs_mask |= (1 << SP_REGNUM);
}
else
{
if (! IS_INTERRUPT (func_type)
&& ! TARGET_REALLY_IWMMXT)
abort ();
}
}
/* On some ARM architectures it is faster to use LDR rather than /* On some ARM architectures it is faster to use LDR rather than
LDM to load a single register. On other architectures, the LDM to load a single register. On other architectures, the
......
2004-01-27 Ian Lance Taylor <ian@wasabisystems.com>
* gcc.dg/arm-mmx-1.c: New test.
2004-01-27 Eric Botcazou <ebotcazou@libertysurf.fr> 2004-01-27 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/20040127-1.c: New test. * gcc.dg/20040127-1.c: New test.
......
/* Verify that if IP is saved to ensure stack alignment, we don't load
it into sp. */
/* { dg-do compile { target arm*-*-* strongarm*-*-* xscale*-*-*} } */
/* { dg-options "-O -mno-apcs-frame -mcpu=iwmmxt" } */
/* { dg-final { scan-assembler "ldmfd\[ ]sp!.*ip,\[ ]*pc" } } */
/* This function uses all the call-saved registers, namely r4, r5, r6,
r7, r8, r9, sl, fp. Since we also save pc, that leaves an odd
number of registers, and the compiler will push ip to align the
stack. Make sure that we restore ip into ip, not into sp as is
done when using a frame pointer. The -mno-apcs-frame option
permits the frame pointer to be used as an ordinary register. */
int
foo(int *a, int *b, int *c, int *d, int *tot)
{
int i, j, k, l, m, n, o;
*tot = 0;
for (i = *a; i < *b; i += *c)
for (j = *a; j < *b; j += *d)
for (k = *a; k < *c; k += *d)
for (l = *b; k < *c; k += *d)
for (m = *d; k < *c; k += *b)
*tot += i + j + k + l + m;
return *tot;
}
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