2005-04-16 15:20:36 -07:00
/ *
* 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 P u b l i c
* License. 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 t h i s a r c h i v e
* for m o r e d e t a i l s .
*
* Unified i m p l e m e n t a t i o n o f m e m c p y , m e m m o v e a n d t h e _ _ c o p y _ u s e r b a c k e n d .
*
* Copyright ( C ) 1 9 9 8 , 9 9 , 2 0 0 0 , 0 1 , 2 0 0 2 R a l f B a e c h l e ( r a l f @gnu.org)
* Copyright ( C ) 1 9 9 9 , 2 0 0 0 , 0 1 , 2 0 0 2 S i l i c o n G r a p h i c s , I n c .
* Copyright ( C ) 2 0 0 2 B r o a d c o m , I n c .
* memcpy/ c o p y _ u s e r a u t h o r : M a r k V a n d e v o o r d e
2007-10-23 12:43:25 +01:00
* Copyright ( C ) 2 0 0 7 M a c i e j W . R o z y c k i
2005-04-16 15:20:36 -07:00
*
* Mnemonic n a m e s f o r a r g u m e n t s t o m e m c p y / _ _ c o p y _ u s e r
* /
2005-10-20 22:55:26 +01:00
/ *
* Hack t o r e s o l v e l o n g s t a n d i n g p r e f e t c h i s s u e
*
* Prefetching m a y b e f a t a l o n s o m e s y s t e m s i f w e ' r e p r e f e t c h i n g b e y o n d t h e
* end o f m e m o r y o n s o m e s y s t e m s . I t ' s a l s o a s e r i o u s l y b a d i d e a o n n o n
* dma- c o h e r e n t s y s t e m s .
* /
2009-01-28 17:48:40 +00:00
# ifdef C O N F I G _ D M A _ N O N C O H E R E N T
2005-10-20 22:55:26 +01:00
# undef C O N F I G _ C P U _ H A S _ P R E F E T C H
# endif
# ifdef C O N F I G _ M I P S _ M A L T A
# undef C O N F I G _ C P U _ H A S _ P R E F E T C H
# endif
2005-04-16 15:20:36 -07:00
# include < a s m / a s m . h >
2005-09-09 22:32:31 +02:00
# include < a s m / a s m - o f f s e t s . h >
2005-04-16 15:20:36 -07:00
# include < a s m / r e g d e f . h >
# define d s t a0
# define s r c a1
# define l e n a2
/ *
* Spec
*
* memcpy c o p i e s l e n b y t e s f r o m s r c t o d s t a n d s e t s v0 t o d s t .
* It a s s u m e s t h a t
* - src a n d d s t d o n ' t o v e r l a p
* - src i s r e a d a b l e
* - dst i s w r i t a b l e
* memcpy u s e s t h e s t a n d a r d c a l l i n g c o n v e n t i o n
*
* _ _ copy_ u s e r c o p i e s u p t o l e n b y t e s f r o m s r c t o d s t a n d s e t s a2 ( l e n ) t o
* the n u m b e r o f u n c o p i e d b y t e s d u e t o a n e x c e p t i o n c a u s e d b y a r e a d o r w r i t e .
* _ _ copy_ u s e r a s s u m e s t h a t s r c a n d d s t d o n ' t o v e r l a p , a n d t h a t t h e c a l l i s
* implementing o n e o f t h e f o l l o w i n g :
* copy_ t o _ u s e r
* - src i s r e a d a b l e ( n o e x c e p t i o n s w h e n r e a d i n g s r c )
* copy_ f r o m _ u s e r
* - dst i s w r i t a b l e ( n o e x c e p t i o n s w h e n w r i t i n g d s t )
* _ _ copy_ u s e r u s e s a n o n - s t a n d a r d c a l l i n g c o n v e n t i o n ; see
* include/ a s m - m i p s / u a c c e s s . h
*
* When a n e x c e p t i o n h a p p e n s o n a l o a d , t h e h a n d l e r m u s t
# ensure t h a t a l l o f t h e d e s t i n a t i o n b u f f e r i s o v e r w r i t t e n t o p r e v e n t
* leaking i n f o r m a t i o n t o u s e r m o d e p r o g r a m s .
* /
/ *
* Implementation
* /
/ *
* The e x c e p t i o n h a n d l e r f o r l o a d s r e q u i r e s t h a t :
* 1 - AT c o n t a i n t h e a d d r e s s o f t h e b y t e j u s t p a s t t h e e n d o f t h e s o u r c e
* of t h e c o p y ,
* 2 - src_ e n t r y < = s r c < A T , a n d
* 3 - ( dst - s r c ) = = ( d s t _ e n t r y - s r c _ e n t r y ) ,
* The _ e n t r y s u f f i x d e n o t e s v a l u e s w h e n _ _ c o p y _ u s e r w a s c a l l e d .
*
* ( 1 ) is s e t u p u p b y u a c c e s s . h a n d m a i n t a i n e d b y n o t w r i t i n g A T i n c o p y _ u s e r
* ( 2 ) is m e t b y i n c r e m e n t i n g s r c b y t h e n u m b e r o f b y t e s c o p i e d
* ( 3 ) is m e t b y n o t d o i n g l o a d s b e t w e e n a p a i r o f i n c r e m e n t s o f d s t a n d s r c
*
* The e x c e p t i o n h a n d l e r s f o r s t o r e s a d j u s t l e n ( i f n e c e s s a r y ) a n d r e t u r n .
* These h a n d l e r s d o n o t n e e d t o o v e r w r i t e a n y d a t a .
*
* For _ _ r m e m c p y a n d m e m m o v e a n e x c e p t i o n i s a l w a y s a k e r n e l b u g , t h e r e f o r e
* they' r e n o t p r o t e c t e d .
* /
# define E X C ( i n s t _ r e g ,a d d r ,h a n d l e r ) \
9 : inst_ r e g , a d d r ; \
.section _ _ ex_ t a b l e ," a " ; \
PTR 9 b , h a n d l e r ; \
.previous
/ *
* Only o n t h e 6 4 - b i t k e r n e l w e c a n m a d e u s e o f 6 4 - b i t r e g i s t e r s .
* /
2005-09-03 15:56:16 -07:00
# ifdef C O N F I G _ 6 4 B I T
2005-04-16 15:20:36 -07:00
# define U S E _ D O U B L E
# endif
# ifdef U S E _ D O U B L E
# define L O A D l d
# define L O A D L l d l
# define L O A D R l d r
# define S T O R E L s d l
# define S T O R E R s d r
# define S T O R E s d
# define A D D d a d d u
# define S U B d s u b u
# define S R L d s r l
# define S R A d s r a
# define S L L d s l l
# define S L L V d s l l v
# define S R L V d s r l v
# define N B Y T E S 8
# define L O G _ N B Y T E S 3
2005-09-03 15:56:17 -07:00
/ *
2005-04-16 15:20:36 -07:00
* As w e a r e s h a r i n g c o d e b a s e w i t h t h e m i p s32 t r e e ( w h i c h u s e t h e o 3 2 A B I
* register d e f i n i t i o n s ) . W e n e e d t o r e d e f i n e t h e r e g i s t e r d e f i n i t i o n s f r o m
* the n 6 4 A B I r e g i s t e r n a m i n g t o t h e o 3 2 A B I r e g i s t e r n a m i n g .
* /
# undef t 0
# undef t 1
# undef t 2
# undef t 3
# define t 0 $ 8
# define t 1 $ 9
# define t 2 $ 1 0
# define t 3 $ 1 1
# define t 4 $ 1 2
# define t 5 $ 1 3
# define t 6 $ 1 4
# define t 7 $ 1 5
2005-09-03 15:56:17 -07:00
2005-04-16 15:20:36 -07:00
# else
# define L O A D l w
# define L O A D L l w l
# define L O A D R l w r
# define S T O R E L s w l
# define S T O R E R s w r
# define S T O R E s w
# define A D D a d d u
# define S U B s u b u
# define S R L s r l
# define S L L s l l
# define S R A s r a
# define S L L V s l l v
# define S R L V s r l v
# define N B Y T E S 4
# define L O G _ N B Y T E S 2
# endif / * U S E _ D O U B L E * /
# ifdef C O N F I G _ C P U _ L I T T L E _ E N D I A N
# define L D F I R S T L O A D R
2013-01-22 12:59:30 +01:00
# define L D R E S T L O A D L
2005-04-16 15:20:36 -07:00
# define S T F I R S T S T O R E R
2013-01-22 12:59:30 +01:00
# define S T R E S T S T O R E L
2005-04-16 15:20:36 -07:00
# define S H I F T _ D I S C A R D S L L V
# else
# define L D F I R S T L O A D L
2013-01-22 12:59:30 +01:00
# define L D R E S T L O A D R
2005-04-16 15:20:36 -07:00
# define S T F I R S T S T O R E L
2013-01-22 12:59:30 +01:00
# define S T R E S T S T O R E R
2005-04-16 15:20:36 -07:00
# define S H I F T _ D I S C A R D S R L V
# endif
# define F I R S T ( u n i t ) ( ( u n i t ) * N B Y T E S )
# define R E S T ( u n i t ) ( F I R S T ( u n i t ) + N B Y T E S - 1 )
# define U N I T ( u n i t ) F I R S T ( u n i t )
# define A D D R M A S K ( N B Y T E S - 1 )
.text
.set noreorder
2007-10-23 12:43:25 +01:00
# ifndef C O N F I G _ C P U _ D A D D I _ W O R K A R O U N D S
2005-04-16 15:20:36 -07:00
.set noat
2007-10-23 12:43:25 +01:00
# else
.set at=v1
# endif
2005-04-16 15:20:36 -07:00
2012-06-06 23:00:31 +01:00
/ *
* t6 i s u s e d a s a f l a g t o n o t e i n a t o m i c m o d e .
* /
LEAF( _ _ c o p y _ u s e r _ i n a t o m i c )
b _ _ c o p y _ u s e r _ c o m m o n
li t 6 , 1
END( _ _ c o p y _ u s e r _ i n a t o m i c )
2005-04-16 15:20:36 -07:00
/ *
* A c o m b i n e d m e m c p y / _ _ c o p y _ u s e r
* _ _ copy_ u s e r s e t s l e n t o 0 f o r s u c c e s s ; else to an upper bound of
* the n u m b e r o f u n c o p i e d b y t e s .
* memcpy s e t s v0 t o d s t .
* /
.align 5
LEAF( m e m c p y ) / * a0 =dst a1 =src a2 =len * /
move v0 , d s t / * r e t u r n v a l u e * /
2008-01-29 10:14:59 +00:00
.L__memcpy :
2005-04-16 15:20:36 -07:00
FEXPORT( _ _ c o p y _ u s e r )
2012-06-06 23:00:31 +01:00
li t 6 , 0 / * n o t i n a t o m i c * /
__copy_user_common :
2005-04-16 15:20:36 -07:00
/ *
* Note : dst & s r c m a y b e u n a l i g n e d , l e n m a y b e 0
* Temps
* /
# define r e m t 8
2007-11-25 11:47:56 +01:00
R1 0 K C B A R R I E R ( 0 ( r a ) )
2005-04-16 15:20:36 -07:00
/ *
* The " i s s u e b r e a k " s b e l o w a r e v e r y a p p r o x i m a t e .
* Issue d e l a y s f o r d c a c h e f i l l s w i l l p e r t u r b t h e s c h e d u l e , a s w i l l
* load q u e u e f u l l r e p l a y t r a p s , e t c .
*
* If l e n < N B Y T E S u s e b y t e o p e r a t i o n s .
* /
PREF( 0 , 0 ( s r c ) )
PREF( 1 , 0 ( d s t ) )
sltu t 2 , l e n , N B Y T E S
and t 1 , d s t , A D D R M A S K
PREF( 0 , 1 * 3 2 ( s r c ) )
PREF( 1 , 1 * 3 2 ( d s t ) )
2008-01-29 10:14:59 +00:00
bnez t 2 , . L c o p y _ b y t e s _ c h e c k l e n
2005-04-16 15:20:36 -07:00
and t 0 , s r c , A D D R M A S K
PREF( 0 , 2 * 3 2 ( s r c ) )
PREF( 1 , 2 * 3 2 ( d s t ) )
2008-01-29 10:14:59 +00:00
bnez t 1 , . L d s t _ u n a l i g n e d
2005-04-16 15:20:36 -07:00
nop
2008-01-29 10:14:59 +00:00
bnez t 0 , . L s r c _ u n a l i g n e d _ d s t _ a l i g n e d
2005-04-16 15:20:36 -07:00
/ *
* use d e l a y s l o t f o r f a l l - t h r o u g h
* src a n d d s t a r e a l i g n e d ; need to compute rem
* /
2008-01-29 10:14:59 +00:00
.Lboth_aligned :
2013-01-22 12:59:30 +01:00
SRL t 0 , l e n , L O G _ N B Y T E S + 3 # + 3 f o r 8 u n i t s / i t e r
2008-01-29 10:14:59 +00:00
beqz t 0 , . L c l e a n u p _ b o t h _ a l i g n e d # l e n < 8 * N B Y T E S
2005-04-16 15:20:36 -07:00
and r e m , l e n , ( 8 * N B Y T E S - 1 ) # r e m = l e n % ( 8 * N B Y T E S )
PREF( 0 , 3 * 3 2 ( s r c ) )
PREF( 1 , 3 * 3 2 ( d s t ) )
.align 4
1 :
2007-11-25 11:47:56 +01:00
R1 0 K C B A R R I E R ( 0 ( r a ) )
2008-01-29 10:14:59 +00:00
EXC( L O A D t 0 , U N I T ( 0 ) ( s r c ) , . L l _ e x c )
EXC( L O A D t 1 , U N I T ( 1 ) ( s r c ) , . L l _ e x c _ c o p y )
EXC( L O A D t 2 , U N I T ( 2 ) ( s r c ) , . L l _ e x c _ c o p y )
EXC( L O A D t 3 , U N I T ( 3 ) ( s r c ) , . L l _ e x c _ c o p y )
2005-04-16 15:20:36 -07:00
SUB l e n , l e n , 8 * N B Y T E S
2008-01-29 10:14:59 +00:00
EXC( L O A D t 4 , U N I T ( 4 ) ( s r c ) , . L l _ e x c _ c o p y )
EXC( L O A D t 7 , U N I T ( 5 ) ( s r c ) , . L l _ e x c _ c o p y )
EXC( S T O R E t 0 , U N I T ( 0 ) ( d s t ) , . L s _ e x c _ p8 u )
EXC( S T O R E t 1 , U N I T ( 1 ) ( d s t ) , . L s _ e x c _ p7 u )
EXC( L O A D t 0 , U N I T ( 6 ) ( s r c ) , . L l _ e x c _ c o p y )
EXC( L O A D t 1 , U N I T ( 7 ) ( s r c ) , . L l _ e x c _ c o p y )
2005-04-16 15:20:36 -07:00
ADD s r c , s r c , 8 * N B Y T E S
ADD d s t , d s t , 8 * N B Y T E S
2008-01-29 10:14:59 +00:00
EXC( S T O R E t 2 , U N I T ( - 6 ) ( d s t ) , . L s _ e x c _ p6 u )
EXC( S T O R E t 3 , U N I T ( - 5 ) ( d s t ) , . L s _ e x c _ p5 u )
EXC( S T O R E t 4 , U N I T ( - 4 ) ( d s t ) , . L s _ e x c _ p4 u )
EXC( S T O R E t 7 , U N I T ( - 3 ) ( d s t ) , . L s _ e x c _ p3 u )
EXC( S T O R E t 0 , U N I T ( - 2 ) ( d s t ) , . L s _ e x c _ p2 u )
EXC( S T O R E t 1 , U N I T ( - 1 ) ( d s t ) , . L s _ e x c _ p1 u )
2005-04-16 15:20:36 -07:00
PREF( 0 , 8 * 3 2 ( s r c ) )
PREF( 1 , 8 * 3 2 ( d s t ) )
bne l e n , r e m , 1 b
nop
/ *
* len = = r e m = = t h e n u m b e r o f b y t e s l e f t t o c o p y < 8 * N B Y T E S
* /
2008-01-29 10:14:59 +00:00
.Lcleanup_both_aligned :
beqz l e n , . L d o n e
2005-04-16 15:20:36 -07:00
sltu t 0 , l e n , 4 * N B Y T E S
2008-01-29 10:14:59 +00:00
bnez t 0 , . L l e s s _ t h a n _ 4 u n i t s
2005-04-16 15:20:36 -07:00
and r e m , l e n , ( N B Y T E S - 1 ) # r e m = l e n % N B Y T E S
/ *
* len > = 4 * N B Y T E S
* /
2008-01-29 10:14:59 +00:00
EXC( L O A D t 0 , U N I T ( 0 ) ( s r c ) , . L l _ e x c )
EXC( L O A D t 1 , U N I T ( 1 ) ( s r c ) , . L l _ e x c _ c o p y )
EXC( L O A D t 2 , U N I T ( 2 ) ( s r c ) , . L l _ e x c _ c o p y )
EXC( L O A D t 3 , U N I T ( 3 ) ( s r c ) , . L l _ e x c _ c o p y )
2005-04-16 15:20:36 -07:00
SUB l e n , l e n , 4 * N B Y T E S
ADD s r c , s r c , 4 * N B Y T E S
2007-11-25 11:47:56 +01:00
R1 0 K C B A R R I E R ( 0 ( r a ) )
2008-01-29 10:14:59 +00:00
EXC( S T O R E t 0 , U N I T ( 0 ) ( d s t ) , . L s _ e x c _ p4 u )
EXC( S T O R E t 1 , U N I T ( 1 ) ( d s t ) , . L s _ e x c _ p3 u )
EXC( S T O R E t 2 , U N I T ( 2 ) ( d s t ) , . L s _ e x c _ p2 u )
EXC( S T O R E t 3 , U N I T ( 3 ) ( d s t ) , . L s _ e x c _ p1 u )
2007-10-23 12:43:25 +01:00
.set reorder /* DADDI_WAR */
ADD d s t , d s t , 4 * N B Y T E S
2008-01-29 10:14:59 +00:00
beqz l e n , . L d o n e
2007-10-23 12:43:25 +01:00
.set noreorder
2008-01-29 10:14:59 +00:00
.Lless_than_4units :
2005-04-16 15:20:36 -07:00
/ *
* rem = l e n % N B Y T E S
* /
2008-01-29 10:14:59 +00:00
beq r e m , l e n , . L c o p y _ b y t e s
2005-04-16 15:20:36 -07:00
nop
1 :
2007-11-25 11:47:56 +01:00
R1 0 K C B A R R I E R ( 0 ( r a ) )
2008-01-29 10:14:59 +00:00
EXC( L O A D t 0 , 0 ( s r c ) , . L l _ e x c )
2005-04-16 15:20:36 -07:00
ADD s r c , s r c , N B Y T E S
SUB l e n , l e n , N B Y T E S
2008-01-29 10:14:59 +00:00
EXC( S T O R E t 0 , 0 ( d s t ) , . L s _ e x c _ p1 u )
2007-10-23 12:43:25 +01:00
.set reorder /* DADDI_WAR */
ADD d s t , d s t , N B Y T E S
2005-04-16 15:20:36 -07:00
bne r e m , l e n , 1 b
2007-10-23 12:43:25 +01:00
.set noreorder
2005-04-16 15:20:36 -07:00
/ *
* src a n d d s t a r e a l i g n e d , n e e d t o c o p y r e m b y t e s ( r e m < N B Y T E S )
* A l o o p w o u l d d o o n l y a b y t e a t a t i m e w i t h p o s s i b l e b r a n c h
2013-01-22 12:59:30 +01:00
* mispredicts. C a n ' t d o a n e x p l i c i t L O A D d s t ,m a s k ,o r ,S T O R E
2005-04-16 15:20:36 -07:00
* because c a n ' t a s s u m e r e a d - a c c e s s t o d s t . I n s t e a d , u s e
* STREST d s t , w h i c h d o e s n ' t r e q u i r e r e a d a c c e s s t o d s t .
*
* This c o d e s h o u l d p e r f o r m b e t t e r t h a n a s i m p l e l o o p o n m o d e r n ,
* wide- i s s u e m i p s p r o c e s s o r s b e c a u s e t h e c o d e h a s f e w e r b r a n c h e s a n d
* more i n s t r u c t i o n - l e v e l p a r a l l e l i s m .
* /
# define b i t s t 2
2008-01-29 10:14:59 +00:00
beqz l e n , . L d o n e
2005-04-16 15:20:36 -07:00
ADD t 1 , d s t , l e n # t 1 i s j u s t p a s t l a s t b y t e o f d s t
li b i t s , 8 * N B Y T E S
SLL r e m , l e n , 3 # r e m = n u m b e r o f b i t s t o k e e p
2008-01-29 10:14:59 +00:00
EXC( L O A D t 0 , 0 ( s r c ) , . L l _ e x c )
2013-01-22 12:59:30 +01:00
SUB b i t s , b i t s , r e m # b i t s = n u m b e r o f b i t s t o d i s c a r d
2005-04-16 15:20:36 -07:00
SHIFT_ D I S C A R D t 0 , t 0 , b i t s
2008-01-29 10:14:59 +00:00
EXC( S T R E S T t 0 , - 1 ( t 1 ) , . L s _ e x c )
2005-04-16 15:20:36 -07:00
jr r a
move l e n , z e r o
2008-01-29 10:14:59 +00:00
.Ldst_unaligned :
2005-04-16 15:20:36 -07:00
/ *
* dst i s u n a l i g n e d
* t0 = s r c & A D D R M A S K
* t1 = d s t & A D D R M A S K ; T1 > 0
* len > = N B Y T E S
*
* Copy e n o u g h b y t e s t o a l i g n d s t
* Set m a t c h = ( s r c a n d d s t h a v e s a m e a l i g n m e n t )
* /
# define m a t c h r e m
2013-01-22 12:59:30 +01:00
EXC( L D F I R S T t 3 , F I R S T ( 0 ) ( s r c ) , . L l _ e x c )
2005-04-16 15:20:36 -07:00
ADD t 2 , z e r o , N B Y T E S
2008-01-29 10:14:59 +00:00
EXC( L D R E S T t 3 , R E S T ( 0 ) ( s r c ) , . L l _ e x c _ c o p y )
2005-04-16 15:20:36 -07:00
SUB t 2 , t 2 , t 1 # t 2 = n u m b e r o f b y t e s c o p i e d
xor m a t c h , t 0 , t 1
2007-11-25 11:47:56 +01:00
R1 0 K C B A R R I E R ( 0 ( r a ) )
2008-01-29 10:14:59 +00:00
EXC( S T F I R S T t 3 , F I R S T ( 0 ) ( d s t ) , . L s _ e x c )
beq l e n , t 2 , . L d o n e
2005-04-16 15:20:36 -07:00
SUB l e n , l e n , t 2
ADD d s t , d s t , t 2
2008-01-29 10:14:59 +00:00
beqz m a t c h , . L b o t h _ a l i g n e d
2005-04-16 15:20:36 -07:00
ADD s r c , s r c , t 2
2008-01-29 10:14:59 +00:00
.Lsrc_unaligned_dst_aligned :
2013-01-22 12:59:30 +01:00
SRL t 0 , l e n , L O G _ N B Y T E S + 2 # + 2 f o r 4 u n i t s / i t e r
2005-04-16 15:20:36 -07:00
PREF( 0 , 3 * 3 2 ( s r c ) )
2008-01-29 10:14:59 +00:00
beqz t 0 , . L c l e a n u p _ s r c _ u n a l i g n e d
2013-01-22 12:59:30 +01:00
and r e m , l e n , ( 4 * N B Y T E S - 1 ) # r e m = l e n % 4 * N B Y T E S
2005-04-16 15:20:36 -07:00
PREF( 1 , 3 * 3 2 ( d s t ) )
1 :
/ *
* Avoid c o n s e c u t i v e L D * ' s t o t h e s a m e r e g i s t e r s i n c e s o m e m i p s
* implementations c a n ' t i s s u e t h e m i n t h e s a m e c y c l e .
* It' s O K t o l o a d F I R S T ( N + 1 ) b e f o r e R E S T ( N ) b e c a u s e t h e t w o a d d r e s s e s
* are t o t h e s a m e u n i t ( u n l e s s s r c i s a l i g n e d , b u t i t ' s n o t ) .
* /
2007-11-25 11:47:56 +01:00
R1 0 K C B A R R I E R ( 0 ( r a ) )
2013-01-22 12:59:30 +01:00
EXC( L D F I R S T t 0 , F I R S T ( 0 ) ( s r c ) , . L l _ e x c )
EXC( L D F I R S T t 1 , F I R S T ( 1 ) ( s r c ) , . L l _ e x c _ c o p y )
SUB l e n , l e n , 4 * N B Y T E S
2008-01-29 10:14:59 +00:00
EXC( L D R E S T t 0 , R E S T ( 0 ) ( s r c ) , . L l _ e x c _ c o p y )
EXC( L D R E S T t 1 , R E S T ( 1 ) ( s r c ) , . L l _ e x c _ c o p y )
2013-01-22 12:59:30 +01:00
EXC( L D F I R S T t 2 , F I R S T ( 2 ) ( s r c ) , . L l _ e x c _ c o p y )
EXC( L D F I R S T t 3 , F I R S T ( 3 ) ( s r c ) , . L l _ e x c _ c o p y )
2008-01-29 10:14:59 +00:00
EXC( L D R E S T t 2 , R E S T ( 2 ) ( s r c ) , . L l _ e x c _ c o p y )
EXC( L D R E S T t 3 , R E S T ( 3 ) ( s r c ) , . L l _ e x c _ c o p y )
2005-04-16 15:20:36 -07:00
PREF( 0 , 9 * 3 2 ( s r c ) ) # 0 i s P R E F _ L O A D ( n o t s t r e a m e d )
ADD s r c , s r c , 4 * N B Y T E S
# ifdef C O N F I G _ C P U _ S B 1
nop # i m p r o v e s s l o t t i n g
# endif
2008-01-29 10:14:59 +00:00
EXC( S T O R E t 0 , U N I T ( 0 ) ( d s t ) , . L s _ e x c _ p4 u )
EXC( S T O R E t 1 , U N I T ( 1 ) ( d s t ) , . L s _ e x c _ p3 u )
EXC( S T O R E t 2 , U N I T ( 2 ) ( d s t ) , . L s _ e x c _ p2 u )
EXC( S T O R E t 3 , U N I T ( 3 ) ( d s t ) , . L s _ e x c _ p1 u )
2013-01-22 12:59:30 +01:00
PREF( 1 , 9 * 3 2 ( d s t ) ) # 1 i s P R E F _ S T O R E ( n o t s t r e a m e d )
2007-10-23 12:43:25 +01:00
.set reorder /* DADDI_WAR */
ADD d s t , d s t , 4 * N B Y T E S
2005-04-16 15:20:36 -07:00
bne l e n , r e m , 1 b
2007-10-23 12:43:25 +01:00
.set noreorder
2005-04-16 15:20:36 -07:00
2008-01-29 10:14:59 +00:00
.Lcleanup_src_unaligned :
beqz l e n , . L d o n e
2005-04-16 15:20:36 -07:00
and r e m , l e n , N B Y T E S - 1 # r e m = l e n % N B Y T E S
2008-01-29 10:14:59 +00:00
beq r e m , l e n , . L c o p y _ b y t e s
2005-04-16 15:20:36 -07:00
nop
1 :
2007-11-25 11:47:56 +01:00
R1 0 K C B A R R I E R ( 0 ( r a ) )
2008-01-29 10:14:59 +00:00
EXC( L D F I R S T t 0 , F I R S T ( 0 ) ( s r c ) , . L l _ e x c )
EXC( L D R E S T t 0 , R E S T ( 0 ) ( s r c ) , . L l _ e x c _ c o p y )
2005-04-16 15:20:36 -07:00
ADD s r c , s r c , N B Y T E S
SUB l e n , l e n , N B Y T E S
2008-01-29 10:14:59 +00:00
EXC( S T O R E t 0 , 0 ( d s t ) , . L s _ e x c _ p1 u )
2007-10-23 12:43:25 +01:00
.set reorder /* DADDI_WAR */
ADD d s t , d s t , N B Y T E S
2005-04-16 15:20:36 -07:00
bne l e n , r e m , 1 b
2007-10-23 12:43:25 +01:00
.set noreorder
2005-04-16 15:20:36 -07:00
2008-01-29 10:14:59 +00:00
.Lcopy_bytes_checklen :
beqz l e n , . L d o n e
2005-04-16 15:20:36 -07:00
nop
2008-01-29 10:14:59 +00:00
.Lcopy_bytes :
2005-04-16 15:20:36 -07:00
/* 0 < len < NBYTES */
2007-11-25 11:47:56 +01:00
R1 0 K C B A R R I E R ( 0 ( r a ) )
2005-04-16 15:20:36 -07:00
# define C O P Y _ B Y T E ( N ) \
2008-01-29 10:14:59 +00:00
EXC( l b t 0 , N ( s r c ) , . L l _ e x c ) ; \
2005-04-16 15:20:36 -07:00
SUB l e n , l e n , 1 ; \
2008-01-29 10:14:59 +00:00
beqz l e n , . L d o n e ; \
EXC( s b t 0 , N ( d s t ) , . L s _ e x c _ p1 )
2005-04-16 15:20:36 -07:00
COPY_ B Y T E ( 0 )
COPY_ B Y T E ( 1 )
# ifdef U S E _ D O U B L E
COPY_ B Y T E ( 2 )
COPY_ B Y T E ( 3 )
COPY_ B Y T E ( 4 )
COPY_ B Y T E ( 5 )
# endif
2008-01-29 10:14:59 +00:00
EXC( l b t 0 , N B Y T E S - 2 ( s r c ) , . L l _ e x c )
2005-04-16 15:20:36 -07:00
SUB l e n , l e n , 1
jr r a
2008-01-29 10:14:59 +00:00
EXC( s b t 0 , N B Y T E S - 2 ( d s t ) , . L s _ e x c _ p1 )
.Ldone :
2005-04-16 15:20:36 -07:00
jr r a
nop
END( m e m c p y )
2008-01-29 10:14:59 +00:00
.Ll_exc_copy :
2005-04-16 15:20:36 -07:00
/ *
* Copy b y t e s f r o m s r c u n t i l f a u l t i n g l o a d a d d r e s s ( o r u n t i l a
* lb f a u l t s )
*
* When r e a c h e d b y a f a u l t i n g L D F I R S T / L D R E S T , T H R E A D _ B U A D D R ( $ 2 8 )
* may b e m o r e t h a n a b y t e b e y o n d t h e l a s t a d d r e s s .
* Hence, t h e l b b e l o w m a y g e t a n e x c e p t i o n .
*
* Assumes s r c < T H R E A D _ B U A D D R ( $ 2 8 )
* /
LOAD t 0 , T I _ T A S K ( $ 2 8 )
nop
LOAD t 0 , T H R E A D _ B U A D D R ( t 0 )
1 :
2008-01-29 10:14:59 +00:00
EXC( l b t 1 , 0 ( s r c ) , . L l _ e x c )
2005-04-16 15:20:36 -07:00
ADD s r c , s r c , 1
sb t 1 , 0 ( d s t ) # c a n ' t f a u l t - - w e ' r e c o p y _ f r o m _ u s e r
2007-10-23 12:43:25 +01:00
.set reorder /* DADDI_WAR */
ADD d s t , d s t , 1
2005-04-16 15:20:36 -07:00
bne s r c , t 0 , 1 b
2007-10-23 12:43:25 +01:00
.set noreorder
2008-01-29 10:14:59 +00:00
.Ll_exc :
2005-04-16 15:20:36 -07:00
LOAD t 0 , T I _ T A S K ( $ 2 8 )
nop
LOAD t 0 , T H R E A D _ B U A D D R ( t 0 ) # t 0 i s j u s t p a s t l a s t g o o d a d d r e s s
nop
SUB l e n , A T , t 0 # l e n n u m b e r o f u n c o p i e d b y t e s
2012-06-06 23:00:31 +01:00
bnez t 6 , . L d o n e / * S k i p t h e z e r o i n g p a r t i f i n a t o m i c * /
2005-04-16 15:20:36 -07:00
/ *
* Here' s w h e r e w e r e l y o n s r c a n d d s t b e i n g i n c r e m e n t e d i n t a n d e m ,
* See ( 3 ) a b o v e .
* dst + = ( f a u l t a d d r - s r c ) t o p u t d s t a t f i r s t b y t e t o c l e a r
* /
ADD d s t , t 0 # c o m p u t e s t a r t a d d r e s s i n a 1
SUB d s t , s r c
/ *
* Clear l e n b y t e s s t a r t i n g a t d s t . C a n ' t c a l l _ _ b z e r o b e c a u s e i t
* might m o d i f y l e n . A n i n e f f i c i e n t l o o p f o r t h e s e r a r e t i m e s . . .
* /
2007-10-23 12:43:25 +01:00
.set reorder /* DADDI_WAR */
SUB s r c , l e n , 1
2008-01-29 10:14:59 +00:00
beqz l e n , . L d o n e
2007-10-23 12:43:25 +01:00
.set noreorder
2005-04-16 15:20:36 -07:00
1 : sb z e r o , 0 ( d s t )
ADD d s t , d s t , 1
2007-10-23 12:43:25 +01:00
# ifndef C O N F I G _ C P U _ D A D D I _ W O R K A R O U N D S
2005-04-16 15:20:36 -07:00
bnez s r c , 1 b
SUB s r c , s r c , 1
2007-10-23 12:43:25 +01:00
# else
.set push
.set noat
li v1 , 1
bnez s r c , 1 b
SUB s r c , s r c , v1
.set pop
# endif
2005-04-16 15:20:36 -07:00
jr r a
nop
2007-10-23 12:43:25 +01:00
# define S E X C ( n ) \
2013-01-22 12:59:30 +01:00
.set reorder; /* DADDI_WAR */ \
2008-01-29 10:14:59 +00:00
.Ls_exc_p # # n ## u : \
2007-10-23 12:43:25 +01:00
ADD l e n , l e n , n * N B Y T E S ; \
jr r a ; \
.set noreorder
2005-04-16 15:20:36 -07:00
SEXC( 8 )
SEXC( 7 )
SEXC( 6 )
SEXC( 5 )
SEXC( 4 )
SEXC( 3 )
SEXC( 2 )
SEXC( 1 )
2008-01-29 10:14:59 +00:00
.Ls_exc_p1 :
2007-10-23 12:43:25 +01:00
.set reorder /* DADDI_WAR */
ADD l e n , l e n , 1
2005-04-16 15:20:36 -07:00
jr r a
2007-10-23 12:43:25 +01:00
.set noreorder
2008-01-29 10:14:59 +00:00
.Ls_exc :
2005-04-16 15:20:36 -07:00
jr r a
nop
.align 5
LEAF( m e m m o v e )
ADD t 0 , a0 , a2
ADD t 1 , a1 , a2
sltu t 0 , a1 , t 0 # d s t + l e n < = s r c - > m e m c p y
sltu t 1 , a0 , t 1 # d s t > = s r c + l e n - > m e m c p y
and t 0 , t 1
2008-01-29 10:14:59 +00:00
beqz t 0 , . L _ _ m e m c p y
2005-04-16 15:20:36 -07:00
move v0 , a0 / * r e t u r n v a l u e * /
2008-01-29 10:14:59 +00:00
beqz a2 , . L r _ o u t
2005-04-16 15:20:36 -07:00
END( m e m m o v e )
/* fall through to __rmemcpy */
LEAF( _ _ r m e m c p y ) / * a0 =dst a1 =src a2 =len * /
sltu t 0 , a1 , a0
2008-01-29 10:14:59 +00:00
beqz t 0 , . L r _ e n d _ b y t e s _ u p # s r c > = d s t
2005-04-16 15:20:36 -07:00
nop
ADD a0 , a2 # d s t = d s t + l e n
ADD a1 , a2 # s r c = s r c + l e n
2008-01-29 10:14:59 +00:00
.Lr_end_bytes :
2007-11-25 11:47:56 +01:00
R1 0 K C B A R R I E R ( 0 ( r a ) )
2005-04-16 15:20:36 -07:00
lb t 0 , - 1 ( a1 )
SUB a2 , a2 , 0 x1
sb t 0 , - 1 ( a0 )
SUB a1 , a1 , 0 x1
2007-10-23 12:43:25 +01:00
.set reorder /* DADDI_WAR */
SUB a0 , a0 , 0 x1
2008-01-29 10:14:59 +00:00
bnez a2 , . L r _ e n d _ b y t e s
2007-10-23 12:43:25 +01:00
.set noreorder
2005-04-16 15:20:36 -07:00
2008-01-29 10:14:59 +00:00
.Lr_out :
2005-04-16 15:20:36 -07:00
jr r a
move a2 , z e r o
2008-01-29 10:14:59 +00:00
.Lr_end_bytes_up :
2007-11-25 11:47:56 +01:00
R1 0 K C B A R R I E R ( 0 ( r a ) )
2005-04-16 15:20:36 -07:00
lb t 0 , ( a1 )
SUB a2 , a2 , 0 x1
sb t 0 , ( a0 )
ADD a1 , a1 , 0 x1
2007-10-23 12:43:25 +01:00
.set reorder /* DADDI_WAR */
ADD a0 , a0 , 0 x1
2008-01-29 10:14:59 +00:00
bnez a2 , . L r _ e n d _ b y t e s _ u p
2007-10-23 12:43:25 +01:00
.set noreorder
2005-04-16 15:20:36 -07:00
jr r a
move a2 , z e r o
END( _ _ r m e m c p y )