rohitarulraj wrote:
> I was able to narrow down the issue.
[snip]
> While emitting the location descriptors of multiple registers (SPE high/low
> part) individually, the GCC hard register number is converted in to DWARF
> register number using "dbx_reg_number" [Statement "A", "B" & "C" below].
> But statement "C" macro "DBX_REGISTER_NUMBER" gets undefined by statement
> "D" hence the GCC hard register number gets emitted in the debug info
> instead of DWARF register number. Previously, without this patch for SPE
> high registers the GCC hard register number was same as the DWARF register
> number (1200 onwards), hence we didn't see this issue.
>
> Removing statement "D" from "sysv4.h" file so as to generate expected
> DWARF register number does work, but will there be any side effects?
Ah, I had completely forgotten about this issue, sorry ...
The problem with DBX_REGISTER_NUMBER is actually described in detail here:
https://gcc.gnu.org/ml/gcc-patches/2012-11/msg02136.html
At the time, we decided to not remove the #undef DBX_REGISTER_NUMBER to
avoid compatibility issues, but use GCC internal numbers in .debug_frame
and .debug_info on Linux (option (3) in the above mail). However, this
was never actually implemented.
Looking at the current status, there are three groups of rs6000 targets:
- Some use the DBX_REGISTER_NUMBER definition from rs6000.h:
These are only AIX and Darwin.
- Some provide their own definition of DBX_REGISTER_NUMBER after the rs6000.h
one was undefined by sysv4.h:
These are FreeBSD, NetBSD, and Lynx.
- All other targets do not have DBX_REGISTER_NUMBER because it is undefined
by sysv4.h, and therefore using GCC internal register numbers:
These are Linux, rtems, vxworks, and all ELF/EABI targets.
The following patch tries to remove the unfortunate confusion about undefining
and redefining DBX_REGISTER_NUMBER, while keeping the behavior on all targets
unchanged with the following two exceptions:
- fix the SPE problem by always translating high register numbers
- implement option (3) above by not replacing CR2 with CR in .debug_frame
on targets that do not use the standard DWARF register numbering
The way this works is to have a common, simple implementation of
DBX_REGISTER_NUMBER and DWARF2_FRAME_REG_OUT for all targets that just
calls to the rs6000_dbx_register_number routine, passing an extra format
argument that decides whether the register number is to be used for
.debug_info, .debug_frame, or .eh_frame. In order to ensure
rs6000_dbx_register_number always gets a GCC internal number as input,
DWARF_FRAME_REGNUM has to be again defined as identity map.
All the logic to decide debug register numbers is now contained in that
single place. However, in order to maintain current behavior, we still
have to distinguish between platforms that want to use the standard
DWARF register numbering scheme, and those that use GCC internal numbers.
This is now simply done by having the former provide a new define
RS6000_USE_DWARF_NUMBERING in a target header file.
Tested on powerpc64le-linux and powerpc64-linux.
Rohit, could you verify whether this fixes the SPE problem?
David, does this approach look reasonable to you?
Bye,
Ulrich
ChangeLog:
* config/rs6000/rs6000.h (DBX_REGISTER_NUMBER): Pass format argument
to rs6000_dbx_register_number.
(DWARF_FRAME_REGNUM): Redefine as identity map.
(DWARF2_FRAME_REG_OUT): Call rs6000_dbx_register_number.
* config/rs6000/rs6000-protos.h (rs6000_dbx_register_number): Update.
* config/rs6000/rs6000.c (rs6000_dbx_register_number): Add format
argument to handle .debug_frame and .eh_frame directly. Always
translate SPE high register numbers. Add special treatment for CR,
but only in .debug_frame. Respect RS6000_USE_DWARF_NUMBERING.
* config/rs6000/sysv.h (DBX_REGISTER_NUMBER): Do not undefine.
* config/rs6000/freebsd.h (DBX_REGISTER_NUMBER): Remove.
(RS6000_USE_DWARF_NUMBERING): Define.
* config/rs6000/freebsd64.h (DBX_REGISTER_NUMBER): Remove.
(RS6000_USE_DWARF_NUMBERING): Define.
* config/rs6000/netbsd.h (DBX_REGISTER_NUMBER): Remove.
(RS6000_USE_DWARF_NUMBERING): Define.
* config/rs6000/lynx.h (DBX_REGISTER_NUMBER): Remove.
(RS6000_USE_DWARF_NUMBERING): Define.
* config/rs6000/aix.h (RS6000_USE_DWARF_NUMBERING): Define.
* config/rs6000/darwin.h (RS6000_USE_DWARF_NUMBERING): Define.
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h (revision 215999)
+++ gcc/config/rs6000/rs6000.h (working copy)
@@ -947,23 +947,16 @@ enum data_align { align_abi, align_opt,
((r) >= 1200 ? ((r) - 1200 + (DWARF_FRAME_REGISTERS - 32)) : (r))
/* Use standard DWARF numbering for DWARF debugging information. */
-#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
+#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number ((REGNO), 0)
/* Use gcc hard register numbering for eh_frame. */
-#define DWARF_FRAME_REGNUM(REGNO) \
- (SPE_HIGH_REGNO_P (REGNO) ? ((REGNO) - FIRST_SPE_HIGH_REGNO + 1200) : (REGNO))
+#define DWARF_FRAME_REGNUM(REGNO) (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))
+ .debug_frame and .eh_frame. */
+#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) \
+ rs6000_dbx_register_number ((REGNO), (FOR_EH)? 2 : 1)
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h (revision 215999)
+++ gcc/config/rs6000/rs6000-protos.h (working copy)
@@ -188,7 +188,7 @@ extern int rs6000_trampoline_size (void)
extern alias_set_type get_TOC_alias_set (void);
extern void rs6000_emit_prologue (void);
extern void rs6000_emit_load_toc_table (int);
-extern unsigned int rs6000_dbx_register_number (unsigned int);
+extern unsigned int rs6000_dbx_register_number (unsigned int, unsigned int);
extern void rs6000_emit_epilogue (int);
extern void rs6000_emit_eh_reg_restore (rtx, rtx);
extern const char * output_isel (rtx *);
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 215999)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -31581,17 +31581,40 @@ rs6000_init_dwarf_reg_sizes_extra (tree
}
}
-/* Map internal gcc register numbers to DWARF2 register numbers. */
+/* Map internal gcc register numbers to debug format register numbers.
+ FORMAT specifies the type of debug register number to use:
+ 0 -- debug information, except for frame-related sections
+ 1 -- DWARF .debug_frame section
+ 2 -- DWARF .eh_frame section */
unsigned int
-rs6000_dbx_register_number (unsigned int regno)
+rs6000_dbx_register_number (unsigned int regno, unsigned int format)
{
- if (regno <= 63 || write_symbols != DWARF2_DEBUG)
+ /* We never use the GCC internal number for SPE high registers.
+ Those are mapped to the 1200..1231 range for all debug formats. */
+ if (SPE_HIGH_REGNO_P (regno))
+ return regno - FIRST_SPE_HIGH_REGNO + 1200;
+
+ /* Except for the above, we use the internal number for non-DWARF
+ debug information, and also for .eh_frame. */
+ if ((format == 0 && write_symbols != DWARF2_DEBUG) || format == 2)
+ return regno;
+
+ /* On some platforms, we use the standard DWARF register
+ numbering for .debug_info and .debug_frame. */
+#ifdef RS6000_USE_DWARF_NUMBERING
+ if (regno <= 63)
return regno;
if (regno == LR_REGNO)
return 108;
if (regno == CTR_REGNO)
return 109;
+ /* Special handling for CR 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. */
+ if (format == 1 && regno == CR2_REGNO)
+ return 64;
if (CR_REGNO_P (regno))
return regno - CR0_REGNO + 86;
if (regno == CA_REGNO)
@@ -31606,8 +31629,7 @@ rs6000_dbx_register_number (unsigned int
return 99;
if (regno == SPEFSCR_REGNO)
return 612;
- if (SPE_HIGH_REGNO_P (regno))
- return regno - FIRST_SPE_HIGH_REGNO + 1200;
+#endif
return regno;
}
Index: gcc/config/rs6000/sysv4.h
===================================================================
--- gcc/config/rs6000/sysv4.h (revision 215999)
+++ gcc/config/rs6000/sysv4.h (working copy)
@@ -949,4 +949,3 @@ ncrtn.o%s"
/* This target uses the sysv4.opt file. */
#define TARGET_USES_SYSV4_OPT 1
-#undef DBX_REGISTER_NUMBER
Index: gcc/config/rs6000/freebsd.h
===================================================================
--- gcc/config/rs6000/freebsd.h (revision 215999)
+++ gcc/config/rs6000/freebsd.h (working copy)
@@ -73,6 +73,7 @@
#define RELOCATABLE_NEEDS_FIXUP \
(rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE)
-#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
+/* Use standard DWARF numbering for DWARF debugging information. */
+#define RS6000_USE_DWARF_NUMBERING
#define POWERPC_FREEBSD
Index: gcc/config/rs6000/freebsd64.h
===================================================================
--- gcc/config/rs6000/freebsd64.h (revision 215999)
+++ gcc/config/rs6000/freebsd64.h (working copy)
@@ -362,7 +362,8 @@ extern int dot_symbols;
/* The default value isn't sufficient in 64-bit mode. */
#define STACK_CHECK_PROTECT (TARGET_64BIT ? 16 * 1024 : 12 * 1024)
-#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
+/* Use standard DWARF numbering for DWARF debugging information. */
+#define RS6000_USE_DWARF_NUMBERING
/* PowerPC64 Linux word-aligns FP doubles when -malign-power is given. */
#undef ADJUST_FIELD_ALIGN
Index: gcc/config/rs6000/netbsd.h
===================================================================
--- gcc/config/rs6000/netbsd.h (revision 215999)
+++ gcc/config/rs6000/netbsd.h (working copy)
@@ -87,4 +87,6 @@
{ "netbsd_endfile_spec", NETBSD_ENDFILE_SPEC },
-#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
+/* Use standard DWARF numbering for DWARF debugging information. */
+#define RS6000_USE_DWARF_NUMBERING
+
Index: gcc/config/rs6000/lynx.h
===================================================================
--- gcc/config/rs6000/lynx.h (revision 215999)
+++ gcc/config/rs6000/lynx.h (working copy)
@@ -99,7 +99,8 @@
#undef HAVE_AS_TLS
#define HAVE_AS_TLS 0
-#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
+/* Use standard DWARF numbering for DWARF debugging information. */
+#define RS6000_USE_DWARF_NUMBERING
#ifdef CRT_BEGIN
/* This function is part of crtbegin*.o which is at the beginning of
Index: gcc/config/rs6000/aix.h
===================================================================
--- gcc/config/rs6000/aix.h (revision 215999)
+++ gcc/config/rs6000/aix.h (working copy)
@@ -223,3 +223,7 @@
/* Static stack checking is supported by means of probes. */
#define STACK_CHECK_STATIC_BUILTIN 1
+
+/* Use standard DWARF numbering for DWARF debugging information. */
+#define RS6000_USE_DWARF_NUMBERING
+
Index: gcc/config/rs6000/darwin.h
===================================================================
--- gcc/config/rs6000/darwin.h (revision 215999)
+++ gcc/config/rs6000/darwin.h (working copy)
@@ -424,3 +424,7 @@ do { \
/* So far, there is no rs6000_fold_builtin, if one is introduced, then
this will need to be modified similar to the x86 case. */
#define TARGET_FOLD_BUILTIN SUBTARGET_FOLD_BUILTIN
+
+/* Use standard DWARF numbering for DWARF debugging information. */
+#define RS6000_USE_DWARF_NUMBERING
+
--
Dr. Ulrich Weigand
GNU/Linux compilers and toolchain
***@de.ibm.com