From: Jason Merrill Date: Wed, 25 Jun 1997 20:58:55 +0000 (+0000) Subject: x X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c53aa1955e4e5bc0d98292e73125218ad5592ec6;p=gcc.git x From-SVN: r14321 --- diff --git a/gcc/config/mips/iris6.h b/gcc/config/mips/iris6.h index dd9914576a0..3521fdd3b3b 100644 --- a/gcc/config/mips/iris6.h +++ b/gcc/config/mips/iris6.h @@ -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" diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h index fca28be7b11..97c315d942d 100644 --- a/gcc/config/sparc/sol2.h +++ b/gcc/config/sparc/sol2.h @@ -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. */ diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 89b0755d164..9cf09747f49 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -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,9 +2909,15 @@ 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), - n_regs += 2; + { + fprintf (file, "\tstx %s,[%s+%d]\n", + 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 @@ -2919,17 +2926,39 @@ save_regs (file, low, high, base, offset, n_regs) { 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), - n_regs += 2; + { + fprintf (file, "\tstd %s,[%s+%d]\n", + 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); +#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], base, offset + 4 * n_regs), + 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; - 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), - 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); + { + 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); + { + 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); + { + 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. */ diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 8cce6d3e880..c787e6036b8 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -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)) diff --git a/gcc/dwarf2.h b/gcc/dwarf2.h index b16c4a3d531..6e394fe4123 100644 --- a/gcc/dwarf2.h +++ b/gcc/dwarf2.h @@ -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 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index f163535af09..aed0de476b4 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -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,7 +246,11 @@ 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 -#define SECTION_FORMAT "\t%s\t%s\n" +#ifdef PUSHSECTION_FORMAT +#define SECTION_FORMAT PUSHSECTION_FORMAT +#else +#define SECTION_FORMAT "\t%s\t%s\n" +#endif #endif #ifndef FRAME_SECTION @@ -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_"; } @@ -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);