diff options
author | Richard Sandiford <richard@codesourcery.com> | 2005-12-15 16:42:10 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2005-12-15 16:42:10 +0000 |
commit | e6add59b161628111dff015502f88d6459927493 (patch) | |
tree | 4f62a760e67319ae6549f22ca192ab7fbe5a8e7a /gcc | |
parent | a8acd1c48099154ef824961457aa1aecfc10bbee (diff) | |
download | gcc-e6add59b161628111dff015502f88d6459927493.zip gcc-e6add59b161628111dff015502f88d6459927493.tar.gz gcc-e6add59b161628111dff015502f88d6459927493.tar.bz2 |
predicates.md (call_memory_operand): New.
* 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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 4 | ||||
-rw-r--r-- | gcc/config/arm/predicates.md | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/20051215-1.c | 36 |
5 files changed, 55 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c5d580..19cd3f0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index f9d4743..a161d4d 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -7561,7 +7561,7 @@ ) (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))] @@ -7655,7 +7655,7 @@ (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))] diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index aa4f60e..4a08204 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -110,6 +110,14 @@ "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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fbef2e6..efeb2a5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..0bb06d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20051215-1.c @@ -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; +} |