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 + -
显示快捷键?