Commit c53aa195 by Jason Merrill

x

From-SVN: r14321
parent 8440cf1b
......@@ -183,8 +183,8 @@ Boston, MA 02111-1307, USA. */
#define POPSECTION_ASM_OP ".popsection"
#define DEBUG_SECTION ".debug_info,0x7000001e,0,0,1"
#define LINE_SECTION ".debug_line,0x7000001e,0,0,1"
#define DEBUG_INFO_SECTION ".debug_info,0x7000001e,0,0,1"
#define DEBUG_LINE_SECTION ".debug_line,0x7000001e,0,0,1"
#define SFNAMES_SECTION ".debug_sfnames,0x7000001e,0,0,1"
#define SRCINFO_SECTION ".debug_srcinfo,0x7000001e,0,0,1"
#define MACINFO_SECTION ".debug_macinfo,0x7000001e,0,0,1"
......
......@@ -62,7 +62,8 @@ Boston, MA 02111-1307, USA. */
#undef DBX_REGISTER_NUMBER
/* Same as sparc.h */
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
#define DBX_REGISTER_NUMBER(REGNO) \
(TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO)
/* We use stabs-in-elf for debugging, because that is what the native
toolchain uses. */
......
......@@ -2894,12 +2894,13 @@ sparc_init_modes ()
__inline__
#endif
static int
save_regs (file, low, high, base, offset, n_regs)
save_regs (file, low, high, base, offset, n_regs, real_offset)
FILE *file;
int low, high;
char *base;
int offset;
int n_regs;
int real_offset;
{
int i;
......@@ -2908,30 +2909,58 @@ save_regs (file, low, high, base, offset, n_regs)
for (i = low; i < high; i++)
{
if (regs_ever_live[i] && ! call_used_regs[i])
{
fprintf (file, "\tstx %s,[%s+%d]\n",
reg_names[i], base, offset + 4 * n_regs),
reg_names[i], base, offset + 4 * n_regs);
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
dwarf2out_reg_save ("", i, real_offset + 4 * n_regs);
#endif
n_regs += 2;
}
}
}
else
{
for (i = low; i < high; i += 2)
{
if (regs_ever_live[i] && ! call_used_regs[i])
if (regs_ever_live[i+1] && ! call_used_regs[i+1])
{
fprintf (file, "\tstd %s,[%s+%d]\n",
reg_names[i], base, offset + 4 * n_regs),
reg_names[i], base, offset + 4 * n_regs);
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
{
char *l = (char *) dwarf2out_cfi_label ();
dwarf2out_reg_save (l, i, real_offset + 4 * n_regs);
dwarf2out_reg_save (l, i+1, real_offset + 4 * n_regs + 4);
}
#endif
n_regs += 2;
}
else
{
fprintf (file, "\tst %s,[%s+%d]\n",
reg_names[i], base, offset + 4 * n_regs),
reg_names[i], base, offset + 4 * n_regs);
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
dwarf2out_reg_save ("", i, real_offset + 4 * n_regs);
#endif
n_regs += 2;
}
else if (regs_ever_live[i+1] && ! call_used_regs[i+1])
{
fprintf (file, "\tst %s,[%s+%d]\n",
reg_names[i+1], base, offset + 4 * n_regs + 4),
reg_names[i+1], base, offset + 4 * n_regs + 4);
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
dwarf2out_reg_save ("", i + 1, real_offset + 4 * n_regs + 4);
#endif
n_regs += 2;
}
}
}
return n_regs;
}
......@@ -3169,6 +3198,29 @@ output_function_prologue (file, size, leaf_function)
}
}
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG && actual_fsize)
{
char *label = (char *) dwarf2out_cfi_label ();
/* The canonical frame address refers to the top of the frame. */
dwarf2out_def_cfa (label, (leaf_function ? STACK_POINTER_REGNUM
: FRAME_POINTER_REGNUM),
frame_base_offset);
if (! leaf_function)
{
/* Note the register window save. This tells the unwinder that
it needs to restore the window registers from the previous
frame's window save area at 0(cfa). */
dwarf2out_window_save (label);
/* The return address (-8) is now in %i7. */
dwarf2out_return_reg (label, 31);
}
}
#endif
/* If doing anything with PIC, do it now. */
if (! flag_pic)
fprintf (file, "\t!#PROLOGUE# 1\n");
......@@ -3176,10 +3228,10 @@ output_function_prologue (file, size, leaf_function)
/* Call saved registers are saved just above the outgoing argument area. */
if (num_gfregs)
{
int offset, n_regs;
int offset, real_offset, n_regs;
char *base;
offset = -apparent_fsize + frame_base_offset;
real_offset = offset = -apparent_fsize + frame_base_offset;
if (offset < -4096 || offset + num_gfregs * 4 > 4096)
{
/* ??? This might be optimized a little as %g1 might already have a
......@@ -3200,12 +3252,13 @@ output_function_prologue (file, size, leaf_function)
if (TARGET_EPILOGUE && ! leaf_function)
/* ??? Originally saved regs 0-15 here. */
n_regs = save_regs (file, 0, 8, base, offset, 0);
n_regs = save_regs (file, 0, 8, base, offset, 0, real_offset);
else if (leaf_function)
/* ??? Originally saved regs 0-31 here. */
n_regs = save_regs (file, 0, 8, base, offset, 0);
n_regs = save_regs (file, 0, 8, base, offset, 0, real_offset);
if (TARGET_EPILOGUE)
save_regs (file, 32, TARGET_V9 ? 96 : 64, base, offset, n_regs);
save_regs (file, 32, TARGET_V9 ? 96 : 64, base, offset, n_regs,
real_offset);
}
leaf_label = 0;
......@@ -4626,7 +4679,7 @@ sparc_flat_compute_frame_size (size)
DOUBLEWORD_OP is either "std" for save, "ldd" for restore. */
void
sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op, doubleword_op)
sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op, doubleword_op, base_offset)
FILE *file;
char *base_reg;
unsigned int offset;
......@@ -4634,6 +4687,7 @@ sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op, doublewo
unsigned long fmask;
char *word_op;
char *doubleword_op;
unsigned long base_offset;
{
int regno;
......@@ -4661,9 +4715,20 @@ sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op, doublewo
offset += UNITS_PER_WORD;
if (word_op[0] == 's')
{
fprintf (file, "\t%s %s,[%s+%d]\n",
doubleword_op, reg_names[regno],
base_reg, offset);
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
{
char *l = (char *) dwarf2out_cfi_label ();
dwarf2out_reg_save (l, regno, offset + base_offset);
dwarf2out_reg_save
(l, regno+1, offset+base_offset + UNITS_PER_WORD);
}
#endif
}
else
fprintf (file, "\t%s [%s+%d],%s\n",
doubleword_op, base_reg, offset,
......@@ -4675,9 +4740,15 @@ sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op, doublewo
else
{
if (word_op[0] == 's')
{
fprintf (file, "\t%s %s,[%s+%d]\n",
word_op, reg_names[regno],
base_reg, offset);
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
dwarf2out_reg_save ("", regno, offset + base_offset);
#endif
}
else
fprintf (file, "\t%s [%s+%d],%s\n",
word_op, base_reg, offset, reg_names[regno]);
......@@ -4695,9 +4766,15 @@ sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op, doublewo
if ((fmask & (1L << (regno - 32))) != 0)
{
if (word_op[0] == 's')
{
fprintf (file, "\t%s %s,[%s+%d]\n",
word_op, reg_names[regno],
base_reg, offset);
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
dwarf2out_reg_save ("", regno, offset + base_offset);
#endif
}
else
fprintf (file, "\t%s [%s+%d],%s\n",
word_op, base_reg, offset, reg_names[regno]);
......@@ -4794,16 +4871,34 @@ sparc_flat_output_function_prologue (file, size)
reg_offset += 4;
}
}
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
{
char *l = (char *) dwarf2out_cfi_label ();
if (gmask & FRAME_POINTER_MASK)
{
dwarf2out_reg_save (l, FRAME_POINTER_REGNUM,
reg_offset - 4 - size);
dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, 0);
}
else
dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, size);
}
#endif
if (gmask & RETURN_ADDR_MASK)
{
fprintf (file, "\tst %s,[%s+%d]\n",
reg_names[RETURN_ADDR_REGNUM], sp_str, reg_offset);
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
dwarf2out_return_save ("", reg_offset - size);
#endif
reg_offset += 4;
}
sparc_flat_save_restore (file, sp_str, reg_offset,
gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
current_frame_info.fmask,
"st", "std");
"st", "std", 0);
}
else
{
......@@ -4836,18 +4931,43 @@ sparc_flat_output_function_prologue (file, size)
offset += 4;
}
}
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
{
char *l = (char *) dwarf2out_cfi_label ();
if (gmask & FRAME_POINTER_MASK)
{
dwarf2out_reg_save (l, FRAME_POINTER_REGNUM,
offset - 4 - size1);
dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, 0);
}
else
dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, size1);
}
#endif
if (gmask & RETURN_ADDR_MASK)
{
fprintf (file, "\tst %s,[%s+%d]\n",
reg_names[RETURN_ADDR_REGNUM], sp_str, offset);
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
/* offset - size1 == reg_offset - size
if reg_offset were updated above like offset. */
dwarf2out_return_save ("", offset - size1);
#endif
offset += 4;
}
sparc_flat_save_restore (file, sp_str, offset,
gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
current_frame_info.fmask,
"st", "std");
"st", "std", size - size1);
fprintf (file, "\tset %d,%s\n\tsub %s,%s,%s\n",
size - size1, t1_str, sp_str, t1_str, sp_str);
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
if (! (gmask & FRAME_POINTER_MASK))
dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, size);
#endif
}
}
......@@ -4952,7 +5072,7 @@ sparc_flat_output_function_epilogue (file, size)
sparc_flat_save_restore (file, sp_str, reg_offset,
current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
current_frame_info.fmask,
"ld", "ldd");
"ld", "ldd", 0);
/* If we had to increment %sp in two steps, record it so the second
restoration in the epilogue finishes up. */
......
......@@ -2788,9 +2788,11 @@ extern struct rtx_def *legitimize_pic_address ();
#define ADDITIONAL_REGISTER_NAMES \
{{"ccr", SPARC_ICC_REG}, {"cc", SPARC_ICC_REG}}
/* How to renumber registers for dbx and gdb. */
/* How to renumber registers for dbx and gdb. In the flat model, the frame
pointer is really %i7. */
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
#define DBX_REGISTER_NUMBER(REGNO) \
(TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO)
/* On Sun 4, this limit is 2048. We use 1000 to be safe, since the length
can run past this up to a continuation point. Once we used 1500, but
......@@ -3124,3 +3126,10 @@ extern char *output_return ();
/* Defined in flags.h, but insn-emit.c does not include flags.h. */
extern int flag_pic;
/* Before the prologue, the return address is %o7 + 8. OK, sometimes it's
+12, but always using +8 is close enough for frame unwind purposes.
Actually, just using %o7 is close enough for unwinding, but %o7+8
is something you can return to. */
#define INCOMING_RETURN_ADDR_RTX \
gen_rtx (PLUS, word_mode, gen_rtx (REG, word_mode, 15), GEN_INT (8))
......@@ -493,7 +493,10 @@ enum dwarf_call_frame_info
DW_CFA_def_cfa_register = 0x0d,
DW_CFA_def_cfa_offset = 0x0e,
/* SGI/MIPS specific */
DW_CFA_MIPS_advance_loc8 = 0x1d
DW_CFA_MIPS_advance_loc8 = 0x1d,
/* GNU extensions */
DW_CFA_GNU_window_save = 0x2d,
};
#define DW_CIE_ID 0xffffffff
......
......@@ -189,7 +189,7 @@ static unsigned long size_of_uleb128 PROTO((unsigned long));
static unsigned long size_of_sleb128 PROTO((long));
static void output_uleb128 PROTO((unsigned long));
static void output_sleb128 PROTO((long));
static char *dwarf2out_cfi_label PROTO((void));
char *dwarf2out_cfi_label PROTO((void));
static void add_fde_cfi PROTO((char *, dw_cfi_ref));
static void lookup_cfa_1 PROTO((dw_cfi_ref, unsigned long *,
long *));
......@@ -246,8 +246,12 @@ static unsigned reg_number PROTO((rtx));
almost all svr4 assemblers, except for the sparc, where the section name
must be enclosed in double quotes. (See sparcv4.h). */
#ifndef SECTION_FORMAT
#ifdef PUSHSECTION_FORMAT
#define SECTION_FORMAT PUSHSECTION_FORMAT
#else
#define SECTION_FORMAT "\t%s\t%s\n"
#endif
#endif
#ifndef FRAME_SECTION
#define FRAME_SECTION ".debug_frame"
......@@ -466,9 +470,15 @@ dwarf_cfi_name (cfi_opc)
return "DW_CFA_def_cfa_register";
case DW_CFA_def_cfa_offset:
return "DW_CFA_def_cfa_offset";
/* SGI/MIPS specific */
case DW_CFA_MIPS_advance_loc8:
return "DW_CFA_MIPS_advance_loc8";
/* GNU extensions */
case DW_CFA_GNU_window_save:
return "DW_CFA_GNU_window_save";
default:
return "DW_CFA_<unknown>";
}
......@@ -506,7 +516,7 @@ add_cfi (list_head, cfi)
/* Generate a new label for the CFI info to refer to. */
static char *
char *
dwarf2out_cfi_label ()
{
static char label[20];
......@@ -698,8 +708,24 @@ reg_save (label, reg, sreg, offset)
add_fde_cfi (label, cfi);
}
/* Entry point for saving a register. REG is the GCC register number.
LABEL and OFFSET are passed to reg_save. */
/* Add the CFI for saving a register window. LABEL is passed to reg_save.
This CFI tells the unwinder that it needs to restore the window registers
from the previous frame's window save area.
??? Perhaps we should note in the CIE where windows are saved (instead of
assuming 0(cfa)) and what registers are in the window. */
void
dwarf2out_window_save (label)
register char * label;
{
register dw_cfi_ref cfi = new_cfi ();
cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
add_fde_cfi (label, cfi);
}
/* Entry point for saving a register to the stack. REG is the GCC register
number. LABEL and OFFSET are passed to reg_save. */
void
dwarf2out_reg_save (label, reg, offset)
......@@ -710,6 +736,28 @@ dwarf2out_reg_save (label, reg, offset)
reg_save (label, DWARF_FRAME_REGNUM (reg), -1, offset);
}
/* Entry point for saving the return address in the stack.
LABEL and OFFSET are passed to reg_save. */
void
dwarf2out_return_save (label, offset)
register char * label;
register long offset;
{
reg_save (label, DWARF_FRAME_RETURN_COLUMN, -1, offset);
}
/* Entry point for saving the return address in a register.
LABEL and SREG are passed to reg_save. */
void
dwarf2out_return_reg (label, sreg)
register char * label;
register unsigned sreg;
{
reg_save (label, DWARF_FRAME_RETURN_COLUMN, sreg, 0);
}
/* Record the initial position of the return address. RTL is
INCOMING_RETURN_ADDR_RTX. */
......@@ -747,6 +795,13 @@ initial_return_save (rtl)
abort ();
}
break;
case PLUS:
/* The return address is at some offset from any value we can
actually load. For instance, on the SPARC it is in %i7+8. Just
ignore the offset for now; it doesn't matter for unwinding frames. */
assert (GET_CODE (XEXP (rtl, 1)) == CONST_INT);
initial_return_save (XEXP (rtl, 0));
return;
default:
abort ();
}
......@@ -1223,6 +1278,8 @@ output_cfi (cfi, fde)
output_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_offset);
fputc ('\n', asm_out_file);
break;
case DW_CFA_GNU_window_save:
break;
default:
break;
}
......@@ -2058,8 +2115,8 @@ static void gen_decl_die PROTO((tree, dw_die_ref));
static unsigned lookup_filename PROTO((char *));
/* Section names used to hold DWARF debugging information. */
#ifndef DEBUG_SECTION
#define DEBUG_SECTION ".debug_info"
#ifndef DEBUG_INFO_SECTION
#define DEBUG_INFO_SECTION ".debug_info"
#endif
#ifndef ABBREV_SECTION
#define ABBREV_SECTION ".debug_abbrev"
......@@ -2070,8 +2127,8 @@ static unsigned lookup_filename PROTO((char *));
#ifndef DW_MACINFO_SECTION
#define DW_MACINFO_SECTION ".debug_macinfo"
#endif
#ifndef LINE_SECTION
#define LINE_SECTION ".debug_line"
#ifndef DEBUG_LINE_SECTION
#define DEBUG_LINE_SECTION ".debug_line"
#endif
#ifndef LOC_SECTION
#define LOC_SECTION ".debug_loc"
......@@ -5005,7 +5062,7 @@ output_pubnames ()
fprintf (asm_out_file, "\t%s DWARF Version", ASM_COMMENT_START);
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (DEBUG_SECTION));
ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (DEBUG_INFO_SECTION));
if (flag_verbose_asm)
fprintf (asm_out_file, "\t%s Offset of Compilation Unit Info.",
ASM_COMMENT_START);
......@@ -5079,7 +5136,7 @@ output_aranges ()
fprintf (asm_out_file, "\t%s DWARF Version", ASM_COMMENT_START);
fputc ('\n', asm_out_file);
ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (DEBUG_SECTION));
ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (DEBUG_INFO_SECTION));
if (flag_verbose_asm)
fprintf (asm_out_file, "\t%s Offset of Compilation Unit Info.",
ASM_COMMENT_START);
......@@ -9218,7 +9275,7 @@ dwarf2out_finish ()
if (line_info_table_in_use > 1 || separate_line_info_table_in_use)
{
fputc ('\n', asm_out_file);
ASM_OUTPUT_SECTION (asm_out_file, LINE_SECTION);
ASM_OUTPUT_SECTION (asm_out_file, DEBUG_LINE_SECTION);
output_line_info ();
/* We can only use the low/high_pc attributes if all of the code
......@@ -9229,7 +9286,7 @@ dwarf2out_finish ()
add_AT_lbl_id (comp_unit_die, DW_AT_high_pc, text_end_label);
}
add_AT_section_offset (comp_unit_die, DW_AT_stmt_list, LINE_SECTION);
add_AT_section_offset (comp_unit_die, DW_AT_stmt_list, DEBUG_LINE_SECTION);
}
/* Output the abbreviation table. */
......@@ -9244,7 +9301,7 @@ dwarf2out_finish ()
/* Output debugging information. */
fputc ('\n', asm_out_file);
ASM_OUTPUT_SECTION (asm_out_file, DEBUG_SECTION);
ASM_OUTPUT_SECTION (asm_out_file, DEBUG_INFO_SECTION);
output_compilation_unit_header ();
output_die (comp_unit_die);
......
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