| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /* | 
					
						
							|  |  |  |  *  linux/arch/arm/lib/findbit.S | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Copyright (C) 1995-2000 Russell King | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify
 | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License version 2 as | 
					
						
							|  |  |  |  * published by the Free Software Foundation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 16th March 2001 - John Ripley <jripley@sonicblue.com>
 | 
					
						
							|  |  |  |  *   Fixed so that "size" is an exclusive not an inclusive quantity. | 
					
						
							|  |  |  |  *   All users of these functions expect exclusive sizes, and may | 
					
						
							|  |  |  |  *   also call with zero size. | 
					
						
							|  |  |  |  * Reworked by rmk. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <linux/linkage.h> | 
					
						
							|  |  |  | #include <asm/assembler.h> | 
					
						
							|  |  |  |                 .text | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * Purpose  : Find a 'zero' bit | 
					
						
							|  |  |  |  * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | ENTRY(_find_first_zero_bit_le) | 
					
						
							|  |  |  | 		teq	r1, #0	 | 
					
						
							|  |  |  | 		beq	3f | 
					
						
							|  |  |  | 		mov	r2, #0 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:32:57 +01:00
										 |  |  | 1: | 
					
						
							|  |  |  |  ARM(		ldrb	r3, [r0, r2, lsr #3]	) | 
					
						
							|  |  |  |  THUMB(		lsr	r3, r2, #3		) | 
					
						
							|  |  |  |  THUMB(		ldrb	r3, [r0, r3]		) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		eors	r3, r3, #0xff		@ invert bits
 | 
					
						
							| 
									
										
										
										
											2005-11-11 21:51:49 +00:00
										 |  |  | 		bne	.L_found		@ any now set - found zero bit
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		add	r2, r2, #8		@ next bit pointer
 | 
					
						
							|  |  |  | 2:		cmp	r2, r1			@ any more?
 | 
					
						
							|  |  |  | 		blo	1b | 
					
						
							|  |  |  | 3:		mov	r0, r1			@ no free bits
 | 
					
						
							| 
									
										
										
										
											2006-06-25 11:17:23 +01:00
										 |  |  | 		mov	pc, lr | 
					
						
							| 
									
										
										
										
											2008-08-28 11:22:32 +01:00
										 |  |  | ENDPROC(_find_first_zero_bit_le) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * Purpose  : Find next 'zero' bit | 
					
						
							|  |  |  |  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset) | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | ENTRY(_find_next_zero_bit_le) | 
					
						
							|  |  |  | 		teq	r1, #0 | 
					
						
							|  |  |  | 		beq	3b | 
					
						
							|  |  |  | 		ands	ip, r2, #7 | 
					
						
							|  |  |  | 		beq	1b			@ If new byte, goto old routine
 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:32:57 +01:00
										 |  |  |  ARM(		ldrb	r3, [r0, r2, lsr #3]	) | 
					
						
							|  |  |  |  THUMB(		lsr	r3, r2, #3		) | 
					
						
							|  |  |  |  THUMB(		ldrb	r3, [r0, r3]		) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		eor	r3, r3, #0xff		@ now looking for a 1 bit
 | 
					
						
							|  |  |  | 		movs	r3, r3, lsr ip		@ shift off unused bits
 | 
					
						
							| 
									
										
										
										
											2005-11-11 21:51:49 +00:00
										 |  |  | 		bne	.L_found | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		orr	r2, r2, #7		@ if zero, then no bits here
 | 
					
						
							|  |  |  | 		add	r2, r2, #1		@ align bit pointer
 | 
					
						
							|  |  |  | 		b	2b			@ loop for next bit
 | 
					
						
							| 
									
										
										
										
											2008-08-28 11:22:32 +01:00
										 |  |  | ENDPROC(_find_next_zero_bit_le) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * Purpose  : Find a 'one' bit | 
					
						
							|  |  |  |  * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | ENTRY(_find_first_bit_le) | 
					
						
							|  |  |  | 		teq	r1, #0	 | 
					
						
							|  |  |  | 		beq	3f | 
					
						
							|  |  |  | 		mov	r2, #0 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:32:57 +01:00
										 |  |  | 1: | 
					
						
							|  |  |  |  ARM(		ldrb	r3, [r0, r2, lsr #3]	) | 
					
						
							|  |  |  |  THUMB(		lsr	r3, r2, #3		) | 
					
						
							|  |  |  |  THUMB(		ldrb	r3, [r0, r3]		) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		movs	r3, r3 | 
					
						
							| 
									
										
										
										
											2005-11-11 21:51:49 +00:00
										 |  |  | 		bne	.L_found		@ any now set - found zero bit
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		add	r2, r2, #8		@ next bit pointer
 | 
					
						
							|  |  |  | 2:		cmp	r2, r1			@ any more?
 | 
					
						
							|  |  |  | 		blo	1b | 
					
						
							|  |  |  | 3:		mov	r0, r1			@ no free bits
 | 
					
						
							| 
									
										
										
										
											2006-06-25 11:17:23 +01:00
										 |  |  | 		mov	pc, lr | 
					
						
							| 
									
										
										
										
											2008-08-28 11:22:32 +01:00
										 |  |  | ENDPROC(_find_first_bit_le) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * Purpose  : Find next 'one' bit | 
					
						
							|  |  |  |  * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset) | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | ENTRY(_find_next_bit_le) | 
					
						
							|  |  |  | 		teq	r1, #0 | 
					
						
							|  |  |  | 		beq	3b | 
					
						
							|  |  |  | 		ands	ip, r2, #7 | 
					
						
							|  |  |  | 		beq	1b			@ If new byte, goto old routine
 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:32:57 +01:00
										 |  |  |  ARM(		ldrb	r3, [r0, r2, lsr #3]	) | 
					
						
							|  |  |  |  THUMB(		lsr	r3, r2, #3		) | 
					
						
							|  |  |  |  THUMB(		ldrb	r3, [r0, r3]		) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		movs	r3, r3, lsr ip		@ shift off unused bits
 | 
					
						
							| 
									
										
										
										
											2005-11-11 21:51:49 +00:00
										 |  |  | 		bne	.L_found | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		orr	r2, r2, #7		@ if zero, then no bits here
 | 
					
						
							|  |  |  | 		add	r2, r2, #1		@ align bit pointer
 | 
					
						
							|  |  |  | 		b	2b			@ loop for next bit
 | 
					
						
							| 
									
										
										
										
											2008-08-28 11:22:32 +01:00
										 |  |  | ENDPROC(_find_next_bit_le) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef __ARMEB__ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ENTRY(_find_first_zero_bit_be) | 
					
						
							|  |  |  | 		teq	r1, #0 | 
					
						
							|  |  |  | 		beq	3f | 
					
						
							|  |  |  | 		mov	r2, #0 | 
					
						
							|  |  |  | 1:		eor	r3, r2, #0x18		@ big endian byte ordering
 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:32:57 +01:00
										 |  |  |  ARM(		ldrb	r3, [r0, r3, lsr #3]	) | 
					
						
							|  |  |  |  THUMB(		lsr	r3, #3			) | 
					
						
							|  |  |  |  THUMB(		ldrb	r3, [r0, r3]		) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		eors	r3, r3, #0xff		@ invert bits
 | 
					
						
							| 
									
										
										
										
											2005-11-11 21:51:49 +00:00
										 |  |  | 		bne	.L_found		@ any now set - found zero bit
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		add	r2, r2, #8		@ next bit pointer
 | 
					
						
							|  |  |  | 2:		cmp	r2, r1			@ any more?
 | 
					
						
							|  |  |  | 		blo	1b | 
					
						
							|  |  |  | 3:		mov	r0, r1			@ no free bits
 | 
					
						
							| 
									
										
										
										
											2006-06-25 11:17:23 +01:00
										 |  |  | 		mov	pc, lr | 
					
						
							| 
									
										
										
										
											2008-08-28 11:22:32 +01:00
										 |  |  | ENDPROC(_find_first_zero_bit_be) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ENTRY(_find_next_zero_bit_be) | 
					
						
							|  |  |  | 		teq	r1, #0 | 
					
						
							|  |  |  | 		beq	3b | 
					
						
							|  |  |  | 		ands	ip, r2, #7 | 
					
						
							|  |  |  | 		beq	1b			@ If new byte, goto old routine
 | 
					
						
							|  |  |  | 		eor	r3, r2, #0x18		@ big endian byte ordering
 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:32:57 +01:00
										 |  |  |  ARM(		ldrb	r3, [r0, r3, lsr #3]	) | 
					
						
							|  |  |  |  THUMB(		lsr	r3, #3			) | 
					
						
							|  |  |  |  THUMB(		ldrb	r3, [r0, r3]		) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		eor	r3, r3, #0xff		@ now looking for a 1 bit
 | 
					
						
							|  |  |  | 		movs	r3, r3, lsr ip		@ shift off unused bits
 | 
					
						
							| 
									
										
										
										
											2005-11-11 21:51:49 +00:00
										 |  |  | 		bne	.L_found | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		orr	r2, r2, #7		@ if zero, then no bits here
 | 
					
						
							|  |  |  | 		add	r2, r2, #1		@ align bit pointer
 | 
					
						
							|  |  |  | 		b	2b			@ loop for next bit
 | 
					
						
							| 
									
										
										
										
											2008-08-28 11:22:32 +01:00
										 |  |  | ENDPROC(_find_next_zero_bit_be) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ENTRY(_find_first_bit_be) | 
					
						
							|  |  |  | 		teq	r1, #0 | 
					
						
							|  |  |  | 		beq	3f | 
					
						
							|  |  |  | 		mov	r2, #0 | 
					
						
							|  |  |  | 1:		eor	r3, r2, #0x18		@ big endian byte ordering
 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:32:57 +01:00
										 |  |  |  ARM(		ldrb	r3, [r0, r3, lsr #3]	) | 
					
						
							|  |  |  |  THUMB(		lsr	r3, #3			) | 
					
						
							|  |  |  |  THUMB(		ldrb	r3, [r0, r3]		) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		movs	r3, r3 | 
					
						
							| 
									
										
										
										
											2005-11-11 21:51:49 +00:00
										 |  |  | 		bne	.L_found		@ any now set - found zero bit
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		add	r2, r2, #8		@ next bit pointer
 | 
					
						
							|  |  |  | 2:		cmp	r2, r1			@ any more?
 | 
					
						
							|  |  |  | 		blo	1b | 
					
						
							|  |  |  | 3:		mov	r0, r1			@ no free bits
 | 
					
						
							| 
									
										
										
										
											2006-06-25 11:17:23 +01:00
										 |  |  | 		mov	pc, lr | 
					
						
							| 
									
										
										
										
											2008-08-28 11:22:32 +01:00
										 |  |  | ENDPROC(_find_first_bit_be) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ENTRY(_find_next_bit_be) | 
					
						
							|  |  |  | 		teq	r1, #0 | 
					
						
							|  |  |  | 		beq	3b | 
					
						
							|  |  |  | 		ands	ip, r2, #7 | 
					
						
							|  |  |  | 		beq	1b			@ If new byte, goto old routine
 | 
					
						
							|  |  |  | 		eor	r3, r2, #0x18		@ big endian byte ordering
 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:32:57 +01:00
										 |  |  |  ARM(		ldrb	r3, [r0, r3, lsr #3]	) | 
					
						
							|  |  |  |  THUMB(		lsr	r3, #3			) | 
					
						
							|  |  |  |  THUMB(		ldrb	r3, [r0, r3]		) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		movs	r3, r3, lsr ip		@ shift off unused bits
 | 
					
						
							| 
									
										
										
										
											2005-11-11 21:51:49 +00:00
										 |  |  | 		bne	.L_found | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		orr	r2, r2, #7		@ if zero, then no bits here
 | 
					
						
							|  |  |  | 		add	r2, r2, #1		@ align bit pointer
 | 
					
						
							|  |  |  | 		b	2b			@ loop for next bit
 | 
					
						
							| 
									
										
										
										
											2008-08-28 11:22:32 +01:00
										 |  |  | ENDPROC(_find_next_bit_be) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * One or more bits in the LSB of r3 are assumed to be set. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2005-11-11 21:51:49 +00:00
										 |  |  | .L_found: | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #if __LINUX_ARM_ARCH__ >= 5 | 
					
						
							| 
									
										
										
										
											2010-11-24 00:21:37 +01:00
										 |  |  | 		rsb	r0, r3, #0 | 
					
						
							|  |  |  | 		and	r3, r3, r0 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		clz	r3, r3 | 
					
						
							|  |  |  | 		rsb	r3, r3, #31 | 
					
						
							|  |  |  | 		add	r0, r2, r3 | 
					
						
							|  |  |  | #else | 
					
						
							|  |  |  | 		tst	r3, #0x0f | 
					
						
							|  |  |  | 		addeq	r2, r2, #4 | 
					
						
							|  |  |  | 		movne	r3, r3, lsl #4 | 
					
						
							|  |  |  | 		tst	r3, #0x30 | 
					
						
							|  |  |  | 		addeq	r2, r2, #2 | 
					
						
							|  |  |  | 		movne	r3, r3, lsl #2 | 
					
						
							|  |  |  | 		tst	r3, #0x40 | 
					
						
							|  |  |  | 		addeq	r2, r2, #1 | 
					
						
							|  |  |  | 		mov	r0, r2 | 
					
						
							|  |  |  | #endif | 
					
						
							| 
									
										
										
										
											2010-11-24 00:21:37 +01:00
										 |  |  | 		cmp	r1, r0			@ Clamp to maxbit
 | 
					
						
							|  |  |  | 		movlo	r0, r1 | 
					
						
							| 
									
										
										
										
											2006-06-25 11:17:23 +01:00
										 |  |  | 		mov	pc, lr | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 |