]> git.pld-linux.org Git - packages/cross-gcc.git/blame - gcc49-aarch64-unwind-opt.patch
- unconditional noarch subpackages
[packages/cross-gcc.git] / gcc49-aarch64-unwind-opt.patch
CommitLineData
b5b0b447
ER
12014-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)
This page took 0.114425 seconds and 4 git commands to generate.