parent
a196f01fdf
commit
59257ff7b8
15
gcc/calls.c
15
gcc/calls.c
|
@ -800,7 +800,7 @@ expand_call (exp, target, ignore)
|
||||||
|
|
||||||
if (old_stack_level == 0)
|
if (old_stack_level == 0)
|
||||||
{
|
{
|
||||||
old_stack_level = copy_to_mode_reg (Pmode, stack_pointer_rtx);
|
emit_stack_save (SAVE_BLOCK, &old_stack_level, 0);
|
||||||
old_pending_adj = pending_stack_adjust;
|
old_pending_adj = pending_stack_adjust;
|
||||||
pending_stack_adjust = 0;
|
pending_stack_adjust = 0;
|
||||||
}
|
}
|
||||||
|
@ -1060,7 +1060,7 @@ expand_call (exp, target, ignore)
|
||||||
{
|
{
|
||||||
if (old_stack_level == 0)
|
if (old_stack_level == 0)
|
||||||
{
|
{
|
||||||
old_stack_level = copy_to_mode_reg (Pmode, stack_pointer_rtx);
|
emit_stack_save (SAVE_BLOCK, &old_stack_level, 0);
|
||||||
old_pending_adj = pending_stack_adjust;
|
old_pending_adj = pending_stack_adjust;
|
||||||
pending_stack_adjust = 0;
|
pending_stack_adjust = 0;
|
||||||
}
|
}
|
||||||
|
@ -1520,7 +1520,7 @@ expand_call (exp, target, ignore)
|
||||||
|
|
||||||
if (old_stack_level)
|
if (old_stack_level)
|
||||||
{
|
{
|
||||||
emit_move_insn (stack_pointer_rtx, old_stack_level);
|
emit_stack_restore (SAVE_BLOCK, old_stack_level, 0);
|
||||||
pending_stack_adjust = old_pending_adj;
|
pending_stack_adjust = old_pending_adj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1570,9 +1570,12 @@ expand_call (exp, target, ignore)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If this was alloca, record the new stack level for nonlocal gotos. */
|
/* If this was alloca, record the new stack level for nonlocal gotos.
|
||||||
if (may_be_alloca && nonlocal_goto_stack_level != 0)
|
Check for the handler slots since we might not have a save area
|
||||||
emit_move_insn (nonlocal_goto_stack_level, stack_pointer_rtx);
|
for non-local gotos. */
|
||||||
|
|
||||||
|
if (may_be_alloca && nonlocal_goto_handler_slot != 0)
|
||||||
|
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, 0);
|
||||||
|
|
||||||
pop_temp_slots ();
|
pop_temp_slots ();
|
||||||
|
|
||||||
|
|
|
@ -2835,9 +2835,7 @@
|
||||||
;; Next come insns related to the calling sequence.
|
;; Next come insns related to the calling sequence.
|
||||||
;;
|
;;
|
||||||
;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
|
;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
|
||||||
;; We move the back-chain and decrement the stack pointer. This is slightly
|
;; We move the back-chain and decrement the stack pointer.
|
||||||
;; less efficient than it needs to be for long constants, but that case
|
|
||||||
;; should be rare.
|
|
||||||
|
|
||||||
(define_expand "allocate_stack"
|
(define_expand "allocate_stack"
|
||||||
[(set (reg:SI 1)
|
[(set (reg:SI 1)
|
||||||
|
@ -2852,6 +2850,63 @@
|
||||||
emit_move_insn (stack_bot, chain);
|
emit_move_insn (stack_bot, chain);
|
||||||
DONE;
|
DONE;
|
||||||
}")
|
}")
|
||||||
|
|
||||||
|
;; These patterns say how to save and restore the stack pointer. We need not
|
||||||
|
;; save the stack pointer at function level since we are careful to
|
||||||
|
;; preserve the backchain. At block level, we have to restore the backchain
|
||||||
|
;; when we restore the stack pointer.
|
||||||
|
;;
|
||||||
|
;; For nonlocal gotos, we must save both the stack pointer and its
|
||||||
|
;; backchain and restore both. Note that in the nonlocal case, the
|
||||||
|
;; save area is a memory location.
|
||||||
|
|
||||||
|
(define_expand "save_stack_function"
|
||||||
|
[(use (const_int 0))]
|
||||||
|
""
|
||||||
|
"")
|
||||||
|
|
||||||
|
(define_expand "restore_stack_function"
|
||||||
|
[(use (const_int 0))]
|
||||||
|
""
|
||||||
|
"")
|
||||||
|
|
||||||
|
(define_expand "restore_stack_block"
|
||||||
|
[(set (match_dup 2) (mem:SI (match_operand:SI 0 "register_operand" "")))
|
||||||
|
(set (match_dup 0) (match_operand:SI 1 "register_operand" ""))
|
||||||
|
(set (mem:SI (match_dup 0)) (match_dup 2))]
|
||||||
|
""
|
||||||
|
"
|
||||||
|
{ operands[2] = gen_reg_rtx (SImode); }")
|
||||||
|
|
||||||
|
(define_expand "save_stack_nonlocal"
|
||||||
|
[(match_operand:DI 0 "memory_operand" "")
|
||||||
|
(match_operand:SI 1 "register_operand" "")]
|
||||||
|
""
|
||||||
|
"
|
||||||
|
{
|
||||||
|
rtx temp = gen_reg_rtx (SImode);
|
||||||
|
|
||||||
|
/* Copy the backchain to the first word, sp to the second. */
|
||||||
|
emit_move_insn (temp, gen_rtx (MEM, SImode, operands[1]));
|
||||||
|
emit_move_insn (operand_subword (operands[0], 0, 0, DImode), temp);
|
||||||
|
emit_move_insn (operand_subword (operands[0], 1, 0, DImode), operands[1]);
|
||||||
|
DONE;
|
||||||
|
}")
|
||||||
|
|
||||||
|
(define_expand "restore_stack_nonlocal"
|
||||||
|
[(match_operand:SI 0 "register_operand" "")
|
||||||
|
(match_operand:DI 1 "memory_operand" "")]
|
||||||
|
""
|
||||||
|
"
|
||||||
|
{
|
||||||
|
rtx temp = gen_reg_rtx (SImode);
|
||||||
|
|
||||||
|
/* Restore the backchain from the first word, sp from the second. */
|
||||||
|
emit_move_insn (temp, operand_subword (operands[1], 0, 0, DImode));
|
||||||
|
emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, DImode));
|
||||||
|
emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp);
|
||||||
|
DONE;
|
||||||
|
}")
|
||||||
|
|
||||||
;; A function pointer is a pointer to a data area whose first word contains
|
;; A function pointer is a pointer to a data area whose first word contains
|
||||||
;; the actual address of the function, whose second word contains a pointer
|
;; the actual address of the function, whose second word contains a pointer
|
||||||
|
|
121
gcc/explow.c
121
gcc/explow.c
|
@ -681,6 +681,127 @@ round_push (size)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save the stack pointer for the purpose in SAVE_LEVEL. PSAVE is a pointer
|
||||||
|
to a previously-created save area. If no save area has been allocated,
|
||||||
|
this function will allocate one. If a save area is specified, it
|
||||||
|
must be of the proper mode.
|
||||||
|
|
||||||
|
The insns are emitted after insn AFTER, if nonzero, otherwise the insns
|
||||||
|
are emitted at the current position. */
|
||||||
|
|
||||||
|
void
|
||||||
|
emit_stack_save (save_level, psave, after)
|
||||||
|
enum save_level save_level;
|
||||||
|
rtx *psave;
|
||||||
|
rtx after;
|
||||||
|
{
|
||||||
|
rtx sa = *psave;
|
||||||
|
/* The default is that we use a move insn and save in a Pmode object. */
|
||||||
|
rtx (*fcn) () = gen_move_insn;
|
||||||
|
enum machine_mode mode = Pmode;
|
||||||
|
|
||||||
|
/* See if this machine has anything special to do for this kind of save. */
|
||||||
|
switch (save_level)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_save_stack_block
|
||||||
|
case SAVE_BLOCK:
|
||||||
|
if (HAVE_save_stack_block)
|
||||||
|
{
|
||||||
|
fcn = gen_save_stack_block;
|
||||||
|
mode = insn_operand_mode[CODE_FOR_save_stack_block][0];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_save_stack_function
|
||||||
|
case SAVE_FUNCTION:
|
||||||
|
if (HAVE_save_stack_function)
|
||||||
|
{
|
||||||
|
fcn = gen_save_stack_function;
|
||||||
|
mode = insn_operand_mode[CODE_FOR_save_stack_function][0];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_save_stack_nonlocal
|
||||||
|
case SAVE_NONLOCAL:
|
||||||
|
if (HAVE_save_stack_nonlocal)
|
||||||
|
{
|
||||||
|
fcn = gen_save_stack_nonlocal;
|
||||||
|
mode = insn_operand_mode[CODE_FOR_save_stack_nonlocal][0];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there is no save area and we have to allocate one, do so. Otherwise
|
||||||
|
verify the save area is the proper mode. */
|
||||||
|
|
||||||
|
if (sa == 0)
|
||||||
|
{
|
||||||
|
if (mode != VOIDmode)
|
||||||
|
{
|
||||||
|
if (save_level == SAVE_NONLOCAL)
|
||||||
|
*psave = sa = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
|
||||||
|
else
|
||||||
|
*psave = sa = gen_reg_rtx (mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mode == VOIDmode || GET_MODE (sa) != mode)
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (after)
|
||||||
|
emit_insn_after (fcn (sa, stack_pointer_rtx), after);
|
||||||
|
else
|
||||||
|
emit_insn (fcn (sa, stack_pointer_rtx));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore the stack pointer for the purpose in SAVE_LEVEL. SA is the save
|
||||||
|
area made by emit_stack_save. If it is zero, we have nothing to do.
|
||||||
|
|
||||||
|
Put any emitted insns after insn AFTER, if nonzero, otherwise at
|
||||||
|
current position. */
|
||||||
|
|
||||||
|
void
|
||||||
|
emit_stack_restore (save_level, sa, after)
|
||||||
|
enum save_level save_level;
|
||||||
|
rtx after;
|
||||||
|
rtx sa;
|
||||||
|
{
|
||||||
|
/* The default is that we use a move insn. */
|
||||||
|
rtx (*fcn) () = gen_move_insn;
|
||||||
|
|
||||||
|
/* See if this machine has anything special to do for this kind of save. */
|
||||||
|
switch (save_level)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_restore_stack_block
|
||||||
|
case SAVE_BLOCK:
|
||||||
|
if (HAVE_restore_stack_block)
|
||||||
|
fcn = gen_restore_stack_block;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_restore_stack_function
|
||||||
|
case SAVE_FUNCTION:
|
||||||
|
if (HAVE_restore_stack_function)
|
||||||
|
fcn = gen_restore_stack_function;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_restore_stack_nonlocal
|
||||||
|
|
||||||
|
case SAVE_NONLOCAL:
|
||||||
|
if (HAVE_restore_stack_nonlocal)
|
||||||
|
fcn = gen_restore_stack_nonlocal;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (after)
|
||||||
|
emit_insn_after (fcn (stack_pointer_rtx, sa), after);
|
||||||
|
else
|
||||||
|
emit_insn (fcn (stack_pointer_rtx, sa));
|
||||||
|
}
|
||||||
|
|
||||||
/* Return an rtx representing the address of an area of memory dynamically
|
/* Return an rtx representing the address of an area of memory dynamically
|
||||||
pushed on the stack. This region of memory is always aligned to
|
pushed on the stack. This region of memory is always aligned to
|
||||||
a multiple of BIGGEST_ALIGNMENT.
|
a multiple of BIGGEST_ALIGNMENT.
|
||||||
|
|
|
@ -539,6 +539,15 @@ extern void adjust_stack ();
|
||||||
/* Add some bytes to the stack. An rtx says how many. */
|
/* Add some bytes to the stack. An rtx says how many. */
|
||||||
extern void anti_adjust_stack ();
|
extern void anti_adjust_stack ();
|
||||||
|
|
||||||
|
/* This enum is used for the following two functions. */
|
||||||
|
enum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL};
|
||||||
|
|
||||||
|
/* Save the stack pointer at the specified level. */
|
||||||
|
extern void emit_stack_save ();
|
||||||
|
|
||||||
|
/* Restore the stack pointer from a save area of the specified level. */
|
||||||
|
extern void emit_stack_restore ();
|
||||||
|
|
||||||
/* Allocate some space on the stack dynamically and return its address. An rtx
|
/* Allocate some space on the stack dynamically and return its address. An rtx
|
||||||
says how many bytes. */
|
says how many bytes. */
|
||||||
extern rtx allocate_dynamic_stack_space ();
|
extern rtx allocate_dynamic_stack_space ();
|
||||||
|
|
|
@ -2317,11 +2317,11 @@ delete_handlers ()
|
||||||
if (GET_CODE (insn) == CODE_LABEL)
|
if (GET_CODE (insn) == CODE_LABEL)
|
||||||
LABEL_PRESERVE_P (insn) = 0;
|
LABEL_PRESERVE_P (insn) = 0;
|
||||||
if (GET_CODE (insn) == INSN
|
if (GET_CODE (insn) == INSN
|
||||||
&& GET_CODE (PATTERN (insn)) == SET
|
&& ((nonlocal_goto_handler_slot != 0
|
||||||
&& (SET_DEST (PATTERN (insn)) == nonlocal_goto_handler_slot
|
&& reg_mentioned_p (nonlocal_goto_handler_slot, PATTERN (insn)))
|
||||||
|| SET_SRC (PATTERN (insn)) == nonlocal_goto_handler_slot
|
|| (nonlocal_goto_stack_level != 0
|
||||||
|| SET_DEST (PATTERN (insn)) == nonlocal_goto_stack_level
|
&& reg_mentioned_p (nonlocal_goto_stack_level,
|
||||||
|| SET_SRC (PATTERN (insn)) == nonlocal_goto_stack_level))
|
PATTERN (insn)))))
|
||||||
delete_insn (insn);
|
delete_insn (insn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3961,10 +3961,10 @@ expand_function_end (filename, line)
|
||||||
#endif
|
#endif
|
||||||
if (current_function_calls_alloca)
|
if (current_function_calls_alloca)
|
||||||
{
|
{
|
||||||
rtx tem = gen_reg_rtx (Pmode);
|
rtx tem = 0;
|
||||||
emit_insn_after (gen_rtx (SET, VOIDmode, tem, stack_pointer_rtx),
|
|
||||||
parm_birth_insn);
|
emit_stack_save (SAVE_FUNCTION, &tem, parm_birth_insn);
|
||||||
emit_insn (gen_rtx (SET, VOIDmode, stack_pointer_rtx, tem));
|
emit_stack_restore (SAVE_FUNCTION, tem, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If scalar return value was computed in a pseudo-reg,
|
/* If scalar return value was computed in a pseudo-reg,
|
||||||
|
|
67
gcc/stmt.c
67
gcc/stmt.c
|
@ -586,11 +586,9 @@ declare_nonlocal_label (label)
|
||||||
{
|
{
|
||||||
nonlocal_goto_handler_slot
|
nonlocal_goto_handler_slot
|
||||||
= assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
|
= assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
|
||||||
nonlocal_goto_stack_level
|
emit_stack_save (SAVE_NONLOCAL,
|
||||||
= assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
|
&nonlocal_goto_stack_level,
|
||||||
emit_insn_before (gen_move_insn (nonlocal_goto_stack_level,
|
PREV_INSN (tail_recursion_reentry));
|
||||||
stack_pointer_rtx),
|
|
||||||
tail_recursion_reentry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,27 +607,50 @@ expand_goto (label)
|
||||||
struct function *p = find_function_data (context);
|
struct function *p = find_function_data (context);
|
||||||
rtx temp;
|
rtx temp;
|
||||||
p->has_nonlocal_label = 1;
|
p->has_nonlocal_label = 1;
|
||||||
|
|
||||||
|
/* Copy the rtl for the slots so that they won't be shared in
|
||||||
|
case the virtual stack vars register gets instantiated differently
|
||||||
|
in the parent than in the child. */
|
||||||
|
|
||||||
#if HAVE_nonlocal_goto
|
#if HAVE_nonlocal_goto
|
||||||
if (HAVE_nonlocal_goto)
|
if (HAVE_nonlocal_goto)
|
||||||
emit_insn (gen_nonlocal_goto (lookup_static_chain (label),
|
emit_insn (gen_nonlocal_goto (lookup_static_chain (label),
|
||||||
p->nonlocal_goto_handler_slot,
|
copy_rtx (p->nonlocal_goto_handler_slot),
|
||||||
p->nonlocal_goto_stack_level,
|
copy_rtx (p->nonlocal_goto_stack_level),
|
||||||
gen_rtx (LABEL_REF, Pmode,
|
gen_rtx (LABEL_REF, Pmode,
|
||||||
label_rtx (label))));
|
label_rtx (label))));
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
rtx addr;
|
||||||
|
|
||||||
/* Restore frame pointer for containing function.
|
/* Restore frame pointer for containing function.
|
||||||
This sets the actual hard register used for the frame pointer
|
This sets the actual hard register used for the frame pointer
|
||||||
to the location of the function's incoming static chain info.
|
to the location of the function's incoming static chain info.
|
||||||
The non-local goto handler will then adjust it to contain the
|
The non-local goto handler will then adjust it to contain the
|
||||||
proper value and reload the argument pointer, if needed. */
|
proper value and reload the argument pointer, if needed. */
|
||||||
emit_move_insn (frame_pointer_rtx, lookup_static_chain (label));
|
emit_move_insn (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,
|
/* Get addr of containing function's current nonlocal goto handler,
|
||||||
which will do any cleanups and then jump to the label. */
|
which will do any cleanups and then jump to the label. */
|
||||||
temp = copy_to_reg (p->nonlocal_goto_handler_slot);
|
addr = copy_rtx (p->nonlocal_goto_handler_slot);
|
||||||
|
temp = copy_to_reg (replace_rtx (addr, virtual_stack_vars_rtx,
|
||||||
|
frame_pointer_rtx));
|
||||||
|
|
||||||
/* Restore the stack pointer. Note this uses fp just restored. */
|
/* Restore the stack pointer. Note this uses fp just restored. */
|
||||||
emit_move_insn (stack_pointer_rtx, p->nonlocal_goto_stack_level);
|
addr = p->nonlocal_goto_stack_level;
|
||||||
|
if (addr)
|
||||||
|
addr = replace_rtx (copy_rtx (p->nonlocal_goto_stack_level),
|
||||||
|
replace_rtx (addr, virtual_stack_vars_rtx,
|
||||||
|
frame_pointer_rtx));
|
||||||
|
|
||||||
|
emit_stack_restore (SAVE_NONLOCAL, addr, 0);
|
||||||
|
|
||||||
/* Put in the static chain register the nonlocal label address. */
|
/* Put in the static chain register the nonlocal label address. */
|
||||||
emit_move_insn (static_chain_rtx,
|
emit_move_insn (static_chain_rtx,
|
||||||
gen_rtx (LABEL_REF, Pmode, label_rtx (label)));
|
gen_rtx (LABEL_REF, Pmode, label_rtx (label)));
|
||||||
|
@ -691,7 +712,7 @@ expand_goto_internal (body, label, last_insn)
|
||||||
the stack pointer. This one should be deleted as dead by flow. */
|
the stack pointer. This one should be deleted as dead by flow. */
|
||||||
clear_pending_stack_adjust ();
|
clear_pending_stack_adjust ();
|
||||||
do_pending_stack_adjust ();
|
do_pending_stack_adjust ();
|
||||||
emit_move_insn (stack_pointer_rtx, stack_level);
|
emit_stack_restore (SAVE_BLOCK, stack_level, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body != 0 && DECL_TOO_LATE (body))
|
if (body != 0 && DECL_TOO_LATE (body))
|
||||||
|
@ -902,8 +923,7 @@ fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
|
||||||
/* Restore stack level for the biggest contour that this
|
/* Restore stack level for the biggest contour that this
|
||||||
jump jumps out of. */
|
jump jumps out of. */
|
||||||
if (f->stack_level)
|
if (f->stack_level)
|
||||||
emit_insn_after (gen_move_insn (stack_pointer_rtx, f->stack_level),
|
emit_stack_restore (SAVE_BLOCK, f->stack_level, f->before_jump);
|
||||||
f->before_jump);
|
|
||||||
f->before_jump = 0;
|
f->before_jump = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2592,14 +2612,15 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
|
||||||
|
|
||||||
if (thisblock->data.block.stack_level != 0)
|
if (thisblock->data.block.stack_level != 0)
|
||||||
{
|
{
|
||||||
emit_move_insn (stack_pointer_rtx,
|
emit_stack_restore (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
|
||||||
thisblock->data.block.stack_level);
|
thisblock->data.block.stack_level, 0);
|
||||||
if (nonlocal_goto_stack_level != 0)
|
if (nonlocal_goto_handler_slot != 0)
|
||||||
emit_move_insn (nonlocal_goto_stack_level, stack_pointer_rtx);
|
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Any gotos out of this block must also do these things.
|
/* Any gotos out of this block must also do these things.
|
||||||
Also report any gotos with fixups that came to labels in this level. */
|
Also report any gotos with fixups that came to labels in this
|
||||||
|
level. */
|
||||||
fixup_gotos (thisblock,
|
fixup_gotos (thisblock,
|
||||||
thisblock->data.block.stack_level,
|
thisblock->data.block.stack_level,
|
||||||
thisblock->data.block.cleanups,
|
thisblock->data.block.cleanups,
|
||||||
|
@ -2753,8 +2774,9 @@ expand_decl (decl)
|
||||||
if (thisblock->data.block.stack_level == 0)
|
if (thisblock->data.block.stack_level == 0)
|
||||||
{
|
{
|
||||||
do_pending_stack_adjust ();
|
do_pending_stack_adjust ();
|
||||||
thisblock->data.block.stack_level
|
emit_stack_save (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
|
||||||
= copy_to_reg (stack_pointer_rtx);
|
&thisblock->data.block.stack_level,
|
||||||
|
thisblock->data.block.first_insn);
|
||||||
stack_block_stack = thisblock;
|
stack_block_stack = thisblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2765,11 +2787,14 @@ expand_decl (decl)
|
||||||
0, VOIDmode, 0);
|
0, VOIDmode, 0);
|
||||||
free_temp_slots ();
|
free_temp_slots ();
|
||||||
|
|
||||||
|
/* This is equivalent to calling alloca. */
|
||||||
|
current_function_calls_alloca = 1;
|
||||||
|
|
||||||
/* Allocate space on the stack for the variable. */
|
/* Allocate space on the stack for the variable. */
|
||||||
address = allocate_dynamic_stack_space (size, 0, DECL_ALIGN (decl));
|
address = allocate_dynamic_stack_space (size, 0, DECL_ALIGN (decl));
|
||||||
|
|
||||||
if (nonlocal_goto_stack_level != 0)
|
if (nonlocal_goto_handler_slot != 0)
|
||||||
emit_move_insn (nonlocal_goto_stack_level, stack_pointer_rtx);
|
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, 0);
|
||||||
|
|
||||||
/* Reference the variable indirect through that rtx. */
|
/* Reference the variable indirect through that rtx. */
|
||||||
DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl), address);
|
DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl), address);
|
||||||
|
|
Loading…
Reference in New Issue