bitops.h

来自「Linux Kernel 2.6.9 for OMAP1710」· C头文件 代码 · 共 1,189 行 · 第 1/3 页

H
1,189
字号
		break;	case 2:		asm volatile ("xi 0(%1),0x04" : "=m" (*(char *) addr)			      : "a" (addr), "m" (*(char *) addr) : "cc" );		break;	case 3:		asm volatile ("xi 0(%1),0x08" : "=m" (*(char *) addr)			      : "a" (addr), "m" (*(char *) addr) : "cc" );		break;	case 4:		asm volatile ("xi 0(%1),0x10" : "=m" (*(char *) addr)			      : "a" (addr), "m" (*(char *) addr) : "cc" );		break;	case 5:		asm volatile ("xi 0(%1),0x20" : "=m" (*(char *) addr)			      : "a" (addr), "m" (*(char *) addr) : "cc" );		break;	case 6:		asm volatile ("xi 0(%1),0x40" : "=m" (*(char *) addr)			      : "a" (addr), "m" (*(char *) addr) : "cc" );		break;	case 7:		asm volatile ("xi 0(%1),0x80" : "=m" (*(char *) addr)			      : "a" (addr), "m" (*(char *) addr) : "cc" );		break;	}}#define change_bit_simple(nr,addr) \(__builtin_constant_p((nr)) ? \ __constant_change_bit((nr),(addr)) : \ __change_bit((nr),(addr)) )/* * fast, non-SMP test_and_set_bit routine */static inline inttest_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr){	unsigned long addr;	unsigned char ch;	addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);	ch = *(unsigned char *) addr;        asm volatile("oc 0(1,%1),0(%2)"		     : "=m" (*(char *) addr)		     : "a" (addr), "a" (_oi_bitmap + (nr & 7)),		       "m" (*(char *) addr) : "cc", "memory" );	return (ch >> (nr & 7)) & 1;}#define __test_and_set_bit(X,Y)		test_and_set_bit_simple(X,Y)/* * fast, non-SMP test_and_clear_bit routine */static inline inttest_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr){	unsigned long addr;	unsigned char ch;	addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);	ch = *(unsigned char *) addr;        asm volatile("nc 0(1,%1),0(%2)"		     : "=m" (*(char *) addr)		     : "a" (addr), "a" (_ni_bitmap + (nr & 7)),		       "m" (*(char *) addr) : "cc", "memory" );	return (ch >> (nr & 7)) & 1;}#define __test_and_clear_bit(X,Y)	test_and_clear_bit_simple(X,Y)/* * fast, non-SMP test_and_change_bit routine */static inline inttest_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr){	unsigned long addr;	unsigned char ch;	addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);	ch = *(unsigned char *) addr;        asm volatile("xc 0(1,%1),0(%2)"		     : "=m" (*(char *) addr)		     : "a" (addr), "a" (_oi_bitmap + (nr & 7)),		       "m" (*(char *) addr) : "cc", "memory" );	return (ch >> (nr & 7)) & 1;}#define __test_and_change_bit(X,Y)	test_and_change_bit_simple(X,Y)#ifdef CONFIG_SMP#define set_bit             set_bit_cs#define clear_bit           clear_bit_cs#define change_bit          change_bit_cs#define test_and_set_bit    test_and_set_bit_cs#define test_and_clear_bit  test_and_clear_bit_cs#define test_and_change_bit test_and_change_bit_cs#else#define set_bit             set_bit_simple#define clear_bit           clear_bit_simple#define change_bit          change_bit_simple#define test_and_set_bit    test_and_set_bit_simple#define test_and_clear_bit  test_and_clear_bit_simple#define test_and_change_bit test_and_change_bit_simple#endif/* * This routine doesn't need to be atomic. */static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr){	unsigned long addr;	unsigned char ch;	addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);	ch = *(volatile unsigned char *) addr;	return (ch >> (nr & 7)) & 1;}static inline int __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) {    return (((volatile char *) addr)	    [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7)));}#define test_bit(nr,addr) \(__builtin_constant_p((nr)) ? \ __constant_test_bit((nr),(addr)) : \ __test_bit((nr),(addr)) )#ifndef __s390x__/* * Find-bit routines.. */static inline intfind_first_zero_bit(const unsigned long * addr, unsigned int size){	typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype;	unsigned long cmp, count;        unsigned int res;        if (!size)                return 0;        __asm__("   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"                "   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"                "   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 int size){	typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype;	unsigned long cmp, count;        unsigned int res;        if (!size)                return 0;        __asm__("   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"                "   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"                "   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;}static inline intfind_next_zero_bit (const unsigned long * addr, int size, int offset){        unsigned long * p = ((unsigned long *) addr) + (offset >> 5);        unsigned long bitvec, reg;        int set, bit = offset & 31, res;        if (bit) {                /*                 * Look for zero in first word                 */                bitvec = (*p) >> bit;                __asm__("   slr  %0,%0\n"                        "   lhi  %2,0xff\n"                        "   tml  %1,0xffff\n"                        "   jno  0f\n"                        "   ahi  %0,16\n"                        "   srl  %1,16\n"                        "0: tml  %1,0x00ff\n"                        "   jno  1f\n"                        "   ahi  %0,8\n"                        "   srl  %1,8\n"                        "1: nr   %1,%2\n"                        "   ic   %1,0(%1,%3)\n"                        "   alr  %0,%1"                        : "=&d" (set), "+a" (bitvec), "=&d" (reg)                        : "a" (&_zb_findmap) : "cc" );                if (set < (32 - bit))                        return set + offset;                offset += 32 - bit;                p++;        }        /*         * No zero yet, search remaining full words for a zero         */        res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));        return (offset + res);}static inline intfind_next_bit (const unsigned long * addr, int size, int offset){        unsigned long * p = ((unsigned long *) addr) + (offset >> 5);        unsigned long bitvec, reg;        int set, bit = offset & 31, res;        if (bit) {                /*                 * Look for set bit in first word                 */                bitvec = (*p) >> bit;                __asm__("   slr  %0,%0\n"                        "   lhi  %2,0xff\n"                        "   tml  %1,0xffff\n"                        "   jnz  0f\n"                        "   ahi  %0,16\n"                        "   srl  %1,16\n"                        "0: tml  %1,0x00ff\n"                        "   jnz  1f\n"                        "   ahi  %0,8\n"                        "   srl  %1,8\n"                        "1: nr   %1,%2\n"                        "   ic   %1,0(%1,%3)\n"                        "   alr  %0,%1"                        : "=&d" (set), "+a" (bitvec), "=&d" (reg)                        : "a" (&_sb_findmap) : "cc" );                if (set < (32 - bit))                        return set + offset;                offset += 32 - bit;                p++;        }        /*         * No set bit yet, search remaining full words for a bit         */        res = find_first_bit (p, size - 32 * (p - (unsigned long *) addr));        return (offset + res);}#else /* __s390x__ *//* * Find-bit routines.. */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__("   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"                "   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"                "   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__("   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;}static inline unsigned longfind_next_zero_bit (const unsigned long * addr, unsigned long size, unsigned long offset){        unsigned long * p = ((unsigned long *) addr) + (offset >> 6);        unsigned long bitvec, reg;        unsigned long set, bit = offset & 63, res;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?