include: Implemented inline asm functions for x86_64. Export Interlocked* only on i386.
This commit is contained in:
parent
fa616418ad
commit
f06d99f67a
|
@ -722,12 +722,12 @@
|
|||
@ stdcall InitializeCriticalSectionAndSpinCount(ptr long)
|
||||
@ stdcall InitializeCriticalSectionEx(ptr long long)
|
||||
@ stdcall InitializeSListHead(ptr) ntdll.RtlInitializeSListHead
|
||||
@ stdcall InterlockedCompareExchange (ptr long long)
|
||||
@ stdcall InterlockedDecrement(ptr)
|
||||
@ stdcall InterlockedExchange(ptr long)
|
||||
@ stdcall InterlockedExchangeAdd (ptr long )
|
||||
@ stdcall -arch=i386 InterlockedCompareExchange (ptr long long)
|
||||
@ stdcall -arch=i386 InterlockedDecrement(ptr)
|
||||
@ stdcall -arch=i386 InterlockedExchange(ptr long)
|
||||
@ stdcall -arch=i386 InterlockedExchangeAdd (ptr long )
|
||||
@ stdcall InterlockedFlushSList(ptr) ntdll.RtlInterlockedFlushSList
|
||||
@ stdcall InterlockedIncrement(ptr)
|
||||
@ stdcall -arch=i386 InterlockedIncrement(ptr)
|
||||
@ stdcall InterlockedPopEntrySList(ptr) ntdll.RtlInterlockedPopEntrySList
|
||||
@ stdcall InterlockedPushEntrySList(ptr ptr) ntdll.RtlInterlockedPushEntrySList
|
||||
@ stub InvalidateConsoleDIBits
|
||||
|
|
|
@ -2314,93 +2314,4 @@ __ASM_GLOBAL_FUNC(InterlockedDecrement,
|
|||
"decl %eax\n\t"
|
||||
"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__ */
|
||||
|
|
|
@ -2315,9 +2315,10 @@ extern char *wine_get_unix_file_name( LPCWSTR dos );
|
|||
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 )
|
||||
|
@ -2358,58 +2359,40 @@ extern inline LONG WINAPI InterlockedDecrement( LONG volatile *dest )
|
|||
return InterlockedExchangeAdd( dest, -1 ) - 1;
|
||||
}
|
||||
|
||||
extern inline DWORD WINAPI GetLastError(void);
|
||||
extern inline DWORD WINAPI GetLastError(void)
|
||||
{
|
||||
DWORD ret;
|
||||
__asm__ __volatile__( ".byte 0x64\n\tmovl 0x34,%0" : "=r" (ret) );
|
||||
return ret;
|
||||
}
|
||||
# else /* __GNUC__ */
|
||||
|
||||
extern inline DWORD WINAPI GetCurrentProcessId(void);
|
||||
extern inline DWORD WINAPI GetCurrentProcessId(void)
|
||||
{
|
||||
DWORD ret;
|
||||
__asm__ __volatile__( ".byte 0x64\n\tmovl 0x20,%0" : "=r" (ret) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern inline DWORD WINAPI GetCurrentThreadId(void);
|
||||
extern inline DWORD WINAPI GetCurrentThreadId(void)
|
||||
{
|
||||
DWORD ret;
|
||||
__asm__ __volatile__( ".byte 0x64\n\tmovl 0x24,%0" : "=r" (ret) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern inline void WINAPI SetLastError( DWORD err );
|
||||
extern inline void WINAPI SetLastError( DWORD err )
|
||||
{
|
||||
__asm__ __volatile__( ".byte 0x64\n\tmovl %0,0x34" : : "r" (err) : "memory" );
|
||||
}
|
||||
|
||||
extern inline HANDLE WINAPI GetProcessHeap(void);
|
||||
extern inline HANDLE WINAPI GetProcessHeap(void)
|
||||
{
|
||||
HANDLE *pdb;
|
||||
__asm__ __volatile__( ".byte 0x64\n\tmovl 0x30,%0" : "=r" (pdb) );
|
||||
return pdb[0x18 / sizeof(HANDLE)]; /* get dword at offset 0x18 in pdb */
|
||||
}
|
||||
|
||||
#else /* __i386__ && __GNUC__ && __WINESRC__ && !_NTSYSTEM_ */
|
||||
|
||||
WINBASEAPI DWORD WINAPI GetCurrentProcessId(void);
|
||||
WINBASEAPI DWORD WINAPI GetCurrentThreadId(void);
|
||||
WINBASEAPI DWORD WINAPI GetLastError(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);
|
||||
|
||||
#endif /* __i386__ && __GNUC__ && __WINESRC__ && !_NTSYSTEM_ */
|
||||
# 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 )
|
||||
{
|
||||
|
@ -2419,7 +2402,21 @@ static inline PVOID WINAPI InterlockedCompareExchangePointer( PVOID volatile *de
|
|||
: "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );
|
||||
return ret;
|
||||
#else
|
||||
return (PVOID)InterlockedCompareExchange( (LONG volatile*)dest, (LONG)xchg, (LONG)compare );
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -2431,10 +2428,109 @@ static inline PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest, PVO
|
|||
: "=r" (ret) :"r" (dest), "0" (val) : "memory" );
|
||||
return ret;
|
||||
#else
|
||||
return (PVOID)InterlockedExchange( (LONG volatile*)dest, (LONG)val );
|
||||
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)
|
||||
{
|
||||
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) );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern inline DWORD WINAPI GetCurrentProcessId(void);
|
||||
extern inline DWORD WINAPI GetCurrentProcessId(void)
|
||||
{
|
||||
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) );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern inline DWORD WINAPI GetCurrentThreadId(void);
|
||||
extern inline DWORD WINAPI GetCurrentThreadId(void)
|
||||
{
|
||||
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) );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
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" );
|
||||
#endif
|
||||
}
|
||||
|
||||
extern inline HANDLE WINAPI GetProcessHeap(void);
|
||||
extern inline HANDLE WINAPI GetProcessHeap(void)
|
||||
{
|
||||
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) );
|
||||
return pdb[0x18 / sizeof(HANDLE)]; /* get dword at offset 0x18 in pdb */
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* __GNUC__ */
|
||||
|
||||
WINBASEAPI DWORD WINAPI GetCurrentProcessId(void);
|
||||
WINBASEAPI DWORD WINAPI GetCurrentThreadId(void);
|
||||
WINBASEAPI DWORD WINAPI GetLastError(void);
|
||||
WINBASEAPI HANDLE WINAPI GetProcessHeap(void);
|
||||
WINBASEAPI VOID WINAPI SetLastError(DWORD);
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#ifdef __WINESRC__
|
||||
#define GetCurrentProcess() ((HANDLE)~(ULONG_PTR)0)
|
||||
#define GetCurrentThread() ((HANDLE)~(ULONG_PTR)1)
|
||||
|
|
|
@ -380,7 +380,7 @@ extern int spawnvp(int mode, const char *cmdname, const char * const argv[]);
|
|||
|
||||
/* 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 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 )
|
|||
extern inline void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare )
|
||||
{
|
||||
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)"
|
||||
: "=a" (ret) : "r" (dest), "r" (xchg), "0" (compare) : "memory" );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -416,8 +421,13 @@ extern inline int interlocked_xchg( int *dest, int val )
|
|||
extern inline void *interlocked_xchg_ptr( void **dest, void *val )
|
||||
{
|
||||
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)"
|
||||
: "=r" (ret) : "r" (dest), "0" (val) : "memory" );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -429,7 +439,7 @@ extern inline int interlocked_xchg_add( int *dest, int incr )
|
|||
return ret;
|
||||
}
|
||||
|
||||
#else /* __i386___ && __GNUC__ */
|
||||
#else /* __GNUC__ */
|
||||
|
||||
extern int interlocked_cmpxchg( int *dest, int xchg, int compare );
|
||||
extern void *interlocked_cmpxchg_ptr( void **dest, void *xchg, void *compare );
|
||||
|
@ -438,7 +448,7 @@ 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 );
|
||||
|
||||
#endif /* __i386___ && __GNUC__ */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#else /* NO_LIBWINE_PORT */
|
||||
|
||||
|
|
Loading…
Reference in New Issue