summaryrefslogtreecommitdiffstats
path: root/meta/packages/gcc/gcc-3.3.4/arm-ldm.dpatch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/gcc/gcc-3.3.4/arm-ldm.dpatch')
-rw-r--r--meta/packages/gcc/gcc-3.3.4/arm-ldm.dpatch148
1 files changed, 148 insertions, 0 deletions
diff --git a/meta/packages/gcc/gcc-3.3.4/arm-ldm.dpatch b/meta/packages/gcc/gcc-3.3.4/arm-ldm.dpatch
new file mode 100644
index 0000000000..561624f39c
--- /dev/null
+++ b/meta/packages/gcc/gcc-3.3.4/arm-ldm.dpatch
@@ -0,0 +1,148 @@
1#! /bin/sh -e
2
3src=gcc
4if [ $# -eq 3 -a "$2" = '-d' ]; then
5 pdir="-d $3"
6 src=$3/gcc
7elif [ $# -ne 1 ]; then
8 echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
9 exit 1
10fi
11case "$1" in
12 -patch)
13 patch $pdir -f --no-backup-if-mismatch -p0 --fuzz 10 < $0
14 ;;
15 -unpatch)
16 patch $pdir -f --no-backup-if-mismatch -R -p0 --fuzz 10 < $0
17 ;;
18 *)
19 echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
20 exit 1
21esac
22exit 0
23
24# DP: try harder to avoid ldm in function epilogues
25
26--- gcc/config/arm/arm.c Fri Mar 5 18:49:42 2004
27+++ gcc/config/arm/arm.c Fri Mar 5 16:00:21 2004
28@@ -7598,6 +7629,26 @@
29 return_used_this_function = 0;
30 }
31
32+/* Return the number (counting from 0) of
33+ the least significant set bit in MASK. */
34+
35+#ifdef __GNUC__
36+inline
37+#endif
38+static int
39+number_of_first_bit_set (mask)
40+ int mask;
41+{
42+ int bit;
43+
44+ for (bit = 0;
45+ (mask & (1 << bit)) == 0;
46+ ++bit)
47+ continue;
48+
49+ return bit;
50+}
51+
52 const char *
53 arm_output_epilogue (really_return)
54 int really_return;
55@@ -7788,27 +7839,47 @@
56 saved_regs_mask |= (1 << PC_REGNUM);
57 }
58
59- /* Load the registers off the stack. If we only have one register
60- to load use the LDR instruction - it is faster. */
61- if (saved_regs_mask == (1 << LR_REGNUM))
62- {
63- /* The exception handler ignores the LR, so we do
64- not really need to load it off the stack. */
65- if (eh_ofs)
66- asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
67- else
68- asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
69- }
70- else if (saved_regs_mask)
71+ if (saved_regs_mask)
72 {
73- if (saved_regs_mask & (1 << SP_REGNUM))
74- /* Note - write back to the stack register is not enabled
75- (ie "ldmfd sp!..."). We know that the stack pointer is
76- in the list of registers and if we add writeback the
77- instruction becomes UNPREDICTABLE. */
78- print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
79+ /* Load the registers off the stack. If we only have one register
80+ to load use the LDR instruction - it is faster. */
81+ if (bit_count (saved_regs_mask) == 1)
82+ {
83+ int reg = number_of_first_bit_set (saved_regs_mask);
84+
85+ switch (reg)
86+ {
87+ case SP_REGNUM:
88+ /* Mustn't use base writeback when loading SP. */
89+ asm_fprintf (f, "\tldr\t%r, [%r]\n", SP_REGNUM, SP_REGNUM);
90+ break;
91+
92+ case LR_REGNUM:
93+ if (eh_ofs)
94+ {
95+ /* The exception handler ignores the LR, so we do
96+ not really need to load it off the stack. */
97+ asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
98+ break;
99+ }
100+ /* else fall through */
101+
102+ default:
103+ asm_fprintf (f, "\tldr\t%r, [%r], #4\n", reg, SP_REGNUM);
104+ break;
105+ }
106+ }
107 else
108- print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
109+ {
110+ if (saved_regs_mask & (1 << SP_REGNUM))
111+ /* Note - write back to the stack register is not enabled
112+ (ie "ldmfd sp!..."). We know that the stack pointer is
113+ in the list of registers and if we add writeback the
114+ instruction becomes UNPREDICTABLE. */
115+ print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
116+ else
117+ print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
118+ }
119 }
120
121 if (current_function_pretend_args_size)
122@@ -9610,26 +9677,6 @@
123 }
124 }
125
126-/* Return the number (counting from 0) of
127- the least significant set bit in MASK. */
128-
129-#ifdef __GNUC__
130-inline
131-#endif
132-static int
133-number_of_first_bit_set (mask)
134- int mask;
135-{
136- int bit;
137-
138- for (bit = 0;
139- (mask & (1 << bit)) == 0;
140- ++bit)
141- continue;
142-
143- return bit;
144-}
145-
146 /* Generate code to return from a thumb function.
147 If 'reg_containing_return_addr' is -1, then the return address is
148 actually on the stack, at the stack pointer. */