From: Richard Sandiford Date: Thu, 15 Dec 2005 16:42:10 +0000 (+0000) Subject: predicates.md (call_memory_operand): New. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e6add59b161628111dff015502f88d6459927493;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c5d580c3ca..19cd3f07089 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 f9d4743380b..a161d4d5a43 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 aa4f60ed013..4a08204d155 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 fbef2e695a0..efeb2a51c4f 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 00000000000..0bb06d9be3e --- /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; +}