linux/arch/arm/lib/findbit.S
<<
>>
Prefs
   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 */
  21ENTRY(_find_first_zero_bit_le)
  22                teq     r1, #0  
  23                beq     3f
  24                mov     r2, #0
  251:
  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
  322:              cmp     r2, r1                  @ any more?
  33                blo     1b
  343:              mov     r0, r1                  @ no free bits
  35                ret     lr
  36ENDPROC(_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 */
  42ENTRY(_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
  56ENDPROC(_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 */
  62ENTRY(_find_first_bit_le)
  63                teq     r1, #0  
  64                beq     3f
  65                mov     r2, #0
  661:
  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
  732:              cmp     r2, r1                  @ any more?
  74                blo     1b
  753:              mov     r0, r1                  @ no free bits
  76                ret     lr
  77ENDPROC(_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 */
  83ENTRY(_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
  96ENDPROC(_find_next_bit_le)
  97
  98#ifdef __ARMEB__
  99
 100ENTRY(_find_first_zero_bit_be)
 101                teq     r1, #0
 102                beq     3f
 103                mov     r2, #0
 1041:              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
 1112:              cmp     r2, r1                  @ any more?
 112                blo     1b
 1133:              mov     r0, r1                  @ no free bits
 114                ret     lr
 115ENDPROC(_find_first_zero_bit_be)
 116
 117ENTRY(_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
 132ENDPROC(_find_next_zero_bit_be)
 133
 134ENTRY(_find_first_bit_be)
 135                teq     r1, #0
 136                beq     3f
 137                mov     r2, #0
 1381:              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
 1452:              cmp     r2, r1                  @ any more?
 146                blo     1b
 1473:              mov     r0, r1                  @ no free bits
 148                ret     lr
 149ENDPROC(_find_first_bit_be)
 150
 151ENTRY(_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
 165ENDPROC(_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
 194