From: Ralf Baechle <ralf@linux-mips.org>
To: "P. Christeas" <p_christ@hol.gr>
Cc: Martin Michlmayr <tbm@cyrius.com>, linux-mips@linux-mips.org
Subject: Re: undefined reference to `__lshrdi3' error with GCC 4.0
Date: Tue, 17 Jan 2006 19:08:59 +0000 [thread overview]
Message-ID: <20060117190859.GA2061@linux-mips.org> (raw)
In-Reply-To: <200601171617.16147.p_christ@hol.gr>
On Tue, Jan 17, 2006 at 04:17:14PM +0200, P. Christeas wrote:
> 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 */
next prev parent reply other threads:[~2006-01-17 19:05 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-01-17 13:48 undefined reference to `__lshrdi3' error with GCC 4.0 Martin Michlmayr
2006-01-17 14:17 ` P. Christeas
2006-01-17 15:14 ` Ralf Baechle
2006-01-17 15:50 ` P. Christeas
2006-01-17 16:21 ` Ralf Baechle
2006-01-17 19:08 ` Ralf Baechle [this message]
2006-01-17 19:38 ` Jan-Benedict Glaw
2006-01-17 20:11 ` Daniel Jacobowitz
2006-02-17 13:57 ` Martin Michlmayr
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060117190859.GA2061@linux-mips.org \
--to=ralf@linux-mips.org \
--cc=linux-mips@linux-mips.org \
--cc=p_christ@hol.gr \
--cc=tbm@cyrius.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.