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 . S
*
* Copyright ( C ) 1 9 9 5 - 1 9 9 8 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 .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / a s s e m b l e r . h >
.text
/ *
* Function : _ _ u3 2 c s u m _ p a r t i a l ( c o n s t c h a r * s r c , i n t l e n , _ _ u 3 2 s u m )
* Params : r0 = b u f f e r , r1 = l e n , r2 = c h e c k s u m
* Returns : r0 = n e w c h e c k s u m
* /
buf . r e q r0
len . r e q r1
sum . r e q r2
td0 . r e q r3
td1 . r e q r4 @ save before use
td2 . r e q r5 @ save before use
td3 . r e q l r
2005-11-12 00:51:49 +03:00
.Lzero : mov r0 , s u m
2005-04-17 02:20:36 +04:00
add s p , s p , #4
ldr p c , [ s p ] , #4
/ *
* 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 b u f , #1 @ odd address?
2005-11-10 14:40:53 +03:00
movne s u m , s u m , r o r #8
2005-04-17 02:20:36 +04:00
ldrneb t d0 , [ b u f ] , #1
subne l e n , l e n , #1
adcnes s u m , s u m , t d0 , p u t _ b y t e _ 1
2005-11-12 00:51:49 +03:00
.Lless4 : tst l e n , #6
beq . L l e s s8 _ b y t e
2005-04-17 02:20:36 +04:00
/* we are now half-word aligned */
2005-11-12 00:51:49 +03:00
.Lless8_wordlp :
2005-04-17 02:20:36 +04:00
# if _ _ L I N U X _ A R M _ A R C H _ _ > = 4
ldrh t d0 , [ b u f ] , #2
sub l e n , l e n , #2
# else
ldrb t d0 , [ b u f ] , #1
ldrb t d3 , [ b u f ] , #1
sub l e n , l e n , #2
# ifndef _ _ A R M E B _ _
orr t d0 , t d0 , t d3 , l s l #8
# else
orr t d0 , t d3 , t d0 , l s l #8
# endif
# endif
adcs s u m , s u m , t d0
tst l e n , #6
2005-11-12 00:51:49 +03:00
bne . L l e s s8 _ w o r d l p
2005-04-17 02:20:36 +04:00
2005-11-12 00:51:49 +03:00
.Lless8_byte : tst l e n , #1 @ odd number of bytes
2005-04-17 02:20:36 +04:00
ldrneb t d0 , [ b u f ] , #1 @ include last byte
adcnes s u m , s u m , t d0 , p u t _ b y t e _ 0 @ update checksum
2005-11-12 00:51:49 +03:00
.Ldone : adc r0 , s u m , #0 @ collect up the last carry
2005-04-17 02:20:36 +04:00
ldr t d0 , [ s p ] , #4
tst t d0 , #1 @ check buffer alignment
movne r0 , r0 , r o r #8 @ rotate checksum by 8 bits
ldr p c , [ s p ] , #4 @ return
2005-11-12 00:51:49 +03:00
.Lnot_aligned : tst b u f , #1 @ odd address
2005-04-17 02:20:36 +04:00
ldrneb t d0 , [ b u f ] , #1 @ make even
subne l e n , l e n , #1
adcnes s u m , s u m , t d0 , p u t _ b y t e _ 1 @ update checksum
tst b u f , #2 @ 32-bit aligned?
# if _ _ L I N U X _ A R M _ A R C H _ _ > = 4
ldrneh t d0 , [ b u f ] , #2 @ make 32-bit aligned
subne l e n , l e n , #2
# else
ldrneb t d0 , [ b u f ] , #1
ldrneb i p , [ b u f ] , #1
subne l e n , l e n , #2
# ifndef _ _ A R M E B _ _
orrne t d0 , t d0 , i p , l s l #8
# else
orrne t d0 , i p , t d0 , l s l #8
# endif
# endif
adcnes s u m , s u m , t d0 @ update checksum
mov p c , l r
ENTRY( c s u m _ p a r t i a l )
stmfd s p ! , { b u f , l r }
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
2005-11-10 14:40:53 +03:00
tst b u f , #1
movne s u m , s u m , r o r #8
2005-04-17 02:20:36 +04:00
adds s u m , s u m , #0 @ C = 0
tst b u f , #3 @ Test destination alignment
2005-11-12 00:51:49 +03:00
blne . L n o t _ a l i g n e d @ align destination, return here
2005-04-17 02:20:36 +04:00
1 : bics i p , l e n , #31
beq 3 f
stmfd s p ! , { r4 - r5 }
2 : ldmia b u f ! , { t d0 , t d1 , t d2 , t d3 }
adcs s u m , s u m , t d0
adcs s u m , s u m , t d1
adcs s u m , s u m , t d2
adcs s u m , s u m , t d3
ldmia b u f ! , { t d0 , t d1 , t d2 , t d3 }
adcs s u m , s u m , t d0
adcs s u m , s u m , t d1
adcs s u m , s u m , t d2
adcs s u m , s u m , t d3
sub i p , i p , #32
teq i p , #0
bne 2 b
ldmfd s p ! , { r4 - r5 }
3 : tst l e n , #0x1c @ should not change C
2005-11-12 00:51:49 +03:00
beq . L l e s s4
2005-04-17 02:20:36 +04:00
4 : ldr t d0 , [ b u f ] , #4
sub l e n , l e n , #4
adcs s u m , s u m , t d0
tst l e n , #0x1c
bne 4 b
2005-11-12 00:51:49 +03:00
b . L l e s s4
2008-08-28 14:22:32 +04:00
ENDPROC( c s u m _ p a r t i a l )