Compiling 2.6.24.5 kernel with GCC 4.4

112 views
Skip to first unread message

Dok Sander

unread,
Aug 26, 2009, 12:43:45 PM8/26/09
to gd...@googlegroups.com
I'm trying to compile the Linux 2.6.24.5 kernel wíth Mandriva patches applied for Gdium using self-compiled toolchain. The build fails due to the following error:

arch/mips/lemote/lm2f/irq.c: In function 'plat_irq_dispatch':
include/asm/delay.h:74: error: impossible constraint in 'asm'
make[1]: *** [arch/mips/lemote/lm2f/irq.o] Error 1

My gcc is of version 4.4 and the code is apparently incompatible with a newer version of the compiler: http://gcc.gnu.org/gcc-4.4/changes.html

This is what's on the line 74 of delay.h and what follows:

                __asm__("dmultu\t%2, %3"
                : "=h" (usecs), "=l" (lo)
                : "r" (usecs), "r" (lpj)
                : GCC_REG_ACCUM);


And the portion of GCC 4.4 changes that makes this code incompliant:

The MIPS port no longer recognizes the
h asm constraint. It was necessary to remove this constraint in order to avoid generating unpredictable code sequences.

One of the main uses of the h constraint was to extract the high part of a multiplication on 64-bit targets. For example:

    asm ("dmultu\t%1,%2" : "=h" (result) : "r" (x), "r" (y));

You can now achieve the same effect using 128-bit types:

    typedef unsigned int uint128_t __attribute__((mode(TI)));
result = ((uint128_t) x * y) >> 64;

The second sequence is better in many ways. For example, if x and y are constants, the compiler can perform the multiplication at compile time. If x and y are not constants, the compiler can schedule the runtime multiplication better than it can schedule an asm statement.



So, does anyone know if there's a patch or how to fix this :) ?

  Thanks,



Philippe Vachon

unread,
Aug 26, 2009, 12:54:58 PM8/26/09
to gd...@googlegroups.com
Hi Dok,

You'll need to replace it with the following (this isn't actually a
complete solution, FWIW, but it should get your kernel building on the
Gdium):

__asm__("dmultu\t%1, %2\n"
"mfhi\t%0"
: "=r" (usecs)
: "r" (usecs), "r" (lpj)
: GCC_REG_ACCUM);

That _should_ do the trick (unfortunately, I don't have a cross
compiler here to test that with).

Cheers,
Phil

Måns Rullgård

unread,
Aug 26, 2009, 1:04:12 PM8/26/09
to gd...@googlegroups.com
Dok Sander <doks...@yahoo.com> writes:

> I'm trying to compile the Linux 2.6.24.5 kernel wíth Mandriva patches applied for Gdium using self-compiled toolchain. The build fails due to the following error:
>
> arch/mips/lemote/lm2f/irq.c: In function 'plat_irq_dispatch':
> include/asm/delay.h:74: error: impossible constraint in 'asm'
> make[1]: *** [arch/mips/lemote/lm2f/irq.o] Error 1
>
> My gcc is of version 4.4 and the code is apparently incompatible with a newer version of the compiler: http://gcc.gnu.org/gcc-4.4/changes.html
>
> This is what's on the line 74 of delay.h and what follows:
>
>                 __asm__("dmultu\t%2, %3"
>                 : "=h" (usecs), "=l" (lo)
>                 : "r" (usecs), "r" (lpj)
>                 : GCC_REG_ACCUM);
>
> And the portion of GCC 4.4 changes that makes this code incompliant:
>
> The MIPS port no longer recognizes the h
> asm constraint. It was necessary to remove
> this constraint in order to avoid generating unpredictable
> code sequences.

That sounds like a lazy excuse for not fixing the real bug. Typical
of gcc devs.

> One of the main uses of the h constraint
> was to extract the high part of a multiplication on
> 64-bit targets. For example:
> asm ("dmultu\t%1,%2" : "=h" (result) : "r" (x), "r" (y));
> You can now achieve the same effect using 128-bit types:
> typedef unsigned int uint128_t __attribute__((mode(TI)));
> result = ((uint128_t) x * y) >> 64;
> The second sequence is better in many ways. For example,
> if x and y are constants, the
> compiler can perform the multiplication at compile time.
> If x and y are not constants,
> the compiler can schedule the runtime multiplication
> better than it can schedule an asm statement.

I would be *very* careful about using such code. More often than not,
operations on larger-than-native types with gcc blows up code size to
monstrous proportions.

> So, does anyone know if there's a patch or how to fix this :) ?

For a quick solution, you could rewrite the asm like this (untested):

                __asm__("dmultu %2, %3 \n\t"
"mfhi %0 \n\t"
                : "=r" (usecs), "=l" (lo)


                : "r" (usecs), "r" (lpj)
                : GCC_REG_ACCUM);

This will of course stall until the multiplication is finished,
whereas the old version theoretically could have deferred the mfhi
until the result is needed, but I doubt gcc was ever that clever.

--
Måns Rullgård
ma...@mansr.com

Dok Sander

unread,
Aug 27, 2009, 4:27:49 AM8/27/09
to gd...@googlegroups.com
Thanks guys. I can compile the kernel now.

--- On Wed, 8/26/09, Måns Rullgård <ma...@mansr.com> wrote:

From: Måns Rullgård <ma...@mansr.com>
Subject: [OLPH] Re: Compiling 2.6.24.5 kernel with GCC 4.4
To: gd...@googlegroups.com
Date: Wednesday, August 26, 2009, 5:04 PM


Dok Sander <doks...@yahoo.com> writes:

> I'm trying to compile the Linux 2.6.24.5 kernel wíth Mandriva patches applied for Gdium using self-compiled toolchain. The build fails due to the following error:
>
> arch/mips/lemote/lm2f/irq.c: In function 'plat_irq_dispatch':
> include/asm/delay.h:74: error: impossible constraint in 'asm'
> make[1]: *** [arch/mips/lemote/lm2f/irq.o] Error 1
>
> My gcc is of version 4.4 and the code is apparently incompatible with a newer version of the compiler: http://gcc.gnu.org/gcc-4.4/changes.html
>
> This is what's on the line 74 of delay.h and what follows:
>
>                 __asm__("dmultu\t%2, %3"
>                 : "=h" (usecs), "=l" (lo)
>                 : "r" (usecs), "r" (lpj)
>                 : GCC_REG_ACCUM);
>
> And the portion of GCC 4.4 changes that makes this code incompliant:
>
> The MIPS port no longer recognizes the h
>     asm constraint.  It was necessary to remove
>     this constraint in order to avoid generating unpredictable
>     code sequences.

That sounds like a lazy excuse for not fixing the real bug.  Typical
of gcc devs.

>     One of the main uses of the h constraint
>     was to extract the high part of a multiplication on
>     64-bit targets..  For example:
start: 0000-00-00 end: 0000-00-00
Reply all
Reply to author
Forward
0 new messages