s390-protos.h (s390_arg_frame_offset): Remove.
* config/s390/s390-protos.h (s390_arg_frame_offset): Remove. (s390_return_address_offset): Remove. (s390_can_eliminate): Add prototype. (s390_initial_elimination_offset): Add prototype. * config/s390/s390.h (CAN_ELIMINATE): Call s390_can_eliminate. (INITIAL_ELIMINATION_OFFSET): Call s390_initial_elimination_offset. * config/s390/s390.c (s390_arg_frame_offset): Remove. (s390_return_address_offset): Remove. (s390_can_eliminate, s390_initial_elimination_offset): New functions. (struct machine_function): New member split_branches_pending_p. (s390_mainpool_start): Allow nonexistant pool insn for empty pool. (s390_mainpool_finish): Likewise. Clear base_reg if pool empty. (s390_optimize_prologue): Remove base_used argument. Call s390_update_frame_layout instead of s390_register_info. Handle prologue/epilogue insns that touch only RETURN_REGNUM. (s390_reorg): Remove base_used. Clear split_branches_pending_p. (s390_register_info): Remove base_used and return_addr_used arguments, compute special register usage inline. Return live register data to caller. (s390_frame_info): Remove arguments, do not call s390_register_info. (s390_init_frame_layout): New function. (s390_update_frame_layout): Likewise. (s390_emit_prologue): Call s390_update_frame_layout; some code move to there. Do not emit pool placeholder insn if unnecessary. From-SVN: r88357
This commit is contained in:
parent
13c025c186
commit
9108699053
@ -1,3 +1,30 @@
|
||||
2004-09-30 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* config/s390/s390-protos.h (s390_arg_frame_offset): Remove.
|
||||
(s390_return_address_offset): Remove.
|
||||
(s390_can_eliminate): Add prototype.
|
||||
(s390_initial_elimination_offset): Add prototype.
|
||||
* config/s390/s390.h (CAN_ELIMINATE): Call s390_can_eliminate.
|
||||
(INITIAL_ELIMINATION_OFFSET): Call s390_initial_elimination_offset.
|
||||
* config/s390/s390.c (s390_arg_frame_offset): Remove.
|
||||
(s390_return_address_offset): Remove.
|
||||
(s390_can_eliminate, s390_initial_elimination_offset): New functions.
|
||||
(struct machine_function): New member split_branches_pending_p.
|
||||
(s390_mainpool_start): Allow nonexistant pool insn for empty pool.
|
||||
(s390_mainpool_finish): Likewise. Clear base_reg if pool empty.
|
||||
(s390_optimize_prologue): Remove base_used argument. Call
|
||||
s390_update_frame_layout instead of s390_register_info. Handle
|
||||
prologue/epilogue insns that touch only RETURN_REGNUM.
|
||||
(s390_reorg): Remove base_used. Clear split_branches_pending_p.
|
||||
(s390_register_info): Remove base_used and return_addr_used
|
||||
arguments, compute special register usage inline. Return live
|
||||
register data to caller.
|
||||
(s390_frame_info): Remove arguments, do not call s390_register_info.
|
||||
(s390_init_frame_layout): New function.
|
||||
(s390_update_frame_layout): Likewise.
|
||||
(s390_emit_prologue): Call s390_update_frame_layout; some code
|
||||
move to there. Do not emit pool placeholder insn if unnecessary.
|
||||
|
||||
2004-09-30 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* config/s390/s390.c (legitimate_reload_constant_p): Remove
|
||||
|
@ -23,8 +23,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
extern void optimization_options (int, int);
|
||||
extern void override_options (void);
|
||||
extern HOST_WIDE_INT s390_arg_frame_offset (void);
|
||||
extern HOST_WIDE_INT s390_return_address_offset (void);
|
||||
extern bool s390_can_eliminate (int, int);
|
||||
extern HOST_WIDE_INT s390_initial_elimination_offset (int, int);
|
||||
extern void s390_emit_prologue (void);
|
||||
extern void s390_emit_epilogue (bool);
|
||||
extern void s390_function_profiler (FILE *, int);
|
||||
|
@ -254,6 +254,9 @@ struct machine_function GTY(())
|
||||
/* Literal pool base register. */
|
||||
rtx base_reg;
|
||||
|
||||
/* True if we may need to perform branch splitting. */
|
||||
bool split_branches_pending_p;
|
||||
|
||||
/* Some local-dynamic TLS symbol name. */
|
||||
const char *some_ld_name;
|
||||
};
|
||||
@ -289,11 +292,13 @@ static void find_constant_pool_ref (rtx, rtx *);
|
||||
static void replace_constant_pool_ref (rtx *, rtx, rtx);
|
||||
static rtx find_ltrel_base (rtx);
|
||||
static void replace_ltrel_base (rtx *);
|
||||
static void s390_optimize_prologue (bool);
|
||||
static void s390_optimize_prologue (void);
|
||||
static int find_unused_clobbered_reg (void);
|
||||
static void s390_frame_area (int *, int *);
|
||||
static void s390_register_info (int, int);
|
||||
static void s390_frame_info (int, int);
|
||||
static void s390_register_info (int []);
|
||||
static void s390_frame_info (void);
|
||||
static void s390_init_frame_layout (void);
|
||||
static void s390_update_frame_layout (void);
|
||||
static rtx save_fpr (rtx, int, int);
|
||||
static rtx restore_fpr (rtx, int, int);
|
||||
static rtx save_gprs (rtx, int, int, int);
|
||||
@ -4895,7 +4900,7 @@ s390_mainpool_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
if (!pool->pool_insn)
|
||||
if (!pool->pool_insn && pool->size > 0)
|
||||
abort ();
|
||||
|
||||
if (pool->size >= 4096)
|
||||
@ -4918,13 +4923,17 @@ s390_mainpool_start (void)
|
||||
static void
|
||||
s390_mainpool_finish (struct constant_pool *pool)
|
||||
{
|
||||
rtx base_reg = SET_DEST (PATTERN (pool->pool_insn));
|
||||
rtx base_reg = cfun->machine->base_reg;
|
||||
rtx insn;
|
||||
|
||||
/* If the pool is empty, we're done. */
|
||||
if (pool->size == 0)
|
||||
{
|
||||
remove_insn (pool->pool_insn);
|
||||
/* We don't actually need a base register after all. */
|
||||
cfun->machine->base_reg = NULL_RTX;
|
||||
|
||||
if (pool->pool_insn)
|
||||
remove_insn (pool->pool_insn);
|
||||
s390_free_pool (pool);
|
||||
return;
|
||||
}
|
||||
@ -5437,20 +5446,16 @@ s390_output_pool_entry (rtx exp, enum machine_mode mode, unsigned int align)
|
||||
|
||||
|
||||
/* Rework the prologue/epilogue to avoid saving/restoring
|
||||
registers unnecessarily. BASE_USED specifies whether
|
||||
the literal pool base register needs to be saved. */
|
||||
registers unnecessarily. */
|
||||
|
||||
static void
|
||||
s390_optimize_prologue (bool base_used)
|
||||
s390_optimize_prologue (void)
|
||||
{
|
||||
rtx insn, new_insn, next_insn;
|
||||
|
||||
/* Do a final recompute of the frame-related data. */
|
||||
|
||||
s390_register_info (base_used, cfun_frame_layout.save_return_addr_p);
|
||||
regs_ever_live[BASE_REGNUM] = base_used;
|
||||
regs_ever_live[RETURN_REGNUM] = cfun_frame_layout.save_return_addr_p;
|
||||
regs_ever_live[STACK_POINTER_REGNUM] = cfun_frame_layout.frame_size > 0;
|
||||
s390_update_frame_layout ();
|
||||
|
||||
/* If all special registers are in fact used, there's nothing we
|
||||
can do, so no point in walking the insn list. */
|
||||
@ -5509,10 +5514,13 @@ s390_optimize_prologue (bool base_used)
|
||||
|
||||
if (GET_CODE (PATTERN (insn)) == SET
|
||||
&& GET_CODE (SET_SRC (PATTERN (insn))) == REG
|
||||
&& REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
|
||||
&& (REGNO (SET_SRC (PATTERN (insn))) == BASE_REGNUM
|
||||
|| (!TARGET_CPU_ZARCH
|
||||
&& REGNO (SET_SRC (PATTERN (insn))) == RETURN_REGNUM))
|
||||
&& GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
|
||||
{
|
||||
set = PATTERN (insn);
|
||||
first = REGNO (SET_SRC (set));
|
||||
offset = const0_rtx;
|
||||
base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
|
||||
off = INTVAL (offset);
|
||||
@ -5526,7 +5534,7 @@ s390_optimize_prologue (bool base_used)
|
||||
{
|
||||
new_insn = save_gprs (base,
|
||||
off + (cfun_frame_layout.first_save_gpr
|
||||
- BASE_REGNUM) * UNITS_PER_WORD,
|
||||
- first) * UNITS_PER_WORD,
|
||||
cfun_frame_layout.first_save_gpr,
|
||||
cfun_frame_layout.last_save_gpr);
|
||||
new_insn = emit_insn_before (new_insn, insn);
|
||||
@ -5572,10 +5580,13 @@ s390_optimize_prologue (bool base_used)
|
||||
|
||||
if (GET_CODE (PATTERN (insn)) == SET
|
||||
&& GET_CODE (SET_DEST (PATTERN (insn))) == REG
|
||||
&& REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
|
||||
&& (REGNO (SET_DEST (PATTERN (insn))) == BASE_REGNUM
|
||||
|| (!TARGET_CPU_ZARCH
|
||||
&& REGNO (SET_DEST (PATTERN (insn))) == RETURN_REGNUM))
|
||||
&& GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
|
||||
{
|
||||
set = PATTERN (insn);
|
||||
first = REGNO (SET_DEST (set));
|
||||
offset = const0_rtx;
|
||||
base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
|
||||
off = INTVAL (offset);
|
||||
@ -5589,7 +5600,7 @@ s390_optimize_prologue (bool base_used)
|
||||
{
|
||||
new_insn = restore_gprs (base,
|
||||
off + (cfun_frame_layout.first_restore_gpr
|
||||
- BASE_REGNUM) * UNITS_PER_WORD,
|
||||
- first) * UNITS_PER_WORD,
|
||||
cfun_frame_layout.first_restore_gpr,
|
||||
cfun_frame_layout.last_restore_gpr);
|
||||
new_insn = emit_insn_before (new_insn, insn);
|
||||
@ -5607,7 +5618,6 @@ s390_optimize_prologue (bool base_used)
|
||||
static void
|
||||
s390_reorg (void)
|
||||
{
|
||||
bool base_used = false;
|
||||
bool pool_overflow = false;
|
||||
|
||||
/* Make sure all splits have been performed; splits after
|
||||
@ -5680,19 +5690,17 @@ s390_reorg (void)
|
||||
|
||||
/* If we made it up to here, both conditions are satisfied.
|
||||
Finish up literal pool related changes. */
|
||||
if ((pool_overflow || pool->size > 0)
|
||||
&& REGNO (cfun->machine->base_reg) == BASE_REGNUM)
|
||||
base_used = true;
|
||||
|
||||
if (pool_overflow)
|
||||
s390_chunkify_finish (pool);
|
||||
else
|
||||
s390_mainpool_finish (pool);
|
||||
|
||||
/* We're done splitting branches. */
|
||||
cfun->machine->split_branches_pending_p = false;
|
||||
break;
|
||||
}
|
||||
|
||||
s390_optimize_prologue (base_used);
|
||||
s390_optimize_prologue ();
|
||||
}
|
||||
|
||||
|
||||
@ -5806,14 +5814,12 @@ s390_frame_area (int *area_bottom, int *area_top)
|
||||
*area_top = t;
|
||||
}
|
||||
|
||||
/* Fill cfun->machine with info about register usage of current
|
||||
function. BASE_USED and RETURN_ADDR_USED specify whether we assume the
|
||||
base and return address register will need to be saved. */
|
||||
/* Fill cfun->machine with info about register usage of current function.
|
||||
Return in LIVE_REGS which GPRs are currently considered live. */
|
||||
|
||||
static void
|
||||
s390_register_info (int base_used, int return_addr_used)
|
||||
s390_register_info (int live_regs[])
|
||||
{
|
||||
int live_regs[16];
|
||||
int i, j;
|
||||
|
||||
/* fprs 8 - 15 are call saved for 64 Bit ABI. */
|
||||
@ -5837,17 +5843,24 @@ s390_register_info (int base_used, int return_addr_used)
|
||||
live_regs[i] = regs_ever_live[i] && !global_regs[i];
|
||||
|
||||
if (flag_pic)
|
||||
live_regs[PIC_OFFSET_TABLE_REGNUM] =
|
||||
regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
|
||||
live_regs[PIC_OFFSET_TABLE_REGNUM]
|
||||
= regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
|
||||
|
||||
live_regs[BASE_REGNUM] = base_used;
|
||||
live_regs[RETURN_REGNUM] = return_addr_used;
|
||||
live_regs[STACK_POINTER_REGNUM] = (!current_function_is_leaf
|
||||
|| TARGET_TPF_PROFILING
|
||||
|| cfun_save_high_fprs_p
|
||||
|| get_frame_size () > 0
|
||||
|| current_function_calls_alloca
|
||||
|| current_function_stdarg);
|
||||
live_regs[BASE_REGNUM]
|
||||
= cfun->machine->base_reg
|
||||
&& REGNO (cfun->machine->base_reg) == BASE_REGNUM;
|
||||
|
||||
live_regs[RETURN_REGNUM]
|
||||
= cfun->machine->split_branches_pending_p
|
||||
|| cfun_frame_layout.save_return_addr_p;
|
||||
|
||||
live_regs[STACK_POINTER_REGNUM]
|
||||
= !current_function_is_leaf
|
||||
|| TARGET_TPF_PROFILING
|
||||
|| cfun_save_high_fprs_p
|
||||
|| get_frame_size () > 0
|
||||
|| current_function_calls_alloca
|
||||
|| current_function_stdarg;
|
||||
|
||||
for (i = 6; i < 16; i++)
|
||||
if (live_regs[i])
|
||||
@ -5895,19 +5908,14 @@ s390_register_info (int base_used, int return_addr_used)
|
||||
cfun_set_fpr_bit (i);
|
||||
}
|
||||
|
||||
/* Fill cfun->machine with info about frame of current
|
||||
function. BASE_USED and RETURN_ADDR_USED specify whether we assume the
|
||||
base and return address register will need to be saved. */
|
||||
/* Fill cfun->machine with info about frame of current function. */
|
||||
|
||||
static void
|
||||
s390_frame_info (int base_used, int return_addr_used)
|
||||
s390_frame_info (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
cfun_frame_layout.frame_size = get_frame_size ();
|
||||
|
||||
s390_register_info (base_used, return_addr_used);
|
||||
|
||||
if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
|
||||
fatal_error ("Total size of local variables exceeds architecture limit.");
|
||||
|
||||
@ -6011,37 +6019,136 @@ s390_frame_info (int base_used, int return_addr_used)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return offset between argument pointer and frame pointer
|
||||
initially after prologue. */
|
||||
/* Generate frame layout. Fills in register and frame data for the current
|
||||
function in cfun->machine. This routine can be called multiple times;
|
||||
it will re-do the complete frame layout every time. */
|
||||
|
||||
HOST_WIDE_INT
|
||||
s390_arg_frame_offset (void)
|
||||
static void
|
||||
s390_init_frame_layout (void)
|
||||
{
|
||||
/* See the comment in s390_emit_prologue about the assumptions we make
|
||||
whether or not the base and return address register need to be saved. */
|
||||
int return_addr_used = !current_function_is_leaf
|
||||
|| TARGET_TPF_PROFILING
|
||||
|| regs_ever_live[RETURN_REGNUM]
|
||||
|| cfun_frame_layout.save_return_addr_p;
|
||||
HOST_WIDE_INT frame_size;
|
||||
int base_used;
|
||||
int live_regs[16];
|
||||
|
||||
s390_frame_info (1, !TARGET_CPU_ZARCH || return_addr_used);
|
||||
/* If return address register is explicitly used, we need to save it. */
|
||||
if (regs_ever_live[RETURN_REGNUM]
|
||||
|| !current_function_is_leaf
|
||||
|| TARGET_TPF_PROFILING
|
||||
|| current_function_stdarg
|
||||
|| current_function_calls_eh_return)
|
||||
cfun_frame_layout.save_return_addr_p = true;
|
||||
|
||||
return cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
|
||||
/* On S/390 machines, we may need to perform branch splitting, which
|
||||
will require both base and return address register. We have no
|
||||
choice but to assume we're going to need them until right at the
|
||||
end of the machine dependent reorg phase. */
|
||||
if (!TARGET_CPU_ZARCH)
|
||||
cfun->machine->split_branches_pending_p = true;
|
||||
|
||||
do
|
||||
{
|
||||
frame_size = cfun_frame_layout.frame_size;
|
||||
|
||||
/* Try to predict whether we'll need the base register. */
|
||||
base_used = cfun->machine->split_branches_pending_p
|
||||
|| current_function_uses_const_pool
|
||||
|| (!DISP_IN_RANGE (-frame_size)
|
||||
&& !CONST_OK_FOR_CONSTRAINT_P (-frame_size, 'K', "K"));
|
||||
|
||||
/* Decide which register to use as literal pool base. In small
|
||||
leaf functions, try to use an unused call-clobbered register
|
||||
as base register to avoid save/restore overhead. */
|
||||
if (!base_used)
|
||||
cfun->machine->base_reg = NULL_RTX;
|
||||
else if (current_function_is_leaf && !regs_ever_live[5])
|
||||
cfun->machine->base_reg = gen_rtx_REG (Pmode, 5);
|
||||
else
|
||||
cfun->machine->base_reg = gen_rtx_REG (Pmode, BASE_REGNUM);
|
||||
|
||||
s390_register_info (live_regs);
|
||||
s390_frame_info ();
|
||||
}
|
||||
while (frame_size != cfun_frame_layout.frame_size);
|
||||
}
|
||||
|
||||
/* Return offset between return address pointer (location of r14
|
||||
on the stack) and frame pointer initially after prologue. */
|
||||
/* Update frame layout. Recompute actual register save data based on
|
||||
current info and update regs_ever_live for the special registers.
|
||||
May be called multiple times, but may never cause *more* registers
|
||||
to be saved than s390_init_frame_layout allocated room for. */
|
||||
|
||||
static void
|
||||
s390_update_frame_layout (void)
|
||||
{
|
||||
int live_regs[16];
|
||||
|
||||
s390_register_info (live_regs);
|
||||
|
||||
regs_ever_live[BASE_REGNUM] = live_regs[BASE_REGNUM];
|
||||
regs_ever_live[RETURN_REGNUM] = live_regs[RETURN_REGNUM];
|
||||
regs_ever_live[STACK_POINTER_REGNUM] = live_regs[STACK_POINTER_REGNUM];
|
||||
|
||||
if (cfun->machine->base_reg)
|
||||
regs_ever_live[REGNO (cfun->machine->base_reg)] = 1;
|
||||
}
|
||||
|
||||
/* Return true if register FROM can be eliminated via register TO. */
|
||||
|
||||
bool
|
||||
s390_can_eliminate (int from, int to)
|
||||
{
|
||||
gcc_assert (to == STACK_POINTER_REGNUM
|
||||
|| to == HARD_FRAME_POINTER_REGNUM);
|
||||
|
||||
gcc_assert (from == FRAME_POINTER_REGNUM
|
||||
|| from == ARG_POINTER_REGNUM
|
||||
|| from == RETURN_ADDRESS_POINTER_REGNUM);
|
||||
|
||||
/* Make sure we actually saved the return address. */
|
||||
if (from == RETURN_ADDRESS_POINTER_REGNUM)
|
||||
if (!current_function_calls_eh_return
|
||||
&& !current_function_stdarg
|
||||
&& !cfun_frame_layout.save_return_addr_p)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return offset between register FROM and TO initially after prolog. */
|
||||
|
||||
HOST_WIDE_INT
|
||||
s390_return_address_offset (void)
|
||||
s390_initial_elimination_offset (int from, int to)
|
||||
{
|
||||
s390_frame_info (1, 1);
|
||||
HOST_WIDE_INT offset;
|
||||
int index;
|
||||
|
||||
if (cfun_frame_layout.last_save_gpr < RETURN_REGNUM)
|
||||
abort ();
|
||||
/* ??? Why are we called for non-eliminable pairs? */
|
||||
if (!s390_can_eliminate (from, to))
|
||||
return 0;
|
||||
|
||||
return (cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset
|
||||
+ (RETURN_REGNUM - cfun_frame_layout.first_save_gpr) * UNITS_PER_WORD);
|
||||
switch (from)
|
||||
{
|
||||
case FRAME_POINTER_REGNUM:
|
||||
offset = 0;
|
||||
break;
|
||||
|
||||
case ARG_POINTER_REGNUM:
|
||||
s390_init_frame_layout ();
|
||||
offset = cfun_frame_layout.frame_size + STACK_POINTER_OFFSET;
|
||||
break;
|
||||
|
||||
case RETURN_ADDRESS_POINTER_REGNUM:
|
||||
s390_init_frame_layout ();
|
||||
index = RETURN_REGNUM - cfun_frame_layout.first_save_gpr;
|
||||
gcc_assert (index >= 0);
|
||||
offset = cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset;
|
||||
offset += index * UNITS_PER_WORD;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* Emit insn to save fpr REGNUM at offset OFFSET relative
|
||||
@ -6230,41 +6337,9 @@ s390_emit_prologue (void)
|
||||
int offset;
|
||||
int next_fpr = 0;
|
||||
|
||||
/* At this point, we decide whether we'll need to save/restore the
|
||||
return address register. This decision is final on zSeries machines;
|
||||
on S/390 it can still be overridden in s390_split_branches. */
|
||||
/* Complete frame layout. */
|
||||
|
||||
if (!current_function_is_leaf
|
||||
|| TARGET_TPF_PROFILING
|
||||
|| regs_ever_live[RETURN_REGNUM])
|
||||
cfun_frame_layout.save_return_addr_p = 1;
|
||||
|
||||
/* Decide which register to use as literal pool base. In small leaf
|
||||
functions, try to use an unused call-clobbered register as base
|
||||
register to avoid save/restore overhead. */
|
||||
|
||||
if (current_function_is_leaf && !regs_ever_live[5])
|
||||
cfun->machine->base_reg = gen_rtx_REG (Pmode, 5);
|
||||
else
|
||||
cfun->machine->base_reg = gen_rtx_REG (Pmode, BASE_REGNUM);
|
||||
|
||||
regs_ever_live[REGNO (cfun->machine->base_reg)] = 1;
|
||||
|
||||
/* Compute frame info. Note that at this point, we assume the base
|
||||
register and -on S/390- the return register always need to be saved.
|
||||
This is done because the usage of these registers might change even
|
||||
after the prologue was emitted. If it turns out later that we really
|
||||
don't need them, the prologue/epilogue code is modified again. */
|
||||
|
||||
s390_frame_info (1, !TARGET_CPU_ZARCH
|
||||
|| cfun_frame_layout.save_return_addr_p);
|
||||
|
||||
/* We need to update regs_ever_live to avoid data-flow problems. */
|
||||
|
||||
regs_ever_live[BASE_REGNUM] = 1;
|
||||
regs_ever_live[RETURN_REGNUM] = (!TARGET_CPU_ZARCH
|
||||
|| cfun_frame_layout.save_return_addr_p);
|
||||
regs_ever_live[STACK_POINTER_REGNUM] = cfun_frame_layout.frame_size > 0;
|
||||
s390_update_frame_layout ();
|
||||
|
||||
/* Annotate all constant pool references to let the scheduler know
|
||||
they implicitly use the base register. */
|
||||
@ -6297,7 +6372,8 @@ s390_emit_prologue (void)
|
||||
|
||||
/* Dummy insn to mark literal pool slot. */
|
||||
|
||||
emit_insn (gen_main_pool (cfun->machine->base_reg));
|
||||
if (cfun->machine->base_reg)
|
||||
emit_insn (gen_main_pool (cfun->machine->base_reg));
|
||||
|
||||
offset = cfun_frame_layout.f0_offset;
|
||||
|
||||
|
@ -652,26 +652,11 @@ extern int current_function_outgoing_args_size;
|
||||
{ RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
|
||||
{ RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
|
||||
|
||||
#define CAN_ELIMINATE(FROM, TO) (1)
|
||||
#define CAN_ELIMINATE(FROM, TO) \
|
||||
s390_can_eliminate ((FROM), (TO))
|
||||
|
||||
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
|
||||
{ if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
|
||||
{ (OFFSET) = 0; } \
|
||||
else if ((FROM) == FRAME_POINTER_REGNUM \
|
||||
&& (TO) == HARD_FRAME_POINTER_REGNUM) \
|
||||
{ (OFFSET) = 0; } \
|
||||
else if ((FROM) == ARG_POINTER_REGNUM \
|
||||
&& (TO) == HARD_FRAME_POINTER_REGNUM) \
|
||||
{ (OFFSET) = s390_arg_frame_offset (); } \
|
||||
else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
|
||||
{ (OFFSET) = s390_arg_frame_offset (); } \
|
||||
else if ((FROM) == RETURN_ADDRESS_POINTER_REGNUM \
|
||||
&& ((TO) == STACK_POINTER_REGNUM \
|
||||
|| (TO) == HARD_FRAME_POINTER_REGNUM)) \
|
||||
{ (OFFSET) = s390_return_address_offset (); } \
|
||||
else \
|
||||
abort(); \
|
||||
}
|
||||
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
|
||||
(OFFSET) = s390_initial_elimination_offset ((FROM), (TO))
|
||||
|
||||
|
||||
/* Stack arguments. */
|
||||
|
Loading…
Reference in New Issue
Block a user