nios2.c (TEMP_REG_NUM): Move define up in file.
authorSandra Loosemore <sandra@codesourcery.com>
Tue, 14 Jul 2015 19:19:35 +0000 (15:19 -0400)
committerSandra Loosemore <sandra@gcc.gnu.org>
Tue, 14 Jul 2015 19:19:35 +0000 (15:19 -0400)
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.

From-SVN: r225787

gcc/ChangeLog
gcc/config/nios2/nios2.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/nios2/nios2-stack-check-1.c
gcc/testsuite/gcc.target/nios2/nios2-stack-check-2.c
gcc/testsuite/gcc.target/nios2/nios2-stack-check-3.c [new file with mode: 0644]

index a34eb8d975d26a800daa05ee89f81ccebf8909ef..79e5ba01c7a56d744f57101950dd49cd5b12102e 100644 (file)
@@ -1,3 +1,13 @@
+2015-07-14  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * 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.
+
 2015-07-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        * Makefile.in (top_srcdir): New.
index 77dac5795c6d6295f63ba3e0018b8054fdebc0a3..a0fb435f5a1f6536e26f633060b520aa2d91bc36 100644 (file)
@@ -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;
index c0932facf701aa18acee570370fa2ca339baabf8..6284431035a161373bf5171a619006db4e89b831 100644 (file)
@@ -1,3 +1,9 @@
+2015-07-14  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * 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.
+
 2015-07-14  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * g++.dg/template/crash81.C: Adjust for error + inform change.
index e64e4f7e4117e33678329157a11cd2bdddc965b4..730c8126efbc56a6564efef30104711eee161914 100644 (file)
@@ -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 b903db5cdc429a30757cdb2e358897e669e40fb7..a7aa677eb6631d6a4e4f95587509d4c020d8f8ef 100644 (file)
@@ -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()
 {
diff --git a/gcc/testsuite/gcc.target/nios2/nios2-stack-check-3.c b/gcc/testsuite/gcc.target/nios2/nios2-stack-check-3.c
new file mode 100644 (file)
index 0000000..33cf522
--- /dev/null
@@ -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;
+}