fix REQ-51
This commit is contained in:
142
lib/bitops.c
Normal file
142
lib/bitops.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/* bitops.c COPYRIGHT FUJITSU LIMITED 2014 */
|
||||
#include <bitops.h>
|
||||
|
||||
#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||
|
||||
/*
|
||||
* Find the next set bit in a memory region.
|
||||
*/
|
||||
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
const unsigned long *p = addr + BITOP_WORD(offset);
|
||||
unsigned long result = offset & ~(BITS_PER_LONG-1);
|
||||
unsigned long tmp;
|
||||
|
||||
if (offset >= size)
|
||||
return size;
|
||||
size -= result;
|
||||
offset %= BITS_PER_LONG;
|
||||
if (offset) {
|
||||
tmp = *(p++);
|
||||
tmp &= (~0UL << offset);
|
||||
if (size < BITS_PER_LONG)
|
||||
goto found_first;
|
||||
if (tmp)
|
||||
goto found_middle;
|
||||
size -= BITS_PER_LONG;
|
||||
result += BITS_PER_LONG;
|
||||
}
|
||||
while (size & ~(BITS_PER_LONG-1)) {
|
||||
if ((tmp = *(p++)))
|
||||
goto found_middle;
|
||||
result += BITS_PER_LONG;
|
||||
size -= BITS_PER_LONG;
|
||||
}
|
||||
if (!size)
|
||||
return result;
|
||||
tmp = *p;
|
||||
|
||||
found_first:
|
||||
tmp &= (~0UL >> (BITS_PER_LONG - size));
|
||||
if (tmp == 0UL) /* Are any bits set? */
|
||||
return result + size; /* Nope. */
|
||||
found_middle:
|
||||
return result + __ffs(tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* This implementation of find_{first,next}_zero_bit was stolen from
|
||||
* Linus' asm-alpha/bitops.h.
|
||||
*/
|
||||
unsigned long find_next_zero_bit(const unsigned long *addr,
|
||||
unsigned long size, unsigned long offset)
|
||||
{
|
||||
const unsigned long *p = addr + BITOP_WORD(offset);
|
||||
unsigned long result = offset & ~(BITS_PER_LONG-1);
|
||||
unsigned long tmp;
|
||||
|
||||
if (offset >= size)
|
||||
return size;
|
||||
size -= result;
|
||||
offset %= BITS_PER_LONG;
|
||||
if (offset) {
|
||||
tmp = *(p++);
|
||||
tmp |= ~0UL >> (BITS_PER_LONG - offset);
|
||||
if (size < BITS_PER_LONG)
|
||||
goto found_first;
|
||||
if (~tmp)
|
||||
goto found_middle;
|
||||
size -= BITS_PER_LONG;
|
||||
result += BITS_PER_LONG;
|
||||
}
|
||||
while (size & ~(BITS_PER_LONG-1)) {
|
||||
if (~(tmp = *(p++)))
|
||||
goto found_middle;
|
||||
result += BITS_PER_LONG;
|
||||
size -= BITS_PER_LONG;
|
||||
}
|
||||
if (!size)
|
||||
return result;
|
||||
tmp = *p;
|
||||
|
||||
found_first:
|
||||
tmp |= ~0UL << size;
|
||||
if (tmp == ~0UL) /* Are any bits zero? */
|
||||
return result + size; /* Nope. */
|
||||
found_middle:
|
||||
return result + ffz(tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first set bit in a memory region.
|
||||
*/
|
||||
unsigned long find_first_bit(const unsigned long *addr,
|
||||
unsigned long size)
|
||||
{
|
||||
const unsigned long *p = addr;
|
||||
unsigned long result = 0;
|
||||
unsigned long tmp;
|
||||
|
||||
while (size & ~(BITS_PER_LONG-1)) {
|
||||
if ((tmp = *(p++)))
|
||||
goto found;
|
||||
result += BITS_PER_LONG;
|
||||
size -= BITS_PER_LONG;
|
||||
}
|
||||
if (!size)
|
||||
return result;
|
||||
|
||||
tmp = (*p) & (~0UL >> (BITS_PER_LONG - size));
|
||||
if (tmp == 0UL) /* Are any bits set? */
|
||||
return result + size; /* Nope. */
|
||||
found:
|
||||
return result + __ffs(tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first cleared bit in a memory region.
|
||||
*/
|
||||
unsigned long find_first_zero_bit(const unsigned long *addr,
|
||||
unsigned long size)
|
||||
{
|
||||
const unsigned long *p = addr;
|
||||
unsigned long result = 0;
|
||||
unsigned long tmp;
|
||||
|
||||
while (size & ~(BITS_PER_LONG-1)) {
|
||||
if (~(tmp = *(p++)))
|
||||
goto found;
|
||||
result += BITS_PER_LONG;
|
||||
size -= BITS_PER_LONG;
|
||||
}
|
||||
if (!size)
|
||||
return result;
|
||||
|
||||
tmp = (*p) | (~0UL << size);
|
||||
if (tmp == ~0UL) /* Are any bits zero? */
|
||||
return result + size; /* Nope. */
|
||||
found:
|
||||
return result + ffz(tmp);
|
||||
}
|
||||
|
||||
37
lib/include/bitops-__ffs.h
Normal file
37
lib/include/bitops-__ffs.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* bitops-__ffs.h COPYRIGHT FUJITSU LIMITED 2014 */
|
||||
#ifndef INCLUDE_BITOPS___FFS_H
|
||||
#define INCLUDE_BITOPS___FFS_H
|
||||
|
||||
static inline unsigned long __ffs(unsigned long word)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
if (BITS_PER_LONG == 64) {
|
||||
if ((word & 0xffffffff) == 0) {
|
||||
num += 32;
|
||||
word >>= 32;
|
||||
}
|
||||
}
|
||||
|
||||
if ((word & 0xffff) == 0) {
|
||||
num += 16;
|
||||
word >>= 16;
|
||||
}
|
||||
if ((word & 0xff) == 0) {
|
||||
num += 8;
|
||||
word >>= 8;
|
||||
}
|
||||
if ((word & 0xf) == 0) {
|
||||
num += 4;
|
||||
word >>= 4;
|
||||
}
|
||||
if ((word & 0x3) == 0) {
|
||||
num += 2;
|
||||
word >>= 2;
|
||||
}
|
||||
if ((word & 0x1) == 0)
|
||||
num += 1;
|
||||
return num;
|
||||
}
|
||||
|
||||
#endif
|
||||
14
lib/include/bitops-clear_bit.h
Normal file
14
lib/include/bitops-clear_bit.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* bitops-clear_bit.h COPYRIGHT FUJITSU LIMITED 2014 */
|
||||
#ifndef INCLUDE_BITOPS_CLEAR_BIT_H
|
||||
#define INCLUDE_BITOPS_CLEAR_BIT_H
|
||||
|
||||
static inline void clear_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
|
||||
unsigned long *p = ((unsigned long *)addr) + (nr / BITS_PER_LONG);
|
||||
|
||||
*p &= ~mask;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
8
lib/include/bitops-ffz.h
Normal file
8
lib/include/bitops-ffz.h
Normal file
@@ -0,0 +1,8 @@
|
||||
/* bitops-ffz.h COPYRIGHT FUJITSU LIMITED 2014 */
|
||||
#ifndef INCLUDE_BITOPS_FFZ_H
|
||||
#define INCLUDE_BITOPS_FFZ_H
|
||||
|
||||
#define ffz(x) __ffs(~(x))
|
||||
|
||||
#endif
|
||||
|
||||
36
lib/include/bitops-fls.h
Normal file
36
lib/include/bitops-fls.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* bitops-fls.h COPYRIGHT FUJITSU LIMITED 2014 */
|
||||
#ifndef INCLUDE_BITOPS_FLS_H
|
||||
#define INCLUDE_BITOPS_FLS_H
|
||||
|
||||
static inline int fls(int x)
|
||||
{
|
||||
int r = 32;
|
||||
if (!x) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(x & 0xffff0000u)) {
|
||||
x <<= 16;
|
||||
r -= 16;
|
||||
}
|
||||
if (!(x & 0xff000000u)) {
|
||||
x <<= 8;
|
||||
r -= 8;
|
||||
}
|
||||
if (!(x & 0xf0000000u)) {
|
||||
x <<= 4;
|
||||
r -= 4;
|
||||
}
|
||||
if (!(x & 0xc0000000u)) {
|
||||
x <<= 2;
|
||||
r -= 2;
|
||||
}
|
||||
if (!(x & 0x80000000u)) {
|
||||
x <<= 1;
|
||||
r -= 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
14
lib/include/bitops-set_bit.h
Normal file
14
lib/include/bitops-set_bit.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* bitops-set_bit.h COPYRIGHT FUJITSU LIMITED 2014 */
|
||||
#ifndef INCLUDE_BITOPS_SET_BIT_H
|
||||
#define INCLUDE_BITOPS_SET_BIT_H
|
||||
|
||||
static inline void set_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
unsigned long mask = (1UL << (nr % BITS_PER_LONG));
|
||||
unsigned long *p = ((unsigned long *)addr) + (nr / BITS_PER_LONG);
|
||||
|
||||
*p |= mask;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
35
lib/include/bitops.h
Normal file
35
lib/include/bitops.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* bitops.h COPYRIGHT FUJITSU LIMITED 2014 */
|
||||
#ifndef INCLUDE_BITOPS_H
|
||||
#define INCLUDE_BITOPS_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define __BITS_TO_LONGS(n,d) (((n) + (d) - 1) / (d))
|
||||
#define BITS_TO_LONGS(nr) __BITS_TO_LONGS(nr, BITS_PER_LONG)
|
||||
#define DECLARE_BITMAP(name,bits) unsigned long name[BITS_TO_LONGS(bits)]
|
||||
|
||||
#define for_each_set_bit(bit, addr, size) \
|
||||
for ((bit) = find_first_bit((addr), (size)); \
|
||||
(bit) < (size); \
|
||||
(bit) = find_next_bit((addr), (size), (bit) + 1))
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset);
|
||||
|
||||
unsigned long find_next_zero_bit(const unsigned long *addr,
|
||||
unsigned long size, unsigned long offset);
|
||||
|
||||
unsigned long find_first_bit(const unsigned long *addr,
|
||||
unsigned long size);
|
||||
|
||||
unsigned long find_first_zero_bit(const unsigned long *addr,
|
||||
unsigned long size);
|
||||
|
||||
#endif /*__ASSEMBLY__*/
|
||||
|
||||
#include <arch-bitops.h>
|
||||
|
||||
#endif /*INCLUDE_BITOPS_H*/
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#define BITS_PER_BYTE 8
|
||||
#define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE)
|
||||
|
||||
#include <ihk/types.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user