]> git.ipfire.org Git - people/amarx/ipfire-3.x.git/blob - gcc/patches/gcc49-aarch64-unwind-opt.patch0
util-linux: Update to 2.27
[people/amarx/ipfire-3.x.git] / gcc / patches / gcc49-aarch64-unwind-opt.patch0
1 2014-08-08 Richard Henderson <rth@redhat.com>
2
3 * config/aarch64/aarch64.c (aarch64_save_or_restore_fprs): Add
4 cfi_ops argument, for restore put REG_CFA_RESTORE notes into
5 *cfi_ops rather than on individual insns. Cleanup.
6 (aarch64_save_or_restore_callee_save_registers): Likewise.
7 (aarch64_expand_prologue): Adjust caller.
8 (aarch64_expand_epilogue): Likewise. Cleanup. Emit queued cfi_ops
9 on the stack restore insn.
10
11 --- gcc/config/aarch64/aarch64.c.jj 2014-07-08 17:38:17.398231989 +0200
12 +++ gcc/config/aarch64/aarch64.c 2014-08-13 10:02:45.599757706 +0200
13 @@ -1810,8 +1810,7 @@ aarch64_register_saved_on_entry (int reg
14
15 static void
16 aarch64_save_or_restore_fprs (int start_offset, int increment,
17 - bool restore, rtx base_rtx)
18 -
19 + bool restore, rtx base_rtx, rtx *cfi_ops)
20 {
21 unsigned regno;
22 unsigned regno2;
23 @@ -1819,16 +1818,16 @@ aarch64_save_or_restore_fprs (int start_
24 rtx (*gen_mem_ref)(enum machine_mode, rtx)
25 = (frame_pointer_needed)? gen_frame_mem : gen_rtx_MEM;
26
27 -
28 for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++)
29 {
30 if (aarch64_register_saved_on_entry (regno))
31 {
32 - rtx mem;
33 + rtx mem, reg1;
34 mem = gen_mem_ref (DFmode,
35 plus_constant (Pmode,
36 base_rtx,
37 start_offset));
38 + reg1 = gen_rtx_REG (DFmode, regno);
39
40 for (regno2 = regno + 1;
41 regno2 <= V31_REGNUM
42 @@ -1840,56 +1839,51 @@ aarch64_save_or_restore_fprs (int start_
43 if (regno2 <= V31_REGNUM &&
44 aarch64_register_saved_on_entry (regno2))
45 {
46 - rtx mem2;
47 + rtx mem2, reg2;
48 /* Next highest register to be saved. */
49 mem2 = gen_mem_ref (DFmode,
50 plus_constant
51 (Pmode,
52 base_rtx,
53 start_offset + increment));
54 + reg2 = gen_rtx_REG (DFmode, regno2);
55 +
56 if (restore == false)
57 {
58 - insn = emit_insn
59 - ( gen_store_pairdf (mem, gen_rtx_REG (DFmode, regno),
60 - mem2, gen_rtx_REG (DFmode, regno2)));
61 -
62 + insn = emit_insn (gen_store_pairdf (mem, reg1, mem2, reg2));
63 + /* The first part of a frame-related parallel insn
64 + is always assumed to be relevant to the frame
65 + calculations; subsequent parts, are only
66 + frame-related if explicitly marked. */
67 + RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1;
68 + RTX_FRAME_RELATED_P (insn) = 1;
69 }
70 else
71 {
72 - insn = emit_insn
73 - ( gen_load_pairdf (gen_rtx_REG (DFmode, regno), mem,
74 - gen_rtx_REG (DFmode, regno2), mem2));
75 -
76 - add_reg_note (insn, REG_CFA_RESTORE,
77 - gen_rtx_REG (DFmode, regno));
78 - add_reg_note (insn, REG_CFA_RESTORE,
79 - gen_rtx_REG (DFmode, regno2));
80 + emit_insn (gen_load_pairdf (reg1, mem, reg2, mem2));
81 + *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg1, *cfi_ops);
82 + *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg2, *cfi_ops);
83 }
84
85 - /* The first part of a frame-related parallel insn
86 - is always assumed to be relevant to the frame
87 - calculations; subsequent parts, are only
88 - frame-related if explicitly marked. */
89 - RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1;
90 regno = regno2;
91 start_offset += increment * 2;
92 }
93 else
94 {
95 if (restore == false)
96 - insn = emit_move_insn (mem, gen_rtx_REG (DFmode, regno));
97 + {
98 + insn = emit_move_insn (mem, reg1);
99 + RTX_FRAME_RELATED_P (insn) = 1;
100 + }
101 else
102 {
103 - insn = emit_move_insn (gen_rtx_REG (DFmode, regno), mem);
104 - add_reg_note (insn, REG_CFA_RESTORE,
105 - gen_rtx_REG (DImode, regno));
106 + emit_move_insn (reg1, mem);
107 + *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg1, *cfi_ops);
108 }
109 start_offset += increment;
110 }
111 - RTX_FRAME_RELATED_P (insn) = 1;
112 }
113 }
114 -
115 }
116
117
118 @@ -1897,13 +1891,14 @@ aarch64_save_or_restore_fprs (int start_
119 restore's have to happen. */
120 static void
121 aarch64_save_or_restore_callee_save_registers (HOST_WIDE_INT offset,
122 - bool restore)
123 + bool restore, rtx *cfi_ops)
124 {
125 rtx insn;
126 rtx base_rtx = stack_pointer_rtx;
127 HOST_WIDE_INT start_offset = offset;
128 HOST_WIDE_INT increment = UNITS_PER_WORD;
129 - rtx (*gen_mem_ref)(enum machine_mode, rtx) = (frame_pointer_needed)? gen_frame_mem : gen_rtx_MEM;
130 + rtx (*gen_mem_ref)(enum machine_mode, rtx)
131 + = (frame_pointer_needed)? gen_frame_mem : gen_rtx_MEM;
132 unsigned limit = (frame_pointer_needed)? R28_REGNUM: R30_REGNUM;
133 unsigned regno;
134 unsigned regno2;
135 @@ -1912,11 +1907,13 @@ aarch64_save_or_restore_callee_save_regi
136 {
137 if (aarch64_register_saved_on_entry (regno))
138 {
139 - rtx mem;
140 + rtx mem, reg1;
141 +
142 mem = gen_mem_ref (Pmode,
143 plus_constant (Pmode,
144 base_rtx,
145 start_offset));
146 + reg1 = gen_rtx_REG (DImode, regno);
147
148 for (regno2 = regno + 1;
149 regno2 <= limit
150 @@ -1928,56 +1925,54 @@ aarch64_save_or_restore_callee_save_regi
151 if (regno2 <= limit &&
152 aarch64_register_saved_on_entry (regno2))
153 {
154 - rtx mem2;
155 + rtx mem2, reg2;
156 /* Next highest register to be saved. */
157 mem2 = gen_mem_ref (Pmode,
158 plus_constant
159 (Pmode,
160 base_rtx,
161 start_offset + increment));
162 + reg2 = gen_rtx_REG (DImode, regno2);
163 +
164 if (restore == false)
165 {
166 - insn = emit_insn
167 - ( gen_store_pairdi (mem, gen_rtx_REG (DImode, regno),
168 - mem2, gen_rtx_REG (DImode, regno2)));
169 -
170 + insn = emit_insn (gen_store_pairdi (mem, reg1, mem2, reg2));
171 + /* The first part of a frame-related parallel insn
172 + is always assumed to be relevant to the frame
173 + calculations; subsequent parts, are only
174 + frame-related if explicitly marked. */
175 + RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1;
176 + RTX_FRAME_RELATED_P (insn) = 1;
177 }
178 else
179 {
180 - insn = emit_insn
181 - ( gen_load_pairdi (gen_rtx_REG (DImode, regno), mem,
182 - gen_rtx_REG (DImode, regno2), mem2));
183 -
184 - add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, regno));
185 - add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, regno2));
186 + emit_insn (gen_load_pairdi (reg1, mem, reg2, mem2));
187 + *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg1, *cfi_ops);
188 + *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg2, *cfi_ops);
189 }
190
191 - /* The first part of a frame-related parallel insn
192 - is always assumed to be relevant to the frame
193 - calculations; subsequent parts, are only
194 - frame-related if explicitly marked. */
195 - RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0,
196 - 1)) = 1;
197 regno = regno2;
198 start_offset += increment * 2;
199 }
200 else
201 {
202 if (restore == false)
203 - insn = emit_move_insn (mem, gen_rtx_REG (DImode, regno));
204 + {
205 + insn = emit_move_insn (mem, reg1);
206 + RTX_FRAME_RELATED_P (insn) = 1;
207 + }
208 else
209 {
210 - insn = emit_move_insn (gen_rtx_REG (DImode, regno), mem);
211 - add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, regno));
212 + emit_move_insn (reg1, mem);
213 + *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg1, *cfi_ops);
214 }
215 start_offset += increment;
216 }
217 - RTX_FRAME_RELATED_P (insn) = 1;
218 }
219 }
220
221 - aarch64_save_or_restore_fprs (start_offset, increment, restore, base_rtx);
222 -
223 + aarch64_save_or_restore_fprs (start_offset, increment, restore,
224 + base_rtx, cfi_ops);
225 }
226
227 /* AArch64 stack frames generated by this compiler look like:
228 @@ -2179,7 +2174,7 @@ aarch64_expand_prologue (void)
229 }
230
231 aarch64_save_or_restore_callee_save_registers
232 - (fp_offset + cfun->machine->frame.hardfp_offset, 0);
233 + (fp_offset + cfun->machine->frame.hardfp_offset, 0, NULL);
234 }
235
236 /* when offset >= 512,
237 @@ -2248,15 +2243,18 @@ aarch64_expand_epilogue (bool for_sibcal
238 insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
239 hard_frame_pointer_rtx,
240 GEN_INT (- fp_offset)));
241 + /* CFA should be calculated from the value of SP from now on. */
242 + add_reg_note (insn, REG_CFA_ADJUST_CFA,
243 + gen_rtx_SET (VOIDmode, stack_pointer_rtx,
244 + plus_constant (Pmode, hard_frame_pointer_rtx,
245 + -fp_offset)));
246 RTX_FRAME_RELATED_P (insn) = 1;
247 - /* As SP is set to (FP - fp_offset), according to the rules in
248 - dwarf2cfi.c:dwarf2out_frame_debug_expr, CFA should be calculated
249 - from the value of SP from now on. */
250 cfa_reg = stack_pointer_rtx;
251 }
252
253 + rtx cfi_ops = NULL;
254 aarch64_save_or_restore_callee_save_registers
255 - (fp_offset + cfun->machine->frame.hardfp_offset, 1);
256 + (fp_offset + cfun->machine->frame.hardfp_offset, 1, &cfi_ops);
257
258 /* Restore the frame pointer and lr if the frame pointer is needed. */
259 if (offset > 0)
260 @@ -2264,6 +2262,8 @@ aarch64_expand_epilogue (bool for_sibcal
261 if (frame_pointer_needed)
262 {
263 rtx mem_fp, mem_lr;
264 + rtx reg_fp = hard_frame_pointer_rtx;
265 + rtx reg_lr = gen_rtx_REG (DImode, LR_REGNUM);
266
267 if (fp_offset)
268 {
269 @@ -2276,52 +2276,36 @@ aarch64_expand_epilogue (bool for_sibcal
270 stack_pointer_rtx,
271 fp_offset
272 + UNITS_PER_WORD));
273 - insn = emit_insn (gen_load_pairdi (hard_frame_pointer_rtx,
274 - mem_fp,
275 - gen_rtx_REG (DImode,
276 - LR_REGNUM),
277 - mem_lr));
278 + emit_insn (gen_load_pairdi (reg_fp, mem_fp, reg_lr, mem_lr));
279 +
280 + insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
281 + GEN_INT (offset)));
282 }
283 else
284 {
285 insn = emit_insn (gen_loadwb_pairdi_di
286 - (stack_pointer_rtx,
287 - stack_pointer_rtx,
288 - hard_frame_pointer_rtx,
289 - gen_rtx_REG (DImode, LR_REGNUM),
290 - GEN_INT (offset),
291 + (stack_pointer_rtx, stack_pointer_rtx,
292 + reg_fp, reg_lr, GEN_INT (offset),
293 GEN_INT (GET_MODE_SIZE (DImode) + offset)));
294 - RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 2)) = 1;
295 - add_reg_note (insn, REG_CFA_ADJUST_CFA,
296 - (gen_rtx_SET (Pmode, stack_pointer_rtx,
297 - plus_constant (Pmode, cfa_reg,
298 - offset))));
299 - }
300 -
301 - /* The first part of a frame-related parallel insn
302 - is always assumed to be relevant to the frame
303 - calculations; subsequent parts, are only
304 - frame-related if explicitly marked. */
305 - RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1;
306 - RTX_FRAME_RELATED_P (insn) = 1;
307 - add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
308 - add_reg_note (insn, REG_CFA_RESTORE,
309 - gen_rtx_REG (DImode, LR_REGNUM));
310 -
311 - if (fp_offset)
312 - {
313 - insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
314 - GEN_INT (offset)));
315 - RTX_FRAME_RELATED_P (insn) = 1;
316 }
317 + cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg_fp, cfi_ops);
318 + cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg_lr, cfi_ops);
319 }
320 else
321 {
322 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
323 GEN_INT (offset)));
324 - RTX_FRAME_RELATED_P (insn) = 1;
325 }
326 + cfi_ops = alloc_reg_note (REG_CFA_ADJUST_CFA,
327 + gen_rtx_SET (VOIDmode, stack_pointer_rtx,
328 + plus_constant (Pmode, cfa_reg,
329 + offset)),
330 + cfi_ops);
331 + REG_NOTES (insn) = cfi_ops;
332 + RTX_FRAME_RELATED_P (insn) = 1;
333 }
334 + else
335 + gcc_assert (cfi_ops == NULL);
336
337 /* Stack adjustment for exception handler. */
338 if (crtl->calls_eh_return)