Commit 2cff4a6e by Andreas Schwab Committed by Andreas Schwab

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
parent b3eed2db
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> 2002-12-03 Kazu Hirata <kazu@cs.umass.edu>
* config/h8300/h8300.c (single_one_operand): Fix a warning. * config/h8300/h8300.c (single_one_operand): Fix a warning.
......
...@@ -67,6 +67,7 @@ static void m68k_svr3_asm_out_constructor PARAMS ((rtx, int)); ...@@ -67,6 +67,7 @@ static void m68k_svr3_asm_out_constructor PARAMS ((rtx, int));
#endif #endif
static void m68k_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, static void m68k_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree)); HOST_WIDE_INT, tree));
static int m68k_save_reg PARAMS ((unsigned int));
/* Alignment to use for loops and jumps */ /* Alignment to use for loops and jumps */
...@@ -207,6 +208,34 @@ override_options () ...@@ -207,6 +208,34 @@ override_options ()
real_format_for_mode[XFmode - QFmode] = &ieee_extended_motorola_format; 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. /* This function generates the assembly code for function entry.
STREAM is a stdio stream to output the code to. STREAM is a stdio stream to output the code to.
SIZE is an int: how many units of temporary storage to allocate. SIZE is an int: how many units of temporary storage to allocate.
...@@ -251,13 +280,13 @@ m68k_output_function_prologue (stream, size) ...@@ -251,13 +280,13 @@ m68k_output_function_prologue (stream, size)
{ {
/* Adding negative number is faster on the 68040. */ /* Adding negative number is faster on the 68040. */
if (fsize + 4 < 0x8000) if (fsize + 4 < 0x8000)
fprintf (stream, "\tadd.w #%d,sp\n", - (fsize + 4)); fprintf (stream, "\tadd.w $%d,sp\n", - (fsize + 4));
else 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++) for (regno = 16; regno < 24; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
mask |= 1 << (regno - 16); mask |= 1 << (regno - 16);
if ((mask & 0xff) != 0) if ((mask & 0xff) != 0)
...@@ -265,10 +294,8 @@ m68k_output_function_prologue (stream, size) ...@@ -265,10 +294,8 @@ m68k_output_function_prologue (stream, size)
mask = 0; mask = 0;
for (regno = 0; regno < 16; regno++) for (regno = 0; regno < 16; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
mask |= 1 << (15 - regno); mask |= 1 << (15 - regno);
if (frame_pointer_needed)
mask &= ~ (1 << (15-FRAME_POINTER_REGNUM));
if (exact_log2 (mask) >= 0) if (exact_log2 (mask) >= 0)
fprintf (stream, "\tmovel %s,-(sp)\n", reg_names[15 - exact_log2 (mask)]); fprintf (stream, "\tmovel %s,-(sp)\n", reg_names[15 - exact_log2 (mask)]);
...@@ -441,7 +468,7 @@ m68k_output_function_prologue (stream, size) ...@@ -441,7 +468,7 @@ m68k_output_function_prologue (stream, size)
} }
#ifdef SUPPORT_SUN_FPA #ifdef SUPPORT_SUN_FPA
for (regno = 24; regno < 56; regno++) for (regno = 24; regno < 56; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
{ {
#ifdef MOTOROLA #ifdef MOTOROLA
asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n", asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
...@@ -467,7 +494,7 @@ m68k_output_function_prologue (stream, size) ...@@ -467,7 +494,7 @@ m68k_output_function_prologue (stream, size)
if (TARGET_68881) if (TARGET_68881)
{ {
for (regno = 16; regno < 24; regno++) for (regno = 16; regno < 24; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
{ {
mask |= 1 << (regno - 16); mask |= 1 << (regno - 16);
num_saved_regs++; num_saved_regs++;
...@@ -500,21 +527,11 @@ m68k_output_function_prologue (stream, size) ...@@ -500,21 +527,11 @@ m68k_output_function_prologue (stream, size)
num_saved_regs = 0; num_saved_regs = 0;
} }
for (regno = 0; regno < 16; regno++) for (regno = 0; regno < 16; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
{ {
mask |= 1 << (15 - regno); mask |= 1 << (15 - regno);
num_saved_regs++; 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 #if NEED_PROBE
#ifdef MOTOROLA #ifdef MOTOROLA
...@@ -656,16 +673,10 @@ use_return_insn () ...@@ -656,16 +673,10 @@ use_return_insn ()
if (!reload_completed || frame_pointer_needed || get_frame_size () != 0) if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
return 0; return 0;
/* Copied from output_function_epilogue (). We should probably create a for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
separate layout routine to perform the common work. */ if (m68k_save_reg (regno))
for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno])
return 0; return 0;
if (flag_pic && current_function_uses_pic_offset_table)
return 0;
return 1; return 1;
} }
...@@ -693,7 +704,7 @@ m68k_output_function_epilogue (stream, size) ...@@ -693,7 +704,7 @@ m68k_output_function_epilogue (stream, size)
nregs = 0; fmask = 0; fpoffset = 0; nregs = 0; fmask = 0; fpoffset = 0;
for (regno = 16; regno < 24; regno++) for (regno = 16; regno < 24; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
{ {
nregs++; nregs++;
fmask |= 1 << (23 - regno); fmask |= 1 << (23 - regno);
...@@ -701,11 +712,9 @@ m68k_output_function_epilogue (stream, size) ...@@ -701,11 +712,9 @@ m68k_output_function_epilogue (stream, size)
foffset = fpoffset + nregs * 12; foffset = fpoffset + nregs * 12;
nregs = 0; mask = 0; nregs = 0; mask = 0;
if (frame_pointer_needed)
regs_ever_live[FRAME_POINTER_REGNUM] = 0;
for (regno = 0; regno < 16; regno++) for (regno = 0; regno < 16; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
{ {
nregs++; nregs++;
mask |= 1 << regno; mask |= 1 << regno;
...@@ -758,7 +767,7 @@ m68k_output_function_epilogue (stream, size) ...@@ -758,7 +767,7 @@ m68k_output_function_epilogue (stream, size)
if (fpoffset != 0) if (fpoffset != 0)
for (regno = 55; regno >= 24; regno--) for (regno = 55; regno >= 24; regno--)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
{ {
if (big) if (big)
fprintf(stream, "\tfpmoved -%d(a6,a0.l), %s\n", fprintf(stream, "\tfpmoved -%d(a6,a0.l), %s\n",
...@@ -777,11 +786,14 @@ m68k_output_function_epilogue (stream, size) ...@@ -777,11 +786,14 @@ m68k_output_function_epilogue (stream, size)
else if (fsize) else if (fsize)
{ {
if (fsize + 4 < 0x8000) if (fsize + 4 < 0x8000)
fprintf (stream, "\tadd.w #%d,sp\n", fsize + 4); fprintf (stream, "\tadd.w $%d,sp\n", fsize + 4);
else 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) if (current_function_pops_args)
fprintf (stream, "\trtd $%d\n", current_function_pops_args); fprintf (stream, "\trtd $%d\n", current_function_pops_args);
else else
...@@ -821,7 +833,7 @@ m68k_output_function_epilogue (stream, size) ...@@ -821,7 +833,7 @@ m68k_output_function_epilogue (stream, size)
nregs = 0; fmask = 0; fpoffset = 0; nregs = 0; fmask = 0; fpoffset = 0;
#ifdef SUPPORT_SUN_FPA #ifdef SUPPORT_SUN_FPA
for (regno = 24 ; regno < 56 ; regno++) for (regno = 24 ; regno < 56 ; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
nregs++; nregs++;
fpoffset = nregs * 8; fpoffset = nregs * 8;
#endif #endif
...@@ -829,7 +841,7 @@ m68k_output_function_epilogue (stream, size) ...@@ -829,7 +841,7 @@ m68k_output_function_epilogue (stream, size)
if (TARGET_68881) if (TARGET_68881)
{ {
for (regno = 16; regno < 24; regno++) for (regno = 16; regno < 24; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
{ {
nregs++; nregs++;
fmask |= 1 << (23 - regno); fmask |= 1 << (23 - regno);
...@@ -837,19 +849,12 @@ m68k_output_function_epilogue (stream, size) ...@@ -837,19 +849,12 @@ m68k_output_function_epilogue (stream, size)
} }
foffset = fpoffset + nregs * 12; foffset = fpoffset + nregs * 12;
nregs = 0; mask = 0; nregs = 0; mask = 0;
if (frame_pointer_needed)
regs_ever_live[FRAME_POINTER_REGNUM] = 0;
for (regno = 0; regno < 16; regno++) for (regno = 0; regno < 16; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
{ {
nregs++; nregs++;
mask |= 1 << regno; mask |= 1 << regno;
} }
if (flag_pic && current_function_uses_pic_offset_table)
{
nregs++;
mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
}
offset = foffset + nregs * 4; offset = foffset + nregs * 4;
/* FIXME : leaf_function_p below is too strong. /* FIXME : leaf_function_p below is too strong.
What we really need to know there is if there could be pending What we really need to know there is if there could be pending
...@@ -995,7 +1000,7 @@ m68k_output_function_epilogue (stream, size) ...@@ -995,7 +1000,7 @@ m68k_output_function_epilogue (stream, size)
} }
if (fpoffset != 0) if (fpoffset != 0)
for (regno = 55; regno >= 24; regno--) for (regno = 55; regno >= 24; regno--)
if (regs_ever_live[regno] && ! call_used_regs[regno]) if (m68k_save_reg (regno))
{ {
if (big) if (big)
{ {
...@@ -1105,6 +1110,14 @@ m68k_output_function_epilogue (stream, size) ...@@ -1105,6 +1110,14 @@ m68k_output_function_epilogue (stream, size)
#endif #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) if (current_function_pops_args)
asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args); asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
else else
......
...@@ -1665,6 +1665,8 @@ __transfer_from_trampoline () \ ...@@ -1665,6 +1665,8 @@ __transfer_from_trampoline () \
#define DATA_SECTION_ASM_OP "\t.data" #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 /* Here are four prefixes that are used by asm_fprintf to
facilitate customization for alternate assembler syntaxes. facilitate customization for alternate assembler syntaxes.
Machines with no likelihood of an alternate syntax need not Machines with no likelihood of an alternate syntax need not
...@@ -1732,7 +1734,23 @@ __transfer_from_trampoline () \ ...@@ -1732,7 +1734,23 @@ __transfer_from_trampoline () \
/* Before the prologue, the top of the frame is at 4(%sp). */ /* Before the prologue, the top of the frame is at 4(%sp). */
#define INCOMING_FRAME_SP_OFFSET 4 #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. /* This is how to output a reference to a user-level label named NAME.
`assemble_name' uses this. */ `assemble_name' uses this. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment