arm.c (arm_output_epilogue): Reverse the order of loading iWMMXt registers with a...
authorDaniel Jacobowitz <drow@mvista.com>
Fri, 23 Apr 2004 13:51:21 +0000 (13:51 +0000)
committerDaniel Jacobowitz <drow@gcc.gnu.org>
Fri, 23 Apr 2004 13:51:21 +0000 (13:51 +0000)
* config/arm/arm.c (arm_output_epilogue): Reverse the order of
loading iWMMXt registers with a frame pointer.  Use post-increment
without a frame pointer.
(arm_expand_prologue): Reverse the order of saving iWMMXt registers.
testsuite/
* gcc.c-torture/execute/simd-5.c: New test.

From-SVN: r81092

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/simd-5.c [new file with mode: 0644]

index b45f29a12bb31ebf889621af55c894af3e28af58..e544a23210a46a0ef17e7770b7abdc4e86ba7ecb 100644 (file)
@@ -1,3 +1,10 @@
+2004-04-23  Daniel Jacobowitz  <drow@mvista.com>
+
+       * config/arm/arm.c (arm_output_epilogue): Reverse the order of
+       loading iWMMXt registers with a frame pointer.  Use post-increment
+       without a frame pointer.
+       (arm_expand_prologue): Reverse the order of saving iWMMXt registers.
+
 2004-04-23  Paolo Bonzini  <bonzini@gnu.org>
 
        * doc/invoke.texi (Optimize Options): Refer to "unit-at-a-time
index d6c0c3d0421a9ef97c3c73d7249bcc66be28b325..1c2f2b2b4949fdd89f6eae4146fb3d1eb5e83691 100644 (file)
@@ -9492,7 +9492,7 @@ arm_output_epilogue (rtx sibling)
             the live_regs_mask.  */
          lrm_count += (lrm_count % 2 ? 2 : 1);
              
-         for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+         for (reg = LAST_IWMMXT_REGNUM; reg >= FIRST_IWMMXT_REGNUM; reg--)
            if (regs_ever_live[reg] && !call_used_regs[reg])
              {
                asm_fprintf (f, "\twldrd\t%r, [%r, #-%d]\n", 
@@ -9613,7 +9613,7 @@ arm_output_epilogue (rtx sibling)
       if (TARGET_IWMMXT)
        for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
          if (regs_ever_live[reg] && !call_used_regs[reg])
-           asm_fprintf (f, "\twldrd\t%r, [%r, #+8]!\n", reg, SP_REGNUM);
+           asm_fprintf (f, "\twldrd\t%r, [%r], #8\n", reg, SP_REGNUM);
 
       /* If we can, restore the LR into the PC.  */
       if (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
@@ -10339,7 +10339,7 @@ arm_expand_prologue (void)
     }
 
   if (TARGET_IWMMXT)
-    for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+    for (reg = LAST_IWMMXT_REGNUM; reg >= FIRST_IWMMXT_REGNUM; reg--)
       if (regs_ever_live[reg] && ! call_used_regs [reg])
        {
          insn = gen_rtx_PRE_DEC (V2SImode, stack_pointer_rtx);
index b57694e76f40101f8bed5930414482102a950d8f..f25bfd1b0c76b39c5b6dcc4380958cc3cc3f81fe 100644 (file)
@@ -1,3 +1,7 @@
+2004-04-23  Daniel Jacobowitz  <drow@mvista.com>
+
+       * gcc.c-torture/execute/simd-5.c: New test.
+
 2004-04-23  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
 
        PR c++/15064
diff --git a/gcc/testsuite/gcc.c-torture/execute/simd-5.c b/gcc/testsuite/gcc.c-torture/execute/simd-5.c
new file mode 100644 (file)
index 0000000..f058432
--- /dev/null
@@ -0,0 +1,59 @@
+/* Test saving and restoring of SIMD registers.  */
+
+typedef short Q __attribute__((vector_size(8)));
+
+Q q1 = {1, 2}, q2 = {3, 4}, q3 = {5, 6}, q4 = {7, 8};
+
+Q w1, w2, w3, w4;
+Q z1, z2, z3, z4;
+
+volatile int dummy;
+
+void  __attribute__((__noinline__))
+func0 (void)
+{
+  dummy = 1;
+}
+
+void __attribute__((__noinline__))
+func1 (void)
+{
+  Q a, b;
+  a = q1 * q2;
+  b = q3 * q4;
+  w1 = a;
+  w2 = b;
+  func0 ();
+  w3 = a;
+  w4 = b;
+}
+
+void __attribute__((__noinline__))
+func2 (void)
+{
+  Q a, b;
+  a = q1 + q2;
+  b = q3 - q4;
+  z1 = a;
+  z2 = b;
+  func1 ();
+  z3 = a;
+  z4 = b;
+}
+
+int
+main (void)
+{
+  func2 ();
+
+  if (memcmp (&w1, &w3, sizeof (Q)) != 0)
+    abort ();
+  if (memcmp (&w2, &w4, sizeof (Q)) != 0)
+    abort ();
+  if (memcmp (&z1, &z3, sizeof (Q)) != 0)
+    abort ();
+  if (memcmp (&z2, &z4, sizeof (Q)) != 0)
+    abort ();
+
+  return 0;
+}