summaryrefslogtreecommitdiff
path: root/patches/gcc/4.8.4/001_gcc_bug_62231.patch
blob: e7c9cf9777e70d9367d1f2a07810c29dcd1e363a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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.