crosstool-ng/patches/gcc/4.9.4/001-gcc_bug_62231.patch

130 lines
4.3 KiB
Diff
Raw Normal View History

As-applied. From:
https://gcc.gnu.org/ml/gcc-patches/2014-09/msg02625.html
Linked from bug62231 comment 4 there
diff -durN a/gcc/defaults.h b/gcc/defaults.h
--- a/gcc/defaults.h 2013-01-10 12:38:27.000000000 -0800
+++ b/gcc/defaults.h 2014-12-15 13:26:13.498904465 -0800
@@ -438,6 +438,11 @@
#define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG)
#endif
+/* The mapping from dwarf CFA reg number to internal dwarf reg numbers. */
+#ifndef DWARF_REG_TO_UNWIND_COLUMN
+#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
+#endif
+
/* Map register numbers held in the call frame info that gcc has
collected using DWARF_FRAME_REGNUM to those that should be output in
.debug_frame and .eh_frame. */
diff -durN a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
--- a/gcc/dwarf2cfi.c 2013-01-10 12:38:27.000000000 -0800
+++ b/gcc/dwarf2cfi.c 2014-12-15 13:50:24.554883694 -0800
@@ -225,7 +225,44 @@
emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
}
-/* Generate code to initialize the register size table. */
+/* Helper for expand_builtin_init_dwarf_reg_sizes. Generate code to
+ initialize the dwarf register size table entry corresponding to register
+ REGNO in REGMODE. TABLE is the table base address, SLOTMODE is the mode
+ to use for the size entry to initialize, and WROTE_RETURN_COLUMN needs to
+ be set to true if the dwarf register number for REGNO is the dwarf return
+ column number. */
+
+static
+void init_one_dwarf_reg_size (int regno, enum machine_mode regmode,
+ rtx table, enum machine_mode slotmode,
+ bool *wrote_return_column)
+{
+ const unsigned int dnum = DWARF_FRAME_REGNUM (regno);
+ const unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
+ const unsigned int dcol = DWARF_REG_TO_UNWIND_COLUMN (rnum);
+
+ const HOST_WIDE_INT slotoffset = dcol * GET_MODE_SIZE (slotmode);
+ const HOST_WIDE_INT regsize = GET_MODE_SIZE (regmode);
+
+ if (rnum >= DWARF_FRAME_REGISTERS)
+ return;
+
+ if (dnum == DWARF_FRAME_RETURN_COLUMN)
+ {
+ if (regmode == VOIDmode)
+ return;
+ *wrote_return_column = true;
+ }
+
+ if (slotoffset < 0)
+ return;
+
+ emit_move_insn (adjust_address (table, slotmode, slotoffset),
+ gen_int_mode (regsize, slotmode));
+}
+
+/* Generate code to initialize the dwarf register size table located
+ at the provided ADDRESS. */
void
expand_builtin_init_dwarf_reg_sizes (tree address)
@@ -238,30 +275,21 @@
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
- unsigned int dnum = DWARF_FRAME_REGNUM (i);
- unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
-
- if (rnum < DWARF_FRAME_REGISTERS)
- {
- HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (mode);
- enum machine_mode save_mode = reg_raw_mode[i];
- HOST_WIDE_INT size;
-
- if (HARD_REGNO_CALL_PART_CLOBBERED (i, save_mode))
- save_mode = choose_hard_reg_mode (i, 1, true);
- if (dnum == DWARF_FRAME_RETURN_COLUMN)
- {
- if (save_mode == VOIDmode)
- continue;
- wrote_return_column = true;
- }
- size = GET_MODE_SIZE (save_mode);
- if (offset < 0)
- continue;
+ enum machine_mode save_mode = reg_raw_mode[i];
+ rtx span;
- emit_move_insn (adjust_address (mem, mode, offset),
- gen_int_mode (size, mode));
- }
+ span = targetm.dwarf_register_span (gen_rtx_REG (save_mode, i));
+ if (!span)
+ init_one_dwarf_reg_size (i, save_mode, mem, mode, &wrote_return_column);
+ else
+ {
+ for (int si = 0; si < XVECLEN (span, 0); si++)
+ {
+ rtx reg = XVECEXP (span, 0, si);
+ init_one_dwarf_reg_size
+ (REGNO (reg), GET_MODE (reg), mem, mode, &wrote_return_column);
+ }
+ }
}
if (!wrote_return_column)
diff -durN a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
--- a/libgcc/unwind-dw2.c 2013-05-31 16:21:46.000000000 -0700
+++ b/libgcc/unwind-dw2.c 2014-12-15 13:26:13.570904866 -0800
@@ -55,10 +55,6 @@
#define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
#endif
-#ifndef DWARF_REG_TO_UNWIND_COLUMN
-#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
-#endif
-
/* ??? For the public function interfaces, we tend to gcc_assert that the
column numbers are in range. For the dwarf2 unwind info this does happen,
although so far in a case that doesn't actually matter.