diff options
author | John David Anglin <dave@hiauly1.hia.nrc.ca> | 1999-08-29 11:04:24 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1999-08-29 05:04:24 -0600 |
commit | cd0e1e4893f4064e0c05581f8e3a2d720bd1756b (patch) | |
tree | bcac0e7e8055966be523faa0a70d681fef128e2d | |
parent | f592f509392ba52fdb9cfed7ea8a3cc93d24814f (diff) | |
download | gcc-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
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/pa/pa.md | 38 |
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") |