--- 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 " 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 " instruction, indicating the CFA register has changed to 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: