findbit.S (4799B)
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