Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Apr 2001 10:27:32 -0700
From:      David O'Brien <stable@FreeBSD.ORG>
To:        Lev Serebryakov <Lev.Serebryakov@arcadia.spb.ru>
Cc:        All <freebsd-stable@freebsd.org>
Subject:   Re: gcc-2.95.3 and sjlj patches
Message-ID:  <20010411102732.C42670@hub.freebsd.org>
In-Reply-To: <190174694797.20010411135211@arcadia.spb.ru>; from Lev.Serebryakov@arcadia.spb.ru on Wed, Apr 11, 2001 at 01:52:11PM %2B0400
References:  <190174694797.20010411135211@arcadia.spb.ru>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Apr 11, 2001 at 01:52:11PM +0400, Lev Serebryakov wrote:
>   Where could I get sjlj patches for gcc-2.95.3 to put in my port,
>   based on gcc-2.95.3?

One way is to get the gcc-2.95.3.tar.* tarball and the
gcc-2.95.3.test3.tar.* tarball, extract the two and diff gcc-2.95.3 to
gcc-2.95.3.test3.  Edit the resulting patch to remove the obivious bits
like the version number and docs differences.

I sent a set of patches to -hackers (these should be the right ones, but
I cannot remember how I produced them):

    Date: Wed, 21 Mar 2001 09:46:38 -0800
    From: David O'Brien <obrien@FreeBSD.org>
    Subject: Re: GCC Upgrade?
    Message-ID: <20010321094638.E92274@dragon.nuxi.com>
    References: <XFMail.20010320172211.ak03@gte.com> <Pine.BSF.4.21.0103211837560.79471-100000@localhost>


Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/except.c,v
retrieving revision 1.82.4.3
retrieving revision 1.82.4.2
diff -u -r1.82.4.3 -r1.82.4.2
--- except.c	2001/02/19 14:01:59	1.82.4.3
+++ except.c	2000/12/29 16:18:54	1.82.4.2
@@ -723,21 +723,41 @@
 receive_exception_label (handler_label)
      rtx handler_label;
 {
+  rtx around_label = NULL_RTX;
+
+  if (! flag_new_exceptions || exceptions_via_longjmp)
+    {
+      around_label = gen_label_rtx ();
+      emit_jump (around_label);
+      emit_barrier ();
+    }
+
   emit_label (handler_label);
   
-#ifdef HAVE_exception_receiver
   if (! exceptions_via_longjmp)
-    if (HAVE_exception_receiver)
-      emit_insn (gen_exception_receiver ());
+    {
+#ifdef HAVE_exception_receiver
+      if (HAVE_exception_receiver)
+       emit_insn (gen_exception_receiver ());
+      else
 #endif
-
 #ifdef HAVE_nonlocal_goto_receiver
-  if (! exceptions_via_longjmp)
-    if (HAVE_nonlocal_goto_receiver)
-      emit_insn (gen_nonlocal_goto_receiver ());
+      if (HAVE_nonlocal_goto_receiver)
+       emit_insn (gen_nonlocal_goto_receiver ());
+      else
 #endif
-}
+       { /* Nothing */ }
+    }
+  else
+    {
+#ifndef DONT_USE_BUILTIN_SETJMP
+      expand_builtin_setjmp_receiver (handler_label);
+#endif
+    }
 
+  if (around_label)
+    emit_label (around_label);
+}
 
 struct func_eh_entry 
 {
@@ -1320,7 +1340,7 @@
 start_dynamic_handler ()
 {
   rtx dhc, dcc;
-  rtx x, arg, buf;
+  rtx arg, buf;
   int size;
 
 #ifndef DONT_USE_BUILTIN_SETJMP
@@ -1362,18 +1382,17 @@
   buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2);
 
 #ifdef DONT_USE_BUILTIN_SETJMP
-  x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1, SImode, 1,
-			       buf, Pmode);
-  /* If we come back here for a catch, transfer control to the handler.  */
-  jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
-#else
   {
-    /* A label to continue execution for the no exception case.  */
-    rtx noex = gen_label_rtx();
-    x = expand_builtin_setjmp (buf, NULL_RTX, noex,
-			       ehstack.top->entry->exception_handler_label);
-    emit_label (noex);
+    rtx x;
+    x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_CONST,
+                                TYPE_MODE (integer_type_node), 1,
+                                buf, Pmode);
+    /* If we come back here for a catch, transfer control to the handler.  */
+    jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
   }
+#else
+  expand_builtin_setjmp_setup (buf,
+                              ehstack.top->entry->exception_handler_label);
 #endif
 
   /* We are committed to this, so update the handler chain.  */
Index: expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expr.c,v
retrieving revision 1.144.4.9
retrieving revision 1.144.4.8
diff -u -r1.144.4.9 -r1.144.4.8
--- expr.c	2001/02/19 14:02:00	1.144.4.9
+++ expr.c	2001/01/25 14:03:06	1.144.4.8
@@ -192,6 +192,7 @@
 static int apply_args_size	PROTO((void));
 static int apply_result_size	PROTO((void));
 static rtx result_vector	PROTO((int, rtx));
+static rtx expand_builtin_setjmp PROTO((tree, rtx));
 static rtx expand_builtin_apply_args PROTO((void));
 static rtx expand_builtin_apply	PROTO((rtx, rtx, rtx));
 static void expand_builtin_return PROTO((rtx));
@@ -8544,44 +8545,29 @@
   return tem;
 }
 
-/* __builtin_setjmp is passed a pointer to an array of five words (not
-   all will be used on all machines).  It operates similarly to the C
-   library function of the same name, but is more efficient.  Much of
-   the code below (and for longjmp) is copied from the handling of
-   non-local gotos.
-
-   NOTE: This is intended for use by GNAT and the exception handling
-   scheme in the compiler and will only work in the method used by
-   them.  */
+/* Construct the leading half of a __builtin_setjmp call.  Control will
+   return to RECEIVER_LABEL.  This is used directly by sjlj exception
+   handling code.  */
 
-rtx
-expand_builtin_setjmp (buf_addr, target, first_label, next_label)
+void
+expand_builtin_setjmp_setup (buf_addr, receiver_label)
      rtx buf_addr;
-     rtx target;
-     rtx first_label, next_label;
+     rtx receiver_label;
 {
-  rtx lab1 = gen_label_rtx ();
   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
-  enum machine_mode value_mode;
   rtx stack_save;
 
-  value_mode = TYPE_MODE (integer_type_node);
-
 #ifdef POINTERS_EXTEND_UNSIGNED
   buf_addr = convert_memory_address (Pmode, buf_addr);
 #endif
 
   buf_addr = force_reg (Pmode, buf_addr);
 
-  if (target == 0 || GET_CODE (target) != REG
-      || REGNO (target) < FIRST_PSEUDO_REGISTER)
-    target = gen_reg_rtx (value_mode);
-
   emit_queue ();
 
-  /* We store the frame pointer and the address of lab1 in the buffer
-     and use the rest of it for the stack save area, which is
-     machine-dependent.  */
+  /* We store the frame pointer and the address of receiver_label in
+     the buffer and use the rest of it for the stack save area, which
+     is machine-dependent.  */
 
 #ifndef BUILTIN_SETJMP_FRAME_VALUE
 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
@@ -8593,7 +8579,7 @@
 		  (gen_rtx_MEM (Pmode,
 				plus_constant (buf_addr,
 					       GET_MODE_SIZE (Pmode)))),
-		  force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, lab1)));
+		  force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
 
   stack_save = gen_rtx_MEM (sa_mode,
 			    plus_constant (buf_addr,
@@ -8606,20 +8592,22 @@
     emit_insn (gen_builtin_setjmp_setup (buf_addr));
 #endif
 
-  /* Set TARGET to zero and branch to the first-time-through label.  */
-  emit_move_insn (target, const0_rtx);
-  emit_jump_insn (gen_jump (first_label));
-  emit_barrier ();
-  emit_label (lab1);
+  /* Tell optimize_save_area_alloca that extra work is going to
+     need to go on during alloca.  */
+  current_function_calls_setjmp = 1;
 
-  /* Tell flow about the strange goings on.  Putting `lab1' on
-     `nonlocal_goto_handler_labels' to indicates that function
-     calls may traverse the arc back to this label.  */
-
+  /* Set this so all the registers get saved in our frame; we need to be
+     able to copy the saved values for any registers from frames we unwind. */
   current_function_has_nonlocal_label = 1;
-  nonlocal_goto_handler_labels =
-    gen_rtx_EXPR_LIST (VOIDmode, lab1, nonlocal_goto_handler_labels);
+}
 
+/* Construct the trailing part of a __builtin_setjmp call.
+   This is used directly by sjlj exception handling code.  */
+ 
+void
+expand_builtin_setjmp_receiver (receiver_label)
+      rtx receiver_label ATTRIBUTE_UNUSED;
+{
   /* Clobber the FP when we get here, so we have to make sure it's
      marked as used by this function.  */
   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
@@ -8666,7 +8654,7 @@
 
 #ifdef HAVE_builtin_setjmp_receiver
   if (HAVE_builtin_setjmp_receiver)
-    emit_insn (gen_builtin_setjmp_receiver (lab1));
+    emit_insn (gen_builtin_setjmp_receiver (receiver_label));
   else
 #endif
 #ifdef HAVE_nonlocal_goto_receiver
@@ -8678,11 +8666,67 @@
 	; /* Nothing */
       }
 
-  /* Set TARGET, and branch to the next-time-through label.  */
-  emit_move_insn (target, const1_rtx);
-  emit_jump_insn (gen_jump (next_label));
+  /* @@@ This is a kludge.  Not all machine descriptions define a blockage
+     insn, but we must not allow the code we just generated to be reordered
+     by scheduling.  Specifically, the update of the frame pointer must
+     happen immediately, not later.  So emit an ASM_INPUT to act as blockage
+     insn.  */
+  emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
+}
+
+
+/* __builtin_setjmp is passed a pointer to an array of five words (not
+   all will be used on all machines).  It operates similarly to the C
+   library function of the same name, but is more efficient.  Much of
+   the code below (and for longjmp) is copied from the handling of
+   non-local gotos.
+
+   NOTE: This is intended for use by GNAT and the exception handling
+   scheme in the compiler and will only work in the method used by
+   them.  */
+
+static rtx
+expand_builtin_setjmp (arglist, target)
+     tree arglist;
+     rtx target;
+{
+  rtx buf_addr, next_lab, cont_lab;
+
+  if (arglist == 0
+      || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
+    return NULL_RTX;
+
+  if (target == 0 || GET_CODE (target) != REG
+      || REGNO (target) < FIRST_PSEUDO_REGISTER)
+    target = gen_reg_rtx (TYPE_MODE (integer_type_node));
+
+  buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
+
+  next_lab = gen_label_rtx ();
+  cont_lab = gen_label_rtx ();
+
+  expand_builtin_setjmp_setup (buf_addr, next_lab);
+
+  /* Set TARGET to zero and branch to the continue label.  */
+  emit_move_insn (target, const0_rtx);
+  emit_jump_insn (gen_jump (cont_lab));
   emit_barrier ();
+  emit_label (next_lab);
 
+  expand_builtin_setjmp_receiver (next_lab);
+
+  /* Set TARGET to one.  */
+  emit_move_insn (target, const1_rtx);
+  emit_label (cont_lab);
+
+  /* Tell flow about the strange goings on.  Putting `next_lab' on
+     `nonlocal_goto_handler_labels' to indicates that function
+     calls may traverse the arc back to this label.  */
+
+  current_function_has_nonlocal_label = 1;
+  nonlocal_goto_handler_labels
+    = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
+ 
   return target;
 }
 
@@ -9703,18 +9747,10 @@
 #endif
 
     case BUILT_IN_SETJMP:
-      if (arglist == 0
-	  || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
-	break;
-      else
-	{
-	  rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
-				      VOIDmode, 0);
-	  rtx lab = gen_label_rtx ();
-	  rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab);
-	  emit_label (lab);
-	  return ret;
-	}
+      target = expand_builtin_setjmp (arglist, target);
+      if (target)
+	return target;
+      break;
 
       /* __builtin_longjmp is passed a pointer to an array of five words.
 	 It's similar to the C library longjmp function but works with
Index: expr.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expr.h,v
retrieving revision 1.34.4.4
retrieving revision 1.34.4.3
diff -u -r1.34.4.4 -r1.34.4.3
--- expr.h	2001/02/19 14:02:02	1.34.4.4
+++ expr.h	2000/12/29 16:18:54	1.34.4.3
@@ -831,7 +831,8 @@
    Useful after calling expand_expr with 1 as sum_ok.  */
 extern rtx force_operand PROTO((rtx, rtx));
 
-extern rtx expand_builtin_setjmp PROTO((rtx, rtx, rtx, rtx));
+extern void expand_builtin_setjmp_setup PARAMS ((rtx, rtx));
+extern void expand_builtin_setjmp_receiver PARAMS ((rtx));
 
 #ifdef TREE_CODE
 /* Generate code for computing expression EXP.
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.59.4.7
retrieving revision 1.59.4.6
diff -u -r1.59.4.7 -r1.59.4.6
--- varasm.c	2001/02/19 14:02:02	1.59.4.7
+++ varasm.c	2001/01/25 14:03:24	1.59.4.6
@@ -3494,6 +3494,18 @@
 
 	  pop_obstacks ();
 	}
+      if (GET_CODE (x) == LABEL_REF)
+	{
+	  extern rtx forced_labels;
+
+	  push_obstacks_nochange ();
+	  rtl_in_saveable_obstack ();
+
+	  forced_labels = gen_rtx_EXPR_LIST (VOIDmode,
+					     XEXP (x, 0),
+					     forced_labels);
+	  pop_obstacks ();
+	}
 
       /* Allocate a pool constant descriptor, fill it in, and chain it in.  */
 

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010411102732.C42670>