[backfire] toolchain: fix gcc 3.4.6 (brcm-2.4) after relocation from usr/, refresh...
[openwrt/svn-archive/archive.git] / toolchain / gcc / patches / 3.4.6 / 601-gcc34-arm-ldm.patch
1 --- a/gcc/config/arm/arm.c
2 +++ b/gcc/config/arm/arm.c
3 @@ -8514,6 +8514,26 @@ arm_output_function_prologue (FILE *f, H
4 return_used_this_function = 0;
5 }
6
7 +/* Return the number (counting from 0) of
8 + the least significant set bit in MASK. */
9 +
10 +#ifdef __GNUC__
11 +inline
12 +#endif
13 +static int
14 +number_of_first_bit_set (mask)
15 + int mask;
16 +{
17 + int bit;
18 +
19 + for (bit = 0;
20 + (mask & (1 << bit)) == 0;
21 + ++bit)
22 + continue;
23 +
24 + return bit;
25 +}
26 +
27 const char *
28 arm_output_epilogue (rtx sibling)
29 {
30 @@ -8747,27 +8767,47 @@ arm_output_epilogue (rtx sibling)
31 saved_regs_mask |= (1 << PC_REGNUM);
32 }
33
34 - /* Load the registers off the stack. If we only have one register
35 - to load use the LDR instruction - it is faster. */
36 - if (saved_regs_mask == (1 << LR_REGNUM))
37 - {
38 - /* The exception handler ignores the LR, so we do
39 - not really need to load it off the stack. */
40 - if (eh_ofs)
41 - asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
42 - else
43 - asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
44 - }
45 - else if (saved_regs_mask)
46 + if (saved_regs_mask)
47 {
48 - if (saved_regs_mask & (1 << SP_REGNUM))
49 - /* Note - write back to the stack register is not enabled
50 - (ie "ldmfd sp!..."). We know that the stack pointer is
51 - in the list of registers and if we add writeback the
52 - instruction becomes UNPREDICTABLE. */
53 - print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
54 + /* Load the registers off the stack. If we only have one register
55 + to load use the LDR instruction - it is faster. */
56 + if (bit_count (saved_regs_mask) == 1)
57 + {
58 + int reg = number_of_first_bit_set (saved_regs_mask);
59 +
60 + switch (reg)
61 + {
62 + case SP_REGNUM:
63 + /* Mustn't use base writeback when loading SP. */
64 + asm_fprintf (f, "\tldr\t%r, [%r]\n", SP_REGNUM, SP_REGNUM);
65 + break;
66 +
67 + case LR_REGNUM:
68 + if (eh_ofs)
69 + {
70 + /* The exception handler ignores the LR, so we do
71 + not really need to load it off the stack. */
72 + asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
73 + break;
74 + }
75 + /* else fall through */
76 +
77 + default:
78 + asm_fprintf (f, "\tldr\t%r, [%r], #4\n", reg, SP_REGNUM);
79 + break;
80 + }
81 + }
82 else
83 - print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
84 + {
85 + if (saved_regs_mask & (1 << SP_REGNUM))
86 + /* Note - write back to the stack register is not enabled
87 + (ie "ldmfd sp!..."). We know that the stack pointer is
88 + in the list of registers and if we add writeback the
89 + instruction becomes UNPREDICTABLE. */
90 + print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
91 + else
92 + print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
93 + }
94 }
95
96 if (current_function_pretend_args_size)
97 @@ -11395,22 +11435,6 @@ replace_symbols_in_block (tree block, rt
98 }
99 }
100
101 -/* Return the number (counting from 0) of
102 - the least significant set bit in MASK. */
103 -
104 -inline static int
105 -number_of_first_bit_set (int mask)
106 -{
107 - int bit;
108 -
109 - for (bit = 0;
110 - (mask & (1 << bit)) == 0;
111 - ++bit)
112 - continue;
113 -
114 - return bit;
115 -}
116 -
117 /* Generate code to return from a thumb function.
118 If 'reg_containing_return_addr' is -1, then the return address is
119 actually on the stack, at the stack pointer. */