2005-04-17 02:20:36 +04:00
/ *
* linux/ a r c h / a r m / l i b / c s u m p a r t i a l c o p y g e n e r i c . S
*
* Copyright ( C ) 1 9 9 5 - 2 0 0 1 R u s s e l l K i n g
*
* 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
* it 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 v e r s i o n 2 a s
* published 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 .
* /
/ *
* unsigned i n t
* csum_ p a r t i a l _ c o p y _ x x x ( 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 , i n t s u m , )
* r0 = s r c , r1 = d s t , r2 = l e n , r3 = s u m
* Returns : r0 = c h e c k s u m
*
* Note t h a t ' t s t ' a n d ' t e q ' p r e s e r v e t h e c a r r y f l a g .
* /
src . r e q r0
dst . r e q r1
len . r e q r2
sum . r e q r3
2005-11-12 00:51:49 +03:00
.Lzero : mov r0 , s u m
2006-01-12 19:53:51 +03:00
load_ r e g s
2005-04-17 02:20:36 +04:00
/ *
* Align a n u n a l i g n e d d e s t i n a t i o n p o i n t e r . W e k n o w t h a t
* we h a v e > = 8 b y t e s h e r e , s o w e d o n ' t n e e d t o c h e c k
* the l e n g t h . N o t e t h a t t h e s o u r c e p o i n t e r h a s n ' t b e e n
* aligned y e t .
* /
2005-11-12 00:51:49 +03:00
.Ldst_unaligned :
tst d s t , #1
beq . L d s t _ 1 6 b i t
2005-04-17 02:20:36 +04:00
load1 b i p
sub l e n , l e n , #1
adcs s u m , s u m , i p , p u t _ b y t e _ 1 @ update checksum
strb i p , [ d s t ] , #1
tst d s t , #2
moveq p c , l r @ dst is now 32bit aligned
2005-11-12 00:51:49 +03:00
.Ldst_16bit : load2 b r8 , i p
2005-04-17 02:20:36 +04:00
sub l e n , l e n , #2
adcs s u m , s u m , r8 , p u t _ b y t e _ 0
strb r8 , [ d s t ] , #1
adcs s u m , s u m , i p , p u t _ b y t e _ 1
strb i p , [ d s t ] , #1
mov p c , l r @ dst is now 32bit aligned
/ *
* Handle 0 t o 7 b y t e s , w i t h a n y a l i g n m e n t o f s o u r c e a n d
* destination p o i n t e r s . N o t e t h a t w h e n w e g e t h e r e , C = 0
* /
2005-11-12 00:51:49 +03:00
.Lless8 : teq l e n , #0 @ check for zero count
beq . L z e r o
2005-04-17 02:20:36 +04:00
/* we must have at least one byte. */
tst d s t , #1 @ dst 16-bit aligned
2005-11-12 00:51:49 +03:00
beq . L l e s s8 _ a l i g n e d
2005-04-17 02:20:36 +04:00
/* Align dst */
load1 b i p
sub l e n , l e n , #1
adcs s u m , s u m , i p , p u t _ b y t e _ 1 @ update checksum
strb i p , [ d s t ] , #1
tst l e n , #6
2005-11-12 00:51:49 +03:00
beq . L l e s s8 _ b y t e o n l y
2005-04-17 02:20:36 +04:00
1 : load2 b r8 , i p
sub l e n , l e n , #2
adcs s u m , s u m , r8 , p u t _ b y t e _ 0
strb r8 , [ d s t ] , #1
adcs s u m , s u m , i p , p u t _ b y t e _ 1
strb i p , [ d s t ] , #1
2005-11-12 00:51:49 +03:00
.Lless8_aligned :
tst l e n , #6
2005-04-17 02:20:36 +04:00
bne 1 b
2005-11-12 00:51:49 +03:00
.Lless8_byteonly :
2005-04-17 02:20:36 +04:00
tst l e n , #1
2005-11-12 00:51:49 +03:00
beq . L d o n e
2005-04-17 02:20:36 +04:00
load1 b r8
adcs s u m , s u m , r8 , p u t _ b y t e _ 0 @ update checksum
strb r8 , [ d s t ] , #1
2005-11-12 00:51:49 +03:00
b . L d o n e
2005-04-17 02:20:36 +04:00
FN_ E N T R Y
save_ r e g s
cmp l e n , #8 @ Ensure that we have at least
2005-11-12 00:51:49 +03:00
blo . L l e s s8 @ 8 bytes to copy.
2005-04-17 02:20:36 +04:00
adds s u m , s u m , #0 @ C = 0
tst d s t , #3 @ Test destination alignment
2005-11-12 00:51:49 +03:00
blne . L d s t _ u n a l i g n e d @ align destination, return here
2005-04-17 02:20:36 +04:00
/ *
* Ok, t h e d s t p o i n t e r i s n o w 3 2 b i t a l i g n e d , a n d w e k n o w
* that w e m u s t h a v e m o r e t h a n 4 b y t e s t o c o p y . N o t e
* that C c o n t a i n s t h e c a r r y f r o m t h e d s t a l i g n m e n t a b o v e .
* /
tst s r c , #3 @ Test source alignment
2005-11-12 00:51:49 +03:00
bne . L s r c _ n o t _ a l i g n e d
2005-04-17 02:20:36 +04:00
/* Routine for src & dst aligned */
bics i p , l e n , #15
beq 2 f
1 : load4 l r4 , r5 , r6 , r7
stmia d s t ! , { r4 , r5 , r6 , r7 }
adcs s u m , s u m , r4
adcs s u m , s u m , r5
adcs s u m , s u m , r6
adcs s u m , s u m , r7
sub i p , i p , #16
teq i p , #0
bne 1 b
2 : ands i p , l e n , #12
beq 4 f
tst i p , #8
beq 3 f
load2 l r4 , r5
stmia d s t ! , { r4 , r5 }
adcs s u m , s u m , r4
adcs s u m , s u m , r5
tst i p , #4
beq 4 f
3 : load1 l r4
str r4 , [ d s t ] , #4
adcs s u m , s u m , r4
4 : ands l e n , l e n , #3
2005-11-12 00:51:49 +03:00
beq . L d o n e
2005-04-17 02:20:36 +04:00
load1 l r4
tst l e n , #2
mov r5 , r4 , g e t _ b y t e _ 0
2005-11-12 00:51:49 +03:00
beq . L e x i t
2005-04-17 02:20:36 +04:00
adcs s u m , s u m , r4 , p u s h #16
strb r5 , [ d s t ] , #1
mov r5 , r4 , g e t _ b y t e _ 1
strb r5 , [ d s t ] , #1
mov r5 , r4 , g e t _ b y t e _ 2
2005-11-12 00:51:49 +03:00
.Lexit : tst l e n , #1
2005-04-17 02:20:36 +04:00
strneb r5 , [ d s t ] , #1
andne r5 , r5 , #255
adcnes s u m , s u m , r5 , p u t _ b y t e _ 0
/ *
* If t h e d s t p o i n t e r w a s n o t 1 6 - b i t a l i g n e d , w e
* need t o r o t a t e t h e c h e c k s u m h e r e t o g e t a r o u n d
* the i n e f f i c i e n t b y t e m a n i p u l a t i o n s i n t h e
* architecture i n d e p e n d e n t c o d e .
* /
2005-11-12 00:51:49 +03:00
.Ldone : adc r0 , s u m , #0
2005-04-17 02:20:36 +04:00
ldr s u m , [ s p , #0 ] @ dst
tst s u m , #1
movne r0 , r0 , r o r #8
2006-01-12 19:53:51 +03:00
load_ r e g s
2005-04-17 02:20:36 +04:00
2005-11-12 00:51:49 +03:00
.Lsrc_not_aligned :
2005-04-17 02:20:36 +04:00
adc s u m , s u m , #0 @ include C from dst alignment
and i p , s r c , #3
bic s r c , s r c , #3
load1 l r5
cmp i p , #2
2005-11-12 00:51:49 +03:00
beq . L s r c2 _ a l i g n e d
bhi . L s r c3 _ a l i g n e d
2005-04-17 02:20:36 +04:00
mov r4 , r5 , p u l l #8 @ C = 0
bics i p , l e n , #15
beq 2 f
1 : load4 l r5 , r6 , r7 , r8
orr r4 , r4 , r5 , p u s h #24
mov r5 , r5 , p u l l #8
orr r5 , r5 , r6 , p u s h #24
mov r6 , r6 , p u l l #8
orr r6 , r6 , r7 , p u s h #24
mov r7 , r7 , p u l l #8
orr r7 , r7 , r8 , p u s h #24
stmia d s t ! , { r4 , r5 , r6 , r7 }
adcs s u m , s u m , r4
adcs s u m , s u m , r5
adcs s u m , s u m , r6
adcs s u m , s u m , r7
mov r4 , r8 , p u l l #8
sub i p , i p , #16
teq i p , #0
bne 1 b
2 : ands i p , l e n , #12
beq 4 f
tst i p , #8
beq 3 f
load2 l r5 , r6
orr r4 , r4 , r5 , p u s h #24
mov r5 , r5 , p u l l #8
orr r5 , r5 , r6 , p u s h #24
stmia d s t ! , { r4 , r5 }
adcs s u m , s u m , r4
adcs s u m , s u m , r5
mov r4 , r6 , p u l l #8
tst i p , #4
beq 4 f
3 : load1 l r5
orr r4 , r4 , r5 , p u s h #24
str r4 , [ d s t ] , #4
adcs s u m , s u m , r4
mov r4 , r5 , p u l l #8
4 : ands l e n , l e n , #3
2005-11-12 00:51:49 +03:00
beq . L d o n e
2005-04-17 02:20:36 +04:00
mov r5 , r4 , g e t _ b y t e _ 0
tst l e n , #2
2005-11-12 00:51:49 +03:00
beq . L e x i t
2005-04-17 02:20:36 +04:00
adcs s u m , s u m , r4 , p u s h #16
strb r5 , [ d s t ] , #1
mov r5 , r4 , g e t _ b y t e _ 1
strb r5 , [ d s t ] , #1
mov r5 , r4 , g e t _ b y t e _ 2
2005-11-12 00:51:49 +03:00
b . L e x i t
2005-04-17 02:20:36 +04:00
2005-11-12 00:51:49 +03:00
.Lsrc2_aligned : mov r4 , r5 , p u l l #16
2005-04-17 02:20:36 +04:00
adds s u m , s u m , #0
bics i p , l e n , #15
beq 2 f
1 : load4 l r5 , r6 , r7 , r8
orr r4 , r4 , r5 , p u s h #16
mov r5 , r5 , p u l l #16
orr r5 , r5 , r6 , p u s h #16
mov r6 , r6 , p u l l #16
orr r6 , r6 , r7 , p u s h #16
mov r7 , r7 , p u l l #16
orr r7 , r7 , r8 , p u s h #16
stmia d s t ! , { r4 , r5 , r6 , r7 }
adcs s u m , s u m , r4
adcs s u m , s u m , r5
adcs s u m , s u m , r6
adcs s u m , s u m , r7
mov r4 , r8 , p u l l #16
sub i p , i p , #16
teq i p , #0
bne 1 b
2 : ands i p , l e n , #12
beq 4 f
tst i p , #8
beq 3 f
load2 l r5 , r6
orr r4 , r4 , r5 , p u s h #16
mov r5 , r5 , p u l l #16
orr r5 , r5 , r6 , p u s h #16
stmia d s t ! , { r4 , r5 }
adcs s u m , s u m , r4
adcs s u m , s u m , r5
mov r4 , r6 , p u l l #16
tst i p , #4
beq 4 f
3 : load1 l r5
orr r4 , r4 , r5 , p u s h #16
str r4 , [ d s t ] , #4
adcs s u m , s u m , r4
mov r4 , r5 , p u l l #16
4 : ands l e n , l e n , #3
2005-11-12 00:51:49 +03:00
beq . L d o n e
2005-04-17 02:20:36 +04:00
mov r5 , r4 , g e t _ b y t e _ 0
tst l e n , #2
2005-11-12 00:51:49 +03:00
beq . L e x i t
2005-04-17 02:20:36 +04:00
adcs s u m , s u m , r4
strb r5 , [ d s t ] , #1
mov r5 , r4 , g e t _ b y t e _ 1
strb r5 , [ d s t ] , #1
tst l e n , #1
2005-11-12 00:51:49 +03:00
beq . L d o n e
2005-04-17 02:20:36 +04:00
load1 b r5
2005-11-12 00:51:49 +03:00
b . L e x i t
2005-04-17 02:20:36 +04:00
2005-11-12 00:51:49 +03:00
.Lsrc3_aligned : mov r4 , r5 , p u l l #24
2005-04-17 02:20:36 +04:00
adds s u m , s u m , #0
bics i p , l e n , #15
beq 2 f
1 : load4 l r5 , r6 , r7 , r8
orr r4 , r4 , r5 , p u s h #8
mov r5 , r5 , p u l l #24
orr r5 , r5 , r6 , p u s h #8
mov r6 , r6 , p u l l #24
orr r6 , r6 , r7 , p u s h #8
mov r7 , r7 , p u l l #24
orr r7 , r7 , r8 , p u s h #8
stmia d s t ! , { r4 , r5 , r6 , r7 }
adcs s u m , s u m , r4
adcs s u m , s u m , r5
adcs s u m , s u m , r6
adcs s u m , s u m , r7
mov r4 , r8 , p u l l #24
sub i p , i p , #16
teq i p , #0
bne 1 b
2 : ands i p , l e n , #12
beq 4 f
tst i p , #8
beq 3 f
load2 l r5 , r6
orr r4 , r4 , r5 , p u s h #8
mov r5 , r5 , p u l l #24
orr r5 , r5 , r6 , p u s h #8
stmia d s t ! , { r4 , r5 }
adcs s u m , s u m , r4
adcs s u m , s u m , r5
mov r4 , r6 , p u l l #24
tst i p , #4
beq 4 f
3 : load1 l r5
orr r4 , r4 , r5 , p u s h #8
str r4 , [ d s t ] , #4
adcs s u m , s u m , r4
mov r4 , r5 , p u l l #24
4 : ands l e n , l e n , #3
2005-11-12 00:51:49 +03:00
beq . L d o n e
2005-04-17 02:20:36 +04:00
mov r5 , r4 , g e t _ b y t e _ 0
tst l e n , #2
2005-11-12 00:51:49 +03:00
beq . L e x i t
2005-04-17 02:20:36 +04:00
strb r5 , [ d s t ] , #1
adcs s u m , s u m , r4
load1 l r4
mov r5 , r4 , g e t _ b y t e _ 0
strb r5 , [ d s t ] , #1
adcs s u m , s u m , r4 , p u s h #24
mov r5 , r4 , g e t _ b y t e _ 1
2005-11-12 00:51:49 +03:00
b . L e x i t
2008-08-28 14:22:32 +04:00
FN_ E X I T