2019-06-04 10:11:33 +02:00
/* SPDX-License-Identifier: GPL-2.0-only */
2005-04-16 15:20:36 -07: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
* /
2014-06-30 16:29:12 +01:00
# include < a s m / a s s e m b l e r . h >
2005-04-16 15:20:36 -07:00
/ *
* 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-11 21:51:49 +00:00
.Lzero : mov r0 , s u m
2006-01-12 16:53:51 +00:00
load_ r e g s
2005-04-16 15:20:36 -07: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-11 21:51:49 +00:00
.Ldst_unaligned :
tst d s t , #1
beq . L d s t _ 1 6 b i t
2005-04-16 15:20:36 -07: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
2014-06-30 16:29:12 +01:00
reteq l r @ dst is now 32bit aligned
2005-04-16 15:20:36 -07:00
2005-11-11 21:51:49 +00:00
.Ldst_16bit : load2 b r8 , i p
2005-04-16 15:20:36 -07: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
2014-06-30 16:29:12 +01:00
ret l r @ dst is now 32bit aligned
2005-04-16 15:20:36 -07:00
/ *
* 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-11 21:51:49 +00:00
.Lless8 : teq l e n , #0 @ check for zero count
beq . L z e r o
2005-04-16 15:20:36 -07:00
/* we must have at least one byte. */
tst d s t , #1 @ dst 16-bit aligned
2005-11-11 21:51:49 +00:00
beq . L l e s s8 _ a l i g n e d
2005-04-16 15:20:36 -07: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-11 21:51:49 +00:00
beq . L l e s s8 _ b y t e o n l y
2005-04-16 15:20:36 -07: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-11 21:51:49 +00:00
.Lless8_aligned :
tst l e n , #6
2005-04-16 15:20:36 -07:00
bne 1 b
2005-11-11 21:51:49 +00:00
.Lless8_byteonly :
2005-04-16 15:20:36 -07:00
tst l e n , #1
2005-11-11 21:51:49 +00:00
beq . L d o n e
2005-04-16 15:20:36 -07: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-11 21:51:49 +00:00
b . L d o n e
2005-04-16 15:20:36 -07:00
FN_ E N T R Y
save_ r e g s
2020-07-12 22:56:34 -04:00
mov s u m , #- 1
2005-04-16 15:20:36 -07:00
cmp l e n , #8 @ Ensure that we have at least
2005-11-11 21:51:49 +00:00
blo . L l e s s8 @ 8 bytes to copy.
2005-04-16 15:20:36 -07:00
adds s u m , s u m , #0 @ C = 0
tst d s t , #3 @ Test destination alignment
2005-11-11 21:51:49 +00:00
blne . L d s t _ u n a l i g n e d @ align destination, return here
2005-04-16 15:20:36 -07: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-11 21:51:49 +00:00
bne . L s r c _ n o t _ a l i g n e d
2005-04-16 15:20:36 -07: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-11 21:51:49 +00:00
beq . L d o n e
2005-04-16 15:20:36 -07:00
load1 l r4
tst l e n , #2
mov r5 , r4 , g e t _ b y t e _ 0
2005-11-11 21:51:49 +00:00
beq . L e x i t
2014-02-25 08:41:09 +01:00
adcs s u m , s u m , r4 , l s p u s h #16
2005-04-16 15:20:36 -07:00
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-11 21:51:49 +00:00
.Lexit : tst l e n , #1
2019-02-18 00:57:38 +01:00
strbne r5 , [ d s t ] , #1
2005-04-16 15:20:36 -07:00
andne r5 , r5 , #255
2019-02-18 00:57:38 +01:00
adcsne s u m , s u m , r5 , p u t _ b y t e _ 0
2005-04-16 15:20:36 -07:00
/ *
* 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-11 21:51:49 +00:00
.Ldone : adc r0 , s u m , #0
2005-04-16 15:20:36 -07:00
ldr s u m , [ s p , #0 ] @ dst
tst s u m , #1
movne r0 , r0 , r o r #8
2006-01-12 16:53:51 +00:00
load_ r e g s
2005-04-16 15:20:36 -07:00
2005-11-11 21:51:49 +00:00
.Lsrc_not_aligned :
2005-04-16 15:20:36 -07: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-11 21:51:49 +00: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
2014-02-25 08:41:09 +01:00
mov r4 , r5 , l s p u l l #8 @ C = 0
2005-04-16 15:20:36 -07:00
bics i p , l e n , #15
beq 2 f
1 : load4 l r5 , r6 , r7 , r8
2014-02-25 08:41:09 +01:00
orr r4 , r4 , r5 , l s p u s h #24
mov r5 , r5 , l s p u l l #8
orr r5 , r5 , r6 , l s p u s h #24
mov r6 , r6 , l s p u l l #8
orr r6 , r6 , r7 , l s p u s h #24
mov r7 , r7 , l s p u l l #8
orr r7 , r7 , r8 , l s p u s h #24
2005-04-16 15:20:36 -07:00
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
2014-02-25 08:41:09 +01:00
mov r4 , r8 , l s p u l l #8
2005-04-16 15:20:36 -07:00
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
2014-02-25 08:41:09 +01:00
orr r4 , r4 , r5 , l s p u s h #24
mov r5 , r5 , l s p u l l #8
orr r5 , r5 , r6 , l s p u s h #24
2005-04-16 15:20:36 -07:00
stmia d s t ! , { r4 , r5 }
adcs s u m , s u m , r4
adcs s u m , s u m , r5
2014-02-25 08:41:09 +01:00
mov r4 , r6 , l s p u l l #8
2005-04-16 15:20:36 -07:00
tst i p , #4
beq 4 f
3 : load1 l r5
2014-02-25 08:41:09 +01:00
orr r4 , r4 , r5 , l s p u s h #24
2005-04-16 15:20:36 -07:00
str r4 , [ d s t ] , #4
adcs s u m , s u m , r4
2014-02-25 08:41:09 +01:00
mov r4 , r5 , l s p u l l #8
2005-04-16 15:20:36 -07:00
4 : ands l e n , l e n , #3
2005-11-11 21:51:49 +00:00
beq . L d o n e
2005-04-16 15:20:36 -07:00
mov r5 , r4 , g e t _ b y t e _ 0
tst l e n , #2
2005-11-11 21:51:49 +00:00
beq . L e x i t
2014-02-25 08:41:09 +01:00
adcs s u m , s u m , r4 , l s p u s h #16
2005-04-16 15:20:36 -07:00
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-11 21:51:49 +00:00
b . L e x i t
2005-04-16 15:20:36 -07:00
2014-02-25 08:41:09 +01:00
.Lsrc2_aligned : mov r4 , r5 , l s p u l l #16
2005-04-16 15:20:36 -07: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
2014-02-25 08:41:09 +01:00
orr r4 , r4 , r5 , l s p u s h #16
mov r5 , r5 , l s p u l l #16
orr r5 , r5 , r6 , l s p u s h #16
mov r6 , r6 , l s p u l l #16
orr r6 , r6 , r7 , l s p u s h #16
mov r7 , r7 , l s p u l l #16
orr r7 , r7 , r8 , l s p u s h #16
2005-04-16 15:20:36 -07:00
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
2014-02-25 08:41:09 +01:00
mov r4 , r8 , l s p u l l #16
2005-04-16 15:20:36 -07:00
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
2014-02-25 08:41:09 +01:00
orr r4 , r4 , r5 , l s p u s h #16
mov r5 , r5 , l s p u l l #16
orr r5 , r5 , r6 , l s p u s h #16
2005-04-16 15:20:36 -07:00
stmia d s t ! , { r4 , r5 }
adcs s u m , s u m , r4
adcs s u m , s u m , r5
2014-02-25 08:41:09 +01:00
mov r4 , r6 , l s p u l l #16
2005-04-16 15:20:36 -07:00
tst i p , #4
beq 4 f
3 : load1 l r5
2014-02-25 08:41:09 +01:00
orr r4 , r4 , r5 , l s p u s h #16
2005-04-16 15:20:36 -07:00
str r4 , [ d s t ] , #4
adcs s u m , s u m , r4
2014-02-25 08:41:09 +01:00
mov r4 , r5 , l s p u l l #16
2005-04-16 15:20:36 -07:00
4 : ands l e n , l e n , #3
2005-11-11 21:51:49 +00:00
beq . L d o n e
2005-04-16 15:20:36 -07:00
mov r5 , r4 , g e t _ b y t e _ 0
tst l e n , #2
2005-11-11 21:51:49 +00:00
beq . L e x i t
2005-04-16 15:20:36 -07: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-11 21:51:49 +00:00
beq . L d o n e
2005-04-16 15:20:36 -07:00
load1 b r5
2005-11-11 21:51:49 +00:00
b . L e x i t
2005-04-16 15:20:36 -07:00
2014-02-25 08:41:09 +01:00
.Lsrc3_aligned : mov r4 , r5 , l s p u l l #24
2005-04-16 15:20:36 -07: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
2014-02-25 08:41:09 +01:00
orr r4 , r4 , r5 , l s p u s h #8
mov r5 , r5 , l s p u l l #24
orr r5 , r5 , r6 , l s p u s h #8
mov r6 , r6 , l s p u l l #24
orr r6 , r6 , r7 , l s p u s h #8
mov r7 , r7 , l s p u l l #24
orr r7 , r7 , r8 , l s p u s h #8
2005-04-16 15:20:36 -07:00
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
2014-02-25 08:41:09 +01:00
mov r4 , r8 , l s p u l l #24
2005-04-16 15:20:36 -07:00
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
2014-02-25 08:41:09 +01:00
orr r4 , r4 , r5 , l s p u s h #8
mov r5 , r5 , l s p u l l #24
orr r5 , r5 , r6 , l s p u s h #8
2005-04-16 15:20:36 -07:00
stmia d s t ! , { r4 , r5 }
adcs s u m , s u m , r4
adcs s u m , s u m , r5
2014-02-25 08:41:09 +01:00
mov r4 , r6 , l s p u l l #24
2005-04-16 15:20:36 -07:00
tst i p , #4
beq 4 f
3 : load1 l r5
2014-02-25 08:41:09 +01:00
orr r4 , r4 , r5 , l s p u s h #8
2005-04-16 15:20:36 -07:00
str r4 , [ d s t ] , #4
adcs s u m , s u m , r4
2014-02-25 08:41:09 +01:00
mov r4 , r5 , l s p u l l #24
2005-04-16 15:20:36 -07:00
4 : ands l e n , l e n , #3
2005-11-11 21:51:49 +00:00
beq . L d o n e
2005-04-16 15:20:36 -07:00
mov r5 , r4 , g e t _ b y t e _ 0
tst l e n , #2
2005-11-11 21:51:49 +00:00
beq . L e x i t
2005-04-16 15:20:36 -07: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
2014-02-25 08:41:09 +01:00
adcs s u m , s u m , r4 , l s p u s h #24
2005-04-16 15:20:36 -07:00
mov r5 , r4 , g e t _ b y t e _ 1
2005-11-11 21:51:49 +00:00
b . L e x i t
2008-08-28 11:22:32 +01:00
FN_ E X I T