OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [include/] [asm-i960/] [bitops.h] - Diff between revs 901 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 901 Rev 1765
#ifndef _ASM_GENERIC_BITOPS_H_
#ifndef _ASM_GENERIC_BITOPS_H_
#define _ASM_GENERIC_BITOPS_H_
#define _ASM_GENERIC_BITOPS_H_
 
 
#include <asm/system.h>
#include <asm/system.h>
 
 
/*
/*
 * N.B.: we shouldn't assume addresses are long*'s; nr can be > 31.
 * N.B.: we shouldn't assume addresses are long*'s; nr can be > 31.
 */
 */
static __inline__ long set_bit(long nr, void *a)
static __inline__ long set_bit(long nr, void *a)
{
{
        long*   addr = a;
        long*   addr = a;
        int     mask, oldval;
        int     mask, oldval;
 
 
        addr += nr >> 5;
        addr += nr >> 5;
        mask = 1 << (nr & 0x1f);
        mask = 1 << (nr & 0x1f);
        __asm__ __volatile__
        __asm__ __volatile__
                ("atmod %3, %2, %2"
                ("atmod %3, %2, %2"
                 : "=m" (*addr), "=r" (oldval)
                 : "=m" (*addr), "=r" (oldval)
                 : "1" (mask), "r" (addr), "m"(*addr));
                 : "1" (mask), "r" (addr), "m"(*addr));
        return (oldval & mask) != 0;
        return (oldval & mask) != 0;
}
}
 
 
static __inline__ long clear_bit(long nr, void *a)
static __inline__ long clear_bit(long nr, void *a)
{
{
        long*   addr = a;
        long*   addr = a;
        int     mask, oldval;
        int     mask, oldval;
 
 
        addr += nr >> 5;
        addr += nr >> 5;
        mask = 1 << (nr & 0x1f);
        mask = 1 << (nr & 0x1f);
        __asm__ __volatile__
        __asm__ __volatile__
                ("atmod %4, %3, %2"
                ("atmod %4, %3, %2"
                 : "=m" (*addr), "=r"(oldval)
                 : "=m" (*addr), "=r"(oldval)
                 : "1" (0), "r" (mask), "r"(addr), "m"(*addr));
                 : "1" (0), "r" (mask), "r"(addr), "m"(*addr));
        return (oldval & mask) != 0;
        return (oldval & mask) != 0;
}
}
 
 
 
 
static __inline__ long change_bit(long nr, void *a)
static __inline__ long change_bit(long nr, void *a)
{
{
        long*   addr = a;
        long*   addr = a;
        long    flags;
        long    flags;
        int     bitpos, retval;
        int     bitpos, retval;
 
 
        addr += nr >> 5;
        addr += nr >> 5;
        bitpos = (nr & 0x1f);
        bitpos = (nr & 0x1f);
        save_flags(flags);
        save_flags(flags);
        cli();
        cli();
 
 
#if 1
#if 1
        retval = (*addr & (1 << bitpos));
        retval = (*addr & (1 << bitpos));
        *addr ^= (1 << bitpos);
        *addr ^= (1 << bitpos);
#else
#else
        __asm__
        __asm__
                ("ld            (%2), r3\n\t"
                ("ld            (%2), r3\n\t"
                 "notbit        %1, r3, r4\n\t"
                 "notbit        %1, r3, r4\n\t"
                 "st            r4, (%2)\n\t"
                 "st            r4, (%2)\n\t"
                 "ldconst       1, r4\n\t"
                 "ldconst       1, r4\n\t"
                 "shlo          %1, r4, r4\n\t"
                 "shlo          %1, r4, r4\n\t"
                 "and           r4, r3, %0\n\t"
                 "and           r4, r3, %0\n\t"
                 : "=&r" (retval)
                 : "=&r" (retval)
                 : "r" (bitpos), "r" (addr)
                 : "r" (bitpos), "r" (addr)
                 : "r3", "r4", "memory");
                 : "r3", "r4", "memory");
#endif
#endif
        restore_flags(flags);
        restore_flags(flags);
        return retval != 0;
        return retval != 0;
}
}
 
 
static __inline__ long test_bit(long nr, void *a)
static __inline__ long test_bit(long nr, void *a)
{
{
        int     * addr = a;
        int     * addr = a;
        int     mask;
        int     mask;
 
 
        addr += nr >> 5;
        addr += nr >> 5;
        mask = 1 << (nr & 0x1f);
        mask = 1 << (nr & 0x1f);
        return ((mask & *addr) != 0);
        return ((mask & *addr) != 0);
}
}
 
 
/* The easy/cheese version for now. */
/* The easy/cheese version for now. */
extern __inline__ unsigned long ffz(unsigned long word)
extern __inline__ unsigned long ffz(unsigned long word)
{
{
        unsigned long result = 0;
        unsigned long result = 0;
 
 
        while(word & 1) {
        while(word & 1) {
                result++;
                result++;
                word >>= 1;
                word >>= 1;
        }
        }
        return result;
        return result;
}
}
 
 
/* find_next_zero_bit() finds the first zero bit in a bit string of length
/* find_next_zero_bit() finds the first zero bit in a bit string of length
 * 'size' bits, starting the search at bit 'offset'. This is largely based
 * 'size' bits, starting the search at bit 'offset'. This is largely based
 * on Linus's ALPHA routines, which are pretty portable BTW.
 * on Linus's ALPHA routines, which are pretty portable BTW.
 */
 */
 
 
extern __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
extern __inline__ unsigned long find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
{
{
        unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
        unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
        unsigned long result = offset & ~31UL;
        unsigned long result = offset & ~31UL;
        unsigned long tmp;
        unsigned long tmp;
 
 
        if (offset >= size)
        if (offset >= size)
                return size;
                return size;
        size -= result;
        size -= result;
        offset &= 31UL;
        offset &= 31UL;
        if (offset) {
        if (offset) {
                tmp = *(p++);
                tmp = *(p++);
                tmp |= ~0UL >> (32-offset);
                tmp |= ~0UL >> (32-offset);
                if (size < 32)
                if (size < 32)
                        goto found_first;
                        goto found_first;
                if (~tmp)
                if (~tmp)
                        goto found_middle;
                        goto found_middle;
                size -= 32;
                size -= 32;
                result += 32;
                result += 32;
        }
        }
        while (size & ~31UL) {
        while (size & ~31UL) {
                if (~(tmp = *(p++)))
                if (~(tmp = *(p++)))
                        goto found_middle;
                        goto found_middle;
                result += 32;
                result += 32;
                size -= 32;
                size -= 32;
        }
        }
        if (!size)
        if (!size)
                return result;
                return result;
        tmp = *p;
        tmp = *p;
 
 
found_first:
found_first:
        tmp |= ~0UL >> size;
        tmp |= ~0UL >> size;
found_middle:
found_middle:
        return result + ffz(tmp);
        return result + ffz(tmp);
}
}
 
 
/* Linus sez that gcc can optimize the following correctly, we'll see if this
/* Linus sez that gcc can optimize the following correctly, we'll see if this
 * holds on the Sparc as it does for the ALPHA.
 * holds on the Sparc as it does for the ALPHA.
 */
 */
 
 
#define find_first_zero_bit(addr, size) \
#define find_first_zero_bit(addr, size) \
        find_next_zero_bit((addr), (size), 0)
        find_next_zero_bit((addr), (size), 0)
 
 
 
 
#endif /* _ASM_I960_BITOPS_H */
#endif /* _ASM_I960_BITOPS_H */
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.