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