[lkml]   [2001]   [Nov]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    SubjectRe: i386 flags register clober in inline assembly
    In article <> you write:
    >They don't need to be. On i386, the flags are (partly for historical reasons) clobbered
    >by default.

    However, this is one area where I would just be tickled pink if gcc were
    to allow asm's to return status in eflags, even if that means that we
    need to fix all our existing asms.

    We have some really _horrid_ code where we use operations that
    intrinsically set the flag bits, and we actually want to use them.
    Using things like cmpxchg, and atomic decrement-and-test-with-zero have
    these horrid asm statements that have to move the eflags value (usually
    just one bit) into a register, so that we can tell gcc where it is.

    (Example code:

    __asm__ __volatile__(
    LOCK "subl %2,%0; sete %1"
    :"=m" (v->counter), "=qm" (c)
    :"ir" (i), "m" (v->counter) : "memory");

    Where we first get the value we _really_ want in ZF in eflags, then we
    use "sete" to move it to a register, and then gcc will end up generating
    code to test that register by hand, so the end result is usually
    something like:

    lock ; decl 20(%edi); sete %al
    testb %al, %al
    je .L1570

    even though what we'd _want_ is really

    lock ; decl 20(%edi)
    jne .L1570

    which is not only smaller and faster, but is often _really_ faster
    because at least some Intel CPU's will forward the flags values to the
    branch prediction stuff, and going through a register dependency will
    add non-forwarded state and thus extra cycles.

    So I would personally _really_ really like for some way to expose the
    internal gcc

    "(set (cc0) ..asm..)"

    construct, together with some way of setting the cc_status.flags.

    >From what I can tell, all the x86 machine description already uses "cc0"
    together with the notion of comparing it to zero (either signed or
    unsigned), so something like this _might_ just work

    unsigned long result;
    asm volatile(
    LOCK "decl %m"
    :"+m" (v->counter),
    "=cc" (result)
    : :"memory");
    if (result > 0) /* "jnb" */

    which would be wonderful, and would expand to

    (set (cc0) ..asm..)
    (set (pc)
    (if_then_else (gtu (cc0) (const_int 0))
    (label_ref (match_operand ..

    Which _should_ just automatically give us

    lock ; decl ..
    ja ..

    which is exactly what we want.

    I know this used to be impossible in gcc, because the x86 didn't
    actually track the flags values, and conditional jumps were really a
    _combination_ of the conditional and the jump, and splitting it up so
    that the conditional would be in an asm was thus not possible.

    But I think gcc makes cc0 explicit on x86 these days, and that the above
    kind of setup might be possible today, no?

    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to
    More majordomo info at
    Please read the FAQ at

     \ /
      Last update: 2005-03-22 13:13    [W:0.025 / U:1.784 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site