lkml.org 
[lkml]   [1998]   [Oct]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: 2.2.0 and egcs 1.1 was Re: Sorry, wrong gcc-version

    > > Actually this is not entirely correct. Even 2.1.x kernels still have lots
    > > of incorrect inline assembler constraints which can cause the compiler
    > > to misoptimize the kernel.

    First, I should note that there are two issues here: we have bugs related to
    inline assembly in both the kernel, and in the compiler. The compiler bugs
    are present in every version of gcc, not just gcc-2.8 or egcs.

    1. Explicitly clobbering a register is supposed to make it unavailable for
    both inputs and outputs of the same statement. This rule has been there
    for a long time; it's documented at least since gcc-2.6.0 (I have no earlier
    docs available at the moment; I suspect it's been there forever). This is
    from gcc.info, version 2.6.0:

    The input operands are guaranteed not to use any of the clobbered
    registers, and neither will the output operands' addresses, so you can
    read and write the clobbered registers as many times as you like.

    [Obviously, the clobbered regs aren't used for output operands either.]
    Thus, using a construct like
    __asm__ (" " : : "a" (somevalue) : "eax")
    is incorrect. This sort of thing occurs in the kernel, and it's a bug.
    It should be written as
    __asm__ (" " : "=&a" (dummy) : "0" (somevalue));

    2. Clobbers are dangerous on the i386. The compiler can't guarantee that
    even for a correctly-written asm, the clobbered register will not be used
    for another operand. Thus, it is highly advisable not to use clobbers
    at all, and to use earlyclobbers as described above. This is a compiler
    bug, and it's very closely related to the one that lets you use "a" as
    a constraint in the example above.

    All of this only affects the i386 and other machines for which gcc has to
    define the macro SMALL_REGISTER_CLASSES in the machine description. Without
    this macro, which normally isn't defined, gcc doesn't use registers which
    are explicitly mentioned anywhere in the internal representation at all for
    other purposes (like register allocation or for spill registers). That makes
    the code correct, but it would also make the compiler fail to work at all for
    a machine where registers can be used explicitly (like eax as the function
    return value) and be necessary for certain instructions (like some
    multiplications that also require eax).

    Thus, on most machines supported by gcc the incorrect asm statement above
    would cause a spill failure error, if it could be written for other machines
    (most other machine descriptions don't have single-register register classes).

    > I don't agree.
    >
    > The assembler used to be correct, and the gcc people unilaterally decided
    > to change the rules. As such, I don't think the asm is any more
    > "incorrect" than the new gcc versions are incorrect.

    The assembler never was correct. It happens to work most of the time, because
    even when SMALL_REGISTER_CLASSES is defined, the compiler puts the explicitly
    mentioned registers at the end of the list that it chooses its reload regs
    from. Only when it can't find any other register will it use any of the
    explicitly mentioned ones.

    > The changes I have seen break older compilers.

    In what ways?

    > So Andi, don't go saying that the kernel has problems, when it is equally
    > true to say that gcc has problems.

    Right. Both have problems. I'm currently working with the egcs people to
    fix the ones in gcc (make the compiler generate errors for the illegal asms,
    and avoid the whole SMALL_REGISTER_CLASSES nonsense). However, once the
    compiler is fixed, the current kernels will fail to compile.

    > > In short, if you want to play safe stay with 2.7.2.3 for kernel compilation.
    >
    > That, I think, everybody can agree on.

    Except that 2.7.2 is buggy as hell. It has the same problems as egcs when
    it comes to asm statements, it just happens you may not have seen them yet.
    Fact is, any change in the kernel could cause the 2.7.2 to fall over just
    as well.

    > For example, everybody in the egcs camp just decided that clobbers and
    > inputs must not overlap. Nobody told me why,

    Because it's documented that way. Because on sane machines, it has always
    worked that way.
    You seem to suggest that the meaning of clobbered registers should be
    redefined so that they work the way you expect them to work. Technically,
    that's feasible. However, for the kernel inline assembly, you'd be left with
    the oh-so-stable gcc-2.7.2 which still doesn't work properly. Worse,
    redefining the meaning of clobbers will suddenly make hundreds of correctly
    written asm statements for other machines as well as for the i386 generate
    incorrect code silently. Are you seriously proposing this is a good idea?

    > and why they can't just be
    > automatically converted to early-clobbers inside gcc.

    Clobbers in an asm statement can use a register number. The operands need
    a register class. There may not be a register class for a register you want
    to clobber (consider clobbering ebp which has no corresponding register class).

    Bernd


    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:45    [W:5.357 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site