predicates.md (call_memory_operand): New.
authorRichard Sandiford <richard@codesourcery.com>
Thu, 15 Dec 2005 16:42:10 +0000 (16:42 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 15 Dec 2005 16:42:10 +0000 (16:42 +0000)
* config/arm/predicates.md (call_memory_operand): New.
* config/arm/arm.md (*call_mem, *call_value_mem): Use it.

testsuite/
* gcc.dg/20051215-1.c: New file.

From-SVN: r108583

gcc/ChangeLog
gcc/config/arm/arm.md
gcc/config/arm/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20051215-1.c [new file with mode: 0644]

index 7c5d580c3ca31351df4c472553087b0a008553df..19cd3f07089ac742724bf629ef3f306e2bc35aac 100644 (file)
@@ -1,3 +1,8 @@
+2005-12-15  Richard Sandiford  <richard@codesourcery.com>
+
+       * config/arm/predicates.md (call_memory_operand): New.
+       * config/arm/arm.md (*call_mem, *call_value_mem): Use it.
+
 2005-12-15  Andrew Haley  <aph@redhat.com>
 
        * unwind-dw2-fde-glibc.c (_Unwind_IteratePhdrCallback): Guard
index f9d4743380b28b1efc9d1bcfd121b8ebffe6043e..a161d4d5a43f2f198a5426a52f9bf24de5391132 100644 (file)
 )
 
 (define_insn "*call_mem"
-  [(call (mem:SI (match_operand:SI 0 "memory_operand" "m"))
+  [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
         (match_operand 1 "" ""))
    (use (match_operand 2 "" ""))
    (clobber (reg:SI LR_REGNUM))]
 
 (define_insn "*call_value_mem"
   [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:SI 1 "memory_operand" "m"))
+       (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
              (match_operand 2 "" "")))
    (use (match_operand 3 "" ""))
    (clobber (reg:SI LR_REGNUM))]
index aa4f60ed0136d3b2d0c4d50c47c9ce907bb606ee..4a08204d155b6227600e0ce0f3a109e3f721fa44 100644 (file)
         "offsettable_address_p (reload_completed | reload_in_progress,
                                mode, XEXP (op, 0))")))
 
+;; True if the operand is a memory operand that does not have an
+;; automodified base register (and thus will not generate output reloads).
+(define_predicate "call_memory_operand"
+  (and (match_code "mem")
+       (and (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0)))
+                        != RTX_AUTOINC")
+           (match_operand 0 "memory_operand"))))
+
 (define_predicate "arm_reload_memory_operand"
   (and (match_code "mem,reg,subreg")
        (match_test "(!CONSTANT_P (op)
index fbef2e695a0920638fe2f2b3c818f7adc0496c51..efeb2a51c4f61f39a2adabd93ae359686f68e14e 100644 (file)
@@ -1,3 +1,7 @@
+2005-12-15  Richard Sandiford  <richard@codesourcery.com>
+
+       * gcc.dg/20051215-1.c: New file.
+
 2005-12-14  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * g++.dg/rtti/repo1.C: Call cleanup-repo-files.
diff --git a/gcc/testsuite/gcc.dg/20051215-1.c b/gcc/testsuite/gcc.dg/20051215-1.c
new file mode 100644 (file)
index 0000000..0bb06d9
--- /dev/null
@@ -0,0 +1,36 @@
+/* ARM's load-and-call patterns used to allow automodified addresses.
+   This was wrong, because if the modified register were spilled,
+   the call would need an output reload.  */
+/* { dg-do run { target arm*-*-* } } */
+/* { dg-options "-O2 -fno-omit-frame-pointer" } */
+extern void abort (void);
+typedef void (*callback) (void);
+
+static void
+foo (callback *first, callback *p)
+{
+  while (p > first)
+    {
+      (*--p) ();
+#ifndef __thumb__
+      asm ("" : "=r" (p) : "0" (p)
+          : "r4", "r5", "r6", "r7", "r8", "r9", "r10");
+#endif
+    }   
+}
+
+static void
+dummy (void)
+{
+  static int count;
+  if (count++ == 1)
+    abort ();
+}
+
+int
+main (void)
+{
+  callback list[1] = { dummy };
+  foo (&list[0], &list[1]);
+  return 0;
+}