[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>

authored by Kumar Gala and committed by Paul Mackerras da3de6df 143580ec

+246 -1
+2
arch/powerpc/Makefile
··· 96 96 else 97 97 KBUILD_CFLAGS += $(call cc-option,-mtune=power4) 98 98 endif 99 + else 100 + LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o 99 101 endif 100 102 101 103 ifeq ($(CONFIG_TUNE_CELL),y)
+14
arch/powerpc/kernel/prom_init_check.sh
··· 48 48 fi 49 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 65 if [ $OK -eq 0 ]; then 52 66 ERROR=1 53 67 echo "Error: External symbol '$UNDEF' referenced" \
+1 -1
arch/powerpc/lib/Makefile
··· 9 9 ifeq ($(CONFIG_PPC_MERGE),y) 10 10 obj-y := string.o alloc.o \ 11 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 13 obj-$(CONFIG_HAS_IOMEM) += devres.o 14 14 endif 15 15
+229
arch/powerpc/lib/crtsavres.S
··· 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