2005-04-16 15:20:36 -07:00
/* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */
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 >
# include < a s m / d w a r f2 . h >
2011-07-13 09:24:10 -04:00
# include < a s m / a l t e r n a t i v e - a s m . h >
2006-09-26 10:52:32 +02:00
ALIGN
copy_page_c :
CFI_ S T A R T P R O C
movl $ 4 0 9 6 / 8 ,% e c x
rep m o v s q
ret
CFI_ E N D P R O C
ENDPROC( c o p y _ p a g e _ c )
2005-04-16 15:20:36 -07:00
/ * Don' t u s e s t r e a m i n g s t o r e b e c a u s e i t ' s b e t t e r w h e n t h e t a r g e t
ends u p i n c a c h e . * /
/* Could vary the prefetch distance based on SMP/UP */
2006-09-26 10:52:32 +02:00
ENTRY( c o p y _ p a g e )
CFI_ S T A R T P R O C
2006-02-03 21:51:02 +01:00
subq $ 3 * 8 ,% r s p
2006-09-26 10:52:32 +02:00
CFI_ A D J U S T _ C F A _ O F F S E T 3 * 8
2006-02-03 21:51:02 +01:00
movq % r b x ,( % r s p )
2006-09-26 10:52:32 +02:00
CFI_ R E L _ O F F S E T r b x , 0
2006-02-03 21:51:02 +01:00
movq % r12 ,1 * 8 ( % r s p )
2006-09-26 10:52:32 +02:00
CFI_ R E L _ O F F S E T r12 , 1 * 8
2006-02-03 21:51:02 +01:00
movq % r13 ,2 * 8 ( % r s p )
2006-09-26 10:52:32 +02:00
CFI_ R E L _ O F F S E T r13 , 2 * 8
2006-02-03 21:51:02 +01:00
movl $ ( 4 0 9 6 / 6 4 ) - 5 ,% e c x
.p2align 4
.Loop64 :
dec % r c x
movq ( % r s i ) , % r a x
movq 8 ( % r s i ) , % r b x
movq 1 6 ( % r s i ) , % r d x
movq 2 4 ( % r s i ) , % r8
movq 3 2 ( % r s i ) , % r9
movq 4 0 ( % r s i ) , % r10
movq 4 8 ( % r s i ) , % r11
movq 5 6 ( % r s i ) , % r12
prefetcht0 5 * 6 4 ( % r s i )
movq % r a x , ( % r d i )
movq % r b x , 8 ( % r d i )
movq % r d x , 1 6 ( % r d i )
movq % r8 , 2 4 ( % r d i )
movq % r9 , 3 2 ( % r d i )
movq % r10 , 4 0 ( % r d i )
movq % r11 , 4 8 ( % r d i )
movq % r12 , 5 6 ( % r d i )
leaq 6 4 ( % r s i ) , % r s i
leaq 6 4 ( % r d i ) , % r d i
jnz . L o o p64
movl $ 5 ,% e c x
.p2align 4
.Loop2 :
decl % e c x
movq ( % r s i ) , % r a x
movq 8 ( % r s i ) , % r b x
movq 1 6 ( % r s i ) , % r d x
movq 2 4 ( % r s i ) , % r8
movq 3 2 ( % r s i ) , % r9
movq 4 0 ( % r s i ) , % r10
movq 4 8 ( % r s i ) , % r11
movq 5 6 ( % r s i ) , % r12
movq % r a x , ( % r d i )
movq % r b x , 8 ( % r d i )
movq % r d x , 1 6 ( % r d i )
movq % r8 , 2 4 ( % r d i )
movq % r9 , 3 2 ( % r d i )
movq % r10 , 4 0 ( % r d i )
movq % r11 , 4 8 ( % r d i )
movq % r12 , 5 6 ( % r d i )
leaq 6 4 ( % r d i ) ,% r d i
leaq 6 4 ( % r s i ) ,% r s i
jnz . L o o p2
movq ( % r s p ) ,% r b x
2006-09-26 10:52:32 +02:00
CFI_ R E S T O R E r b x
2006-02-03 21:51:02 +01:00
movq 1 * 8 ( % r s p ) ,% r12
2006-09-26 10:52:32 +02:00
CFI_ R E S T O R E r12
2006-02-03 21:51:02 +01:00
movq 2 * 8 ( % r s p ) ,% r13
2006-09-26 10:52:32 +02:00
CFI_ R E S T O R E r13
2006-02-03 21:51:02 +01:00
addq $ 3 * 8 ,% r s p
2006-09-26 10:52:32 +02:00
CFI_ A D J U S T _ C F A _ O F F S E T - 3 * 8
2006-02-03 21:51:02 +01:00
ret
2006-09-26 10:52:32 +02:00
.Lcopy_page_end :
CFI_ E N D P R O C
ENDPROC( c o p y _ p a g e )
2006-02-03 21:51:02 +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 * /
# include < a s m / c p u f e a t u r e . h >
2006-09-26 10:52:32 +02:00
.section .altinstr_replacement , " ax"
1 : .byte 0xeb /* jmp <disp8> */
.byte ( copy_ p a g e _ c - c o p y _ p a g e ) - ( 2 f - 1 b ) / * o f f s e t * /
2 :
.previous
2006-02-03 21:51:02 +01:00
.section .altinstructions , " a"
2011-07-13 09:24:10 -04:00
altinstruction_ e n t r y c o p y _ p a g e , 1 b , X 8 6 _ F E A T U R E _ R E P _ G O O D , \
.Lcopy_page_end - copy_ p a g e , 2 b - 1 b
2006-02-03 21:51:02 +01:00
.previous