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 .text 19 20/* 21 * Purpose : Find a 'zero' bit 22 * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit); 23 */ 24ENTRY(_find_first_zero_bit_le) 25 teq r1, #0 26 beq 3f 27 mov r2, #0 281: ldrb r3, [r0, r2, lsr #3] 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 mov pc, 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 ldrb r3, [r0, r2, lsr #3] 48 eor r3, r3, #0xff @ now looking for a 1 bit 49 movs r3, r3, lsr ip @ shift off unused bits 50 bne .L_found 51 orr r2, r2, #7 @ if zero, then no bits here 52 add r2, r2, #1 @ align bit pointer 53 b 2b @ loop for next bit 54ENDPROC(_find_next_zero_bit_le) 55 56/* 57 * Purpose : Find a 'one' bit 58 * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit); 59 */ 60ENTRY(_find_first_bit_le) 61 teq r1, #0 62 beq 3f 63 mov r2, #0 641: ldrb r3, [r0, r2, lsr #3] 65 movs r3, r3 66 bne .L_found @ any now set - found zero bit 67 add r2, r2, #8 @ next bit pointer 682: cmp r2, r1 @ any more? 69 blo 1b 703: mov r0, r1 @ no free bits 71 mov pc, lr 72ENDPROC(_find_first_bit_le) 73 74/* 75 * Purpose : Find next 'one' bit 76 * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset) 77 */ 78ENTRY(_find_next_bit_le) 79 teq r1, #0 80 beq 3b 81 ands ip, r2, #7 82 beq 1b @ If new byte, goto old routine 83 ldrb r3, [r0, r2, lsr #3] 84 movs r3, r3, lsr ip @ shift off unused bits 85 bne .L_found 86 orr r2, r2, #7 @ if zero, then no bits here 87 add r2, r2, #1 @ align bit pointer 88 b 2b @ loop for next bit 89ENDPROC(_find_next_bit_le) 90 91#ifdef __ARMEB__ 92 93ENTRY(_find_first_zero_bit_be) 94 teq r1, #0 95 beq 3f 96 mov r2, #0 971: eor r3, r2, #0x18 @ big endian byte ordering 98 ldrb r3, [r0, r3, lsr #3] 99 eors r3, r3, #0xff @ invert bits 100 bne .L_found @ any now set - found zero bit 101 add r2, r2, #8 @ next bit pointer 1022: cmp r2, r1 @ any more? 103 blo 1b 1043: mov r0, r1 @ no free bits 105 mov pc, lr 106ENDPROC(_find_first_zero_bit_be) 107 108ENTRY(_find_next_zero_bit_be) 109 teq r1, #0 110 beq 3b 111 ands ip, r2, #7 112 beq 1b @ If new byte, goto old routine 113 eor r3, r2, #0x18 @ big endian byte ordering 114 ldrb r3, [r0, r3, lsr #3] 115 eor r3, r3, #0xff @ now looking for a 1 bit 116 movs r3, r3, lsr ip @ shift off unused bits 117 bne .L_found 118 orr r2, r2, #7 @ if zero, then no bits here 119 add r2, r2, #1 @ align bit pointer 120 b 2b @ loop for next bit 121ENDPROC(_find_next_zero_bit_be) 122 123ENTRY(_find_first_bit_be) 124 teq r1, #0 125 beq 3f 126 mov r2, #0 1271: eor r3, r2, #0x18 @ big endian byte ordering 128 ldrb r3, [r0, r3, lsr #3] 129 movs r3, r3 130 bne .L_found @ any now set - found zero bit 131 add r2, r2, #8 @ next bit pointer 1322: cmp r2, r1 @ any more? 133 blo 1b 1343: mov r0, r1 @ no free bits 135 mov pc, lr 136ENDPROC(_find_first_bit_be) 137 138ENTRY(_find_next_bit_be) 139 teq r1, #0 140 beq 3b 141 ands ip, r2, #7 142 beq 1b @ If new byte, goto old routine 143 eor r3, r2, #0x18 @ big endian byte ordering 144 ldrb r3, [r0, r3, lsr #3] 145 movs r3, r3, lsr ip @ shift off unused bits 146 bne .L_found 147 orr r2, r2, #7 @ if zero, then no bits here 148 add r2, r2, #1 @ align bit pointer 149 b 2b @ loop for next bit 150ENDPROC(_find_next_bit_be) 151 152#endif 153 154/* 155 * One or more bits in the LSB of r3 are assumed to be set. 156 */ 157.L_found: 158#if __LINUX_ARM_ARCH__ >= 5 159 rsb r1, r3, #0 160 and r3, r3, r1 161 clz r3, r3 162 rsb r3, r3, #31 163 add r0, r2, r3 164#else 165 tst r3, #0x0f 166 addeq r2, r2, #4 167 movne r3, r3, lsl #4 168 tst r3, #0x30 169 addeq r2, r2, #2 170 movne r3, r3, lsl #2 171 tst r3, #0x40 172 addeq r2, r2, #1 173 mov r0, r2 174#endif 175 mov pc, lr 176 177