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]

Re: update dwarf2 asm unwind info [hppa64-*-* failures]


John David Anglin wrote:
As can be seen, gas is dividing DWARF2_CIE_DATA_ALIGNMENT when the
offset is negative.  GCC is also dividing by the data alignment.
So, which is wrong?

Gcc is wrong. Here's a patch to avoid doing the division twice.



r~
--- dwarf2out.c	(revision 139547)
+++ dwarf2out.c	(local)
@@ -776,23 +776,16 @@ lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_loc
   switch (cfi->dw_cfi_opc)
     {
     case DW_CFA_def_cfa_offset:
-      loc->offset = cfi->dw_cfi_oprnd1.dw_cfi_offset;
-      break;
     case DW_CFA_def_cfa_offset_sf:
-      loc->offset
-	= cfi->dw_cfi_oprnd1.dw_cfi_offset * DWARF_CIE_DATA_ALIGNMENT;
+      loc->offset = cfi->dw_cfi_oprnd1.dw_cfi_offset;
       break;
     case DW_CFA_def_cfa_register:
       loc->reg = cfi->dw_cfi_oprnd1.dw_cfi_reg_num;
       break;
     case DW_CFA_def_cfa:
-      loc->reg = cfi->dw_cfi_oprnd1.dw_cfi_reg_num;
-      loc->offset = cfi->dw_cfi_oprnd2.dw_cfi_offset;
-      break;
     case DW_CFA_def_cfa_sf:
       loc->reg = cfi->dw_cfi_oprnd1.dw_cfi_reg_num;
-      loc->offset
-	= cfi->dw_cfi_oprnd2.dw_cfi_offset * DWARF_CIE_DATA_ALIGNMENT;
+      loc->offset = cfi->dw_cfi_oprnd2.dw_cfi_offset;
       break;
     case DW_CFA_def_cfa_expression:
       get_cfa_from_loc_descr (loc, cfi->dw_cfi_oprnd1.dw_cfi_loc);
@@ -891,20 +884,14 @@ def_cfa_1 (const char *label, dw_cfa_loc
   if (loc.reg == old_cfa.reg && !loc.indirect)
     {
       /* Construct a "DW_CFA_def_cfa_offset <offset>" instruction, indicating
-	 the CFA register did not change but the offset did.  */
+	 the CFA register did not change but the offset did.  The data 
+	 factoring for DW_CFA_def_cfa_offset_sf happens in output_cfi, or
+	 in the assembler via the .cfi_def_cfa_offset directive.  */
       if (loc.offset < 0)
-	{
-	  HOST_WIDE_INT f_offset = loc.offset / DWARF_CIE_DATA_ALIGNMENT;
-	  gcc_assert (f_offset * DWARF_CIE_DATA_ALIGNMENT == loc.offset);
-
-	  cfi->dw_cfi_opc = DW_CFA_def_cfa_offset_sf;
-	  cfi->dw_cfi_oprnd1.dw_cfi_offset = f_offset;
-	}
+	cfi->dw_cfi_opc = DW_CFA_def_cfa_offset_sf;
       else
-	{
-	  cfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
-	  cfi->dw_cfi_oprnd1.dw_cfi_offset = loc.offset;
-	}
+	cfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
+      cfi->dw_cfi_oprnd1.dw_cfi_offset = loc.offset;
     }
 
 #ifndef MIPS_DEBUGGING_INFO  /* SGI dbx thinks this means no offset.  */
@@ -924,22 +911,15 @@ def_cfa_1 (const char *label, dw_cfa_loc
     {
       /* Construct a "DW_CFA_def_cfa <register> <offset>" instruction,
 	 indicating the CFA register has changed to <register> with
-	 the specified offset.  */
+	 the specified offset.  The data factoring for DW_CFA_def_cfa_sf
+	 happens in output_cfi, or in the assembler via the .cfi_def_cfa
+	 directive.  */
       if (loc.offset < 0)
-	{
-	  HOST_WIDE_INT f_offset = loc.offset / DWARF_CIE_DATA_ALIGNMENT;
-	  gcc_assert (f_offset * DWARF_CIE_DATA_ALIGNMENT == loc.offset);
-
-	  cfi->dw_cfi_opc = DW_CFA_def_cfa_sf;
-	  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = loc.reg;
-	  cfi->dw_cfi_oprnd2.dw_cfi_offset = f_offset;
-	}
+	cfi->dw_cfi_opc = DW_CFA_def_cfa_sf;
       else
-	{
-	  cfi->dw_cfi_opc = DW_CFA_def_cfa;
-	  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = loc.reg;
-	  cfi->dw_cfi_oprnd2.dw_cfi_offset = loc.offset;
-	}
+	cfi->dw_cfi_opc = DW_CFA_def_cfa;
+      cfi->dw_cfi_oprnd1.dw_cfi_reg_num = loc.reg;
+      cfi->dw_cfi_oprnd2.dw_cfi_offset = loc.offset;
     }
   else
     {
@@ -2552,6 +2532,8 @@ static void
 output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
 {
   unsigned long r;
+  HOST_WIDE_INT off;
+
   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)),
@@ -2622,12 +2604,20 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref f
 	  break;
 
 	case DW_CFA_offset_extended_sf:
-	case DW_CFA_def_cfa_sf:
 	  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;
 
+	case DW_CFA_def_cfa_sf:
+	  r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+	  dw2_asm_output_data_uleb128 (r, NULL);
+
+	  off = cfi->dw_cfi_oprnd2.dw_cfi_offset;
+	  gcc_assert (off % DWARF_CIE_DATA_ALIGNMENT == 0);
+	  dw2_asm_output_data_sleb128 (off / DWARF_CIE_DATA_ALIGNMENT, NULL);
+	  break;
+
 	case DW_CFA_restore_extended:
 	case DW_CFA_undefined:
 	case DW_CFA_same_value:
@@ -2649,7 +2639,9 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref f
 	  break;
 
 	case DW_CFA_def_cfa_offset_sf:
-	  dw2_asm_output_data_sleb128 (cfi->dw_cfi_oprnd1.dw_cfi_offset, NULL);
+	  off = cfi->dw_cfi_oprnd1.dw_cfi_offset;
+	  gcc_assert (off % DWARF_CIE_DATA_ALIGNMENT == 0);
+	  dw2_asm_output_data_sleb128 (off / DWARF_CIE_DATA_ALIGNMENT, NULL);
 	  break;
 
 	case DW_CFA_GNU_window_save:

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