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