Fix the 64-bit i386 atomic according to assembly output
The assembly output showed that GCC was generating some wrong code in some conditions, so update the constraints so it will do the right thing: the expectedValue constraint needs to be in/out with early clobber. In/out because cmpxchg8b really does produce output and, even if we don't care about it, GCC needs to be told that the registers used (EAX:EDX) were modified. The early clobber is necessary so it won't schedule EAX or EDX to be the same as the EBX_reg (the register we'll xchg EBX with). Since EAX and EDX are in/out and EBX can't be used, the only remaining low register for the "sete" instruction is CL. So use it directly and set ECX to be in/out too. For whatever reason, it can't find enough registers in debug mode and this expansion doesn't work. It looks like a bug though, since this requires 4 registers and one memory operand and in debug mode it must have EAX, ECX, EDX, ESI and EDI free for use. One of ESI or EDI is used to xchg EBX with, which means there must be at least one more free general register. Change-Id: I1f11e68d776bf9ad216b34ca316a53129122fabe Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
This commit is contained in:
parent
fe778b94bd
commit
99802f0c14
@ -322,17 +322,17 @@ template <> struct QBasicAtomicOps<8>: QGenericAtomicOps<QBasicAtomicOps<8> >
|
||||
# define EBX_reg "b"
|
||||
# define EBX_load(reg)
|
||||
#endif
|
||||
unsigned char ret;
|
||||
quint32 highExpectedValue = quint32(newValue >> 32); // ECX
|
||||
asm volatile(EBX_load("%3")
|
||||
"lock\n"
|
||||
"cmpxchg8b %0\n"
|
||||
EBX_load("%3")
|
||||
"sete %1\n"
|
||||
: "+m" (_q_value), "=qm" (ret),
|
||||
"+A" (expectedValue)
|
||||
: EBX_reg (quint32(newValue & 0xffffffff)), "c" (quint32(newValue >> 32))
|
||||
"sete %%cl\n"
|
||||
: "+m" (_q_value), "+c" (highExpectedValue), "+&A" (expectedValue)
|
||||
: EBX_reg (quint32(newValue & 0xffffffff))
|
||||
: "memory");
|
||||
return ret != 0;
|
||||
// if the comparison failed, expectedValue here contains the current value
|
||||
return quint8(highExpectedValue) != 0;
|
||||
#undef EBX_reg
|
||||
#undef EBX_load
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user