Annotation of Gnu-Mach/linux/src/include/asm-i386/bitops.h, revision 1.1

1.1     ! root        1: #ifndef _I386_BITOPS_H
        !             2: #define _I386_BITOPS_H
        !             3: 
        !             4: /*
        !             5:  * Copyright 1992, Linus Torvalds.
        !             6:  */
        !             7: 
        !             8: /*
        !             9:  * These have to be done with inline assembly: that way the bit-setting
        !            10:  * is guaranteed to be atomic. All bit operations return 0 if the bit
        !            11:  * was cleared before the operation and != 0 if it was not.
        !            12:  *
        !            13:  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
        !            14:  */
        !            15: 
        !            16: #ifdef __SMP__
        !            17: #define LOCK_PREFIX "lock ; "
        !            18: #define SMPVOL volatile
        !            19: #else
        !            20: #define LOCK_PREFIX ""
        !            21: #define SMPVOL
        !            22: #endif
        !            23: 
        !            24: /*
        !            25:  * Some hacks to defeat gcc over-optimizations..
        !            26:  */
        !            27: struct __dummy { unsigned long a[100]; };
        !            28: #define ADDR (*(struct __dummy *) addr)
        !            29: #define CONST_ADDR (*(const struct __dummy *) addr)
        !            30: 
        !            31: extern __inline__ int set_bit(int nr, SMPVOL void * addr)
        !            32: {
        !            33:        int oldbit;
        !            34: 
        !            35:        __asm__ __volatile__(LOCK_PREFIX
        !            36:                "btsl %2,%1\n\tsbbl %0,%0"
        !            37:                :"=r" (oldbit),"=m" (ADDR)
        !            38:                :"ir" (nr));
        !            39:        return oldbit;
        !            40: }
        !            41: 
        !            42: extern __inline__ int clear_bit(int nr, SMPVOL void * addr)
        !            43: {
        !            44:        int oldbit;
        !            45: 
        !            46:        __asm__ __volatile__(LOCK_PREFIX
        !            47:                "btrl %2,%1\n\tsbbl %0,%0"
        !            48:                :"=r" (oldbit),"=m" (ADDR)
        !            49:                :"ir" (nr));
        !            50:        return oldbit;
        !            51: }
        !            52: 
        !            53: extern __inline__ int change_bit(int nr, SMPVOL void * addr)
        !            54: {
        !            55:        int oldbit;
        !            56: 
        !            57:        __asm__ __volatile__(LOCK_PREFIX
        !            58:                "btcl %2,%1\n\tsbbl %0,%0"
        !            59:                :"=r" (oldbit),"=m" (ADDR)
        !            60:                :"ir" (nr));
        !            61:        return oldbit;
        !            62: }
        !            63: 
        !            64: /*
        !            65:  * This routine doesn't need to be atomic.
        !            66:  */
        !            67: extern __inline__ int test_bit(int nr, const SMPVOL void * addr)
        !            68: {
        !            69:        return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0;
        !            70: }
        !            71: 
        !            72: /*
        !            73:  * Find-bit routines..
        !            74:  */
        !            75: extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
        !            76: {
        !            77:        int res;
        !            78: 
        !            79:        if (!size)
        !            80:                return 0;
        !            81:        __asm__("cld\n\t"
        !            82:                "movl $-1,%%eax\n\t"
        !            83:                "xorl %%edx,%%edx\n\t"
        !            84:                "repe; scasl\n\t"
        !            85:                "je 1f\n\t"
        !            86:                "xorl -4(%%edi),%%eax\n\t"
        !            87:                "subl $4,%%edi\n\t"
        !            88:                "bsfl %%eax,%%edx\n"
        !            89:                "1:\tsubl %%ebx,%%edi\n\t"
        !            90:                "shll $3,%%edi\n\t"
        !            91:                "addl %%edi,%%edx"
        !            92:                :"=d" (res)
        !            93:                :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
        !            94:                :"ax", "cx", "di");
        !            95:        return res;
        !            96: }
        !            97: 
        !            98: extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
        !            99: {
        !           100:        unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
        !           101:        int set = 0, bit = offset & 31, res;
        !           102:        
        !           103:        if (bit) {
        !           104:                /*
        !           105:                 * Look for zero in first byte
        !           106:                 */
        !           107:                __asm__("bsfl %1,%0\n\t"
        !           108:                        "jne 1f\n\t"
        !           109:                        "movl $32, %0\n"
        !           110:                        "1:"
        !           111:                        : "=r" (set)
        !           112:                        : "r" (~(*p >> bit)));
        !           113:                if (set < (32 - bit))
        !           114:                        return set + offset;
        !           115:                set = 32 - bit;
        !           116:                p++;
        !           117:        }
        !           118:        /*
        !           119:         * No zero yet, search remaining full bytes for a zero
        !           120:         */
        !           121:        res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
        !           122:        return (offset + set + res);
        !           123: }
        !           124: 
        !           125: /*
        !           126:  * ffz = Find First Zero in word. Undefined if no zero exists,
        !           127:  * so code should check against ~0UL first..
        !           128:  */
        !           129: extern __inline__ unsigned long ffz(unsigned long word)
        !           130: {
        !           131:        __asm__("bsfl %1,%0"
        !           132:                :"=r" (word)
        !           133:                :"r" (~word));
        !           134:        return word;
        !           135: }
        !           136: 
        !           137: #endif /* _I386_BITOPS_H */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.