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;
|
||||
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
|
||||
extern struct _TEB * WINAPI NtCurrentTeb(void);
|
||||
#endif
|
||||
|
|
|
@ -696,6 +696,94 @@ __ASM_GLOBAL_FUNC(interlocked_xchg_add,
|
|||
"lock; xaddl %eax,(%edx)\n\t"
|
||||
"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__)
|
||||
|
||||
/*
|
||||
|
@ -757,7 +845,6 @@ long interlocked_xchg_add( long *dest, long incr )
|
|||
_lwp_mutex_unlock( &interlocked_mutex );
|
||||
return retv;
|
||||
}
|
||||
|
||||
#else
|
||||
# error You must implement the interlocked* functions for your CPU
|
||||
#endif
|
||||
|
|
|
@ -85,6 +85,9 @@ void SYSDEPS_SetCurThread( TEB *teb )
|
|||
#if defined(__i386__)
|
||||
/* On the i386, the current thread is in the %fs register */
|
||||
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)
|
||||
/* On non-i386 Solaris, we use the LWP private pointer */
|
||||
_lwp_setprivate( teb );
|
||||
|
@ -249,13 +252,13 @@ __declspec(naked) void SYSDEPS_CallOnStack( void (*func)(LPVOID), LPVOID arg )
|
|||
__asm int 3;
|
||||
}
|
||||
#endif /* defined(__GNUC__) || defined(_MSC_VER) */
|
||||
#else /* defined(__i386__) */
|
||||
#else /* !defined(__i386__) */
|
||||
void SYSDEPS_CallOnStack( void (*func)(LPVOID), LPVOID arg )
|
||||
{
|
||||
func( arg );
|
||||
while(1); /* avoid warning */
|
||||
}
|
||||
#endif /* defined(__i386__) */
|
||||
#endif /* !defined(__i386__) */
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -335,6 +338,8 @@ struct _TEB * WINAPI NtCurrentTeb(void)
|
|||
extern void *_lwp_getprivate(void);
|
||||
return (struct _TEB *)_lwp_getprivate();
|
||||
}
|
||||
#elif defined(__powerpc__)
|
||||
__ASM_GLOBAL_FUNC( NtCurrentTeb, "\n\tmr 3,13\n\tblr" );
|
||||
#else
|
||||
# error NtCurrentTeb not defined for this architecture
|
||||
#endif /* __i386__ */
|
||||
|
|
Loading…
Reference in New Issue