linux/arch/arm/lib/findbit.S
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/lib/findbit.S
   3 *
   4 *  Copyright (C) 1995-2000 Russell King
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * 16th March 2001 - John Ripley <jripley@sonicblue.com>
  11 *   Fixed so that "size" is an exclusive not an inclusive quantity.
  12 *   All users of these functions expect exclusive sizes, and may
  13 *   also call with zero size.
  14 * Reworked by rmk.
  15 */
  16#include <linux/linkage.h>
  17#include <asm/assembler.h>
  18                .text
  19
  20/*
  21 * Purpose  : Find a 'zero' bit
  22 * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
  23 */
  24ENTRY(_find_first_zero_bit_le)
  25                teq     r1, #0  
  26                beq     3f
  27                mov     r2, #0
  281:
  29 ARM(           ldrb    r3, [r0, r2, lsr #3]    )
  30 THUMB(         lsr     r3, r2, #3              )
  31 THUMB(         ldrb    r3, [r0, r3]            )
  32                eors    r3, r3, #0xff           @ invert bits
  33                bne     .L_found                @ any now set - found zero bit
  34                add     r2, r2, #8              @ next bit pointer
  352:              cmp     r2, r1                  @ any more?
  36                blo     1b
  373:              mov     r0, r1                  @ no free bits
  38                mov     pc, lr
  39ENDPROC(_find_first_zero_bit_le)
  40
  41/*
  42 * Purpose  : Find next 'zero' bit
  43 * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  44 */
  45ENTRY(_find_next_zero_bit_le)
  46                teq     r1, #0
  47                beq     3b
  48                ands    ip, r2, #7
  49                beq     1b                      @ If new byte, goto old routine
  50 ARM(           ldrb    r3, [r0, r2, lsr #3]    )
  51 THUMB(         lsr     r3, r2, #3              )
  52 THUMB(         ldrb    r3, [r0, r3]            )
  53                eor     r3, r3, #0xff           @ now looking for a 1 bit
  54                movs    r3, r3, lsr ip          @ shift off unused bits
  55                bne     .L_found
  56                orr     r2, r2, #7              @ if zero, then no bits here
  57                add     r2, r2, #1              @ align bit pointer
  58                b       2b                      @ loop for next bit
  59ENDPROC(_find_next_zero_bit_le)
  60
  61/*
  62 * Purpose  : Find a 'one' bit
  63 * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
  64 */
  65ENTRY(_find_first_bit_le)
  66                teq     r1, #0  
  67                beq     3f
  68                mov     r2, #0
  691:
  70 ARM(           ldrb    r3, [r0, r2, lsr #3]    )
  71 THUMB(         lsr     r3, r2, #3              )
  72 THUMB(         ldrb    r3, [r0, r3]            )
  73                movs    r3, r3
  74                bne     .L_found                @ any now set - found zero bit
  75                add     r2, r2, #8              @ next bit pointer
  762:              cmp     r2, r1                  @ any more?
  77                blo     1b
  783:              mov     r0, r1                  @ no free bits
  79                mov     pc, lr
  80ENDPROC(_find_first_bit_le)
  81
  82/*
  83 * Purpose  : Find next 'one' bit
  84 * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
  85 */
  86ENTRY(_find_next_bit_le)
  87                teq     r1, #0
  88                beq     3b
  89                ands    ip, r2, #7
  90                beq     1b                      @ If new byte, goto old routine
  91 ARM(           ldrb    r3, [r0, r2, lsr #3]    )
  92 THUMB(         lsr     r3, r2, #3              )
  93 THUMB(         ldrb    r3, [r0, r3]            )
  94                movs    r3, r3, lsr ip          @ shift off unused bits
  95                bne     .L_found
  96                orr     r2, r2, #7              @ if zero, then no bits here
  97                add     r2, r2, #1              @ align bit pointer
  98                b       2b                      @ loop for next bit
  99ENDPROC(_find_next_bit_le)
 100
 101#ifdef __ARMEB__
 102
 103ENTRY(_find_first_zero_bit_be)
 104                teq     r1, #0
 105                beq     3f
 106                mov     r2, #0
 1071:              eor     r3, r2, #0x18           @ big endian byte ordering
 108 ARM(           ldrb    r3, [r0, r3, lsr #3]    )
 109 THUMB(         lsr     r3, #3                  )
 110 THUMB(         ldrb    r3, [r0, r3]            )
 111                eors    r3, r3, #0xff           @ invert bits
 112                bne     .L_found                @ any now set - found zero bit
 113                add     r2, r2, #8              @ next bit pointer
 1142:              cmp     r2, r1                  @ any more?
 115                blo     1b
 1163:              mov     r0, r1                  @ no free bits
 117                mov     pc, lr
 118ENDPROC(_find_first_zero_bit_be)
 119
 120ENTRY(_find_next_zero_bit_be)
 121                teq     r1, #0
 122                beq     3b
 123                ands    ip, r2, #7
 124                beq     1b                      @ If new byte, goto old routine
 125                eor     r3, r2, #0x18           @ big endian byte ordering
 126 ARM(           ldrb    r3, [r0, r3, lsr #3]    )
 127 THUMB(         lsr     r3, #3                  )
 128 THUMB(         ldrb    r3, [r0, r3]            )
 129                eor     r3, r3, #0xff           @ now looking for a 1 bit
 130                movs    r3, r3, lsr ip          @ shift off unused bits
 131                bne     .L_found
 132                orr     r2, r2, #7              @ if zero, then no bits here
 133                add     r2, r2, #1              @ align bit pointer
 134                b       2b                      @ loop for next bit
 135ENDPROC(_find_next_zero_bit_be)
 136
 137ENTRY(_find_first_bit_be)
 138                teq     r1, #0
 139                beq     3f
 140                mov     r2, #0
 1411:              eor     r3, r2, #0x18           @ big endian byte ordering
 142 ARM(           ldrb    r3, [r0, r3, lsr #3]    )
 143 THUMB(         lsr     r3, #3                  )
 144 THUMB(         ldrb    r3, [r0, r3]            )
 145                movs    r3, r3
 146                bne     .L_found                @ any now set - found zero bit
 147                add     r2, r2, #8              @ next bit pointer
 1482:              cmp     r2, r1                  @ any more?
 149                blo     1b
 1503:              mov     r0, r1                  @ no free bits
 151                mov     pc, lr
 152ENDPROC(_find_first_bit_be)
 153
 154ENTRY(_find_next_bit_be)
 155                teq     r1, #0
 156                beq     3b
 157                ands    ip, r2, #7
 158                beq     1b                      @ If new byte, goto old routine
 159                eor     r3, r2, #0x18           @ big endian byte ordering
 160 ARM(           ldrb    r3, [r0, r3, lsr #3]    )
 161 THUMB(         lsr     r3, #3                  )
 162 THUMB(         ldrb    r3, [r0, r3]            )
 163                movs    r3, r3, lsr ip          @ shift off unused bits
 164                bne     .L_found
 165                orr     r2, r2, #7              @ if zero, then no bits here
 166                add     r2, r2, #1              @ align bit pointer
 167                b       2b                      @ loop for next bit
 168ENDPROC(_find_next_bit_be)
 169
 170#endif
 171
 172/*
 173 * One or more bits in the LSB of r3 are assumed to be set.
 174 */
 175.L_found:
 176#if __LINUX_ARM_ARCH__ >= 5
 177                rsb     r0, r3, #0
 178                and     r3, r3, r0
 179                clz     r3, r3
 180                rsb     r3, r3, #31
 181                add     r0, r2, r3
 182#else
 183                tst     r3, #0x0f
 184                addeq   r2, r2, #4
 185                movne   r3, r3, lsl #4
 186                tst     r3, #0x30
 187                addeq   r2, r2, #2
 188                movne   r3, r3, lsl #2
 189                tst     r3, #0x40
 190                addeq   r2, r2, #1
 191                mov     r0, r2
 192#endif
 193                cmp     r1, r0                  @ Clamp to maxbit
 194                movlo   r0, r1
 195                mov     pc, lr
 196
 197