summaryrefslogtreecommitdiffstats
path: root/meta/packages/gcc/gcc-3.4.3/gcc34-arm-ldm.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/gcc/gcc-3.4.3/gcc34-arm-ldm.patch')
-rw-r--r--meta/packages/gcc/gcc-3.4.3/gcc34-arm-ldm.patch119
1 files changed, 119 insertions, 0 deletions
diff --git a/meta/packages/gcc/gcc-3.4.3/gcc34-arm-ldm.patch b/meta/packages/gcc/gcc-3.4.3/gcc34-arm-ldm.patch
new file mode 100644
index 0000000000..142052fdf0
--- /dev/null
+++ b/meta/packages/gcc/gcc-3.4.3/gcc34-arm-ldm.patch
@@ -0,0 +1,119 @@
1--- gcc-3.4.0/gcc/config/arm/arm.c.arm-ldm 2004-02-27 09:51:05.000000000 -0500
2+++ gcc-3.4.0/gcc/config/arm/arm.c 2004-04-24 18:16:25.000000000 -0400
3@@ -8520,6 +8520,26 @@
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@@ -8753,27 +8773,47 @@
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@@ -11401,22 +11441,6 @@
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. */