aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorGeoff Keating <geoffk@cygnus.com>1999-12-04 03:00:04 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>1999-12-04 03:00:04 +0000
commita157febd0ca69d5b4570fc714c141fd5da555a7a (patch)
tree9c9c8b5fa8e01f95d849e7b0f24402c7081b73d4 /gcc/config
parent3c12fcc27809a223032e1b0ad2beba1f6844a5c6 (diff)
downloadgcc-a157febd0ca69d5b4570fc714c141fd5da555a7a.zip
gcc-a157febd0ca69d5b4570fc714c141fd5da555a7a.tar.gz
gcc-a157febd0ca69d5b4570fc714c141fd5da555a7a.tar.bz2
c-common.c (enum attrs): Add A_NO_LIMIT_STACK.
* c-common.c (enum attrs): Add A_NO_LIMIT_STACK. (init_attributes): Add A_NO_LIMIT_STACK. (decl_attributes): Handle A_NO_LIMIT_STACK. * c-decl.c (duplicate_decls): Handle DECL_NO_LIMIT_STACK. * explow.c (allocate_dynamic_stack_space) [!HAVE_allocate_stack]: Handle stack bounds checking. * flags.h (flag_stack_check): Use the word 'probe' rather than 'check', because the flag doesn't actually cause any checking to be done. * function.c (expand_function_start): Set current_function_limit_stack. * function.h (struct function): Add limit_stack. (current_function_limit_stack): Define. * invoke.texi (Code Gen Options): Document new options. * rtl.h: Declare stack_limit_rtx. * toplev.c (stack_limit_rtx): New variable. (decode_f_option): Handle new options -fstack-limit-register=REG, -fstack-limit-symbol=IDENT, -fno-stack-limit. (main): Add stack_limit_rtx as GC root. * tree.h (DECL_NO_LIMIT_STACK): New macro. (struct tree_decl): New member no_limit_stack. * config/rs6000/rs6000.c (rs6000_allocate_stack_space): Handle stack_limit_rtx. * config/rs6000/rs6000.md (allocate_stack): Handle stack_limit_rtx. (conditional_trap+1): Get new mnemonic correct. (conditional_trap+2): New pattern for DImode traps. * config/m68k/m68k.c (output_function_prologue): Handle stack_limit_rtx. * config/m68k/m68k.md (trap): New insn. (conditional_trap): New insn. * md.texi (Standard Names): Document `trap' and `conditional_trap'. * optabs.c (gen_cond_trap): Use start_sequence()/end_sequence() so a cc0 setter doesn't get emitted at some random place in the function. * config/i960/i960.md (trap): New insn. (conditional_trap): New expander. (conditional_trap+1, conditional_trap+2): New insns for signed and unsigned cases. * config/i960/i960.c (i960_function_prologue): Use STARTING_FRAME_OFFSET. Handle stack_limit_rtx. Co-Authored-By: Greg McGary <gkm@gnu.org> From-SVN: r30771
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i960/i960.c31
-rw-r--r--gcc/config/i960/i960.md33
-rw-r--r--gcc/config/m68k/m68k.c31
-rw-r--r--gcc/config/m68k/m68k.md28
-rw-r--r--gcc/config/rs6000/rs6000.c47
-rw-r--r--gcc/config/rs6000/rs6000.md20
6 files changed, 188 insertions, 2 deletions
diff --git a/gcc/config/i960/i960.c b/gcc/config/i960/i960.c
index c7dc008..0c9ae30 100644
--- a/gcc/config/i960/i960.c
+++ b/gcc/config/i960/i960.c
@@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA. */
#include "except.h"
#include "function.h"
#include "recog.h"
+#include "toplev.h"
#include <math.h>
/* Save the operands last given to a compare for use when we
@@ -1431,6 +1432,34 @@ i960_function_prologue (file, size)
actual_fsize = (actual_fsize + 15) & ~0xF;
#endif
+ /* Check stack limit if necessary. */
+ if (current_function_limit_stack)
+ {
+ rtx min_stack = stack_limit_rtx;
+ if (actual_fsize != 0)
+ min_stack = plus_constant (stack_limit_rtx, -actual_fsize);
+
+ /* Now, emulate a little bit of reload. We want to turn 'min_stack'
+ into an arith_operand. Use register 20 as the temporary. */
+ if (legitimate_address_p (Pmode, min_stack, 1)
+ && !arith_operand (min_stack, Pmode))
+ {
+ rtx tmp = gen_rtx_MEM (Pmode, min_stack);
+ fputs ("\tlda\t", file);
+ i960_print_operand (file, tmp, 0);
+ fputs (",r4\n", file);
+ min_stack = gen_rtx_REG (Pmode, 20);
+ }
+ if (arith_operand (min_stack, Pmode))
+ {
+ fputs ("\tcmpo\tsp,", file);
+ i960_print_operand (file, min_stack, 0);
+ fputs ("\n\tfaultge.f\n", file);
+ }
+ else
+ warning ("stack limit expression is not supported");
+ }
+
/* Allocate space for register save and locals. */
if (actual_fsize > 0)
{
@@ -1443,7 +1472,7 @@ i960_function_prologue (file, size)
/* Take hardware register save area created by the call instruction
into account, but store them before the argument block area. */
lvar_size = actual_fsize - compute_frame_size (0) - n_saved_regs * 4;
- offset = 64 + lvar_size;
+ offset = STARTING_FRAME_OFFSET + lvar_size;
/* Save registers on stack if needed. */
/* ??? Is it worth to use the same algorithm as one for saving
global registers in local registers? */
diff --git a/gcc/config/i960/i960.md b/gcc/config/i960/i960.md
index 1e5c112..38c14ba 100644
--- a/gcc/config/i960/i960.md
+++ b/gcc/config/i960/i960.md
@@ -540,6 +540,39 @@
"cmp%S0%B0%X0 %2,%1,%l3"
[(set_attr "type" "branch")])
+;; Now the trap instructions. The i960 appears to only have conditional
+;; traps...
+
+(define_insn ("trap")
+ [(trap_if (const_int 1) (const_int 0))]
+ ""
+ "cmpo g0,g0 ; faulteq.t")
+
+(define_expand "conditional_trap"
+ [(trap_if (match_operator 0 "comparison_operator"
+ [(match_dup 2) (const_int 0)])
+ (match_operand 1 "const_int_operand" "i"))]
+ ""
+ "
+{
+ operands[2] = gen_compare_reg (GET_CODE (operands[0]),
+ i960_compare_op0, i960_compare_op1);
+}")
+
+(define_insn ""
+ [(trap_if (match_operator 0 "comparison_operator"
+ [(reg:CC 36) (const_int 0)])
+ (match_operand 1 "const_int_operand" "i"))]
+ ""
+ "fault%C0.f")
+
+(define_insn ""
+ [(trap_if (match_operator 0 "comparison_operator"
+ [(reg:CC_UNS 36) (const_int 0)])
+ (match_operand 1 "const_int_operand" "i"))]
+ ""
+ "fault%C0.f")
+
;; Normal move instructions.
;; This code is based on the sparc machine description.
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index f718ccd..8a798b7 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -151,6 +151,19 @@ output_function_prologue (stream, size)
int fsize = (size + 3) & -4;
int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset;
+ /* If the stack limit is a symbol, we can check it here,
+ before actually allocating the space. */
+ if (current_function_limit_stack
+ && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
+ {
+#if defined (MOTOROLA)
+ asm_fprintf (stream, "\tcmp.l %0I%s+%d,%Rsp\n\ttrapcs\n",
+ XSTR (stack_limit_rtx, 0), fsize + 4);
+#else
+ asm_fprintf (stream, "\tcmpl %0I%s+%d,%Rsp\n\ttrapcs\n",
+ XSTR (stack_limit_rtx, 0), fsize + 4);
+#endif
+ }
if (frame_pointer_needed)
{
@@ -374,6 +387,24 @@ output_function_prologue (stream, size)
#endif
#endif
+ /* If the stack limit is not a symbol, check it here.
+ This has the disadvantage that it may be too late... */
+ if (current_function_limit_stack)
+ {
+ if (REG_P (stack_limit_rtx))
+ {
+#if defined (MOTOROLA)
+ asm_fprintf (stream, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
+ reg_names[REGNO (stack_limit_rtx)]);
+#else
+ asm_fprintf (stream, "\tcmpl %s,%Rsp\n\ttrapcs\n",
+ reg_names[REGNO (stack_limit_rtx)]);
+#endif
+ }
+ else if (GET_CODE (stack_limit_rtx) != SYMBOL_REF)
+ warning ("stack limit expression is not supported");
+ }
+
if (num_saved_regs <= 2)
{
/* Store each separately in the same order moveml uses.
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 8a95259..6217719 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -7897,3 +7897,31 @@
(unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 2))]
"TARGET_68881 && flag_fast_math"
"fcos%.x %1,%0")
+
+(define_insn "trap"
+ [(trap_if (const_int -1) (const_int 7))]
+ ""
+ "trap %#7")
+
+(define_insn "conditional_trap"
+ [(trap_if (match_operator 0 "valid_dbcc_comparison_p"
+ [(cc0) (const_int 0)])
+ (match_operand:SI 1 "const_int_operand" "I"))]
+ "TARGET_68020 && ! flags_in_68881 ()"
+ "*
+{
+ switch (GET_CODE (operands[0]))
+ {
+ case EQ: return \"trapeq\";
+ case NE: return \"trapne\";
+ case GT: return \"trapgt\";
+ case GTU: return \"traphi\";
+ case LT: return \"traplt\";
+ case LTU: return \"trapcs\";
+ case GE: return \"trapge\";
+ case GEU: return \"trapcc\";
+ case LE: return \"traple\";
+ case LEU: return \"trapls\";
+ default: abort();
+ }
+}")
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 250c8cd..a8db6d0 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -4176,6 +4176,53 @@ rs6000_allocate_stack_space (file, size, copy_r12)
int copy_r12;
{
int neg_size = -size;
+
+ if (current_function_limit_stack)
+ {
+ if (REG_P (stack_limit_rtx)
+ && REGNO (stack_limit_rtx) > 1
+ && REGNO (stack_limit_rtx) <= 31)
+ {
+ if (size <= 32767)
+ asm_fprintf (file, "\t{cal %s,%d(%s)|addi %s,%s,%d}\n",
+ reg_names[0], reg_names[REGNO (stack_limit_rtx)],
+ size);
+ else
+ {
+ asm_fprintf (file, "\t{cau|addis} %s,%s,0x%x\n",
+ reg_names[0], reg_names[REGNO (stack_limit_rtx)],
+ ((size + 0x8000) >> 16) & 0xffff);
+ asm_fprintf (file, "\t{ai|addic} %s,%s,%d\n",
+ reg_names[0], reg_names[0],
+ (size & 0x7fff) | -(size & 0x8000));
+ }
+ if (TARGET_32BIT)
+ asm_fprintf (file, "\t{t|tw}llt %s,%s\n",
+ reg_names[1], reg_names[0]);
+ else
+ asm_fprintf (file, "\ttdllt %s,%s\n", reg_names[1], reg_names[0]);
+ }
+ else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
+ && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
+ {
+ char * l_name = XSTR (stack_limit_rtx, 0);
+ const char * stripped_name;
+
+ STRIP_NAME_ENCODING (stripped_name, l_name);
+ asm_fprintf (file, "\t{liu|lis} %s,%s@ha+%d\n",
+ reg_names[0], stripped_name, size);
+ asm_fprintf (file, "\t{ai|addic} %s,%s,%s@l+%d\n",
+ reg_names[0], reg_names[0], stripped_name, size);
+ if (TARGET_32BIT)
+ asm_fprintf (file, "\t{t|tw}llt %s,%s\n",
+ reg_names[1], reg_names[0]);
+ else
+ asm_fprintf (file, "\ttdllt %s,%s\n", reg_names[1], reg_names[0]);
+ }
+ else
+ warning ("stack limit expression is not supported");
+ }
+
if (TARGET_UPDATE)
{
if (size < 32767)
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 8d6e85c..bde6369 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7882,6 +7882,16 @@
emit_move_insn (chain, stack_bot);
+ /* Check stack bounds if necessary. */
+ if (current_function_limit_stack)
+ {
+ rtx available;
+ available = expand_binop (Pmode, sub_optab,
+ stack_pointer_rtx, stack_limit_rtx,
+ NULL_RTX, 1, OPTAB_WIDEN);
+ emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
+ }
+
/* Under Windows NT, we need to add stack probes for large/variable
allocations, so do it via a call to the external function alloca
instead of doing it inline. */
@@ -11151,4 +11161,12 @@
(match_operand:SI 2 "reg_or_short_operand" "rI")])
(const_int 0))]
""
- "t%V0%I2 %1,%2")
+ "{t|tw}%V0%I2 %1,%2")
+
+(define_insn ""
+ [(trap_if (match_operator 0 "trap_comparison_operator"
+ [(match_operand:DI 1 "register_operand" "r")
+ (match_operand:DI 2 "reg_or_short_operand" "rI")])
+ (const_int 0))]
+ "TARGET_POWERPC64"
+ "td%V0%I2 %1,%2")