On 05/16/2013 12:27 AM, Cary Coutant wrote: >>> How about using dbx_reg_number (XVECEXP (regs, 0, i)) instead? The >>> bare use of DBX_REGISTER_NUMBER earlier in that function is protected >>> by a gcc_assert, but this one isn't. >> For the respective targets maintainers that drop into the thread: Here is a summary of the problem:
Since http://gcc.gnu.org/ml/gcc-patches/2012-03/msg00209.html, dwarf double floating point registers are not correctly described for the SH. But this patch was needed to fix an assertion in the dwarf2cfi. Therefore, we have a discrepancy between the different targets, that can result in assertions, (or possibly silent wrong unwind code I believe) SH,MIPS,C6X ; dwarf_register_span returns hard_reg numbers. regno is never translated for DBX ARM NEON ; converts regno into DBX numbers POWERPC ; ? returns boths. So a second set of patches http://gcc.gnu.org/ml/gcc-patches/2013-05/msg01230.html http://gcc.gnu.org/ml/gcc-patches/2013-05/msg00312.html fixed it with a common rule. All interfaces are changed to return hard_reg numbers only. multiple_reg_location is in charge of calling DBX_REGISTER_NUMBER with an assertion check. Well, in fact this was not doing some good for the powerpc, that now asserts here. The problem is that rs6000_dwarf_register_span stores in the PARALLEL rtx both the hard reg and the dbx reg, so we can't call dbx_reg_number in it. Using DBX_REGISTER_NUMBER instead of dbx_reg_number restores the previous working status for all targets. This is dwarf-span-assert-rs6000.patch for reference. However I feel a little bit uncomfortable with this solution that doesn't seem to fix the root cause. The dbx_register_number hooks is called basically from two places : dwarf2cfi.c and dwarf2out.c. That show different uses: either we want to refer to the hard regno when dealing with the cfa description (whereas we want DWARF_FRAME_REGNUM, not DBX_REGISTER_NUMBER). or we use the DBX_REGISTER_NUMBER for output register locations. Since this information cannot be detected contextually, I'd like to extend the dwarf_register_span target hook to return a dbx number or not. This is dwarf-span-target-dbx.patch build tested with the configurations that failed at one time or the other: - sh64-unknown-elf (The original sh64-elf build failure assertion in dwarf2cfi is fixed.) - arm-none-eabi -with-fpu=neon-vfpv4 - powerpc-e500v2-linux-gnuspe - x86_64-unknown-linux-gnu sanity build OK Is dwarf-span-target-dbx.patch OK for trunk ?. More comments ? Many Thanks, Christian
2013-05-23 Christian Bruel <christian.br...@st.com> PR debug/57351 PR debug/57389 * config/arm/arm.c (arm_dwarf_register_span): Add bool dbx parameter. * config/c6x/c6x.c (c6x_dwarf_register_span): Likewise. * config/mips/mips (mips_dwarf_register_span): Likewise. * config/rs6000/rs6000.c (rs6000_dwarf_register_span): Likewise. * config/sh/sh.c (sh_dwarf_register_span): Likewise. Declare static. * config/sh/sh-protos.h (sh_dwarf_register_span): Remove declaration. * gcc/doc/tm.texi: Add bool dbx parameter. * gcc/target.def: Likewise, * gcc/dwarf2cfi.c (dwarf2out_frame_debug_cfa_offset): Don't span dbx. (dwarf2out_frame_debug_cfa_expression): Don't span dbx. * gcc/dwarf2out.c (reg_loc_descriptor): Span dbx. * gcc/hooks.c: (hook_rtx_bool_null): Define. * gcc/hooks.h: (hook_rtx_bool_null): Declare. Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c (revision 199354) +++ gcc/config/arm/arm.c (working copy) @@ -213,7 +213,7 @@ static bool arm_output_ttype (rtx); static void arm_asm_emit_except_personality (rtx); static void arm_asm_init_sections (void); #endif -static rtx arm_dwarf_register_span (rtx); +static rtx arm_dwarf_register_span (rtx, bool); static tree arm_cxx_guard_type (void); static bool arm_cxx_guard_mask_bit (void); @@ -25855,7 +25855,7 @@ arm_dbx_register_number (unsigned int regno) 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) +arm_dwarf_register_span (rtx rtl, bool dbx) { unsigned regno; int nregs; @@ -25878,6 +25878,8 @@ static rtx nregs = GET_MODE_SIZE (GET_MODE (rtl)) / 8; p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs)); + if (dbx) + regno = 256 + (regno - FIRST_VFP_REGNUM) / 2; for (i = 0; i < nregs; i++) XVECEXP (p, 0, i) = gen_rtx_REG (DImode, regno + i); Index: gcc/config/c6x/c6x.c =================================================================== --- gcc/config/c6x/c6x.c (revision 199354) +++ gcc/config/c6x/c6x.c (working copy) @@ -6304,7 +6304,7 @@ c6x_set_return_address (rtx source, rtx scratch) registers for DWARF generation code. */ static rtx -c6x_dwarf_register_span (rtx rtl) +c6x_dwarf_register_span (rtx rtl, bool dbx ATTRIBUTE_UNUSED) { unsigned regno; unsigned real_regno; Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c (revision 199354) +++ gcc/config/mips/mips.c (working copy) @@ -8533,7 +8533,7 @@ mips_output_dwarf_dtprel (FILE *file, int size, rt /* Implement TARGET_DWARF_REGISTER_SPAN. */ static rtx -mips_dwarf_register_span (rtx reg) +mips_dwarf_register_span (rtx reg, bool dbx ATTRIBUTE_UNUSED) { rtx high, low; enum machine_mode mode; Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 199354) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -27738,7 +27738,7 @@ rs6000_initial_elimination_offset (int from, int t } static rtx -rs6000_dwarf_register_span (rtx reg) +rs6000_dwarf_register_span (rtx reg, bool dbx ATTRIBUTE_UNUSED) { rtx parts[8]; int i, words; Index: gcc/config/sh/sh-protos.h =================================================================== --- gcc/config/sh/sh-protos.h (revision 199354) +++ gcc/config/sh/sh-protos.h (working copy) @@ -214,7 +214,6 @@ extern rtx sh_get_pr_initial_val (void); extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, signed int, enum machine_mode); -extern rtx sh_dwarf_register_span (rtx); extern rtx replace_n_hard_rtx (rtx, rtx *, int , int); extern int shmedia_cleanup_truncate (rtx *, void *); Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c (revision 199354) +++ gcc/config/sh/sh.c (working copy) @@ -303,6 +303,7 @@ static rtx sh_function_arg (cumulative_args_t, enu const_tree, bool); static bool sh_scalar_mode_supported_p (enum machine_mode); static int sh_dwarf_calling_convention (const_tree); +static rtx sh_dwarf_register_span (rtx, bool); static void sh_encode_section_info (tree, rtx, int); static bool sh2a_function_vector_p (tree); static void sh_trampoline_init (rtx, tree, rtx); @@ -8760,14 +8761,17 @@ sh_gimplify_va_arg_expr (tree valist, tree type, g /* 64 bit floating points memory transfers are paired single precision loads or store. So DWARF information needs fixing in little endian (unless PR=SZ=1 in FPSCR). */ -rtx -sh_dwarf_register_span (rtx reg) +static rtx +sh_dwarf_register_span (rtx reg, bool dbx) { unsigned regno = REGNO (reg); if (WORDS_BIG_ENDIAN || GET_MODE (reg) != DFmode) return NULL_RTX; + if (dbx) + regno = DBX_REGISTER_NUMBER (regno); + return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi (revision 199354) +++ gcc/doc/tm.texi (working copy) @@ -8971,7 +8971,7 @@ Default value is false if @code{EH_FRAME_SECTION_N true otherwise. @end deftypevr -@deftypefn {Target Hook} rtx TARGET_DWARF_REGISTER_SPAN (rtx @var{reg}) +@deftypefn {Target Hook} rtx TARGET_DWARF_REGISTER_SPAN (rtx @var{reg}, @var{bool}) Given a register, this hook should return a parallel of registers to represent where to find the register pieces. Define this hook if the register and its mode are represented in Dwarf in non-contiguous Index: gcc/dwarf2cfi.c =================================================================== --- gcc/dwarf2cfi.c (revision 199354) +++ gcc/dwarf2cfi.c (working copy) @@ -1134,7 +1134,7 @@ dwarf2out_frame_debug_cfa_offset (rtx set) } else { - span = targetm.dwarf_register_span (src); + span = targetm.dwarf_register_span (src, false); sregno = dwf_regno (src); } @@ -1203,7 +1203,7 @@ dwarf2out_frame_debug_cfa_expression (rtx set) gcc_assert (REG_P (src)); gcc_assert (MEM_P (dest)); - span = targetm.dwarf_register_span (src); + span = targetm.dwarf_register_span (src, false); gcc_assert (!span); regno = dwf_regno (src); @@ -1882,7 +1882,7 @@ dwarf2out_frame_debug_expr (rtx expr) span = NULL; if (REG_P (src)) - span = targetm.dwarf_register_span (src); + span = targetm.dwarf_register_span (src, false); if (!span) queue_reg_save (src, NULL_RTX, offset); else Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 199354) +++ gcc/dwarf2out.c (working copy) @@ -10572,7 +10572,7 @@ reg_loc_descriptor (rtx rtl, enum var_init_status return result; } - regs = targetm.dwarf_register_span (rtl); + regs = targetm.dwarf_register_span (rtl, true); if (hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)] > 1 || regs) return multiple_reg_loc_descriptor (rtl, regs, initialized); @@ -10660,7 +10660,7 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs, { dw_loc_descr_ref t; - t = one_reg_loc_descriptor (dbx_reg_number (XVECEXP (regs, 0, i)), + t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)), VAR_INIT_STATUS_INITIALIZED); add_loc_descr (&loc_result, t); add_loc_descr_op_piece (&loc_result, size); Index: gcc/hooks.c =================================================================== --- gcc/hooks.c (revision 199354) +++ gcc/hooks.c (working copy) @@ -338,13 +338,20 @@ hook_rtx_rtx_identity (rtx x) return x; } -/* Generic hook that takes an rtx and returns NULL_RTX. */ +/* Generic hook that takes a rtx and returns NULL_RTX. */ rtx hook_rtx_rtx_null (rtx x ATTRIBUTE_UNUSED) { return NULL; } +/* Generic hook that takes a rtx and a bool and returns NULL_RTX. */ +rtx +hook_rtx_bool_null (rtx x ATTRIBUTE_UNUSED, bool dbx ATTRIBUTE_UNUSED) +{ + return NULL; +} + /* Generic hook that takes a tree and an int and returns NULL_RTX. */ rtx hook_rtx_tree_int_null (tree a ATTRIBUTE_UNUSED, int b ATTRIBUTE_UNUSED) Index: gcc/hooks.h =================================================================== --- gcc/hooks.h (revision 199354) +++ gcc/hooks.h (working copy) @@ -95,6 +95,7 @@ extern bool default_can_output_mi_thunk_no_vcall ( extern rtx hook_rtx_rtx_identity (rtx); extern rtx hook_rtx_rtx_null (rtx); +extern rtx hook_rtx_bool_null (rtx, bool dbx); extern rtx hook_rtx_tree_int_null (tree, int); extern const char *hook_constcharptr_void_null (void); Index: gcc/target.def =================================================================== --- gcc/target.def (revision 199354) +++ gcc/target.def (working copy) @@ -1850,8 +1850,8 @@ DEFHOOK DEFHOOK (dwarf_register_span, "", - rtx, (rtx reg), - hook_rtx_rtx_null) + rtx, (rtx reg, bool), + hook_rtx_bool_null) /* If expand_builtin_init_dwarf_reg_sizes needs to fill in table entries not corresponding directly to registers below
2013-05-23 Christian Bruel <christian.br...@st.com> PR debug/57389 * dwarf2out.c (multiple_reg_loc_descriptor): Use DBX_REGISTER_NUMBER instead of dbx_reg_number. Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 199354) +++ gcc/dwarf2out.c (working copy) @@ -10660,8 +10660,11 @@ multiple_reg_loc_descriptor (rtx rtl, rtx regs, { dw_loc_descr_ref t; - t = one_reg_loc_descriptor (dbx_reg_number (XVECEXP (regs, 0, i)), + /* Cannot use dbx_reg_number here because regno could be out of the hard-reg + range and not handled by DBX_REGISTER_NUMBER. See rs6000.h. */ + t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (REGNO (XVECEXP (regs, 0, i))), VAR_INIT_STATUS_INITIALIZED); + add_loc_descr (&loc_result, t); add_loc_descr_op_piece (&loc_result, size); }