|
|
dd89bb |
#include <psxtypes/psxtypes.h>
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_inc(
|
|
|
dd89bb |
intptr_t volatile * ptr)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"incl %0"
|
|
|
dd89bb |
: "=m" (*ptr)
|
|
|
dd89bb |
: "m" (*ptr)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_inc_32(
|
|
|
dd89bb |
int32_t volatile * ptr)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"incl %0"
|
|
|
dd89bb |
: "=m" (*ptr)
|
|
|
dd89bb |
: "m" (*ptr)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_inc_64(
|
|
|
dd89bb |
int64_t volatile * ptr)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__sync_fetch_and_add(ptr,1);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_dec(
|
|
|
dd89bb |
intptr_t volatile * ptr)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"decl %0"
|
|
|
dd89bb |
: "=m" (*ptr)
|
|
|
dd89bb |
: "m" (*ptr)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_dec_32(
|
|
|
dd89bb |
int32_t volatile * ptr)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"decl %0"
|
|
|
dd89bb |
: "=m" (*ptr)
|
|
|
dd89bb |
: "m" (*ptr)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_dec_64(
|
|
|
dd89bb |
int64_t volatile * ptr)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__sync_fetch_and_sub(ptr,1);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_add(
|
|
|
dd89bb |
intptr_t volatile * ptr,
|
|
|
dd89bb |
intptr_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"xaddl %1, %0"
|
|
|
dd89bb |
: "=m" (*ptr), "=r" (val)
|
|
|
dd89bb |
: "1" (val)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_add_32(
|
|
|
dd89bb |
int32_t volatile * ptr,
|
|
|
dd89bb |
int32_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"xaddl %1, %0"
|
|
|
dd89bb |
: "=m" (*ptr), "=r" (val)
|
|
|
dd89bb |
: "1" (val)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_add_64(
|
|
|
dd89bb |
int64_t volatile * ptr,
|
|
|
dd89bb |
int64_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__sync_fetch_and_add(ptr,val);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_sub(
|
|
|
dd89bb |
intptr_t volatile * ptr,
|
|
|
dd89bb |
intptr_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
val = -val;
|
|
|
dd89bb |
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"xaddl %1, %0"
|
|
|
dd89bb |
: "=m" (*ptr), "=r" (val)
|
|
|
dd89bb |
: "1" (val)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_sub_32(
|
|
|
dd89bb |
int32_t volatile * ptr,
|
|
|
dd89bb |
int32_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
val = -val;
|
|
|
dd89bb |
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"xaddl %1, %0"
|
|
|
dd89bb |
: "=m" (*ptr), "=r" (val)
|
|
|
dd89bb |
: "1" (val)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_locked_sub_64(
|
|
|
dd89bb |
int64_t volatile * ptr,
|
|
|
dd89bb |
int64_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__sync_fetch_and_sub(ptr,val);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ intptr_t at_locked_xadd(
|
|
|
dd89bb |
intptr_t volatile * ptr,
|
|
|
dd89bb |
intptr_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"xaddl %1, %0"
|
|
|
dd89bb |
: "=m" (*ptr), "=r" (val)
|
|
|
dd89bb |
: "1" (val)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
return val;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ int32_t at_locked_xadd_32(
|
|
|
dd89bb |
int32_t volatile * ptr,
|
|
|
dd89bb |
int32_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"xaddl %1, %0"
|
|
|
dd89bb |
: "=m" (*ptr), "=r" (val)
|
|
|
dd89bb |
: "1" (val)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
return val;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ int64_t at_locked_xadd_64(
|
|
|
dd89bb |
int64_t volatile * ptr,
|
|
|
dd89bb |
int64_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
return __sync_fetch_and_add(ptr,val);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ intptr_t at_locked_xsub(
|
|
|
dd89bb |
intptr_t volatile * ptr,
|
|
|
dd89bb |
intptr_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
val = -val;
|
|
|
dd89bb |
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"xaddl %1, %0"
|
|
|
dd89bb |
: "=m" (*ptr), "=r" (val)
|
|
|
dd89bb |
: "1" (val)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
return val;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ int32_t at_locked_xsub_32(
|
|
|
dd89bb |
int32_t volatile * ptr,
|
|
|
dd89bb |
int32_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
val = -val;
|
|
|
dd89bb |
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"xaddl %1, %0"
|
|
|
dd89bb |
: "=m" (*ptr), "=r" (val)
|
|
|
dd89bb |
: "1" (val)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
return val;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ int64_t at_locked_xsub_64(
|
|
|
dd89bb |
int64_t volatile * ptr,
|
|
|
dd89bb |
int64_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
return __sync_fetch_and_sub(ptr,val);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ intptr_t at_locked_cas(
|
|
|
dd89bb |
intptr_t volatile * dst,
|
|
|
dd89bb |
intptr_t cmp,
|
|
|
dd89bb |
intptr_t xchg)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
intptr_t ret;
|
|
|
dd89bb |
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"cmpxchg %3, %0"
|
|
|
dd89bb |
: "=m" (*dst), "=a" (ret)
|
|
|
dd89bb |
: "a" (cmp), "r" (xchg)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
|
|
|
dd89bb |
return ret;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ int32_t at_locked_cas_32(
|
|
|
dd89bb |
int32_t volatile * dst,
|
|
|
dd89bb |
int32_t cmp,
|
|
|
dd89bb |
int32_t xchg)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int32_t ret;
|
|
|
dd89bb |
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"cmpxchg %3, %0"
|
|
|
dd89bb |
: "=m" (*dst), "=a" (ret)
|
|
|
dd89bb |
: "a" (cmp), "r" (xchg)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
|
|
|
dd89bb |
return ret;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ int64_t at_locked_cas_64(
|
|
|
dd89bb |
int64_t volatile * dst,
|
|
|
dd89bb |
int64_t cmp,
|
|
|
dd89bb |
int64_t xchg)
|
|
|
dd89bb |
{
|
|
|
381f65 |
unsigned edx, eax;
|
|
|
381f65 |
unsigned ecx, ebx;
|
|
|
381f65 |
|
|
|
381f65 |
eax = (unsigned)cmp;
|
|
|
381f65 |
edx = (uint64_t)cmp >> 32;
|
|
|
381f65 |
|
|
|
381f65 |
ebx = (unsigned)xchg;
|
|
|
381f65 |
ecx = (uint64_t)xchg >> 32;
|
|
|
381f65 |
|
|
|
381f65 |
__asm__ volatile (
|
|
|
381f65 |
"lock;"
|
|
|
381f65 |
"cmpxchg8b %6"
|
|
|
381f65 |
|
|
|
381f65 |
: "=a" (eax), "=d" (edx)
|
|
|
381f65 |
: "a" (eax), "d" (edx), "b" (ebx), "c" (ecx), "m" (*dst)
|
|
|
381f65 |
: "memory");
|
|
|
381f65 |
|
|
|
381f65 |
|
|
|
381f65 |
return ((int64_t)edx << 32) + eax;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
f1a766 |
static __inline__ void at_locked_and(
|
|
|
dd89bb |
intptr_t volatile * dst,
|
|
|
dd89bb |
intptr_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"andl %1, %0"
|
|
|
f1a766 |
: "=m" (*dst)
|
|
|
dd89bb |
: "r" (mask)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
f1a766 |
static __inline__ void at_locked_and_32(
|
|
|
dd89bb |
int32_t volatile * dst,
|
|
|
dd89bb |
int32_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"andl %1, %0"
|
|
|
f1a766 |
: "=m" (*dst)
|
|
|
dd89bb |
: "r" (mask)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
f1a766 |
static __inline__ void at_locked_and_64(
|
|
|
dd89bb |
int64_t volatile * dst,
|
|
|
dd89bb |
int64_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int64_t ret;
|
|
|
dd89bb |
int64_t cmp;
|
|
|
dd89bb |
int64_t xchg;
|
|
|
dd89bb |
|
|
|
dd89bb |
do {
|
|
|
dd89bb |
cmp = *dst;
|
|
|
dd89bb |
xchg = cmp & mask;
|
|
|
dd89bb |
ret = at_locked_cas_64(dst,cmp,xchg);
|
|
|
dd89bb |
} while (ret != cmp);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
f1a766 |
static __inline__ void at_locked_or(
|
|
|
dd89bb |
intptr_t volatile * dst,
|
|
|
dd89bb |
intptr_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"orl %1, %0"
|
|
|
f1a766 |
: "=m" (*dst)
|
|
|
dd89bb |
: "r" (mask)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
f1a766 |
static __inline__ void at_locked_or_32(
|
|
|
dd89bb |
int32_t volatile * dst,
|
|
|
dd89bb |
int32_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"orl %1, %0"
|
|
|
f1a766 |
: "=m" (*dst)
|
|
|
dd89bb |
: "r" (mask)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
f1a766 |
static __inline__ void at_locked_or_64(
|
|
|
dd89bb |
int64_t volatile * dst,
|
|
|
dd89bb |
int64_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int64_t ret;
|
|
|
dd89bb |
int64_t cmp;
|
|
|
dd89bb |
int64_t xchg;
|
|
|
dd89bb |
|
|
|
dd89bb |
do {
|
|
|
dd89bb |
cmp = *dst;
|
|
|
dd89bb |
xchg = cmp | mask;
|
|
|
dd89bb |
ret = at_locked_cas_64(dst,cmp,xchg);
|
|
|
dd89bb |
} while (ret != cmp);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
f1a766 |
static __inline__ void at_locked_xor(
|
|
|
dd89bb |
intptr_t volatile * dst,
|
|
|
dd89bb |
intptr_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"xorl %1, %0"
|
|
|
f1a766 |
: "=m" (*dst)
|
|
|
dd89bb |
: "r" (mask)
|
|
|
dfd2ed |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
f1a766 |
static __inline__ void at_locked_xor_32(
|
|
|
dd89bb |
int32_t volatile * dst,
|
|
|
dd89bb |
int32_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"lock;"
|
|
|
dd89bb |
"xorl %1, %0"
|
|
|
f1a766 |
: "=m" (*dst)
|
|
|
dd89bb |
: "r" (mask)
|
|
|
dfd2ed |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
f1a766 |
static __inline__ void at_locked_xor_64(
|
|
|
dd89bb |
int64_t volatile * dst,
|
|
|
dd89bb |
int64_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int64_t ret;
|
|
|
dd89bb |
int64_t cmp;
|
|
|
dd89bb |
int64_t xchg;
|
|
|
dd89bb |
|
|
|
dd89bb |
do {
|
|
|
dd89bb |
cmp = *dst;
|
|
|
dd89bb |
xchg = cmp ^ mask;
|
|
|
dd89bb |
ret = at_locked_cas_64(dst,cmp,xchg);
|
|
|
dd89bb |
} while (ret != cmp);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_store(
|
|
|
e40843 |
intptr_t volatile * dst,
|
|
|
dd89bb |
intptr_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
ca62e5 |
"mov %1, %0;"
|
|
|
ca62e5 |
"lock;"
|
|
|
ca62e5 |
"orl $0,%0;"
|
|
|
dd89bb |
: "=m" (*dst)
|
|
|
dd89bb |
: "r" (val)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_store_32(
|
|
|
e40843 |
int32_t volatile * dst,
|
|
|
dd89bb |
int32_t val)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
ca62e5 |
"mov %1, %0;"
|
|
|
ca62e5 |
"lock;"
|
|
|
ca62e5 |
"orl $0,%0;"
|
|
|
dd89bb |
: "=m" (*dst)
|
|
|
dd89bb |
: "r" (val)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ void at_store_64(
|
|
|
e40843 |
int64_t volatile * dst,
|
|
|
ca62e5 |
int64_t xchg)
|
|
|
dd89bb |
{
|
|
|
ca62e5 |
int64_t cmp;
|
|
|
ca62e5 |
int64_t prev;
|
|
|
dd89bb |
|
|
|
ca62e5 |
do {
|
|
|
ca62e5 |
prev = *dst;
|
|
|
ca62e5 |
cmp = prev;
|
|
|
ca62e5 |
|
|
|
8ce0ee |
prev = at_locked_cas_64(
|
|
|
8ce0ee |
dst,cmp,xchg);
|
|
|
8ce0ee |
|
|
|
ca62e5 |
} while (cmp != prev);
|
|
|
ca62e5 |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ int at_bsf(
|
|
|
dd89bb |
unsigned int * index,
|
|
|
dd89bb |
uintptr_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
if (mask) {
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"bsf %1, %0"
|
|
|
dd89bb |
: "=r" (mask)
|
|
|
dd89bb |
: "r" (mask));
|
|
|
dd89bb |
|
|
|
dd89bb |
*index = (int)mask;
|
|
|
dd89bb |
return 1;
|
|
|
dd89bb |
} else
|
|
|
dd89bb |
return 0;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ int at_bsr(
|
|
|
dd89bb |
unsigned int * index,
|
|
|
dd89bb |
uintptr_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
if (mask) {
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"bsr %1, %0"
|
|
|
dd89bb |
: "=r" (mask)
|
|
|
dd89bb |
: "r" (mask));
|
|
|
dd89bb |
|
|
|
dd89bb |
*index = (int)mask;
|
|
|
dd89bb |
return 1;
|
|
|
dd89bb |
} else
|
|
|
dd89bb |
return 0;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ size_t at_popcount(
|
|
|
dd89bb |
uintptr_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"popcnt %0, %0"
|
|
|
dd89bb |
: "=r" (mask)
|
|
|
dd89bb |
: "0" (mask)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
return mask;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ size_t at_popcount_16(
|
|
|
dd89bb |
uint16_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"popcnt %0, %0"
|
|
|
dd89bb |
: "=r" (mask)
|
|
|
dd89bb |
: "0" (mask)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
return mask;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ size_t at_popcount_32(
|
|
|
dd89bb |
uint32_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__asm__(
|
|
|
dd89bb |
"popcnt %0, %0"
|
|
|
dd89bb |
: "=r" (mask)
|
|
|
dd89bb |
: "0" (mask)
|
|
|
dd89bb |
: "memory");
|
|
|
dd89bb |
return mask;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
static __inline__ size_t at_popcount_64(
|
|
|
dd89bb |
uint64_t mask)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
int ret = at_popcount_32(mask >> 32);
|
|
|
dd89bb |
return ret + ((mask << 32) >> 32);
|
|
|
dd89bb |
}
|