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]

Blackfin patch: stack checking


When your system doesn't have virtual memory, stack checking is a pretty
important issue.  We currently support -fstack-limit-symbol for flat
binaries, but not for FD-PIC ELF ones, and it doesn't work for threaded
programs either.
This implements an additional method that uses a word in a known memory
location to hold the lowest stack address.  This is about equivalent to
using a register, but slightly more convenient in that you can link code
that isn't compiled with stack checking and doesn't need to be aware of
having to keep that reg untouched.

Committed as 119049.  Looking at the patch now it seems my invoke.texi
patch from yesterday didn't get committed last time; it's included in
this commit.


Bernd
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 119048)
+++ ChangeLog	(working copy)
@@ -1,3 +1,14 @@
+2006-11-21  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+	* config/bfin/bfin.opt (mstack-check-l1): New.
+	* doc/invoke.texi (Blackfin Options): Document it.
+	* config/bfin/bfin.c (bfin_expand_prologue): Generate code to use
+	stack bounds in L1 memory if the new option is enabled.
+	(override_options): Don't allow combinations of -fstack-limit and
+	-mstack-check-l1.
+	(add_to_reg): Renamed from add_to_sp.  All callers changed.  Lose some
+	dead code.
+
 2006-11-21  Ben Elliston  <bje@au.ibm.com>
 
 	* config/spu/spu.c (spu_expand_vector_init): Initialise x.
Index: config/bfin/bfin.c
===================================================================
--- config/bfin/bfin.c	(revision 119048)
+++ config/bfin/bfin.c	(working copy)
@@ -547,12 +547,12 @@ frame_related_constant_load (rtx reg, HO
     RTX_FRAME_RELATED_P (insn) = 1;
 }
 
-/* Generate efficient code to add a value to the frame pointer.  We
-   can use P1 as a scratch register.  Set RTX_FRAME_RELATED_P on the
-   generated insns if FRAME is nonzero.  */
+/* Generate efficient code to add a value to a P register.  We can use
+   P1 as a scratch register.  Set RTX_FRAME_RELATED_P on the generated
+   insns if FRAME is nonzero.  */
 
 static void
-add_to_sp (rtx spreg, HOST_WIDE_INT value, int frame)
+add_to_reg (rtx reg, HOST_WIDE_INT value, int frame)
 {
   if (value == 0)
     return;
@@ -568,13 +568,9 @@ add_to_sp (rtx spreg, HOST_WIDE_INT valu
       if (frame)
 	frame_related_constant_load (tmpreg, value, TRUE);
       else
-	{
-	  insn = emit_move_insn (tmpreg, GEN_INT (value));
-	  if (frame)
-	    RTX_FRAME_RELATED_P (insn) = 1;
-	}
+	insn = emit_move_insn (tmpreg, GEN_INT (value));
 
-      insn = emit_insn (gen_addsi3 (spreg, spreg, tmpreg));
+      insn = emit_insn (gen_addsi3 (reg, reg, tmpreg));
       if (frame)
 	RTX_FRAME_RELATED_P (insn) = 1;
     }
@@ -591,7 +587,7 @@ add_to_sp (rtx spreg, HOST_WIDE_INT valu
 	     it's no good.  */
 	  size = -60;
 
-	insn = emit_insn (gen_addsi3 (spreg, spreg, GEN_INT (size)));
+	insn = emit_insn (gen_addsi3 (reg, reg, GEN_INT (size)));
 	if (frame)
 	  RTX_FRAME_RELATED_P (insn) = 1;
 	value -= size;
@@ -684,7 +680,7 @@ do_link (rtx spreg, HOST_WIDE_INT frame_
 	  rtx insn = emit_insn (pat);
 	  RTX_FRAME_RELATED_P (insn) = 1;
 	}
-      add_to_sp (spreg, -frame_size, 1);
+      add_to_reg (spreg, -frame_size, 1);
     }
 }
 
@@ -701,7 +697,7 @@ do_unlink (rtx spreg, HOST_WIDE_INT fram
     {
       rtx postinc = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, spreg));
 
-      add_to_sp (spreg, frame_size, 0);
+      add_to_reg (spreg, frame_size, 0);
       if (must_save_fp_p ())
 	{
 	  rtx fpreg = gen_rtx_REG (Pmode, REG_FP);
@@ -911,16 +907,24 @@ bfin_expand_prologue (void)
       return;
     }
 
-  if (current_function_limit_stack)
+  if (current_function_limit_stack
+      || TARGET_STACK_CHECK_L1)
     {
       HOST_WIDE_INT offset
 	= bfin_initial_elimination_offset (ARG_POINTER_REGNUM,
 					   STACK_POINTER_REGNUM);
-      rtx lim = stack_limit_rtx;
+      rtx lim = current_function_limit_stack ? stack_limit_rtx : NULL_RTX;
+      rtx p2reg = gen_rtx_REG (Pmode, REG_P2);
 
+      if (!lim)
+	{
+	  rtx p1reg = gen_rtx_REG (Pmode, REG_P1);
+	  emit_move_insn (p2reg, gen_int_mode (0xFFB00000, SImode));
+	  emit_move_insn (p2reg, gen_rtx_MEM (Pmode, p2reg));
+	  lim = p2reg;
+	}
       if (GET_CODE (lim) == SYMBOL_REF)
 	{
-	  rtx p2reg = gen_rtx_REG (Pmode, REG_P2);
 	  if (TARGET_ID_SHARED_LIBRARY)
 	    {
 	      rtx p1reg = gen_rtx_REG (Pmode, REG_P1);
@@ -935,11 +939,18 @@ bfin_expand_prologue (void)
 	    }
 	  else
 	    {
-	      rtx limit = plus_constant (stack_limit_rtx, offset);
+	      rtx limit = plus_constant (lim, offset);
 	      emit_move_insn (p2reg, limit);
 	      lim = p2reg;
 	    }
 	}
+      else
+	{
+	  if (lim != p2reg)
+	    emit_move_insn (p2reg, lim);
+	  add_to_reg (p2reg, offset, 0);
+	  lim = p2reg;
+	}
       emit_insn (gen_compare_lt (bfin_cc_rtx, spreg, lim));
       emit_insn (gen_trapifcc ());
     }
@@ -2026,8 +2037,11 @@ override_options (void)
   if (TARGET_ID_SHARED_LIBRARY && flag_pic == 0)
     flag_pic = 1;
 
+  if (stack_limit_rtx && TARGET_STACK_CHECK_L1)
+    error ("Can't use multiple stack checking methods together.");
+
   if (TARGET_ID_SHARED_LIBRARY && TARGET_FDPIC)
-      error ("ID shared libraries and FD-PIC mode can't be used together.");
+    error ("ID shared libraries and FD-PIC mode can't be used together.");
 
   /* Don't allow the user to specify -mid-shared-library and -msep-data
      together, as it makes little sense from a user's point of view...  */
Index: config/bfin/bfin.opt
===================================================================
--- config/bfin/bfin.opt	(revision 119048)
+++ config/bfin/bfin.opt	(working copy)
@@ -60,3 +60,7 @@ Avoid generating pc-relative calls; use 
 mfdpic
 Target Report Mask(FDPIC)
 Enable Function Descriptor PIC mode
+
+mstack-check-l1
+Target Report Mask(STACK_CHECK_L1)
+Do stack checking using bounds in L1 scratch memory
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 119048)
+++ doc/invoke.texi	(working copy)
@@ -429,9 +429,10 @@ Objective-C and Objective-C++ Dialects}.
 @emph{Blackfin Options}
 @gccoptlist{-momit-leaf-frame-pointer -mno-omit-leaf-frame-pointer @gol
 -mspecld-anomaly -mno-specld-anomaly -mcsync-anomaly -mno-csync-anomaly @gol
--mlow-64k -mno-low64k -mid-shared-library @gol
+-mlow-64k  -mno-low64k  -mstack-check-l1  -mid-shared-library @gol
 -mno-id-shared-library -mshared-library-id=@var{n} @gol
--mlong-calls  -mno-long-calls}
+-mleaf-id-shared-library  -mno-leaf-id-shared-library @gol
+-msep-data  -mno-sep-data  -mlong-calls  -mno-long-calls}
 
 @emph{CRIS Options}
 @gccoptlist{-mcpu=@var{cpu}  -march=@var{cpu}  -mtune=@var{cpu} @gol
@@ -7845,6 +7846,11 @@ the entire program fits into the low 64k
 @opindex mno-low-64k
 Assume that the program is arbitrarily large.  This is the default.
 
+@item -mstack-check-l1
+@opindex mstack-check-l1
+Do stack checking using information placed into L1 scratchpad memory by the
+uClinux kernel.
+
 @item -mid-shared-library
 @opindex mid-shared-library
 Generate code that supports shared libraries via the library ID method.
@@ -7856,6 +7862,18 @@ without virtual memory management.  This
 Generate code that doesn't assume ID based shared libraries are being used.
 This is the default.
 
+@item -mleaf-id-shared-library
+@opindex mleaf-id-shared-library
+Generate code that supports shared libraries via the library ID method,
+but assumes that this library or executable won't link against any other
+ID shared libraries.  That allows the compiler to use faster code for jumps
+and calls.
+
+@item -mno-leaf-id-shared-library
+@opindex mno-leaf-id-shared-library
+Do not assume that the code being compiled won't link against any ID shared
+libraries.  Slower code will be generated for jump and call insns.
+
 @item -mshared-library-id=n
 @opindex mshared-library-id
 Specified the identification number of the ID based shared library being
@@ -7863,6 +7881,18 @@ compiled.  Specifying a value of 0 will 
 other values will force the allocation of that number to the current
 library but is no more space or time efficient than omitting this option.
 
+@item -msep-data
+@opindex msep-data
+Generate code that allows the data segment to be located in a different
+area of memory from the text segment.  This allows for execute in place in
+an environment without virtual memory management by eliminating relocations
+against the text section.
+
+@item -mno-sep-data
+@opindex mno-sep-data
+Generate code that assumes that the data segment follows the text segment.
+This is the default.
+
 @item -mlong-calls
 @itemx -mno-long-calls
 @opindex mlong-calls

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