bitops.h
来自「linux 内核源代码」· C头文件 代码 · 共 916 行 · 第 1/2 页
H
916 行
} if (likely((word & 0xff) == 0xff)) { word >>= 8; bit += 8; } return bit + _zb_findmap[word & 0xff];}/* * __ffs = find first bit in word. Undefined if no bit exists, * so code should check against 0UL first.. */static inline unsigned long __ffs (unsigned long word){ unsigned long bit = 0;#ifdef __s390x__ if (likely((word & 0xffffffff) == 0)) { word >>= 32; bit += 32; }#endif if (likely((word & 0xffff) == 0)) { word >>= 16; bit += 16; } if (likely((word & 0xff) == 0)) { word >>= 8; bit += 8; } return bit + _sb_findmap[word & 0xff];}/* * Find-bit routines.. */#ifndef __s390x__static inline intfind_first_zero_bit(const unsigned long * addr, unsigned long size){ typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; unsigned long cmp, count; unsigned int res; if (!size) return 0; asm volatile( " lhi %1,-1\n" " lr %2,%3\n" " slr %0,%0\n" " ahi %2,31\n" " srl %2,5\n" "0: c %1,0(%0,%4)\n" " jne 1f\n" " la %0,4(%0)\n" " brct %2,0b\n" " lr %0,%3\n" " j 4f\n" "1: l %2,0(%0,%4)\n" " sll %0,3\n" " lhi %1,0xff\n" " tml %2,0xffff\n" " jno 2f\n" " ahi %0,16\n" " srl %2,16\n" "2: tml %2,0x00ff\n" " jno 3f\n" " ahi %0,8\n" " srl %2,8\n" "3: nr %2,%1\n" " ic %2,0(%2,%5)\n" " alr %0,%2\n" "4:" : "=&a" (res), "=&d" (cmp), "=&a" (count) : "a" (size), "a" (addr), "a" (&_zb_findmap), "m" (*(addrtype *) addr) : "cc"); return (res < size) ? res : size;}static inline intfind_first_bit(const unsigned long * addr, unsigned long size){ typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; unsigned long cmp, count; unsigned int res; if (!size) return 0; asm volatile( " slr %1,%1\n" " lr %2,%3\n" " slr %0,%0\n" " ahi %2,31\n" " srl %2,5\n" "0: c %1,0(%0,%4)\n" " jne 1f\n" " la %0,4(%0)\n" " brct %2,0b\n" " lr %0,%3\n" " j 4f\n" "1: l %2,0(%0,%4)\n" " sll %0,3\n" " lhi %1,0xff\n" " tml %2,0xffff\n" " jnz 2f\n" " ahi %0,16\n" " srl %2,16\n" "2: tml %2,0x00ff\n" " jnz 3f\n" " ahi %0,8\n" " srl %2,8\n" "3: nr %2,%1\n" " ic %2,0(%2,%5)\n" " alr %0,%2\n" "4:" : "=&a" (res), "=&d" (cmp), "=&a" (count) : "a" (size), "a" (addr), "a" (&_sb_findmap), "m" (*(addrtype *) addr) : "cc"); return (res < size) ? res : size;}#else /* __s390x__ */static inline unsigned longfind_first_zero_bit(const unsigned long * addr, unsigned long size){ typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; unsigned long res, cmp, count; if (!size) return 0; asm volatile( " lghi %1,-1\n" " lgr %2,%3\n" " slgr %0,%0\n" " aghi %2,63\n" " srlg %2,%2,6\n" "0: cg %1,0(%0,%4)\n" " jne 1f\n" " la %0,8(%0)\n" " brct %2,0b\n" " lgr %0,%3\n" " j 5f\n" "1: lg %2,0(%0,%4)\n" " sllg %0,%0,3\n" " clr %2,%1\n" " jne 2f\n" " aghi %0,32\n" " srlg %2,%2,32\n" "2: lghi %1,0xff\n" " tmll %2,0xffff\n" " jno 3f\n" " aghi %0,16\n" " srl %2,16\n" "3: tmll %2,0x00ff\n" " jno 4f\n" " aghi %0,8\n" " srl %2,8\n" "4: ngr %2,%1\n" " ic %2,0(%2,%5)\n" " algr %0,%2\n" "5:" : "=&a" (res), "=&d" (cmp), "=&a" (count) : "a" (size), "a" (addr), "a" (&_zb_findmap), "m" (*(addrtype *) addr) : "cc"); return (res < size) ? res : size;}static inline unsigned longfind_first_bit(const unsigned long * addr, unsigned long size){ typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; unsigned long res, cmp, count; if (!size) return 0; asm volatile( " slgr %1,%1\n" " lgr %2,%3\n" " slgr %0,%0\n" " aghi %2,63\n" " srlg %2,%2,6\n" "0: cg %1,0(%0,%4)\n" " jne 1f\n" " aghi %0,8\n" " brct %2,0b\n" " lgr %0,%3\n" " j 5f\n" "1: lg %2,0(%0,%4)\n" " sllg %0,%0,3\n" " clr %2,%1\n" " jne 2f\n" " aghi %0,32\n" " srlg %2,%2,32\n" "2: lghi %1,0xff\n" " tmll %2,0xffff\n" " jnz 3f\n" " aghi %0,16\n" " srl %2,16\n" "3: tmll %2,0x00ff\n" " jnz 4f\n" " aghi %0,8\n" " srl %2,8\n" "4: ngr %2,%1\n" " ic %2,0(%2,%5)\n" " algr %0,%2\n" "5:" : "=&a" (res), "=&d" (cmp), "=&a" (count) : "a" (size), "a" (addr), "a" (&_sb_findmap), "m" (*(addrtype *) addr) : "cc"); return (res < size) ? res : size;}#endif /* __s390x__ */static inline intfind_next_zero_bit (const unsigned long * addr, unsigned long size, unsigned long offset){ const unsigned long *p; unsigned long bit, set; if (offset >= size) return size; bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* * s390 version of ffz returns __BITOPS_WORDSIZE * if no zero bit is present in the word. */ set = ffz(*p >> bit) + bit; if (set >= size) return size + offset; if (set < __BITOPS_WORDSIZE) return set + offset; offset += __BITOPS_WORDSIZE; size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_zero_bit(p, size);}static inline intfind_next_bit (const unsigned long * addr, unsigned long size, unsigned long offset){ const unsigned long *p; unsigned long bit, set; if (offset >= size) return size; bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; p = addr + offset / __BITOPS_WORDSIZE; if (bit) { /* * s390 version of __ffs returns __BITOPS_WORDSIZE * if no one bit is present in the word. */ set = __ffs(*p & (~0UL << bit)); if (set >= size) return size + offset; if (set < __BITOPS_WORDSIZE) return set + offset; offset += __BITOPS_WORDSIZE; size -= __BITOPS_WORDSIZE; p++; } return offset + find_first_bit(p, size);}/* * Every architecture must define this function. It's the fastest * way of searching a 140-bit bitmap where the first 100 bits are * unlikely to be set. It's guaranteed that at least one of the 140 * bits is cleared. */static inline int sched_find_first_bit(unsigned long *b){ return find_first_bit(b, 140);}#include <asm-generic/bitops/ffs.h>#include <asm-generic/bitops/fls.h>#include <asm-generic/bitops/fls64.h>#include <asm-generic/bitops/hweight.h>#include <asm-generic/bitops/lock.h>/* * ATTENTION: intel byte ordering convention for ext2 and minix !! * bit 0 is the LSB of addr; bit 31 is the MSB of addr; * bit 32 is the LSB of (addr+4). * That combined with the little endian byte order of Intel gives the * following bit order in memory: * 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 \ * 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24 */#define ext2_set_bit(nr, addr) \ __test_and_set_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)#define ext2_set_bit_atomic(lock, nr, addr) \ test_and_set_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)#define ext2_clear_bit(nr, addr) \ __test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)#define ext2_clear_bit_atomic(lock, nr, addr) \ test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)#define ext2_test_bit(nr, addr) \ test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr)#ifndef __s390x__static inline int ext2_find_first_zero_bit(void *vaddr, unsigned int size){ typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; unsigned long cmp, count; unsigned int res; if (!size) return 0; asm volatile( " lhi %1,-1\n" " lr %2,%3\n" " ahi %2,31\n" " srl %2,5\n" " slr %0,%0\n" "0: cl %1,0(%0,%4)\n" " jne 1f\n" " ahi %0,4\n" " brct %2,0b\n" " lr %0,%3\n" " j 4f\n" "1: l %2,0(%0,%4)\n" " sll %0,3\n" " ahi %0,24\n" " lhi %1,0xff\n" " tmh %2,0xffff\n" " jo 2f\n" " ahi %0,-16\n" " srl %2,16\n" "2: tml %2,0xff00\n" " jo 3f\n" " ahi %0,-8\n" " srl %2,8\n" "3: nr %2,%1\n" " ic %2,0(%2,%5)\n" " alr %0,%2\n" "4:" : "=&a" (res), "=&d" (cmp), "=&a" (count) : "a" (size), "a" (vaddr), "a" (&_zb_findmap), "m" (*(addrtype *) vaddr) : "cc"); return (res < size) ? res : size;}#else /* __s390x__ */static inline unsigned longext2_find_first_zero_bit(void *vaddr, unsigned long size){ typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; unsigned long res, cmp, count; if (!size) return 0; asm volatile( " lghi %1,-1\n" " lgr %2,%3\n" " aghi %2,63\n" " srlg %2,%2,6\n" " slgr %0,%0\n" "0: clg %1,0(%0,%4)\n" " jne 1f\n" " aghi %0,8\n" " brct %2,0b\n" " lgr %0,%3\n" " j 5f\n" "1: cl %1,0(%0,%4)\n" " jne 2f\n" " aghi %0,4\n" "2: l %2,0(%0,%4)\n" " sllg %0,%0,3\n" " aghi %0,24\n" " lghi %1,0xff\n" " tmlh %2,0xffff\n" " jo 3f\n" " aghi %0,-16\n" " srl %2,16\n" "3: tmll %2,0xff00\n" " jo 4f\n" " aghi %0,-8\n" " srl %2,8\n" "4: ngr %2,%1\n" " ic %2,0(%2,%5)\n" " algr %0,%2\n" "5:" : "=&a" (res), "=&d" (cmp), "=&a" (count) : "a" (size), "a" (vaddr), "a" (&_zb_findmap), "m" (*(addrtype *) vaddr) : "cc"); return (res < size) ? res : size;}#endif /* __s390x__ */static inline intext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset){ unsigned long *addr = vaddr, *p; unsigned long word, bit, set; if (offset >= size) return size; bit = offset & (__BITOPS_WORDSIZE - 1); offset -= bit; size -= offset; p = addr + offset / __BITOPS_WORDSIZE; if (bit) {#ifndef __s390x__ asm volatile( " ic %0,0(%1)\n" " icm %0,2,1(%1)\n" " icm %0,4,2(%1)\n" " icm %0,8,3(%1)" : "=&a" (word) : "a" (p), "m" (*p) : "cc");#else asm volatile( " lrvg %0,%1" : "=a" (word) : "m" (*p) );#endif /* * s390 version of ffz returns __BITOPS_WORDSIZE * if no zero bit is present in the word. */ set = ffz(word >> bit) + bit; if (set >= size) return size + offset; if (set < __BITOPS_WORDSIZE) return set + offset; offset += __BITOPS_WORDSIZE; size -= __BITOPS_WORDSIZE; p++; } return offset + ext2_find_first_zero_bit(p, size);}#include <asm-generic/bitops/minix.h>#endif /* __KERNEL__ */#endif /* _S390_BITOPS_H */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?