OSDN Git Service

PR target/49437
authorjye2 <jye2@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Aug 2011 08:28:08 +0000 (08:28 +0000)
committerjye2 <jye2@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Aug 2011 08:28:08 +0000 (08:28 +0000)
       * config/arm/arm.c (arm_output_epilogue): Properly handle epilogue
       when stack was realigned in interrupt handler prologue.

testsuite:

       PR target/49437
       * gcc.target/arm/handler-align.c: New test.
       * lib/target-supports.exp (check_effective_target_arm_cortex_m):
         New Function.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@177891 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/handler-align.c [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp

index 14723eb..7c0c7b5 100644 (file)
@@ -1,3 +1,9 @@
+2011-08-19  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
+       PR target/49437
+       * config/arm/arm.c (arm_output_epilogue): Properly handle epilogue
+       when stack was realigned in interrupt handler prologue.
+
 2011-08-18  Joseph Myers  <joseph@codesourcery.com>
 
        * c-decl.c (shadow_tag_warned): Check for _Noreturn.
index d1a3490..3162b30 100644 (file)
@@ -15230,6 +15230,7 @@ arm_output_epilogue (rtx sibling)
                  && !crtl->calls_eh_return
                  && bit_count(saved_regs_mask) * 4 == count
                  && !IS_INTERRUPT (func_type)
+                 && !IS_STACKALIGN (func_type)
                  && !crtl->tail_call_emit)
                {
                  unsigned long mask;
index 3f286ed..0cadc3c 100644 (file)
@@ -1,5 +1,12 @@
 2011-08-19  Joey Ye  <joey.ye@arm.com>
 
+       PR target/49437
+       * gcc.target/arm/handler-align.c: New test.
+       * lib/target-supports.exp (check_effective_target_arm_cortex_m):
+       New Function.
+
+2011-08-19  Joey Ye  <joey.ye@arm.com>
+
        * gcc.c-torture/execute/20101011-1.c (DO_TEST): Skip on ARM.
 
 2011-08-19  Mikael Morin  <mikael.morin@sfr.fr>
diff --git a/gcc/testsuite/gcc.target/arm/handler-align.c b/gcc/testsuite/gcc.target/arm/handler-align.c
new file mode 100644 (file)
index 0000000..6c5187b
--- /dev/null
@@ -0,0 +1,42 @@
+/* Test epilogue of a realigned interrupt handler. */
+/* { dg-do run } */
+/* { dg-options "-mthumb -Os" } */
+/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */
+/* { dg-require-effective-target arm_cortex_m } */
+/* { dg-require-effective-target arm_eabi } */
+
+extern __attribute__((noreturn)) void abort(void);
+extern int snprintf(char *, int, const char *, ...);
+
+#define BUFF_LEN 256
+char buff[BUFF_LEN];
+
+char *get_buffer(void)
+{
+       return buff;
+}
+
+void __attribute__((interrupt)) foo(void)
+{
+        char *msg = get_buffer();
+        snprintf(msg, BUFF_LEN, "%d %p", 1, buff+BUFF_LEN);
+}
+
+volatile void * save_sp;
+int main()
+{
+       register volatile void * sp asm("sp");
+       /* Check stack pointer before/after calling the interrupt
+         * handler. Not equal means that handler doesn't restore
+         * stack correctly.  */
+       save_sp = sp;
+       foo();
+       /* Abort here instead of return non-zero. Due to wrong sp, lr value,
+        * returning from main may not work.  */
+       if (save_sp != sp)
+       {
+               sp = save_sp;
+               abort();
+       }
+       return 0;
+}
index 28dedc9..54dc6b6 100644 (file)
@@ -2116,6 +2116,19 @@ proc check_effective_target_arm_thumb2 { } {
     } ""]
 }
 
+# Return 1 if this is an ARM cortex-M profile cpu
+
+proc check_effective_target_arm_cortex_m { } {
+    return [check_no_compiler_messages arm_cortex_m assembly {
+       #if !defined(__ARM_ARCH_7M__) \
+            && !defined (__ARM_ARCH_7EM__) \
+            && !defined (__ARM_ARCH_6M__)
+       #error FOO
+       #endif
+       int i;
+    } "-mthumb"]
+}
+
 # Return 1 if the target supports executing NEON instructions, 0
 # otherwise.  Cache the result.