2005-04-17 02:20:36 +04:00
/ *
* linux/ a r c h / a r m / l i b / f i n d b i t . S
*
* Copyright ( C ) 1 9 9 5 - 2 0 0 0 R u s s e l l K i n g
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or modify
* it u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e v e r s i o n 2 a s
* published b y t h e F r e e S o f t w a r e F o u n d a t i o n .
*
* 1 6 th M a r c h 2 0 0 1 - J o h n R i p l e y < j r i p l e y @sonicblue.com>
* Fixed s o t h a t " s i z e " i s a n e x c l u s i v e n o t a n i n c l u s i v e q u a n t i t y .
* All u s e r s o f t h e s e f u n c t i o n s e x p e c t e x c l u s i v e s i z e s , a n d m a y
* also c a l l w i t h z e r o s i z e .
* Reworked b y r m k .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s s e m b l e r . h >
.text
/ *
* Purpose : F i n d a ' z e r o ' b i t
* Prototype : int f i n d _ f i r s t _ z e r o _ b i t ( v o i d * a d d r , u n s i g n e d i n t m a x b i t ) ;
* /
ENTRY( _ f i n d _ f i r s t _ z e r o _ b i t _ l e )
teq r1 , #0
beq 3 f
mov r2 , #0
2009-07-24 15:32:57 +04:00
1 :
ARM( l d r b r3 , [ r0 , r2 , l s r #3 ] )
THUMB( l s r r3 , r2 , #3 )
THUMB( l d r b r3 , [ r0 , r3 ] )
2005-04-17 02:20:36 +04:00
eors r3 , r3 , #0xff @ invert bits
2005-11-12 00:51:49 +03:00
bne . L _ f o u n d @ any now set - found zero bit
2005-04-17 02:20:36 +04:00
add r2 , r2 , #8 @ next bit pointer
2 : cmp r2 , r1 @ any more?
blo 1 b
3 : mov r0 , r1 @ no free bits
2006-06-25 14:17:23 +04:00
mov p c , l r
2008-08-28 14:22:32 +04:00
ENDPROC( _ f i n d _ f i r s t _ z e r o _ b i t _ l e )
2005-04-17 02:20:36 +04:00
/ *
* Purpose : F i n d n e x t ' z e r o ' b i t
* Prototype : int f i n d _ n e x t _ z e r o _ b i t ( v o i d * a d d r , u n s i g n e d i n t m a x b i t , i n t o f f s e t )
* /
ENTRY( _ f i n d _ n e x t _ z e r o _ b i t _ l e )
teq r1 , #0
beq 3 b
ands i p , r2 , #7
beq 1 b @ If new byte, goto old routine
2009-07-24 15:32:57 +04:00
ARM( l d r b r3 , [ r0 , r2 , l s r #3 ] )
THUMB( l s r r3 , r2 , #3 )
THUMB( l d r b r3 , [ r0 , r3 ] )
2005-04-17 02:20:36 +04:00
eor r3 , r3 , #0xff @ now looking for a 1 bit
movs r3 , r3 , l s r i p @ shift off unused bits
2005-11-12 00:51:49 +03:00
bne . L _ f o u n d
2005-04-17 02:20:36 +04:00
orr r2 , r2 , #7 @ if zero, then no bits here
add r2 , r2 , #1 @ align bit pointer
b 2 b @ loop for next bit
2008-08-28 14:22:32 +04:00
ENDPROC( _ f i n d _ n e x t _ z e r o _ b i t _ l e )
2005-04-17 02:20:36 +04:00
/ *
* Purpose : F i n d a ' o n e ' b i t
* Prototype : int f i n d _ f i r s t _ b i t ( c o n s t u n s i g n e d l o n g * a d d r , u n s i g n e d i n t m a x b i t ) ;
* /
ENTRY( _ f i n d _ f i r s t _ b i t _ l e )
teq r1 , #0
beq 3 f
mov r2 , #0
2009-07-24 15:32:57 +04:00
1 :
ARM( l d r b r3 , [ r0 , r2 , l s r #3 ] )
THUMB( l s r r3 , r2 , #3 )
THUMB( l d r b r3 , [ r0 , r3 ] )
2005-04-17 02:20:36 +04:00
movs r3 , r3
2005-11-12 00:51:49 +03:00
bne . L _ f o u n d @ any now set - found zero bit
2005-04-17 02:20:36 +04:00
add r2 , r2 , #8 @ next bit pointer
2 : cmp r2 , r1 @ any more?
blo 1 b
3 : mov r0 , r1 @ no free bits
2006-06-25 14:17:23 +04:00
mov p c , l r
2008-08-28 14:22:32 +04:00
ENDPROC( _ f i n d _ f i r s t _ b i t _ l e )
2005-04-17 02:20:36 +04:00
/ *
* Purpose : F i n d n e x t ' o n e ' b i t
* Prototype : int f i n d _ n e x t _ z e r o _ b i t ( v o i d * a d d r , u n s i g n e d i n t m a x b i t , i n t o f f s e t )
* /
ENTRY( _ f i n d _ n e x t _ b i t _ l e )
teq r1 , #0
beq 3 b
ands i p , r2 , #7
beq 1 b @ If new byte, goto old routine
2009-07-24 15:32:57 +04:00
ARM( l d r b r3 , [ r0 , r2 , l s r #3 ] )
THUMB( l s r r3 , r2 , #3 )
THUMB( l d r b r3 , [ r0 , r3 ] )
2005-04-17 02:20:36 +04:00
movs r3 , r3 , l s r i p @ shift off unused bits
2005-11-12 00:51:49 +03:00
bne . L _ f o u n d
2005-04-17 02:20:36 +04:00
orr r2 , r2 , #7 @ if zero, then no bits here
add r2 , r2 , #1 @ align bit pointer
b 2 b @ loop for next bit
2008-08-28 14:22:32 +04:00
ENDPROC( _ f i n d _ n e x t _ b i t _ l e )
2005-04-17 02:20:36 +04:00
# ifdef _ _ A R M E B _ _
ENTRY( _ f i n d _ f i r s t _ z e r o _ b i t _ b e )
teq r1 , #0
beq 3 f
mov r2 , #0
1 : eor r3 , r2 , #0x18 @ big endian byte ordering
2009-07-24 15:32:57 +04:00
ARM( l d r b r3 , [ r0 , r3 , l s r #3 ] )
THUMB( l s r r3 , #3 )
THUMB( l d r b r3 , [ r0 , r3 ] )
2005-04-17 02:20:36 +04:00
eors r3 , r3 , #0xff @ invert bits
2005-11-12 00:51:49 +03:00
bne . L _ f o u n d @ any now set - found zero bit
2005-04-17 02:20:36 +04:00
add r2 , r2 , #8 @ next bit pointer
2 : cmp r2 , r1 @ any more?
blo 1 b
3 : mov r0 , r1 @ no free bits
2006-06-25 14:17:23 +04:00
mov p c , l r
2008-08-28 14:22:32 +04:00
ENDPROC( _ f i n d _ f i r s t _ z e r o _ b i t _ b e )
2005-04-17 02:20:36 +04:00
ENTRY( _ f i n d _ n e x t _ z e r o _ b i t _ b e )
teq r1 , #0
beq 3 b
ands i p , r2 , #7
beq 1 b @ If new byte, goto old routine
eor r3 , r2 , #0x18 @ big endian byte ordering
2009-07-24 15:32:57 +04:00
ARM( l d r b r3 , [ r0 , r3 , l s r #3 ] )
THUMB( l s r r3 , #3 )
THUMB( l d r b r3 , [ r0 , r3 ] )
2005-04-17 02:20:36 +04:00
eor r3 , r3 , #0xff @ now looking for a 1 bit
movs r3 , r3 , l s r i p @ shift off unused bits
2005-11-12 00:51:49 +03:00
bne . L _ f o u n d
2005-04-17 02:20:36 +04:00
orr r2 , r2 , #7 @ if zero, then no bits here
add r2 , r2 , #1 @ align bit pointer
b 2 b @ loop for next bit
2008-08-28 14:22:32 +04:00
ENDPROC( _ f i n d _ n e x t _ z e r o _ b i t _ b e )
2005-04-17 02:20:36 +04:00
ENTRY( _ f i n d _ f i r s t _ b i t _ b e )
teq r1 , #0
beq 3 f
mov r2 , #0
1 : eor r3 , r2 , #0x18 @ big endian byte ordering
2009-07-24 15:32:57 +04:00
ARM( l d r b r3 , [ r0 , r3 , l s r #3 ] )
THUMB( l s r r3 , #3 )
THUMB( l d r b r3 , [ r0 , r3 ] )
2005-04-17 02:20:36 +04:00
movs r3 , r3
2005-11-12 00:51:49 +03:00
bne . L _ f o u n d @ any now set - found zero bit
2005-04-17 02:20:36 +04:00
add r2 , r2 , #8 @ next bit pointer
2 : cmp r2 , r1 @ any more?
blo 1 b
3 : mov r0 , r1 @ no free bits
2006-06-25 14:17:23 +04:00
mov p c , l r
2008-08-28 14:22:32 +04:00
ENDPROC( _ f i n d _ f i r s t _ b i t _ b e )
2005-04-17 02:20:36 +04:00
ENTRY( _ f i n d _ n e x t _ b i t _ b e )
teq r1 , #0
beq 3 b
ands i p , r2 , #7
beq 1 b @ If new byte, goto old routine
eor r3 , r2 , #0x18 @ big endian byte ordering
2009-07-24 15:32:57 +04:00
ARM( l d r b r3 , [ r0 , r3 , l s r #3 ] )
THUMB( l s r r3 , #3 )
THUMB( l d r b r3 , [ r0 , r3 ] )
2005-04-17 02:20:36 +04:00
movs r3 , r3 , l s r i p @ shift off unused bits
2005-11-12 00:51:49 +03:00
bne . L _ f o u n d
2005-04-17 02:20:36 +04:00
orr r2 , r2 , #7 @ if zero, then no bits here
add r2 , r2 , #1 @ align bit pointer
b 2 b @ loop for next bit
2008-08-28 14:22:32 +04:00
ENDPROC( _ f i n d _ n e x t _ b i t _ b e )
2005-04-17 02:20:36 +04:00
# endif
/ *
* One o r m o r e b i t s i n t h e L S B o f r3 a r e a s s u m e d t o b e s e t .
* /
2005-11-12 00:51:49 +03:00
.L_found :
2005-04-17 02:20:36 +04:00
# if _ _ L I N U X _ A R M _ A R C H _ _ > = 5
2010-11-24 02:21:37 +03:00
rsb r0 , r3 , #0
and r3 , r3 , r0
2005-04-17 02:20:36 +04:00
clz r3 , r3
rsb r3 , r3 , #31
add r0 , r2 , r3
# else
tst r3 , #0x0f
addeq r2 , r2 , #4
movne r3 , r3 , l s l #4
tst r3 , #0x30
addeq r2 , r2 , #2
movne r3 , r3 , l s l #2
tst r3 , #0x40
addeq r2 , r2 , #1
mov r0 , r2
# endif
2010-11-24 02:21:37 +03:00
cmp r1 , r0 @ Clamp to maxbit
movlo r0 , r1
2006-06-25 14:17:23 +04:00
mov p c , l r
2005-04-17 02:20:36 +04:00