[backfire] toolchain: fix gcc 3.4.6 (brcm-2.4) after relocation from usr/, refresh...
[openwrt-10.03/.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.  */