aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2004-01-20 22:29:24 +0000
committerAlan Modra <amodra@gcc.gnu.org>2004-01-21 08:59:24 +1030
commit34c80057fcd1c1019fa93f44483842e1d1c9cc55 (patch)
tree92a413817c8bb86d3351646e048b5b3145798b76
parenta42952105e3bbc56a74773323f81bf23bd7e5ba1 (diff)
downloadgcc-34c80057fcd1c1019fa93f44483842e1d1c9cc55.zip
gcc-34c80057fcd1c1019fa93f44483842e1d1c9cc55.tar.gz
gcc-34c80057fcd1c1019fa93f44483842e1d1c9cc55.tar.bz2
sysv4.h (DWARF2_FRAME_REG_OUT): Define.
* config/rs6000/sysv4.h (DWARF2_FRAME_REG_OUT): Define. * dwarf2out.c (output_cfi): Map regs using DWARF2_FRAME_REG_OUT. * doc/tm.texi (DWARF_FRAME_REGNUM, DWARF2_FRAME_REG_OUT): Document. From-SVN: r76235
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/rs6000/sysv4.h12
-rw-r--r--gcc/doc/tm.texi20
-rw-r--r--gcc/dwarf2out.c46
4 files changed, 65 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b82d6fb..0d7623b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2004-01-21 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/sysv4.h (DWARF2_FRAME_REG_OUT): Define.
+ * dwarf2out.c (output_cfi): Map regs using DWARF2_FRAME_REG_OUT.
+ * doc/tm.texi (DWARF_FRAME_REGNUM, DWARF2_FRAME_REG_OUT): Document.
+
2004-01-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa-protos.h (compute_frame_size): Use HOST_WIDE_INT for frame sizes.
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 20e7c9a..3658047 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -744,6 +744,18 @@ extern int fixuplabelno;
#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
+/* Map register numbers held in the call frame info that gcc has
+ collected using DWARF_FRAME_REGNUM to those that should be output in
+ .debug_frame and .eh_frame. We continue to use gcc hard reg numbers
+ for .eh_frame, but use the numbers mandated by the various ABIs for
+ .debug_frame. rs6000_emit_prologue has translated any combination of
+ CR2, CR3, CR4 saves to a save of CR2. The actual code emitted saves
+ the whole of CR, so we map CR2_REGNO to the DWARF reg for CR. */
+#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) \
+ ((FOR_EH) ? (REGNO) \
+ : (REGNO) == CR2_REGNO ? 64 \
+ : DBX_REGISTER_NUMBER (REGNO))
+
#define TARGET_ENCODE_SECTION_INFO rs6000_elf_encode_section_info
#define TARGET_IN_SMALL_DATA_P rs6000_elf_in_small_data_p
#define TARGET_SECTION_TYPE_FLAGS rs6000_elf_section_type_flags
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index fd2b370..7866e1a 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3289,6 +3289,26 @@ column number to use instead.
See the PowerPC's SPE target for an example.
@end defmac
+@defmac DWARF_FRAME_REGNUM (@var{regno})
+
+Define this macro if the target's representation for dwarf registers
+used in .eh_frame or .debug_frame is different from that used in other
+debug info sections. Given a gcc hard register number, this macro
+should return the .eh_frame register number. The default is
+@code{DBX_REGISTER_NUMBER (@var{regno})}.
+
+@end defmac
+
+@defmac DWARF2_FRAME_REG_OUT (@var{regno}, @var{for_eh})
+
+Define this macro to map register numbers held in the call frame info
+that gcc has collected using @code{DWARF_FRAME_REGNUM} to those that
+should be output in .debug_frame (@code{@var{for_eh}} is zero) and
+.eh_frame (@code{@var{for_eh}} is non-zero). The default is to
+return @code{@var{regno}}.
+
+@end defmac
+
@node Elimination
@subsection Eliminating Frame Pointer and Arg Pointer
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 51c0f1c..7dca634 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -1790,11 +1790,19 @@ dw_cfi_oprnd2_desc (enum dwarf_call_frame_info cfi)
#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
+/* Map register numbers held in the call frame info that gcc has
+ collected using DWARF_FRAME_REGNUM to those that should be output in
+ .debug_frame and .eh_frame. */
+#ifndef DWARF2_FRAME_REG_OUT
+#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO)
+#endif
+
/* Output a Call Frame Information opcode and its operand(s). */
static void
output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
{
+ unsigned long r;
if (cfi->dw_cfi_opc == DW_CFA_advance_loc)
dw2_asm_output_data (1, (cfi->dw_cfi_opc
| (cfi->dw_cfi_oprnd1.dw_cfi_offset & 0x3f)),
@@ -1802,17 +1810,17 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
cfi->dw_cfi_oprnd1.dw_cfi_offset);
else if (cfi->dw_cfi_opc == DW_CFA_offset)
{
- dw2_asm_output_data (1, (cfi->dw_cfi_opc
- | (cfi->dw_cfi_oprnd1.dw_cfi_reg_num & 0x3f)),
- "DW_CFA_offset, column 0x%lx",
- cfi->dw_cfi_oprnd1.dw_cfi_reg_num);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)),
+ "DW_CFA_offset, column 0x%lx", r);
dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
}
else if (cfi->dw_cfi_opc == DW_CFA_restore)
- dw2_asm_output_data (1, (cfi->dw_cfi_opc
- | (cfi->dw_cfi_oprnd1.dw_cfi_reg_num & 0x3f)),
- "DW_CFA_restore, column 0x%lx",
- cfi->dw_cfi_oprnd1.dw_cfi_reg_num);
+ {
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)),
+ "DW_CFA_restore, column 0x%lx", r);
+ }
else
{
dw2_asm_output_data (1, cfi->dw_cfi_opc,
@@ -1857,15 +1865,15 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
case DW_CFA_offset_extended:
case DW_CFA_def_cfa:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
break;
case DW_CFA_offset_extended_sf:
case DW_CFA_def_cfa_sf:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
dw2_asm_output_data_sleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
break;
@@ -1873,15 +1881,15 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
case DW_CFA_undefined:
case DW_CFA_same_value:
case DW_CFA_def_cfa_register:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
break;
case DW_CFA_register:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd2.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
break;
case DW_CFA_def_cfa_offset:
@@ -1911,7 +1919,7 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
}
}
-/* Output the call frame information used to used to record information
+/* Output the call frame information used to record information
that relates to calculating the frame pointer, and records the
location of saved registers. */