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]

[PATCH,rs6000] fix interrupt safety issue on E500 targets


The attached patch fixes an interrupt safety problem on E500 targets;
this problem was introduced by the ABI fixes that were committed several
months ago.  On SPE targets we would generate the following code for a
function epilogue:

    point r11 into the stack frame
    restore registers
    restore stack pointer
    return

and the instruction scheduler, being clever, would turn this into:

    point r11 into the stack frame
    restore a few registers
    restore stack pointer
    restore remaining registers		(XXX)
    return

Which causes problems if an interrupt happens during XXX because the OS
will clobber the space from which we are restoring registers, believing
it to be unused.

The fix is simple.  We just have to tell the scheduler that we
have a blocking insn just before the restore of the stack pointer.

Tested on powerpc-none-linux-gnuspe with no regressions.  OK to commit?

-Nathan

2007-10-03  Nathan Froyd  <froydnj@codesourcery.com>

	gcc/
	* config/rs6000/rs6000.c (rs6000_emit_epilogue): Emit a stack tie
	when compiling for SPE targets due to r11 pointing into the frame.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 128981)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -16329,13 +16329,18 @@ rs6000_emit_epilogue (int sibcall)
 	    }
     }
 
+  if (frame_reg_rtx != sp_reg_rtx
+      || (TARGET_SPE_ABI
+          && info->spe_64bit_regs_used != 0
+          && info->first_gp_reg_save != 32))
+    /* This blockage is needed so that sched doesn't decide to move
+       the sp change before the register restores.  */
+    rs6000_emit_stack_tie ();
+    
   /* If this is V.4, unwind the stack pointer after all of the loads
      have been done.  */
   if (frame_reg_rtx != sp_reg_rtx)
     {
-      /* This blockage is needed so that sched doesn't decide to move
-	 the sp change before the register restores.  */
-      rs6000_emit_stack_tie ();
       if (TARGET_SPE_ABI
           && info->spe_64bit_regs_used != 0
           && info->first_gp_reg_save != 32)

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