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