2007-02-13 13:26:19 +01:00
/ * Copyright 2 0 0 2 A n d i K l e e n , S u S E L a b s .
* Subject t o t h e G N U P u b l i c L i c e n s e v2 .
*
* Functions t o c o p y f r o m a n d t o u s e r s p a c e .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / d w a r f2 . h >
# define F I X _ A L I G N M E N T 1
# include < a s m / c u r r e n t . h >
# include < a s m / a s m - o f f s e t s . h >
# include < a s m / t h r e a d _ i n f o . h >
# include < a s m / c p u f e a t u r e . h >
/ *
* copy_ u s e r _ n o c a c h e - U n c a c h e d m e m o r y c o p y w i t h e x c e p t i o n h a n d l i n g
* This w i l l f o r c e d e s t i n a t i o n / s o u r c e o u t o f c a c h e f o r m o r e p e r f o r m a n c e .
*
* 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
* rcx z e r o f l a g w h e n 1 z e r o o n e x c e p t i o n
*
* Output :
* eax u n c o p i e d b y t e s o r 0 i f s u c c e s s f u l .
* /
ENTRY( _ _ c o p y _ u s e r _ n o c a c h e )
CFI_ S T A R T P R O C
pushq % r b x
CFI_ A D J U S T _ C F A _ O F F S E T 8
CFI_ R E L _ O F F S E T r b x , 0
pushq % r c x / * s a v e z e r o f l a g * /
CFI_ A D J U S T _ C F A _ O F F S E T 8
CFI_ R E L _ O F F S E T r c x , 0
xorl % e a x ,% e a x / * z e r o f o r t h e e x c e p t i o n h a n d l e r * /
# ifdef F I X _ A L I G N M E N T
/* check for bad alignment of destination */
movl % e d i ,% e c x
andl $ 7 ,% e c x
jnz . L b a d _ a l i g n m e n t
.Lafter_bad_alignment :
# endif
movq % r d x ,% r c x
movl $ 6 4 ,% e b x
shrq $ 6 ,% r d x
decq % r d x
js . L h a n d l e _ t a i l
.p2align 4
.Lloop :
.Ls1 : movq ( % r s i ) ,% r11
.Ls2 : movq 1 * 8 ( % r s i ) ,% r8
.Ls3 : movq 2 * 8 ( % r s i ) ,% r9
.Ls4 : movq 3 * 8 ( % r s i ) ,% r10
.Ld1 : movnti % r11 ,( % r d i )
.Ld2 : movnti % r8 ,1 * 8 ( % r d i )
.Ld3 : movnti % r9 ,2 * 8 ( % r d i )
.Ld4 : movnti % r10 ,3 * 8 ( % r d i )
.Ls5 : movq 4 * 8 ( % r s i ) ,% r11
.Ls6 : movq 5 * 8 ( % r s i ) ,% r8
.Ls7 : movq 6 * 8 ( % r s i ) ,% r9
.Ls8 : movq 7 * 8 ( % r s i ) ,% r10
.Ld5 : movnti % r11 ,4 * 8 ( % r d i )
.Ld6 : movnti % r8 ,5 * 8 ( % r d i )
.Ld7 : movnti % r9 ,6 * 8 ( % r d i )
.Ld8 : movnti % r10 ,7 * 8 ( % r d i )
dec % r d x
leaq 6 4 ( % r s i ) ,% r s i
leaq 6 4 ( % r d i ) ,% r d i
jns . L l o o p
.p2align 4
.Lhandle_tail :
movl % e c x ,% e d x
andl $ 6 3 ,% e c x
shrl $ 3 ,% e c x
jz . L h a n d l e _ 7
movl $ 8 ,% e b x
.p2align 4
.Lloop_8 :
.Ls9 : movq ( % r s i ) ,% r8
.Ld9 : movnti % r8 ,( % r d i )
decl % e c x
leaq 8 ( % r d i ) ,% r d i
leaq 8 ( % r s i ) ,% r s i
jnz . L l o o p _ 8
.Lhandle_7 :
movl % e d x ,% e c x
andl $ 7 ,% e c x
jz . L e n d e
.p2align 4
.Lloop_1 :
.Ls10 : movb ( % r s i ) ,% b l
.Ld10 : movb % b l ,( % r d i )
incq % r d i
incq % r s i
decl % e c x
jnz . L l o o p _ 1
CFI_ R E M E M B E R _ S T A T E
.Lende :
popq % r c x
CFI_ A D J U S T _ C F A _ O F F S E T - 8
CFI_ R E S T O R E % r c x
popq % r b x
CFI_ A D J U S T _ C F A _ O F F S E T - 8
CFI_ R E S T O R E r b x
2007-10-13 03:06:00 +02:00
sfence
2007-02-13 13:26:19 +01:00
ret
CFI_ R E S T O R E _ S T A T E
# ifdef F I X _ A L I G N M E N T
/* align destination */
.p2align 4
.Lbad_alignment :
movl $ 8 ,% r9 d
subl % e c x ,% r9 d
movl % r9 d ,% e c x
cmpq % r9 ,% r d x
jz . L h a n d l e _ 7
js . L h a n d l e _ 7
.Lalign_1 :
.Ls11 : movb ( % r s i ) ,% b l
.Ld11 : movb % b l ,( % r d i )
incq % r s i
incq % r d i
decl % e c x
jnz . L a l i g n _ 1
subq % r9 ,% r d x
jmp . L a f t e r _ b a d _ a l i g n m e n t
# endif
/* table sorted by exception address */
.section _ _ ex_ t a b l e ," a "
.align 8
.quad .Ls1 , .Ls1e
.quad .Ls2 , .Ls2e
.quad .Ls3 , .Ls3e
.quad .Ls4 , .Ls4e
.quad .Ld1 , .Ls1e
.quad .Ld2 , .Ls2e
.quad .Ld3 , .Ls3e
.quad .Ld4 , .Ls4e
.quad .Ls5 , .Ls5e
.quad .Ls6 , .Ls6e
.quad .Ls7 , .Ls7e
.quad .Ls8 , .Ls8e
.quad .Ld5 , .Ls5e
.quad .Ld6 , .Ls6e
.quad .Ld7 , .Ls7e
.quad .Ld8 , .Ls8e
.quad .Ls9 , .Le_quad
.quad .Ld9 , .Le_quad
.quad .Ls10 , .Le_byte
.quad .Ld10 , .Le_byte
# ifdef F I X _ A L I G N M E N T
.quad .Ls11 , .Lzero_rest
.quad .Ld11 , .Lzero_rest
# endif
.quad .Le5 , .Le_zero
.previous
/ * compute 6 4 - o f f s e t f o r m a i n l o o p . 8 b y t e s a c c u r a c y w i t h e r r o r o n t h e
pessimistic s i d e . t h i s i s g r o s s . i t w o u l d b e b e t t e r t o f i x t h e
interface. * /
/* eax: zero, ebx: 64 */
.Ls1e : addl $ 8 ,% e a x
.Ls2e : addl $ 8 ,% e a x
.Ls3e : addl $ 8 ,% e a x
.Ls4e : addl $ 8 ,% e a x
.Ls5e : addl $ 8 ,% e a x
.Ls6e : addl $ 8 ,% e a x
.Ls7e : addl $ 8 ,% e a x
.Ls8e : addl $ 8 ,% e a x
addq % r b x ,% r d i / * + 6 4 * /
subq % r a x ,% r d i / * c o r r e c t d e s t i n a t i o n w i t h c o m p u t e d o f f s e t * /
shlq $ 6 ,% r d x / * l o o p c o u n t e r * 6 4 ( s t r i d e l e n g t h ) * /
addq % r a x ,% r d x / * a d d o f f s e t t o l o o p c n t * /
andl $ 6 3 ,% e c x / * r e m a i n i n g b y t e s * /
addq % r c x ,% r d x / * a d d t h e m * /
jmp . L z e r o _ r e s t
/* exception on quad word loop in tail handling */
/* ecx: loopcnt/8, %edx: length, rdi: correct */
.Le_quad :
shll $ 3 ,% e c x
andl $ 7 ,% e d x
addl % e c x ,% e d x
/* edx: bytes to zero, rdi: dest, eax:zero */
.Lzero_rest :
cmpl $ 0 ,( % r s p ) / * z e r o f l a g s e t ? * /
jz . L e _ z e r o
movq % r d x ,% r c x
.Le_byte :
xorl % e a x ,% e a x
.Le5 : rep
stosb
/* when there is another exception while zeroing the rest just return */
.Le_zero :
movq % r d x ,% r a x
jmp . L e n d e
CFI_ E N D P R O C
ENDPROC( _ _ c o p y _ u s e r _ n o c a c h e )