diff options
Diffstat (limited to 'openembedded/packages/gcc/gcc-3.3.4/arm-ldm.dpatch')
-rw-r--r-- | openembedded/packages/gcc/gcc-3.3.4/arm-ldm.dpatch | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/openembedded/packages/gcc/gcc-3.3.4/arm-ldm.dpatch b/openembedded/packages/gcc/gcc-3.3.4/arm-ldm.dpatch new file mode 100644 index 0000000000..561624f39c --- /dev/null +++ b/openembedded/packages/gcc/gcc-3.3.4/arm-ldm.dpatch | |||
@@ -0,0 +1,148 @@ | |||
1 | #! /bin/sh -e | ||
2 | |||
3 | src=gcc | ||
4 | if [ $# -eq 3 -a "$2" = '-d' ]; then | ||
5 | pdir="-d $3" | ||
6 | src=$3/gcc | ||
7 | elif [ $# -ne 1 ]; then | ||
8 | echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" | ||
9 | exit 1 | ||
10 | fi | ||
11 | case "$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 | ||
21 | esac | ||
22 | exit 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. */ | ||