Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  *  linux/arch/arm/lib/findbit.S
0004  *
0005  *  Copyright (C) 1995-2000 Russell King
0006  *
0007  * 16th March 2001 - John Ripley <jripley@sonicblue.com>
0008  *   Fixed so that "size" is an exclusive not an inclusive quantity.
0009  *   All users of these functions expect exclusive sizes, and may
0010  *   also call with zero size.
0011  * Reworked by rmk.
0012  */
0013 #include <linux/linkage.h>
0014 #include <asm/assembler.h>
0015                 .text
0016 
0017 /*
0018  * Purpose  : Find a 'zero' bit
0019  * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
0020  */
0021 ENTRY(_find_first_zero_bit_le)
0022         teq r1, #0  
0023         beq 3f
0024         mov r2, #0
0025 1:
0026  ARM(       ldrb    r3, [r0, r2, lsr #3]    )
0027  THUMB(     lsr r3, r2, #3      )
0028  THUMB(     ldrb    r3, [r0, r3]        )
0029         eors    r3, r3, #0xff       @ invert bits
0030         bne .L_found        @ any now set - found zero bit
0031         add r2, r2, #8      @ next bit pointer
0032 2:      cmp r2, r1          @ any more?
0033         blo 1b
0034 3:      mov r0, r1          @ no free bits
0035         ret lr
0036 ENDPROC(_find_first_zero_bit_le)
0037 
0038 /*
0039  * Purpose  : Find next 'zero' bit
0040  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
0041  */
0042 ENTRY(_find_next_zero_bit_le)
0043         cmp r2, r1
0044         bhs 3b
0045         ands    ip, r2, #7
0046         beq 1b          @ If new byte, goto old routine
0047  ARM(       ldrb    r3, [r0, r2, lsr #3]    )
0048  THUMB(     lsr r3, r2, #3      )
0049  THUMB(     ldrb    r3, [r0, r3]        )
0050         eor r3, r3, #0xff       @ now looking for a 1 bit
0051         movs    r3, r3, lsr ip      @ shift off unused bits
0052         bne .L_found
0053         orr r2, r2, #7      @ if zero, then no bits here
0054         add r2, r2, #1      @ align bit pointer
0055         b   2b          @ loop for next bit
0056 ENDPROC(_find_next_zero_bit_le)
0057 
0058 /*
0059  * Purpose  : Find a 'one' bit
0060  * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
0061  */
0062 ENTRY(_find_first_bit_le)
0063         teq r1, #0  
0064         beq 3f
0065         mov r2, #0
0066 1:
0067  ARM(       ldrb    r3, [r0, r2, lsr #3]    )
0068  THUMB(     lsr r3, r2, #3      )
0069  THUMB(     ldrb    r3, [r0, r3]        )
0070         movs    r3, r3
0071         bne .L_found        @ any now set - found zero bit
0072         add r2, r2, #8      @ next bit pointer
0073 2:      cmp r2, r1          @ any more?
0074         blo 1b
0075 3:      mov r0, r1          @ no free bits
0076         ret lr
0077 ENDPROC(_find_first_bit_le)
0078 
0079 /*
0080  * Purpose  : Find next 'one' bit
0081  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
0082  */
0083 ENTRY(_find_next_bit_le)
0084         cmp r2, r1
0085         bhs 3b
0086         ands    ip, r2, #7
0087         beq 1b          @ If new byte, goto old routine
0088  ARM(       ldrb    r3, [r0, r2, lsr #3]    )
0089  THUMB(     lsr r3, r2, #3      )
0090  THUMB(     ldrb    r3, [r0, r3]        )
0091         movs    r3, r3, lsr ip      @ shift off unused bits
0092         bne .L_found
0093         orr r2, r2, #7      @ if zero, then no bits here
0094         add r2, r2, #1      @ align bit pointer
0095         b   2b          @ loop for next bit
0096 ENDPROC(_find_next_bit_le)
0097 
0098 #ifdef __ARMEB__
0099 
0100 ENTRY(_find_first_zero_bit_be)
0101         teq r1, #0
0102         beq 3f
0103         mov r2, #0
0104 1:      eor r3, r2, #0x18       @ big endian byte ordering
0105  ARM(       ldrb    r3, [r0, r3, lsr #3]    )
0106  THUMB(     lsr r3, #3          )
0107  THUMB(     ldrb    r3, [r0, r3]        )
0108         eors    r3, r3, #0xff       @ invert bits
0109         bne .L_found        @ any now set - found zero bit
0110         add r2, r2, #8      @ next bit pointer
0111 2:      cmp r2, r1          @ any more?
0112         blo 1b
0113 3:      mov r0, r1          @ no free bits
0114         ret lr
0115 ENDPROC(_find_first_zero_bit_be)
0116 
0117 ENTRY(_find_next_zero_bit_be)
0118         cmp r2, r1
0119         bhs 3b
0120         ands    ip, r2, #7
0121         beq 1b          @ If new byte, goto old routine
0122         eor r3, r2, #0x18       @ big endian byte ordering
0123  ARM(       ldrb    r3, [r0, r3, lsr #3]    )
0124  THUMB(     lsr r3, #3          )
0125  THUMB(     ldrb    r3, [r0, r3]        )
0126         eor r3, r3, #0xff       @ now looking for a 1 bit
0127         movs    r3, r3, lsr ip      @ shift off unused bits
0128         bne .L_found
0129         orr r2, r2, #7      @ if zero, then no bits here
0130         add r2, r2, #1      @ align bit pointer
0131         b   2b          @ loop for next bit
0132 ENDPROC(_find_next_zero_bit_be)
0133 
0134 ENTRY(_find_first_bit_be)
0135         teq r1, #0
0136         beq 3f
0137         mov r2, #0
0138 1:      eor r3, r2, #0x18       @ big endian byte ordering
0139  ARM(       ldrb    r3, [r0, r3, lsr #3]    )
0140  THUMB(     lsr r3, #3          )
0141  THUMB(     ldrb    r3, [r0, r3]        )
0142         movs    r3, r3
0143         bne .L_found        @ any now set - found zero bit
0144         add r2, r2, #8      @ next bit pointer
0145 2:      cmp r2, r1          @ any more?
0146         blo 1b
0147 3:      mov r0, r1          @ no free bits
0148         ret lr
0149 ENDPROC(_find_first_bit_be)
0150 
0151 ENTRY(_find_next_bit_be)
0152         cmp r2, r1
0153         bhs 3b
0154         ands    ip, r2, #7
0155         beq 1b          @ If new byte, goto old routine
0156         eor r3, r2, #0x18       @ big endian byte ordering
0157  ARM(       ldrb    r3, [r0, r3, lsr #3]    )
0158  THUMB(     lsr r3, #3          )
0159  THUMB(     ldrb    r3, [r0, r3]        )
0160         movs    r3, r3, lsr ip      @ shift off unused bits
0161         bne .L_found
0162         orr r2, r2, #7      @ if zero, then no bits here
0163         add r2, r2, #1      @ align bit pointer
0164         b   2b          @ loop for next bit
0165 ENDPROC(_find_next_bit_be)
0166 
0167 #endif
0168 
0169 /*
0170  * One or more bits in the LSB of r3 are assumed to be set.
0171  */
0172 .L_found:
0173 #if __LINUX_ARM_ARCH__ >= 5
0174         rsb r0, r3, #0
0175         and r3, r3, r0
0176         clz r3, r3
0177         rsb r3, r3, #31
0178         add r0, r2, r3
0179 #else
0180         tst r3, #0x0f
0181         addeq   r2, r2, #4
0182         movne   r3, r3, lsl #4
0183         tst r3, #0x30
0184         addeq   r2, r2, #2
0185         movne   r3, r3, lsl #2
0186         tst r3, #0x40
0187         addeq   r2, r2, #1
0188         mov r0, r2
0189 #endif
0190         cmp r1, r0          @ Clamp to maxbit
0191         movlo   r0, r1
0192         ret lr
0193