Phil Endecott <[EMAIL PROTECTED]> writes:

> I'm having trouble compiling code that uses the following macro from
> the Apache Portable Runtime:
> 
> #define apr_atomic_cas(mem,with,cmp) \
> ({ apr_atomic_t prev; \
>      asm volatile ("lock; cmpxchgl %1, %2"              \
>           : "=a" (prev)               \
>           : "r" (with), "m" (*(mem)), "0"(cmp) \
>           : "memory"); \
>      prev;})
> 
> It seems that on some machines it tries to use the AMD64 register
> %dil, which does not exist on a regular x86 machine, and gives an
> assembler error.
> 
> I've found bug 10153 and its duplicates which seem to be describing
> essentially the same thing, but say that the input is invalid because
> it uses "r" rather than "q".  I don't know enough about x86 to
> understand this; presumably only certain registers can be used with
> this instruction, or something.
> 
> However, naively, I'd argue that it is never right for gcc to use a
> register that doesn't exist on the target architecture.  Can someone
> justify its behaviour?  If the input is illegal surely it should
> generate an error.

The use of cmpxchgl implies that a full 32-bit register value is
expected.  I would guess that the code is passing in a char value.
That would cause gcc to print the name of the register in char mode,
which for %edi is %dil.

It would be straightforward to teach gcc to not use %dil when not on
AMD64.  But it wouldn't help.  You apparently do have a char in %edi,
but with cmpxchgl you really want an int.

Changing "(with)" to "((int) with)" might do it.  It would probably
work to use %k1 instead of %1, though I doubt that is documented
anywhere, and it assumes that %edi holds a correct 32-bit value, which
is not guaranteed.

Ian

Reply via email to