root/arch/arm/lib/findbit.S

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

/* [<][>][^][v][top][bottom][index][help] */