mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-21 14:50:57 +08:00
re PR target/46030 (registers trashed with -Os)
PR target/46030 * config/rs6000/rs6000.c (struct rs6000_stack): Add reload_completed and savres_strategy. (stack_info): New file scope var. (rs6000_init_machine_status): Init stack_info. (SAVRES_INLINE_FPRS, SAVRES_INLINE_GPRS, SAVRES_NOINLINE_GPRS_SAVES_LR, SAVRES_NOINLINE_FPRS_SAVES_LR, SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR): Replace with.. (SAVE_INLINE_FPRS, SAVE_INLINE_GPRS, REST_INLINE_FPRS, REST_INLINE_GPRS, SAVE_NOINLINE_GPRS_SAVES_LR, SAVE_NOINLINE_FPRS_SAVES_LR REST_NOINLINE_FPRS_DOESNT_RESTORE_LR): ..this. Update all refs. (rs6000_savres_strategy): Rewrite. (rs6000_stack_info): Use "stack_info" in place of local "info". Return cached stack info when reload_completed unless ENABLE_CHECKING in which case confirm newly calculated stack info matches old info. Delay calculation of lr_save_p, set it for out of line gp save/restore as well as fp. Call rs6000_savres_strategy from here.. (rs6000_emit_prologue, rs6000_emit_epilogue): ..rather than here. (rs6000_output_function_prologue): Use info->savres_strategy to determine whether fp save/restore externs need to be emitted. From-SVN: r166125
This commit is contained in:
parent
0930cc0ece
commit
942c9c076a
@ -1,3 +1,26 @@
|
||||
2010-11-01 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR target/46030
|
||||
* config/rs6000/rs6000.c (struct rs6000_stack): Add reload_completed
|
||||
and savres_strategy.
|
||||
(stack_info): New file scope var.
|
||||
(rs6000_init_machine_status): Init stack_info.
|
||||
(SAVRES_INLINE_FPRS, SAVRES_INLINE_GPRS,
|
||||
SAVRES_NOINLINE_GPRS_SAVES_LR, SAVRES_NOINLINE_FPRS_SAVES_LR,
|
||||
SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR): Replace with..
|
||||
(SAVE_INLINE_FPRS, SAVE_INLINE_GPRS, REST_INLINE_FPRS, REST_INLINE_GPRS,
|
||||
SAVE_NOINLINE_GPRS_SAVES_LR, SAVE_NOINLINE_FPRS_SAVES_LR
|
||||
REST_NOINLINE_FPRS_DOESNT_RESTORE_LR): ..this. Update all refs.
|
||||
(rs6000_savres_strategy): Rewrite.
|
||||
(rs6000_stack_info): Use "stack_info" in place of local "info".
|
||||
Return cached stack info when reload_completed unless ENABLE_CHECKING
|
||||
in which case confirm newly calculated stack info matches old info.
|
||||
Delay calculation of lr_save_p, set it for out of line gp save/restore
|
||||
as well as fp. Call rs6000_savres_strategy from here..
|
||||
(rs6000_emit_prologue, rs6000_emit_epilogue): ..rather than here.
|
||||
(rs6000_output_function_prologue): Use info->savres_strategy to
|
||||
determine whether fp save/restore externs need to be emitted.
|
||||
|
||||
2010-10-31 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* tree.h (EXPR_LOC_OR_HERE): New macro.
|
||||
|
@ -73,6 +73,7 @@
|
||||
|
||||
/* Structure used to define the rs6000 stack */
|
||||
typedef struct rs6000_stack {
|
||||
int reload_completed; /* stack info won't change from here on */
|
||||
int first_gp_reg_save; /* first callee saved GP register used */
|
||||
int first_fp_reg_save; /* first callee saved FP register used */
|
||||
int first_altivec_reg_save; /* first callee saved AltiVec register used */
|
||||
@ -109,6 +110,7 @@ typedef struct rs6000_stack {
|
||||
int spe_padding_size;
|
||||
HOST_WIDE_INT total_size; /* total bytes allocated for stack */
|
||||
int spe_64bit_regs_used;
|
||||
int savres_strategy;
|
||||
} rs6000_stack_t;
|
||||
|
||||
/* A C structure for machine-specific, per-function data.
|
||||
@ -994,7 +996,6 @@ static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
|
||||
static bool rs6000_reg_live_or_pic_offset_p (int);
|
||||
static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
|
||||
static tree rs6000_builtin_vectorized_function (tree, tree, tree);
|
||||
static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
|
||||
static void rs6000_restore_saved_cr (rtx, int);
|
||||
static bool rs6000_output_addr_const_extra (FILE *, rtx);
|
||||
static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
|
||||
@ -15161,6 +15162,8 @@ rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
|
||||
return pic_offset_table_rtx;
|
||||
}
|
||||
|
||||
static rs6000_stack_t stack_info;
|
||||
|
||||
/* Function to init struct machine_function.
|
||||
This will be called, via a pointer variable,
|
||||
from push_function_context. */
|
||||
@ -15168,6 +15171,7 @@ rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
|
||||
static struct machine_function *
|
||||
rs6000_init_machine_status (void)
|
||||
{
|
||||
stack_info.reload_completed = 0;
|
||||
return ggc_alloc_cleared_machine_function ();
|
||||
}
|
||||
|
||||
@ -18050,6 +18054,107 @@ is_altivec_return_reg (rtx reg, void *xyes)
|
||||
}
|
||||
|
||||
|
||||
/* Determine the strategy for savings/restoring registers. */
|
||||
|
||||
enum {
|
||||
SAVRES_MULTIPLE = 0x1,
|
||||
SAVE_INLINE_FPRS = 0x2,
|
||||
SAVE_INLINE_GPRS = 0x4,
|
||||
REST_INLINE_FPRS = 0x8,
|
||||
REST_INLINE_GPRS = 0x10,
|
||||
SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
|
||||
SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
|
||||
REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
|
||||
};
|
||||
|
||||
static int
|
||||
rs6000_savres_strategy (rs6000_stack_t *info,
|
||||
bool using_static_chain_p)
|
||||
{
|
||||
int strategy = 0;
|
||||
|
||||
if (TARGET_MULTIPLE
|
||||
&& !TARGET_POWERPC64
|
||||
&& !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
|
||||
&& info->first_gp_reg_save < 31
|
||||
&& no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
|
||||
strategy |= SAVRES_MULTIPLE;
|
||||
|
||||
if (crtl->calls_eh_return
|
||||
|| cfun->machine->ra_need_lr
|
||||
|| info->total_size > 32767)
|
||||
strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
|
||||
| SAVE_INLINE_GPRS | REST_INLINE_GPRS);
|
||||
|
||||
if (info->first_fp_reg_save == 64
|
||||
|| FP_SAVE_INLINE (info->first_fp_reg_save)
|
||||
/* The out-of-line FP routines use double-precision stores;
|
||||
we can't use those routines if we don't have such stores. */
|
||||
|| (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
|
||||
|| !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
|
||||
strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
|
||||
|
||||
if (info->first_gp_reg_save == 32
|
||||
|| GP_SAVE_INLINE (info->first_gp_reg_save)
|
||||
|| !((strategy & SAVRES_MULTIPLE)
|
||||
|| no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
|
||||
strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
|
||||
|
||||
/* Don't bother to try to save things out-of-line if r11 is occupied
|
||||
by the static chain. It would require too much fiddling and the
|
||||
static chain is rarely used anyway. */
|
||||
if (using_static_chain_p)
|
||||
strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
|
||||
|
||||
/* If we are going to use store multiple, then don't even bother
|
||||
with the out-of-line routines, since the store-multiple
|
||||
instruction will always be smaller. */
|
||||
if ((strategy & SAVRES_MULTIPLE))
|
||||
strategy |= SAVE_INLINE_GPRS;
|
||||
|
||||
/* The situation is more complicated with load multiple. We'd
|
||||
prefer to use the out-of-line routines for restores, since the
|
||||
"exit" out-of-line routines can handle the restore of LR and the
|
||||
frame teardown. However if doesn't make sense to use the
|
||||
out-of-line routine if that is the only reason we'd need to save
|
||||
LR, and we can't use the "exit" out-of-line gpr restore if we
|
||||
have saved some fprs; In those cases it is advantageous to use
|
||||
load multiple when available. */
|
||||
if ((strategy & SAVRES_MULTIPLE)
|
||||
&& (!info->lr_save_p
|
||||
|| info->first_fp_reg_save != 64))
|
||||
strategy |= REST_INLINE_GPRS;
|
||||
|
||||
/* We can only use load multiple or the out-of-line routines to
|
||||
restore if we've used store multiple or out-of-line routines
|
||||
in the prologue, i.e. if we've saved all the registers from
|
||||
first_gp_reg_save. Otherwise, we risk loading garbage. */
|
||||
if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
|
||||
strategy |= REST_INLINE_GPRS;
|
||||
|
||||
/* Saving CR interferes with the exit routines used on the SPE, so
|
||||
just punt here. */
|
||||
if (TARGET_SPE_ABI
|
||||
&& info->spe_64bit_regs_used
|
||||
&& info->cr_save_p)
|
||||
strategy |= REST_INLINE_GPRS;
|
||||
|
||||
#ifdef POWERPC_LINUX
|
||||
if (TARGET_64BIT)
|
||||
{
|
||||
if (!(strategy & SAVE_INLINE_FPRS))
|
||||
strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
|
||||
else if (!(strategy & SAVE_INLINE_GPRS)
|
||||
&& info->first_fp_reg_save == 64)
|
||||
strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
|
||||
}
|
||||
#else
|
||||
if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
|
||||
strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
|
||||
#endif
|
||||
return strategy;
|
||||
}
|
||||
|
||||
/* Calculate the stack information for the current function. This is
|
||||
complicated by having two separate calling sequences, the AIX calling
|
||||
sequence and the V.4 calling sequence.
|
||||
@ -18150,15 +18255,26 @@ is_altivec_return_reg (rtx reg, void *xyes)
|
||||
static rs6000_stack_t *
|
||||
rs6000_stack_info (void)
|
||||
{
|
||||
static rs6000_stack_t info;
|
||||
rs6000_stack_t *info_ptr = &info;
|
||||
#ifdef ENABLE_CHECKING
|
||||
static rs6000_stack_t info_save;
|
||||
#endif
|
||||
rs6000_stack_t *info_ptr = &stack_info;
|
||||
int reg_size = TARGET_32BIT ? 4 : 8;
|
||||
int ehrd_size;
|
||||
int save_align;
|
||||
int first_gp;
|
||||
HOST_WIDE_INT non_fixed_size;
|
||||
bool using_static_chain_p;
|
||||
|
||||
memset (&info, 0, sizeof (info));
|
||||
#ifdef ENABLE_CHECKING
|
||||
memcpy (&info_save, &stack_info, sizeof stack_info);
|
||||
#else
|
||||
if (reload_completed && info_ptr->reload_completed)
|
||||
return info_ptr;
|
||||
#endif
|
||||
|
||||
memset (&stack_info, 0, sizeof (stack_info));
|
||||
info_ptr->reload_completed = reload_completed;
|
||||
|
||||
if (TARGET_SPE)
|
||||
{
|
||||
@ -18215,23 +18331,6 @@ rs6000_stack_info (void)
|
||||
info_ptr->calls_p = (! current_function_is_leaf
|
||||
|| cfun->machine->ra_needs_full_frame);
|
||||
|
||||
/* Determine if we need to save the link register. */
|
||||
if ((DEFAULT_ABI == ABI_AIX
|
||||
&& crtl->profile
|
||||
&& !TARGET_PROFILE_KERNEL)
|
||||
#ifdef TARGET_RELOCATABLE
|
||||
|| (TARGET_RELOCATABLE && (get_pool_size () != 0))
|
||||
#endif
|
||||
|| (info_ptr->first_fp_reg_save != 64
|
||||
&& !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
|
||||
|| (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
|
||||
|| info_ptr->calls_p
|
||||
|| rs6000_ra_ever_killed ())
|
||||
{
|
||||
info_ptr->lr_save_p = 1;
|
||||
df_set_regs_ever_live (LR_REGNO, true);
|
||||
}
|
||||
|
||||
/* Determine if we need to save the condition code registers. */
|
||||
if (df_regs_ever_live_p (CR2_REGNO)
|
||||
|| df_regs_ever_live_p (CR3_REGNO)
|
||||
@ -18400,6 +18499,33 @@ rs6000_stack_info (void)
|
||||
info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
|
||||
ABI_STACK_BOUNDARY / BITS_PER_UNIT);
|
||||
|
||||
/* Determine if we need to save the link register. */
|
||||
if (info_ptr->calls_p
|
||||
|| (DEFAULT_ABI == ABI_AIX
|
||||
&& crtl->profile
|
||||
&& !TARGET_PROFILE_KERNEL)
|
||||
|| (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
|
||||
#ifdef TARGET_RELOCATABLE
|
||||
|| (TARGET_RELOCATABLE && (get_pool_size () != 0))
|
||||
#endif
|
||||
|| rs6000_ra_ever_killed ())
|
||||
info_ptr->lr_save_p = 1;
|
||||
|
||||
using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
|
||||
&& df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
|
||||
&& call_used_regs[STATIC_CHAIN_REGNUM]);
|
||||
info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
|
||||
using_static_chain_p);
|
||||
|
||||
if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
|
||||
|| !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
|
||||
|| !(info_ptr->savres_strategy & REST_INLINE_GPRS)
|
||||
|| !(info_ptr->savres_strategy & REST_INLINE_FPRS))
|
||||
info_ptr->lr_save_p = 1;
|
||||
|
||||
if (info_ptr->lr_save_p)
|
||||
df_set_regs_ever_live (LR_REGNO, true);
|
||||
|
||||
/* Determine if we need to allocate any stack frame:
|
||||
|
||||
For AIX we need to push the stack if a frame pointer is needed
|
||||
@ -18451,6 +18577,10 @@ rs6000_stack_info (void)
|
||||
if (! info_ptr->cr_save_p)
|
||||
info_ptr->cr_save_offset = 0;
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
gcc_assert (!(reload_completed && info_save.reload_completed)
|
||||
|| memcmp (&info_save, &stack_info, sizeof stack_info) == 0);
|
||||
#endif
|
||||
return info_ptr;
|
||||
}
|
||||
|
||||
@ -19714,106 +19844,6 @@ rs6000_reg_live_or_pic_offset_p (int reg)
|
||||
|| (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
|
||||
}
|
||||
|
||||
enum {
|
||||
SAVRES_MULTIPLE = 0x1,
|
||||
SAVRES_INLINE_FPRS = 0x2,
|
||||
SAVRES_INLINE_GPRS = 0x4,
|
||||
SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
|
||||
SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
|
||||
SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
|
||||
};
|
||||
|
||||
/* Determine the strategy for savings/restoring registers. */
|
||||
|
||||
static int
|
||||
rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
|
||||
int using_static_chain_p, int sibcall)
|
||||
{
|
||||
bool using_multiple_p;
|
||||
bool common;
|
||||
bool savres_fprs_inline;
|
||||
bool savres_gprs_inline;
|
||||
bool noclobber_global_gprs
|
||||
= no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
|
||||
int strategy;
|
||||
|
||||
using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
|
||||
&& (!TARGET_SPE_ABI
|
||||
|| info->spe_64bit_regs_used == 0)
|
||||
&& info->first_gp_reg_save < 31
|
||||
&& noclobber_global_gprs);
|
||||
/* Don't bother to try to save things out-of-line if r11 is occupied
|
||||
by the static chain. It would require too much fiddling and the
|
||||
static chain is rarely used anyway. */
|
||||
common = (using_static_chain_p
|
||||
|| sibcall
|
||||
|| crtl->calls_eh_return
|
||||
|| !info->lr_save_p
|
||||
|| cfun->machine->ra_need_lr
|
||||
|| info->total_size > 32767);
|
||||
savres_fprs_inline = (common
|
||||
|| info->first_fp_reg_save == 64
|
||||
|| !no_global_regs_above (info->first_fp_reg_save,
|
||||
/*gpr=*/false)
|
||||
/* The out-of-line FP routines use
|
||||
double-precision stores; we can't use those
|
||||
routines if we don't have such stores. */
|
||||
|| (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
|
||||
|| FP_SAVE_INLINE (info->first_fp_reg_save));
|
||||
savres_gprs_inline = (common
|
||||
/* Saving CR interferes with the exit routines
|
||||
used on the SPE, so just punt here. */
|
||||
|| (!savep
|
||||
&& TARGET_SPE_ABI
|
||||
&& info->spe_64bit_regs_used != 0
|
||||
&& info->cr_save_p != 0)
|
||||
|| info->first_gp_reg_save == 32
|
||||
|| !noclobber_global_gprs
|
||||
|| GP_SAVE_INLINE (info->first_gp_reg_save));
|
||||
|
||||
if (savep)
|
||||
/* If we are going to use store multiple, then don't even bother
|
||||
with the out-of-line routines, since the store-multiple instruction
|
||||
will always be smaller. */
|
||||
savres_gprs_inline = savres_gprs_inline || using_multiple_p;
|
||||
else
|
||||
{
|
||||
/* The situation is more complicated with load multiple. We'd
|
||||
prefer to use the out-of-line routines for restores, since the
|
||||
"exit" out-of-line routines can handle the restore of LR and
|
||||
the frame teardown. But we can only use the out-of-line
|
||||
routines if we know that we've used store multiple or
|
||||
out-of-line routines in the prologue, i.e. if we've saved all
|
||||
the registers from first_gp_reg_save. Otherwise, we risk
|
||||
loading garbage from the stack. Furthermore, we can only use
|
||||
the "exit" out-of-line gpr restore if we haven't saved any
|
||||
fprs. */
|
||||
bool saved_all = !savres_gprs_inline || using_multiple_p;
|
||||
|
||||
if (saved_all && info->first_fp_reg_save != 64)
|
||||
/* We can't use the exit routine; use load multiple if it's
|
||||
available. */
|
||||
savres_gprs_inline = savres_gprs_inline || using_multiple_p;
|
||||
}
|
||||
|
||||
strategy = (using_multiple_p
|
||||
| (savres_fprs_inline << 1)
|
||||
| (savres_gprs_inline << 2));
|
||||
#ifdef POWERPC_LINUX
|
||||
if (TARGET_64BIT)
|
||||
{
|
||||
if (!savres_fprs_inline)
|
||||
strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
|
||||
else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
|
||||
strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
|
||||
}
|
||||
#else
|
||||
if (TARGET_AIX && !savres_fprs_inline)
|
||||
strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
|
||||
#endif
|
||||
return strategy;
|
||||
}
|
||||
|
||||
/* Emit function prologue as insns. */
|
||||
|
||||
void
|
||||
@ -19862,12 +19892,10 @@ rs6000_emit_prologue (void)
|
||||
reg_size = 8;
|
||||
}
|
||||
|
||||
strategy = rs6000_savres_strategy (info, /*savep=*/true,
|
||||
/*static_chain_p=*/using_static_chain_p,
|
||||
/*sibcall=*/0);
|
||||
strategy = info->savres_strategy;
|
||||
using_store_multiple = strategy & SAVRES_MULTIPLE;
|
||||
saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
|
||||
saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
|
||||
saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
|
||||
saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
|
||||
|
||||
/* For V.4, update stack before we do any saving and set back pointer. */
|
||||
if (! WORLD_SAVE_P (info)
|
||||
@ -20037,8 +20065,8 @@ rs6000_emit_prologue (void)
|
||||
gen_rtx_REG (Pmode, LR_REGNO));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
|
||||
| SAVRES_NOINLINE_FPRS_SAVES_LR)))
|
||||
if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
|
||||
| SAVE_NOINLINE_FPRS_SAVES_LR)))
|
||||
{
|
||||
addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
|
||||
GEN_INT (info->lr_save_offset + sp_offset));
|
||||
@ -20098,7 +20126,7 @@ rs6000_emit_prologue (void)
|
||||
DFmode,
|
||||
/*savep=*/true, /*gpr=*/false,
|
||||
/*lr=*/(strategy
|
||||
& SAVRES_NOINLINE_FPRS_SAVES_LR)
|
||||
& SAVE_NOINLINE_FPRS_SAVES_LR)
|
||||
!= 0);
|
||||
insn = emit_insn (par);
|
||||
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
|
||||
@ -20225,7 +20253,7 @@ rs6000_emit_prologue (void)
|
||||
reg_mode,
|
||||
/*savep=*/true, /*gpr=*/true,
|
||||
/*lr=*/(strategy
|
||||
& SAVRES_NOINLINE_GPRS_SAVES_LR)
|
||||
& SAVE_NOINLINE_GPRS_SAVES_LR)
|
||||
!= 0);
|
||||
insn = emit_insn (par);
|
||||
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
|
||||
@ -20533,19 +20561,23 @@ rs6000_output_function_prologue (FILE *file,
|
||||
|
||||
/* Write .extern for any function we will call to save and restore
|
||||
fp values. */
|
||||
if (info->first_fp_reg_save < 64
|
||||
&& !FP_SAVE_INLINE (info->first_fp_reg_save))
|
||||
if (info->first_fp_reg_save < 64)
|
||||
{
|
||||
char *name;
|
||||
int regno = info->first_fp_reg_save - 32;
|
||||
|
||||
name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
|
||||
/*gpr=*/false, /*lr=*/false);
|
||||
fprintf (file, "\t.extern %s\n", name);
|
||||
|
||||
name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
|
||||
/*gpr=*/false, /*lr=*/true);
|
||||
fprintf (file, "\t.extern %s\n", name);
|
||||
if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
|
||||
{
|
||||
name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
|
||||
/*gpr=*/false, /*lr=*/false);
|
||||
fprintf (file, "\t.extern %s\n", name);
|
||||
}
|
||||
if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
|
||||
{
|
||||
name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
|
||||
/*gpr=*/false, /*lr=*/true);
|
||||
fprintf (file, "\t.extern %s\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write .extern for AIX common mode routines, if needed. */
|
||||
@ -20691,11 +20723,10 @@ rs6000_emit_epilogue (int sibcall)
|
||||
reg_size = 8;
|
||||
}
|
||||
|
||||
strategy = rs6000_savres_strategy (info, /*savep=*/false,
|
||||
/*static_chain_p=*/0, sibcall);
|
||||
strategy = info->savres_strategy;
|
||||
using_load_multiple = strategy & SAVRES_MULTIPLE;
|
||||
restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
|
||||
restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
|
||||
restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
|
||||
restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
|
||||
using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
|
||||
|| rs6000_cpu == PROCESSOR_PPC603
|
||||
|| rs6000_cpu == PROCESSOR_PPC750
|
||||
@ -20713,7 +20744,7 @@ rs6000_emit_epilogue (int sibcall)
|
||||
&& !frame_pointer_needed));
|
||||
restore_lr = (info->lr_save_p
|
||||
&& (restoring_FPRs_inline
|
||||
|| (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
|
||||
|| (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
|
||||
&& (restoring_GPRs_inline
|
||||
|| info->first_fp_reg_save < 64));
|
||||
|
||||
@ -21352,7 +21383,7 @@ rs6000_emit_epilogue (int sibcall)
|
||||
if (!sibcall)
|
||||
{
|
||||
rtvec p;
|
||||
bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
|
||||
bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
|
||||
if (! restoring_FPRs_inline)
|
||||
p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user