m68k.h (EH_RETURN_DATA_REGNO): Define.
* config/m68k/m68k.h (EH_RETURN_DATA_REGNO): Define. (EH_RETURN_STACKADJ_RTX): Define. (EH_RETURN_HANDLER_RTX): Define. (ASM_PREFERRED_EH_DATA_FORMAT): Define. * config/m68k/m68k.c (m68k_save_reg): New function. Handle eh registers and don't save fixed registers. (m68k_output_function_prologue): Use it. (use_return_insn): Likewise. (m68k_output_function_epilogue): Likewise. From-SVN: r59780
This commit is contained in:
parent
b3eed2db61
commit
2cff4a6e82
3 changed files with 89 additions and 46 deletions
|
@ -1,3 +1,15 @@
|
|||
2002-12-03 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* config/m68k/m68k.h (EH_RETURN_DATA_REGNO): Define.
|
||||
(EH_RETURN_STACKADJ_RTX): Define.
|
||||
(EH_RETURN_HANDLER_RTX): Define.
|
||||
(ASM_PREFERRED_EH_DATA_FORMAT): Define.
|
||||
* config/m68k/m68k.c (m68k_save_reg): New function. Handle eh
|
||||
registers and don't save fixed registers.
|
||||
(m68k_output_function_prologue): Use it.
|
||||
(use_return_insn): Likewise.
|
||||
(m68k_output_function_epilogue): Likewise.
|
||||
|
||||
2002-12-03 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* config/h8300/h8300.c (single_one_operand): Fix a warning.
|
||||
|
|
|
@ -67,6 +67,7 @@ static void m68k_svr3_asm_out_constructor PARAMS ((rtx, int));
|
|||
#endif
|
||||
static void m68k_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
|
||||
HOST_WIDE_INT, tree));
|
||||
static int m68k_save_reg PARAMS ((unsigned int));
|
||||
|
||||
|
||||
/* Alignment to use for loops and jumps */
|
||||
|
@ -207,6 +208,34 @@ override_options ()
|
|||
real_format_for_mode[XFmode - QFmode] = &ieee_extended_motorola_format;
|
||||
}
|
||||
|
||||
/* Return 1 if we need to save REGNO. */
|
||||
static int
|
||||
m68k_save_reg (regno)
|
||||
unsigned int regno;
|
||||
{
|
||||
if (flag_pic && current_function_uses_pic_offset_table
|
||||
&& regno == PIC_OFFSET_TABLE_REGNUM)
|
||||
return 1;
|
||||
|
||||
if (current_function_calls_eh_return)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
unsigned int test = EH_RETURN_DATA_REGNO (i);
|
||||
if (test == INVALID_REGNUM)
|
||||
break;
|
||||
if (test == regno)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (regs_ever_live[regno]
|
||||
&& !call_used_regs[regno]
|
||||
&& !fixed_regs[regno]
|
||||
&& !(regno == FRAME_POINTER_REGNUM && frame_pointer_needed));
|
||||
}
|
||||
|
||||
/* This function generates the assembly code for function entry.
|
||||
STREAM is a stdio stream to output the code to.
|
||||
SIZE is an int: how many units of temporary storage to allocate.
|
||||
|
@ -251,13 +280,13 @@ m68k_output_function_prologue (stream, size)
|
|||
{
|
||||
/* Adding negative number is faster on the 68040. */
|
||||
if (fsize + 4 < 0x8000)
|
||||
fprintf (stream, "\tadd.w #%d,sp\n", - (fsize + 4));
|
||||
fprintf (stream, "\tadd.w $%d,sp\n", - (fsize + 4));
|
||||
else
|
||||
fprintf (stream, "\tadd.l #%d,sp\n", - (fsize + 4));
|
||||
fprintf (stream, "\tadd.l $%d,sp\n", - (fsize + 4));
|
||||
}
|
||||
|
||||
for (regno = 16; regno < 24; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
mask |= 1 << (regno - 16);
|
||||
|
||||
if ((mask & 0xff) != 0)
|
||||
|
@ -265,10 +294,8 @@ m68k_output_function_prologue (stream, size)
|
|||
|
||||
mask = 0;
|
||||
for (regno = 0; regno < 16; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
mask |= 1 << (15 - regno);
|
||||
if (frame_pointer_needed)
|
||||
mask &= ~ (1 << (15-FRAME_POINTER_REGNUM));
|
||||
|
||||
if (exact_log2 (mask) >= 0)
|
||||
fprintf (stream, "\tmovel %s,-(sp)\n", reg_names[15 - exact_log2 (mask)]);
|
||||
|
@ -441,7 +468,7 @@ m68k_output_function_prologue (stream, size)
|
|||
}
|
||||
#ifdef SUPPORT_SUN_FPA
|
||||
for (regno = 24; regno < 56; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
{
|
||||
#ifdef MOTOROLA
|
||||
asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
|
||||
|
@ -467,7 +494,7 @@ m68k_output_function_prologue (stream, size)
|
|||
if (TARGET_68881)
|
||||
{
|
||||
for (regno = 16; regno < 24; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
{
|
||||
mask |= 1 << (regno - 16);
|
||||
num_saved_regs++;
|
||||
|
@ -500,21 +527,11 @@ m68k_output_function_prologue (stream, size)
|
|||
num_saved_regs = 0;
|
||||
}
|
||||
for (regno = 0; regno < 16; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
{
|
||||
mask |= 1 << (15 - regno);
|
||||
num_saved_regs++;
|
||||
}
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM));
|
||||
num_saved_regs--;
|
||||
}
|
||||
if (flag_pic && current_function_uses_pic_offset_table)
|
||||
{
|
||||
mask |= 1 << (15 - PIC_OFFSET_TABLE_REGNUM);
|
||||
num_saved_regs++;
|
||||
}
|
||||
|
||||
#if NEED_PROBE
|
||||
#ifdef MOTOROLA
|
||||
|
@ -656,16 +673,10 @@ use_return_insn ()
|
|||
if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
|
||||
return 0;
|
||||
|
||||
/* Copied from output_function_epilogue (). We should probably create a
|
||||
separate layout routine to perform the common work. */
|
||||
|
||||
for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
||||
if (m68k_save_reg (regno))
|
||||
return 0;
|
||||
|
||||
if (flag_pic && current_function_uses_pic_offset_table)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -693,7 +704,7 @@ m68k_output_function_epilogue (stream, size)
|
|||
|
||||
nregs = 0; fmask = 0; fpoffset = 0;
|
||||
for (regno = 16; regno < 24; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
{
|
||||
nregs++;
|
||||
fmask |= 1 << (23 - regno);
|
||||
|
@ -701,11 +712,9 @@ m68k_output_function_epilogue (stream, size)
|
|||
|
||||
foffset = fpoffset + nregs * 12;
|
||||
nregs = 0; mask = 0;
|
||||
if (frame_pointer_needed)
|
||||
regs_ever_live[FRAME_POINTER_REGNUM] = 0;
|
||||
|
||||
for (regno = 0; regno < 16; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
{
|
||||
nregs++;
|
||||
mask |= 1 << regno;
|
||||
|
@ -758,7 +767,7 @@ m68k_output_function_epilogue (stream, size)
|
|||
|
||||
if (fpoffset != 0)
|
||||
for (regno = 55; regno >= 24; regno--)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
{
|
||||
if (big)
|
||||
fprintf(stream, "\tfpmoved -%d(a6,a0.l), %s\n",
|
||||
|
@ -777,11 +786,14 @@ m68k_output_function_epilogue (stream, size)
|
|||
else if (fsize)
|
||||
{
|
||||
if (fsize + 4 < 0x8000)
|
||||
fprintf (stream, "\tadd.w #%d,sp\n", fsize + 4);
|
||||
fprintf (stream, "\tadd.w $%d,sp\n", fsize + 4);
|
||||
else
|
||||
fprintf (stream, "\tadd.l #%d,sp\n", fsize + 4);
|
||||
fprintf (stream, "\tadd.l $%d,sp\n", fsize + 4);
|
||||
}
|
||||
|
||||
if (current_function_calls_eh_return)
|
||||
fprintf (stream, "\tadd.l a0,sp\n");
|
||||
|
||||
if (current_function_pops_args)
|
||||
fprintf (stream, "\trtd $%d\n", current_function_pops_args);
|
||||
else
|
||||
|
@ -821,7 +833,7 @@ m68k_output_function_epilogue (stream, size)
|
|||
nregs = 0; fmask = 0; fpoffset = 0;
|
||||
#ifdef SUPPORT_SUN_FPA
|
||||
for (regno = 24 ; regno < 56 ; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
nregs++;
|
||||
fpoffset = nregs * 8;
|
||||
#endif
|
||||
|
@ -829,7 +841,7 @@ m68k_output_function_epilogue (stream, size)
|
|||
if (TARGET_68881)
|
||||
{
|
||||
for (regno = 16; regno < 24; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
{
|
||||
nregs++;
|
||||
fmask |= 1 << (23 - regno);
|
||||
|
@ -837,19 +849,12 @@ m68k_output_function_epilogue (stream, size)
|
|||
}
|
||||
foffset = fpoffset + nregs * 12;
|
||||
nregs = 0; mask = 0;
|
||||
if (frame_pointer_needed)
|
||||
regs_ever_live[FRAME_POINTER_REGNUM] = 0;
|
||||
for (regno = 0; regno < 16; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
{
|
||||
nregs++;
|
||||
mask |= 1 << regno;
|
||||
}
|
||||
if (flag_pic && current_function_uses_pic_offset_table)
|
||||
{
|
||||
nregs++;
|
||||
mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
|
||||
}
|
||||
offset = foffset + nregs * 4;
|
||||
/* FIXME : leaf_function_p below is too strong.
|
||||
What we really need to know there is if there could be pending
|
||||
|
@ -995,7 +1000,7 @@ m68k_output_function_epilogue (stream, size)
|
|||
}
|
||||
if (fpoffset != 0)
|
||||
for (regno = 55; regno >= 24; regno--)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
if (m68k_save_reg (regno))
|
||||
{
|
||||
if (big)
|
||||
{
|
||||
|
@ -1105,6 +1110,14 @@ m68k_output_function_epilogue (stream, size)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
if (current_function_calls_eh_return)
|
||||
{
|
||||
#ifdef MOTOROLA
|
||||
asm_fprintf (stream, "\tadd.l %Ra0,%Rsp\n");
|
||||
#else
|
||||
asm_fprintf (stream, "\taddl %Ra0,%Rsp\n");
|
||||
#endif
|
||||
}
|
||||
if (current_function_pops_args)
|
||||
asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
|
||||
else
|
||||
|
|
|
@ -1665,6 +1665,8 @@ __transfer_from_trampoline () \
|
|||
|
||||
#define DATA_SECTION_ASM_OP "\t.data"
|
||||
|
||||
#define GLOBAL_ASM_OP "\t.globl\t"
|
||||
|
||||
/* Here are four prefixes that are used by asm_fprintf to
|
||||
facilitate customization for alternate assembler syntaxes.
|
||||
Machines with no likelihood of an alternate syntax need not
|
||||
|
@ -1732,7 +1734,23 @@ __transfer_from_trampoline () \
|
|||
/* Before the prologue, the top of the frame is at 4(%sp). */
|
||||
#define INCOMING_FRAME_SP_OFFSET 4
|
||||
|
||||
#define GLOBAL_ASM_OP "\t.globl\t"
|
||||
/* Describe how we implement __builtin_eh_return. */
|
||||
#define EH_RETURN_DATA_REGNO(N) \
|
||||
((N) < 2 ? (N) : INVALID_REGNUM)
|
||||
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 8)
|
||||
#define EH_RETURN_HANDLER_RTX \
|
||||
gen_rtx_MEM (Pmode, \
|
||||
gen_rtx_PLUS (Pmode, arg_pointer_rtx, \
|
||||
plus_constant (EH_RETURN_STACKADJ_RTX, \
|
||||
UNITS_PER_WORD)))
|
||||
|
||||
/* Select a format to encode pointers in exception handling data. CODE
|
||||
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
|
||||
true if the symbol may be affected by dynamic relocations. */
|
||||
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
|
||||
(flag_pic \
|
||||
? ((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4 \
|
||||
: DW_EH_PE_absptr)
|
||||
|
||||
/* This is how to output a reference to a user-level label named NAME.
|
||||
`assemble_name' uses this. */
|
||||
|
|
Loading…
Add table
Reference in a new issue