[kernel] r5505 - dists/trunk/arch/mips/linux-patch-2.6.15-mips-2.6.15/debian/patches

Martin Michlmayr tbm at costa.debian.org
Wed Jan 18 01:08:25 UTC 2006


Author: tbm
Date: Wed Jan 18 01:08:24 2006
New Revision: 5505

Added:
   dists/trunk/arch/mips/linux-patch-2.6.15-mips-2.6.15/debian/patches/65_fix_gcc4_opt.dpatch
Log:
Fixes CONFIG_CC_OPTIMIZE_FOR_SIZE=y builds with GCC 4.0


Added: dists/trunk/arch/mips/linux-patch-2.6.15-mips-2.6.15/debian/patches/65_fix_gcc4_opt.dpatch
==============================================================================
--- (empty file)
+++ dists/trunk/arch/mips/linux-patch-2.6.15-mips-2.6.15/debian/patches/65_fix_gcc4_opt.dpatch	Wed Jan 18 01:08:24 2006
@@ -0,0 +1,236 @@
+#! /bin/sh -e
+## 65_fix_gcc4_opt.dpatch by Ralf Baechle <ralf at linux-mips.org>
+##
+## DP: Fixes CONFIG_CC_OPTIMIZE_FOR_SIZE=y builds with GCC 4.0
+## DP: Upstream status: suggested on linux-mips list, not in git yet
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p1 ${patch_opts} < $0;;
+    -unpatch) patch -R -p1 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+
+> On Tuesday 17 January 2006 3:48 pm, Martin Michlmayr wrote:
+> > Has anyone else seen the following error when compiling a kernel with GCC
+> > 4.0 (GCC 3.3 works) and knows what to do about it?
+> >
+> > arch/mips/kernel/built-in.o: In function `time_init':
+> > : undefined reference to `__lshrdi3'
+
+Thanks to Martin Michlmayr's testing I now know this problem is limited
+to kernels built with gcc 4.0 and newer when optimizing for size.
+
+> I think I've solved it by copying the files
+> ashldi3.c ashrdi3.c lshrdi3.c
+> from arch/ppc/lib to arch/mips/lib
+
+There is an awful lot of libgcc bits flying around in the kernel and I guess
+I'd be flamed for submitting even more ;-)  so I tried to come up with
+something to make most if not all unnecessary.  Still needs a little
+polishing but below for testing and commenting.
+
+  Ralf
+
+diff --git a/include/asm-mips/libgcc.h b/include/asm-mips/libgcc.h
+new file mode 100644
+index 0000000..0aef711
+ include/asm-mips/libgcc.h |    8 ++++++++
+ include/linux/libgcc.h    |   32 ++++++++++++++++++++++++++++++++
+ lib/Makefile              |    1 +
+ lib/ashldi3.c             |   32 ++++++++++++++++++++++++++++++++
+ lib/ashrdi3.c             |   36 ++++++++++++++++++++++++++++++++++++
+ lib/lshrdi3.c             |   34 ++++++++++++++++++++++++++++++++++
+ 6 files changed, 143 insertions(+)
+
+Index: linux-mips/include/asm-mips/libgcc.h
+===================================================================
+--- /dev/null
++++ linux-mips/include/asm-mips/libgcc.h
+@@ -0,0 +1,8 @@
++#ifndef __ASM_LIBGCC_H
++#define __ASM_LIBGCC_H
++
++#define ARCH_NEEDS_ashldi3
++#define ARCH_NEEDS_ashrdi3
++#define ARCH_NEEDS_lshrdi3
++
++#endif /* __ASM_LIBGCC_H */
+Index: linux-mips/include/linux/libgcc.h
+===================================================================
+--- /dev/null
++++ linux-mips/include/linux/libgcc.h
+@@ -0,0 +1,32 @@
++#ifndef __LINUX_LIBGCC_H
++#define __LINUX_LIBGCC_H
++
++#include <asm/byteorder.h>
++#include <asm/libgcc.h>
++
++typedef long long DWtype;
++typedef int Wtype;
++typedef unsigned int UWtype;
++typedef int word_type __attribute__ ((mode (__word__)));
++
++#define BITS_PER_UNIT 8
++
++#ifdef __BIG_ENDIAN
++struct DWstruct {
++	Wtype high, low;
++};
++#elif defined(__LITTLE_ENDIAN)
++struct DWstruct {
++	Wtype low, high;
++};
++#else
++#error I feel sick.
++#endif
++
++typedef union
++{
++	struct DWstruct s;
++	DWtype ll;
++} DWunion;
++
++#endif /* __LINUX_LIBGCC_H */
+Index: linux-mips/lib/Makefile
+===================================================================
+--- linux-mips.orig/lib/Makefile
++++ linux-mips/lib/Makefile
+@@ -8,6 +8,7 @@ lib-y := errno.o ctype.o string.o vsprin
+ 	 sha1.o
+ 
+ lib-y	+= kobject.o kref.o kobject_uevent.o klist.o
++lib-y	+= ashldi3.o ashrdi3.o lshrdi3.o
+ 
+ obj-y += sort.o parser.o halfmd4.o
+ 
+Index: linux-mips/lib/ashldi3.c
+===================================================================
+--- /dev/null
++++ linux-mips/lib/ashldi3.c
+@@ -0,0 +1,32 @@
++#include <linux/libgcc.h>
++#include <linux/module.h>
++
++#ifdef ARCH_NEEDS_ashldi3
++
++DWtype __ashldi3(DWtype u, word_type b)
++{
++	DWunion uu, w;
++	word_type bm;
++
++	if (b == 0)
++		return u;
++
++	uu.ll = u;
++	bm = (sizeof(Wtype) * BITS_PER_UNIT) - b;
++
++	if (bm <= 0) {
++		w.s.low = 0;
++		w.s.high = (UWtype) uu.s.low << -bm;
++	} else {
++		const UWtype carries = (UWtype) uu.s.low >> bm;
++
++		w.s.low = (UWtype) uu.s.low << b;
++		w.s.high = ((UWtype) uu.s.high << b) | carries;
++	}
++
++	return w.ll;
++}
++
++EXPORT_SYMBOL(__ashldi3);
++
++#endif /* ARCH_NEEDS_ashldi3 */
+Index: linux-mips/lib/ashrdi3.c
+===================================================================
+--- /dev/null
++++ linux-mips/lib/ashrdi3.c
+@@ -0,0 +1,36 @@
++#include <linux/libgcc.h>
++#include <linux/module.h>
++
++/* Unless shift functions are defined with full ANSI prototypes,
++   parameter b will be promoted to int if word_type is smaller than an int.  */
++#ifdef ARCH_NEEDS_ashrdi3
++
++DWtype __ashrdi3(DWtype u, word_type b)
++{
++	DWunion uu, w;
++	word_type bm;
++
++	if (b == 0)
++		return u;
++
++	uu.ll = u;
++	bm = (sizeof(Wtype) * BITS_PER_UNIT) - b;
++
++	if (bm <= 0) {
++		/* w.s.high = 1..1 or 0..0 */
++		w.s.high =
++		    uu.s.high >> (sizeof(Wtype) * BITS_PER_UNIT - 1);
++		w.s.low = uu.s.high >> -bm;
++	} else {
++		const UWtype carries = (UWtype) uu.s.high << bm;
++
++		w.s.high = uu.s.high >> b;
++		w.s.low = ((UWtype) uu.s.low >> b) | carries;
++	}
++
++	return w.ll;
++}
++
++EXPORT_SYMBOL(__ashrdi3);
++
++#endif /* ARCH_NEEDS_ashrdi3 */
+Index: linux-mips/lib/lshrdi3.c
+===================================================================
+--- /dev/null
++++ linux-mips/lib/lshrdi3.c
+@@ -0,0 +1,34 @@
++#include <linux/libgcc.h>
++#include <linux/module.h>
++
++/* Unless shift functions are defined with full ANSI prototypes,
++   parameter b will be promoted to int if word_type is smaller than an int.  */
++#ifdef ARCH_NEEDS_lshrdi3
++
++DWtype __lshrdi3(DWtype u, word_type b)
++{
++	DWunion uu, w;
++	word_type bm;
++
++	if (b == 0)
++		return u;
++
++	uu.ll = u;
++	bm = (sizeof(Wtype) * BITS_PER_UNIT) - b;
++
++	if (bm <= 0) {
++		w.s.high = 0;
++		w.s.low = (UWtype) uu.s.high >> -bm;
++	} else {
++		const UWtype carries = (UWtype) uu.s.high << bm;
++
++		w.s.high = (UWtype) uu.s.high >> b;
++		w.s.low = ((UWtype) uu.s.low >> b) | carries;
++	}
++
++	return w.ll;
++}
++
++EXPORT_SYMBOL(__lshrdi3);
++
++#endif /* ARCH_NEEDS_lshrdi3 */



More information about the Kernel-svn-changes mailing list