Emit the prologue/epilogue using frame offsets.
Record register save offsets in ix86_frame. Move SP/FP offsets into the global state; update them everywhere we currently handle CFA offsets. Use that global state to choose base registers and offsets for the register saves and restores. There is a bug fix contained herein, whereby r11 could be clobbered along an indirect sibcall path when the stack frame is very large (>2GB). The emit_restore_{sse_,}regs_using_mov functions didn't handle this case, but pro_epilogue_adjust_stack does. From-SVN: r162888
This commit is contained in:
parent
17959958bc
commit
ec7ded37e7
@ -1,5 +1,35 @@
|
||||
2010-08-04 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/i386/i386.h (struct machine_frame_state): Rename from
|
||||
machine_cfa_state. Add members tracking SP and FP regardless
|
||||
of the current CFA register.
|
||||
(ix86_cfa_state): Remove.
|
||||
* config/i386/i386.c (struct ix86_frame): Add reg_save_offset
|
||||
and sse_reg_save_offset members.
|
||||
(ix86_compute_frame_layout): Set them.
|
||||
(gen_push): Increment sp_offset too.
|
||||
(choose_baseaddr_len, choose_baseaddr): New.
|
||||
(ix86_emit_save_reg_using_mov): New.
|
||||
(ix86_emit_save_regs_using_mov): Use it.
|
||||
(ix86_emit_save_sse_regs_using_mov): Likewise.
|
||||
(ix86_add_cfa_restore_note): Take cfa_offset not red_offset argument;
|
||||
compare vs the saved red_zone_offset.
|
||||
(pro_epilogue_adjust_stack): Adjust sp_offset.
|
||||
(ix86_adjust_stack_and_probe): Likewise.
|
||||
(ix86_expand_prologue): Set up, use, and validate the new
|
||||
frame_state_info members. Use gen_frame_mem.
|
||||
(ix86_emit_restore_regs_using_pop): Remove red_offset parameter.
|
||||
(ix86_emit_restore_reg_using_pop): Likewise. Use and update the
|
||||
new frame_state_info members.
|
||||
(ix86_emit_leave): Likewise.
|
||||
(ix86_emit_restore_regs_using_mov): Likewise. Don't check for
|
||||
out-of-range stack pointer offsets here.
|
||||
(ix86_emit_restore_sse_regs_using_mov): Likewise.
|
||||
(ix86_expand_epilogue): Use and validate the new frame_state_info
|
||||
members. Break up and simplify the logic selecting the
|
||||
restore_regs_via_mov code path. Ensure that there will be no
|
||||
out-of-range stack pointer offsets.
|
||||
|
||||
* config/i386/cygming.h (TARGET_64BIT_MS_ABI): Remove.
|
||||
|
||||
* config/i386/i386.c (ix86_function_ms_hook_prologue): Fix
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2292,13 +2292,37 @@ enum ix86_stack_slot
|
||||
|
||||
#define FASTCALL_PREFIX '@'
|
||||
|
||||
/* Machine specific CFA tracking during prologue/epilogue generation. */
|
||||
/* Machine specific frame tracking during prologue/epilogue generation. */
|
||||
|
||||
#ifndef USED_FOR_TARGET
|
||||
struct GTY(()) machine_cfa_state
|
||||
struct GTY(()) machine_frame_state
|
||||
{
|
||||
rtx reg;
|
||||
HOST_WIDE_INT offset;
|
||||
/* This pair tracks the currently active CFA as reg+offset. When reg
|
||||
is drap_reg, we don't bother trying to record here the real CFA when
|
||||
it might really be a DW_CFA_def_cfa_expression. */
|
||||
rtx cfa_reg;
|
||||
HOST_WIDE_INT cfa_offset;
|
||||
|
||||
/* The current offset (canonically from the CFA) of ESP and EBP.
|
||||
When stack frame re-alignment is active, these may not be relative
|
||||
to the CFA. However, in all cases they are relative to the offsets
|
||||
of the saved registers stored in ix86_frame. */
|
||||
HOST_WIDE_INT sp_offset;
|
||||
HOST_WIDE_INT fp_offset;
|
||||
|
||||
/* The size of the red-zone that may be assumed for the purposes of
|
||||
eliding register restore notes in the epilogue. This may be zero
|
||||
if no red-zone is in effect, or may be reduced from the real
|
||||
red-zone value by a maximum runtime stack re-alignment value. */
|
||||
int red_zone_offset;
|
||||
|
||||
/* Indicate whether each of ESP, EBP or DRAP currently holds a valid
|
||||
value within the frame. If false then the offset above should be
|
||||
ignored. Note that DRAP, if valid, *always* points to the CFA and
|
||||
thus has an offset of zero. */
|
||||
BOOL_BITFIELD sp_valid : 1;
|
||||
BOOL_BITFIELD fp_valid : 1;
|
||||
BOOL_BITFIELD drap_valid : 1;
|
||||
};
|
||||
|
||||
struct GTY(()) machine_function {
|
||||
@ -2341,8 +2365,9 @@ struct GTY(()) machine_function {
|
||||
stack below the return address. */
|
||||
BOOL_BITFIELD static_chain_on_stack : 1;
|
||||
|
||||
/* The CFA state at the end of the prologue. */
|
||||
struct machine_cfa_state cfa;
|
||||
/* During prologue/epilogue generation, the current frame state.
|
||||
Otherwise, the frame state at the end of the prologue. */
|
||||
struct machine_frame_state fs;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -2360,7 +2385,6 @@ struct GTY(()) machine_function {
|
||||
REG_SP is live. */
|
||||
#define ix86_current_function_calls_tls_descriptor \
|
||||
(ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG))
|
||||
#define ix86_cfa_state (&cfun->machine->cfa)
|
||||
#define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack)
|
||||
|
||||
/* Control behavior of x86_file_start. */
|
||||
|
Loading…
Reference in New Issue
Block a user