Bug in local spilling code

Bernd Schmidt crux@pool.informatik.rwth-aachen.de
Wed Oct 28 04:03:00 GMT 1998


On Mon, 26 Oct 1998, Richard Henderson wrote:

> On Mon, Oct 26, 1998 at 01:35:04PM +0100, Bernd Schmidt wrote:
> > Obviously not.  There's a death note for it on insn 29!
> > We might need to teach flow.c that jumps to nonlocal labels do in fact use
> > the static chain register.
> 
> Well, the worst part is that flow blatently lies about the real cfg
> in handling non-local gotos.  I discovered this when my new flow code
> failed that very test.
> 
> Personally, I think this non-local goto handler nonsense is just too
> bogus.  There are one or two fixup instructions that are needed in 
> the containing function, and we spend two or three times that making
> multiple non-local goto labels use the same handler.  Replicating the
> fixup block for each such label seems the best solution to me.  With
> the additional benefit of not needing the static chain register.

The patch below implements this.  Note that I'm not familiar with either
the sparc or the i960; the patch seems to work on the sparc but I have no
i960 available for testing.

WIth this patch, the actual nonlocal goto performs better, but the setup
overhead in the function containing the nonlocal label is increased.
Functions that only contain one or two nonlocal labels should benefit from
this change; this is less likely for functions that have more such labels.

Bernd

	* function.c (nonlocal_goto_handler_slots): Renamed from
	nonlocal_goto_handler_slot; now an EXPR_LIST chain.
	(push_function_context_to): Adjust for this change.
	(pop_function_context_from): Likewise.
	(init_function_start): Likewise.
	(expand_function_end): Likewise.
	* function.h (struct function): Likewise.
	* calls.c (expand_call): Likewise.
	* explow.c (allocate_dynamic_stack_space): Likewise.
	* expr.h (nonlocal_goto_handler_slots): Rename its declaration.

	* stmt.c (declare_nonlocal_label): Make a new handler slot for each
	label.
	(expand_goto): When doing a nonlocal goto, find corresponding handler
	slot for it.  Don't put the label address in the static chain register.
	(expand_end_bindings): Break out nonlocal goto handling code into
	three new functions.
	(expand_nl_handler_label, expand_nl_goto_receiver,
	expand_nl_goto_receivers): New static functions, broken out of
	expand_end_bindings and adapted to create one handler per nonlocal
	label.
	* function.c (delete_handlers): Delete insn if it references any of
	the nonlocal goto handler slots.

	* i960.md (nonlocal_goto): Comment out code that modifies
	static_chain_rtx.
	* sparc.md (nonlocal_goto): Likewise.
	(goto_handler_and_restore_v9): Comment out.
	(goto_handler_and_restore_v9_sp64): Comment out.
	
Index: calls.c
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/calls.c,v
retrieving revision 1.1.1.26
diff -u -p -r1.1.1.26 calls.c
--- calls.c	1998/10/15 16:58:11	1.1.1.26
+++ calls.c	1998/10/27 18:33:30
@@ -2200,7 +2200,7 @@ expand_call (exp, target, ignore)
      Check for the handler slots since we might not have a save area
      for non-local gotos.  */
 
-  if (may_be_alloca && nonlocal_goto_handler_slot != 0)
+  if (may_be_alloca && nonlocal_goto_handler_slots != 0)
     emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
 
   pop_temp_slots ();
Index: explow.c
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/explow.c,v
retrieving revision 1.1.1.15
diff -u -p -r1.1.1.15 explow.c
--- explow.c	1998/10/15 13:29:14	1.1.1.15
+++ explow.c	1998/10/27 18:33:52
@@ -1299,7 +1299,7 @@ allocate_dynamic_stack_space (size, targ
 #endif
 
   /* Record the new stack level for nonlocal gotos.  */
-  if (nonlocal_goto_handler_slot != 0)
+  if (nonlocal_goto_handler_slots != 0)
     emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
 
   return target;
Index: expr.h
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/expr.h,v
retrieving revision 1.1.1.22
diff -u -p -r1.1.1.22 expr.h
--- expr.h	1998/10/12 10:43:52	1.1.1.22
+++ expr.h	1998/10/27 18:09:51
@@ -105,10 +105,12 @@ extern int inhibit_defer_pop;
 
 extern int function_call_count;
 
-/* RTX for stack slot that holds the current handler for nonlocal gotos.
+/* List (chain of EXPR_LIST) of stack slots that hold the current handlers
+   for nonlocal gotos.  There is one for every nonlocal label in the function;
+   this list matches the one in nonlocal_labels.
    Zero when function does not have nonlocal labels.  */
 
-extern rtx nonlocal_goto_handler_slot;
+extern rtx nonlocal_goto_handler_slots;
 
 /* RTX for stack slot that holds the stack pointer value to restore
    for a nonlocal goto.
Index: function.c
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/function.c,v
retrieving revision 1.1.1.43
diff -u -p -r1.1.1.43 function.c
--- function.c	1998/10/22 11:02:17	1.1.1.43
+++ function.c	1998/10/27 18:06:45
@@ -243,10 +243,12 @@ int function_call_count;
 
 tree nonlocal_labels;
 
-/* RTX for stack slot that holds the current handler for nonlocal gotos.
+/* List (chain of EXPR_LIST) of stack slots that hold the current handlers
+   for nonlocal gotos.  There is one for every nonlocal label in the function;
+   this list matches the one in nonlocal_labels.
    Zero when function does not have nonlocal labels.  */
 
-rtx nonlocal_goto_handler_slot;
+rtx nonlocal_goto_handler_slots;
 
 /* RTX for stack slot that holds the stack pointer value to restore
    for a nonlocal goto.
@@ -528,7 +530,7 @@ push_function_context_to (context)
   p->parm_reg_stack_loc = parm_reg_stack_loc;
   p->outgoing_args_size = current_function_outgoing_args_size;
   p->return_rtx = current_function_return_rtx;
-  p->nonlocal_goto_handler_slot = nonlocal_goto_handler_slot;
+  p->nonlocal_goto_handler_slots = nonlocal_goto_handler_slots;
   p->nonlocal_goto_stack_level = nonlocal_goto_stack_level;
   p->nonlocal_labels = nonlocal_labels;
   p->cleanup_label = cleanup_label;
@@ -612,7 +614,7 @@ pop_function_context_from (context)
   parm_reg_stack_loc = p->parm_reg_stack_loc;
   current_function_outgoing_args_size = p->outgoing_args_size;
   current_function_return_rtx = p->return_rtx;
-  nonlocal_goto_handler_slot = p->nonlocal_goto_handler_slot;
+  nonlocal_goto_handler_slots = p->nonlocal_goto_handler_slots;
   nonlocal_goto_stack_level = p->nonlocal_goto_stack_level;
   nonlocal_labels = p->nonlocal_labels;
   cleanup_label = p->cleanup_label;
@@ -3615,13 +3609,22 @@ delete_handlers ()
 		TREE_CHAIN (last_t) = TREE_CHAIN (t);
 	    }
 	}
-      if (GET_CODE (insn) == INSN
-	  && ((nonlocal_goto_handler_slot != 0
-	       && reg_mentioned_p (nonlocal_goto_handler_slot, PATTERN (insn)))
+      if (GET_CODE (insn) == INSN)
+	{
+	  int can_delete = 0;
+	  rtx t;
+	  for (t = nonlocal_goto_handler_slots; t != 0; t = XEXP (t, 1))
+	    if (reg_mentioned_p (t, PATTERN (insn)))
+	      {
+		can_delete = 1;
+		break;
+	      }
+	  if (can_delete
 	      || (nonlocal_goto_stack_level != 0
 		  && reg_mentioned_p (nonlocal_goto_stack_level,
-				      PATTERN (insn)))))
-	delete_insn (insn);
+				      PATTERN (insn))))
+	    delete_insn (insn);
+	}
     }
 }
 
@@ -5403,7 +5406,7 @@ init_function_start (subr, filename, lin
   stack_slot_list = 0;
 
   /* There is no stack slot for handling nonlocal gotos.  */
-  nonlocal_goto_handler_slot = 0;
+  nonlocal_goto_handler_slots = 0;
   nonlocal_goto_stack_level = 0;
 
   /* No labels have been declared for nonlocal use.  */
@@ -5923,7 +5926,8 @@ expand_function_end (filename, line, end
     }
 
   /* Delete handlers for nonlocal gotos if nothing uses them.  */
-  if (nonlocal_goto_handler_slot != 0 && !current_function_has_nonlocal_label)
+  if (nonlocal_goto_handler_slots != 0
+      && ! current_function_has_nonlocal_label)
     delete_handlers ();
 
   /* End any sequences that failed to be closed due to syntax errors.  */
Index: function.h
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/function.h,v
retrieving revision 1.1.1.14
diff -u -p -r1.1.1.14 function.h
--- function.h	1998/10/23 15:17:06	1.1.1.14
+++ function.h	1998/10/27 17:40:58
@@ -81,7 +81,7 @@ struct function
   int has_nonlocal_goto;
   int contains_functions;
   int is_thunk;
-  rtx nonlocal_goto_handler_slot;
+  rtx nonlocal_goto_handler_slots;
   rtx nonlocal_goto_stack_level;
   tree nonlocal_labels;
   int args_size;
Index: stmt.c
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/stmt.c,v
retrieving revision 1.1.1.36
diff -u -p -r1.1.1.36 stmt.c
--- stmt.c	1998/10/27 16:52:33	1.1.1.36
+++ stmt.c	1998/10/27 19:59:30
@@ -428,6 +428,9 @@ static int using_eh_for_cleanups_p = 0;
 static int n_occurrences		PROTO((int, char *));
 static void expand_goto_internal	PROTO((tree, rtx, rtx));
 static int expand_fixup			PROTO((tree, rtx, rtx));
+static void expand_nl_handler_label	PROTO((rtx, rtx));
+static void expand_nl_goto_receiver	PROTO((void));
+static void expand_nl_goto_receivers	PROTO((struct nesting *));
 static void fixup_gotos			PROTO((struct nesting *, rtx, tree,
 					       rtx, int));
 static void expand_null_return_1	PROTO((rtx, int));
@@ -632,16 +635,18 @@ void
 declare_nonlocal_label (label)
      tree label;
 {
+  rtx slot = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
+
   nonlocal_labels = tree_cons (NULL_TREE, label, nonlocal_labels);
   LABEL_PRESERVE_P (label_rtx (label)) = 1;
-  if (nonlocal_goto_handler_slot == 0)
+  if (nonlocal_goto_handler_slots == 0)
     {
-      nonlocal_goto_handler_slot
-	= assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
       emit_stack_save (SAVE_NONLOCAL,
 		       &nonlocal_goto_stack_level,
 		       PREV_INSN (tail_recursion_reentry));
     }
+  nonlocal_goto_handler_slots
+    = gen_rtx_EXPR_LIST (VOIDmode, slot, nonlocal_goto_handler_slots);
 }
 
 /* Generate RTL code for a `goto' statement with target label LABEL.
@@ -660,7 +665,15 @@ expand_goto (label)
     {
       struct function *p = find_function_data (context);
       rtx label_ref = gen_rtx_LABEL_REF (Pmode, label_rtx (label));
-      rtx temp;
+      rtx temp, handler_slot;
+      tree link;
+
+      /* Find the corresponding handler slot for this label.  */
+      handler_slot = p->nonlocal_goto_handler_slots;
+      for (link = p->nonlocal_labels; TREE_VALUE (link) != label;
+	   link = TREE_CHAIN (link))
+	handler_slot = XEXP (handler_slot, 1);
+      handler_slot = XEXP (handler_slot, 0);
 
       p->has_nonlocal_label = 1;
       current_function_has_nonlocal_goto = 1;
@@ -673,7 +686,7 @@ expand_goto (label)
 #if HAVE_nonlocal_goto
       if (HAVE_nonlocal_goto)
 	emit_insn (gen_nonlocal_goto (lookup_static_chain (label),
-				      copy_rtx (p->nonlocal_goto_handler_slot),
+				      copy_rtx (handler_slot),
 				      copy_rtx (p->nonlocal_goto_stack_level),
 				      label_ref));
       else
@@ -695,7 +708,7 @@ expand_goto (label)
 
 	  /* Get addr of containing function's current nonlocal goto handler,
 	     which will do any cleanups and then jump to the label.  */
-	  addr = copy_rtx (p->nonlocal_goto_handler_slot);
+	  addr = copy_rtx (handler_slot);
 	  temp = copy_to_reg (replace_rtx (addr, virtual_stack_vars_rtx,
 					   hard_frame_pointer_rtx));
 	  
@@ -708,13 +721,10 @@ expand_goto (label)
 
 	  emit_stack_restore (SAVE_NONLOCAL, addr, NULL_RTX);
 
-	  /* Put in the static chain register the nonlocal label address.  */
-	  emit_move_insn (static_chain_rtx, label_ref);
 	  /* USE of hard_frame_pointer_rtx added for consistency; not clear if
 	     really needed.  */
 	  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
 	  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
-	  emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
 	  emit_indirect_jump (temp);
 	}
      }
@@ -2973,6 +2983,161 @@ remember_end_note (block)
   last_block_end_note = NULL_RTX;
 }
 
+/* Emit a handler label for a nonlocal goto handler.
+   Also emit code to store the handler label in SLOT before BEFORE_INSN.  */
+
+static void
+expand_nl_handler_label (slot, before_insn)
+     rtx slot, before_insn;
+{
+  rtx insns;
+  rtx handler_label = gen_label_rtx ();
+
+  /* Don't let jump_optimize delete the handler.  */
+  LABEL_PRESERVE_P (handler_label) = 1;
+
+  start_sequence ();
+  emit_move_insn (slot, gen_rtx_LABEL_REF (Pmode, handler_label));
+  insns = get_insns ();
+  end_sequence ();
+  emit_insns_before (insns, before_insn);
+
+  emit_label (handler_label);
+}
+
+/* Emit code to restore vital registers at the beginning of a nonlocal goto
+   handler.  */
+static void
+expand_nl_goto_receiver ()
+{
+#ifdef HAVE_nonlocal_goto
+  if (! HAVE_nonlocal_goto)
+#endif
+    /* First adjust our frame pointer to its actual value.  It was
+       previously set to the start of the virtual area corresponding to
+       the stacked variables when we branched here and now needs to be
+       adjusted to the actual hardware fp value.
+
+       Assignments are to virtual registers are converted by
+       instantiate_virtual_regs into the corresponding assignment
+       to the underlying register (fp in this case) that makes
+       the original assignment true.
+       So the following insn will actually be
+       decrementing fp by STARTING_FRAME_OFFSET.  */
+    emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
+
+#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+  if (fixed_regs[ARG_POINTER_REGNUM])
+    {
+#ifdef ELIMINABLE_REGS
+      /* If the argument pointer can be eliminated in favor of the
+	 frame pointer, we don't need to restore it.  We assume here
+	 that if such an elimination is present, it can always be used.
+	 This is the case on all known machines; if we don't make this
+	 assumption, we do unnecessary saving on many machines.  */
+      static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
+      size_t i;
+
+      for (i = 0; i < sizeof elim_regs / sizeof elim_regs[0]; i++)
+	if (elim_regs[i].from == ARG_POINTER_REGNUM
+	    && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
+	  break;
+
+      if (i == sizeof elim_regs / sizeof elim_regs [0])
+#endif
+	{
+	  /* Now restore our arg pointer from the address at which it
+	     was saved in our stack frame.
+	     If there hasn't be space allocated for it yet, make
+	     some now.  */
+	  if (arg_pointer_save_area == 0)
+	    arg_pointer_save_area
+	      = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
+	  emit_move_insn (virtual_incoming_args_rtx,
+			  /* We need a pseudo here, or else
+			     instantiate_virtual_regs_1 complains.  */
+			  copy_to_reg (arg_pointer_save_area));
+	}
+    }
+#endif
+
+#ifdef HAVE_nonlocal_goto_receiver
+  if (HAVE_nonlocal_goto_receiver)
+    emit_insn (gen_nonlocal_goto_receiver ());
+#endif
+}
+
+/* Make handlers for nonlocal gotos taking place in the function calls in
+   block THISBLOCK.  */
+
+static void
+expand_nl_goto_receivers (thisblock)
+     struct nesting *thisblock;
+{
+  tree link;
+  rtx afterward = gen_label_rtx ();
+  rtx insns, slot;
+  int any_invalid;
+
+  /* Record the handler address in the stack slot for that purpose,
+     during this block, saving and restoring the outer value.  */
+  if (thisblock->next != 0)
+    for (slot = nonlocal_goto_handler_slots; slot; slot = XEXP (slot, 1))
+      {
+	rtx save_receiver = gen_reg_rtx (Pmode);
+	emit_move_insn (XEXP (slot, 0), save_receiver);
+
+	start_sequence ();
+	emit_move_insn (save_receiver, XEXP (slot, 0));
+	insns = get_insns ();
+	end_sequence ();
+	emit_insns_before (insns, thisblock->data.block.first_insn);
+      }
+
+  /* Jump around the handlers; they run only when specially invoked.  */
+  emit_jump (afterward);
+
+  /* Make a separate handler for each label.  */
+  link = nonlocal_labels;
+  slot = nonlocal_goto_handler_slots;
+  for (; link; link = TREE_CHAIN (link), slot = XEXP (slot, 1))
+    /* Skip any labels we shouldn't be able to jump to from here,
+       we generate one special handler for all of them below which just calls
+       abort.  */
+    if (! DECL_TOO_LATE (TREE_VALUE (link)))
+      {
+	expand_nl_handler_label (XEXP (slot, 0),
+				 thisblock->data.block.first_insn);
+	expand_nl_goto_receiver ();
+
+	/* Jump to the "real" nonlocal label.  */
+	expand_goto (TREE_VALUE (link));
+      }
+
+  /* A second pass over all nonlocal labels; this time we handle those
+     we should not be able to jump to at this point.  */
+  link = nonlocal_labels;
+  slot = nonlocal_goto_handler_slots;
+  any_invalid = 0;
+  for (; link; link = TREE_CHAIN (link), slot = XEXP (slot, 1))
+    if (DECL_TOO_LATE (TREE_VALUE (link)))
+      {
+	expand_nl_handler_label (XEXP (slot, 0),
+				 thisblock->data.block.first_insn);
+	any_invalid = 1;
+      }
+
+  if (any_invalid)
+    {
+      expand_nl_goto_receiver ();
+      emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "abort"), 0,
+			 VOIDmode, 0);
+      emit_barrier ();
+    }
+
+  emit_label (afterward);
+}
+
 /* Generate RTL code to terminate a binding contour.
    VARS is the chain of VAR_DECL nodes
    for the variables bound in this contour.
@@ -3023,7 +3188,7 @@ expand_end_bindings (vars, mark_ends, do
       emit_label (thisblock->exit_label);
     }
 
-  /* If necessary, make a handler for nonlocal gotos taking
+  /* If necessary, make handlers for nonlocal gotos taking
      place in the function calls in this block.  */
   if (function_call_count != thisblock->data.block.function_call_count
       && nonlocal_labels
@@ -3034,120 +3199,8 @@ expand_end_bindings (vars, mark_ends, do
 	     special to do when you jump out of it.  */
 	  : (thisblock->data.block.cleanups != 0
 	     || thisblock->data.block.stack_level != 0)))
-    {
-      tree link;
-      rtx afterward = gen_label_rtx ();
-      rtx handler_label = gen_label_rtx ();
-      rtx save_receiver = gen_reg_rtx (Pmode);
-      rtx insns;
-
-      /* Don't let jump_optimize delete the handler.  */
-      LABEL_PRESERVE_P (handler_label) = 1;
-
-      /* Record the handler address in the stack slot for that purpose,
-	 during this block, saving and restoring the outer value.  */
-      if (thisblock->next != 0)
-	{
-	  emit_move_insn (nonlocal_goto_handler_slot, save_receiver);
-
-	  start_sequence ();
-	  emit_move_insn (save_receiver, nonlocal_goto_handler_slot);
-	  insns = get_insns ();
-	  end_sequence ();
-	  emit_insns_before (insns, thisblock->data.block.first_insn);
-	}
-
-      start_sequence ();
-      emit_move_insn (nonlocal_goto_handler_slot,
-		      gen_rtx_LABEL_REF (Pmode, handler_label));
-      insns = get_insns ();
-      end_sequence ();
-      emit_insns_before (insns, thisblock->data.block.first_insn);
-
-      /* Jump around the handler; it runs only when specially invoked.  */
-      emit_jump (afterward);
-      emit_label (handler_label);
-
-#ifdef HAVE_nonlocal_goto
-      if (! HAVE_nonlocal_goto)
-#endif
-	/* First adjust our frame pointer to its actual value.  It was
-	   previously set to the start of the virtual area corresponding to
-	   the stacked variables when we branched here and now needs to be
-	   adjusted to the actual hardware fp value.
-
-	   Assignments are to virtual registers are converted by
-	   instantiate_virtual_regs into the corresponding assignment
-	   to the underlying register (fp in this case) that makes
-	   the original assignment true.
-	   So the following insn will actually be
-	   decrementing fp by STARTING_FRAME_OFFSET.  */
-	emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
+    expand_nl_goto_receivers (thisblock);
 
-#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
-      if (fixed_regs[ARG_POINTER_REGNUM])
-	{
-#ifdef ELIMINABLE_REGS
-	  /* If the argument pointer can be eliminated in favor of the
-	     frame pointer, we don't need to restore it.  We assume here
-	     that if such an elimination is present, it can always be used.
-	     This is the case on all known machines; if we don't make this
-	     assumption, we do unnecessary saving on many machines.  */
-	  static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
-	  size_t i;
-
-	  for (i = 0; i < sizeof elim_regs / sizeof elim_regs[0]; i++)
-	    if (elim_regs[i].from == ARG_POINTER_REGNUM
-		&& elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
-	      break;
-
-	  if (i == sizeof elim_regs / sizeof elim_regs [0])
-#endif
-	    {
-	      /* Now restore our arg pointer from the address at which it
-		 was saved in our stack frame.
-		 If there hasn't be space allocated for it yet, make
-		 some now.  */
-	      if (arg_pointer_save_area == 0)
-		arg_pointer_save_area
-		  = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
-	      emit_move_insn (virtual_incoming_args_rtx,
-			      /* We need a pseudo here, or else
-				 instantiate_virtual_regs_1 complains.  */
-			      copy_to_reg (arg_pointer_save_area));
-	    }
-	}
-#endif
-
-#ifdef HAVE_nonlocal_goto_receiver
-      if (HAVE_nonlocal_goto_receiver)
-	emit_insn (gen_nonlocal_goto_receiver ());
-#endif
-
-      /* The handler expects the desired label address in the static chain
-	 register.  It tests the address and does an appropriate jump
-	 to whatever label is desired.  */
-      for (link = nonlocal_labels; link; link = TREE_CHAIN (link))
-	/* Skip any labels we shouldn't be able to jump to from here.  */
-	if (! DECL_TOO_LATE (TREE_VALUE (link)))
-	  {
-	    rtx not_this = gen_label_rtx ();
-	    rtx this = gen_label_rtx ();
-	    do_jump_if_equal (static_chain_rtx,
-			      gen_rtx_LABEL_REF (Pmode, DECL_RTL (TREE_VALUE (link))),
-			      this, 0);
-	    emit_jump (not_this);
-	    emit_label (this);
-	    expand_goto (TREE_VALUE (link));
-	    emit_label (not_this);
-	  }
-      /* If label is not recognized, abort.  */
-      emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "abort"), 0,
-			 VOIDmode, 0);
-      emit_barrier ();
-      emit_label (afterward);
-    }
-
   /* Don't allow jumping into a block that has a stack level.
      Cleanups are allowed, though.  */
   if (dont_jump_in
@@ -3200,7 +3253,7 @@ expand_end_bindings (vars, mark_ends, do
 	{
 	  emit_stack_restore (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
 			      thisblock->data.block.stack_level, NULL_RTX);
-	  if (nonlocal_goto_handler_slot != 0)
+	  if (nonlocal_goto_handler_slots != 0)
 	    emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level,
 			     NULL_RTX);
 	}
@@ -3247,8 +3300,6 @@ expand_end_bindings (vars, mark_ends, do
   /* Pop the stack slot nesting and free any slots at this level.  */
   pop_temp_slots ();
 }
-
-
 
 /* Generate RTL for the automatic variable declaration DECL.
    (Other kinds of declarations are simply ignored if seen here.)  */
Index: config/i960/i960.md
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/config/i960/i960.md,v
retrieving revision 1.1.1.4
diff -u -p -r1.1.1.4 i960.md
--- i960.md	1998/06/11 15:32:06	1.1.1.4
+++ i960.md	1998/10/27 19:59:14
@@ -2343,6 +2343,7 @@
 			   plus_constant (fp, 8)),
 		  new_pc);
 
+#if 0
   /* Next, we put the value into the static chain register's save
      area on the stack.  After the ret below, this will be loaded into
      r3 (the static chain).  */
@@ -2350,6 +2351,7 @@
   emit_move_insn (gen_rtx (MEM, SImode,
 			   plus_constant (fp, 12)),
 		  val);
+#endif
 
   /* We now load pfp (the previous frame pointer) with the value that
      we want fp to be.  */
Index: config/sparc/sparc.md
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/config/sparc/sparc.md,v
retrieving revision 1.1.1.30
diff -u -p -r1.1.1.30 sparc.md
--- sparc.md	1998/10/05 10:53:25	1.1.1.30
+++ sparc.md	1998/10/27 19:56:35
@@ -7689,6 +7689,8 @@
      really needed.  */
   /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+
+#if 0
   /* Return, restoring reg window and jumping to goto handler.  */
   if (TARGET_V9 && GET_CODE (chain) == CONST_INT
       && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
@@ -7700,6 +7702,8 @@
     }
   /* Put in the static chain register the nonlocal label address.  */
   emit_move_insn (static_chain_rtx, chain);
+#endif
+
   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
   emit_insn (gen_goto_handler_and_restore (labreg));
   emit_barrier ();
@@ -7721,27 +7725,27 @@
   [(set_attr "type" "misc")
    (set_attr "length" "2")])
 
-(define_insn "goto_handler_and_restore_v9"
-  [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
-		     (match_operand:SI 1 "register_operand" "=r,r")
-		     (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
-  "TARGET_V9 && ! TARGET_ARCH64"
-  "@
-   return\\t%0+0\\n\\tmov\\t%2, %Y1
-   sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
-  [(set_attr "type" "misc")
-   (set_attr "length" "2,3")])
-
-(define_insn "*goto_handler_and_restore_v9_sp64"
-  [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
-		     (match_operand:DI 1 "register_operand" "=r,r")
-		     (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
-  "TARGET_V9 && TARGET_ARCH64"
-  "@
-   return\\t%0+0\\n\\tmov\\t%2, %Y1
-   sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
-  [(set_attr "type" "misc")
-   (set_attr "length" "2,3")])
+;;(define_insn "goto_handler_and_restore_v9"
+;;  [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
+;;		     (match_operand:SI 1 "register_operand" "=r,r")
+;;		     (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
+;;  "TARGET_V9 && ! TARGET_ARCH64"
+;;  "@
+;;   return\\t%0+0\\n\\tmov\\t%2, %Y1
+;;   sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
+;;  [(set_attr "type" "misc")
+;;   (set_attr "length" "2,3")])
+;;
+;;(define_insn "*goto_handler_and_restore_v9_sp64"
+;;  [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
+;;		     (match_operand:DI 1 "register_operand" "=r,r")
+;;		     (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
+;;  "TARGET_V9 && TARGET_ARCH64"
+;;  "@
+;;   return\\t%0+0\\n\\tmov\\t%2, %Y1
+;;   sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
+;;  [(set_attr "type" "misc")
+;;   (set_attr "length" "2,3")])
 
 ;; Pattern for use after a setjmp to store FP and the return register
 ;; into the stack area.




More information about the Gcc-patches mailing list