2005-06-23 22:01:20 -07:00
/ *
* arch/ x t e n s a / l i b / s t r n l e n _ u s e r . S
*
* This f i l e i s s u b j e c t t o t h e t e r m s a n d c o n d i t i o n s o f t h e G N U G e n e r a l
* Public L i c e n s e . S e e t h e f i l e " C O P Y I N G " i n t h e m a i n d i r e c t o r y o f
* this a r c h i v e f o r m o r e d e t a i l s .
*
* Returns s t r n l e n , i n c l u d i n g t r a i l i n g z e r o t e r m i n a t o r .
* Zero i n d i c a t e s e r r o r .
*
* Copyright ( C ) 2 0 0 2 T e n s i l i c a I n c .
* /
2006-12-10 02:18:48 -08:00
# include < a s m / v a r i a n t / c o r e . h >
2005-06-23 22:01:20 -07:00
/* Load or store instructions that may cause exceptions use the EX macro. */
# define E X ( i n s n ,r e g 1 ,r e g 2 ,o f f s e t ,h a n d l e r ) \
9 : insn r e g 1 , r e g 2 , o f f s e t ; \
.section _ _ ex_ t a b l e , " a " ; \
.word 9 b, h a n d l e r ; \
.previous
/ *
* size_ t _ _ s t r n l e n _ u s e r ( c o n s t c h a r * s , s i z e _ t l e n )
* /
.text
.begin literal
.align 4
.Lmask0 :
.byte 0 xff, 0 x00 , 0 x00 , 0 x00
.Lmask1 :
.byte 0 x0 0 , 0 x f f , 0 x00 , 0 x00
.Lmask2 :
.byte 0 x0 0 , 0 x00 , 0 x f f , 0 x00
.Lmask3 :
.byte 0 x0 0 , 0 x00 , 0 x00 , 0 x f f
.end literal
# Register u s e :
# a2 / s r c
# a3 / l e n
# a4 / t m p
# a5 / m a s k 0
# a6 / m a s k 1
# a7 / m a s k 2
# a8 / m a s k 3
# a9 / t m p
# a1 0 / t m p
.align 4
.global __strnlen_user
.type _ _ strnlen_ u s e r ,@function
__strnlen_user :
entry s p , 1 6 # m i n i m a l s t a c k f r a m e
# a2 / s , a3 / l e n
addi a4 , a2 , - 4 # b e c a u s e w e o v e r i n c r e m e n t a t t h e e n d ;
# we c o m p e n s a t e w i t h l o a d o f f s e t s o f 4
l3 2 r a5 , . L m a s k 0 # m a s k f o r b y t e 0
l3 2 r a6 , . L m a s k 1 # m a s k f o r b y t e 1
l3 2 r a7 , . L m a s k 2 # m a s k f o r b y t e 2
l3 2 r a8 , . L m a s k 3 # m a s k f o r b y t e 3
bbsi. l a2 , 0 , . L 1 m o d2 # i f o n l y 8 - b i t a l i g n e d
bbsi. l a2 , 1 , . L 2 m o d4 # i f o n l y 16 - b i t a l i g n e d
/ *
* String i s w o r d - a l i g n e d .
* /
.Laligned :
srli a10 , a3 , 2 # n u m b e r o f l o o p i t e r a t i o n s w i t h 4 B p e r l o o p
# if X C H A L _ H A V E _ L O O P S
loopnez a10 , . L d o n e
# else
beqz a10 , . L d o n e
slli a10 , a10 , 2
add a10 , a10 , a4 # a 10 = e n d o f l a s t 4 B c h u n k
# endif / * X C H A L _ H A V E _ L O O P S * /
.Loop :
EX( l 3 2 i , a9 , a4 , 4 , l e n f i x u p ) # g e t n e x t w o r d o f s t r i n g
addi a4 , a4 , 4 # a d v a n c e s t r i n g p o i n t e r
bnone a9 , a5 , . L z 0 # i f b y t e 0 i s z e r o
bnone a9 , a6 , . L z 1 # i f b y t e 1 i s z e r o
bnone a9 , a7 , . L z 2 # i f b y t e 2 i s z e r o
bnone a9 , a8 , . L z 3 # i f b y t e 3 i s z e r o
# if ! X C H A L _ H A V E _ L O O P S
blt a4 , a10 , . L o o p
# endif
.Ldone :
EX( l 3 2 i , a9 , a4 , 4 , l e n f i x u p ) # l o a d 4 b y t e s f o r r e m a i n i n g c h e c k s
bbci. l a3 , 1 , . L 1 0 0
# check t w o m o r e b y t e s ( b y t e s 0 , 1 o f w o r d )
addi a4 , a4 , 2 # a d v a n c e s t r i n g p o i n t e r
bnone a9 , a5 , . L z 0 # i f b y t e 0 i s z e r o
bnone a9 , a6 , . L z 1 # i f b y t e 1 i s z e r o
.L100 :
bbci. l a3 , 0 , . L 1 0 1
# check o n e m o r e b y t e ( b y t e 2 o f w o r d )
# Actually, w e d o n ' t n e e d t o c h e c k . Z e r o o r n o n z e r o , w e ' l l a d d o n e .
# Do n o t a d d a n e x t r a o n e f o r t h e N U L L t e r m i n a t o r s i n c e w e h a v e
# exhausted t h e o r i g i n a l l e n p a r a m e t e r .
addi a4 , a4 , 1 # a d v a n c e s t r i n g p o i n t e r
.L101 :
sub a2 , a4 , a2 # c o m p u t e l e n g t h
retw
# NOTE t h a t i n s e v e r a l p l a c e s b e l o w , w e p o i n t t o t h e b y t e j u s t a f t e r
# the z e r o b y t e i n o r d e r t o i n c l u d e t h e N U L L t e r m i n a t o r i n t h e c o u n t .
.Lz3 : # byte 3 i s z e r o
addi a4 , a4 , 3 # p o i n t t o z e r o b y t e
.Lz0 : # byte 0 i s z e r o
addi a4 , a4 , 1 # p o i n t j u s t b e y o n d z e r o b y t e
sub a2 , a4 , a2 # s u b t r a c t t o g e t l e n g t h
retw
.Lz1 : # byte 1 i s z e r o
addi a4 , a4 , 1 + 1 # p o i n t j u s t b e y o n d z e r o b y t e
sub a2 , a4 , a2 # s u b t r a c t t o g e t l e n g t h
retw
.Lz2 : # byte 2 i s z e r o
addi a4 , a4 , 2 + 1 # p o i n t j u s t b e y o n d z e r o b y t e
sub a2 , a4 , a2 # s u b t r a c t t o g e t l e n g t h
retw
.L1mod2 : # address i s o d d
EX( l 8 u i , a9 , a4 , 4 , l e n f i x u p ) # g e t b y t e 0
addi a4 , a4 , 1 # a d v a n c e s t r i n g p o i n t e r
beqz a9 , . L z 3 # i f b y t e 0 i s z e r o
bbci. l a4 , 1 , . L a l i g n e d # i f s t r i n g p o i n t e r i s n o w w o r d - a l i g n e d
.L2mod4 : # address i s 2 m o d 4
addi a4 , a4 , 2 # a d v a n c e p t r f o r a l i g n e d a c c e s s
EX( l 3 2 i , a9 , a4 , 0 , l e n f i x u p ) # g e t w o r d w i t h f i r s t t w o b y t e s o f s t r i n g
bnone a9 , a7 , . L z 2 # i f b y t e 2 ( o f w o r d , n o t s t r i n g ) i s z e r o
bany a9 , a8 , . L a l i g n e d # i f b y t e 3 ( o f w o r d , n o t s t r i n g ) i s n o n z e r o
# byte 3 i s z e r o
addi a4 , a4 , 3 + 1 # p o i n t j u s t b e y o n d z e r o b y t e
sub a2 , a4 , a2 # s u b t r a c t t o g e t l e n g t h
retw
.section .fixup , " ax"
.align 4
lenfixup :
movi a2 , 0
retw