This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: Save/restore PIC register on PA when using builtin_setjmp/longjmp


Here is a patch to save and restore the PIC register when using builtin_setjmp
and builtin_longjmp for sjlj exceptions.  I have tested it with a complete
bootstrap and check under hppa1.1-hp-hpux10.20 on the 3.0 branch.  I believe
it is also suitable for the main but I haven't had time to test it there.
Test results are here:
<http://gcc.gnu.org/ml/gcc-testresults/2001-05/msg00141.html>.

The patch fixes g++ testsuite FAILs for cxa_vec.C, spec[2,3].C,
dyncast[1,2].C and eh51.C.  eh[33,50].C now are execution XPASSes.
The only remaining g++ FAILs that don't have an obvious explanation
are rethrow[1,2,4,6].C.  These failures are probably a design problem
in the exception code as they also fail under i686 linux with
-fsjlj-exceptions.  See
<http://gcc.gnu.org/ml/gcc-testresults/2001-05/msg00142.html>.
Hopefully, these failures will be fixed when Richard replaces the
exception code.  It it good to see that g++ on the PA is working
better than on i686 linux when sjlj exceptions are used.

I am also pleased to see that only other remaining FAILs for g++ are due
to the HP linker, and the lack of alias and weak support.  The build was
done with --enable-shared.  The g++ tests are using the shared version
of libstdc++.  Having a working shared version of libstdc++ is excellent
news.  I am somewhat surprised that this appears to to work without
a shared libgcc, since this was a problem on the 2.95 branch.

The patch uses the same technique to save and restore the pic register
as is used across calls.  It relies on the fact that the save rtx is
a stack slot and not a register when current_function_has_nonlocal_label
is defined.  I did try a patch where I put the PIC register in the
jmpbuf with identical results.  However, this one is less invasive.

The patch also fixes a minor problem with builtin_longjmp where I
noticed that load instructions were being placed into the delay slot
of the interspace branch after the space register was updated for
the branch.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)

2001-05-03  John David Anglin  <dave@hiauly1.hia.nrc.ca>

	* pa.md (interspace_jump): Revise comment.
	(builtin_longjmp): Block initial setup insns from delay slot of
	interspace branch.
	(builtin_setjmp_receiver): New expander to save and restore PIC
	register.

--- pa.md.orig	Tue Apr 17 14:36:54 2001
+++ pa.md	Thu May  3 15:26:53 2001
@@ -6211,8 +6211,7 @@
 
 ;;; EH does longjmp's from and within the data section.  Thus,
 ;;; an interspace branch is required for the longjmp implementation.
-;;; Registers r1 and r2 are not saved in the jmpbuf environment.
-;;; Thus, they can be used as scratch registers for the jump.
+;;; Registers r1 and r2 are used as scratch registers for the jump.
 (define_expand "interspace_jump"
   [(parallel
      [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
@@ -6262,10 +6261,16 @@
      where to look for it when we get back to setjmp's function for
      restoring the gp.  */
   emit_move_insn (pv, lab);
+
+  /* Prevent the insns above from being scheduled into the delay slot
+     of the interspace jump because the space register could change.  */
+  emit_insn (gen_blockage ());
+
   emit_jump_insn (gen_interspace_jump (pv));
   emit_barrier ();
   DONE;
 }")
+
 ;;; Hope this is only within a function...
 (define_insn "indirect_jump"
   [(set (pc) (match_operand 0 "register_operand" "r"))]
@@ -7131,3 +7136,18 @@
   emit_insn (gen_blockage ());
   DONE;
 }")
+
+(define_expand "builtin_setjmp_receiver"
+  [(label_ref (match_operand 0 "" ""))]
+  "flag_pic"
+  "
+{
+  if (PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX)
+    hppa_init_pic_save ();
+
+  /* Restore the PIC register.  Hopefully, this will always be from
+     a stack slot.  The only registers that are valid after a
+     builtin_longjmp are the stack and frame pointers.  */
+  emit_move_insn (pic_offset_table_rtx, PIC_OFFSET_TABLE_SAVE_RTX);
+  DONE;
+}")


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]