2018-12-28 00:32:28 -08:00
/ * SPDX- L i c e n s e - I d e n t i f i e r : G P L - 2 . 0 +
*
* $ Id : checksum. S ,v 1 . 1 0 2 0 0 1 / 0 7 / 0 6 1 3 : 1 1 : 3 2 g n i i b e E x p $
2005-04-16 15:20:36 -07: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
*
* SuperH v e r s i o n : C o p y r i g h t ( C ) 1 9 9 9 N i i b e Y u t a k a
* /
# include < a s m / e r r n o . h >
# include < l i n u x / l i n k a g e . 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
* /
/ *
2008-12-12 18:34:38 +00:00
* asmlinkage _ _ w s u m c s u m _ p a r t i a l ( c o n s t v o i d * b u f , i n t l e n , _ _ w s u m s u m ) ;
2005-04-16 15:20:36 -07:00
* /
.text
ENTRY( c s u m _ p a r t i a l )
/ *
* 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 .
* /
mov r4 , r0
2008-12-12 18:34:38 +00:00
tst #3 , r0 ! C h e c k a l i g n m e n t .
bt/ s 2 f ! J u m p i f a l i g n m e n t i s o k .
mov r4 , r7 ! K e e p a c o p y t o c h e c k f o r a l i g n m e n t
2005-04-16 15:20:36 -07:00
!
2008-12-12 18:34:38 +00:00
tst #1 , r0 ! C h e c k a l i g n m e n t .
bt 2 1 f ! J u m p i f a l i g n m e n t i s b o u n d a r y o f 2 b y t e s .
! buf i s o d d
tst r5 , r5
add #- 1 , r5
bt 9 f
mov. b @r4+, r0
extu. b r0 , r0
addc r0 , r6 ! t =0 f r o m p r e v i o u s t s t
mov r6 , r0
shll8 r6
shlr1 6 r0
shlr8 r0
or r0 , r6
mov r4 , r0
tst #2 , r0
bt 2 f
21 :
! buf i s 2 b y t e a l i g n e d ( l e n c o u l d b e 0 )
2005-04-16 15:20:36 -07:00
add #- 2 , r5 ! A l i g n m e n t u s e s u p t w o b y t e s .
cmp/ p z r5 !
bt/ s 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 .
clrt
bra 6 f
add #2 , r5 ! r5 w a s < 2 . D e a l w i t h i t .
1 :
mov. w @r4+, r0
extu. w r0 , r0
addc r0 , r6
bf 2 f
add #1 , r6
2 :
2008-12-12 18:34:38 +00:00
! buf i s 4 b y t e a l i g n e d ( l e n c o u l d b e 0 )
mov r5 , r1
2005-04-16 15:20:36 -07:00
mov #- 5 , r0
2008-12-12 18:34:38 +00:00
shld r0 , r1
tst r1 , r1
2005-04-16 15:20:36 -07:00
bt/ s 4 f ! i f i t ' s =0 , g o t o 4 f
clrt
.align 2
3 :
mov. l @r4+, r0
mov. l @r4+, r2
mov. l @r4+, r3
addc r0 , r6
mov. l @r4+, r0
addc r2 , r6
mov. l @r4+, r2
addc r3 , r6
mov. l @r4+, r3
addc r0 , r6
mov. l @r4+, r0
addc r2 , r6
mov. l @r4+, r2
addc r3 , r6
addc r0 , r6
addc r2 , r6
movt r0
2008-12-12 18:34:38 +00:00
dt r1
2005-04-16 15:20:36 -07:00
bf/ s 3 b
cmp/ e q #1 , r0
2008-12-12 18:34:38 +00:00
! here, w e k n o w r1 = =0
addc r1 , r6 ! a d d c a r r y t o r6
2005-04-16 15:20:36 -07:00
4 :
2008-12-12 18:34:38 +00:00
mov r5 , r0
2005-04-16 15:20:36 -07:00
and #0x1c , r0
tst r0 , r0
2008-12-12 18:34:38 +00:00
bt 6 f
! 4 bytes o r m o r e r e m a i n i n g
mov r0 , r1
shlr2 r1
2005-04-16 15:20:36 -07:00
mov #0 , r2
5 :
addc r2 , r6
mov. l @r4+, r2
movt r0
2008-12-12 18:34:38 +00:00
dt r1
2005-04-16 15:20:36 -07:00
bf/ s 5 b
cmp/ e q #1 , r0
addc r2 , r6
2008-12-12 18:34:38 +00:00
addc r1 , r6 ! r1 = =0 h e r e , s o i t m e a n s a d d c a r r y - b i t
2005-04-16 15:20:36 -07:00
6 :
2008-12-12 18:34:38 +00:00
! 3 bytes o r l e s s r e m a i n i n g
2005-04-16 15:20:36 -07:00
mov #3 , r0
and r0 , r5
tst r5 , r5
bt 9 f ! i f i t ' s =0 g o t o 9 f
mov #2 , r1
cmp/ h s r1 , r5
bf 7 f
mov. w @r4+, r0
extu. w r0 , r0
cmp/ e q r1 , r5
bt/ s 8 f
clrt
shll1 6 r0
addc r0 , r6
7 :
mov. b @r4+, r0
extu. b r0 , r0
# ifndef _ _ L I T T L E _ E N D I A N _ _
shll8 r0
# endif
8 :
addc r0 , r6
mov #0 , r0
2008-12-12 18:34:38 +00:00
addc r0 , r6
2005-04-16 15:20:36 -07:00
9 :
2008-12-12 18:34:38 +00:00
! Check i f t h e b u f f e r w a s m i s a l i g n e d , i f s o r e a l i g n s u m
mov r7 , r0
tst #1 , r0
bt 1 0 f
mov r6 , r0
shll8 r6
shlr1 6 r0
shlr8 r0
or r0 , r6
10 :
2005-04-16 15:20:36 -07:00
rts
mov r6 , r0
/ *
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 , i n t l e n ,
int 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 ( . . . ) \
9999 : _ _ VA_ A R G S _ _ ; \
.section _ _ ex_ t a b l e , " a " ; \
.long 9 9 9 9 b, 6 0 0 1 f ; \
.previous
# define D S T ( . . . ) \
9999 : _ _ VA_ A R G S _ _ ; \
.section _ _ ex_ t a b l e , " a " ; \
.long 9 9 9 9 b, 6 0 0 2 f ; \
.previous
!
! r4 : const c h a r * S R C
! r5 : char * D S T
! r6 : int L E N
! r7 : int S U M
!
! on s t a c k :
! int * S R C _ E R R _ P T R
! int * D S T _ E R R _ P T R
!
ENTRY( c s u m _ p a r t i a l _ c o p y _ g e n e r i c )
mov. l r5 ,@-r15
mov. l r6 ,@-r15
mov #3 ,r0 ! C h e c k s r c a n d d e s t a r e e q u a l l y a l i g n e d
mov r4 ,r1
and r0 ,r1
and r5 ,r0
cmp/ e q r1 ,r0
bf 3 f ! D i f f e r e n t a l i g n m e n t s , u s e s l o w v e r s i o n
tst #1 ,r0 ! C h e c k d e s t w o r d a l i g n e d
bf 3 f ! I f n o t , d o i t t h e s l o w w a y
mov #2 ,r0
tst r0 ,r5 ! C h e c k d e s t a l i g n m e n t .
bt 2 f ! J u m p i f a l i g n m e n t i s o k .
add #- 2 ,r6 ! A l i g n m e n t u s e s u p t w o b y t e s .
cmp/ p z r6 ! 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 .
bt/ s 1 f
clrt
2006-09-27 14:46:24 +09:00
add #2 ,r6 ! r6 w a s < 2 . D e a l w i t h i t .
2005-04-16 15:20:36 -07:00
bra 4 f
2006-09-27 14:46:24 +09:00
mov r6 ,r2
2005-04-16 15:20:36 -07:00
3 : ! Handle d i f f e r e n t s r c a n d d e s t a l i g n m e n t s .
! This i s n o t c o m m o n , s o s i m p l e b y t e b y b y t e c o p y w i l l d o .
mov r6 ,r2
shlr r6
tst r6 ,r6
bt 4 f
clrt
.align 2
5 :
SRC( m o v . b @r4+,r1 )
SRC( m o v . b @r4+,r0 )
extu. b r1 ,r1
DST( m o v . b r1 ,@r5 )
DST( m o v . b r0 ,@(1,r5) )
extu. b r0 ,r0
add #2 ,r5
# ifdef _ _ L I T T L E _ E N D I A N _ _
shll8 r0
# else
shll8 r1
# endif
or r1 ,r0
addc r0 ,r7
movt r0
dt r6
bf/ s 5 b
cmp/ e q #1 ,r0
mov #0 ,r0
addc r0 , r7
mov r2 , r0
tst #1 , r0
bt 7 f
bra 5 f
clrt
! src a n d d e s t e q u a l l y a l i g n e d , b u t t o a t w o b y t e b o u n d a r y .
! Handle f i r s t t w o b y t e s a s a s p e c i a l c a s e
.align 2
1 :
SRC( m o v . w @r4+,r0 )
DST( m o v . w r0 ,@r5 )
add #2 ,r5
extu. w r0 ,r0
addc r0 ,r7
mov #0 ,r0
addc r0 ,r7
2 :
mov r6 ,r2
mov #- 5 ,r0
shld r0 ,r6
tst r6 ,r6
bt/ s 2 f
clrt
.align 2
1 :
SRC( m o v . l @r4+,r0 )
SRC( m o v . l @r4+,r1 )
addc r0 ,r7
DST( m o v . l r0 ,@r5 )
DST( m o v . l r1 ,@(4,r5) )
addc r1 ,r7
SRC( m o v . l @r4+,r0 )
SRC( m o v . l @r4+,r1 )
addc r0 ,r7
DST( m o v . l r0 ,@(8,r5) )
DST( m o v . l r1 ,@(12,r5) )
addc r1 ,r7
SRC( m o v . l @r4+,r0 )
SRC( m o v . l @r4+,r1 )
addc r0 ,r7
DST( m o v . l r0 ,@(16,r5) )
DST( m o v . l r1 ,@(20,r5) )
addc r1 ,r7
SRC( m o v . l @r4+,r0 )
SRC( m o v . l @r4+,r1 )
addc r0 ,r7
DST( m o v . l r0 ,@(24,r5) )
DST( m o v . l r1 ,@(28,r5) )
addc r1 ,r7
add #32 ,r5
movt r0
dt r6
bf/ s 1 b
cmp/ e q #1 ,r0
mov #0 ,r0
addc r0 ,r7
2 : mov r2 ,r6
mov #0x1c ,r0
and r0 ,r6
cmp/ p l r6
bf/ s 4 f
clrt
shlr2 r6
3 :
SRC( m o v . l @r4+,r0 )
addc r0 ,r7
DST( m o v . l r0 ,@r5 )
add #4 ,r5
movt r0
dt r6
bf/ s 3 b
cmp/ e q #1 ,r0
mov #0 ,r0
addc r0 ,r7
4 : mov r2 ,r6
mov #3 ,r0
and r0 ,r6
cmp/ p l r6
bf 7 f
mov #2 ,r1
cmp/ h s r1 ,r6
bf 5 f
SRC( m o v . w @r4+,r0 )
DST( m o v . w r0 ,@r5 )
extu. w r0 ,r0
add #2 ,r5
cmp/ e q r1 ,r6
bt/ s 6 f
clrt
shll1 6 r0
addc r0 ,r7
5 :
SRC( m o v . b @r4+,r0 )
DST( m o v . b r0 ,@r5 )
extu. b r0 ,r0
# ifndef _ _ L I T T L E _ E N D I A N _ _
shll8 r0
# endif
6 : addc r0 ,r7
mov #0 ,r0
addc r0 ,r7
7 :
5000 :
# Exception h a n d l e r :
.section .fixup , " ax"
6001 :
mov. l @(8,r15),r0 ! src_err_ptr
mov #- E F A U L T , r 1
mov. l r1 ,@r0
! 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
mov. l @(4,r15),r5 ! dst
mov. l @r15,r6 ! len
mov #0 ,r7
1 : mov. b r7 ,@r5
dt r6
bf/ s 1 b
add #1 ,r5
mov. l 8 0 0 0 f ,r0
jmp @r0
nop
.align 2
8000 : .long 5000 b
6002 :
mov. l @(12,r15),r0 ! dst_err_ptr
mov #- E F A U L T , r 1
mov. l r1 ,@r0
mov. l 8 0 0 1 f ,r0
jmp @r0
nop
.align 2
8001 : .long 5000 b
.previous
add #8 ,r15
rts
mov r7 ,r0