diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-05-25 13:07:42 +0000 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-05-25 13:07:42 +0000 |
commit | e69550b83aef6e4cb61602239cde612355d3d27c (patch) | |
tree | 16246d73f19b302545bbcc9e45fe69e88c8a8936 /xen/include/asm-x86/system.h | |
parent | 28d92ab92e4f70afd59b0a90ccb6564313d9b802 (diff) | |
download | xen-e69550b83aef6e4cb61602239cde612355d3d27c.tar.gz xen-e69550b83aef6e4cb61602239cde612355d3d27c.tar.bz2 xen-e69550b83aef6e4cb61602239cde612355d3d27c.zip |
bitkeeper revision 1.1551 (4294789ea5Ghsn6s5aIMFHK5LY4uSw)
Add 64-bit (cmpxchg8b) support to the cmpxchg() macro for x86_32.
Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'xen/include/asm-x86/system.h')
-rw-r--r-- | xen/include/asm-x86/system.h | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/xen/include/asm-x86/system.h b/xen/include/asm-x86/system.h index cd0619008d..a614d11b4a 100644 --- a/xen/include/asm-x86/system.h +++ b/xen/include/asm-x86/system.h @@ -2,6 +2,7 @@ #define __ASM_SYSTEM_H #include <xen/config.h> +#include <xen/types.h> #include <asm/bitops.h> /* Clear and set 'TS' bit respectively */ @@ -70,8 +71,8 @@ static always_inline unsigned long __xchg(unsigned long x, volatile void * ptr, * indicated by comparing RETURN with OLD. */ -static always_inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, - unsigned long new, int size) +static always_inline unsigned long __cmpxchg( + volatile void *ptr, unsigned long old, unsigned long new, int size) { unsigned long prev; switch (size) { @@ -113,9 +114,49 @@ static always_inline unsigned long __cmpxchg(volatile void *ptr, unsigned long o } #define __HAVE_ARCH_CMPXCHG -#define cmpxchg(ptr,o,n)\ - ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ - (unsigned long)(n),sizeof(*(ptr)))) + +#if BITS_PER_LONG == 64 + +#define cmpxchg(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \ + (unsigned long)(n),sizeof(*(ptr)))) +#else + +static always_inline unsigned long long __cmpxchg8b( + volatile void *ptr, unsigned long long old, unsigned long long new) +{ + unsigned long long prev; + __asm__ __volatile__ ( + LOCK_PREFIX "cmpxchg8b %3" + : "=A" (prev) + : "c" ((u32)(new>>32)), "b" ((u32)new), + "m" (*__xg((volatile void *)ptr)), "0" (old) + : "memory" ); + return prev; +} + +#define cmpxchg(ptr,o,n) \ +({ \ + __typeof__(*(ptr)) __prev; \ + switch ( sizeof(*(ptr)) ) { \ + case 8: \ + __prev = ((__typeof__(*(ptr)))__cmpxchg8b( \ + (ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n))); \ + break; \ + default: \ + __prev = ((__typeof__(*(ptr)))__cmpxchg( \ + (ptr), \ + (unsigned long)(o), \ + (unsigned long)(n), \ + sizeof(*(ptr)))); \ + break; \ + } \ + __prev; \ +}) + +#endif /* |