Add a generic implementation of InterlockedBitTestAndSet/InterlockedBitTestAndReset/BitScanReverse

svn path=/trunk/; revision=28807
This commit is contained in:
Hervé Poussineau 2007-09-03 08:50:06 +00:00
parent af1226ddc6
commit 5b3a9d3b2d

View file

@ -4,6 +4,9 @@
#pragma GCC system_header
#endif
#ifdef __GNUC__
#include "intrin.h"
#endif
/* translate GCC target defines to MS equivalents. Keep this synchronized
with windows.h. */
@ -2341,7 +2344,7 @@ typedef struct _CONTEXT {
#endif
} CONTEXT;
#elif defined(MIPS)
#elif defined(_MIPS_)
/* The following flags control the contents of the CONTEXT structure. */
@ -4039,7 +4042,7 @@ typedef struct _OBJECT_TYPE_LIST {
#if defined(__GNUC__)
#ifdef _M_IX86
#if defined(_M_IX86)
static __inline__ PVOID GetCurrentFiber(void)
{
void* ret;
@ -4050,6 +4053,7 @@ static __inline__ PVOID GetCurrentFiber(void)
return ret;
}
#else
#if defined(_M_PPC)
static __inline__ __attribute__((always_inline)) unsigned long __readfsdword_winnt(const unsigned long Offset)
{
unsigned long result;
@ -4061,6 +4065,9 @@ static __inline__ __attribute__((always_inline)) unsigned long __readfsdword_win
return result;
}
#else
#error Unknown architecture
#endif
static __inline__ PVOID GetCurrentFiber(void)
{
return __readfsdword_winnt(0x10);
@ -4147,78 +4154,36 @@ static __inline__ BOOLEAN
InterlockedBitTestAndSet(IN LONG volatile *Base,
IN LONG Bit)
{
#if defined(_M_IX86)
LONG OldBit;
#ifdef _M_IX86
__asm__ __volatile__("lock "
"btsl %2,%1\n\t"
"sbbl %0,%0\n\t"
:"=r" (OldBit),"=m" (*Base)
:"Ir" (Bit)
: "memory");
#elif defined(_M_PPC)
LONG scratch = 0;
Bit = 1 << Bit;
/* %0 - OldBit
* %1 - Bit
* %2 - scratch
* %3 - Base
*/
__asm__ __volatile__(
"sync\n"
"0:\n\t"
"lwarx %2,0,%3\n\t"
"mr %0,%2\n\t"
"or %2,%1,%2\n\t"
"stwcx. %2,0,%3\n\t"
"bne- 0b\n\t" :
"=r" (OldBit) :
"r" (Bit),
"r" (scratch),
"r" (Base)
);
#endif
return OldBit;
#else
return (_InterlockedOr(Base, 1 << Bit) >> Bit) & 1;
#endif
}
static __inline__ BOOLEAN
InterlockedBitTestAndReset(IN LONG volatile *Base,
IN LONG Bit)
{
#if defined(_M_IX86)
LONG OldBit;
#ifdef _M_IX86
__asm__ __volatile__("lock "
"btrl %2,%1\n\t"
"sbbl %0,%0\n\t"
:"=r" (OldBit),"=m" (*Base)
:"Ir" (Bit)
: "memory");
#elif defined(_M_PPC)
LONG scratch = 0;
Bit = ~(1 << Bit);
/* %0 - OldBit
* %1 - Bit
* %2 - scratch
* %3 - Base
*/
__asm__ __volatile__(
"sync\n"
"0:\n\t"
"lwarx %2,0,%3\n\t"
"mr %0,%2\n\t"
"and %2,%1,%2\n\t"
"stwcx. %2,0,%3\n\t"
"bne- 0b\n\t" :
"=r" (OldBit) :
"r" (Bit),
"r" (scratch),
"r" (Base)
);
#endif
return OldBit;
#else
return (_InterlockedAnd(Base, ~(1 << Bit)) >> Bit) & 1;
#endif
}
static __inline__ BOOLEAN
@ -4226,14 +4191,14 @@ BitScanReverse(OUT ULONG *Index,
IN ULONG Mask)
{
BOOLEAN BitPosition = 0;
#ifdef _M_IX86
#if defined(_M_IX86)
__asm__ __volatile__("bsrl %2,%0\n\t"
"setnz %1\n\t"
:"=&r" (*Index), "=r" (BitPosition)
:"rm" (Mask)
:"memory");
return BitPosition;
#elif defined(_M_PPC)
#else
/* Slow implementation for now */
for( *Index = 31; *Index; *Index-- ) {
if( (1<<*Index) & Mask ) {
@ -4247,10 +4212,14 @@ BitScanReverse(OUT ULONG *Index,
#endif
#ifdef _M_IX86
#if defined(_M_IX86)
#define YieldProcessor() __asm__ __volatile__("pause");
#elif defined(_M_PPC)
#define YieldProcessor() __asm__ __volatile__("nop");
#elif defined(_M_MIPS)
#define YieldProcessor() __asm__ __volatile__("nop");
#else
#error Unknown architecture
#endif
#if defined(_AMD64_)