diff --git a/include/wine/port.h b/include/wine/port.h index c7a9e36e950..8861408c334 100644 --- a/include/wine/port.h +++ b/include/wine/port.h @@ -50,6 +50,14 @@ * Type definitions */ +#if !defined(_MSC_VER) && !defined(__int64) +# if defined(__x86_64__) || defined(_WIN64) +# define __int64 long +# else +# define __int64 long long +# endif +#endif + #ifndef HAVE_MODE_T typedef int mode_t; #endif @@ -359,6 +367,7 @@ extern int spawnvp(int mode, const char *cmdname, const char * const argv[]); extern inline int interlocked_cmpxchg( int *dest, int xchg, int compare ); extern inline void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare ); +extern __int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare ); extern inline int interlocked_xchg( int *dest, int val ); extern inline void *interlocked_xchg_ptr( void **dest, void *val ); extern inline int interlocked_xchg_add( int *dest, int incr ); @@ -407,6 +416,7 @@ extern inline int interlocked_xchg_add( int *dest, int incr ) extern int interlocked_cmpxchg( int *dest, int xchg, int compare ); extern void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare ); +extern __int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare ); extern int interlocked_xchg( int *dest, int val ); extern void *interlocked_xchg_ptr( void **dest, void *val ); extern int interlocked_xchg_add( int *dest, int incr ); diff --git a/libs/port/interlocked.c b/libs/port/interlocked.c index ea32cefa8be..6e49437bd8e 100644 --- a/libs/port/interlocked.c +++ b/libs/port/interlocked.c @@ -20,6 +20,7 @@ #include "config.h" #include "wine/port.h" +#include #ifdef __i386__ @@ -37,6 +38,18 @@ __ASM_GLOBAL_FUNC(interlocked_cmpxchg_ptr, "movl 4(%esp),%edx\n\t" "lock; cmpxchgl %ecx,(%edx)\n\t" "ret") + __ASM_GLOBAL_FUNC(interlocked_cmpxchg64, + "push %ebx\n\t" + "push %esi\n\t" + "movl 12(%esp),%esi\n\t" + "movl 16(%esp),%ebx\n\t" + "movl 20(%esp),%ecx\n\t" + "movl 24(%esp),%eax\n\t" + "movl 28(%esp),%edx\n\t" + "lock; cmpxchg8b (%esi)\n\t" + "pop %esi\n\t" + "pop %ebx\n\t" + "ret"); __ASM_GLOBAL_FUNC(interlocked_xchg, "movl 8(%esp),%eax\n\t" "movl 4(%esp),%edx\n\t" @@ -73,6 +86,21 @@ __declspec(naked) void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void * __asm ret; } +__declspec(naked) __int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare) +{ + __asm push ebx; + __asm push esi; + __asm mov esi, 12[esp]; + __asm mov ebx, 16[esp]; + __asm mov ecx, 20[esp]; + __asm mov eax, 24[esp]; + __asm mov edx, 28[esp]; + __asm lock cmpxchg8b [esi]; + __asm pop esi; + __asm pop ebx; + __asm ret; +} + __declspec(naked) int interlocked_xchg( int *dest, int val ) { __asm mov eax, 8[esp]; @@ -113,6 +141,11 @@ __ASM_GLOBAL_FUNC(interlocked_cmpxchg_ptr, "mov %rdx, %rax\n\t" "lock cmpxchgq %rsi,(%rdi)\n\t" "ret") +__int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare) +{ + /* FIXME: add code */ + assert(0); +} __ASM_GLOBAL_FUNC(interlocked_xchg, "mov %esi, %eax\n\t" "lock xchgl %eax, (%rdi)\n\t" @@ -149,6 +182,12 @@ void* interlocked_cmpxchg_ptr( void **dest, void* xchg, void* compare) return ret; } +__int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare) +{ + /* FIXME: add code */ + assert(0); +} + int interlocked_cmpxchg( int *dest, int xchg, int compare) { int ret = 0; @@ -244,6 +283,15 @@ void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare ) return compare; } +__int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare ) +{ + _lwp_mutex_lock( &interlocked_mutex ); + if (*dest == compare) *dest = xchg; + else compare = *dest; + _lwp_mutex_unlock( &interlocked_mutex ); + return compare; +} + int interlocked_xchg( int *dest, int val ) { int retv; @@ -300,6 +348,12 @@ __ASM_GLOBAL_FUNC(interlocked_cmpxchg_ptr, "L1cmpxchg_ptr:\n\t" "mb") +__int64 interlocked_cmpxchg64(__int64 *dest, __int64 xchg, __int64 compare) +{ + /* FIXME: add code */ + assert(0); +} + __ASM_GLOBAL_FUNC(interlocked_xchg, "L0xchg:\n\t" "ldl_l $0,0($16)\n\t"