diff options
Diffstat (limited to 'recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99323.patch')
-rw-r--r-- | recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99323.patch | 688 |
1 files changed, 688 insertions, 0 deletions
diff --git a/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99323.patch b/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99323.patch new file mode 100644 index 0000000000..38b6fa3f0e --- /dev/null +++ b/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99323.patch | |||
@@ -0,0 +1,688 @@ | |||
1 | Vladimir Prus <vladimir@codesourcery.com> | ||
2 | Julian Brown <julian@codesourcery.com> | ||
3 | |||
4 | gcc/ | ||
5 | * config/arm/arm.c (arm_override_options): Warn if mlow-irq-latency is | ||
6 | specified in Thumb mode. | ||
7 | (load_multiple_sequence): Return 0 if low irq latency is requested. | ||
8 | (store_multiple_sequence): Likewise. | ||
9 | (arm_gen_load_multiple): Load registers one-by-one if low irq latency | ||
10 | is requested. | ||
11 | (arm_gen_store_multiple): Likewise. | ||
12 | (vfp_output_fldmd): When low_irq_latency is non zero, pop each | ||
13 | register separately. | ||
14 | (vfp_emit_fstmd): When low_irq_latency is non zero, save each register | ||
15 | separately. | ||
16 | (arm_get_vfp_saved_size): Adjust saved register size calculation for | ||
17 | the above changes. | ||
18 | (print_pop_reg_by_ldr): New. | ||
19 | (arm_output_epilogue): Use print_pop_reg_by_ldr when low irq latency | ||
20 | is requested. | ||
21 | (emit_multi_reg_push): Push registers separately if low irq latency | ||
22 | is requested. | ||
23 | * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Set __low_irq_latency__. | ||
24 | (low_irq_latency): Define. | ||
25 | (USE_RETURN_INSN): Don't use return insn when low irq latency is | ||
26 | requested. | ||
27 | * config/arm/lib1funcs.asm (do_pop, do_push): Define as variadic | ||
28 | macros. When __low_irq_latency__ is defined, push and pop registers | ||
29 | individually. | ||
30 | (div0): Use correct punctuation. | ||
31 | * config/arm/ieee754-df.S: Adjust syntax of using do_push. | ||
32 | * config/arm/ieee754-sf.S: Likewise. | ||
33 | * config/arm/bpabi.S: Likewise. | ||
34 | * config/arm/arm.opt (mlow-irq-latency): New option. | ||
35 | * config/arm/predicates.md (load_multiple_operation): Return false is | ||
36 | low irq latency is requested. | ||
37 | (store_multiple_operation): Likewise. | ||
38 | * config/arm/arm.md (movmemqi): Don't use it if low irq latency is | ||
39 | requested. | ||
40 | * doc/invoke.texi (-mlow-irq-latency): Add documentation. | ||
41 | |||
42 | 2010-07-26 Julian Brown <julian@codesourcery.com> | ||
43 | |||
44 | Merge from Sourcery G++ 4.4: | ||
45 | |||
46 | 2007-06-06 Joseph Myers <joseph@codesourcery.com> | ||
47 | |||
48 | gcc/ | ||
49 | |||
50 | === modified file 'gcc/config/arm/arm.c' | ||
51 | --- old/gcc/config/arm/arm.c 2010-08-05 14:33:31 +0000 | ||
52 | +++ new/gcc/config/arm/arm.c 2010-08-05 15:20:54 +0000 | ||
53 | @@ -1884,6 +1884,13 @@ | ||
54 | |||
55 | /* Register global variables with the garbage collector. */ | ||
56 | arm_add_gc_roots (); | ||
57 | + | ||
58 | + if (low_irq_latency && TARGET_THUMB) | ||
59 | + { | ||
60 | + warning (0, | ||
61 | + "-mlow-irq-latency has no effect when compiling for Thumb"); | ||
62 | + low_irq_latency = 0; | ||
63 | + } | ||
64 | } | ||
65 | |||
66 | static void | ||
67 | @@ -9053,6 +9060,9 @@ | ||
68 | int base_reg = -1; | ||
69 | int i; | ||
70 | |||
71 | + if (low_irq_latency) | ||
72 | + return 0; | ||
73 | + | ||
74 | /* Can only handle 2, 3, or 4 insns at present, | ||
75 | though could be easily extended if required. */ | ||
76 | gcc_assert (nops >= 2 && nops <= 4); | ||
77 | @@ -9282,6 +9292,9 @@ | ||
78 | int base_reg = -1; | ||
79 | int i; | ||
80 | |||
81 | + if (low_irq_latency) | ||
82 | + return 0; | ||
83 | + | ||
84 | /* Can only handle 2, 3, or 4 insns at present, though could be easily | ||
85 | extended if required. */ | ||
86 | gcc_assert (nops >= 2 && nops <= 4); | ||
87 | @@ -9489,7 +9502,7 @@ | ||
88 | |||
89 | As a compromise, we use ldr for counts of 1 or 2 regs, and ldm | ||
90 | for counts of 3 or 4 regs. */ | ||
91 | - if (arm_tune_xscale && count <= 2 && ! optimize_size) | ||
92 | + if (low_irq_latency || (arm_tune_xscale && count <= 2 && ! optimize_size)) | ||
93 | { | ||
94 | rtx seq; | ||
95 | |||
96 | @@ -9552,7 +9565,7 @@ | ||
97 | |||
98 | /* See arm_gen_load_multiple for discussion of | ||
99 | the pros/cons of ldm/stm usage for XScale. */ | ||
100 | - if (arm_tune_xscale && count <= 2 && ! optimize_size) | ||
101 | + if (low_irq_latency || (arm_tune_xscale && count <= 2 && ! optimize_size)) | ||
102 | { | ||
103 | rtx seq; | ||
104 | |||
105 | @@ -11795,6 +11808,21 @@ | ||
106 | vfp_output_fldmd (FILE * stream, unsigned int base, int reg, int count) | ||
107 | { | ||
108 | int i; | ||
109 | + int offset; | ||
110 | + | ||
111 | + if (low_irq_latency) | ||
112 | + { | ||
113 | + /* Output a sequence of FLDD instructions. */ | ||
114 | + offset = 0; | ||
115 | + for (i = reg; i < reg + count; ++i, offset += 8) | ||
116 | + { | ||
117 | + fputc ('\t', stream); | ||
118 | + asm_fprintf (stream, "fldd\td%d, [%r,#%d]\n", i, base, offset); | ||
119 | + } | ||
120 | + asm_fprintf (stream, "\tadd\tsp, sp, #%d\n", count * 8); | ||
121 | + return; | ||
122 | + } | ||
123 | + | ||
124 | |||
125 | /* Workaround ARM10 VFPr1 bug. */ | ||
126 | if (count == 2 && !arm_arch6) | ||
127 | @@ -11865,6 +11893,56 @@ | ||
128 | rtx tmp, reg; | ||
129 | int i; | ||
130 | |||
131 | + if (low_irq_latency) | ||
132 | + { | ||
133 | + int saved_size; | ||
134 | + rtx sp_insn; | ||
135 | + | ||
136 | + if (!count) | ||
137 | + return 0; | ||
138 | + | ||
139 | + saved_size = count * GET_MODE_SIZE (DFmode); | ||
140 | + | ||
141 | + /* Since fstd does not have postdecrement addressing mode, | ||
142 | + we first decrement stack pointer and then use base+offset | ||
143 | + stores for VFP registers. The ARM EABI unwind information | ||
144 | + can't easily describe base+offset loads, so we attach | ||
145 | + a note for the effects of the whole block in the first insn, | ||
146 | + and avoid marking the subsequent instructions | ||
147 | + with RTX_FRAME_RELATED_P. */ | ||
148 | + sp_insn = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, | ||
149 | + GEN_INT (-saved_size)); | ||
150 | + sp_insn = emit_insn (sp_insn); | ||
151 | + RTX_FRAME_RELATED_P (sp_insn) = 1; | ||
152 | + | ||
153 | + dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1)); | ||
154 | + XVECEXP (dwarf, 0, 0) = | ||
155 | + gen_rtx_SET (VOIDmode, stack_pointer_rtx, | ||
156 | + plus_constant (stack_pointer_rtx, -saved_size)); | ||
157 | + | ||
158 | + /* push double VFP registers to stack */ | ||
159 | + for (i = 0; i < count; ++i ) | ||
160 | + { | ||
161 | + rtx reg; | ||
162 | + rtx mem; | ||
163 | + rtx addr; | ||
164 | + rtx insn; | ||
165 | + reg = gen_rtx_REG (DFmode, base_reg + 2*i); | ||
166 | + addr = (i == 0) ? stack_pointer_rtx | ||
167 | + : gen_rtx_PLUS (SImode, stack_pointer_rtx, | ||
168 | + GEN_INT (i * GET_MODE_SIZE (DFmode))); | ||
169 | + mem = gen_frame_mem (DFmode, addr); | ||
170 | + insn = emit_move_insn (mem, reg); | ||
171 | + XVECEXP (dwarf, 0, i+1) = | ||
172 | + gen_rtx_SET (VOIDmode, mem, reg); | ||
173 | + } | ||
174 | + | ||
175 | + REG_NOTES (sp_insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf, | ||
176 | + REG_NOTES (sp_insn)); | ||
177 | + | ||
178 | + return saved_size; | ||
179 | + } | ||
180 | + | ||
181 | /* Workaround ARM10 VFPr1 bug. Data corruption can occur when exactly two | ||
182 | register pairs are stored by a store multiple insn. We avoid this | ||
183 | by pushing an extra pair. */ | ||
184 | @@ -13307,7 +13385,7 @@ | ||
185 | if (count > 0) | ||
186 | { | ||
187 | /* Workaround ARM10 VFPr1 bug. */ | ||
188 | - if (count == 2 && !arm_arch6) | ||
189 | + if (count == 2 && !arm_arch6 && !low_irq_latency) | ||
190 | count++; | ||
191 | saved += count * 8; | ||
192 | } | ||
193 | @@ -13645,6 +13723,41 @@ | ||
194 | |||
195 | } | ||
196 | |||
197 | +/* Generate to STREAM a code sequence that pops registers identified | ||
198 | + in REGS_MASK from SP. SP is incremented as the result. | ||
199 | +*/ | ||
200 | +static void | ||
201 | +print_pop_reg_by_ldr (FILE *stream, int regs_mask, int rfe) | ||
202 | +{ | ||
203 | + int reg; | ||
204 | + | ||
205 | + gcc_assert (! (regs_mask & (1 << SP_REGNUM))); | ||
206 | + | ||
207 | + for (reg = 0; reg < PC_REGNUM; ++reg) | ||
208 | + if (regs_mask & (1 << reg)) | ||
209 | + asm_fprintf (stream, "\tldr\t%r, [%r], #4\n", | ||
210 | + reg, SP_REGNUM); | ||
211 | + | ||
212 | + if (regs_mask & (1 << PC_REGNUM)) | ||
213 | + { | ||
214 | + if (rfe) | ||
215 | + /* When returning from exception, we need to | ||
216 | + copy SPSR to CPSR. There are two ways to do | ||
217 | + that: the ldm instruction with "^" suffix, | ||
218 | + and movs instruction. The latter would | ||
219 | + require that we load from stack to some | ||
220 | + scratch register, and then move to PC. | ||
221 | + Therefore, we'd need extra instruction and | ||
222 | + have to make sure we actually have a spare | ||
223 | + register. Using ldm with a single register | ||
224 | + is simler. */ | ||
225 | + asm_fprintf (stream, "\tldm\tsp!, {pc}^\n"); | ||
226 | + else | ||
227 | + asm_fprintf (stream, "\tldr\t%r, [%r], #4\n", | ||
228 | + PC_REGNUM, SP_REGNUM); | ||
229 | + } | ||
230 | +} | ||
231 | + | ||
232 | const char * | ||
233 | arm_output_epilogue (rtx sibling) | ||
234 | { | ||
235 | @@ -14018,22 +14131,19 @@ | ||
236 | to load use the LDR instruction - it is faster. For Thumb-2 | ||
237 | always use pop and the assembler will pick the best instruction.*/ | ||
238 | if (TARGET_ARM && saved_regs_mask == (1 << LR_REGNUM) | ||
239 | - && !IS_INTERRUPT(func_type)) | ||
240 | + && !IS_INTERRUPT (func_type)) | ||
241 | { | ||
242 | asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM); | ||
243 | } | ||
244 | else if (saved_regs_mask) | ||
245 | { | ||
246 | - if (saved_regs_mask & (1 << SP_REGNUM)) | ||
247 | - /* Note - write back to the stack register is not enabled | ||
248 | - (i.e. "ldmfd sp!..."). We know that the stack pointer is | ||
249 | - in the list of registers and if we add writeback the | ||
250 | - instruction becomes UNPREDICTABLE. */ | ||
251 | - print_multi_reg (f, "ldmfd\t%r, ", SP_REGNUM, saved_regs_mask, | ||
252 | - rfe); | ||
253 | - else if (TARGET_ARM) | ||
254 | - print_multi_reg (f, "ldmfd\t%r!, ", SP_REGNUM, saved_regs_mask, | ||
255 | - rfe); | ||
256 | + gcc_assert ( ! (saved_regs_mask & (1 << SP_REGNUM))); | ||
257 | + if (TARGET_ARM) | ||
258 | + if (low_irq_latency) | ||
259 | + print_pop_reg_by_ldr (f, saved_regs_mask, rfe); | ||
260 | + else | ||
261 | + print_multi_reg (f, "ldmfd\t%r!, ", SP_REGNUM, saved_regs_mask, | ||
262 | + rfe); | ||
263 | else | ||
264 | print_multi_reg (f, "pop\t", SP_REGNUM, saved_regs_mask, 0); | ||
265 | } | ||
266 | @@ -14154,6 +14264,32 @@ | ||
267 | |||
268 | gcc_assert (num_regs && num_regs <= 16); | ||
269 | |||
270 | + if (low_irq_latency) | ||
271 | + { | ||
272 | + rtx insn = 0; | ||
273 | + | ||
274 | + /* Emit a series of ldr instructions rather rather than a single ldm. */ | ||
275 | + /* TODO: Use ldrd where possible. */ | ||
276 | + gcc_assert (! (mask & (1 << SP_REGNUM))); | ||
277 | + | ||
278 | + for (i = LAST_ARM_REGNUM; i >= 0; --i) | ||
279 | + { | ||
280 | + if (mask & (1 << i)) | ||
281 | + | ||
282 | + { | ||
283 | + rtx reg, where, mem; | ||
284 | + | ||
285 | + reg = gen_rtx_REG (SImode, i); | ||
286 | + where = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx); | ||
287 | + mem = gen_rtx_MEM (SImode, where); | ||
288 | + insn = emit_move_insn (mem, reg); | ||
289 | + RTX_FRAME_RELATED_P (insn) = 1; | ||
290 | + } | ||
291 | + } | ||
292 | + | ||
293 | + return insn; | ||
294 | + } | ||
295 | + | ||
296 | /* We don't record the PC in the dwarf frame information. */ | ||
297 | num_dwarf_regs = num_regs; | ||
298 | if (mask & (1 << PC_REGNUM)) | ||
299 | |||
300 | === modified file 'gcc/config/arm/arm.h' | ||
301 | --- old/gcc/config/arm/arm.h 2010-08-05 14:33:31 +0000 | ||
302 | +++ new/gcc/config/arm/arm.h 2010-08-05 15:20:54 +0000 | ||
303 | @@ -101,6 +101,8 @@ | ||
304 | builtin_define ("__ARM_PCS"); \ | ||
305 | builtin_define ("__ARM_EABI__"); \ | ||
306 | } \ | ||
307 | + if (low_irq_latency) \ | ||
308 | + builtin_define ("__low_irq_latency__"); \ | ||
309 | } while (0) | ||
310 | |||
311 | /* The various ARM cores. */ | ||
312 | @@ -449,6 +451,10 @@ | ||
313 | /* Nonzero if chip supports integer division instruction. */ | ||
314 | extern int arm_arch_hwdiv; | ||
315 | |||
316 | +/* Nonzero if we should minimize interrupt latency of the | ||
317 | + generated code. */ | ||
318 | +extern int low_irq_latency; | ||
319 | + | ||
320 | #ifndef TARGET_DEFAULT | ||
321 | #define TARGET_DEFAULT (MASK_APCS_FRAME) | ||
322 | #endif | ||
323 | @@ -1823,9 +1829,10 @@ | ||
324 | /* Determine if the epilogue should be output as RTL. | ||
325 | You should override this if you define FUNCTION_EXTRA_EPILOGUE. */ | ||
326 | /* This is disabled for Thumb-2 because it will confuse the | ||
327 | - conditional insn counter. */ | ||
328 | + conditional insn counter. | ||
329 | + Do not use a return insn if we're avoiding ldm/stm instructions. */ | ||
330 | #define USE_RETURN_INSN(ISCOND) \ | ||
331 | - (TARGET_ARM ? use_return_insn (ISCOND, NULL) : 0) | ||
332 | + ((TARGET_ARM && !low_irq_latency) ? use_return_insn (ISCOND, NULL) : 0) | ||
333 | |||
334 | /* Definitions for register eliminations. | ||
335 | |||
336 | |||
337 | === modified file 'gcc/config/arm/arm.md' | ||
338 | --- old/gcc/config/arm/arm.md 2010-08-05 12:06:40 +0000 | ||
339 | +++ new/gcc/config/arm/arm.md 2010-08-05 15:20:54 +0000 | ||
340 | @@ -6587,7 +6587,7 @@ | ||
341 | (match_operand:BLK 1 "general_operand" "") | ||
342 | (match_operand:SI 2 "const_int_operand" "") | ||
343 | (match_operand:SI 3 "const_int_operand" "")] | ||
344 | - "TARGET_EITHER" | ||
345 | + "TARGET_EITHER && !low_irq_latency" | ||
346 | " | ||
347 | if (TARGET_32BIT) | ||
348 | { | ||
349 | |||
350 | === modified file 'gcc/config/arm/arm.opt' | ||
351 | --- old/gcc/config/arm/arm.opt 2009-06-18 11:24:10 +0000 | ||
352 | +++ new/gcc/config/arm/arm.opt 2010-08-05 15:20:54 +0000 | ||
353 | @@ -161,6 +161,10 @@ | ||
354 | Target Report Mask(NEON_VECTORIZE_QUAD) | ||
355 | Use Neon quad-word (rather than double-word) registers for vectorization | ||
356 | |||
357 | +mlow-irq-latency | ||
358 | +Target Report Var(low_irq_latency) | ||
359 | +Try to reduce interrupt latency of the generated code | ||
360 | + | ||
361 | mword-relocations | ||
362 | Target Report Var(target_word_relocations) Init(TARGET_DEFAULT_WORD_RELOCATIONS) | ||
363 | Only generate absolute relocations on word sized values. | ||
364 | |||
365 | === modified file 'gcc/config/arm/bpabi.S' | ||
366 | --- old/gcc/config/arm/bpabi.S 2009-12-17 15:37:23 +0000 | ||
367 | +++ new/gcc/config/arm/bpabi.S 2010-08-05 15:20:54 +0000 | ||
368 | @@ -116,16 +116,17 @@ | ||
369 | test_div_by_zero signed | ||
370 | |||
371 | sub sp, sp, #8 | ||
372 | -#if defined(__thumb2__) | ||
373 | +/* Low latency and Thumb-2 do_push implementations can't push sp directly. */ | ||
374 | +#if defined(__thumb2__) || defined(__irq_low_latency__) | ||
375 | mov ip, sp | ||
376 | - push {ip, lr} | ||
377 | + do_push (ip, lr) | ||
378 | #else | ||
379 | - do_push {sp, lr} | ||
380 | + stmfd sp!, {sp, lr} | ||
381 | #endif | ||
382 | bl SYM(__gnu_ldivmod_helper) __PLT__ | ||
383 | ldr lr, [sp, #4] | ||
384 | add sp, sp, #8 | ||
385 | - do_pop {r2, r3} | ||
386 | + do_pop (r2, r3) | ||
387 | RET | ||
388 | |||
389 | #endif /* L_aeabi_ldivmod */ | ||
390 | @@ -136,16 +137,17 @@ | ||
391 | test_div_by_zero unsigned | ||
392 | |||
393 | sub sp, sp, #8 | ||
394 | -#if defined(__thumb2__) | ||
395 | +/* Low latency and Thumb-2 do_push implementations can't push sp directly. */ | ||
396 | +#if defined(__thumb2__) || defined(__irq_low_latency__) | ||
397 | mov ip, sp | ||
398 | - push {ip, lr} | ||
399 | + do_push (ip, lr) | ||
400 | #else | ||
401 | - do_push {sp, lr} | ||
402 | + stmfd sp!, {sp, lr} | ||
403 | #endif | ||
404 | bl SYM(__gnu_uldivmod_helper) __PLT__ | ||
405 | ldr lr, [sp, #4] | ||
406 | add sp, sp, #8 | ||
407 | - do_pop {r2, r3} | ||
408 | + do_pop (r2, r3) | ||
409 | RET | ||
410 | |||
411 | #endif /* L_aeabi_divmod */ | ||
412 | |||
413 | === modified file 'gcc/config/arm/ieee754-df.S' | ||
414 | --- old/gcc/config/arm/ieee754-df.S 2009-06-05 12:52:36 +0000 | ||
415 | +++ new/gcc/config/arm/ieee754-df.S 2010-08-05 15:20:54 +0000 | ||
416 | @@ -83,7 +83,7 @@ | ||
417 | ARM_FUNC_START adddf3 | ||
418 | ARM_FUNC_ALIAS aeabi_dadd adddf3 | ||
419 | |||
420 | -1: do_push {r4, r5, lr} | ||
421 | +1: do_push (r4, r5, lr) | ||
422 | |||
423 | @ Look for zeroes, equal values, INF, or NAN. | ||
424 | shift1 lsl, r4, xh, #1 | ||
425 | @@ -427,7 +427,7 @@ | ||
426 | do_it eq, t | ||
427 | moveq r1, #0 | ||
428 | RETc(eq) | ||
429 | - do_push {r4, r5, lr} | ||
430 | + do_push (r4, r5, lr) | ||
431 | mov r4, #0x400 @ initial exponent | ||
432 | add r4, r4, #(52-1 - 1) | ||
433 | mov r5, #0 @ sign bit is 0 | ||
434 | @@ -447,7 +447,7 @@ | ||
435 | do_it eq, t | ||
436 | moveq r1, #0 | ||
437 | RETc(eq) | ||
438 | - do_push {r4, r5, lr} | ||
439 | + do_push (r4, r5, lr) | ||
440 | mov r4, #0x400 @ initial exponent | ||
441 | add r4, r4, #(52-1 - 1) | ||
442 | ands r5, r0, #0x80000000 @ sign bit in r5 | ||
443 | @@ -481,7 +481,7 @@ | ||
444 | RETc(eq) @ we are done already. | ||
445 | |||
446 | @ value was denormalized. We can normalize it now. | ||
447 | - do_push {r4, r5, lr} | ||
448 | + do_push (r4, r5, lr) | ||
449 | mov r4, #0x380 @ setup corresponding exponent | ||
450 | and r5, xh, #0x80000000 @ move sign bit in r5 | ||
451 | bic xh, xh, #0x80000000 | ||
452 | @@ -508,9 +508,9 @@ | ||
453 | @ compatibility. | ||
454 | adr ip, LSYM(f0_ret) | ||
455 | @ Push pc as well so that RETLDM works correctly. | ||
456 | - do_push {r4, r5, ip, lr, pc} | ||
457 | + do_push (r4, r5, ip, lr, pc) | ||
458 | #else | ||
459 | - do_push {r4, r5, lr} | ||
460 | + do_push (r4, r5, lr) | ||
461 | #endif | ||
462 | |||
463 | mov r5, #0 | ||
464 | @@ -534,9 +534,9 @@ | ||
465 | @ compatibility. | ||
466 | adr ip, LSYM(f0_ret) | ||
467 | @ Push pc as well so that RETLDM works correctly. | ||
468 | - do_push {r4, r5, ip, lr, pc} | ||
469 | + do_push (r4, r5, ip, lr, pc) | ||
470 | #else | ||
471 | - do_push {r4, r5, lr} | ||
472 | + do_push (r4, r5, lr) | ||
473 | #endif | ||
474 | |||
475 | ands r5, ah, #0x80000000 @ sign bit in r5 | ||
476 | @@ -585,7 +585,7 @@ | ||
477 | @ Legacy code expects the result to be returned in f0. Copy it | ||
478 | @ there as well. | ||
479 | LSYM(f0_ret): | ||
480 | - do_push {r0, r1} | ||
481 | + do_push (r0, r1) | ||
482 | ldfd f0, [sp], #8 | ||
483 | RETLDM | ||
484 | |||
485 | @@ -602,7 +602,7 @@ | ||
486 | |||
487 | ARM_FUNC_START muldf3 | ||
488 | ARM_FUNC_ALIAS aeabi_dmul muldf3 | ||
489 | - do_push {r4, r5, r6, lr} | ||
490 | + do_push (r4, r5, r6, lr) | ||
491 | |||
492 | @ Mask out exponents, trap any zero/denormal/INF/NAN. | ||
493 | mov ip, #0xff | ||
494 | @@ -910,7 +910,7 @@ | ||
495 | ARM_FUNC_START divdf3 | ||
496 | ARM_FUNC_ALIAS aeabi_ddiv divdf3 | ||
497 | |||
498 | - do_push {r4, r5, r6, lr} | ||
499 | + do_push (r4, r5, r6, lr) | ||
500 | |||
501 | @ Mask out exponents, trap any zero/denormal/INF/NAN. | ||
502 | mov ip, #0xff | ||
503 | @@ -1195,7 +1195,7 @@ | ||
504 | |||
505 | @ The status-returning routines are required to preserve all | ||
506 | @ registers except ip, lr, and cpsr. | ||
507 | -6: do_push {r0, lr} | ||
508 | +6: do_push (r0, lr) | ||
509 | ARM_CALL cmpdf2 | ||
510 | @ Set the Z flag correctly, and the C flag unconditionally. | ||
511 | cmp r0, #0 | ||
512 | |||
513 | === modified file 'gcc/config/arm/ieee754-sf.S' | ||
514 | --- old/gcc/config/arm/ieee754-sf.S 2009-06-05 12:52:36 +0000 | ||
515 | +++ new/gcc/config/arm/ieee754-sf.S 2010-08-05 15:20:54 +0000 | ||
516 | @@ -481,7 +481,7 @@ | ||
517 | and r3, ip, #0x80000000 | ||
518 | |||
519 | @ Well, no way to make it shorter without the umull instruction. | ||
520 | - do_push {r3, r4, r5} | ||
521 | + do_push (r3, r4, r5) | ||
522 | mov r4, r0, lsr #16 | ||
523 | mov r5, r1, lsr #16 | ||
524 | bic r0, r0, r4, lsl #16 | ||
525 | @@ -492,7 +492,7 @@ | ||
526 | mla r0, r4, r1, r0 | ||
527 | adds r3, r3, r0, lsl #16 | ||
528 | adc r1, ip, r0, lsr #16 | ||
529 | - do_pop {r0, r4, r5} | ||
530 | + do_pop (r0, r4, r5) | ||
531 | |||
532 | #else | ||
533 | |||
534 | @@ -882,7 +882,7 @@ | ||
535 | |||
536 | @ The status-returning routines are required to preserve all | ||
537 | @ registers except ip, lr, and cpsr. | ||
538 | -6: do_push {r0, r1, r2, r3, lr} | ||
539 | +6: do_push (r0, r1, r2, r3, lr) | ||
540 | ARM_CALL cmpsf2 | ||
541 | @ Set the Z flag correctly, and the C flag unconditionally. | ||
542 | cmp r0, #0 | ||
543 | |||
544 | === modified file 'gcc/config/arm/lib1funcs.asm' | ||
545 | --- old/gcc/config/arm/lib1funcs.asm 2010-04-02 18:54:46 +0000 | ||
546 | +++ new/gcc/config/arm/lib1funcs.asm 2010-08-05 15:20:54 +0000 | ||
547 | @@ -254,8 +254,8 @@ | ||
548 | .macro shift1 op, arg0, arg1, arg2 | ||
549 | \op \arg0, \arg1, \arg2 | ||
550 | .endm | ||
551 | -#define do_push push | ||
552 | -#define do_pop pop | ||
553 | +#define do_push(...) push {__VA_ARGS__} | ||
554 | +#define do_pop(...) pop {__VA_ARGS__} | ||
555 | #define COND(op1, op2, cond) op1 ## op2 ## cond | ||
556 | /* Perform an arithmetic operation with a variable shift operand. This | ||
557 | requires two instructions and a scratch register on Thumb-2. */ | ||
558 | @@ -269,8 +269,42 @@ | ||
559 | .macro shift1 op, arg0, arg1, arg2 | ||
560 | mov \arg0, \arg1, \op \arg2 | ||
561 | .endm | ||
562 | -#define do_push stmfd sp!, | ||
563 | -#define do_pop ldmfd sp!, | ||
564 | +#if defined(__low_irq_latency__) | ||
565 | +#define do_push(...) \ | ||
566 | + _buildN1(do_push, _buildC1(__VA_ARGS__))( __VA_ARGS__) | ||
567 | +#define _buildN1(BASE, X) _buildN2(BASE, X) | ||
568 | +#define _buildN2(BASE, X) BASE##X | ||
569 | +#define _buildC1(...) _buildC2(__VA_ARGS__,9,8,7,6,5,4,3,2,1) | ||
570 | +#define _buildC2(a1,a2,a3,a4,a5,a6,a7,a8,a9,c,...) c | ||
571 | + | ||
572 | +#define do_push1(r1) str r1, [sp, #-4]! | ||
573 | +#define do_push2(r1, r2) str r2, [sp, #-4]! ; str r1, [sp, #-4]! | ||
574 | +#define do_push3(r1, r2, r3) str r3, [sp, #-4]! ; str r2, [sp, #-4]!; str r1, [sp, #-4]! | ||
575 | +#define do_push4(r1, r2, r3, r4) \ | ||
576 | + do_push3 (r2, r3, r4);\ | ||
577 | + do_push1 (r1) | ||
578 | +#define do_push5(r1, r2, r3, r4, r5) \ | ||
579 | + do_push4 (r2, r3, r4, r5);\ | ||
580 | + do_push1 (r1) | ||
581 | + | ||
582 | +#define do_pop(...) \ | ||
583 | +_buildN1(do_pop, _buildC1(__VA_ARGS__))( __VA_ARGS__) | ||
584 | + | ||
585 | +#define do_pop1(r1) ldr r1, [sp], #4 | ||
586 | +#define do_pop2(r1, r2) ldr r1, [sp], #4 ; ldr r2, [sp], #4 | ||
587 | +#define do_pop3(r1, r2, r3) ldr r1, [sp], #4 ; str r2, [sp], #4; str r3, [sp], #4 | ||
588 | +#define do_pop4(r1, r2, r3, r4) \ | ||
589 | + do_pop1 (r1);\ | ||
590 | + do_pup3 (r2, r3, r4) | ||
591 | +#define do_pop5(r1, r2, r3, r4, r5) \ | ||
592 | + do_pop1 (r1);\ | ||
593 | + do_pop4 (r2, r3, r4, r5) | ||
594 | +#else | ||
595 | +#define do_push(...) stmfd sp!, { __VA_ARGS__} | ||
596 | +#define do_pop(...) ldmfd sp!, {__VA_ARGS__} | ||
597 | +#endif | ||
598 | + | ||
599 | + | ||
600 | #define COND(op1, op2, cond) op1 ## cond ## op2 | ||
601 | .macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp | ||
602 | \name \dest, \src1, \src2, \shiftop \shiftreg | ||
603 | @@ -1260,7 +1294,7 @@ | ||
604 | ARM_FUNC_START div0 | ||
605 | #endif | ||
606 | |||
607 | - do_push {r1, lr} | ||
608 | + do_push (r1, lr) | ||
609 | mov r0, #SIGFPE | ||
610 | bl SYM(raise) __PLT__ | ||
611 | RETLDM r1 | ||
612 | @@ -1277,7 +1311,7 @@ | ||
613 | #if defined __ARM_EABI__ && defined __linux__ | ||
614 | @ EABI GNU/Linux call to cacheflush syscall. | ||
615 | ARM_FUNC_START clear_cache | ||
616 | - do_push {r7} | ||
617 | + do_push (r7) | ||
618 | #if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__) | ||
619 | movw r7, #2 | ||
620 | movt r7, #0xf | ||
621 | @@ -1287,7 +1321,7 @@ | ||
622 | #endif | ||
623 | mov r2, #0 | ||
624 | swi 0 | ||
625 | - do_pop {r7} | ||
626 | + do_pop (r7) | ||
627 | RET | ||
628 | FUNC_END clear_cache | ||
629 | #else | ||
630 | @@ -1490,7 +1524,7 @@ | ||
631 | push {r4, lr} | ||
632 | # else | ||
633 | ARM_FUNC_START clzdi2 | ||
634 | - do_push {r4, lr} | ||
635 | + do_push (r4, lr) | ||
636 | # endif | ||
637 | cmp xxh, #0 | ||
638 | bne 1f | ||
639 | |||
640 | === modified file 'gcc/config/arm/predicates.md' | ||
641 | --- old/gcc/config/arm/predicates.md 2010-07-30 14:17:05 +0000 | ||
642 | +++ new/gcc/config/arm/predicates.md 2010-08-05 15:20:54 +0000 | ||
643 | @@ -328,6 +328,9 @@ | ||
644 | HOST_WIDE_INT i = 1, base = 0; | ||
645 | rtx elt; | ||
646 | |||
647 | + if (low_irq_latency) | ||
648 | + return false; | ||
649 | + | ||
650 | if (count <= 1 | ||
651 | || GET_CODE (XVECEXP (op, 0, 0)) != SET) | ||
652 | return false; | ||
653 | @@ -385,6 +388,9 @@ | ||
654 | HOST_WIDE_INT i = 1, base = 0; | ||
655 | rtx elt; | ||
656 | |||
657 | + if (low_irq_latency) | ||
658 | + return false; | ||
659 | + | ||
660 | if (count <= 1 | ||
661 | || GET_CODE (XVECEXP (op, 0, 0)) != SET) | ||
662 | return false; | ||
663 | |||
664 | === modified file 'gcc/doc/invoke.texi' | ||
665 | --- old/gcc/doc/invoke.texi 2010-07-29 17:03:20 +0000 | ||
666 | +++ new/gcc/doc/invoke.texi 2010-08-05 15:20:54 +0000 | ||
667 | @@ -469,6 +469,7 @@ | ||
668 | -mtpcs-frame -mtpcs-leaf-frame @gol | ||
669 | -mcaller-super-interworking -mcallee-super-interworking @gol | ||
670 | -mtp=@var{name} @gol | ||
671 | +-mlow-irq-latency @gol | ||
672 | -mword-relocations @gol | ||
673 | -mfix-cortex-m3-ldrd} | ||
674 | |||
675 | @@ -9489,6 +9490,12 @@ | ||
676 | @code{,}, @code{!}, @code{|}, and @code{*} as needed. | ||
677 | |||
678 | |||
679 | +@item -mlow-irq-latency | ||
680 | +@opindex mlow-irq-latency | ||
681 | +Avoid instructions with high interrupt latency when generating | ||
682 | +code. This can increase code size and reduce performance. | ||
683 | +The option is off by default. | ||
684 | + | ||
685 | @end table | ||
686 | |||
687 | The conditional text @code{X} in a %@{@code{S}:@code{X}@} or similar | ||
688 | |||