mirror of git://gcc.gnu.org/git/gcc.git
i386.c (x86_64_ms_sysv_extra_clobbered_registers): Make static.
2017-06-01 Bernd Edlinger <bernd.edlinger@hotmail.de>
* config/i386/i386.c (x86_64_ms_sysv_extra_clobbered_registers): Make
static.
(xlogue_layout::get_stack_space_used, xlogue_layout::s_instances,
xlogue_layout::get_instance, logue_layout::xlogue_layout,
sp_valid_at, fp_valid_at, choose_basereg): Formatting.
(xlogue_layout::get_stub_rtx): Make static.
(xlogue_layout::get_stub_name): Avoid const-cast, make static.
(xlogue_layout::compute_stub_managed_regs): Rename to...
(xlogue_layout::count_stub_managed_regs): ...this.
(xlogue_layout::is_stub_managed_reg): New function.
(xlogue_layout::m_stub_names): Rename to...
(xlogue_layout::s_stub_names): ...this, make static.
(xlogue_layout::STUB_INDEX_OFFSET, xlogue_layout::MIN_REGS,
xlogue_layout::MAX_REGS, xlogue_layout::MAX_EXTRA_REGS,
xlogue_layout::VARIANT_COUNT, xlogue_layout::STUB_NAME_MAX_LEN,
xlogue_layout::s_stub_names): Instantiate statics.
(stub_managed_regs): Remove.
(ix86_save_reg): Use xlogue_layout::compute_stub_managed_regs.
(disable_call_ms2sysv_xlogues): Rename to...
(warn_once_call_ms2sysv_xlogues): ...this, and warn only once.
(ix86_initial_elimination_offset, ix86_expand_call): Fix call_ms2sysv
warning logic.
(ix86_static_chain): Make sure that ix86_static_chain_on_stack can't
change after reload_completed.
(ix86_can_use_return_insn_p): Use the ix86_frame data structure
directly.
(ix86_expand_prologue): Likewise.
(ix86_expand_epilogue): Likewise.
(ix86_expand_split_stack_prologue): Likewise.
(ix86_compute_frame_layout): Remove frame parameter ...
(TARGET_COMPUTE_FRAME_LAYOUT): ... and export it as a target hook.
(ix86_finalize_stack_realign_flags): Call ix86_compute_frame_layout
only if necessary.
(ix86_init_machine_status): Don't set use_fast_prologue_epilogue_nregs.
(ix86_frame): Move from here ...
* config/i386/i386.h (ix86_frame): ... to here.
(machine_function): Remove use_fast_prologue_epilogue_nregs, cache the
complete ix86_frame data structure instead. Remove some_ld_name.
From-SVN: r248798
This commit is contained in:
parent
2ded3754ad
commit
77560086aa
|
|
@ -1,3 +1,44 @@
|
||||||
|
2017-06-01 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
|
|
||||||
|
* config/i386/i386.c (x86_64_ms_sysv_extra_clobbered_registers): Make
|
||||||
|
static.
|
||||||
|
(xlogue_layout::get_stack_space_used, xlogue_layout::s_instances,
|
||||||
|
xlogue_layout::get_instance, logue_layout::xlogue_layout,
|
||||||
|
sp_valid_at, fp_valid_at, choose_basereg): Formatting.
|
||||||
|
(xlogue_layout::get_stub_rtx): Make static.
|
||||||
|
(xlogue_layout::get_stub_name): Avoid const-cast, make static.
|
||||||
|
(xlogue_layout::compute_stub_managed_regs): Rename to...
|
||||||
|
(xlogue_layout::count_stub_managed_regs): ...this.
|
||||||
|
(xlogue_layout::is_stub_managed_reg): New function.
|
||||||
|
(xlogue_layout::m_stub_names): Rename to...
|
||||||
|
(xlogue_layout::s_stub_names): ...this, make static.
|
||||||
|
(xlogue_layout::STUB_INDEX_OFFSET, xlogue_layout::MIN_REGS,
|
||||||
|
xlogue_layout::MAX_REGS, xlogue_layout::MAX_EXTRA_REGS,
|
||||||
|
xlogue_layout::VARIANT_COUNT, xlogue_layout::STUB_NAME_MAX_LEN,
|
||||||
|
xlogue_layout::s_stub_names): Instantiate statics.
|
||||||
|
(stub_managed_regs): Remove.
|
||||||
|
(ix86_save_reg): Use xlogue_layout::compute_stub_managed_regs.
|
||||||
|
(disable_call_ms2sysv_xlogues): Rename to...
|
||||||
|
(warn_once_call_ms2sysv_xlogues): ...this, and warn only once.
|
||||||
|
(ix86_initial_elimination_offset, ix86_expand_call): Fix call_ms2sysv
|
||||||
|
warning logic.
|
||||||
|
(ix86_static_chain): Make sure that ix86_static_chain_on_stack can't
|
||||||
|
change after reload_completed.
|
||||||
|
(ix86_can_use_return_insn_p): Use the ix86_frame data structure
|
||||||
|
directly.
|
||||||
|
(ix86_expand_prologue): Likewise.
|
||||||
|
(ix86_expand_epilogue): Likewise.
|
||||||
|
(ix86_expand_split_stack_prologue): Likewise.
|
||||||
|
(ix86_compute_frame_layout): Remove frame parameter ...
|
||||||
|
(TARGET_COMPUTE_FRAME_LAYOUT): ... and export it as a target hook.
|
||||||
|
(ix86_finalize_stack_realign_flags): Call ix86_compute_frame_layout
|
||||||
|
only if necessary.
|
||||||
|
(ix86_init_machine_status): Don't set use_fast_prologue_epilogue_nregs.
|
||||||
|
(ix86_frame): Move from here ...
|
||||||
|
* config/i386/i386.h (ix86_frame): ... to here.
|
||||||
|
(machine_function): Remove use_fast_prologue_epilogue_nregs, cache the
|
||||||
|
complete ix86_frame data structure instead. Remove some_ld_name.
|
||||||
|
|
||||||
2017-06-01 Pierre-Marie de Rodat <derodat@adacore.com>
|
2017-06-01 Pierre-Marie de Rodat <derodat@adacore.com>
|
||||||
|
|
||||||
* dwarf2out.c (dwarf2out_late_global_decl): Add locations for
|
* dwarf2out.c (dwarf2out_late_global_decl): Add locations for
|
||||||
|
|
|
||||||
|
|
@ -2425,7 +2425,9 @@ static int const x86_64_int_return_registers[4] =
|
||||||
|
|
||||||
/* Additional registers that are clobbered by SYSV calls. */
|
/* Additional registers that are clobbered by SYSV calls. */
|
||||||
|
|
||||||
unsigned const x86_64_ms_sysv_extra_clobbered_registers[12] =
|
#define NUM_X86_64_MS_CLOBBERED_REGS 12
|
||||||
|
static int const x86_64_ms_sysv_extra_clobbered_registers
|
||||||
|
[NUM_X86_64_MS_CLOBBERED_REGS] =
|
||||||
{
|
{
|
||||||
SI_REG, DI_REG,
|
SI_REG, DI_REG,
|
||||||
XMM6_REG, XMM7_REG,
|
XMM6_REG, XMM7_REG,
|
||||||
|
|
@ -2472,24 +2474,25 @@ public:
|
||||||
return m_regs[reg];
|
return m_regs[reg];
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *get_stub_name (enum xlogue_stub stub,
|
static const char *get_stub_name (enum xlogue_stub stub,
|
||||||
unsigned n_extra_args) const;
|
unsigned n_extra_args);
|
||||||
|
|
||||||
/* Returns an rtx for the stub's symbol based upon
|
/* Returns an rtx for the stub's symbol based upon
|
||||||
1.) the specified stub (save, restore or restore_ret) and
|
1.) the specified stub (save, restore or restore_ret) and
|
||||||
2.) the value of cfun->machine->call_ms2sysv_extra_regs and
|
2.) the value of cfun->machine->call_ms2sysv_extra_regs and
|
||||||
3.) rather or not stack alignment is being performed. */
|
3.) rather or not stack alignment is being performed. */
|
||||||
rtx get_stub_rtx (enum xlogue_stub stub) const;
|
static rtx get_stub_rtx (enum xlogue_stub stub);
|
||||||
|
|
||||||
/* Returns the amount of stack space (including padding) that the stub
|
/* Returns the amount of stack space (including padding) that the stub
|
||||||
needs to store registers based upon data in the machine_function. */
|
needs to store registers based upon data in the machine_function. */
|
||||||
HOST_WIDE_INT get_stack_space_used () const
|
HOST_WIDE_INT get_stack_space_used () const
|
||||||
{
|
{
|
||||||
const struct machine_function &m = *cfun->machine;
|
const struct machine_function *m = cfun->machine;
|
||||||
unsigned last_reg = m.call_ms2sysv_extra_regs + MIN_REGS - 1;
|
unsigned last_reg = m->call_ms2sysv_extra_regs + MIN_REGS - 1;
|
||||||
|
|
||||||
gcc_assert (m.call_ms2sysv_extra_regs <= MAX_EXTRA_REGS);
|
gcc_assert (m->call_ms2sysv_extra_regs <= MAX_EXTRA_REGS);
|
||||||
return m_regs[last_reg].offset
|
return m_regs[last_reg].offset
|
||||||
+ (m.call_ms2sysv_pad_out ? 8 : 0)
|
+ (m->call_ms2sysv_pad_out ? 8 : 0)
|
||||||
+ STUB_INDEX_OFFSET;
|
+ STUB_INDEX_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2500,7 +2503,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct xlogue_layout &get_instance ();
|
static const struct xlogue_layout &get_instance ();
|
||||||
static unsigned compute_stub_managed_regs (HARD_REG_SET &stub_managed_regs);
|
static unsigned count_stub_managed_regs ();
|
||||||
|
static bool is_stub_managed_reg (unsigned regno, unsigned count);
|
||||||
|
|
||||||
static const HOST_WIDE_INT STUB_INDEX_OFFSET = 0x70;
|
static const HOST_WIDE_INT STUB_INDEX_OFFSET = 0x70;
|
||||||
static const unsigned MIN_REGS = NUM_X86_64_MS_CLOBBERED_REGS;
|
static const unsigned MIN_REGS = NUM_X86_64_MS_CLOBBERED_REGS;
|
||||||
|
|
@ -2530,9 +2534,10 @@ private:
|
||||||
struct reginfo m_regs[MAX_REGS];
|
struct reginfo m_regs[MAX_REGS];
|
||||||
|
|
||||||
/* Lazy-inited cache of symbol names for stubs. */
|
/* Lazy-inited cache of symbol names for stubs. */
|
||||||
char m_stub_names[XLOGUE_STUB_COUNT][VARIANT_COUNT][STUB_NAME_MAX_LEN];
|
static char s_stub_names[XLOGUE_STUB_COUNT][VARIANT_COUNT]
|
||||||
|
[STUB_NAME_MAX_LEN];
|
||||||
|
|
||||||
static const struct xlogue_layout GTY(()) s_instances[XLOGUE_SET_COUNT];
|
static const xlogue_layout s_instances[XLOGUE_SET_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
const char * const xlogue_layout::STUB_BASE_NAMES[XLOGUE_STUB_COUNT] = {
|
const char * const xlogue_layout::STUB_BASE_NAMES[XLOGUE_STUB_COUNT] = {
|
||||||
|
|
@ -2572,9 +2577,20 @@ const unsigned xlogue_layout::REG_ORDER[xlogue_layout::MAX_REGS] = {
|
||||||
R15_REG, /* 0xe0 0xe8 0xd8 0xe0 */
|
R15_REG, /* 0xe0 0xe8 0xd8 0xe0 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Instantiate static const values. */
|
||||||
|
const HOST_WIDE_INT xlogue_layout::STUB_INDEX_OFFSET;
|
||||||
|
const unsigned xlogue_layout::MIN_REGS;
|
||||||
|
const unsigned xlogue_layout::MAX_REGS;
|
||||||
|
const unsigned xlogue_layout::MAX_EXTRA_REGS;
|
||||||
|
const unsigned xlogue_layout::VARIANT_COUNT;
|
||||||
|
const unsigned xlogue_layout::STUB_NAME_MAX_LEN;
|
||||||
|
|
||||||
|
/* Initialize xlogue_layout::s_stub_names to zero. */
|
||||||
|
char xlogue_layout::s_stub_names[XLOGUE_STUB_COUNT][VARIANT_COUNT]
|
||||||
|
[STUB_NAME_MAX_LEN];
|
||||||
|
|
||||||
/* Instantiates all xlogue_layout instances. */
|
/* Instantiates all xlogue_layout instances. */
|
||||||
const struct xlogue_layout GTY(())
|
const xlogue_layout xlogue_layout::s_instances[XLOGUE_SET_COUNT] = {
|
||||||
xlogue_layout::s_instances[XLOGUE_SET_COUNT] = {
|
|
||||||
xlogue_layout (0, false),
|
xlogue_layout (0, false),
|
||||||
xlogue_layout (8, false),
|
xlogue_layout (8, false),
|
||||||
xlogue_layout (0, true),
|
xlogue_layout (0, true),
|
||||||
|
|
@ -2583,7 +2599,8 @@ xlogue_layout::s_instances[XLOGUE_SET_COUNT] = {
|
||||||
|
|
||||||
/* Return an appropriate const instance of xlogue_layout based upon values
|
/* Return an appropriate const instance of xlogue_layout based upon values
|
||||||
in cfun->machine and crtl. */
|
in cfun->machine and crtl. */
|
||||||
const struct xlogue_layout &xlogue_layout::get_instance ()
|
const struct xlogue_layout &
|
||||||
|
xlogue_layout::get_instance ()
|
||||||
{
|
{
|
||||||
enum xlogue_stub_sets stub_set;
|
enum xlogue_stub_sets stub_set;
|
||||||
bool aligned_plus_8 = cfun->machine->call_ms2sysv_pad_in;
|
bool aligned_plus_8 = cfun->machine->call_ms2sysv_pad_in;
|
||||||
|
|
@ -2600,50 +2617,54 @@ const struct xlogue_layout &xlogue_layout::get_instance ()
|
||||||
return s_instances[stub_set];
|
return s_instances[stub_set];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine which clobbered registers can be saved by the stub and store
|
/* Determine how many clobbered registers can be saved by the stub.
|
||||||
them in stub_managed_regs. Returns the count of registers the stub will
|
Returns the count of registers the stub will save and restore. */
|
||||||
save and restore. */
|
|
||||||
unsigned
|
unsigned
|
||||||
xlogue_layout::compute_stub_managed_regs (HARD_REG_SET &stub_managed_regs)
|
xlogue_layout::count_stub_managed_regs ()
|
||||||
{
|
{
|
||||||
bool hfp = frame_pointer_needed || stack_realign_fp;
|
bool hfp = frame_pointer_needed || stack_realign_fp;
|
||||||
|
|
||||||
unsigned i, count;
|
unsigned i, count;
|
||||||
unsigned regno;
|
unsigned regno;
|
||||||
|
|
||||||
for (i = 0; i < NUM_X86_64_MS_CLOBBERED_REGS; ++i)
|
for (count = i = MIN_REGS; i < MAX_REGS; ++i)
|
||||||
{
|
|
||||||
regno = x86_64_ms_sysv_extra_clobbered_registers[i];
|
|
||||||
if (regno == BP_REG && hfp)
|
|
||||||
continue;
|
|
||||||
if (!ix86_save_reg (regno, false, false))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (count = i = 0; i < MAX_REGS; ++i)
|
|
||||||
{
|
{
|
||||||
regno = REG_ORDER[i];
|
regno = REG_ORDER[i];
|
||||||
if (regno == BP_REG && hfp)
|
if (regno == BP_REG && hfp)
|
||||||
continue;
|
continue;
|
||||||
if (!ix86_save_reg (regno, false, false))
|
if (!ix86_save_reg (regno, false, false))
|
||||||
break;
|
break;
|
||||||
add_to_hard_reg_set (&stub_managed_regs, DImode, regno);
|
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
gcc_assert (count >= MIN_REGS && count <= MAX_REGS);
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Determine if register REGNO is a stub managed register given the
|
||||||
|
total COUNT of stub managed registers. */
|
||||||
|
bool
|
||||||
|
xlogue_layout::is_stub_managed_reg (unsigned regno, unsigned count)
|
||||||
|
{
|
||||||
|
bool hfp = frame_pointer_needed || stack_realign_fp;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
gcc_assert (i < MAX_REGS);
|
||||||
|
if (REG_ORDER[i] == BP_REG && hfp)
|
||||||
|
++count;
|
||||||
|
else if (REG_ORDER[i] == regno)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Constructor for xlogue_layout. */
|
/* Constructor for xlogue_layout. */
|
||||||
xlogue_layout::xlogue_layout (HOST_WIDE_INT stack_align_off_in, bool hfp)
|
xlogue_layout::xlogue_layout (HOST_WIDE_INT stack_align_off_in, bool hfp)
|
||||||
: m_hfp (hfp) , m_nregs (hfp ? 17 : 18),
|
: m_hfp (hfp) , m_nregs (hfp ? 17 : 18),
|
||||||
m_stack_align_off_in (stack_align_off_in)
|
m_stack_align_off_in (stack_align_off_in)
|
||||||
{
|
{
|
||||||
memset (m_regs, 0, sizeof (m_regs));
|
|
||||||
memset (m_stub_names, 0, sizeof (m_stub_names));
|
|
||||||
|
|
||||||
HOST_WIDE_INT offset = stack_align_off_in;
|
HOST_WIDE_INT offset = stack_align_off_in;
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
|
|
||||||
for (i = j = 0; i < MAX_REGS; ++i)
|
for (i = j = 0; i < MAX_REGS; ++i)
|
||||||
{
|
{
|
||||||
unsigned regno = REG_ORDER[i];
|
unsigned regno = REG_ORDER[i];
|
||||||
|
|
@ -2665,18 +2686,18 @@ xlogue_layout::xlogue_layout (HOST_WIDE_INT stack_align_off_in, bool hfp)
|
||||||
gcc_assert (j == m_nregs);
|
gcc_assert (j == m_nregs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *xlogue_layout::get_stub_name (enum xlogue_stub stub,
|
const char *
|
||||||
unsigned n_extra_regs) const
|
xlogue_layout::get_stub_name (enum xlogue_stub stub,
|
||||||
|
unsigned n_extra_regs)
|
||||||
{
|
{
|
||||||
xlogue_layout *writey_this = const_cast<xlogue_layout*>(this);
|
char *name = s_stub_names[stub][n_extra_regs];
|
||||||
char *name = writey_this->m_stub_names[stub][n_extra_regs];
|
|
||||||
|
|
||||||
/* Lazy init */
|
/* Lazy init */
|
||||||
if (!*name)
|
if (!*name)
|
||||||
{
|
{
|
||||||
int res = snprintf (name, STUB_NAME_MAX_LEN, "__%s_%u",
|
int res = snprintf (name, STUB_NAME_MAX_LEN, "__%s_%u",
|
||||||
STUB_BASE_NAMES[stub], MIN_REGS + n_extra_regs);
|
STUB_BASE_NAMES[stub], MIN_REGS + n_extra_regs);
|
||||||
gcc_checking_assert (res <= (int)STUB_NAME_MAX_LEN);
|
gcc_checking_assert (res < (int)STUB_NAME_MAX_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
|
|
@ -2684,7 +2705,8 @@ const char *xlogue_layout::get_stub_name (enum xlogue_stub stub,
|
||||||
|
|
||||||
/* Return rtx of a symbol ref for the entry point (based upon
|
/* Return rtx of a symbol ref for the entry point (based upon
|
||||||
cfun->machine->call_ms2sysv_extra_regs) of the specified stub. */
|
cfun->machine->call_ms2sysv_extra_regs) of the specified stub. */
|
||||||
rtx xlogue_layout::get_stub_rtx (enum xlogue_stub stub) const
|
rtx
|
||||||
|
xlogue_layout::get_stub_rtx (enum xlogue_stub stub)
|
||||||
{
|
{
|
||||||
const unsigned n_extra_regs = cfun->machine->call_ms2sysv_extra_regs;
|
const unsigned n_extra_regs = cfun->machine->call_ms2sysv_extra_regs;
|
||||||
gcc_checking_assert (n_extra_regs <= MAX_EXTRA_REGS);
|
gcc_checking_assert (n_extra_regs <= MAX_EXTRA_REGS);
|
||||||
|
|
@ -2703,73 +2725,6 @@ struct GTY(()) stack_local_entry {
|
||||||
struct stack_local_entry *next;
|
struct stack_local_entry *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Structure describing stack frame layout.
|
|
||||||
Stack grows downward:
|
|
||||||
|
|
||||||
[arguments]
|
|
||||||
<- ARG_POINTER
|
|
||||||
saved pc
|
|
||||||
|
|
||||||
saved static chain if ix86_static_chain_on_stack
|
|
||||||
|
|
||||||
saved frame pointer if frame_pointer_needed
|
|
||||||
<- HARD_FRAME_POINTER
|
|
||||||
[saved regs]
|
|
||||||
<- reg_save_offset
|
|
||||||
[padding0]
|
|
||||||
<- stack_realign_offset
|
|
||||||
[saved SSE regs]
|
|
||||||
OR
|
|
||||||
[stub-saved registers for ms x64 --> sysv clobbers
|
|
||||||
<- Start of out-of-line, stub-saved/restored regs
|
|
||||||
(see libgcc/config/i386/(sav|res)ms64*.S)
|
|
||||||
[XMM6-15]
|
|
||||||
[RSI]
|
|
||||||
[RDI]
|
|
||||||
[?RBX] only if RBX is clobbered
|
|
||||||
[?RBP] only if RBP and RBX are clobbered
|
|
||||||
[?R12] only if R12 and all previous regs are clobbered
|
|
||||||
[?R13] only if R13 and all previous regs are clobbered
|
|
||||||
[?R14] only if R14 and all previous regs are clobbered
|
|
||||||
[?R15] only if R15 and all previous regs are clobbered
|
|
||||||
<- end of stub-saved/restored regs
|
|
||||||
[padding1]
|
|
||||||
]
|
|
||||||
<- outlined_save_offset
|
|
||||||
<- sse_regs_save_offset
|
|
||||||
[padding2]
|
|
||||||
| <- FRAME_POINTER
|
|
||||||
[va_arg registers] |
|
|
||||||
|
|
|
||||||
[frame] |
|
|
||||||
|
|
|
||||||
[padding2] | = to_allocate
|
|
||||||
<- STACK_POINTER
|
|
||||||
*/
|
|
||||||
struct ix86_frame
|
|
||||||
{
|
|
||||||
int nsseregs;
|
|
||||||
int nregs;
|
|
||||||
int va_arg_size;
|
|
||||||
int red_zone_size;
|
|
||||||
int outgoing_arguments_size;
|
|
||||||
|
|
||||||
/* The offsets relative to ARG_POINTER. */
|
|
||||||
HOST_WIDE_INT frame_pointer_offset;
|
|
||||||
HOST_WIDE_INT hard_frame_pointer_offset;
|
|
||||||
HOST_WIDE_INT stack_pointer_offset;
|
|
||||||
HOST_WIDE_INT hfp_save_offset;
|
|
||||||
HOST_WIDE_INT reg_save_offset;
|
|
||||||
HOST_WIDE_INT stack_realign_allocate_offset;
|
|
||||||
HOST_WIDE_INT stack_realign_offset;
|
|
||||||
HOST_WIDE_INT outlined_save_offset;
|
|
||||||
HOST_WIDE_INT sse_reg_save_offset;
|
|
||||||
|
|
||||||
/* When save_regs_using_mov is set, emit prologue using
|
|
||||||
move instead of push instructions. */
|
|
||||||
bool save_regs_using_mov;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Which cpu are we scheduling for. */
|
/* Which cpu are we scheduling for. */
|
||||||
enum attr_cpu ix86_schedule;
|
enum attr_cpu ix86_schedule;
|
||||||
|
|
||||||
|
|
@ -2861,7 +2816,7 @@ static unsigned int ix86_function_arg_boundary (machine_mode,
|
||||||
const_tree);
|
const_tree);
|
||||||
static rtx ix86_static_chain (const_tree, bool);
|
static rtx ix86_static_chain (const_tree, bool);
|
||||||
static int ix86_function_regparm (const_tree, const_tree);
|
static int ix86_function_regparm (const_tree, const_tree);
|
||||||
static void ix86_compute_frame_layout (struct ix86_frame *);
|
static void ix86_compute_frame_layout (void);
|
||||||
static bool ix86_expand_vector_init_one_nonzero (bool, machine_mode,
|
static bool ix86_expand_vector_init_one_nonzero (bool, machine_mode,
|
||||||
rtx, rtx, int);
|
rtx, rtx, int);
|
||||||
static void ix86_add_new_builtins (HOST_WIDE_INT, HOST_WIDE_INT);
|
static void ix86_add_new_builtins (HOST_WIDE_INT, HOST_WIDE_INT);
|
||||||
|
|
@ -12293,7 +12248,7 @@ ix86_can_use_return_insn_p (void)
|
||||||
if (crtl->args.pops_args && crtl->args.size >= 32768)
|
if (crtl->args.pops_args && crtl->args.size >= 32768)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ix86_compute_frame_layout (&frame);
|
frame = cfun->machine->frame;
|
||||||
return (frame.stack_pointer_offset == UNITS_PER_WORD
|
return (frame.stack_pointer_offset == UNITS_PER_WORD
|
||||||
&& (frame.nregs + frame.nsseregs) == 0);
|
&& (frame.nregs + frame.nsseregs) == 0);
|
||||||
}
|
}
|
||||||
|
|
@ -12634,10 +12589,6 @@ ix86_hard_regno_scratch_ok (unsigned int regno)
|
||||||
&& df_regs_ever_live_p (regno)));
|
&& df_regs_ever_live_p (regno)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Registers who's save & restore will be managed by stubs called from
|
|
||||||
pro/epilogue. */
|
|
||||||
static HARD_REG_SET GTY(()) stub_managed_regs;
|
|
||||||
|
|
||||||
/* Return true if register class CL should be an additional allocno
|
/* Return true if register class CL should be an additional allocno
|
||||||
class. */
|
class. */
|
||||||
|
|
||||||
|
|
@ -12718,9 +12669,13 @@ ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ignore_outlined && cfun->machine->call_ms2sysv
|
if (ignore_outlined && cfun->machine->call_ms2sysv)
|
||||||
&& in_hard_reg_set_p (stub_managed_regs, DImode, regno))
|
{
|
||||||
|
unsigned count = cfun->machine->call_ms2sysv_extra_regs
|
||||||
|
+ xlogue_layout::MIN_REGS;
|
||||||
|
if (xlogue_layout::is_stub_managed_reg (regno, count))
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (crtl->drap_reg
|
if (crtl->drap_reg
|
||||||
&& regno == REGNO (crtl->drap_reg)
|
&& regno == REGNO (crtl->drap_reg)
|
||||||
|
|
@ -12787,8 +12742,7 @@ ix86_can_eliminate (const int from, const int to)
|
||||||
HOST_WIDE_INT
|
HOST_WIDE_INT
|
||||||
ix86_initial_elimination_offset (int from, int to)
|
ix86_initial_elimination_offset (int from, int to)
|
||||||
{
|
{
|
||||||
struct ix86_frame frame;
|
struct ix86_frame frame = cfun->machine->frame;
|
||||||
ix86_compute_frame_layout (&frame);
|
|
||||||
|
|
||||||
if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
|
if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
|
||||||
return frame.hard_frame_pointer_offset;
|
return frame.hard_frame_pointer_offset;
|
||||||
|
|
@ -12818,13 +12772,16 @@ ix86_builtin_setjmp_frame_value (void)
|
||||||
return stack_realign_fp ? hard_frame_pointer_rtx : virtual_stack_vars_rtx;
|
return stack_realign_fp ? hard_frame_pointer_rtx : virtual_stack_vars_rtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disables out-of-lined msabi to sysv pro/epilogues and emits a warning if
|
/* Emits a warning for unsupported msabi to sysv pro/epilogues. */
|
||||||
warn_once is null, or *warn_once is zero. */
|
static void warn_once_call_ms2sysv_xlogues (const char *feature)
|
||||||
static void disable_call_ms2sysv_xlogues (const char *feature)
|
|
||||||
{
|
{
|
||||||
cfun->machine->call_ms2sysv = false;
|
static bool warned_once = false;
|
||||||
warning (OPT_mcall_ms2sysv_xlogues, "not currently compatible with %s.",
|
if (!warned_once)
|
||||||
|
{
|
||||||
|
warning (0, "-mcall-ms2sysv-xlogues is not compatible with %s",
|
||||||
feature);
|
feature);
|
||||||
|
warned_once = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When using -fsplit-stack, the allocation routines set a field in
|
/* When using -fsplit-stack, the allocation routines set a field in
|
||||||
|
|
@ -12836,8 +12793,9 @@ static void disable_call_ms2sysv_xlogues (const char *feature)
|
||||||
/* Fill structure ix86_frame about frame of currently computed function. */
|
/* Fill structure ix86_frame about frame of currently computed function. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ix86_compute_frame_layout (struct ix86_frame *frame)
|
ix86_compute_frame_layout (void)
|
||||||
{
|
{
|
||||||
|
struct ix86_frame *frame = &cfun->machine->frame;
|
||||||
struct machine_function *m = cfun->machine;
|
struct machine_function *m = cfun->machine;
|
||||||
unsigned HOST_WIDE_INT stack_alignment_needed;
|
unsigned HOST_WIDE_INT stack_alignment_needed;
|
||||||
HOST_WIDE_INT offset;
|
HOST_WIDE_INT offset;
|
||||||
|
|
@ -12845,8 +12803,6 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
|
||||||
HOST_WIDE_INT size = get_frame_size ();
|
HOST_WIDE_INT size = get_frame_size ();
|
||||||
HOST_WIDE_INT to_allocate;
|
HOST_WIDE_INT to_allocate;
|
||||||
|
|
||||||
CLEAR_HARD_REG_SET (stub_managed_regs);
|
|
||||||
|
|
||||||
/* m->call_ms2sysv is initially enabled in ix86_expand_call for all 64-bit
|
/* m->call_ms2sysv is initially enabled in ix86_expand_call for all 64-bit
|
||||||
* ms_abi functions that call a sysv function. We now need to prune away
|
* ms_abi functions that call a sysv function. We now need to prune away
|
||||||
* cases where it should be disabled. */
|
* cases where it should be disabled. */
|
||||||
|
|
@ -12855,32 +12811,27 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
|
||||||
gcc_assert (TARGET_64BIT_MS_ABI);
|
gcc_assert (TARGET_64BIT_MS_ABI);
|
||||||
gcc_assert (TARGET_CALL_MS2SYSV_XLOGUES);
|
gcc_assert (TARGET_CALL_MS2SYSV_XLOGUES);
|
||||||
gcc_assert (!TARGET_SEH);
|
gcc_assert (!TARGET_SEH);
|
||||||
|
gcc_assert (TARGET_SSE);
|
||||||
|
gcc_assert (!ix86_using_red_zone ());
|
||||||
|
|
||||||
if (!TARGET_SSE)
|
if (crtl->calls_eh_return)
|
||||||
|
{
|
||||||
|
gcc_assert (!reload_completed);
|
||||||
m->call_ms2sysv = false;
|
m->call_ms2sysv = false;
|
||||||
|
warn_once_call_ms2sysv_xlogues ("__builtin_eh_return");
|
||||||
/* Don't break hot-patched functions. */
|
}
|
||||||
else if (ix86_function_ms_hook_prologue (current_function_decl))
|
|
||||||
m->call_ms2sysv = false;
|
|
||||||
|
|
||||||
/* TODO: Cases not yet examined. */
|
|
||||||
else if (crtl->calls_eh_return)
|
|
||||||
disable_call_ms2sysv_xlogues ("__builtin_eh_return");
|
|
||||||
|
|
||||||
else if (ix86_static_chain_on_stack)
|
else if (ix86_static_chain_on_stack)
|
||||||
disable_call_ms2sysv_xlogues ("static call chains");
|
{
|
||||||
|
gcc_assert (!reload_completed);
|
||||||
else if (ix86_using_red_zone ())
|
m->call_ms2sysv = false;
|
||||||
disable_call_ms2sysv_xlogues ("red zones");
|
warn_once_call_ms2sysv_xlogues ("static call chains");
|
||||||
|
}
|
||||||
else if (flag_split_stack)
|
|
||||||
disable_call_ms2sysv_xlogues ("split stack");
|
|
||||||
|
|
||||||
/* Finally, compute which registers the stub will manage. */
|
/* Finally, compute which registers the stub will manage. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned count = xlogue_layout
|
unsigned count = xlogue_layout::count_stub_managed_regs ();
|
||||||
::compute_stub_managed_regs (stub_managed_regs);
|
|
||||||
m->call_ms2sysv_extra_regs = count - xlogue_layout::MIN_REGS;
|
m->call_ms2sysv_extra_regs = count - xlogue_layout::MIN_REGS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -12916,19 +12867,11 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
|
||||||
in doing anything except PUSHs. */
|
in doing anything except PUSHs. */
|
||||||
if (TARGET_SEH)
|
if (TARGET_SEH)
|
||||||
m->use_fast_prologue_epilogue = false;
|
m->use_fast_prologue_epilogue = false;
|
||||||
|
else if (!optimize_bb_for_size_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
|
||||||
/* During reload iteration the amount of registers saved can change.
|
|
||||||
Recompute the value as needed. Do not recompute when amount of registers
|
|
||||||
didn't change as reload does multiple calls to the function and does not
|
|
||||||
expect the decision to change within single iteration. */
|
|
||||||
else if (!optimize_bb_for_size_p (ENTRY_BLOCK_PTR_FOR_FN (cfun))
|
|
||||||
&& m->use_fast_prologue_epilogue_nregs != frame->nregs)
|
|
||||||
{
|
{
|
||||||
int count = frame->nregs;
|
int count = frame->nregs;
|
||||||
struct cgraph_node *node = cgraph_node::get (current_function_decl);
|
struct cgraph_node *node = cgraph_node::get (current_function_decl);
|
||||||
|
|
||||||
m->use_fast_prologue_epilogue_nregs = count;
|
|
||||||
|
|
||||||
/* The fast prologue uses move instead of push to save registers. This
|
/* The fast prologue uses move instead of push to save registers. This
|
||||||
is significantly longer, but also executes faster as modern hardware
|
is significantly longer, but also executes faster as modern hardware
|
||||||
can execute the moves in parallel, but can't do that for push/pop.
|
can execute the moves in parallel, but can't do that for push/pop.
|
||||||
|
|
@ -13145,7 +13088,8 @@ choose_baseaddr_len (unsigned int regno, HOST_WIDE_INT offset)
|
||||||
|
|
||||||
/* Determine if the stack pointer is valid for accessing the cfa_offset. */
|
/* Determine if the stack pointer is valid for accessing the cfa_offset. */
|
||||||
|
|
||||||
static inline bool sp_valid_at (HOST_WIDE_INT cfa_offset)
|
static inline bool
|
||||||
|
sp_valid_at (HOST_WIDE_INT cfa_offset)
|
||||||
{
|
{
|
||||||
const struct machine_frame_state &fs = cfun->machine->fs;
|
const struct machine_frame_state &fs = cfun->machine->fs;
|
||||||
return fs.sp_valid && !(fs.sp_realigned
|
return fs.sp_valid && !(fs.sp_realigned
|
||||||
|
|
@ -13154,7 +13098,8 @@ static inline bool sp_valid_at (HOST_WIDE_INT cfa_offset)
|
||||||
|
|
||||||
/* Determine if the frame pointer is valid for accessing the cfa_offset. */
|
/* Determine if the frame pointer is valid for accessing the cfa_offset. */
|
||||||
|
|
||||||
static inline bool fp_valid_at (HOST_WIDE_INT cfa_offset)
|
static inline bool
|
||||||
|
fp_valid_at (HOST_WIDE_INT cfa_offset)
|
||||||
{
|
{
|
||||||
const struct machine_frame_state &fs = cfun->machine->fs;
|
const struct machine_frame_state &fs = cfun->machine->fs;
|
||||||
return fs.fp_valid && !(fs.sp_valid && fs.sp_realigned
|
return fs.fp_valid && !(fs.sp_valid && fs.sp_realigned
|
||||||
|
|
@ -13164,7 +13109,8 @@ static inline bool fp_valid_at (HOST_WIDE_INT cfa_offset)
|
||||||
/* Choose a base register based upon alignment requested, speed and/or
|
/* Choose a base register based upon alignment requested, speed and/or
|
||||||
size. */
|
size. */
|
||||||
|
|
||||||
static void choose_basereg (HOST_WIDE_INT cfa_offset, rtx &base_reg,
|
static void
|
||||||
|
choose_basereg (HOST_WIDE_INT cfa_offset, rtx &base_reg,
|
||||||
HOST_WIDE_INT &base_offset,
|
HOST_WIDE_INT &base_offset,
|
||||||
unsigned int align_reqested, unsigned int *align)
|
unsigned int align_reqested, unsigned int *align)
|
||||||
{
|
{
|
||||||
|
|
@ -14159,6 +14105,7 @@ ix86_finalize_stack_realign_flags (void)
|
||||||
< (crtl->is_leaf && !ix86_current_function_calls_tls_descriptor
|
< (crtl->is_leaf && !ix86_current_function_calls_tls_descriptor
|
||||||
? crtl->max_used_stack_slot_alignment
|
? crtl->max_used_stack_slot_alignment
|
||||||
: crtl->stack_alignment_needed));
|
: crtl->stack_alignment_needed));
|
||||||
|
bool recompute_frame_layout_p = false;
|
||||||
|
|
||||||
if (crtl->stack_realign_finalized)
|
if (crtl->stack_realign_finalized)
|
||||||
{
|
{
|
||||||
|
|
@ -14208,8 +14155,12 @@ ix86_finalize_stack_realign_flags (void)
|
||||||
&& requires_stack_frame_p (insn, prologue_used,
|
&& requires_stack_frame_p (insn, prologue_used,
|
||||||
set_up_by_prologue))
|
set_up_by_prologue))
|
||||||
{
|
{
|
||||||
|
if (crtl->stack_realign_needed != stack_realign)
|
||||||
|
recompute_frame_layout_p = true;
|
||||||
crtl->stack_realign_needed = stack_realign;
|
crtl->stack_realign_needed = stack_realign;
|
||||||
crtl->stack_realign_finalized = true;
|
crtl->stack_realign_finalized = true;
|
||||||
|
if (recompute_frame_layout_p)
|
||||||
|
ix86_compute_frame_layout ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14240,10 +14191,15 @@ ix86_finalize_stack_realign_flags (void)
|
||||||
df_scan_blocks ();
|
df_scan_blocks ();
|
||||||
df_compute_regs_ever_live (true);
|
df_compute_regs_ever_live (true);
|
||||||
df_analyze ();
|
df_analyze ();
|
||||||
|
recompute_frame_layout_p = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (crtl->stack_realign_needed != stack_realign)
|
||||||
|
recompute_frame_layout_p = true;
|
||||||
crtl->stack_realign_needed = stack_realign;
|
crtl->stack_realign_needed = stack_realign;
|
||||||
crtl->stack_realign_finalized = true;
|
crtl->stack_realign_finalized = true;
|
||||||
|
if (recompute_frame_layout_p)
|
||||||
|
ix86_compute_frame_layout ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete SET_GOT right after entry block if it is allocated to reg. */
|
/* Delete SET_GOT right after entry block if it is allocated to reg. */
|
||||||
|
|
@ -14372,7 +14328,7 @@ ix86_expand_prologue (void)
|
||||||
m->fs.sp_valid = true;
|
m->fs.sp_valid = true;
|
||||||
m->fs.sp_realigned = false;
|
m->fs.sp_realigned = false;
|
||||||
|
|
||||||
ix86_compute_frame_layout (&frame);
|
frame = m->frame;
|
||||||
|
|
||||||
if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
|
if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
|
||||||
{
|
{
|
||||||
|
|
@ -15212,7 +15168,7 @@ ix86_expand_epilogue (int style)
|
||||||
bool restore_stub_is_tail = false;
|
bool restore_stub_is_tail = false;
|
||||||
|
|
||||||
ix86_finalize_stack_realign_flags ();
|
ix86_finalize_stack_realign_flags ();
|
||||||
ix86_compute_frame_layout (&frame);
|
frame = m->frame;
|
||||||
|
|
||||||
m->fs.sp_realigned = stack_realign_fp;
|
m->fs.sp_realigned = stack_realign_fp;
|
||||||
m->fs.sp_valid = stack_realign_fp
|
m->fs.sp_valid = stack_realign_fp
|
||||||
|
|
@ -15757,7 +15713,7 @@ ix86_expand_split_stack_prologue (void)
|
||||||
gcc_assert (flag_split_stack && reload_completed);
|
gcc_assert (flag_split_stack && reload_completed);
|
||||||
|
|
||||||
ix86_finalize_stack_realign_flags ();
|
ix86_finalize_stack_realign_flags ();
|
||||||
ix86_compute_frame_layout (&frame);
|
frame = cfun->machine->frame;
|
||||||
allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
|
allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
|
||||||
|
|
||||||
/* This is the label we will branch to if we have enough stack
|
/* This is the label we will branch to if we have enough stack
|
||||||
|
|
@ -29326,8 +29282,25 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
|
||||||
|
|
||||||
/* Set here, but it may get cleared later. */
|
/* Set here, but it may get cleared later. */
|
||||||
if (TARGET_CALL_MS2SYSV_XLOGUES)
|
if (TARGET_CALL_MS2SYSV_XLOGUES)
|
||||||
|
{
|
||||||
|
if (!TARGET_SSE)
|
||||||
|
;
|
||||||
|
|
||||||
|
/* Don't break hot-patched functions. */
|
||||||
|
else if (ix86_function_ms_hook_prologue (current_function_decl))
|
||||||
|
;
|
||||||
|
|
||||||
|
/* TODO: Cases not yet examined. */
|
||||||
|
else if (flag_split_stack)
|
||||||
|
warn_once_call_ms2sysv_xlogues ("-fsplit-stack");
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gcc_assert (!reload_completed);
|
||||||
cfun->machine->call_ms2sysv = true;
|
cfun->machine->call_ms2sysv = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (vec_len > 1)
|
if (vec_len > 1)
|
||||||
call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (vec_len, vec));
|
call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (vec_len, vec));
|
||||||
|
|
@ -29461,7 +29434,6 @@ ix86_init_machine_status (void)
|
||||||
struct machine_function *f;
|
struct machine_function *f;
|
||||||
|
|
||||||
f = ggc_cleared_alloc<machine_function> ();
|
f = ggc_cleared_alloc<machine_function> ();
|
||||||
f->use_fast_prologue_epilogue_nregs = -1;
|
|
||||||
f->call_abi = ix86_abi;
|
f->call_abi = ix86_abi;
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
|
|
@ -31521,8 +31493,12 @@ ix86_static_chain (const_tree fndecl_or_type, bool incoming_p)
|
||||||
same once we're executing the nested function. */
|
same once we're executing the nested function. */
|
||||||
if (incoming_p)
|
if (incoming_p)
|
||||||
{
|
{
|
||||||
if (fndecl == current_function_decl)
|
if (fndecl == current_function_decl
|
||||||
|
&& !ix86_static_chain_on_stack)
|
||||||
|
{
|
||||||
|
gcc_assert (!reload_completed);
|
||||||
ix86_static_chain_on_stack = true;
|
ix86_static_chain_on_stack = true;
|
||||||
|
}
|
||||||
return gen_frame_mem (SImode,
|
return gen_frame_mem (SImode,
|
||||||
plus_constant (Pmode,
|
plus_constant (Pmode,
|
||||||
arg_pointer_rtx, -8));
|
arg_pointer_rtx, -8));
|
||||||
|
|
@ -52833,6 +52809,9 @@ ix86_run_selftests (void)
|
||||||
#undef TARGET_LEGITIMATE_CONSTANT_P
|
#undef TARGET_LEGITIMATE_CONSTANT_P
|
||||||
#define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
|
#define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
|
||||||
|
|
||||||
|
#undef TARGET_COMPUTE_FRAME_LAYOUT
|
||||||
|
#define TARGET_COMPUTE_FRAME_LAYOUT ix86_compute_frame_layout
|
||||||
|
|
||||||
#undef TARGET_FRAME_POINTER_REQUIRED
|
#undef TARGET_FRAME_POINTER_REQUIRED
|
||||||
#define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
|
#define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2163,10 +2163,6 @@ extern int const dbx_register_map[FIRST_PSEUDO_REGISTER];
|
||||||
extern int const dbx64_register_map[FIRST_PSEUDO_REGISTER];
|
extern int const dbx64_register_map[FIRST_PSEUDO_REGISTER];
|
||||||
extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
|
extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
|
||||||
|
|
||||||
extern unsigned const x86_64_ms_sysv_extra_clobbered_registers[12];
|
|
||||||
#define NUM_X86_64_MS_CLOBBERED_REGS \
|
|
||||||
(ARRAY_SIZE (x86_64_ms_sysv_extra_clobbered_registers))
|
|
||||||
|
|
||||||
/* Before the prologue, RA is at 0(%esp). */
|
/* Before the prologue, RA is at 0(%esp). */
|
||||||
#define INCOMING_RETURN_ADDR_RTX \
|
#define INCOMING_RETURN_ADDR_RTX \
|
||||||
gen_rtx_MEM (Pmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM))
|
gen_rtx_MEM (Pmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM))
|
||||||
|
|
@ -2448,9 +2444,76 @@ enum avx_u128_state
|
||||||
|
|
||||||
#define FASTCALL_PREFIX '@'
|
#define FASTCALL_PREFIX '@'
|
||||||
|
|
||||||
|
#ifndef USED_FOR_TARGET
|
||||||
|
/* Structure describing stack frame layout.
|
||||||
|
Stack grows downward:
|
||||||
|
|
||||||
|
[arguments]
|
||||||
|
<- ARG_POINTER
|
||||||
|
saved pc
|
||||||
|
|
||||||
|
saved static chain if ix86_static_chain_on_stack
|
||||||
|
|
||||||
|
saved frame pointer if frame_pointer_needed
|
||||||
|
<- HARD_FRAME_POINTER
|
||||||
|
[saved regs]
|
||||||
|
<- reg_save_offset
|
||||||
|
[padding0]
|
||||||
|
<- stack_realign_offset
|
||||||
|
[saved SSE regs]
|
||||||
|
OR
|
||||||
|
[stub-saved registers for ms x64 --> sysv clobbers
|
||||||
|
<- Start of out-of-line, stub-saved/restored regs
|
||||||
|
(see libgcc/config/i386/(sav|res)ms64*.S)
|
||||||
|
[XMM6-15]
|
||||||
|
[RSI]
|
||||||
|
[RDI]
|
||||||
|
[?RBX] only if RBX is clobbered
|
||||||
|
[?RBP] only if RBP and RBX are clobbered
|
||||||
|
[?R12] only if R12 and all previous regs are clobbered
|
||||||
|
[?R13] only if R13 and all previous regs are clobbered
|
||||||
|
[?R14] only if R14 and all previous regs are clobbered
|
||||||
|
[?R15] only if R15 and all previous regs are clobbered
|
||||||
|
<- end of stub-saved/restored regs
|
||||||
|
[padding1]
|
||||||
|
]
|
||||||
|
<- outlined_save_offset
|
||||||
|
<- sse_regs_save_offset
|
||||||
|
[padding2]
|
||||||
|
| <- FRAME_POINTER
|
||||||
|
[va_arg registers] |
|
||||||
|
|
|
||||||
|
[frame] |
|
||||||
|
|
|
||||||
|
[padding2] | = to_allocate
|
||||||
|
<- STACK_POINTER
|
||||||
|
*/
|
||||||
|
struct GTY(()) ix86_frame
|
||||||
|
{
|
||||||
|
int nsseregs;
|
||||||
|
int nregs;
|
||||||
|
int va_arg_size;
|
||||||
|
int red_zone_size;
|
||||||
|
int outgoing_arguments_size;
|
||||||
|
|
||||||
|
/* The offsets relative to ARG_POINTER. */
|
||||||
|
HOST_WIDE_INT frame_pointer_offset;
|
||||||
|
HOST_WIDE_INT hard_frame_pointer_offset;
|
||||||
|
HOST_WIDE_INT stack_pointer_offset;
|
||||||
|
HOST_WIDE_INT hfp_save_offset;
|
||||||
|
HOST_WIDE_INT reg_save_offset;
|
||||||
|
HOST_WIDE_INT stack_realign_allocate_offset;
|
||||||
|
HOST_WIDE_INT stack_realign_offset;
|
||||||
|
HOST_WIDE_INT outlined_save_offset;
|
||||||
|
HOST_WIDE_INT sse_reg_save_offset;
|
||||||
|
|
||||||
|
/* When save_regs_using_mov is set, emit prologue using
|
||||||
|
move instead of push instructions. */
|
||||||
|
bool save_regs_using_mov;
|
||||||
|
};
|
||||||
|
|
||||||
/* Machine specific frame tracking during prologue/epilogue generation. */
|
/* Machine specific frame tracking during prologue/epilogue generation. */
|
||||||
|
|
||||||
#ifndef USED_FOR_TARGET
|
|
||||||
struct GTY(()) machine_frame_state
|
struct GTY(()) machine_frame_state
|
||||||
{
|
{
|
||||||
/* This pair tracks the currently active CFA as reg+offset. When reg
|
/* This pair tracks the currently active CFA as reg+offset. When reg
|
||||||
|
|
@ -2515,14 +2578,12 @@ enum function_type
|
||||||
|
|
||||||
struct GTY(()) machine_function {
|
struct GTY(()) machine_function {
|
||||||
struct stack_local_entry *stack_locals;
|
struct stack_local_entry *stack_locals;
|
||||||
const char *some_ld_name;
|
|
||||||
int varargs_gpr_size;
|
int varargs_gpr_size;
|
||||||
int varargs_fpr_size;
|
int varargs_fpr_size;
|
||||||
int optimize_mode_switching[MAX_386_ENTITIES];
|
int optimize_mode_switching[MAX_386_ENTITIES];
|
||||||
|
|
||||||
/* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE
|
/* Cached initial frame layout for the current function. */
|
||||||
has been computed for. */
|
struct ix86_frame frame;
|
||||||
int use_fast_prologue_epilogue_nregs;
|
|
||||||
|
|
||||||
/* For -fsplit-stack support: A stack local which holds a pointer to
|
/* For -fsplit-stack support: A stack local which holds a pointer to
|
||||||
the stack arguments for a function with a variable number of
|
the stack arguments for a function with a variable number of
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue