From: rsandifo Date: Thu, 15 Dec 2005 16:42:10 +0000 (+0000) Subject: * config/arm/predicates.md (call_memory_operand): New. X-Git-Tag: upstream/4.9.2~56993 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a3c63a9d6a7166efa40161fc87977cb101466f32;p=platform%2Fupstream%2Flinaro-gcc.git * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108583 138bc75d-0d04-0410-961f-82ee72b054a4 --- 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 + + * config/arm/predicates.md (call_memory_operand): New. + * config/arm/arm.md (*call_mem, *call_value_mem): Use it. + 2005-12-15 Andrew Haley * 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 + + * gcc.dg/20051215-1.c: New file. + 2005-12-14 Kaveh R. Ghazi * 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; +}