public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch, nios2] stack limit checking improvements
@ 2015-07-14 20:06 Sandra Loosemore
  2015-07-16  7:05 ` Sandra Loosemore
  0 siblings, 1 reply; 2+ messages in thread
From: Sandra Loosemore @ 2015-07-14 20:06 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 501 bytes --]

In preparation for some other changes to the Nios II prologue code that 
are in my queue, I've checked in the attached patch to the stack limit 
checking logic.  With this patch, the check generation code now takes an 
offset so that the check can be emitted before the SP adjustment; this 
allows cases where multiple stack adjustments are emitted to do only a 
single stack limit check.

While I was at it, I also added support for -fstack-limit-symbol as well 
as -fstack-limit-register.

-Sandra


[-- Attachment #2: gcc-stack-check.log --]
[-- Type: text/x-log, Size: 641 bytes --]

2015-07-14  Sandra Loosemore  <sandra@codesourcery.com>

	gcc/
	* config/nios2/nios2.c (TEMP_REG_NUM): Move define up in file.
	(nios2_emit_stack_limit_check): Add size parameter.  Handle
	-fstack-limit-symbol as well as -fstack-limit-register.
	(nios2_expand_prologue): Emit only a single stack limit check,
	even if multiple stack adjustments are required.
	(nios2_option_override): Diagnose unsupported combination of -fpic
	and -stack-limit-symbol.

	gcc/testsuite/
	* gcc.target/nios2/nios2-stack-check-1.c: Adjust patterns.
	* gcc.target/nios2/nios2-stack-check-2.c: Likewise.
	* gcc.target/nios2/nios2-stack-check-3.c: New test case.

[-- Attachment #3: gcc-stack-check.patch --]
[-- Type: text/x-patch, Size: 5620 bytes --]

Index: gcc/testsuite/gcc.target/nios2/nios2-stack-check-1.c
===================================================================
--- gcc/testsuite/gcc.target/nios2/nios2-stack-check-1.c	(revision 225722)
+++ gcc/testsuite/gcc.target/nios2/nios2-stack-check-1.c	(working copy)
@@ -1,7 +1,8 @@
 /* { dg-do compile } */
 /* { dg-options "-fstack-limit-register=et" } */
-/* { dg-final { scan-assembler "bgeu\\tsp, et" } } */
-/* { dg-final { scan-assembler "trap\\t3" } } */
+/* { dg-final { scan-assembler "bgeu\\tsp, " } } */
+/* { dg-final { scan-assembler "trap\\t3|trap.n\\t3" } } */
+
 /* check stack checking */
 void test()
 {
Index: gcc/testsuite/gcc.target/nios2/nios2-stack-check-2.c
===================================================================
--- gcc/testsuite/gcc.target/nios2/nios2-stack-check-2.c	(revision 225722)
+++ gcc/testsuite/gcc.target/nios2/nios2-stack-check-2.c	(working copy)
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options " " } */
-/* { dg-final { scan-assembler-not "bgeu\\tsp, et" } } */
-/* { dg-final { scan-assembler-not "break\\t3" } } */
+/* { dg-final { scan-assembler-not "trap\\t3|trap.n\\t3" } } */
+
 /* check stack checking */
 void test()
 {
Index: gcc/testsuite/gcc.target/nios2/nios2-stack-check-3.c
===================================================================
--- gcc/testsuite/gcc.target/nios2/nios2-stack-check-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/nios2/nios2-stack-check-3.c	(revision 0)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-fstack-limit-symbol=__stackend -fno-pic" } */
+/* { dg-final { scan-assembler "movhi\\t.*, %hiadj\\(__stackend.*\\)" } } */
+/* { dg-final { scan-assembler "addi\\t.*, .*, %lo\\(__stackend.*\\)" } } */
+/* { dg-final { scan-assembler "bgeu\\tsp, " } } */
+/* { dg-final { scan-assembler "trap\\t3|trap.n\\t3" } } */
+
+/* check stack checking */
+void test()
+{
+  int a, b, c;
+}
Index: gcc/config/nios2/nios2.c
===================================================================
--- gcc/config/nios2/nios2.c	(revision 225722)
+++ gcc/config/nios2/nios2.c	(working copy)
@@ -456,20 +456,47 @@ restore_reg (int regno, unsigned offset)
   RTX_FRAME_RELATED_P (insn) = 1;
 }
 
-/* Emit conditional trap for checking stack limit.  */
+/* Temp regno used inside prologue/epilogue.  */
+#define TEMP_REG_NUM 8
+
+/* Emit conditional trap for checking stack limit.  SIZE is the number of
+   additional bytes required.  
+
+   GDB prologue analysis depends on this generating a direct comparison
+   to the SP register, so the adjustment to add SIZE needs to be done on
+   the other operand to the comparison.  Use TEMP_REG_NUM as a temporary,
+   if necessary.  */
 static void
-nios2_emit_stack_limit_check (void)
+nios2_emit_stack_limit_check (int size)
 {
-  if (REG_P (stack_limit_rtx))
-    emit_insn (gen_ctrapsi4 (gen_rtx_LTU (VOIDmode, stack_pointer_rtx,
-					  stack_limit_rtx),
-			     stack_pointer_rtx, stack_limit_rtx, GEN_INT (3)));
+  rtx sum;
+
+  if (GET_CODE (stack_limit_rtx) == SYMBOL_REF)
+    {
+      /* This generates a %hiadj/%lo pair with the constant size
+	 add handled by the relocations.  */
+      sum = gen_rtx_REG (Pmode, TEMP_REG_NUM);
+      emit_move_insn (sum, plus_constant (Pmode, stack_limit_rtx, size));
+    }
+  else if (!REG_P (stack_limit_rtx))
+    sorry ("Unknown form for stack limit expression");
+  else if (size == 0)
+    sum = stack_limit_rtx;
+  else if (SMALL_INT (size))
+    {
+      sum = gen_rtx_REG (Pmode, TEMP_REG_NUM);
+      emit_move_insn (sum, plus_constant (Pmode, stack_limit_rtx, size));
+    }
   else
-    sorry ("only register based stack limit is supported");
-}
+    {
+      sum = gen_rtx_REG (Pmode, TEMP_REG_NUM);
+      emit_move_insn (sum, gen_int_mode (size, Pmode));
+      emit_insn (gen_add2_insn (sum, stack_limit_rtx));
+    }
 
-/* Temp regno used inside prologue/epilogue.  */
-#define TEMP_REG_NUM 8
+  emit_insn (gen_ctrapsi4 (gen_rtx_LTU (VOIDmode, stack_pointer_rtx, sum),
+			   stack_pointer_rtx, sum, GEN_INT (3)));
+}
 
 static rtx_insn *
 nios2_emit_add_constant (rtx reg, HOST_WIDE_INT immed)
@@ -511,6 +538,8 @@ nios2_expand_prologue (void)
       RTX_FRAME_RELATED_P (insn) = 1;
       save_regs_base = 0;
       sp_offset = -cfun->machine->save_regs_offset;
+      if (crtl->limit_stack)
+	nios2_emit_stack_limit_check (cfun->machine->save_regs_offset);
     }
   else if (total_frame_size)
     {
@@ -520,13 +549,12 @@ nios2_expand_prologue (void)
       RTX_FRAME_RELATED_P (insn) = 1;
       save_regs_base = cfun->machine->save_regs_offset;
       sp_offset = 0;
+      if (crtl->limit_stack)
+	nios2_emit_stack_limit_check (0);
     }
   else
     save_regs_base = sp_offset = 0;
 
-  if (crtl->limit_stack)
-    nios2_emit_stack_limit_check ();
-
   save_offset = save_regs_base + cfun->machine->save_reg_size;
 
   for (regno = LAST_GP_REG; regno > 0; regno--)
@@ -561,9 +589,6 @@ nios2_expand_prologue (void)
 	  add_reg_note (insn, REG_FRAME_RELATED_EXPR, sp_adjust);
 	}
       RTX_FRAME_RELATED_P (insn) = 1;
-
-      if (crtl->limit_stack)
-	nios2_emit_stack_limit_check ();
     }
 
   /* Load the PIC register if needed.  */
@@ -1029,6 +1054,9 @@ nios2_option_override (void)
   /* Check for unsupported options.  */
   if (flag_pic && !TARGET_LINUX_ABI)
     sorry ("position-independent code requires the Linux ABI");
+  if (flag_pic && stack_limit_rtx
+      && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
+    sorry ("PIC support for -fstack-limit-symbol");
 
   /* Function to allocate machine-dependent function status.  */
   init_machine_status = &nios2_init_machine_status;

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [patch, nios2] stack limit checking improvements
  2015-07-14 20:06 [patch, nios2] stack limit checking improvements Sandra Loosemore
@ 2015-07-16  7:05 ` Sandra Loosemore
  0 siblings, 0 replies; 2+ messages in thread
From: Sandra Loosemore @ 2015-07-16  7:05 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 989 bytes --]

On 07/14/2015 01:31 PM, Sandra Loosemore wrote:
> 2015-07-14  Sandra Loosemore  <sandra@codesourcery.com>
>
> 	gcc/
> 	* config/nios2/nios2.c (TEMP_REG_NUM): Move define up in file.
> 	(nios2_emit_stack_limit_check): Add size parameter.  Handle
> 	-fstack-limit-symbol as well as -fstack-limit-register.
> 	(nios2_expand_prologue): Emit only a single stack limit check,
> 	even if multiple stack adjustments are required.
> 	(nios2_option_override): Diagnose unsupported combination of -fpic
> 	and -stack-limit-symbol.
>
> 	gcc/testsuite/
> 	* gcc.target/nios2/nios2-stack-check-1.c: Adjust patterns.
> 	* gcc.target/nios2/nios2-stack-check-2.c: Likewise.
> 	* gcc.target/nios2/nios2-stack-check-3.c: New test case.

Ooops -- this patch caused a possibly-uninitialized-variable 
warning.(Mainline compiles had been very noisy with other random 
warnings while I was working on this, and it was easy to overlook one 
more warning....)
Anyway, fixed now with this followup patch.

-Sandra


[-- Attachment #2: gcc.log --]
[-- Type: text/x-log, Size: 156 bytes --]

2015-07-16  Sandra Loosemore  <sandra@codesourcery.com>

	gcc/
	* config/nios2/nios2.c (nios2_emit_stack_limit_check): Fix
	uninitialized-variable warning.

[-- Attachment #3: gcc.patch --]
[-- Type: text/x-patch, Size: 402 bytes --]

Index: gcc/config/nios2/nios2.c
===================================================================
--- gcc/config/nios2/nios2.c	(revision 225856)
+++ gcc/config/nios2/nios2.c	(working copy)
@@ -563,7 +563,7 @@ nios2_create_cfa_notes (rtx_insn *insn, 
 static void
 nios2_emit_stack_limit_check (int size)
 {
-  rtx sum;
+  rtx sum = NULL_RTX;
 
   if (GET_CODE (stack_limit_rtx) == SYMBOL_REF)
     {

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-07-16  4:05 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-14 20:06 [patch, nios2] stack limit checking improvements Sandra Loosemore
2015-07-16  7:05 ` Sandra Loosemore

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).