Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[MIPS] Fix optimization for size build. It took a while longer than on other architectures but gcc has finally started to strike us as well ... This also fixes the damage by 6edfba1b33c701108717f4e036320fc39abe1912. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

+120
+2
arch/mips/Makefile
··· 83 83 LDFLAGS_vmlinux += -G 0 -static -n -nostdlib 84 84 MODFLAGS += -mlong-calls 85 85 86 + cflags-y += -ffreestanding 87 + 86 88 # 87 89 # We explicitly add the endianness specifier if needed, this allows 88 90 # to compile kernels with a toolchain for the other endianness. We
+3
arch/mips/lib/Makefile
··· 7 7 8 8 obj-y += iomap.o 9 9 10 + # libgcc-style stuff needed in the kernel 11 + lib-y += ashldi3.o ashrdi3.o lshrdi3.o 12 + 10 13 EXTRA_AFLAGS := $(CFLAGS)
+29
arch/mips/lib/ashldi3.c
··· 1 + #include <linux/module.h> 2 + 3 + #include "libgcc.h" 4 + 5 + long long __ashldi3(long long u, word_type b) 6 + { 7 + DWunion uu, w; 8 + word_type bm; 9 + 10 + if (b == 0) 11 + return u; 12 + 13 + uu.ll = u; 14 + bm = 32 - b; 15 + 16 + if (bm <= 0) { 17 + w.s.low = 0; 18 + w.s.high = (unsigned int) uu.s.low << -bm; 19 + } else { 20 + const unsigned int carries = (unsigned int) uu.s.low >> bm; 21 + 22 + w.s.low = (unsigned int) uu.s.low << b; 23 + w.s.high = ((unsigned int) uu.s.high << b) | carries; 24 + } 25 + 26 + return w.ll; 27 + } 28 + 29 + EXPORT_SYMBOL(__ashldi3);
+31
arch/mips/lib/ashrdi3.c
··· 1 + #include <linux/module.h> 2 + 3 + #include "libgcc.h" 4 + 5 + long long __ashrdi3(long long u, word_type b) 6 + { 7 + DWunion uu, w; 8 + word_type bm; 9 + 10 + if (b == 0) 11 + return u; 12 + 13 + uu.ll = u; 14 + bm = 32 - b; 15 + 16 + if (bm <= 0) { 17 + /* w.s.high = 1..1 or 0..0 */ 18 + w.s.high = 19 + uu.s.high >> 31; 20 + w.s.low = uu.s.high >> -bm; 21 + } else { 22 + const unsigned int carries = (unsigned int) uu.s.high << bm; 23 + 24 + w.s.high = uu.s.high >> b; 25 + w.s.low = ((unsigned int) uu.s.low >> b) | carries; 26 + } 27 + 28 + return w.ll; 29 + } 30 + 31 + EXPORT_SYMBOL(__ashrdi3);
+26
arch/mips/lib/libgcc.h
··· 1 + #ifndef __ASM_LIBGCC_H 2 + #define __ASM_LIBGCC_H 3 + 4 + #include <asm/byteorder.h> 5 + 6 + typedef int word_type __attribute__ ((mode (__word__))); 7 + 8 + #ifdef __BIG_ENDIAN 9 + struct DWstruct { 10 + int high, low; 11 + }; 12 + #elif defined(__LITTLE_ENDIAN) 13 + struct DWstruct { 14 + int low, high; 15 + }; 16 + #else 17 + #error I feel sick. 18 + #endif 19 + 20 + typedef union 21 + { 22 + struct DWstruct s; 23 + long long ll; 24 + } DWunion; 25 + 26 + #endif /* __ASM_LIBGCC_H */
+29
arch/mips/lib/lshrdi3.c
··· 1 + #include <linux/module.h> 2 + 3 + #include "libgcc.h" 4 + 5 + long long __lshrdi3(long long u, word_type b) 6 + { 7 + DWunion uu, w; 8 + word_type bm; 9 + 10 + if (b == 0) 11 + return u; 12 + 13 + uu.ll = u; 14 + bm = 32 - b; 15 + 16 + if (bm <= 0) { 17 + w.s.high = 0; 18 + w.s.low = (unsigned int) uu.s.high >> -bm; 19 + } else { 20 + const unsigned int carries = (unsigned int) uu.s.high << bm; 21 + 22 + w.s.high = (unsigned int) uu.s.high >> b; 23 + w.s.low = ((unsigned int) uu.s.low >> b) | carries; 24 + } 25 + 26 + return w.ll; 27 + } 28 + 29 + EXPORT_SYMBOL(__lshrdi3);