diff options
Diffstat (limited to 'gcc/dwarf2cfi.c')
-rw-r--r-- | gcc/dwarf2cfi.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index eb59f2864b9..36fa7f86cf5 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -285,6 +285,17 @@ add_cfi (dw_cfi_ref cfi) VEC_safe_push (dw_cfi_ref, gc, *add_cfi_vec, cfi); } +/* Perform ROW->REG_SAVE[COLUMN] = CFI. CFI may be null, indicating + that the register column is no longer saved. */ + +static void +update_row_reg_save (dw_cfi_row_ref row, unsigned column, dw_cfi_ref cfi) +{ + if (VEC_length (dw_cfi_ref, row->reg_save) <= column) + VEC_safe_grow_cleared (dw_cfi_ref, gc, row->reg_save, column + 1); + VEC_replace (dw_cfi_ref, row->reg_save, column, cfi); +} + /* This function fills in aa dw_cfa_location structure from a dwarf location descriptor sequence. */ @@ -574,7 +585,13 @@ reg_save (unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset) cfi->dw_cfi_oprnd2.dw_cfi_offset = offset; } else if (sreg == reg) - cfi->dw_cfi_opc = DW_CFA_same_value; + { + /* While we could emit something like DW_CFA_same_value or + DW_CFA_restore, we never expect to see something like that + in a prologue. This is more likely to be a bug. A backend + can always bypass this by using REG_CFA_RESTORE directly. */ + gcc_unreachable (); + } else { cfi->dw_cfi_opc = DW_CFA_register; @@ -582,6 +599,7 @@ reg_save (unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset) } add_cfi (cfi); + update_row_reg_save (cur_row, reg, cfi); } /* Given a SET, calculate the amount of stack adjustment it @@ -1337,6 +1355,7 @@ dwarf2out_frame_debug_cfa_expression (rtx set) { rtx src, dest, span; dw_cfi_ref cfi = new_cfi (); + unsigned regno; dest = SET_DEST (set); src = SET_SRC (set); @@ -1347,8 +1366,10 @@ dwarf2out_frame_debug_cfa_expression (rtx set) span = targetm.dwarf_register_span (src); gcc_assert (!span); + regno = dwf_regno (src); + cfi->dw_cfi_opc = DW_CFA_expression; - cfi->dw_cfi_oprnd1.dw_cfi_reg_num = dwf_regno (src); + cfi->dw_cfi_oprnd1.dw_cfi_reg_num = regno; cfi->dw_cfi_oprnd2.dw_cfi_loc = mem_loc_descriptor (XEXP (dest, 0), get_address_mode (dest), GET_MODE (dest), VAR_INIT_STATUS_INITIALIZED); @@ -1356,6 +1377,7 @@ dwarf2out_frame_debug_cfa_expression (rtx set) /* ??? We'd like to use queue_reg_save, were the interface different, and, as above, we could manage flushing for epilogues. */ add_cfi (cfi); + update_row_reg_save (cur_row, regno, cfi); } /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE note. */ @@ -1370,6 +1392,7 @@ dwarf2out_frame_debug_cfa_restore (rtx reg) cfi->dw_cfi_oprnd1.dw_cfi_reg_num = regno; add_cfi (cfi); + update_row_reg_save (cur_row, regno, NULL); } /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_WINDOW_SAVE. |