This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ARM] Fix prologue and epilogue for interrupt function


On 07/07/2010 09:49 PM, Paul Brook wrote:
ARM GCC will save r3 to the stack when it tries to align the stack to
double-word. But it can only do so when r3 will not be saved. Otherwise
there will be inconsistent information about how many registers will be
saved and how much the stack will be adjusted. This patch fixes it.

Tested on arm-none-eabi. No regressions are found. Is it OK?

Your test fails for Thumb multilibs.


Other than that, ok.

Here is the updated patch, with test cases updated. The method used in the tests to make them work with thumb is Paul's idea. I will commit on trunk and 4.5 branch soon.


-- Jie Zhang CodeSourcery
	* config/arm/arm.c (arm_get_frame_offsets): Don't use r3 to
	align the stack when it's going to be saved.

	testsuite/
	* gcc.target/arm/interrupt-1.c: New test.
	* gcc.target/arm/interrupt-2.c: New test.

Index: testsuite/gcc.target/arm/interrupt-1.c
===================================================================
--- testsuite/gcc.target/arm/interrupt-1.c	(revision 0)
+++ testsuite/gcc.target/arm/interrupt-1.c	(revision 0)
@@ -0,0 +1,23 @@
+/* Verify that prologue and epilogue are correct for functions with
+   __attribute__ ((interrupt)).  */
+/* { dg-do compile } */
+/* { dg-options "-O0" } */
+
+/* This test is not valid when -mthumb.  We just cheat.  */
+#ifndef __thumb__
+extern void bar (int);
+extern void foo (void) __attribute__ ((interrupt("IRQ")));
+
+void foo ()
+{
+  bar (0);
+}
+#else
+void foo ()
+{
+  asm ("stmfd\tsp!, {r0, r1, r2, r3, r4, fp, ip, lr}");
+  asm ("ldmfd\tsp!, {r0, r1, r2, r3, r4, fp, ip, pc}^");
+}
+#endif
+/* { dg-final { scan-assembler "stmfd\tsp!, {r0, r1, r2, r3, r4, fp, ip, lr}" } } */
+/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, r4, fp, ip, pc}\\^" } } */
Index: testsuite/gcc.target/arm/interrupt-2.c
===================================================================
--- testsuite/gcc.target/arm/interrupt-2.c	(revision 0)
+++ testsuite/gcc.target/arm/interrupt-2.c	(revision 0)
@@ -0,0 +1,26 @@
+/* Verify that prologue and epilogue are correct for functions with
+   __attribute__ ((interrupt)).  */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+/* This test is not valid when -mthum.  We just cheat.  */
+#ifndef __thumb__
+extern void bar (int);
+extern void test (void) __attribute__((__interrupt__));
+
+int foo;
+void test()
+{
+  funcptrs(foo);
+  foo = 0;
+}
+#else
+void test ()
+{
+  asm ("stmfd\tsp!, {r0, r1, r2, r3, r4, r5, ip, lr}");
+  asm ("ldmfd\tsp!, {r0, r1, r2, r3, r4, r5, ip, pc}^");
+}
+#endif
+
+/* { dg-final { scan-assembler "stmfd\tsp!, {r0, r1, r2, r3, r4, r5, ip, lr}" } } */
+/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, r4, r5, ip, pc}\\^" } } */
Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c	(revision 162071)
+++ config/arm/arm.c	(working copy)
@@ -14691,7 +14691,8 @@ arm_get_frame_offsets (void)
 	     generates better code on Thumb-2 by avoiding the need to
 	     use 32-bit push/pop instructions.  */
 	  if (!crtl->tail_call_emit
-	      && arm_size_return_regs () <= 12)
+	      && arm_size_return_regs () <= 12
+	      && (offsets->saved_regs_mask & (1 << 3)) == 0)
 	    {
 	      reg = 3;
 	    }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]