/* Note 2: xchg has side effect, so that attribute volatile is necessary, but generally the primitive is invalid, *ptr is output argument.  */
static unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
/* Note 2: xchg has side effect, so that attribute volatile is necessary, but generally the primitive is invalid, *ptr is output argument.  */
static unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
{
	switch (size) {
	case 1:
		__asm__ __volatile__("xchgb %b0,%1"
			: "=q" (x)
			: "m" (*__xg(ptr)), "0" (x)
			: "memory");
		break;
	case 2:
		__asm__ __volatile__("xchgw %w0,%1"
			: "=r" (x)
			: "m" (*__xg(ptr)), "0" (x)
			: "memory");
		break;
	case 4:
		__asm__ __volatile__("xchgl %0,%1"
			: "=r" (x)
			: "m" (*__xg(ptr)), "0" (x)
			: "memory");
		break;
	}
	return x;
}