2005-04-17 02:20:36 +04:00
/ *
* INET A n i m p l e m e n t a t i o n o f t h e T C P / I P p r o t o c o l s u i t e f o r t h e L I N U X
* operating s y s t e m . I N E T i s i m p l e m e n t e d u s i n g t h e B S D S o c k e t
* interface a s t h e m e a n s o f c o m m u n i c a t i o n w i t h t h e u s e r l e v e l .
*
* IP/ T C P / U D P c h e c k s u m m i n g r o u t i n e s
*
* Authors : Jorge C w i k , < j o r g e @laser.satlink.net>
* Arnt G u l b r a n d s e n , < a g u l b r a @nvg.unit.no>
* Tom M a y , < f t o m @netcom.com>
* Pentium P r o / I I r o u t i n e s :
* Alexander K j e l d a a s < a s t o r @guardian.no>
* Finn A r n e G a n g s t a d < f i n n a g @guardian.no>
* Lots o f c o d e m o v e d f r o m t c p . c a n d i p . c ; see those files
* for m o r e n a m e s .
*
* Changes : Ingo M o l n a r , c o n v e r t e d c s u m _ p a r t i a l _ c o p y ( ) t o 2 . 1 e x c e p t i o n
* handling.
* Andi K l e e n , a d d z e r o i n g o n e r r o r
* converted t o p u r e a s s e m b l e r
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or
* modify i t u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e
* as p u b l i s h e d b y t h e F r e e S o f t w a r e F o u n d a t i o n ; either version
* 2 of t h e L i c e n s e , o r ( a t y o u r o p t i o n ) a n y l a t e r v e r s i o n .
* /
# include < a s m / e r r n o . h >
/ *
* computes a p a r t i a l c h e c k s u m , e . g . f o r T C P / U D P f r a g m e n t s
* /
/ *
unsigned i n t c s u m _ p a r t i a l ( c o n s t u n s i g n e d c h a r * b u f f , i n t l e n , u n s i g n e d i n t s u m )
* /
.text
.align 4
2005-05-06 03:15:36 +04:00
.globl csum_partial
2005-04-17 02:20:36 +04:00
# ifndef C O N F I G _ X 8 6 _ U S E _ P P R O _ C H E C K S U M
/ *
* Experiments w i t h E t h e r n e t a n d S L I P c o n n e c t i o n s s h o w t h a t b u f f
* is a l i g n e d o n e i t h e r a 2 - b y t e o r 4 - b y t e b o u n d a r y . W e g e t a t
* least a t w o f o l d s p e e d u p o n 4 8 6 a n d P e n t i u m i f i t i s 4 - b y t e a l i g n e d .
* Fortunately, i t i s e a s y t o c o n v e r t 2 - b y t e a l i g n m e n t t o 4 - b y t e
* alignment f o r t h e u n r o l l e d l o o p .
* /
2005-05-06 03:15:36 +04:00
csum_partial :
2005-04-17 02:20:36 +04:00
pushl % e s i
pushl % e b x
movl 2 0 ( % e s p ) ,% e a x # F u n c t i o n a r g : u n s i g n e d i n t s u m
movl 1 6 ( % e s p ) ,% e c x # F u n c t i o n a r g : i n t l e n
movl 1 2 ( % e s p ) ,% e s i # F u n c t i o n a r g : u n s i g n e d c h a r * b u f f
testl $ 2 , % e s i # C h e c k a l i g n m e n t .
jz 2 f # J u m p i f a l i g n m e n t i s o k .
subl $ 2 , % e c x # A l i g n m e n t u s e s u p t w o b y t e s .
jae 1 f # J u m p i f w e h a d a t l e a s t t w o b y t e s .
addl $ 2 , % e c x # e c x w a s < 2 . D e a l w i t h i t .
jmp 4 f
1 : movw ( % e s i ) , % b x
addl $ 2 , % e s i
addw % b x , % a x
adcl $ 0 , % e a x
2 :
movl % e c x , % e d x
shrl $ 5 , % e c x
jz 2 f
testl % e s i , % e s i
1 : movl ( % e s i ) , % e b x
adcl % e b x , % e a x
movl 4 ( % e s i ) , % e b x
adcl % e b x , % e a x
movl 8 ( % e s i ) , % e b x
adcl % e b x , % e a x
movl 1 2 ( % e s i ) , % e b x
adcl % e b x , % e a x
movl 1 6 ( % e s i ) , % e b x
adcl % e b x , % e a x
movl 2 0 ( % e s i ) , % e b x
adcl % e b x , % e a x
movl 2 4 ( % e s i ) , % e b x
adcl % e b x , % e a x
movl 2 8 ( % e s i ) , % e b x
adcl % e b x , % e a x
lea 3 2 ( % e s i ) , % e s i
dec % e c x
jne 1 b
adcl $ 0 , % e a x
2 : movl % e d x , % e c x
andl $ 0 x1 c , % e d x
je 4 f
shrl $ 2 , % e d x # T h i s c l e a r s C F
3 : adcl ( % e s i ) , % e a x
lea 4 ( % e s i ) , % e s i
dec % e d x
jne 3 b
adcl $ 0 , % e a x
4 : andl $ 3 , % e c x
jz 7 f
cmpl $ 2 , % e c x
jb 5 f
movw ( % e s i ) ,% c x
leal 2 ( % e s i ) ,% e s i
je 6 f
shll $ 1 6 ,% e c x
5 : movb ( % e s i ) ,% c l
6 : addl % e c x ,% e a x
adcl $ 0 , % e a x
7 :
popl % e b x
popl % e s i
ret
# else
/* Version for PentiumII/PPro */
2005-05-06 03:15:36 +04:00
csum_partial :
2005-04-17 02:20:36 +04:00
pushl % e s i
pushl % e b x
movl 2 0 ( % e s p ) ,% e a x # F u n c t i o n a r g : u n s i g n e d i n t s u m
movl 1 6 ( % e s p ) ,% e c x # F u n c t i o n a r g : i n t l e n
movl 1 2 ( % e s p ) ,% e s i # F u n c t i o n a r g : c o n s t u n s i g n e d c h a r * b u f
testl $ 2 , % e s i
jnz 3 0 f
10 :
movl % e c x , % e d x
movl % e c x , % e b x
andl $ 0 x7 c , % e b x
shrl $ 7 , % e c x
addl % e b x ,% e s i
shrl $ 2 , % e b x
negl % e b x
lea 4 5 f ( % e b x ,% e b x ,2 ) , % e b x
testl % e s i , % e s i
jmp * % e b x
# Handle 2 - b y t e - a l i g n e d r e g i o n s
20 : addw ( % e s i ) , % a x
lea 2 ( % e s i ) , % e s i
adcl $ 0 , % e a x
jmp 1 0 b
30 : subl $ 2 , % e c x
ja 2 0 b
je 3 2 f
movzbl ( % e s i ) ,% e b x # c s u m m i n g 1 b y t e , 2 - a l i g n e d
addl % e b x , % e a x
adcl $ 0 , % e a x
jmp 8 0 f
32 :
addw ( % e s i ) , % a x # c s u m m i n g 2 b y t e s , 2 - a l i g n e d
adcl $ 0 , % e a x
jmp 8 0 f
40 :
addl - 1 2 8 ( % e s i ) , % e a x
adcl - 1 2 4 ( % e s i ) , % e a x
adcl - 1 2 0 ( % e s i ) , % e a x
adcl - 1 1 6 ( % e s i ) , % e a x
adcl - 1 1 2 ( % e s i ) , % e a x
adcl - 1 0 8 ( % e s i ) , % e a x
adcl - 1 0 4 ( % e s i ) , % e a x
adcl - 1 0 0 ( % e s i ) , % e a x
adcl - 9 6 ( % e s i ) , % e a x
adcl - 9 2 ( % e s i ) , % e a x
adcl - 8 8 ( % e s i ) , % e a x
adcl - 8 4 ( % e s i ) , % e a x
adcl - 8 0 ( % e s i ) , % e a x
adcl - 7 6 ( % e s i ) , % e a x
adcl - 7 2 ( % e s i ) , % e a x
adcl - 6 8 ( % e s i ) , % e a x
adcl - 6 4 ( % e s i ) , % e a x
adcl - 6 0 ( % e s i ) , % e a x
adcl - 5 6 ( % e s i ) , % e a x
adcl - 5 2 ( % e s i ) , % e a x
adcl - 4 8 ( % e s i ) , % e a x
adcl - 4 4 ( % e s i ) , % e a x
adcl - 4 0 ( % e s i ) , % e a x
adcl - 3 6 ( % e s i ) , % e a x
adcl - 3 2 ( % e s i ) , % e a x
adcl - 2 8 ( % e s i ) , % e a x
adcl - 2 4 ( % e s i ) , % e a x
adcl - 2 0 ( % e s i ) , % e a x
adcl - 1 6 ( % e s i ) , % e a x
adcl - 1 2 ( % e s i ) , % e a x
adcl - 8 ( % e s i ) , % e a x
adcl - 4 ( % e s i ) , % e a x
45 :
lea 1 2 8 ( % e s i ) , % e s i
adcl $ 0 , % e a x
dec % e c x
jge 4 0 b
movl % e d x , % e c x
50 : andl $ 3 , % e c x
jz 8 0 f
# Handle t h e l a s t 1 - 3 b y t e s w i t h o u t j u m p i n g
notl % e c x # 1 - > 2 , 2 - > 1 , 3 - > 0 , h i g h e r b i t s a r e m a s k e d
movl $ 0 x f f f f f f ,% e b x # b y t h e s h l l a n d s h r l i n s t r u c t i o n s
shll $ 3 ,% e c x
shrl % c l ,% e b x
andl - 1 2 8 ( % e s i ) ,% e b x # e s i i s 4 - a l i g n e d s o s h o u l d b e o k
addl % e b x ,% e a x
adcl $ 0 ,% e a x
80 :
popl % e b x
popl % e s i
ret
# endif
/ *
unsigned i n t c s u m _ p a r t i a l _ c o p y _ g e n e r i c ( c o n s t c h a r * s r c , c h a r * d s t ,
int l e n , i n t s u m , i n t * s r c _ e r r _ p t r , i n t * d s t _ e r r _ p t r )
* /
/ *
* Copy f r o m d s w h i l e c h e c k s u m m i n g , o t h e r w i s e l i k e c s u m _ p a r t i a l
*
* The m a c r o s S R C a n d D S T s p e c i f y t h e t y p e o f a c c e s s f o r t h e i n s t r u c t i o n .
* thus w e c a n c a l l a c u s t o m e x c e p t i o n h a n d l e r f o r a l l a c c e s s t y p e s .
*
* FIXME : could s o m e o n e d o u b l e - c h e c k w h e t h e r I h a v e n ' t m i x e d u p s o m e S R C a n d
* DST d e f i n i t i o n s ? I t ' s d a m n h a r d t o t r i g g e r a l l c a s e s . I h o p e I g o t
* them a l l b u t t h e r e ' s n o g u a r a n t e e .
* /
# define S R C ( y . . . ) \
9999 : y; \
.section _ _ ex_ t a b l e , " a " ; \
.long 9 9 9 9 b, 6 0 0 1 f ; \
.previous
# define D S T ( y . . . ) \
9999 : y; \
.section _ _ ex_ t a b l e , " a " ; \
.long 9 9 9 9 b, 6 0 0 2 f ; \
.previous
.align 4
2008-07-24 08:28:49 +04:00
2005-04-17 02:20:36 +04:00
# ifndef C O N F I G _ X 8 6 _ U S E _ P P R O _ C H E C K S U M
# define A R G B A S E 1 6
# define F P 1 2
2008-07-24 08:28:49 +04:00
2005-04-17 02:20:36 +04:00
csum_partial_copy_generic_i386 :
subl $ 4 ,% e s p
pushl % e d i
pushl % e s i
pushl % e b x
movl A R G B A S E + 1 6 ( % e s p ) ,% e a x # s u m
movl A R G B A S E + 1 2 ( % e s p ) ,% e c x # l e n
movl A R G B A S E + 4 ( % e s p ) ,% e s i # s r c
movl A R G B A S E + 8 ( % e s p ) ,% e d i # d s t
testl $ 2 , % e d i # C h e c k a l i g n m e n t .
jz 2 f # J u m p i f a l i g n m e n t i s o k .
subl $ 2 , % e c x # A l i g n m e n t u s e s u p t w o b y t e s .
jae 1 f # J u m p i f w e h a d a t l e a s t t w o b y t e s .
addl $ 2 , % e c x # e c x w a s < 2 . D e a l w i t h i t .
jmp 4 f
SRC( 1 : m o v w ( % e s i ) , % b x )
addl $ 2 , % e s i
DST( m o v w % b x , ( % e d i ) )
addl $ 2 , % e d i
addw % b x , % a x
adcl $ 0 , % e a x
2 :
movl % e c x , F P ( % e s p )
shrl $ 5 , % e c x
jz 2 f
testl % e s i , % e s i
SRC( 1 : m o v l ( % e s i ) , % e b x )
SRC( m o v l 4 ( % e s i ) , % e d x )
adcl % e b x , % e a x
DST( m o v l % e b x , ( % e d i ) )
adcl % e d x , % e a x
DST( m o v l % e d x , 4 ( % e d i ) )
SRC( m o v l 8 ( % e s i ) , % e b x )
SRC( m o v l 1 2 ( % e s i ) , % e d x )
adcl % e b x , % e a x
DST( m o v l % e b x , 8 ( % e d i ) )
adcl % e d x , % e a x
DST( m o v l % e d x , 1 2 ( % e d i ) )
SRC( m o v l 1 6 ( % e s i ) , % e b x )
SRC( m o v l 2 0 ( % e s i ) , % e d x )
adcl % e b x , % e a x
DST( m o v l % e b x , 1 6 ( % e d i ) )
adcl % e d x , % e a x
DST( m o v l % e d x , 2 0 ( % e d i ) )
SRC( m o v l 2 4 ( % e s i ) , % e b x )
SRC( m o v l 2 8 ( % e s i ) , % e d x )
adcl % e b x , % e a x
DST( m o v l % e b x , 2 4 ( % e d i ) )
adcl % e d x , % e a x
DST( m o v l % e d x , 2 8 ( % e d i ) )
lea 3 2 ( % e s i ) , % e s i
lea 3 2 ( % e d i ) , % e d i
dec % e c x
jne 1 b
adcl $ 0 , % e a x
2 : movl F P ( % e s p ) , % e d x
movl % e d x , % e c x
andl $ 0 x1 c , % e d x
je 4 f
shrl $ 2 , % e d x # T h i s c l e a r s C F
SRC( 3 : m o v l ( % e s i ) , % e b x )
adcl % e b x , % e a x
DST( m o v l % e b x , ( % e d i ) )
lea 4 ( % e s i ) , % e s i
lea 4 ( % e d i ) , % e d i
dec % e d x
jne 3 b
adcl $ 0 , % e a x
4 : andl $ 3 , % e c x
jz 7 f
cmpl $ 2 , % e c x
jb 5 f
SRC( m o v w ( % e s i ) , % c x )
leal 2 ( % e s i ) , % e s i
DST( m o v w % c x , ( % e d i ) )
leal 2 ( % e d i ) , % e d i
je 6 f
shll $ 1 6 ,% e c x
SRC( 5 : m o v b ( % e s i ) , % c l )
DST( m o v b % c l , ( % e d i ) )
6 : addl % e c x , % e a x
adcl $ 0 , % e a x
7 :
5000 :
# Exception h a n d l e r :
.section .fixup , " ax"
6001 :
movl A R G B A S E + 2 0 ( % e s p ) , % e b x # s r c _ e r r _ p t r
movl $ - E F A U L T , ( % e b x )
# zero t h e c o m p l e t e d e s t i n a t i o n - c o m p u t i n g t h e r e s t
# is t o o m u c h w o r k
movl A R G B A S E + 8 ( % e s p ) , % e d i # d s t
movl A R G B A S E + 1 2 ( % e s p ) , % e c x # l e n
xorl % e a x ,% e a x
rep ; stosb
jmp 5 0 0 0 b
6002 :
movl A R G B A S E + 2 4 ( % e s p ) , % e b x # d s t _ e r r _ p t r
movl $ - E F A U L T ,( % e b x )
jmp 5 0 0 0 b
.previous
popl % e b x
popl % e s i
popl % e d i
popl % e c x # e q u i v a l e n t t o a d d l $ 4 ,% e s p
ret
# else
/* Version for PentiumII/PPro */
# define R O U N D 1 ( x ) \
SRC( m o v l x ( % e s i ) , % e b x ) ; \
addl % e b x , % e a x ; \
DST( m o v l % e b x , x ( % e d i ) ) ;
# define R O U N D ( x ) \
SRC( m o v l x ( % e s i ) , % e b x ) ; \
adcl % e b x , % e a x ; \
DST( m o v l % e b x , x ( % e d i ) ) ;
# define A R G B A S E 1 2
csum_partial_copy_generic_i386 :
pushl % e b x
pushl % e d i
pushl % e s i
movl A R G B A S E + 4 ( % e s p ) ,% e s i #s r c
movl A R G B A S E + 8 ( % e s p ) ,% e d i #d s t
movl A R G B A S E + 1 2 ( % e s p ) ,% e c x #l e n
movl A R G B A S E + 1 6 ( % e s p ) ,% e a x #s u m
# movl % e c x , % e d x
movl % e c x , % e b x
movl % e s i , % e d x
shrl $ 6 , % e c x
andl $ 0 x3 c , % e b x
negl % e b x
subl % e b x , % e s i
subl % e b x , % e d i
lea - 1 ( % e s i ) ,% e d x
andl $ - 3 2 ,% e d x
lea 3 f ( % e b x ,% e b x ) , % e b x
testl % e s i , % e s i
jmp * % e b x
1 : addl $ 6 4 ,% e s i
addl $ 6 4 ,% e d i
SRC( m o v b - 3 2 ( % e d x ) ,% b l ) ; SRC(movb (%edx),%bl)
ROUND1 ( - 6 4 ) R O U N D ( - 6 0 ) R O U N D ( - 5 6 ) R O U N D ( - 5 2 )
ROUND ( - 4 8 ) R O U N D ( - 4 4 ) R O U N D ( - 4 0 ) R O U N D ( - 3 6 )
ROUND ( - 3 2 ) R O U N D ( - 2 8 ) R O U N D ( - 2 4 ) R O U N D ( - 2 0 )
ROUND ( - 1 6 ) R O U N D ( - 1 2 ) R O U N D ( - 8 ) R O U N D ( - 4 )
3 : adcl $ 0 ,% e a x
addl $ 6 4 , % e d x
dec % e c x
jge 1 b
4 : movl A R G B A S E + 1 2 ( % e s p ) ,% e d x #l e n
andl $ 3 , % e d x
jz 7 f
cmpl $ 2 , % e d x
jb 5 f
SRC( m o v w ( % e s i ) , % d x )
leal 2 ( % e s i ) , % e s i
DST( m o v w % d x , ( % e d i ) )
leal 2 ( % e d i ) , % e d i
je 6 f
shll $ 1 6 ,% e d x
5 :
SRC( m o v b ( % e s i ) , % d l )
DST( m o v b % d l , ( % e d i ) )
6 : addl % e d x , % e a x
adcl $ 0 , % e a x
7 :
.section .fixup , " ax"
6001 : movl A R G B A S E + 2 0 ( % e s p ) , % e b x # s r c _ e r r _ p t r
movl $ - E F A U L T , ( % e b x )
# zero t h e c o m p l e t e d e s t i n a t i o n ( c o m p u t i n g t h e r e s t i s t o o m u c h w o r k )
movl A R G B A S E + 8 ( % e s p ) ,% e d i # d s t
movl A R G B A S E + 1 2 ( % e s p ) ,% e c x # l e n
xorl % e a x ,% e a x
rep; stosb
jmp 7 b
6002 : movl A R G B A S E + 2 4 ( % e s p ) , % e b x # d s t _ e r r _ p t r
movl $ - E F A U L T , ( % e b x )
jmp 7 b
.previous
popl % e s i
popl % e d i
popl % e b x
ret
# undef R O U N D
# undef R O U N D 1
# endif