2014-04-28 09:11:34 +04:00
/ *
* Copyright ( C ) 2 0 1 3 A R M L t d .
* Copyright ( C ) 2 0 1 3 L i n a r o .
*
* This c o d e i s b a s e d o n g l i b c c o r t e x s t r i n g s w o r k o r i g i n a l l y a u t h o r e d b y L i n a r o
* and r e - l i c e n s e d u n d e r G P L v2 f o r t h e L i n u x k e r n e l . T h e o r i g i n a l c o d e c a n
* be f o u n d @
*
* http : / / bazaar. l a u n c h p a d . n e t / ~ l i n a r o - t o o l c h a i n - d e v / c o r t e x - s t r i n g s / t r u n k /
* files/ h e a d : / s r c / a a r c h64 /
*
* 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 .
*
* This p r o g r a m i s d i s t r i b u t e d i n t h e h o p e t h a t i t w i l l b e u s e f u l ,
* but W I T H O U T A N Y W A R R A N T Y ; without even the implied warranty of
* MERCHANTABILITY o r F I T N E S S F O R A P A R T I C U L A R P U R P O S E . S e e t h e
* GNU G e n e r a l P u b l i c L i c e n s e f o r m o r e d e t a i l s .
*
* You s h o u l d h a v e r e c e i v e d a c o p y 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
* along w i t h t h i s p r o g r a m . I f n o t , s e e < h t t p : / / w w w . g n u . o r g / l i c e n s e s / > .
* /
# 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 >
/ *
* determine t h e l e n g t h o f a f i x e d - s i z e s t r i n g
*
* Parameters :
* x0 - c o n s t s t r i n g p o i n t e r
* x1 - m a x i m a l s t r i n g l e n g t h
* Returns :
* x0 - t h e r e t u r n l e n g t h o f s p e c i f i c s t r i n g
* /
/* Arguments and results. */
srcin . r e q x0
len . r e q x0
limit . r e q x1
/* Locals and temporaries. */
src . r e q x2
data1 . r e q x3
data2 . r e q x4
data2 a . r e q x5
has_ n u l 1 . r e q x6
has_ n u l 2 . r e q x7
tmp1 . r e q x8
tmp2 . r e q x9
tmp3 . r e q x10
tmp4 . r e q x11
zeroones . r e q x12
pos . r e q x13
limit_ w d . r e q x14
# define R E P 8 _ 0 1 0 x01 0 1 0 1 0 1 0 1 0 1 0 1 0 1
# define R E P 8 _ 7 f 0 x7 f7 f7 f7 f7 f7 f7 f7 f
# define R E P 8 _ 8 0 0 x80 8 0 8 0 8 0 8 0 8 0 8 0 8 0
ENTRY( s t r n l e n )
cbz l i m i t , . L h i t _ l i m i t
mov z e r o o n e s , #R E P 8 _ 0 1
bic s r c , s r c i n , #15
ands t m p1 , s r c i n , #15
b. n e . L m i s a l i g n e d
/* Calculate the number of full and partial words -1. */
sub l i m i t _ w d , l i m i t , #1 / * L i m i t ! = 0 , s o n o u n d e r f l o w . * /
lsr l i m i t _ w d , l i m i t _ w d , #4 / * C o n v e r t t o Q w o r d s . * /
/ *
* NUL d e t e c t i o n w o r k s o n t h e p r i n c i p l e t h a t ( X - 1 ) & ( ~ X ) & 0 x80
* ( = > ( X - 1 ) & ~ ( X | 0 x7 f ) ) i s n o n - z e r o i f f a b y t e i s z e r o , a n d
* can b e d o n e i n p a r a l l e l a c r o s s t h e e n t i r e w o r d .
* /
/ *
* The i n n e r l o o p d e a l s w i t h t w o D w o r d s a t a t i m e . T h i s h a s a
* slightly h i g h e r s t a r t - u p c o s t , b u t w e s h o u l d w i n q u i t e q u i c k l y ,
* especially o n c o r e s w i t h a h i g h n u m b e r o f i s s u e s l o t s p e r
* cycle, a s w e g e t m u c h b e t t e r p a r a l l e l i s m o u t o f t h e o p e r a t i o n s .
* /
.Lloop :
ldp d a t a1 , d a t a2 , [ s r c ] , #16
.Lrealigned :
sub t m p1 , d a t a1 , z e r o o n e s
orr t m p2 , d a t a1 , #R E P 8 _ 7 f
sub t m p3 , d a t a2 , z e r o o n e s
orr t m p4 , d a t a2 , #R E P 8 _ 7 f
bic h a s _ n u l 1 , t m p1 , t m p2
bic h a s _ n u l 2 , t m p3 , t m p4
subs l i m i t _ w d , l i m i t _ w d , #1
orr t m p1 , h a s _ n u l 1 , h a s _ n u l 2
ccmp t m p1 , #0 , #0 , p l / * N Z C V = 0 0 0 0 * /
b. e q . L l o o p
cbz t m p1 , . L h i t _ l i m i t / * N o n u l l i n f i n a l Q w o r d . * /
/ *
* We k n o w t h e r e ' s a n u l l i n t h e f i n a l Q w o r d . T h e e a s i e s t t h i n g
* to d o n o w i s w o r k o u t t h e l e n g t h o f t h e s t r i n g a n d r e t u r n
* MIN ( l e n , l i m i t ) .
* /
sub l e n , s r c , s r c i n
cbz h a s _ n u l 1 , . L n u l _ i n _ d a t a2
CPU_ B E ( m o v d a t a2 , d a t a1 ) / * p e r p a r e d a t a t o r e - c a l c u l a t e t h e s y n d r o m e * /
sub l e n , l e n , #8
mov h a s _ n u l 2 , h a s _ n u l 1
.Lnul_in_data2 :
/ *
* For b i g - e n d i a n , c a r r y p r o p a g a t i o n ( i f t h e f i n a l b y t e i n t h e
* string i s 0 x01 ) m e a n s w e c a n n o t u s e h a s _ n u l d i r e c t l y . T h e
* easiest w a y t o g e t t h e c o r r e c t b y t e i s t o b y t e - s w a p t h e d a t a
* and c a l c u l a t e t h e s y n d r o m e a s e c o n d t i m e .
* /
CPU_ B E ( r e v d a t a2 , d a t a2 )
CPU_ B E ( s u b t m p1 , d a t a2 , z e r o o n e s )
CPU_ B E ( o r r t m p2 , d a t a2 , #R E P 8 _ 7 f )
CPU_ B E ( b i c h a s _ n u l 2 , t m p1 , t m p2 )
sub l e n , l e n , #8
rev h a s _ n u l 2 , h a s _ n u l 2
clz p o s , h a s _ n u l 2
add l e n , l e n , p o s , l s r #3 / * B i t s t o b y t e s . * /
cmp l e n , l i m i t
csel l e n , l e n , l i m i t , l s / * R e t u r n t h e l o w e r v a l u e . * /
ret
.Lmisaligned :
/ *
* Deal w i t h a p a r t i a l f i r s t w o r d .
* We' r e d o i n g t w o t h i n g s i n p a r a l l e l h e r e ;
* 1 ) Calculate t h e n u m b e r o f w o r d s ( b u t a v o i d i n g o v e r f l o w i f
* limit i s n e a r U L O N G _ M A X ) - t o d o t h i s w e n e e d t o w o r k o u t
* limit + t m p1 - 1 a s a 6 5 - b i t v a l u e b e f o r e s h i f t i n g i t ;
* 2 ) Load a n d m a s k t h e i n i t i a l d a t a w o r d s - w e f o r c e t h e b y t e s
* before t h e o n e s w e a r e i n t e r e s t e d i n t o 0 x f f - t h i s e n s u r e s
* early b y t e s w i l l n o t h i t a n y z e r o d e t e c t i o n .
* /
ldp d a t a1 , d a t a2 , [ s r c ] , #16
sub l i m i t _ w d , l i m i t , #1
and t m p3 , l i m i t _ w d , #15
lsr l i m i t _ w d , l i m i t _ w d , #4
add t m p3 , t m p3 , t m p1
add l i m i t _ w d , l i m i t _ w d , t m p3 , l s r #4
neg t m p4 , t m p1
lsl t m p4 , t m p4 , #3 / * B y t e s b e y o n d a l i g n m e n t - > b i t s . * /
mov t m p2 , #~ 0
/* Big-endian. Early bytes are at MSB. */
CPU_ B E ( l s l t m p2 , t m p2 , t m p4 ) / * S h i f t ( t m p1 & 6 3 ) . * /
/* Little-endian. Early bytes are at LSB. */
CPU_ L E ( l s r t m p2 , t m p2 , t m p4 ) / * S h i f t ( t m p1 & 6 3 ) . * /
cmp t m p1 , #8
orr d a t a1 , d a t a1 , t m p2
orr d a t a2 a , d a t a2 , t m p2
csinv d a t a1 , d a t a1 , x z r , l e
csel d a t a2 , d a t a2 , d a t a2 a , l e
b . L r e a l i g n e d
.Lhit_limit :
mov l e n , l i m i t
ret
2016-02-16 13:16:31 +03:00
ENDPIPROC( s t r n l e n )