This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, ARM] VFP3 dwarf register numbering


This patch fixes DWARF debug info for VFP3 registers. ARM have defined
a replacement set of encodings for these, which also cover the VFPv2
registers. (Older versions of?) GDB can't cope with the new
single-precision register representation though, so the old numbering
is used for VFPv2 registers.

(Paul Brook writes: "GDB does not inderstand DW_OP_reg; DW_OP_bit_piece.
With the introduction of VFPv3, AADWARF uses this to describe the
single precision registers (DW_OP_reg refers to a double precision
register).")

Tested with no regressions (cross to ARM Linux). OK for mainline?

Julian

ChangeLog

        Paul Brook  <paul@codesourcery.com>

        gcc/
        * config/arm/arm.c (TARGET_DWARF_REGISTER_SPAN): Define.
        (arm_dwarf_register_span): New function.
        (arm_dbx_register_number): Add VFPv3 dwarf numbering.
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 148209)
+++ gcc/config/arm/arm.c	(working copy)
@@ -178,6 +178,7 @@ static void arm_unwind_emit (FILE *, rtx
 static bool arm_output_ttype (rtx);
 #endif
 static void arm_dwarf_handle_frame_unspec (const char *, rtx, int);
+static rtx arm_dwarf_register_span(rtx);
 
 static tree arm_cxx_guard_type (void);
 static bool arm_cxx_guard_mask_bit (void);
@@ -366,6 +367,9 @@ static bool arm_allocate_stack_slots_for
 #undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
 #define TARGET_DWARF_HANDLE_FRAME_UNSPEC arm_dwarf_handle_frame_unspec
 
+#undef TARGET_DWARF_REGISTER_SPAN
+#define TARGET_DWARF_REGISTER_SPAN arm_dwarf_register_span
+
 #undef  TARGET_CANNOT_COPY_INSN_P
 #define TARGET_CANNOT_COPY_INSN_P arm_cannot_copy_insn_p
 
@@ -19159,9 +19163,14 @@ arm_dbx_register_number (unsigned int re
   if (IS_FPA_REGNUM (regno))
     return (TARGET_AAPCS_BASED ? 96 : 16) + regno - FIRST_FPA_REGNUM;
 
-  /* FIXME: VFPv3 register numbering.  */
   if (IS_VFP_REGNUM (regno))
-    return 64 + regno - FIRST_VFP_REGNUM;
+    {
+      /* See comment in arm_dwarf_register_span.  */
+      if (VFP_REGNO_OK_FOR_SINGLE (regno))
+	  return 64 + regno - FIRST_VFP_REGNUM;
+      else
+	  return 256 + (regno - FIRST_VFP_REGNUM) / 2;
+    }
 
   if (IS_IWMMXT_GR_REGNUM (regno))
     return 104 + regno - FIRST_IWMMXT_GR_REGNUM;
@@ -19172,6 +19181,39 @@ arm_dbx_register_number (unsigned int re
   gcc_unreachable ();
 }
 
+/* Dwarf models VFPv3 registers as 32 64-bit registers.
+   GCC models tham as 64 32-bit registers, so we need to describe this to
+   the DWARF generation code.  Other registers can use the default.  */
+static rtx
+arm_dwarf_register_span(rtx rtl)
+{
+    unsigned regno;
+    int nregs;
+    int i;
+    rtx p;
+
+    regno = REGNO (rtl);
+    if (!IS_VFP_REGNUM (regno))
+	return NULL_RTX;
+
+    /* The EABI defines two VFP register ranges:
+	  64-95: Legacy VFPv2 numbering for S0-S31 (obsolescent)
+	  256-287: D0-D31
+       The recommended encodings for s0-s31 is a DW_OP_bit_piece of the
+       corresponding D register.  However gdb6.6 does not support this, so
+       we use the legacy encodings.  We also use these encodings for D0-D15
+       for compatibility with older debuggers.  */
+    if (VFP_REGNO_OK_FOR_SINGLE (regno))
+	return NULL_RTX;
+
+    nregs = GET_MODE_SIZE (GET_MODE (rtl)) / 8;
+    p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc(nregs));
+    regno = (regno - FIRST_VFP_REGNUM) / 2;
+    for (i = 0; i < nregs; i++)
+      XVECEXP (p, 0, i) = gen_rtx_REG (DImode, 256 + regno + i);
+
+    return p;
+}
 
 #ifdef TARGET_UNWIND_INFO
 /* Emit unwind directives for a store-multiple instruction or stack pointer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]