fix REQ-51

This commit is contained in:
Tomoki Shirasawa
2016-03-26 12:23:16 +09:00
parent a11479eba8
commit b0096a2740
10 changed files with 249 additions and 109 deletions

View File

@ -0,0 +1,96 @@
/**
* \file arch-bitops.h
* License details are found in the file LICENSE.
* \brief
* Find last set bit in word.
* \author Taku Shimosawa <shimosawa@is.s.u-tokyo.ac.jp> \par
* Copyright (C) 2011 - 2012 Taku Shimosawa
*/
/*
* HISTORY
*/
#ifndef HEADER_X86_COMMON_ARCH_BITOPS_H
#define HEADER_X86_COMMON_ARCH_BITOPS_H
static inline int fls(int x)
{
int r;
asm("bsrl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:" : "=r" (r) : "rm" (x));
return r + 1;
}
/**
* ffs - find first set bit in word
* @x: the word to search
*
* This is defined the same way as the libc and compiler builtin ffs
* routines, therefore differs in spirit from the other bitops.
*
* ffs(value) returns 0 if value is 0 or the position of the first
* set bit if value is nonzero. The first (least significant) bit
* is at position 1.
*/
static inline int ffs(int x)
{
int r;
asm("bsfl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:" : "=r" (r) : "rm" (x));
return r + 1;
}
/**
* __ffs - find first set bit in word
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static inline unsigned long __ffs(unsigned long word)
{
asm("bsf %1,%0"
: "=r" (word)
: "rm" (word));
return word;
}
/**
* ffz - find first zero bit in word
* @word: The word to search
*
* Undefined if no zero exists, so code should check against ~0UL first.
*/
static inline unsigned long ffz(unsigned long word)
{
asm("bsf %1,%0"
: "=r" (word)
: "r" (~word));
return word;
}
#define ADDR (*(volatile long *)addr)
static inline void set_bit(int nr, volatile unsigned long *addr)
{
asm volatile("lock; btsl %1,%0"
: "+m" (ADDR)
: "Ir" (nr)
: "memory");
}
static inline void clear_bit(int nr, volatile unsigned long *addr)
{
asm volatile("lock; btrl %1,%0"
: "+m" (ADDR)
: "Ir" (nr)
: "memory");
}
#endif

View File

@ -31,9 +31,5 @@ typedef int64_t off_t;
#define NULL ((void *)0)
#define BITS_PER_LONG_SHIFT 6
#define BITS_PER_LONG (1 << BITS_PER_LONG_SHIFT)
#endif

View File

@ -1,109 +1,12 @@
/**
* \file bitops.h
* License details are found in the file LICENSE.
* \brief
* Find last set bit in word.
* \author Taku Shimosawa <shimosawa@is.s.u-tokyo.ac.jp> \par
* Copyright (C) 2011 - 2012 Taku Shimosawa
*/
/*
* HISTORY
*/
#ifndef HEADER_X86_COMMON_BITOPS_H
#define HEADER_X86_COMMON_BITOPS_H
static inline int fls(int x)
{
int r;
asm("bsrl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:" : "=r" (r) : "rm" (x));
return r + 1;
}
/**
* ffs - find first set bit in word
* @x: the word to search
*
* This is defined the same way as the libc and compiler builtin ffs
* routines, therefore differs in spirit from the other bitops.
*
* ffs(value) returns 0 if value is 0 or the position of the first
* set bit if value is nonzero. The first (least significant) bit
* is at position 1.
*/
static inline int ffs(int x)
{
int r;
asm("bsfl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n"
"1:" : "=r" (r) : "rm" (x));
return r + 1;
}
/**
* __ffs - find first set bit in word
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static inline unsigned long __ffs(unsigned long word)
{
asm("bsf %1,%0"
: "=r" (word)
: "rm" (word));
return word;
}
/**
* ffz - find first zero bit in word
* @word: The word to search
*
* Undefined if no zero exists, so code should check against ~0UL first.
*/
static inline unsigned long ffz(unsigned long word)
{
asm("bsf %1,%0"
: "=r" (word)
: "r" (~word));
return word;
}
#define ADDR (*(volatile long *)addr)
static inline void set_bit(int nr, volatile unsigned long *addr)
{
asm volatile("lock; btsl %1,%0"
: "+m" (ADDR)
: "Ir" (nr)
: "memory");
}
static inline void clear_bit(int nr, volatile unsigned long *addr)
{
asm volatile("lock; btrl %1,%0"
: "+m" (ADDR)
: "Ir" (nr)
: "memory");
}
#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))
/* 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.
*/
static unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
const unsigned long *p = addr + BITOP_WORD(offset);
@ -146,7 +49,7 @@ found_middle:
* This implementation of find_{first,next}_zero_bit was stolen from
* Linus' asm-alpha/bitops.h.
*/
static unsigned long find_next_zero_bit(const unsigned long *addr,
unsigned long find_next_zero_bit(const unsigned long *addr,
unsigned long size, unsigned long offset)
{
const unsigned long *p = addr + BITOP_WORD(offset);
@ -188,7 +91,7 @@ found_middle:
/*
* Find the first set bit in a memory region.
*/
static unsigned long find_first_bit(const unsigned long *addr,
unsigned long find_first_bit(const unsigned long *addr,
unsigned long size)
{
const unsigned long *p = addr;
@ -214,7 +117,7 @@ found:
/*
* Find the first cleared bit in a memory region.
*/
static unsigned long find_first_zero_bit(const unsigned long *addr,
unsigned long find_first_zero_bit(const unsigned long *addr,
unsigned long size)
{
const unsigned long *p = addr;
@ -237,4 +140,3 @@ found:
return result + ffz(tmp);
}
#endif

View 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

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

View 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
View 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*/

View File

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