Annotation of Gnu-Mach/linux/src/include/asm-i386/bitops.h, revision 1.1.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.