]> git.neil.brown.name Git - history.git/commitdiff
[ARM] Add find_first_bit and find_next_bit.
authorRussell King <rmk@flint.arm.linux.org.uk>
Tue, 20 Apr 2004 16:58:21 +0000 (17:58 +0100)
committerRussell King <rmk@flint.arm.linux.org.uk>
Tue, 20 Apr 2004 16:58:21 +0000 (17:58 +0100)
arch/arm/lib/findbit.S
include/asm-arm/bitops.h

index 304d7bc469e62745e4f30c6036758261636cdbf1..d3a81da57c3e71b94db2b80094dd7fe88f20ca01 100644 (file)
@@ -51,6 +51,39 @@ ENTRY(_find_next_zero_bit_le)
                add     r2, r2, #1              @ align bit pointer
                b       2b                      @ loop for next bit
 
+/*
+ * Purpose  : Find a 'one' bit
+ * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
+ */
+ENTRY(_find_first_bit_le)
+               teq     r1, #0  
+               beq     3f
+               mov     r2, #0
+1:             ldrb    r3, [r0, r2, lsr #3]
+               movs    r3, r3
+               bne     .found                  @ any now set - found zero bit
+               add     r2, r2, #8              @ next bit pointer
+2:             cmp     r2, r1                  @ any more?
+               blo     1b
+3:             mov     r0, r1                  @ no free bits
+               RETINSTR(mov,pc,lr)
+
+/*
+ * Purpose  : Find next 'one' bit
+ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
+ */
+ENTRY(_find_next_bit_le)
+               teq     r1, #0
+               beq     2b
+               ands    ip, r2, #7
+               beq     1b                      @ If new byte, goto old routine
+               ldrb    r3, [r0, r2, lsr #3]
+               movs    r3, r3, lsr ip          @ shift off unused bits
+               bne     .found
+               orr     r2, r2, #7              @ if zero, then no bits here
+               add     r2, r2, #1              @ align bit pointer
+               b       2b                      @ loop for next bit
+
 #ifdef __ARMEB__
 
 ENTRY(_find_first_zero_bit_be)
@@ -78,6 +111,30 @@ ENTRY(_find_next_zero_bit_be)
                addeq   r2, r2, #1              @ align bit pointer
                beq     2b                      @ loop for next bit
 
+ENTRY(_find_first_bit_be)
+               teq     r1, #0
+               beq     3f
+               mov     r2, #0
+1:             eor     r3, r2, #0x18           @ big endian byte ordering
+               ldrb    r3, [r0, r3, lsr #3]
+               movs    r3, r3
+               bne     .found                  @ any now set - found zero bit
+               add     r2, r2, #8              @ next bit pointer
+2:             cmp     r2, r1                  @ any more?
+               blo     1b
+3:             mov     r0, r1                  @ no free bits
+               RETINSTR(mov,pc,lr)
+
+ENTRY(_find_next_bit_be)
+               ands    ip, r2, #7
+               beq     1b                      @ If new byte, goto old routine
+               eor     r3, r2, #0x18           @ big endian byte ordering
+               ldrb    r3, [r0, r3, lsr #3]
+               movs    r3, r3, lsr ip          @ shift off unused bits
+               orreq   r2, r2, #7              @ if zero, then no bits here
+               addeq   r2, r2, #1              @ align bit pointer
+               beq     2b                      @ loop for next bit
+
 #endif
 
 /*
index 8ae0be984492142fcf77f566ff9eac6c50e36259..7fb3046c6729f0fdff7363f109da5f9659c70feb 100644 (file)
@@ -212,6 +212,8 @@ extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
 extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
 extern int _find_first_zero_bit_le(void * p, unsigned size);
 extern int _find_next_zero_bit_le(void * p, int size, int offset);
+extern int _find_first_bit_le(const unsigned long *p, unsigned size);
+extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
 
 /*
  * Big endian assembly bitops.  nr = 0 -> byte 3 bit 0.
@@ -224,7 +226,8 @@ extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
 extern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
 extern int _find_first_zero_bit_be(void * p, unsigned size);
 extern int _find_next_zero_bit_be(void * p, int size, int offset);
-
+extern int _find_first_bit_be(const unsigned long *p, unsigned size);
+extern int _find_next_bit_be(unsigned long *p, int size, int offset);
 
 /*
  * The __* form of bitops are non-atomic and may be reordered.
@@ -255,6 +258,8 @@ extern int _find_next_zero_bit_be(void * p, int size, int offset);
 #define test_bit(nr,p)                 __test_bit(nr,p)
 #define find_first_zero_bit(p,sz)      _find_first_zero_bit_le(p,sz)
 #define find_next_zero_bit(p,sz,off)   _find_next_zero_bit_le(p,sz,off)
+#define find_first_bit(p,sz)           _find_first_bit_le(p,sz)
+#define find_next_bit(p,sz,off)                _find_next_bit_le(p,sz,off)
 
 #define WORD_BITOFF_TO_LE(x)           ((x))
 
@@ -272,6 +277,8 @@ extern int _find_next_zero_bit_be(void * p, int size, int offset);
 #define test_bit(nr,p)                 __test_bit(nr,p)
 #define find_first_zero_bit(p,sz)      _find_first_zero_bit_be(p,sz)
 #define find_next_zero_bit(p,sz,off)   _find_next_zero_bit_be(p,sz,off)
+#define find_first_bit(p,sz)           _find_first_bit_be(p,sz)
+#define find_next_bit(p,sz,off)                _find_next_bit_be(p,sz,off)
 
 #define WORD_BITOFF_TO_LE(x)           ((x) ^ 0x18)