+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>
* config/sparc/sparc.c (function_arg_pass_by_reference): Return 1
return_reg = reg_names[LR_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
- old stack pointer, or an ISR routine corrupted it. If this in an
- ISR routine then just restore IP, otherwise restore IP into SP. */
- if (! IS_INTERRUPT (func_type))
- {
- live_regs_mask &= ~ (1 << IP_REGNUM);
- live_regs_mask |= (1 << SP_REGNUM);
- }
+ {
+ /* There are three possible reasons for the IP register
+ being saved. 1) a stack frame was created, in which case
+ IP contains the old stack pointer, or 2) an ISR routine
+ corrupted it, or 3) it was saved to align the stack on
+ iWMMXt. In case 1, restore IP into SP, otherwise just
+ restore IP. */
+ 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
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>
* gcc.dg/20040127-1.c: New test.
--- /dev/null
+/* 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;
+}