aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJohn David Anglin <dave@hiauly1.hia.nrc.ca>1999-08-29 11:04:24 +0000
committerJeff Law <law@gcc.gnu.org>1999-08-29 05:04:24 -0600
commitcd0e1e4893f4064e0c05581f8e3a2d720bd1756b (patch)
treebcac0e7e8055966be523faa0a70d681fef128e2d /gcc
parentf592f509392ba52fdb9cfed7ea8a3cc93d24814f (diff)
downloadgcc-cd0e1e4893f4064e0c05581f8e3a2d720bd1756b.zip
gcc-cd0e1e4893f4064e0c05581f8e3a2d720bd1756b.tar.gz
gcc-cd0e1e4893f4064e0c05581f8e3a2d720bd1756b.tar.bz2
pa.md (interspace_jump): New pattern.
* pa.md (interspace_jump): New pattern. (builtin_longjmp): New expander. From-SVN: r28964
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/pa/pa.md38
2 files changed, 43 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c43a6bb..1ecc178 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+Sun Aug 29 05:01:17 1999 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.md (interspace_jump): New pattern.
+ (builtin_longjmp): New expander.
+
1999-08-29 Bernd Schmidt <bernds@cygnus.co.uk>
* fp-bit.c (add, sub, multiply, divide, compare, _eq_f2, _ne_f2,
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 8b22dc0..f28d191 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -4697,6 +4697,44 @@
[(set_attr "type" "branch")
(set_attr "length" "4")])
+;;; 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.
+(define_insn "interspace_jump"
+ [(set (pc) (match_operand:SI 0 "register_operand" "a"))
+ (clobber (reg:SI 2))]
+ ""
+ "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
+ [(set_attr "type" "branch")
+ (set_attr "length" "12")])
+
+(define_expand "builtin_longjmp"
+ [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
+ ""
+ "
+{
+ /* The elements of the buffer are, in order: */
+ rtx fp = gen_rtx_MEM (Pmode, operands[0]);
+ rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4));
+ rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
+ rtx pv = gen_rtx_REG (Pmode, 1);
+
+ /* This bit is the same as expand_builtin_longjmp. */
+ emit_move_insn (hard_frame_pointer_rtx, fp);
+ emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
+ emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
+ emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+
+ /* Load the label we are jumping through into r1 so that we know
+ where to look for it when we get back to setjmp's function for
+ restoring the gp. */
+ emit_move_insn (pv, lab);
+ emit_jump_insn (gen_interspace_jump (pv));
+ emit_barrier ();
+ DONE;
+}")
+
(define_insn "extzv"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")