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#include <asm/export.h> 19 .text 20 21/* 22 * Purpose : Find a 'zero' bit 23 * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit); 24 */ 25ENTRY(_find_first_zero_bit_le) 26 teq r1, #0 27 beq 3f 28 mov r2, #0 291: 30 ARM( ldrb r3, [r0, r2, lsr #3] ) 31 THUMB( lsr r3, r2, #3 ) 32 THUMB( ldrb r3, [r0, r3] ) 33 eors r3, r3, #0xff @ invert bits 34 bne .L_found @ any now set - found zero bit 35 add r2, r2, #8 @ next bit pointer 362: cmp r2, r1 @ any more? 37 blo 1b 383: mov r0, r1 @ no free bits 39 ret lr 40ENDPROC(_find_first_zero_bit_le) 41EXPORT_SYMBOL(_find_first_zero_bit_le) 42 43/* 44 * Purpose : Find next 'zero' bit 45 * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset) 46 */ 47ENTRY(_find_next_zero_bit_le) 48 teq r1, #0 49 beq 3b 50 ands ip, r2, #7 51 beq 1b @ If new byte, goto old routine 52 ARM( ldrb r3, [r0, r2, lsr #3] ) 53 THUMB( lsr r3, r2, #3 ) 54 THUMB( ldrb r3, [r0, r3] ) 55 eor r3, r3, #0xff @ now looking for a 1 bit 56 movs r3, r3, lsr ip @ shift off unused bits 57 bne .L_found 58 orr r2, r2, #7 @ if zero, then no bits here 59 add r2, r2, #1 @ align bit pointer 60 b 2b @ loop for next bit 61ENDPROC(_find_next_zero_bit_le) 62EXPORT_SYMBOL(_find_next_zero_bit_le) 63 64/* 65 * Purpose : Find a 'one' bit 66 * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit); 67 */ 68ENTRY(_find_first_bit_le) 69 teq r1, #0 70 beq 3f 71 mov r2, #0 721: 73 ARM( ldrb r3, [r0, r2, lsr #3] ) 74 THUMB( lsr r3, r2, #3 ) 75 THUMB( ldrb r3, [r0, r3] ) 76 movs r3, r3 77 bne .L_found @ any now set - found zero bit 78 add r2, r2, #8 @ next bit pointer 792: cmp r2, r1 @ any more? 80 blo 1b 813: mov r0, r1 @ no free bits 82 ret lr 83ENDPROC(_find_first_bit_le) 84EXPORT_SYMBOL(_find_first_bit_le) 85 86/* 87 * Purpose : Find next 'one' bit 88 * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset) 89 */ 90ENTRY(_find_next_bit_le) 91 teq r1, #0 92 beq 3b 93 ands ip, r2, #7 94 beq 1b @ If new byte, goto old routine 95 ARM( ldrb r3, [r0, r2, lsr #3] ) 96 THUMB( lsr r3, r2, #3 ) 97 THUMB( ldrb r3, [r0, r3] ) 98 movs r3, r3, lsr ip @ shift off unused bits 99 bne .L_found 100 orr r2, r2, #7 @ if zero, then no bits here 101 add r2, r2, #1 @ align bit pointer 102 b 2b @ loop for next bit 103ENDPROC(_find_next_bit_le) 104EXPORT_SYMBOL(_find_next_bit_le) 105 106#ifdef __ARMEB__ 107 108ENTRY(_find_first_zero_bit_be) 109 teq r1, #0 110 beq 3f 111 mov r2, #0 1121: eor r3, r2, #0x18 @ big endian byte ordering 113 ARM( ldrb r3, [r0, r3, lsr #3] ) 114 THUMB( lsr r3, #3 ) 115 THUMB( ldrb r3, [r0, r3] ) 116 eors r3, r3, #0xff @ invert bits 117 bne .L_found @ any now set - found zero bit 118 add r2, r2, #8 @ next bit pointer 1192: cmp r2, r1 @ any more? 120 blo 1b 1213: mov r0, r1 @ no free bits 122 ret lr 123ENDPROC(_find_first_zero_bit_be) 124EXPORT_SYMBOL(_find_first_zero_bit_be) 125 126ENTRY(_find_next_zero_bit_be) 127 teq r1, #0 128 beq 3b 129 ands ip, r2, #7 130 beq 1b @ If new byte, goto old routine 131 eor r3, r2, #0x18 @ big endian byte ordering 132 ARM( ldrb r3, [r0, r3, lsr #3] ) 133 THUMB( lsr r3, #3 ) 134 THUMB( ldrb r3, [r0, r3] ) 135 eor r3, r3, #0xff @ now looking for a 1 bit 136 movs r3, r3, lsr ip @ shift off unused bits 137 bne .L_found 138 orr r2, r2, #7 @ if zero, then no bits here 139 add r2, r2, #1 @ align bit pointer 140 b 2b @ loop for next bit 141ENDPROC(_find_next_zero_bit_be) 142EXPORT_SYMBOL(_find_next_zero_bit_be) 143 144ENTRY(_find_first_bit_be) 145 teq r1, #0 146 beq 3f 147 mov r2, #0 1481: eor r3, r2, #0x18 @ big endian byte ordering 149 ARM( ldrb r3, [r0, r3, lsr #3] ) 150 THUMB( lsr r3, #3 ) 151 THUMB( ldrb r3, [r0, r3] ) 152 movs r3, r3 153 bne .L_found @ any now set - found zero bit 154 add r2, r2, #8 @ next bit pointer 1552: cmp r2, r1 @ any more? 156 blo 1b 1573: mov r0, r1 @ no free bits 158 ret lr 159ENDPROC(_find_first_bit_be) 160EXPORT_SYMBOL(_find_first_bit_be) 161 162ENTRY(_find_next_bit_be) 163 teq r1, #0 164 beq 3b 165 ands ip, r2, #7 166 beq 1b @ If new byte, goto old routine 167 eor r3, r2, #0x18 @ big endian byte ordering 168 ARM( ldrb r3, [r0, r3, lsr #3] ) 169 THUMB( lsr r3, #3 ) 170 THUMB( ldrb r3, [r0, r3] ) 171 movs r3, r3, lsr ip @ shift off unused bits 172 bne .L_found 173 orr r2, r2, #7 @ if zero, then no bits here 174 add r2, r2, #1 @ align bit pointer 175 b 2b @ loop for next bit 176ENDPROC(_find_next_bit_be) 177EXPORT_SYMBOL(_find_next_bit_be) 178 179#endif 180 181/* 182 * One or more bits in the LSB of r3 are assumed to be set. 183 */ 184.L_found: 185#if __LINUX_ARM_ARCH__ >= 5 186 rsb r0, r3, #0 187 and r3, r3, r0 188 clz r3, r3 189 rsb r3, r3, #31 190 add r0, r2, r3 191#else 192 tst r3, #0x0f 193 addeq r2, r2, #4 194 movne r3, r3, lsl #4 195 tst r3, #0x30 196 addeq r2, r2, #2 197 movne r3, r3, lsl #2 198 tst r3, #0x40 199 addeq r2, r2, #1 200 mov r0, r2 201#endif 202 cmp r1, r0 @ Clamp to maxbit 203 movlo r0, r1 204 ret lr 205 206