2005-06-23 22:01:20 -07:00
/ *
* arch/ x t e n s a / l i b / s t r n c p y _ 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 : - EFAULT i f e x c e p t i o n b e f o r e t e r m i n a t o r , N i f t h e e n t i r e
* buffer f i l l e d , e l s e s t r l e n .
*
* 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
# include < l i n u x / e r r n o . h >
/* 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
/ *
* char * _ _ s t r n c p y _ u s e r ( c h a r * d s t , c o n s t c h a r * s r c , 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
# a0 / r e t u r n a d d r e s s
# a1 / s t a c k p o i n t e r
# a2 / r e t u r n v a l u e
# a3 / s r c
# a4 / l e n
# 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
# a1 1 / d s t
# a1 2 / t m p
.align 4
.global __strncpy_user
.type _ _ strncpy_ u s e r ,@function
__strncpy_user :
entry s p , 1 6 # m i n i m a l s t a c k f r a m e
# a2 / d s t , a3 / s r c , a4 / l e n
mov a11 , a2 # l e a v e d s t i n r e t u r n v a l u e r e g i s t e r
beqz a4 , . L r e t # i f l e n i s z e r o
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 a3 , 0 , . L s r c1 m o d2 # i f o n l y 8 - b i t a l i g n e d
bbsi. l a3 , 1 , . L s r c2 m o d4 # i f o n l y 16 - b i t a l i g n e d
.Lsrcaligned : # return h e r e w h e n s r c i s w o r d - a l i g n e d
srli a12 , a4 , 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
movi a9 , 3
bnone a11 , a9 , . L a l i g n e d
j . L d s t u n a l i g n e d
.Lsrc1mod2 : # src a d d r e s s i s o d d
EX( l 8 u i , a9 , a3 , 0 , f i x u p _ l ) # g e t b y t e 0
addi a3 , a3 , 1 # a d v a n c e s r c p o i n t e r
EX( s8 i , a9 , a11 , 0 , f i x u p _ s ) # s t o r e b y t e 0
beqz a9 , . L r e t # i f b y t e 0 i s z e r o
addi a11 , a11 , 1 # a d v a n c e d s t p o i n t e r
addi a4 , a4 , - 1 # d e c r e m e n t l e n
beqz a4 , . L r e t # i f l e n i s z e r o
bbci. l a3 , 1 , . L s r c a l i g n e d # i f s r c i s n o w w o r d - a l i g n e d
.Lsrc2mod4 : # src a d d r e s s i s 2 m o d 4
EX( l 8 u i , a9 , a3 , 0 , f i x u p _ l ) # g e t b y t e 0
/* 1-cycle interlock */
EX( s8 i , a9 , a11 , 0 , f i x u p _ s ) # s t o r e b y t e 0
beqz a9 , . L r e t # i f b y t e 0 i s z e r o
addi a11 , a11 , 1 # a d v a n c e d s t p o i n t e r
addi a4 , a4 , - 1 # d e c r e m e n t l e n
beqz a4 , . L r e t # i f l e n i s z e r o
EX( l 8 u i , a9 , a3 , 1 , f i x u p _ l ) # g e t b y t e 0
addi a3 , a3 , 2 # a d v a n c e s r c p o i n t e r
EX( s8 i , a9 , a11 , 0 , f i x u p _ s ) # s t o r e b y t e 0
beqz a9 , . L r e t # i f b y t e 0 i s z e r o
addi a11 , a11 , 1 # a d v a n c e d s t p o i n t e r
addi a4 , a4 , - 1 # d e c r e m e n t l e n
bnez a4 , . L s r c a l i g n e d # i f l e n i s n o n z e r o
.Lret :
sub a2 , a11 , a2 # c o m p u t e s t r l e n
retw
/ *
* dst i s w o r d - a l i g n e d , s r c i s w o r d - a l i g n e d
* /
.align 4 # 1 mod 4 a l i g n m e n t f o r L O O P N E Z
.byte 0 # ( 0 mod 4 a l i g n m e n t f o r L B E G )
.Laligned :
# if X C H A L _ H A V E _ L O O P S
loopnez a12 , . L o o p1 d o n e
# else
beqz a12 , . L o o p1 d o n e
slli a12 , a12 , 2
add a12 , a12 , a11 # a 12 = e n d o f l a s t 4 B c h u n c k
# endif
.Loop1 :
EX( l 3 2 i , a9 , a3 , 0 , f i x u p _ l ) # g e t w o r d f r o m s r c
addi a3 , a3 , 4 # a d v a n c e s r c 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
EX( s32 i , a9 , a11 , 0 , f i x u p _ s ) # s t o r e w o r d t o d s t
bnone a9 , a8 , . L z 3 # i f b y t e 3 i s z e r o
addi a11 , a11 , 4 # a d v a n c e d s t p o i n t e r
# if ! X C H A L _ H A V E _ L O O P S
blt a11 , a12 , . L o o p1
# endif
.Loop1done :
bbci. l a4 , 1 , . L 1 0 0
# copy 2 b y t e s
EX( l 1 6 u i , a9 , a3 , 0 , f i x u p _ l )
addi a3 , a3 , 2 # a d v a n c e s r c p o i n t e r
# ifdef _ _ X T E N S A _ E B _ _
bnone a9 , a7 , . L z 0 # i f b y t e 2 i s z e r o
bnone a9 , a8 , . L z 1 # i f b y t e 3 i s z e r o
# else
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
# endif
EX( s16 i , a9 , a11 , 0 , f i x u p _ s )
addi a11 , a11 , 2 # a d v a n c e d s t p o i n t e r
.L100 :
bbci. l a4 , 0 , . L r e t
EX( l 8 u i , a9 , a3 , 0 , f i x u p _ l )
/* slot */
EX( s8 i , a9 , a11 , 0 , f i x u p _ s )
beqz a9 , . L r e t # i f b y t e i s z e r o
addi a11 , a11 , 1 - 3 # a d v a n c e d s t p t r 1 , b u t a l s o c a n c e l
# the e f f e c t o f a d d i n g 3 i n . L z 3 c o d e
/* fall thru to .Lz3 and "retw" */
.Lz3 : # byte 3 i s z e r o
addi a11 , a11 , 3 # a d v a n c e d s t p o i n t e r
sub a2 , a11 , a2 # c o m p u t e s t r l e n
retw
.Lz0 : # byte 0 i s z e r o
# ifdef _ _ X T E N S A _ E B _ _
movi a9 , 0
# endif / * _ _ X T E N S A _ E B _ _ * /
EX( s8 i , a9 , a11 , 0 , f i x u p _ s )
sub a2 , a11 , a2 # c o m p u t e s t r l e n
retw
.Lz1 : # byte 1 i s z e r o
# ifdef _ _ X T E N S A _ E B _ _
extui a9 , a9 , 1 6 , 1 6
# endif / * _ _ X T E N S A _ E B _ _ * /
EX( s16 i , a9 , a11 , 0 , f i x u p _ s )
addi a11 , a11 , 1 # a d v a n c e d s t p o i n t e r
sub a2 , a11 , a2 # c o m p u t e s t r l e n
retw
.Lz2 : # byte 2 i s z e r o
# ifdef _ _ X T E N S A _ E B _ _
extui a9 , a9 , 1 6 , 1 6
# endif / * _ _ X T E N S A _ E B _ _ * /
EX( s16 i , a9 , a11 , 0 , f i x u p _ s )
movi a9 , 0
EX( s8 i , a9 , a11 , 2 , f i x u p _ s )
addi a11 , a11 , 2 # a d v a n c e d s t p o i n t e r
sub a2 , a11 , a2 # c o m p u t e s t r l e n
retw
.align 4 # 1 mod 4 a l i g n m e n t f o r L O O P N E Z
.byte 0 # ( 0 mod 4 a l i g n m e n t f o r L B E G )
.Ldstunaligned :
/ *
* for n o w j u s t u s e b y t e c o p y l o o p
* /
# if X C H A L _ H A V E _ L O O P S
loopnez a4 , . L u n a l i g n e d e n d
# else
beqz a4 , . L u n a l i g n e d e n d
add a12 , a11 , a4 # a 12 = e n d i n g a d d r e s s
# endif / * X C H A L _ H A V E _ L O O P S * /
.Lnextbyte :
EX( l 8 u i , a9 , a3 , 0 , f i x u p _ l )
addi a3 , a3 , 1
EX( s8 i , a9 , a11 , 0 , f i x u p _ s )
beqz a9 , . L u n a l i g n e d e n d
addi a11 , a11 , 1
# if ! X C H A L _ H A V E _ L O O P S
blt a11 , a12 , . L n e x t b y t e
# endif
.Lunalignedend :
sub a2 , a11 , a2 # c o m p u t e s t r l e n
retw
.section .fixup , " ax"
.align 4
/ * For n o w , j u s t r e t u r n - E F A U L T . F u t u r e i m p l e m e n t a t i o n s m i g h t
* like t o c l e a r r e m a i n i n g k e r n e l s p a c e , l i k e t h e f i x u p
* implementation i n m e m s e t ( ) . T h u s , w e d i f f e r e n t i a t e b e t w e e n
* load/ s t o r e f i x u p s . * /
fixup_s :
fixup_l :
movi a2 , - E F A U L T
retw