]> git.pld-linux.org Git - packages/cross-gcc.git/blob - gcc49-aarch64-unwind-opt.patch
new package
[packages/cross-gcc.git] / gcc49-aarch64-unwind-opt.patch
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)
This page took 0.114732 seconds and 3 git commands to generate.