Authors: Josh DuBois <duboisj@codeweavers.com>, Marcus Meissner <meissner@suse.de>
PowerPC locked exchange functions merged from old ppc patch. NtCurrentTeb handling for PowerPC (using gpr 13).
This commit is contained in:
parent
53e5bd5000
commit
c1dec29304
|
@ -2314,6 +2314,14 @@ extern inline struct _TEB * WINAPI NtCurrentTeb(void)
|
||||||
__asm mov teb, eax;
|
__asm mov teb, eax;
|
||||||
return teb;
|
return teb;
|
||||||
}
|
}
|
||||||
|
#elif defined(__powerpc__)
|
||||||
|
extern inline struct _TEB * WINAPI NtCurrentTeb(void);
|
||||||
|
extern inline struct _TEB * WINAPI NtCurrentTeb(void)
|
||||||
|
{
|
||||||
|
struct _TEB *teb;
|
||||||
|
__asm__("\tmr %0, 13" : "=r" (teb));
|
||||||
|
return teb;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
extern struct _TEB * WINAPI NtCurrentTeb(void);
|
extern struct _TEB * WINAPI NtCurrentTeb(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -696,6 +696,94 @@ __ASM_GLOBAL_FUNC(interlocked_xchg_add,
|
||||||
"lock; xaddl %eax,(%edx)\n\t"
|
"lock; xaddl %eax,(%edx)\n\t"
|
||||||
"ret");
|
"ret");
|
||||||
|
|
||||||
|
#elif defined(__powerpc__)
|
||||||
|
void* interlocked_cmpxchg_ptr( void **dest, void* xchg, void* compare)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
long scratch;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"sync; "
|
||||||
|
"0: lwarx %0,0,%2 ;"
|
||||||
|
" xor. %1,%4,%0;"
|
||||||
|
" bne 1f;"
|
||||||
|
" stwcx. %3,0,%2;"
|
||||||
|
" bne- 0b;"
|
||||||
|
"1: "
|
||||||
|
"sync; "
|
||||||
|
: "=&r"(ret), "=&r"(scratch)
|
||||||
|
: "r"(dest), "r"(xchg), "r"(compare)
|
||||||
|
: "cr0", "memory");
|
||||||
|
return (void*)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
long interlocked_cmpxchg( long *dest, long xchg, long compare)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
long scratch;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"sync; "
|
||||||
|
"0: lwarx %0,0,%2 ;"
|
||||||
|
" xor. %1,%4,%0;"
|
||||||
|
" bne 1f;"
|
||||||
|
" stwcx. %3,0,%2;"
|
||||||
|
" bne- 0b;"
|
||||||
|
"1: "
|
||||||
|
"sync; "
|
||||||
|
: "=&r"(ret), "=&r"(scratch)
|
||||||
|
: "r"(dest), "r"(xchg), "r"(compare)
|
||||||
|
: "cr0", "memory");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
long interlocked_xchg_add( long *dest, long incr )
|
||||||
|
{
|
||||||
|
void *ret __attribute__ ((aligned (4))) = &ret;
|
||||||
|
long inc = incr;
|
||||||
|
long zero = 0;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"sync; "
|
||||||
|
"0: lwarx %0, %3, %1;"
|
||||||
|
" add %0, %2, %0;"
|
||||||
|
" stwcx. %0, %3, %1;"
|
||||||
|
" bne- 0b;"
|
||||||
|
"sync; "
|
||||||
|
: "=&r"(ret)
|
||||||
|
: "r"(dest), "r"(inc), "r"(zero)
|
||||||
|
: "cr0", "memory"
|
||||||
|
);
|
||||||
|
return (long)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
long interlocked_xchg( long* dest, long val )
|
||||||
|
{
|
||||||
|
void *ret __attribute__ ((aligned (4))) = &ret;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"sync; "
|
||||||
|
"0: lwarx %0,0,%1 ;"
|
||||||
|
" stwcx. %2,0,%1;"
|
||||||
|
" bne- 0b;"
|
||||||
|
"sync; "
|
||||||
|
: "=&r"(ret)
|
||||||
|
: "r"(dest), "r"(val)
|
||||||
|
: "cr0", "memory");
|
||||||
|
return (long)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* interlocked_xchg_ptr( void** dest, void* val )
|
||||||
|
{
|
||||||
|
void *ret __attribute__ ((aligned (4))) = &ret;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"sync; "
|
||||||
|
"0: lwarx %0,0,%1 ;"
|
||||||
|
" stwcx. %2,0,%1;"
|
||||||
|
" bne- 0b;"
|
||||||
|
"sync; "
|
||||||
|
: "=&r"(ret)
|
||||||
|
: "r"(dest), "r"(val)
|
||||||
|
: "cr0", "memory");
|
||||||
|
return (void*)ret;
|
||||||
|
}
|
||||||
|
|
||||||
#elif defined(__sparc__) && defined(__sun__)
|
#elif defined(__sparc__) && defined(__sun__)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -757,7 +845,6 @@ long interlocked_xchg_add( long *dest, long incr )
|
||||||
_lwp_mutex_unlock( &interlocked_mutex );
|
_lwp_mutex_unlock( &interlocked_mutex );
|
||||||
return retv;
|
return retv;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# error You must implement the interlocked* functions for your CPU
|
# error You must implement the interlocked* functions for your CPU
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -85,6 +85,9 @@ void SYSDEPS_SetCurThread( TEB *teb )
|
||||||
#if defined(__i386__)
|
#if defined(__i386__)
|
||||||
/* On the i386, the current thread is in the %fs register */
|
/* On the i386, the current thread is in the %fs register */
|
||||||
wine_set_fs( teb->teb_sel );
|
wine_set_fs( teb->teb_sel );
|
||||||
|
#elif defined(__powerpc__)
|
||||||
|
/* On PowerPC, the current TEB is in the gpr13 register */
|
||||||
|
__asm__ __volatile__("mr 13, %0" : : "r" (teb));
|
||||||
#elif defined(HAVE__LWP_CREATE)
|
#elif defined(HAVE__LWP_CREATE)
|
||||||
/* On non-i386 Solaris, we use the LWP private pointer */
|
/* On non-i386 Solaris, we use the LWP private pointer */
|
||||||
_lwp_setprivate( teb );
|
_lwp_setprivate( teb );
|
||||||
|
@ -249,13 +252,13 @@ __declspec(naked) void SYSDEPS_CallOnStack( void (*func)(LPVOID), LPVOID arg )
|
||||||
__asm int 3;
|
__asm int 3;
|
||||||
}
|
}
|
||||||
#endif /* defined(__GNUC__) || defined(_MSC_VER) */
|
#endif /* defined(__GNUC__) || defined(_MSC_VER) */
|
||||||
#else /* defined(__i386__) */
|
#else /* !defined(__i386__) */
|
||||||
void SYSDEPS_CallOnStack( void (*func)(LPVOID), LPVOID arg )
|
void SYSDEPS_CallOnStack( void (*func)(LPVOID), LPVOID arg )
|
||||||
{
|
{
|
||||||
func( arg );
|
func( arg );
|
||||||
while(1); /* avoid warning */
|
while(1); /* avoid warning */
|
||||||
}
|
}
|
||||||
#endif /* defined(__i386__) */
|
#endif /* !defined(__i386__) */
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -335,6 +338,8 @@ struct _TEB * WINAPI NtCurrentTeb(void)
|
||||||
extern void *_lwp_getprivate(void);
|
extern void *_lwp_getprivate(void);
|
||||||
return (struct _TEB *)_lwp_getprivate();
|
return (struct _TEB *)_lwp_getprivate();
|
||||||
}
|
}
|
||||||
|
#elif defined(__powerpc__)
|
||||||
|
__ASM_GLOBAL_FUNC( NtCurrentTeb, "\n\tmr 3,13\n\tblr" );
|
||||||
#else
|
#else
|
||||||
# error NtCurrentTeb not defined for this architecture
|
# error NtCurrentTeb not defined for this architecture
|
||||||
#endif /* __i386__ */
|
#endif /* __i386__ */
|
||||||
|
|
Loading…
Reference in New Issue