emit_move_insn (gen_rtx (MEM, SImode,
plus_constant (hard_frame_pointer_rtx, -56)),
- replace_rtx (copy_rtx (handler), virtual_stack_vars_rtx,
- hard_frame_pointer_rtx));
+ handler);
/* Next, we put stack into the saved $sp value in the frame. */
emit_move_insn (gen_rtx (MEM, SImode,
plus_constant (hard_frame_pointer_rtx, -60)),
- replace_rtx (copy_rtx (stack), virtual_stack_vars_rtx,
- hard_frame_pointer_rtx));
+ stack);
/* And finally, we can now just ret to get all the values saved
above into all the right registers, and also, all the local
(match_operand:SI 3 "" "")]
""
"{
- rtx addr;
- rtx temp;
+ operands[2] = force_reg (Pmode, XEXP (operands[2], 0));
emit_move_insn (hard_frame_pointer_rtx, operands[0]);
-
- temp = copy_to_reg (replace_rtx (operands[1],
- virtual_stack_vars_rtx,
- hard_frame_pointer_rtx));
-
- addr = replace_rtx (copy_rtx (operands[2]),
- virtual_stack_vars_rtx,
- hard_frame_pointer_rtx);
-
emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
- emit_insn (gen_nonlocal_goto_helper (force_reg (Pmode, XEXP (addr, 0)),
- temp));
+ emit_insn (gen_nonlocal_goto_helper (operands[2], operands[1]));
emit_barrier ();
DONE;
- }")
+ }")
\f
;; Function overhead.
{
struct function *p = find_function_data (context);
rtx label_ref = gen_rtx_LABEL_REF (Pmode, label_rtx (label));
- rtx temp, handler_slot;
+ rtx handler_slot, static_chain, save_area;
tree link;
/* Find the corresponding handler slot for this label. */
case the virtual stack vars register gets instantiated differently
in the parent than in the child. */
+ static_chain = copy_to_reg (lookup_static_chain (label));
+
+ /* Get addr of containing function's current nonlocal goto handler,
+ which will do any cleanups and then jump to the label. */
+ handler_slot = copy_to_reg (replace_rtx (copy_rtx (handler_slot),
+ virtual_stack_vars_rtx,
+ static_chain));
+
+ /* Get addr of containing function's nonlocal save area. */
+ save_area = p->x_nonlocal_goto_stack_level;
+ if (save_area)
+ save_area = replace_rtx (copy_rtx (save_area),
+ virtual_stack_vars_rtx, static_chain);
+
#if HAVE_nonlocal_goto
if (HAVE_nonlocal_goto)
- emit_insn (gen_nonlocal_goto (lookup_static_chain (label),
- copy_rtx (handler_slot),
- copy_rtx (p->x_nonlocal_goto_stack_level),
- label_ref));
+ emit_insn (gen_nonlocal_goto (static_chain, handler_slot,
+ save_area, label_ref));
else
#endif
{
- rtx addr;
-
/* Restore frame pointer for containing function.
This sets the actual hard register used for the frame pointer
to the location of the function's incoming static chain info.
The non-local goto handler will then adjust it to contain the
proper value and reload the argument pointer, if needed. */
- emit_move_insn (hard_frame_pointer_rtx, lookup_static_chain (label));
-
- /* We have now loaded the frame pointer hardware register with
- the address of that corresponds to the start of the virtual
- stack vars. So replace virtual_stack_vars_rtx in all
- addresses we use with stack_pointer_rtx. */
-
- /* Get addr of containing function's current nonlocal goto handler,
- which will do any cleanups and then jump to the label. */
- addr = copy_rtx (handler_slot);
- temp = copy_to_reg (replace_rtx (addr, virtual_stack_vars_rtx,
- hard_frame_pointer_rtx));
-
- /* Restore the stack pointer. Note this uses fp just restored. */
- addr = p->x_nonlocal_goto_stack_level;
- if (addr)
- addr = replace_rtx (copy_rtx (addr),
- virtual_stack_vars_rtx,
- hard_frame_pointer_rtx);
-
- emit_stack_restore (SAVE_NONLOCAL, addr, NULL_RTX);
+ emit_move_insn (hard_frame_pointer_rtx, static_chain);
+ emit_stack_restore (SAVE_NONLOCAL, save_area, NULL_RTX);
- /* USE of hard_frame_pointer_rtx added for consistency; not clear if
- really needed. */
+ /* USE of hard_frame_pointer_rtx added for consistency;
+ not clear if really needed. */
emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
- emit_indirect_jump (temp);
+ emit_indirect_jump (handler_slot);
}
}
else