2005-04-16 15:20:36 -07:00
/ *
2011-03-18 10:42:11 +01:00
* Copyright 2 0 0 2 , 2 0 0 3 A n d i K l e e n , S u S E L a b s .
*
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 . N o w a r r a n t y f o r a n y t h i n g g i v e n a t a l l .
* /
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 >
# include < a s m / e r r n o . h >
2012-04-20 12:19:51 -07:00
# include < a s m / a s m . h >
2005-04-16 15:20:36 -07:00
/ *
* Checksum 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 .
2011-03-18 10:42:11 +01:00
* On e x c e p t i o n s s r c _ e r r _ p t r o r d s t _ e r r _ p t r i s s e t t o - E F A U L T a n d t h e
2005-04-16 15:20:36 -07:00
* destination i s z e r o e d .
2011-03-18 10:42:11 +01:00
*
2005-04-16 15:20:36 -07:00
* Input
* rdi s o u r c e
* rsi d e s t i n a t i o n
* edx l e n ( 3 2 b i t )
2011-03-18 10:42:11 +01:00
* ecx s u m ( 3 2 b i t )
2005-04-16 15:20:36 -07:00
* r8 s r c _ e r r _ p t r ( i n t )
* r9 d s t _ e r r _ p t r ( i n t )
*
* Output
* eax 6 4 b i t s u m . u n d e f i n e d i n c a s e o f e x c e p t i o n .
2011-03-18 10:42:11 +01:00
*
* Wrappers n e e d t o t a k e c a r e o f v a l i d e x c e p t i o n s u m a n d z e r o i n g .
2005-04-16 15:20:36 -07:00
* They a l s o s h o u l d a l i g n s o u r c e o r d e s t i n a t i o n t o 8 b y t e s .
* /
.macro source
10 :
2012-04-20 12:19:51 -07:00
_ ASM_ E X T A B L E ( 1 0 b , . L b a d _ s o u r c e )
2005-04-16 15:20:36 -07:00
.endm
2011-03-18 10:42:11 +01:00
2005-04-16 15:20:36 -07:00
.macro dest
20 :
2012-04-20 12:19:51 -07:00
_ ASM_ E X T A B L E ( 2 0 b , . L b a d _ d e s t )
2005-04-16 15:20:36 -07:00
.endm
2011-03-18 10:42:11 +01:00
2005-04-16 15:20:36 -07:00
.macro ignore L= . L i g n o r e
30 :
2012-04-20 12:19:51 -07:00
_ ASM_ E X T A B L E ( 3 0 b , \ L )
2005-04-16 15:20:36 -07:00
.endm
2011-03-18 10:42:11 +01:00
2006-09-26 10:52:32 +02:00
ENTRY( c s u m _ p a r t i a l _ c o p y _ g e n e r i c )
CFI_ S T A R T P R O C
2011-03-18 10:42:11 +01:00
cmpl $ 3 * 6 4 , % e d x
jle . L i g n o r e
2005-04-16 15:20:36 -07:00
2011-03-18 10:42:11 +01:00
.Lignore :
subq $ 7 * 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 7 * 8
2011-03-18 10:42:11 +01:00
movq % r b x , 2 * 8 ( % r s p )
2006-09-26 10:52:32 +02:00
CFI_ R E L _ O F F S E T r b x , 2 * 8
2011-03-18 10:42:11 +01:00
movq % r12 , 3 * 8 ( % r s p )
2006-09-26 10:52:32 +02:00
CFI_ R E L _ O F F S E T r12 , 3 * 8
2011-03-18 10:42:11 +01:00
movq % r14 , 4 * 8 ( % r s p )
2006-09-26 10:52:32 +02:00
CFI_ R E L _ O F F S E T r14 , 4 * 8
2011-03-18 10:42:11 +01:00
movq % r13 , 5 * 8 ( % r s p )
2006-09-26 10:52:32 +02:00
CFI_ R E L _ O F F S E T r13 , 5 * 8
2011-03-18 10:42:11 +01:00
movq % r b p , 6 * 8 ( % r s p )
2006-09-26 10:52:32 +02:00
CFI_ R E L _ O F F S E T r b p , 6 * 8
2005-04-16 15:20:36 -07:00
2011-03-18 10:42:11 +01:00
movq % r8 , ( % r s p )
movq % r9 , 1 * 8 ( % r s p )
2005-04-16 15:20:36 -07:00
2011-03-18 10:42:11 +01:00
movl % e c x , % e a x
movl % e d x , % e c x
2005-04-16 15:20:36 -07:00
2011-03-18 10:42:11 +01:00
xorl % r9 d , % r9 d
movq % r c x , % r12
shrq $ 6 , % r12
jz . L h a n d l e _ t a i l / * < 6 4 * /
2005-04-16 15:20:36 -07:00
clc
2011-03-18 10:42:11 +01:00
2005-04-16 15:20:36 -07:00
/* main loop. clear in 64 byte blocks */
/* r9: zero, r8: temp2, rbx: temp1, rax: sum, rcx: saved length */
/* r11: temp3, rdx: temp4, r12 loopcnt */
/* r10: temp5, rbp: temp6, r14 temp7, r13 temp8 */
.p2align 4
.Lloop :
source
2011-03-18 10:42:11 +01:00
movq ( % r d i ) , % r b x
2005-04-16 15:20:36 -07:00
source
2011-03-18 10:42:11 +01:00
movq 8 ( % r d i ) , % r8
2005-04-16 15:20:36 -07:00
source
2011-03-18 10:42:11 +01:00
movq 1 6 ( % r d i ) , % r11
2005-04-16 15:20:36 -07:00
source
2011-03-18 10:42:11 +01:00
movq 2 4 ( % r d i ) , % r d x
2005-04-16 15:20:36 -07:00
source
2011-03-18 10:42:11 +01:00
movq 3 2 ( % r d i ) , % r10
2005-04-16 15:20:36 -07:00
source
2011-03-18 10:42:11 +01:00
movq 4 0 ( % r d i ) , % r b p
2005-04-16 15:20:36 -07:00
source
2011-03-18 10:42:11 +01:00
movq 4 8 ( % r d i ) , % r14
2005-04-16 15:20:36 -07:00
source
2011-03-18 10:42:11 +01:00
movq 5 6 ( % r d i ) , % r13
2005-04-16 15:20:36 -07:00
ignore 2 f
prefetcht0 5 * 6 4 ( % r d i )
2011-03-18 10:42:11 +01:00
2 :
adcq % r b x , % r a x
adcq % r8 , % r a x
adcq % r11 , % r a x
adcq % r d x , % r a x
adcq % r10 , % r a x
adcq % r b p , % r a x
adcq % r14 , % r a x
adcq % r13 , % r a x
2005-04-16 15:20:36 -07:00
decl % r12 d
2011-03-18 10:42:11 +01:00
2005-04-16 15:20:36 -07:00
dest
2011-03-18 10:42:11 +01:00
movq % r b x , ( % r s i )
2005-04-16 15:20:36 -07:00
dest
2011-03-18 10:42:11 +01:00
movq % r8 , 8 ( % r s i )
2005-04-16 15:20:36 -07:00
dest
2011-03-18 10:42:11 +01:00
movq % r11 , 1 6 ( % r s i )
2005-04-16 15:20:36 -07:00
dest
2011-03-18 10:42:11 +01:00
movq % r d x , 2 4 ( % r s i )
2005-04-16 15:20:36 -07:00
dest
2011-03-18 10:42:11 +01:00
movq % r10 , 3 2 ( % r s i )
2005-04-16 15:20:36 -07:00
dest
2011-03-18 10:42:11 +01:00
movq % r b p , 4 0 ( % r s i )
2005-04-16 15:20:36 -07:00
dest
2011-03-18 10:42:11 +01:00
movq % r14 , 4 8 ( % r s i )
2005-04-16 15:20:36 -07:00
dest
2011-03-18 10:42:11 +01:00
movq % r13 , 5 6 ( % r s i )
2005-04-16 15:20:36 -07:00
3 :
2011-03-18 10:42:11 +01:00
leaq 6 4 ( % r d i ) , % r d i
leaq 6 4 ( % r s i ) , % r s i
2005-04-16 15:20:36 -07:00
2011-03-18 10:42:11 +01:00
jnz . L l o o p
adcq % r9 , % r a x
2005-04-16 15:20:36 -07:00
2011-03-17 16:24:16 -03:00
/* do last up to 56 bytes */
2005-04-16 15:20:36 -07:00
.Lhandle_tail :
/* ecx: count */
2011-03-18 10:42:11 +01:00
movl % e c x , % r10 d
andl $ 6 3 , % e c x
shrl $ 3 , % e c x
jz . L f o l d
2005-04-16 15:20:36 -07:00
clc
.p2align 4
2011-03-18 10:42:11 +01:00
.Lloop_8 :
2005-04-16 15:20:36 -07:00
source
2011-03-18 10:42:11 +01:00
movq ( % r d i ) , % r b x
adcq % r b x , % r a x
2005-04-16 15:20:36 -07:00
decl % e c x
dest
2011-03-18 10:42:11 +01:00
movq % r b x , ( % r s i )
leaq 8 ( % r s i ) , % r s i / * p r e s e r v e c a r r y * /
leaq 8 ( % r d i ) , % r d i
2005-04-16 15:20:36 -07:00
jnz . L l o o p _ 8
2011-03-18 10:42:11 +01:00
adcq % r9 , % r a x / * a d d i n c a r r y * /
2005-04-16 15:20:36 -07:00
.Lfold :
/* reduce checksum to 32bits */
2011-03-18 10:42:11 +01:00
movl % e a x , % e b x
shrq $ 3 2 , % r a x
addl % e b x , % e a x
adcl % r9 d , % e a x
2005-04-16 15:20:36 -07:00
2011-03-18 10:42:11 +01:00
/* do last up to 6 bytes */
2005-04-16 15:20:36 -07:00
.Lhandle_7 :
2011-03-18 10:42:11 +01:00
movl % r10 d , % e c x
andl $ 7 , % e c x
shrl $ 1 , % e c x
2005-04-16 15:20:36 -07:00
jz . L h a n d l e _ 1
2011-03-18 10:42:11 +01:00
movl $ 2 , % e d x
xorl % e b x , % e b x
clc
2005-04-16 15:20:36 -07:00
.p2align 4
2011-03-18 10:42:11 +01:00
.Lloop_1 :
2005-04-16 15:20:36 -07:00
source
2011-03-18 10:42:11 +01:00
movw ( % r d i ) , % b x
adcl % e b x , % e a x
2005-04-16 15:20:36 -07:00
decl % e c x
2005-07-29 22:59:20 -07:00
dest
2011-03-18 10:42:11 +01:00
movw % b x , ( % r s i )
leaq 2 ( % r d i ) , % r d i
leaq 2 ( % r s i ) , % r s i
2005-04-16 15:20:36 -07:00
jnz . L l o o p _ 1
2011-03-18 10:42:11 +01:00
adcl % r9 d , % e a x / * a d d i n c a r r y * /
2005-04-16 15:20:36 -07:00
/* handle last odd byte */
.Lhandle_1 :
2011-03-18 10:42:11 +01:00
testl $ 1 , % r10 d
2005-04-16 15:20:36 -07:00
jz . L e n d e
2011-03-18 10:42:11 +01:00
xorl % e b x , % e b x
2005-04-16 15:20:36 -07:00
source
2011-03-18 10:42:11 +01:00
movb ( % r d i ) , % b l
2005-04-16 15:20:36 -07:00
dest
2011-03-18 10:42:11 +01:00
movb % b l , ( % r s i )
addl % e b x , % e a x
adcl % r9 d , % e a x / * c a r r y * /
2006-09-26 10:52:32 +02:00
CFI_ R E M E M B E R _ S T A T E
2005-04-16 15:20:36 -07:00
.Lende :
2011-03-18 10:42:11 +01:00
movq 2 * 8 ( % 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
2011-03-18 10:42:11 +01:00
movq 3 * 8 ( % r s p ) , % r12
2006-09-26 10:52:32 +02:00
CFI_ R E S T O R E r12
2011-03-18 10:42:11 +01:00
movq 4 * 8 ( % r s p ) , % r14
2006-09-26 10:52:32 +02:00
CFI_ R E S T O R E r14
2011-03-18 10:42:11 +01:00
movq 5 * 8 ( % r s p ) , % r13
2006-09-26 10:52:32 +02:00
CFI_ R E S T O R E r13
2011-03-18 10:42:11 +01:00
movq 6 * 8 ( % r s p ) , % r b p
2006-09-26 10:52:32 +02:00
CFI_ R E S T O R E r b p
2011-03-18 10:42:11 +01:00
addq $ 7 * 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 - 7 * 8
2005-04-16 15:20:36 -07:00
ret
2006-09-26 10:52:32 +02:00
CFI_ R E S T O R E _ S T A T E
2005-04-16 15:20:36 -07:00
/* Exception handlers. Very simple, zeroing is done in the wrappers */
.Lbad_source :
2011-03-18 10:42:11 +01:00
movq ( % r s p ) , % r a x
testq % r a x , % r a x
2005-04-16 15:20:36 -07:00
jz . L e n d e
2011-03-18 10:42:11 +01:00
movl $ - E F A U L T , ( % r a x )
2005-04-16 15:20:36 -07:00
jmp . L e n d e
2011-03-18 10:42:11 +01:00
2005-04-16 15:20:36 -07:00
.Lbad_dest :
2011-03-18 10:42:11 +01:00
movq 8 ( % r s p ) , % r a x
testq % r a x , % r a x
jz . L e n d e
movl $ - E F A U L T , ( % r a x )
2005-04-16 15:20:36 -07:00
jmp . L e n d e
2006-09-26 10:52:32 +02:00
CFI_ E N D P R O C
ENDPROC( c s u m _ p a r t i a l _ c o p y _ g e n e r i c )