2011-01-18 04:39:15 +03:00
/ *
* Normally c o m p i l e r b u i l t i n s a r e u s e d , b u t s o m e t i m e s t h e c o m p i l e r c a l l s o u t
* of l i n e c o d e . B a s e d o n a s m - i 3 8 6 / s t r i n g . h .
*
* This a s s e m b l y f i l e i s r e - w r i t t e n f r o m m e m m o v e _ 6 4 . c f i l e .
* - Copyright 2 0 1 1 F e n g h u a Y u < f e n g h u a . y u @intel.com>
* /
# define _ S T R I N G _ C
# include < l i n u x / l i n k a g e . h >
# include < a s m / d w a r f2 . h >
2011-05-18 02:29:17 +04:00
# include < a s m / c p u f e a t u r e . h >
2011-07-13 17:24:10 +04:00
# include < a s m / a l t e r n a t i v e - a s m . h >
2011-01-18 04:39:15 +03:00
# undef m e m m o v e
/ *
* Implement m e m m o v e ( ) . T h i s c a n h a n d l e o v e r l a p b e t w e e n s r c a n d d s t .
*
* Input :
* rdi : dest
* rsi : src
* rdx : count
*
* Output :
* rax : dest
* /
ENTRY( m e m m o v e )
CFI_ S T A R T P R O C
2011-05-18 02:29:17 +04:00
2011-01-18 04:39:15 +03:00
/* Handle more 32bytes in loop */
mov % r d i , % r a x
cmp $ 0 x20 , % r d x
jb 1 f
/* Decide forward/backward copy mode */
cmp % r d i , % r s i
2011-05-18 02:29:17 +04:00
jge . L m e m m o v e _ b e g i n _ f o r w a r d
mov % r s i , % r8
add % r d x , % r8
cmp % r d i , % r8
jg 2 f
2011-01-18 04:39:15 +03:00
2011-05-18 02:29:17 +04:00
.Lmemmove_begin_forward :
2011-01-18 04:39:15 +03:00
/ *
* movsq i n s t r u c t i o n h a v e m a n y s t a r t u p l a t e n c y
* so w e h a n d l e s m a l l s i z e b y g e n e r a l r e g i s t e r .
* /
cmp $ 6 8 0 , % r d x
jb 3 f
/ *
* movsq i n s t r u c t i o n i s o n l y g o o d f o r a l i g n e d c a s e .
* /
cmpb % d i l , % s i l
je 4 f
3 :
sub $ 0 x20 , % r d x
/ *
* We g o b b l e 3 2 b y t s f o r w a r d i n e a c h l o o p .
* /
5 :
sub $ 0 x20 , % r d x
movq 0 * 8 ( % r s i ) , % r11
movq 1 * 8 ( % r s i ) , % r10
movq 2 * 8 ( % r s i ) , % r9
movq 3 * 8 ( % r s i ) , % r8
leaq 4 * 8 ( % r s i ) , % r s i
movq % r11 , 0 * 8 ( % r d i )
movq % r10 , 1 * 8 ( % r d i )
movq % r9 , 2 * 8 ( % r d i )
movq % r8 , 3 * 8 ( % r d i )
leaq 4 * 8 ( % r d i ) , % r d i
jae 5 b
addq $ 0 x20 , % r d x
jmp 1 f
/ *
* Handle d a t a f o r w a r d b y m o v s q .
* /
.p2align 4
4 :
movq % r d x , % r c x
movq - 8 ( % r s i , % r d x ) , % r11
lea - 8 ( % r d i , % r d x ) , % r10
shrq $ 3 , % r c x
rep m o v s q
movq % r11 , ( % r10 )
jmp 1 3 f
2011-05-18 02:29:17 +04:00
.Lmemmove_end_forward :
2011-01-18 04:39:15 +03:00
/ *
* Handle d a t a b a c k w a r d b y m o v s q .
* /
.p2align 4
7 :
movq % r d x , % r c x
movq ( % r s i ) , % r11
movq % r d i , % r10
leaq - 8 ( % r s i , % r d x ) , % r s i
leaq - 8 ( % r d i , % r d x ) , % r d i
shrq $ 3 , % r c x
std
rep m o v s q
cld
movq % r11 , ( % r10 )
jmp 1 3 f
/ *
* Start t o p r e p a r e f o r b a c k w a r d c o p y .
* /
.p2align 4
2 :
cmp $ 6 8 0 , % r d x
jb 6 f
cmp % d i l , % s i l
je 7 b
6 :
/ *
* Calculate c o p y p o s i t i o n t o t a i l .
* /
addq % r d x , % r s i
addq % r d x , % r d i
subq $ 0 x20 , % r d x
/ *
* We g o b b l e 3 2 b y t s b a c k w a r d i n e a c h l o o p .
* /
8 :
subq $ 0 x20 , % r d x
movq - 1 * 8 ( % r s i ) , % r11
movq - 2 * 8 ( % r s i ) , % r10
movq - 3 * 8 ( % r s i ) , % r9
movq - 4 * 8 ( % r s i ) , % r8
leaq - 4 * 8 ( % r s i ) , % r s i
movq % r11 , - 1 * 8 ( % r d i )
movq % r10 , - 2 * 8 ( % r d i )
movq % r9 , - 3 * 8 ( % r d i )
movq % r8 , - 4 * 8 ( % r d i )
leaq - 4 * 8 ( % r d i ) , % r d i
jae 8 b
/ *
* Calculate c o p y p o s i t i o n t o h e a d .
* /
addq $ 0 x20 , % r d x
subq % r d x , % r s i
subq % r d x , % r d i
1 :
cmpq $ 1 6 , % r d x
jb 9 f
/ *
* Move d a t a f r o m 1 6 b y t e s t o 3 1 b y t e s .
* /
movq 0 * 8 ( % r s i ) , % r11
movq 1 * 8 ( % r s i ) , % r10
movq - 2 * 8 ( % r s i , % r d x ) , % r9
movq - 1 * 8 ( % r s i , % r d x ) , % r8
movq % r11 , 0 * 8 ( % r d i )
movq % r10 , 1 * 8 ( % r d i )
movq % r9 , - 2 * 8 ( % r d i , % r d x )
movq % r8 , - 1 * 8 ( % r d i , % r d x )
jmp 1 3 f
.p2align 4
9 :
cmpq $ 8 , % r d x
jb 1 0 f
/ *
* Move d a t a f r o m 8 b y t e s t o 1 5 b y t e s .
* /
movq 0 * 8 ( % r s i ) , % r11
movq - 1 * 8 ( % r s i , % r d x ) , % r10
movq % r11 , 0 * 8 ( % r d i )
movq % r10 , - 1 * 8 ( % r d i , % r d x )
jmp 1 3 f
10 :
cmpq $ 4 , % r d x
jb 1 1 f
/ *
* Move d a t a f r o m 4 b y t e s t o 7 b y t e s .
* /
movl ( % r s i ) , % r11 d
movl - 4 ( % r s i , % r d x ) , % r10 d
movl % r11 d , ( % r d i )
movl % r10 d , - 4 ( % r d i , % r d x )
jmp 1 3 f
11 :
cmp $ 2 , % r d x
jb 1 2 f
/ *
* Move d a t a f r o m 2 b y t e s t o 3 b y t e s .
* /
movw ( % r s i ) , % r11 w
movw - 2 ( % r s i , % r d x ) , % r10 w
movw % r11 w , ( % r d i )
movw % r10 w , - 2 ( % r d i , % r d x )
jmp 1 3 f
12 :
cmp $ 1 , % r d x
jb 1 3 f
/ *
* Move d a t a f o r 1 b y t e .
* /
movb ( % r s i ) , % r11 b
movb % r11 b , ( % r d i )
13 :
retq
CFI_ E N D P R O C
2011-05-18 02:29:17 +04:00
.section .altinstr_replacement , " ax"
.Lmemmove_begin_forward_efs :
/* Forward moving data. */
movq % r d x , % r c x
rep m o v s b
retq
.Lmemmove_end_forward_efs :
.previous
.section .altinstructions , " a"
2011-07-13 17:24:10 +04:00
altinstruction_ e n t r y . L m e m m o v e _ b e g i n _ f o r w a r d , \
.Lmemmove_begin_forward_efs , X8 6 _ F E A T U R E _ E R M S , \
.Lmemmove_end_forward - .Lmemmove_begin_forward , \
.Lmemmove_end_forward_efs - .Lmemmove_begin_forward_efs
2011-05-18 02:29:17 +04:00
.previous
2011-01-18 04:39:15 +03:00
ENDPROC( m e m m o v e )