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:
Alexandre Julliard 2002-08-06 23:51:25 +00:00
parent 53e5bd5000
commit c1dec29304
3 changed files with 103 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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__ */