2006-12-13 12:52:42

by Meelis Roos

[permalink] [raw]
Subject: V4L2: __ucmpdi2 undefined on ppc

MODPOST 618 modules
WARNING: "__ucmpdi2" [drivers/media/video/v4l2-common.ko] undefined!

This 32-bit ppc architecture, using gcc version 4.1.2 20061115
(prerelease) (Debian 4.1.1-21). .config below if important.

__ucmpdi2 seems to be 64-bit comparision. gcc seems to use it for switch
statements on 64-bit values.

drivers/media/video/v4l2-common.c::v4l2_norm_to_name seems to be one
such switch statement - type of id is v4l2_std_id which is 64-bit.

Should ppc have __ucmpdi2 defined in arch-specific lib? Some other
architectures seem to implement it (arm, arm26, frv, h8300).

--
Meelis Roos ([email protected])


2006-12-13 13:21:22

by Paweł Sikora

[permalink] [raw]
Subject: Re: V4L2: __ucmpdi2 undefined on ppc

Meelis Roos napisał(a):
> MODPOST 618 modules
> WARNING: "__ucmpdi2" [drivers/media/video/v4l2-common.ko] undefined!
>
> This 32-bit ppc architecture, using gcc version 4.1.2 20061115
> (prerelease) (Debian 4.1.1-21). .config below if important.
>
> __ucmpdi2 seems to be 64-bit comparision. gcc seems to use it for switch
> statements on 64-bit values.
>
> drivers/media/video/v4l2-common.c::v4l2_norm_to_name seems to be one
> such switch statement - type of id is v4l2_std_id which is 64-bit.
>
> Should ppc have __ucmpdi2 defined in arch-specific lib? Some other
> architectures seem to implement it (arm, arm26, frv, h8300).

maybe it's new gcc bug.

[ already fixed ]
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21237
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25724

2006-12-13 23:42:20

by Mauro Carvalho Chehab

[permalink] [raw]
Subject: Re: V4L2: __ucmpdi2 undefined on ppc

Em Qua, 2006-12-13 ?s 14:11 +0200, Meelis Roos escreveu:
> MODPOST 618 modules
> WARNING: "__ucmpdi2" [drivers/media/video/v4l2-common.ko] undefined!
>
> This 32-bit ppc architecture, using gcc version 4.1.2 20061115
> (prerelease) (Debian 4.1.1-21). .config below if important.
Hmm... does it work with gcc 4.0?
>
> __ucmpdi2 seems to be 64-bit comparision. gcc seems to use it for switch
> statements on 64-bit values.
Argh! if this is caused by switch / ifs, compilation will fail on other
places.

Cheers,
Mauro.

2006-12-14 19:58:47

by Kyle McMartin

[permalink] [raw]
Subject: Re: V4L2: __ucmpdi2 undefined on ppc

On Wed, Dec 13, 2006 at 09:41:56PM -0200, Mauro Carvalho Chehab wrote:
> Argh! if this is caused by switch / ifs, compilation will fail on other
> places.
>

I posted a patch to Paul this week to fix this, as saw we saw it on
Ubuntu's powerpc kernel builds.

Since ppc32 can't do a 64bit comparison on its own it seems, gcc
will generate a call to a helper function from libgcc. What other
arches do is link libgcc.a into libs-y, and export the symbol
they want from it. The build process will discard the rest of the
.a that is unused. parisc uses this method, for example.

Gcc targets can provide optimized versions of these helpers in
assembly, but at least in this case, the generic C version seems
to be used everywhere. It might be useful to provide kernel local
copies of these C versions linked __weak or something if the
arch happens to need them.

(Not going to sign off or anything, since I've already sent it to
paulus@ and I don't want it to get merged without his approval...)

Cheers,
Kyle

---
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index a00fe72..5b60c05 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -139,6 +139,8 @@ core-$(CONFIG_XMON) += arch/powerpc/xmon/

drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/

+libs-y += `$(CC) -print-libgcc-file-name`
+
# Default to zImage, override when needed
defaultimage-y := zImage
defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 9179f07..dea8384 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -164,6 +164,9 @@ long long __lshrdi3(long long, int);
EXPORT_SYMBOL(__ashrdi3);
EXPORT_SYMBOL(__ashldi3);
EXPORT_SYMBOL(__lshrdi3);
+
+extern void __ucmpdi2(void);
+EXPORT_SYMBOL(__ucmpdi2);
#endif

EXPORT_SYMBOL(memcpy);

2006-12-16 18:15:27

by Mauro Carvalho Chehab

[permalink] [raw]
Subject: Re: V4L2: __ucmpdi2 undefined on ppc

> I posted a patch to Paul this week to fix this, as saw we saw it on
> Ubuntu's powerpc kernel builds.
>
> Since ppc32 can't do a 64bit comparison on its own it seems, gcc
> will generate a call to a helper function from libgcc. What other
> arches do is link libgcc.a into libs-y, and export the symbol
> they want from it. The build process will discard the rest of the
> .a that is unused. parisc uses this method, for example.
>
> Gcc targets can provide optimized versions of these helpers in
> assembly, but at least in this case, the generic C version seems
> to be used everywhere. It might be useful to provide kernel local
> copies of these C versions linked __weak or something if the
> arch happens to need them.
>
> (Not going to sign off or anything, since I've already sent it to
> paulus@ and I don't want it to get merged without his approval...)

Seems to be a good way to solve it.


> ---
> diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
> index a00fe72..5b60c05 100644
> --- a/arch/powerpc/Makefile
> +++ b/arch/powerpc/Makefile
> @@ -139,6 +139,8 @@ core-$(CONFIG_XMON) += arch/powerpc/xmon/
>
> drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
>
> +libs-y += `$(CC) -print-libgcc-file-name`
> +
> # Default to zImage, override when needed
> defaultimage-y := zImage
> defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
> diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
> index 9179f07..dea8384 100644
> --- a/arch/powerpc/kernel/ppc_ksyms.c
> +++ b/arch/powerpc/kernel/ppc_ksyms.c
> @@ -164,6 +164,9 @@ long long __lshrdi3(long long, int);
> EXPORT_SYMBOL(__ashrdi3);
> EXPORT_SYMBOL(__ashldi3);
> EXPORT_SYMBOL(__lshrdi3);
> +
> +extern void __ucmpdi2(void);
> +EXPORT_SYMBOL(__ucmpdi2);
> #endif
>
> EXPORT_SYMBOL(memcpy);
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
Cheers,
Mauro.

2006-12-17 13:29:12

by David Woodhouse

[permalink] [raw]
Subject: Re: V4L2: __ucmpdi2 undefined on ppc

On Thu, 2006-12-14 at 14:58 -0500, Kyle McMartin wrote:
> I posted a patch to Paul this week to fix this,

Hm, I didn't see it on linuxppc-dev.

> Since ppc32 can't do a 64bit comparison on its own it seems, gcc
> will generate a call to a helper function from libgcc. What other
> arches do is link libgcc.a into libs-y, and export the symbol
> they want from it.

You still get to 'accidentally' do 64-bit arithmetic in-kernel that way
though. Might be better just to provide __ucmpdi2, just as we have for
the other functions which are required from libgcc

It'd be better just to fix the compiler though -- which is in fact what
they've done: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25724
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21237

I've applied this as a temporary hack to the Fedora kernel until the
compiler is updated there...

--- linux-2.6.19.ppc/arch/powerpc/kernel/misc_32.S~ 2006-11-29 21:57:37.000000000 +0000
+++ linux-2.6.19.ppc/arch/powerpc/kernel/misc_32.S 2006-12-17 12:19:48.000000000 +0000
@@ -728,6 +728,27 @@ _GLOBAL(__lshrdi3)
or r4,r4,r7 # LSW |= t2
blr

+/*
+ * __ucmpdi2: 64-bit comparison
+ *
+ * R3/R4 has 64 bit value A
+ * R5/R6 has 64 bit value B
+ * result in R3: 0 for A < B
+ * 1 for A == B
+ * 2 for A > B
+ */
+_GLOBAL(__ucmpdi2)
+ cmplw r7,r3,r5 # compare high words
+ li r3,0
+ blt r7,2f # a < b ... return 0
+ bgt r7,1f # a > b ... return 2
+ cmplw r6,r4,r6 # compare low words
+ blt r6,2f # a < b ... return 0
+ li r3,1
+ ble r6,2f # a = b ... return 1
+1: li r3,2
+2: blr
+
_GLOBAL(abs)
srawi r4,r3,31
xor r3,r3,r4
--- linux-2.6.19.ppc/arch/powerpc/kernel/ppc_ksyms.c~ 2006-12-15 17:19:56.000000000 +0000
+++ linux-2.6.19.ppc/arch/powerpc/kernel/ppc_ksyms.c 2006-12-17 12:16:54.000000000 +0000
@@ -161,9 +161,11 @@ EXPORT_SYMBOL(to_tm);
long long __ashrdi3(long long, int);
long long __ashldi3(long long, int);
long long __lshrdi3(long long, int);
+int __ucmpdi2(uint64_t, uint64_t);
EXPORT_SYMBOL(__ashrdi3);
EXPORT_SYMBOL(__ashldi3);
EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__ucmpdi2);
#endif

EXPORT_SYMBOL(memcpy);

--
dwmw2

2008-03-02 18:49:05

by Stephane Marchesin

[permalink] [raw]
Subject: Re: V4L2: __ucmpdi2 undefined on ppc

On 2/6/08, Stephane Marchesin <[email protected]> wrote:
>
> We're hitting this i nouveau as well (http://nouveau.freedesktop.org),
> since we make extensive use ot 64 bit ints. Over time, we've had a
> number of reports on this issue, and at one point I read that it
> should be fixed in gcc. But recently, a nouveau user on PPC32 (Henrik
> in CC:) reported the issue again with gcc 4.2.3. Others have it on gcc
> 4.2.2 too:
> http://bugs.freedesktop.org/show_bug.cgi?id=10547
>
> So, the point of this email is to ask about the possibility of merging
> in one of the __ucmpdi2 patches, like David's which is kept below for
> reference. Most distros seem to ship with such a patch already, and it
> seems that other drivers hit this as well.
>

So, could we have that thing in main tree ? It's not like it's
untested, most distros carry that, and a couple of arches provide
their own ucmpdi2 implementation already. It's also such a small
function...

Stephane