This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
DWARF2 exception handling for m68k
- From: Andreas Schwab <schwab at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 29 Nov 2002 23:03:52 +0100
- Subject: DWARF2 exception handling for m68k
This implements DWARF2 exception handing support on m68k. It passes the
simple tests I tried.
Andreas.
2002-11-29 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.
Index: gcc/config/m68k/m68k.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68k/m68k.c,v
retrieving revision 1.75
diff -u -p -a -u -p -a -r1.75 gcc/config/m68k/m68k.c
--- gcc/config/m68k/m68k.c 24 Nov 2002 18:32:01 -0000 1.75
+++ gcc/config/m68k/m68k.c 29 Nov 2002 21:09:04 -0000
@@ -207,6 +207,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)
+ int regno;
+{
+ if (flag_pic && current_function_uses_pic_offset_table
+ && regno == PIC_OFFSET_TABLE_REGNUM)
+ return 1;
+
+ if (current_function_calls_eh_return)
+ {
+ int i;
+ for (i = 0; ; i++)
+ {
+ 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 +279,13 @@ m68k_output_function_prologue (stream, s
{
/* 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 +293,8 @@ m68k_output_function_prologue (stream, s
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 +467,7 @@ m68k_output_function_prologue (stream, s
}
#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 +493,7 @@ m68k_output_function_prologue (stream, s
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 +526,11 @@ m68k_output_function_prologue (stream, s
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 +672,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 +703,7 @@ m68k_output_function_epilogue (stream, s
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 +711,9 @@ m68k_output_function_epilogue (stream, s
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 +766,7 @@ m68k_output_function_epilogue (stream, s
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 +785,14 @@ m68k_output_function_epilogue (stream, s
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 +832,7 @@ m68k_output_function_epilogue (stream, s
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 +840,7 @@ m68k_output_function_epilogue (stream, s
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 +848,12 @@ m68k_output_function_epilogue (stream, s
}
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 +999,7 @@ m68k_output_function_epilogue (stream, s
}
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)
{
@@ -1104,6 +1108,14 @@ m68k_output_function_epilogue (stream, s
asm_fprintf (stream, "\taddl %0I%d,%Rsp\n", fsize + 4);
#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);
Index: gcc/config/m68k/m68k.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68k/m68k.h,v
retrieving revision 1.80
diff -u -p -a -u -p -a -r1.80 m68k.h
--- gcc/config/m68k/m68k.h 16 Oct 2002 00:40:33 -0000 1.80
+++ gcc/config/m68k/m68k.h 29 Nov 2002 21:09:52 -0000
@@ -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. */
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."