2005-04-16 15:20:36 -07:00
/* Copyright 2002 Andi Kleen */
2006-10-04 03:38:54 -04:00
2006-09-26 10:52:32 +02:00
# include < l i n u x / l i n k a g e . h >
2009-03-12 12:20:17 +01:00
2006-09-26 10:52:32 +02:00
# include < a s m / c p u f e a t u r e . h >
2009-03-12 12:20:17 +01:00
# include < a s m / d w a r f2 . h >
2006-09-26 10:52:32 +02:00
2005-04-16 15:20:36 -07:00
/ *
* memcpy - C o p y a m e m o r y b l o c k .
*
2009-03-12 12:20:17 +01:00
* Input :
* rdi d e s t i n a t i o n
* rsi s o u r c e
* rdx c o u n t
*
2005-04-16 15:20:36 -07:00
* Output :
* rax o r i g i n a l d e s t i n a t i o n
2009-03-12 12:20:17 +01:00
* /
2005-04-16 15:20:36 -07:00
2009-03-12 12:20:17 +01:00
/ *
* memcpy_ c ( ) - f a s t s t r i n g o p s ( R E P M O V S Q ) b a s e d v a r i a n t .
*
* Calls t o t h i s g e t p a t c h e d i n t o t h e k e r n e l i m a g e v i a t h e
* alternative i n s t r u c t i o n s f r a m e w o r k :
* /
2006-09-26 10:52:32 +02:00
ALIGN
memcpy_c :
CFI_ S T A R T P R O C
2009-03-12 12:20:17 +01:00
movq % r d i , % r a x
movl % e d x , % e c x
shrl $ 3 , % e c x
andl $ 7 , % e d x
2006-09-26 10:52:32 +02:00
rep m o v s q
2009-03-12 12:20:17 +01:00
movl % e d x , % e c x
2006-09-26 10:52:32 +02:00
rep m o v s b
ret
CFI_ E N D P R O C
ENDPROC( m e m c p y _ c )
ENTRY( _ _ m e m c p y )
ENTRY( m e m c p y )
CFI_ S T A R T P R O C
2006-02-03 21:51:02 +01:00
2009-03-12 12:20:17 +01:00
/ *
* Put t h e n u m b e r o f f u l l 6 4 - b y t e b l o c k s i n t o % e c x .
* Tail p o r t i o n i s h a n d l e d a t t h e e n d :
* /
movq % r d i , % r a x
movl % e d x , % e c x
shrl $ 6 , % e c x
2006-02-03 21:51:02 +01:00
jz . L h a n d l e _ t a i l
.p2align 4
.Lloop_64 :
2009-03-12 12:20:17 +01:00
/ *
* We d e c r e m e n t t h e l o o p i n d e x h e r e - a n d t h e z e r o - f l a g i s
* checked a t t h e e n d o f t h e l o o p ( i n s t r u c t i o n s i n b e t w e e n d o
* not c h a n g e t h e z e r o f l a g ) :
* /
2006-02-03 21:51:02 +01:00
decl % e c x
2009-03-12 12:20:17 +01:00
/ *
* Move i n b l o c k s o f 4 x16 b y t e s :
* /
movq 0 * 8 ( % r s i ) , % r11
movq 1 * 8 ( % r s i ) , % r8
movq % r11 , 0 * 8 ( % r d i )
movq % r8 , 1 * 8 ( % r d i )
2006-02-03 21:51:02 +01:00
2009-03-12 12:20:17 +01:00
movq 2 * 8 ( % r s i ) , % r9
movq 3 * 8 ( % r s i ) , % r10
movq % r9 , 2 * 8 ( % r d i )
movq % r10 , 3 * 8 ( % r d i )
2006-02-03 21:51:02 +01:00
2009-03-12 12:20:17 +01:00
movq 4 * 8 ( % r s i ) , % r11
movq 5 * 8 ( % r s i ) , % r8
movq % r11 , 4 * 8 ( % r d i )
movq % r8 , 5 * 8 ( % r d i )
2006-02-03 21:51:02 +01:00
2009-03-12 12:20:17 +01:00
movq 6 * 8 ( % r s i ) , % r9
movq 7 * 8 ( % r s i ) , % r10
movq % r9 , 6 * 8 ( % r d i )
movq % r10 , 7 * 8 ( % r d i )
2006-02-03 21:51:02 +01:00
2009-03-12 12:20:17 +01:00
leaq 6 4 ( % r s i ) , % r s i
leaq 6 4 ( % r d i ) , % r d i
2006-02-03 21:51:02 +01:00
jnz . L l o o p _ 6 4
.Lhandle_tail :
2009-03-12 12:20:17 +01:00
movl % e d x , % e c x
andl $ 6 3 , % e c x
shrl $ 3 , % e c x
2006-02-03 21:51:02 +01:00
jz . L h a n d l e _ 7
2009-03-12 12:20:17 +01:00
2006-02-03 21:51:02 +01:00
.p2align 4
.Lloop_8 :
decl % e c x
2009-03-12 12:20:17 +01:00
movq ( % r s i ) , % r8
movq % r8 , ( % r d i )
leaq 8 ( % r d i ) , % r d i
leaq 8 ( % r s i ) , % r s i
2006-02-03 21:51:02 +01:00
jnz . L l o o p _ 8
.Lhandle_7 :
2009-03-12 12:20:17 +01:00
movl % e d x , % e c x
andl $ 7 , % e c x
jz . L e n d
2006-02-03 21:51:02 +01:00
.p2align 4
.Lloop_1 :
2009-03-12 12:20:17 +01:00
movb ( % r s i ) , % r8 b
movb % r8 b , ( % r d i )
2006-02-03 21:51:02 +01:00
incq % r d i
incq % r s i
decl % e c x
jnz . L l o o p _ 1
2009-03-12 12:20:17 +01:00
.Lend :
2006-02-03 21:51:02 +01:00
ret
2006-09-26 10:52:32 +02:00
CFI_ E N D P R O C
ENDPROC( m e m c p y )
ENDPROC( _ _ m e m c p y )
2006-02-03 21:51:02 +01:00
2009-03-12 12:20:17 +01:00
/ *
* Some C P U s r u n f a s t e r u s i n g t h e s t r i n g c o p y i n s t r u c t i o n s .
* It i s a l s o a l o t s i m p l e r . U s e t h i s w h e n p o s s i b l e :
* /
2006-02-03 21:51:02 +01:00
2009-03-12 12:20:17 +01:00
.section .altinstr_replacement , " ax"
2006-09-26 10:52:32 +02:00
1 : .byte 0xeb /* jmp <disp8> */
.byte ( memcpy_ c - m e m c p y ) - ( 2 f - 1 b ) / * o f f s e t * /
2 :
.previous
2009-03-12 12:20:17 +01:00
.section .altinstructions , " a"
2006-02-03 21:51:02 +01:00
.align 8
2006-09-26 10:52:32 +02:00
.quad memcpy
.quad 1b
.byte X86_FEATURE_REP_GOOD
2009-03-12 12:20:17 +01:00
/ *
* Replace o n l y b e g i n n i n g , m e m c p y i s u s e d t o a p p l y a l t e r n a t i v e s ,
* so i t i s s i l l y t o o v e r w r i t e i t s e l f w i t h n o p s - r e b o o t i s t h e
* only o u t c o m e . . .
* /
2007-08-12 10:12:52 +02:00
.byte 2b - 1 b
2006-09-26 10:52:32 +02:00
.byte 2b - 1 b
2006-02-03 21:51:02 +01:00
.previous