Commit f06d99f6 authored by Alexandre Julliard's avatar Alexandre Julliard

include: Implemented inline asm functions for x86_64. Export Interlocked* only on i386.

parent fa616418
...@@ -722,12 +722,12 @@ ...@@ -722,12 +722,12 @@
@ stdcall InitializeCriticalSectionAndSpinCount(ptr long) @ stdcall InitializeCriticalSectionAndSpinCount(ptr long)
@ stdcall InitializeCriticalSectionEx(ptr long long) @ stdcall InitializeCriticalSectionEx(ptr long long)
@ stdcall InitializeSListHead(ptr) ntdll.RtlInitializeSListHead @ stdcall InitializeSListHead(ptr) ntdll.RtlInitializeSListHead
@ stdcall InterlockedCompareExchange (ptr long long) @ stdcall -arch=i386 InterlockedCompareExchange (ptr long long)
@ stdcall InterlockedDecrement(ptr) @ stdcall -arch=i386 InterlockedDecrement(ptr)
@ stdcall InterlockedExchange(ptr long) @ stdcall -arch=i386 InterlockedExchange(ptr long)
@ stdcall InterlockedExchangeAdd (ptr long ) @ stdcall -arch=i386 InterlockedExchangeAdd (ptr long )
@ stdcall InterlockedFlushSList(ptr) ntdll.RtlInterlockedFlushSList @ stdcall InterlockedFlushSList(ptr) ntdll.RtlInterlockedFlushSList
@ stdcall InterlockedIncrement(ptr) @ stdcall -arch=i386 InterlockedIncrement(ptr)
@ stdcall InterlockedPopEntrySList(ptr) ntdll.RtlInterlockedPopEntrySList @ stdcall InterlockedPopEntrySList(ptr) ntdll.RtlInterlockedPopEntrySList
@ stdcall InterlockedPushEntrySList(ptr ptr) ntdll.RtlInterlockedPushEntrySList @ stdcall InterlockedPushEntrySList(ptr ptr) ntdll.RtlInterlockedPushEntrySList
@ stub InvalidateConsoleDIBits @ stub InvalidateConsoleDIBits
......
...@@ -2314,93 +2314,4 @@ __ASM_GLOBAL_FUNC(InterlockedDecrement, ...@@ -2314,93 +2314,4 @@ __ASM_GLOBAL_FUNC(InterlockedDecrement,
"decl %eax\n\t" "decl %eax\n\t"
"ret $4") "ret $4")
#else /* __i386__ */
/***********************************************************************
* InterlockedCompareExchange (KERNEL32.@)
*
* Atomically swap one value with another.
*
* PARAMS
* dest [I/O] The value to replace
* xchq [I] The value to be swapped
* compare [I] The value to compare to dest
*
* RETURNS
* The resulting value of dest.
*
* NOTES
* dest is updated only if it is equal to compare, otherwise no swap is done.
*/
LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare )
{
return interlocked_cmpxchg( (int *)dest, xchg, compare );
}
/***********************************************************************
* InterlockedExchange (KERNEL32.@)
*
* Atomically swap one value with another.
*
* PARAMS
* dest [I/O] The value to replace
* val [I] The value to be swapped
*
* RETURNS
* The resulting value of dest.
*/
LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val )
{
return interlocked_xchg( (int *)dest, val );
}
/***********************************************************************
* InterlockedExchangeAdd (KERNEL32.@)
*
* Atomically add one value to another.
*
* PARAMS
* dest [I/O] The value to add to
* incr [I] The value to be added
*
* RETURNS
* The resulting value of dest.
*/
LONG WINAPI InterlockedExchangeAdd( LONG volatile *dest, LONG incr )
{
return interlocked_xchg_add( (int *)dest, incr );
}
/***********************************************************************
* InterlockedIncrement (KERNEL32.@)
*
* Atomically increment a value.
*
* PARAMS
* dest [I/O] The value to increment
*
* RETURNS
* The resulting value of dest.
*/
LONG WINAPI InterlockedIncrement( LONG volatile *dest )
{
return interlocked_xchg_add( (int *)dest, 1 ) + 1;
}
/***********************************************************************
* InterlockedDecrement (KERNEL32.@)
*
* Atomically decrement a value.
*
* PARAMS
* dest [I/O] The value to decrement
*
* RETURNS
* The resulting value of dest.
*/
LONG WINAPI InterlockedDecrement( LONG volatile *dest )
{
return interlocked_xchg_add( (int *)dest, -1 ) - 1;
}
#endif /* __i386__ */ #endif /* __i386__ */
...@@ -2315,9 +2315,10 @@ extern char *wine_get_unix_file_name( LPCWSTR dos ); ...@@ -2315,9 +2315,10 @@ extern char *wine_get_unix_file_name( LPCWSTR dos );
extern WCHAR *wine_get_dos_file_name( LPCSTR str ); extern WCHAR *wine_get_dos_file_name( LPCSTR str );
/* a few optimizations for i386/gcc */ /* Interlocked functions */
#if defined(__i386__) && defined(__GNUC__) && defined(__WINESRC__) && !defined(_NTSYSTEM_) #ifdef __i386__
# if defined(__GNUC__) && !defined(_NTSYSTEM_)
extern inline LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ); extern inline LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare );
extern inline LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) extern inline LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare )
...@@ -2358,11 +2359,118 @@ extern inline LONG WINAPI InterlockedDecrement( LONG volatile *dest ) ...@@ -2358,11 +2359,118 @@ extern inline LONG WINAPI InterlockedDecrement( LONG volatile *dest )
return InterlockedExchangeAdd( dest, -1 ) - 1; return InterlockedExchangeAdd( dest, -1 ) - 1;
} }
# else /* __GNUC__ */
WINBASEAPI LONG WINAPI InterlockedCompareExchange(LONG volatile*,LONG,LONG);
WINBASEAPI LONG WINAPI InterlockedDecrement(LONG volatile*);
WINBASEAPI LONG WINAPI InterlockedExchange(LONG volatile*,LONG);
WINBASEAPI LONG WINAPI InterlockedExchangeAdd(LONG volatile*,LONG);
WINBASEAPI LONG WINAPI InterlockedIncrement(LONG volatile*);
# endif /* __GNUC__ */
static inline PVOID WINAPI InterlockedCompareExchangePointer( PVOID volatile *dest, PVOID xchg, PVOID compare )
{
return (PVOID)InterlockedCompareExchange( (LONG volatile*)dest, (LONG)xchg, (LONG)compare );
}
static inline PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest, PVOID val )
{
return (PVOID)InterlockedExchange( (LONG volatile*)dest, (LONG)val );
}
#else /* __i386__ */
static inline LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare )
{
#if defined(__x86_64__) && defined(__GNUC__)
LONG ret;
__asm__ __volatile__( "lock; cmpxchgl %2,(%1)"
: "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );
return ret;
#else
extern int interlocked_cmpxchg( int *dest, int xchg, int compare );
return interlocked_cmpxchg( (int *)dest, xchg, compare );
#endif
}
static inline PVOID WINAPI InterlockedCompareExchangePointer( PVOID volatile *dest, PVOID xchg, PVOID compare )
{
#if defined(__x86_64__) && defined(__GNUC__)
PVOID ret;
__asm__ __volatile__( "lock; cmpxchgq %2,(%1)"
: "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );
return ret;
#else
extern void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare );
return interlocked_cmpxchg_ptr( (void **)dest, xchg, compare );
#endif
}
static inline LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val )
{
#if defined(__x86_64__) && defined(__GNUC__)
LONG ret;
__asm__ __volatile__( "lock; xchgl %0,(%1)"
: "=r" (ret) :"r" (dest), "0" (val) : "memory" );
return ret;
#else
extern int interlocked_xchg( int *dest, int val );
return interlocked_xchg( (int *)dest, val );
#endif
}
static inline PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest, PVOID val )
{
#if defined(__x86_64__) && defined(__GNUC__)
PVOID ret;
__asm__ __volatile__( "lock; xchgq %0,(%1)"
: "=r" (ret) :"r" (dest), "0" (val) : "memory" );
return ret;
#else
extern void *interlocked_xchg_ptr( void **dest, void *val );
return interlocked_xchg_ptr( (void **)dest, val );
#endif
}
static inline LONG WINAPI InterlockedExchangeAdd( LONG volatile *dest, LONG incr )
{
#if defined(__x86_64__) && defined(__GNUC__)
LONG ret;
__asm__ __volatile__( "lock; xaddl %0,(%1)"
: "=r" (ret) : "r" (dest), "0" (incr) : "memory" );
return ret;
#else
extern int interlocked_xchg_add( int *dest, int incr );
return interlocked_xchg_add( (int *)dest, incr );
#endif
}
static inline LONG WINAPI InterlockedIncrement( LONG volatile *dest )
{
return InterlockedExchangeAdd( dest, 1 ) + 1;
}
static inline LONG WINAPI InterlockedDecrement( LONG volatile *dest )
{
return InterlockedExchangeAdd( dest, -1 ) - 1;
}
#endif /* __i386__ */
/* A few optimizations for gcc */
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64))
extern inline DWORD WINAPI GetLastError(void); extern inline DWORD WINAPI GetLastError(void);
extern inline DWORD WINAPI GetLastError(void) extern inline DWORD WINAPI GetLastError(void)
{ {
DWORD ret; DWORD ret;
#ifdef __x86_64__
__asm__ __volatile__( ".byte 0x65\n\tmovl 0x68,%0" : "=r" (ret) );
#else
__asm__ __volatile__( ".byte 0x64\n\tmovl 0x34,%0" : "=r" (ret) ); __asm__ __volatile__( ".byte 0x64\n\tmovl 0x34,%0" : "=r" (ret) );
#endif
return ret; return ret;
} }
...@@ -2370,7 +2478,11 @@ extern inline DWORD WINAPI GetCurrentProcessId(void); ...@@ -2370,7 +2478,11 @@ extern inline DWORD WINAPI GetCurrentProcessId(void);
extern inline DWORD WINAPI GetCurrentProcessId(void) extern inline DWORD WINAPI GetCurrentProcessId(void)
{ {
DWORD ret; DWORD ret;
#ifdef __x86_64__
__asm__ __volatile__( ".byte 0x65\n\tmovl 0x40,%0" : "=r" (ret) );
#else
__asm__ __volatile__( ".byte 0x64\n\tmovl 0x20,%0" : "=r" (ret) ); __asm__ __volatile__( ".byte 0x64\n\tmovl 0x20,%0" : "=r" (ret) );
#endif
return ret; return ret;
} }
...@@ -2378,62 +2490,46 @@ extern inline DWORD WINAPI GetCurrentThreadId(void); ...@@ -2378,62 +2490,46 @@ extern inline DWORD WINAPI GetCurrentThreadId(void);
extern inline DWORD WINAPI GetCurrentThreadId(void) extern inline DWORD WINAPI GetCurrentThreadId(void)
{ {
DWORD ret; DWORD ret;
#ifdef __x86_64__
__asm__ __volatile__( ".byte 0x65\n\tmovl 0x48,%0" : "=r" (ret) );
#else
__asm__ __volatile__( ".byte 0x64\n\tmovl 0x24,%0" : "=r" (ret) ); __asm__ __volatile__( ".byte 0x64\n\tmovl 0x24,%0" : "=r" (ret) );
#endif
return ret; return ret;
} }
extern inline void WINAPI SetLastError( DWORD err ); extern inline void WINAPI SetLastError( DWORD err );
extern inline void WINAPI SetLastError( DWORD err ) extern inline void WINAPI SetLastError( DWORD err )
{ {
#ifdef __x86_64__
__asm__ __volatile__( ".byte 0x65\n\tmovl %0,0x68" : : "r" (err) : "memory" );
#else
__asm__ __volatile__( ".byte 0x64\n\tmovl %0,0x34" : : "r" (err) : "memory" ); __asm__ __volatile__( ".byte 0x64\n\tmovl %0,0x34" : : "r" (err) : "memory" );
#endif
} }
extern inline HANDLE WINAPI GetProcessHeap(void); extern inline HANDLE WINAPI GetProcessHeap(void);
extern inline HANDLE WINAPI GetProcessHeap(void) extern inline HANDLE WINAPI GetProcessHeap(void)
{ {
HANDLE *pdb; HANDLE *pdb;
#ifdef __x86_64__
__asm__ __volatile__( ".byte 0x64\n\tmovq 0x60,%0" : "=r" (pdb) );
return pdb[0x30 / sizeof(HANDLE)]; /* get dword at offset 0x30 in pdb */
#else
__asm__ __volatile__( ".byte 0x64\n\tmovl 0x30,%0" : "=r" (pdb) ); __asm__ __volatile__( ".byte 0x64\n\tmovl 0x30,%0" : "=r" (pdb) );
return pdb[0x18 / sizeof(HANDLE)]; /* get dword at offset 0x18 in pdb */ return pdb[0x18 / sizeof(HANDLE)]; /* get dword at offset 0x18 in pdb */
#endif
} }
#else /* __i386__ && __GNUC__ && __WINESRC__ && !_NTSYSTEM_ */ #else /* __GNUC__ */
WINBASEAPI DWORD WINAPI GetCurrentProcessId(void); WINBASEAPI DWORD WINAPI GetCurrentProcessId(void);
WINBASEAPI DWORD WINAPI GetCurrentThreadId(void); WINBASEAPI DWORD WINAPI GetCurrentThreadId(void);
WINBASEAPI DWORD WINAPI GetLastError(void); WINBASEAPI DWORD WINAPI GetLastError(void);
WINBASEAPI HANDLE WINAPI GetProcessHeap(void); WINBASEAPI HANDLE WINAPI GetProcessHeap(void);
WINBASEAPI LONG WINAPI InterlockedCompareExchange(LONG volatile*,LONG,LONG);
WINBASEAPI LONG WINAPI InterlockedDecrement(LONG volatile*);
WINBASEAPI LONG WINAPI InterlockedExchange(LONG volatile*,LONG);
WINBASEAPI LONG WINAPI InterlockedExchangeAdd(LONG volatile*,LONG);
WINBASEAPI LONG WINAPI InterlockedIncrement(LONG volatile*);
WINBASEAPI VOID WINAPI SetLastError(DWORD); WINBASEAPI VOID WINAPI SetLastError(DWORD);
#endif /* __i386__ && __GNUC__ && __WINESRC__ && !_NTSYSTEM_ */ #endif /* __GNUC__ */
static inline PVOID WINAPI InterlockedCompareExchangePointer( PVOID volatile *dest, PVOID xchg, PVOID compare )
{
#if defined(__x86_64__) && defined(__GNUC__)
PVOID ret;
__asm__ __volatile__( "lock; cmpxchgq %2,(%1)"
: "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );
return ret;
#else
return (PVOID)InterlockedCompareExchange( (LONG volatile*)dest, (LONG)xchg, (LONG)compare );
#endif
}
static inline PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest, PVOID val )
{
#if defined(__x86_64__) && defined(__GNUC__)
PVOID ret;
__asm__ __volatile__( "lock; xchgq %0,(%1)"
: "=r" (ret) :"r" (dest), "0" (val) : "memory" );
return ret;
#else
return (PVOID)InterlockedExchange( (LONG volatile*)dest, (LONG)val );
#endif
}
#ifdef __WINESRC__ #ifdef __WINESRC__
#define GetCurrentProcess() ((HANDLE)~(ULONG_PTR)0) #define GetCurrentProcess() ((HANDLE)~(ULONG_PTR)0)
......
...@@ -380,7 +380,7 @@ extern int spawnvp(int mode, const char *cmdname, const char * const argv[]); ...@@ -380,7 +380,7 @@ extern int spawnvp(int mode, const char *cmdname, const char * const argv[]);
/* Interlocked functions */ /* Interlocked functions */
#if defined(__i386__) && defined(__GNUC__) #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
extern inline int interlocked_cmpxchg( int *dest, int xchg, int compare ); extern inline int interlocked_cmpxchg( int *dest, int xchg, int compare );
extern inline void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare ); extern inline void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare );
...@@ -400,8 +400,13 @@ extern inline int interlocked_cmpxchg( int *dest, int xchg, int compare ) ...@@ -400,8 +400,13 @@ extern inline int interlocked_cmpxchg( int *dest, int xchg, int compare )
extern inline void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare ) extern inline void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )
{ {
void *ret; void *ret;
#ifdef __x86_64__
__asm__ __volatile__( "lock; cmpxchgq %2,(%1)"
: "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );
#else
__asm__ __volatile__( "lock; cmpxchgl %2,(%1)" __asm__ __volatile__( "lock; cmpxchgl %2,(%1)"
: "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" ); : "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );
#endif
return ret; return ret;
} }
...@@ -416,8 +421,13 @@ extern inline int interlocked_xchg( int *dest, int val ) ...@@ -416,8 +421,13 @@ extern inline int interlocked_xchg( int *dest, int val )
extern inline void *interlocked_xchg_ptr( void **dest, void *val ) extern inline void *interlocked_xchg_ptr( void **dest, void *val )
{ {
void *ret; void *ret;
#ifdef __x86_64__
__asm__ __volatile__( "lock; xchgq %0,(%1)"
: "=r" (ret) :"r" (dest), "0" (val) : "memory" );
#else
__asm__ __volatile__( "lock; xchgl %0,(%1)" __asm__ __volatile__( "lock; xchgl %0,(%1)"
: "=r" (ret) : "r" (dest), "0" (val) : "memory" ); : "=r" (ret) : "r" (dest), "0" (val) : "memory" );
#endif
return ret; return ret;
} }
...@@ -429,7 +439,7 @@ extern inline int interlocked_xchg_add( int *dest, int incr ) ...@@ -429,7 +439,7 @@ extern inline int interlocked_xchg_add( int *dest, int incr )
return ret; return ret;
} }
#else /* __i386___ && __GNUC__ */ #else /* __GNUC__ */
extern int interlocked_cmpxchg( int *dest, int xchg, int compare ); extern int interlocked_cmpxchg( int *dest, int xchg, int compare );
extern void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare ); extern void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare );
...@@ -438,7 +448,7 @@ extern int interlocked_xchg( int *dest, int val ); ...@@ -438,7 +448,7 @@ extern int interlocked_xchg( int *dest, int val );
extern void *interlocked_xchg_ptr( void **dest, void *val ); extern void *interlocked_xchg_ptr( void **dest, void *val );
extern int interlocked_xchg_add( int *dest, int incr ); extern int interlocked_xchg_add( int *dest, int incr );
#endif /* __i386___ && __GNUC__ */ #endif /* __GNUC__ */
#else /* NO_LIBWINE_PORT */ #else /* NO_LIBWINE_PORT */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment