]>
Commit | Line | Data |
---|---|---|
513f8ca4 MT |
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) |