Andrea Arcangeli wrote:
> >BTW Look also into asm-i386/bitops.h and dummy cast to some crap there.
> >Are you impressed? 8)
> 
> Yep 8). If we add "memory" such stuff could be removed I think. As far I
> can see the object of such stuff is to cause gcc to say `I'm too lazy to
> see exactly what memory this guy is trying to change, so just assume he
> added "memory" in the clobber list' :))

No, that's not the reason for __dummy.  It is an important side effect,
though as ever it isn't guaranteed.  Someone should add "memory" to the
bitops _iff_ the bitops are supposed to imply a compiler memory barrier.
It's a kernel policy decision.

     -----------

For the benefit of GCC list readers: Linux uses asm constraints like
this:  `"m" (*(volatile struct __dummy *) &object)', where __dummy is
defined by  `struct __dummy { unsigned long a[100]; }'.

This is used extensively in asms for spinlocks, semaphores and atomic
bit operations, atomic counters etc.  In short, anything needing to
operate on a specific memory object.

Passing the address as an operand would be correct but generates worse
code, because in general we don't need a register to hold the address of
`object'.  It is often part of a larger struct, and the __dummy method
lets it be addressed using offset addressing, and often fewer registers.

Casting via __dummy is there so that the "m" (or "=m") memory constraint
will make that operand refer to the actual object in memory, and not a
copy (in a different area of memory).

Most of the time there is no reason for GCC to use a copy of the object
for an "m" constraint, but things like CSE can allow the compiler to
choose a different object known to have the same contents.  Other
scenarios cause __dummy to be required for "=m" constraints.

(Even with __dummy there is no guarantee that a future GCC won't use a
different object anyway, but I expect that is years away).

I'm posting this to the GCC list to make a feature request.

GCC feature request
-------------------

An additional constraint character, like "m" but means "the object at
the specified address".

The operand in C source code would be the object's address (not
dereferenced as Linux does now), so there is no need for bizarre
semantics.

So if I write (assume `@' because most letters are taken):

   asm ("movl %1,%0" : "=g" (result) : "@" (&object));

it would a clean equivalent to this:

   asm ("movl %1,%0" : "=g" (result)
                     : "m" (*(volatile struct __dummy *) &object));

and more or less equivalent to this (but generates better code):

   asm ("movl (%1),%0" : "=g" (result) : "r" (&object));

An alternative would be a modifier to "m" that means "definitely use the
actual object referred to".  I prefer the direct approach.

What do GCC designers think?  This is useful for any code that must use
asms for atomic operations such as semaphores in threads etc.

-- Jamie
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to