Commit 0bc02db4 by Mike Stump Committed by Jeff Law

expr.c (expand_builtin_setjmp): Handle BUILTIN_SETJMP_FRAME_VALUE.

        * expr.c (expand_builtin_setjmp): Handle BUILTIN_SETJMP_FRAME_VALUE.
        * i960.h (SETUP_FRAME_ADDRESSES, BUILTIN_SETJMP_FRAME_VALUE): Define.
        * i960.md (ret, flush_register_windows): Define.
        (nonlocal_goto): Likewise.  Nested function nonlocal gotos don't
        work yet.
        * tm.texi (BUILTIN_SETJMP_FRAME_VALUE): Document new macro.

From-SVN: r20192
parent 666e0f5a
1998-06-02 Mike Stump <mrs@wrs.com>
* expr.c (expand_builtin_setjmp): Handle BUILTIN_SETJMP_FRAME_VALUE.
* i960.h (SETUP_FRAME_ADDRESSES, BUILTIN_SETJMP_FRAME_VALUE): Define.
* i960.md (ret, flush_register_windows): Define.
(nonlocal_goto): Likewise. Nested function nonlocal gotos don't
work yet.
* tm.texi (BUILTIN_SETJMP_FRAME_VALUE): Document new macro.
Tue Jun 2 14:02:38 1998 Richard Henderson <rth@cygnus.com>
* alpha.md (divsi3, udivsi3, modsi3, umodsi3): Enable, and work
......
......@@ -1495,6 +1495,13 @@ extern struct rtx_def *gen_compare_reg ();
CXT); \
}
/* Generate RTL to flush the register windows so as to make arbitrary frames
available. */
#define SETUP_FRAME_ADDRESSES() \
emit_insn (gen_flush_register_windows ())
#define BUILTIN_SETJMP_FRAME_VALUE hard_frame_pointer_rtx
#if 0
/* Promote char and short arguments to ints, when want compatibility with
the iC960 compilers. */
......
......@@ -2287,6 +2287,95 @@
"* return i960_output_ret_insn (insn);"
[(set_attr "type" "branch")])
;; A return instruction. Used only by nonlocal_goto to change the
;; stack pointer, frame pointer, previous frame pointer and the return
;; instruction pointer.
(define_insn "ret"
[(use (reg:SI 16))
(unspec_volatile [(const_int 0)] 3)]
""
"ret"
[(set_attr "type" "branch")
(set_attr "length" "1")])
(define_expand "nonlocal_goto"
[(match_operand:SI 0 "" "")
(match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")
(match_operand:SI 3 "general_operand" "")]
""
"
{
rtx fp = operands[1];
rtx new_pc = operands[3];
rtx stack = operands[2];
rtx val = operands[0];
/* This code isn't sufficient to make nonlocal_gotos for nested
functions to work fully. Here we assume that the passed frame
pointer is a real hard frame pointer, not a
virtual_stack_vars_rtx type of frame. */
/* We must restore the stack pointer, frame pointer, previous frame
pointer and the return instruction pointer. Since the ret
instruction does all this for us with one instruction, we arrange
everything so that ret will do everything we need done. */
if (GET_CODE (fp) != REG)
fp = force_reg (Pmode, fp);
if (GET_CODE (val) != REG)
val = force_reg (Pmode, val);
if (GET_CODE (new_pc) != REG)
new_pc = force_reg (Pmode, new_pc);
/* First, we must flush the register windows, so that we can modify
the saved local registers on the stack directly and because we
are going to change the previous frame pointer. */
emit_insn (gen_flush_register_windows ());
/* Next, we put the address that we want to transfer to, into the
saved $rip value on the stack. Once we ret below, that value
will be loaded into the pc (IP). */
emit_move_insn (gen_rtx (MEM, SImode,
plus_constant (fp, 8)),
new_pc);
/* 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). */
emit_move_insn (gen_rtx (MEM, SImode,
plus_constant (fp, 12)),
val);
/* We now load pfp (the previous frame pointer) with the value that
we want fp to be. */
emit_move_insn (gen_rtx (REG, SImode, 16), fp);
/* And finally, we can now just ret to get all the values saved
above into all the right registers, and also, all the local
register that were in use in the function, are restored from
their saved values (from the call instruction) on the stack
because we are very careful to ret from the exact save area in
use during the original call. */
emit_insn (gen_ret ());
emit_barrier ();
DONE;
}")
;; Special insn to flush register windows.
(define_insn "flush_register_windows"
[(unspec_volatile [(const_int 0)] 1)]
""
"flushreg"
[(set_attr "type" "misc")
(set_attr "length" "1")])
(define_insn "nop"
[(const_int 0)]
""
......
......@@ -7725,11 +7725,15 @@ expand_builtin_setjmp (buf_addr, target, first_label, next_label)
emit_queue ();
#ifndef BUILTIN_SETJMP_FRAME_VALUE
#define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
#endif
/* 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. */
emit_move_insn (gen_rtx_MEM (Pmode, buf_addr),
virtual_stack_vars_rtx);
BUILTIN_SETJMP_FRAME_VALUE);
emit_move_insn (validize_mem
(gen_rtx_MEM (Pmode,
plus_constant (buf_addr,
......
......@@ -2188,12 +2188,20 @@ of @var{frameaddr}---that is, the stack frame address is also the
address of the stack word that points to the previous frame.
@findex SETUP_FRAME_ADDRESSES
@item SETUP_FRAME_ADDRESSES ()
@item SETUP_FRAME_ADDRESSES
If defined, a C expression that produces the machine-specific code to
setup the stack so that arbitrary frames can be accessed. For example,
on the Sparc, we must flush all of the register windows to the stack
before we can access arbitrary stack frames.
This macro will seldom need to be defined.
before we can access arbitrary stack frames. You will seldom need to
define this macro.
@findex BUILTIN_SETJMP_FRAME_VALUE
@item BUILTIN_SETJMP_FRAME_VALUE
If defined, a C expression that contains an rtx that is used to store
the address of the current frame into the built in @code{setjmp} buffer.
The default value, @code{virtual_stack_vars_rtx}, is correct for most
machines. One reason you may need to define this macro is if
@code{hard_frame_pointer_rtx} is the appropriate value on your machine.
@findex RETURN_ADDR_RTX
@item RETURN_ADDR_RTX (@var{count}, @var{frameaddr})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment