diff options
author | Kumar Gala <galak@kernel.crashing.org> | 2008-06-12 17:20:58 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-06-16 01:00:54 -0400 |
commit | da3de6df33f5f42ff9dc40093fbc884f524c9a49 (patch) | |
tree | b0c5d209cde49e55bdd41b6125ae58918bd31ed5 | |
parent | 143580ecfb7999147e546cc3814023e233e95fa5 (diff) |
[POWERPC] Fix -Os kernel builds with newer gcc versions
GCC 4.4.x looks to be adding support for generating out-of-line register
saves/restores based on:
http://gcc.gnu.org/ml/gcc-patches/2008-04/msg01678.html
This breaks the kernel if we enable CONFIG_CC_OPTIMIZE_FOR_SIZE. To fix
this we add the use the save/restore code from gcc and simplified it down
for our needs (integer only).
Additionally, we have to link this code into each module. The other
solution was to add EXPORT_SYMBOL() which meant going through the
trampoline which seemed nonsensical for these out-of-line routines.
Finally, we add some checks to prom_init_check.sh to ignore the
out-of-line save/restore functions.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_init_check.sh | 14 | ||||
-rw-r--r-- | arch/powerpc/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/lib/crtsavres.S | 229 |
4 files changed, 246 insertions, 1 deletions
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 86096ccc5914..b7d4c4ce2fe6 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -96,6 +96,8 @@ endif | |||
96 | else | 96 | else |
97 | KBUILD_CFLAGS += $(call cc-option,-mtune=power4) | 97 | KBUILD_CFLAGS += $(call cc-option,-mtune=power4) |
98 | endif | 98 | endif |
99 | else | ||
100 | LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o | ||
99 | endif | 101 | endif |
100 | 102 | ||
101 | ifeq ($(CONFIG_TUNE_CELL),y) | 103 | ifeq ($(CONFIG_TUNE_CELL),y) |
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index 31729a9387df..2c7e8e87f770 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh | |||
@@ -48,6 +48,20 @@ do | |||
48 | fi | 48 | fi |
49 | done | 49 | done |
50 | 50 | ||
51 | # ignore register save/restore funcitons | ||
52 | if [ "${UNDEF:0:9}" = "_restgpr_" ]; then | ||
53 | OK=1 | ||
54 | fi | ||
55 | if [ "${UNDEF:0:11}" = "_rest32gpr_" ]; then | ||
56 | OK=1 | ||
57 | fi | ||
58 | if [ "${UNDEF:0:9}" = "_savegpr_" ]; then | ||
59 | OK=1 | ||
60 | fi | ||
61 | if [ "${UNDEF:0:11}" = "_save32gpr_" ]; then | ||
62 | OK=1 | ||
63 | fi | ||
64 | |||
51 | if [ $OK -eq 0 ]; then | 65 | if [ $OK -eq 0 ]; then |
52 | ERROR=1 | 66 | ERROR=1 |
53 | echo "Error: External symbol '$UNDEF' referenced" \ | 67 | echo "Error: External symbol '$UNDEF' referenced" \ |
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index c71d37dc6a88..e522b06cc42f 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile | |||
@@ -9,7 +9,7 @@ endif | |||
9 | ifeq ($(CONFIG_PPC_MERGE),y) | 9 | ifeq ($(CONFIG_PPC_MERGE),y) |
10 | obj-y := string.o alloc.o \ | 10 | obj-y := string.o alloc.o \ |
11 | checksum_$(CONFIG_WORD_SIZE).o | 11 | checksum_$(CONFIG_WORD_SIZE).o |
12 | obj-$(CONFIG_PPC32) += div64.o copy_32.o | 12 | obj-$(CONFIG_PPC32) += div64.o copy_32.o crtsavres.o |
13 | obj-$(CONFIG_HAS_IOMEM) += devres.o | 13 | obj-$(CONFIG_HAS_IOMEM) += devres.o |
14 | endif | 14 | endif |
15 | 15 | ||
diff --git a/arch/powerpc/lib/crtsavres.S b/arch/powerpc/lib/crtsavres.S new file mode 100644 index 000000000000..70a9cd8a3008 --- /dev/null +++ b/arch/powerpc/lib/crtsavres.S | |||
@@ -0,0 +1,229 @@ | |||
1 | /* | ||
2 | * Special support for eabi and SVR4 | ||
3 | * | ||
4 | * Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc. | ||
5 | * Copyright 2008 Freescale Semiconductor, Inc. | ||
6 | * Written By Michael Meissner | ||
7 | * | ||
8 | * Based on gcc/config/rs6000/crtsavres.asm from gcc | ||
9 | * | ||
10 | * This file is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2, or (at your option) any | ||
13 | * later version. | ||
14 | * | ||
15 | * In addition to the permissions in the GNU General Public License, the | ||
16 | * Free Software Foundation gives you unlimited permission to link the | ||
17 | * compiled version of this file with other programs, and to distribute | ||
18 | * those programs without any restriction coming from the use of this | ||
19 | * file. (The General Public License restrictions do apply in other | ||
20 | * respects; for example, they cover modification of the file, and | ||
21 | * distribution when not linked into another program.) | ||
22 | * | ||
23 | * This file is distributed in the hope that it will be useful, but | ||
24 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
26 | * General Public License for more details. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License | ||
29 | * along with this program; see the file COPYING. If not, write to | ||
30 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, | ||
31 | * Boston, MA 02110-1301, USA. | ||
32 | * | ||
33 | * As a special exception, if you link this library with files | ||
34 | * compiled with GCC to produce an executable, this does not cause | ||
35 | * the resulting executable to be covered by the GNU General Public License. | ||
36 | * This exception does not however invalidate any other reasons why | ||
37 | * the executable file might be covered by the GNU General Public License. | ||
38 | */ | ||
39 | |||
40 | #include <asm/ppc_asm.h> | ||
41 | |||
42 | .file "crtsavres.S" | ||
43 | .section ".text" | ||
44 | |||
45 | #ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE | ||
46 | |||
47 | /* Routines for saving integer registers, called by the compiler. */ | ||
48 | /* Called with r11 pointing to the stack header word of the caller of the */ | ||
49 | /* function, just beyond the end of the integer save area. */ | ||
50 | |||
51 | _GLOBAL(_savegpr_14) | ||
52 | _GLOBAL(_save32gpr_14) | ||
53 | stw 14,-72(11) /* save gp registers */ | ||
54 | _GLOBAL(_savegpr_15) | ||
55 | _GLOBAL(_save32gpr_15) | ||
56 | stw 15,-68(11) | ||
57 | _GLOBAL(_savegpr_16) | ||
58 | _GLOBAL(_save32gpr_16) | ||
59 | stw 16,-64(11) | ||
60 | _GLOBAL(_savegpr_17) | ||
61 | _GLOBAL(_save32gpr_17) | ||
62 | stw 17,-60(11) | ||
63 | _GLOBAL(_savegpr_18) | ||
64 | _GLOBAL(_save32gpr_18) | ||
65 | stw 18,-56(11) | ||
66 | _GLOBAL(_savegpr_19) | ||
67 | _GLOBAL(_save32gpr_19) | ||
68 | stw 19,-52(11) | ||
69 | _GLOBAL(_savegpr_20) | ||
70 | _GLOBAL(_save32gpr_20) | ||
71 | stw 20,-48(11) | ||
72 | _GLOBAL(_savegpr_21) | ||
73 | _GLOBAL(_save32gpr_21) | ||
74 | stw 21,-44(11) | ||
75 | _GLOBAL(_savegpr_22) | ||
76 | _GLOBAL(_save32gpr_22) | ||
77 | stw 22,-40(11) | ||
78 | _GLOBAL(_savegpr_23) | ||
79 | _GLOBAL(_save32gpr_23) | ||
80 | stw 23,-36(11) | ||
81 | _GLOBAL(_savegpr_24) | ||
82 | _GLOBAL(_save32gpr_24) | ||
83 | stw 24,-32(11) | ||
84 | _GLOBAL(_savegpr_25) | ||
85 | _GLOBAL(_save32gpr_25) | ||
86 | stw 25,-28(11) | ||
87 | _GLOBAL(_savegpr_26) | ||
88 | _GLOBAL(_save32gpr_26) | ||
89 | stw 26,-24(11) | ||
90 | _GLOBAL(_savegpr_27) | ||
91 | _GLOBAL(_save32gpr_27) | ||
92 | stw 27,-20(11) | ||
93 | _GLOBAL(_savegpr_28) | ||
94 | _GLOBAL(_save32gpr_28) | ||
95 | stw 28,-16(11) | ||
96 | _GLOBAL(_savegpr_29) | ||
97 | _GLOBAL(_save32gpr_29) | ||
98 | stw 29,-12(11) | ||
99 | _GLOBAL(_savegpr_30) | ||
100 | _GLOBAL(_save32gpr_30) | ||
101 | stw 30,-8(11) | ||
102 | _GLOBAL(_savegpr_31) | ||
103 | _GLOBAL(_save32gpr_31) | ||
104 | stw 31,-4(11) | ||
105 | blr | ||
106 | |||
107 | /* Routines for restoring integer registers, called by the compiler. */ | ||
108 | /* Called with r11 pointing to the stack header word of the caller of the */ | ||
109 | /* function, just beyond the end of the integer restore area. */ | ||
110 | |||
111 | _GLOBAL(_restgpr_14) | ||
112 | _GLOBAL(_rest32gpr_14) | ||
113 | lwz 14,-72(11) /* restore gp registers */ | ||
114 | _GLOBAL(_restgpr_15) | ||
115 | _GLOBAL(_rest32gpr_15) | ||
116 | lwz 15,-68(11) | ||
117 | _GLOBAL(_restgpr_16) | ||
118 | _GLOBAL(_rest32gpr_16) | ||
119 | lwz 16,-64(11) | ||
120 | _GLOBAL(_restgpr_17) | ||
121 | _GLOBAL(_rest32gpr_17) | ||
122 | lwz 17,-60(11) | ||
123 | _GLOBAL(_restgpr_18) | ||
124 | _GLOBAL(_rest32gpr_18) | ||
125 | lwz 18,-56(11) | ||
126 | _GLOBAL(_restgpr_19) | ||
127 | _GLOBAL(_rest32gpr_19) | ||
128 | lwz 19,-52(11) | ||
129 | _GLOBAL(_restgpr_20) | ||
130 | _GLOBAL(_rest32gpr_20) | ||
131 | lwz 20,-48(11) | ||
132 | _GLOBAL(_restgpr_21) | ||
133 | _GLOBAL(_rest32gpr_21) | ||
134 | lwz 21,-44(11) | ||
135 | _GLOBAL(_restgpr_22) | ||
136 | _GLOBAL(_rest32gpr_22) | ||
137 | lwz 22,-40(11) | ||
138 | _GLOBAL(_restgpr_23) | ||
139 | _GLOBAL(_rest32gpr_23) | ||
140 | lwz 23,-36(11) | ||
141 | _GLOBAL(_restgpr_24) | ||
142 | _GLOBAL(_rest32gpr_24) | ||
143 | lwz 24,-32(11) | ||
144 | _GLOBAL(_restgpr_25) | ||
145 | _GLOBAL(_rest32gpr_25) | ||
146 | lwz 25,-28(11) | ||
147 | _GLOBAL(_restgpr_26) | ||
148 | _GLOBAL(_rest32gpr_26) | ||
149 | lwz 26,-24(11) | ||
150 | _GLOBAL(_restgpr_27) | ||
151 | _GLOBAL(_rest32gpr_27) | ||
152 | lwz 27,-20(11) | ||
153 | _GLOBAL(_restgpr_28) | ||
154 | _GLOBAL(_rest32gpr_28) | ||
155 | lwz 28,-16(11) | ||
156 | _GLOBAL(_restgpr_29) | ||
157 | _GLOBAL(_rest32gpr_29) | ||
158 | lwz 29,-12(11) | ||
159 | _GLOBAL(_restgpr_30) | ||
160 | _GLOBAL(_rest32gpr_30) | ||
161 | lwz 30,-8(11) | ||
162 | _GLOBAL(_restgpr_31) | ||
163 | _GLOBAL(_rest32gpr_31) | ||
164 | lwz 31,-4(11) | ||
165 | blr | ||
166 | |||
167 | /* Routines for restoring integer registers, called by the compiler. */ | ||
168 | /* Called with r11 pointing to the stack header word of the caller of the */ | ||
169 | /* function, just beyond the end of the integer restore area. */ | ||
170 | |||
171 | _GLOBAL(_restgpr_14_x) | ||
172 | _GLOBAL(_rest32gpr_14_x) | ||
173 | lwz 14,-72(11) /* restore gp registers */ | ||
174 | _GLOBAL(_restgpr_15_x) | ||
175 | _GLOBAL(_rest32gpr_15_x) | ||
176 | lwz 15,-68(11) | ||
177 | _GLOBAL(_restgpr_16_x) | ||
178 | _GLOBAL(_rest32gpr_16_x) | ||
179 | lwz 16,-64(11) | ||
180 | _GLOBAL(_restgpr_17_x) | ||
181 | _GLOBAL(_rest32gpr_17_x) | ||
182 | lwz 17,-60(11) | ||
183 | _GLOBAL(_restgpr_18_x) | ||
184 | _GLOBAL(_rest32gpr_18_x) | ||
185 | lwz 18,-56(11) | ||
186 | _GLOBAL(_restgpr_19_x) | ||
187 | _GLOBAL(_rest32gpr_19_x) | ||
188 | lwz 19,-52(11) | ||
189 | _GLOBAL(_restgpr_20_x) | ||
190 | _GLOBAL(_rest32gpr_20_x) | ||
191 | lwz 20,-48(11) | ||
192 | _GLOBAL(_restgpr_21_x) | ||
193 | _GLOBAL(_rest32gpr_21_x) | ||
194 | lwz 21,-44(11) | ||
195 | _GLOBAL(_restgpr_22_x) | ||
196 | _GLOBAL(_rest32gpr_22_x) | ||
197 | lwz 22,-40(11) | ||
198 | _GLOBAL(_restgpr_23_x) | ||
199 | _GLOBAL(_rest32gpr_23_x) | ||
200 | lwz 23,-36(11) | ||
201 | _GLOBAL(_restgpr_24_x) | ||
202 | _GLOBAL(_rest32gpr_24_x) | ||
203 | lwz 24,-32(11) | ||
204 | _GLOBAL(_restgpr_25_x) | ||
205 | _GLOBAL(_rest32gpr_25_x) | ||
206 | lwz 25,-28(11) | ||
207 | _GLOBAL(_restgpr_26_x) | ||
208 | _GLOBAL(_rest32gpr_26_x) | ||
209 | lwz 26,-24(11) | ||
210 | _GLOBAL(_restgpr_27_x) | ||
211 | _GLOBAL(_rest32gpr_27_x) | ||
212 | lwz 27,-20(11) | ||
213 | _GLOBAL(_restgpr_28_x) | ||
214 | _GLOBAL(_rest32gpr_28_x) | ||
215 | lwz 28,-16(11) | ||
216 | _GLOBAL(_restgpr_29_x) | ||
217 | _GLOBAL(_rest32gpr_29_x) | ||
218 | lwz 29,-12(11) | ||
219 | _GLOBAL(_restgpr_30_x) | ||
220 | _GLOBAL(_rest32gpr_30_x) | ||
221 | lwz 30,-8(11) | ||
222 | _GLOBAL(_restgpr_31_x) | ||
223 | _GLOBAL(_rest32gpr_31_x) | ||
224 | lwz 0,4(11) | ||
225 | lwz 31,-4(11) | ||
226 | mtlr 0 | ||
227 | mr 1,11 | ||
228 | blr | ||
229 | #endif | ||