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
2014-01-07 12:57:04 +00:00
* Copyright ( C ) 2 0 1 4 I m a g i n a t i o n T e c h n o l o g i e s L t d .
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 .
* /
2014-01-07 12:57:04 +00:00
/* Instruction type */
# define L D _ I N S N 1
# define S T _ I N S N 2
2014-01-07 15:59:03 +00:00
/* Pretech type */
# define S R C _ P R E F E T C H 1
# define D S T _ P R E F E T C H 2
2014-01-07 14:34:05 +00:00
# define L E G A C Y _ M O D E 1
# define E V A _ M O D E 2
# define U S E R O P 1
# define K E R N E L O P 2
2014-01-07 12:57:04 +00:00
/ *
* Wrapper t o a d d a n e n t r y i n t h e e x c e p t i o n t a b l e
* in c a s e t h e i n s n c a u s e s a m e m o r y e x c e p t i o n .
* Arguments :
* insn : L o a d / s t o r e i n s t r u c t i o n
* type : I n s t r u c t i o n t y p e
* reg : R e g i s t e r
* addr : A d d r e s s
* handler : E x c e p t i o n h a n d l e r
* /
2005-04-16 15:20:36 -07:00
2014-01-07 14:34:05 +00:00
# define E X C ( i n s n , t y p e , r e g , a d d r , h a n d l e r ) \
.if \ mode = = L E G A C Y _ M O D E ; \
9 : insn 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 ; \
2014-01-07 16:20:22 +00:00
/* This is assembled in EVA mode */ \
.else ; \
/* If loading from user or storing to user */ \
.if ( ( \ from = = U S E R O P ) & & ( t y p e = = L D _ I N S N ) ) | | \
( ( \ to = = U S E R O P ) & & ( t y p e = = S T _ I N S N ) ) ; \
9 : _ _ BUILD_ E V A _ I N S N ( i n s n ## e , 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 ; \
.else ; \
/ * \
* Still i n E V A , b u t n o n e e d f o r \
* exception h a n d l e r o r E V A i n s n \
* / \
insn r e g , a d d r ; \
.endif ; \
2014-01-07 14:34:05 +00:00
.endif
2014-01-07 16:20:22 +00:00
2005-04-16 15:20:36 -07:00
/ *
* 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
2014-01-07 12:57:04 +00:00
# define L O A D K l d / * N o e x c e p t i o n * /
# define L O A D ( r e g , a d d r , h a n d l e r ) E X C ( l d , L D _ I N S N , r e g , a d d r , h a n d l e r )
# define L O A D L ( r e g , a d d r , h a n d l e r ) E X C ( l d l , L D _ I N S N , r e g , a d d r , h a n d l e r )
# define L O A D R ( r e g , a d d r , h a n d l e r ) E X C ( l d r , L D _ I N S N , r e g , a d d r , h a n d l e r )
# define S T O R E L ( r e g , a d d r , h a n d l e r ) E X C ( s d l , S T _ I N S N , r e g , a d d r , h a n d l e r )
# define S T O R E R ( r e g , a d d r , h a n d l e r ) E X C ( s d r , S T _ I N S N , r e g , a d d r , h a n d l e r )
# define S T O R E ( r e g , a d d r , h a n d l e r ) E X C ( s d , S T _ I N S N , r e g , a d d r , h a n d l e r )
2005-04-16 15:20:36 -07:00
# 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
2014-01-07 12:57:04 +00:00
# define L O A D K l w / * N o e x c e p t i o n * /
# define L O A D ( r e g , a d d r , h a n d l e r ) E X C ( l w , L D _ I N S N , r e g , a d d r , h a n d l e r )
# define L O A D L ( r e g , a d d r , h a n d l e r ) E X C ( l w l , L D _ I N S N , r e g , a d d r , h a n d l e r )
# define L O A D R ( r e g , a d d r , h a n d l e r ) E X C ( l w r , L D _ I N S N , r e g , a d d r , h a n d l e r )
# define S T O R E L ( r e g , a d d r , h a n d l e r ) E X C ( s w l , S T _ I N S N , r e g , a d d r , h a n d l e r )
# define S T O R E R ( r e g , a d d r , h a n d l e r ) E X C ( s w r , S T _ I N S N , r e g , a d d r , h a n d l e r )
# define S T O R E ( r e g , a d d r , h a n d l e r ) E X C ( s w , S T _ I N S N , r e g , a d d r , h a n d l e r )
2005-04-16 15:20:36 -07:00
# 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 * /
2014-01-07 12:57:04 +00:00
# define L O A D B ( r e g , a d d r , h a n d l e r ) E X C ( l b , L D _ I N S N , r e g , a d d r , h a n d l e r )
# define S T O R E B ( r e g , a d d r , h a n d l e r ) E X C ( s b , S T _ I N S N , r e g , a d d r , h a n d l e r )
2014-01-07 14:34:05 +00:00
# define _ P R E F ( h i n t , a d d r , t y p e ) \
.if \ mode = = L E G A C Y _ M O D E ; \
PREF( h i n t , a d d r ) ; \
2014-01-07 16:20:22 +00:00
.else ; \
.if ( ( \ from = = U S E R O P ) & & ( t y p e = = S R C _ P R E F E T C H ) ) | | \
( ( \ to = = U S E R O P ) & & ( t y p e = = D S T _ P R E F E T C H ) ) ; \
/ * \
* PREFE h a s o n l y 9 b i t s f o r t h e o f f s e t \
* compared t o P R E F w h i c h h a s 1 6 , s o i t m a y \
* need t o u s e t h e $ a t r e g i s t e r b u t t h i s \
* register s h o u l d r e m a i n i n t a c t b e c a u s e i t ' s \
* used l a t e r o n . T h e r e f o r e u s e $ v1 . \
* / \
.set at=v1 ; \
PREFE( h i n t , a d d r ) ; \
.set noat; \
.else ; \
PREF( h i n t , a d d r ) ; \
.endif ; \
2014-01-07 14:34:05 +00:00
.endif
2014-01-07 15:59:03 +00:00
# define P R E F S ( h i n t , a d d r ) _ P R E F ( h i n t , a d d r , S R C _ P R E F E T C H )
# define P R E F D ( h i n t , a d d r ) _ P R E F ( h i n t , a d d r , D S T _ P R E F E T C H )
2005-04-16 15:20:36 -07:00
# 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
.align 5
2014-01-07 14:34:05 +00:00
/ *
* Macro t o b u i l d t h e _ _ c o p y _ u s e r c o m m o n c o d e
* Arguements :
* mode : L E G A C Y _ M O D E o r E V A _ M O D E
* from : S o u r c e o p e r a n d . U S E R O P o r K E R N E L O P
* to : D e s t i n a t i o n o p e r a n d . U S E R O P o r K E R N E L O P
* /
.macro __BUILD_COPY_USER mode, f r o m , t o
/* initialize __memcpy if this the first time we execute this macro */
.ifnotdef __memcpy
.set _ _ memcpy, 1
.hidden __memcpy /* make sure it does not leak */
.endif
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 .
* /
2014-01-07 15:59:03 +00:00
PREFS( 0 , 0 ( s r c ) )
PREFD( 1 , 0 ( d s t ) )
2005-04-16 15:20:36 -07:00
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
2014-01-07 15:59:03 +00:00
PREFS( 0 , 1 * 3 2 ( s r c ) )
PREFD( 1 , 1 * 3 2 ( d s t ) )
2014-01-07 14:34:05 +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
2014-01-07 15:59:03 +00:00
PREFS( 0 , 2 * 3 2 ( s r c ) )
PREFD( 1 , 2 * 3 2 ( d s t ) )
2014-11-14 11:55:50 +00:00
# ifndef C O N F I G _ C P U _ M I P S R 6
2014-01-07 14:34:05 +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
2014-01-07 14:34:05 +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 \ @
2014-11-14 11:55:50 +00:00
# else
or t 0 , t 0 , t 1
bnez t 0 , . L c o p y _ u n a l i g n e d _ b y t e s \ @
# endif
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
* /
2014-01-07 14:34:05 +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
2014-01-07 14:34:05 +00:00
beqz t 0 , . L c l e a n u p _ b o t h _ a l i g n e d \ @ # len < 8*NBYTES
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 )
2014-01-07 15:59:03 +00:00
PREFS( 0 , 3 * 3 2 ( s r c ) )
PREFD( 1 , 3 * 3 2 ( d s t ) )
2005-04-16 15:20:36 -07:00
.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 ) )
2014-01-07 14:34:05 +00:00
LOAD( t 0 , U N I T ( 0 ) ( s r c ) , . L l _ e x c \ @)
LOAD( t 1 , U N I T ( 1 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
LOAD( t 2 , U N I T ( 2 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
LOAD( 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
2014-01-07 14:34:05 +00:00
LOAD( t 4 , U N I T ( 4 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
LOAD( t 7 , U N I T ( 5 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
STORE( t 0 , U N I T ( 0 ) ( d s t ) , . L s _ e x c _ p8 u \ @)
STORE( t 1 , U N I T ( 1 ) ( d s t ) , . L s _ e x c _ p7 u \ @)
LOAD( t 0 , U N I T ( 6 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
LOAD( 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
2014-01-07 14:34:05 +00:00
STORE( t 2 , U N I T ( - 6 ) ( d s t ) , . L s _ e x c _ p6 u \ @)
STORE( t 3 , U N I T ( - 5 ) ( d s t ) , . L s _ e x c _ p5 u \ @)
STORE( t 4 , U N I T ( - 4 ) ( d s t ) , . L s _ e x c _ p4 u \ @)
STORE( t 7 , U N I T ( - 3 ) ( d s t ) , . L s _ e x c _ p3 u \ @)
STORE( t 0 , U N I T ( - 2 ) ( d s t ) , . L s _ e x c _ p2 u \ @)
STORE( t 1 , U N I T ( - 1 ) ( d s t ) , . L s _ e x c _ p1 u \ @)
2014-01-07 15:59:03 +00:00
PREFS( 0 , 8 * 3 2 ( s r c ) )
PREFD( 1 , 8 * 3 2 ( d s t ) )
2005-04-16 15:20:36 -07:00
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
* /
2014-01-07 14:34:05 +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
2014-01-07 14:34:05 +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
* /
2014-01-07 14:34:05 +00:00
LOAD( t 0 , U N I T ( 0 ) ( s r c ) , . L l _ e x c \ @)
LOAD( t 1 , U N I T ( 1 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
LOAD( t 2 , U N I T ( 2 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
LOAD( 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 ) )
2014-01-07 14:34:05 +00:00
STORE( t 0 , U N I T ( 0 ) ( d s t ) , . L s _ e x c _ p4 u \ @)
STORE( t 1 , U N I T ( 1 ) ( d s t ) , . L s _ e x c _ p3 u \ @)
STORE( t 2 , U N I T ( 2 ) ( d s t ) , . L s _ e x c _ p2 u \ @)
STORE( 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
2014-01-07 14:34:05 +00:00
beqz l e n , . L d o n e \ @
2007-10-23 12:43:25 +01:00
.set noreorder
2014-01-07 14:34:05 +00:00
.Lless_than_4units \ @:
2005-04-16 15:20:36 -07:00
/ *
* rem = l e n % N B Y T E S
* /
2014-01-07 14:34:05 +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 ) )
2014-01-07 14:34:05 +00:00
LOAD( 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
2014-01-07 14:34:05 +00:00
STORE( 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
2014-11-14 11:55:50 +00:00
# ifndef C O N F I G _ C P U _ M I P S R 6
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
2014-01-07 14:34:05 +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
2014-01-07 14:34:05 +00:00
LOAD( 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
2014-01-07 14:34:05 +00:00
STREST( 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
2014-01-07 14:34:05 +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
2014-01-07 14:34:05 +00:00
LDFIRST( 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
2014-01-07 14:34:05 +00:00
LDREST( 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 ) )
2014-01-07 14:34:05 +00:00
STFIRST( 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
2014-01-07 14:34:05 +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
2014-01-07 14:34:05 +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
2014-01-07 15:59:03 +00:00
PREFS( 0 , 3 * 3 2 ( s r c ) )
2014-01-07 14:34:05 +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
2014-01-07 15:59:03 +00:00
PREFD( 1 , 3 * 3 2 ( d s t ) )
2005-04-16 15:20:36 -07:00
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 ) )
2014-01-07 14:34:05 +00:00
LDFIRST( t 0 , F I R S T ( 0 ) ( s r c ) , . L l _ e x c \ @)
LDFIRST( t 1 , F I R S T ( 1 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
2013-01-22 12:59:30 +01:00
SUB l e n , l e n , 4 * N B Y T E S
2014-01-07 14:34:05 +00:00
LDREST( t 0 , R E S T ( 0 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
LDREST( t 1 , R E S T ( 1 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
LDFIRST( t 2 , F I R S T ( 2 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
LDFIRST( t 3 , F I R S T ( 3 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
LDREST( t 2 , R E S T ( 2 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
LDREST( t 3 , R E S T ( 3 ) ( s r c ) , . L l _ e x c _ c o p y \ @)
2014-01-07 15:59:03 +00:00
PREFS( 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 )
2005-04-16 15:20:36 -07:00
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
2014-01-07 14:34:05 +00:00
STORE( t 0 , U N I T ( 0 ) ( d s t ) , . L s _ e x c _ p4 u \ @)
STORE( t 1 , U N I T ( 1 ) ( d s t ) , . L s _ e x c _ p3 u \ @)
STORE( t 2 , U N I T ( 2 ) ( d s t ) , . L s _ e x c _ p2 u \ @)
STORE( t 3 , U N I T ( 3 ) ( d s t ) , . L s _ e x c _ p1 u \ @)
2014-01-07 15:59:03 +00:00
PREFD( 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
2014-01-07 14:34:05 +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
2014-01-07 14:34:05 +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 ) )
2014-01-07 14:34:05 +00:00
LDFIRST( t 0 , F I R S T ( 0 ) ( s r c ) , . L l _ e x c \ @)
LDREST( 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
2014-01-07 14:34:05 +00:00
STORE( 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
2014-11-14 11:55:50 +00:00
# endif / * ! C O N F I G _ C P U _ M I P S R 6 * /
2014-01-07 14:34:05 +00:00
.Lcopy_bytes_checklen \ @:
beqz l e n , . L d o n e \ @
2005-04-16 15:20:36 -07:00
nop
2014-01-07 14:34:05 +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 ) \
2014-01-07 14:34:05 +00:00
LOADB( 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 ; \
2014-01-07 14:34:05 +00:00
beqz l e n , . L d o n e \ @; \
STOREB( 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
2014-01-07 14:34:05 +00:00
LOADB( 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
2014-01-07 14:34:05 +00:00
STOREB( 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
2014-11-17 09:32:38 +00:00
nop
2014-11-14 11:55:50 +00:00
# ifdef C O N F I G _ C P U _ M I P S R 6
.Lcopy_unaligned_bytes \ @:
1 :
COPY_ B Y T E ( 0 )
COPY_ B Y T E ( 1 )
COPY_ B Y T E ( 2 )
COPY_ B Y T E ( 3 )
COPY_ B Y T E ( 4 )
COPY_ B Y T E ( 5 )
COPY_ B Y T E ( 6 )
COPY_ B Y T E ( 7 )
ADD s r c , s r c , 8
b 1 b
ADD d s t , d s t , 8
# endif / * C O N F I G _ C P U _ M I P S R 6 * /
2014-01-07 14:34:05 +00:00
.if __memcpy = = 1
2005-04-16 15:20:36 -07:00
END( m e m c p y )
2014-01-07 14:34:05 +00:00
.set _ _ memcpy, 0
.hidden __memcpy
.endif
2005-04-16 15:20:36 -07:00
2014-01-07 14:34:05 +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 )
* /
2014-01-07 12:57:04 +00:00
LOADK t 0 , T I _ T A S K ( $ 2 8 )
2005-04-16 15:20:36 -07:00
nop
2014-01-07 12:57:04 +00:00
LOADK t 0 , T H R E A D _ B U A D D R ( t 0 )
2005-04-16 15:20:36 -07:00
1 :
2014-01-07 14:34:05 +00:00
LOADB( 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
2014-01-07 14:34:05 +00:00
.Ll_exc \ @:
2014-01-07 12:57:04 +00:00
LOADK t 0 , T I _ T A S K ( $ 2 8 )
2005-04-16 15:20:36 -07:00
nop
2014-01-07 12:57:04 +00:00
LOADK 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
2005-04-16 15:20:36 -07:00
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
2014-01-07 14:34:05 +00:00
bnez t 6 , . L d o n e \ @ /* Skip the zeroing part if inatomic */
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
2014-01-07 14:34:05 +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 */ \
2014-01-07 14:34:05 +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 )
2014-01-07 14:34:05 +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
2014-01-07 14:34:05 +00:00
.Ls_exc \ @:
2005-04-16 15:20:36 -07:00
jr r a
nop
2014-01-07 14:34:05 +00:00
.endm
2005-04-16 15:20:36 -07:00
.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 )
2014-01-07 14:34:05 +00: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 )
/ *
* 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 * /
.L__memcpy :
FEXPORT( _ _ c o p y _ u s e r )
li t 6 , 0 / * n o t i n a t o m i c * /
__copy_user_common :
/* Legacy Mode, user <-> user */
_ _ BUILD_ C O P Y _ U S E R L E G A C Y _ M O D E U S E R O P U S E R O P
2014-01-07 16:20:22 +00:00
# ifdef C O N F I G _ E V A
/ *
* For E V A w e n e e d d i s t i n c t s y m b o l s f o r r e a d i n g a n d w r i t i n g t o u s e r s p a c e .
* This i s b e c a u s e w e n e e d t o u s e s p e c i f i c E V A i n s t r u c t i o n s t o p e r f o r m t h e
* virtual < - > p h y s i c a l t r a n s l a t i o n w h e n a v i r t u a l a d d r e s s i s a c t u a l l y i n u s e r
* space
* /
LEAF( _ _ c o p y _ u s e r _ i n a t o m i c _ e v a )
b _ _ c o p y _ f r o m _ 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 _ e v a )
/ *
* _ _ copy_ f r o m _ u s e r ( E V A )
* /
LEAF( _ _ c o p y _ f r o m _ u s e r _ e v a )
li t 6 , 0 / * n o t i n a t o m i c * /
__copy_from_user_common :
_ _ BUILD_ C O P Y _ U S E R E V A _ M O D E U S E R O P K E R N E L O P
END( _ _ c o p y _ f r o m _ u s e r _ e v a )
/ *
* _ _ copy_ t o _ u s e r ( E V A )
* /
LEAF( _ _ c o p y _ t o _ u s e r _ e v a )
_ _ BUILD_ C O P Y _ U S E R E V A _ M O D E K E R N E L O P U S E R O P
END( _ _ c o p y _ t o _ u s e r _ e v a )
/ *
* _ _ copy_ i n _ u s e r ( E V A )
* /
LEAF( _ _ c o p y _ i n _ u s e r _ e v a )
_ _ BUILD_ C O P Y _ U S E R E V A _ M O D E U S E R O P U S E R O P
END( _ _ c o p y _ i n _ u s e r _ e v a )
# endif