.text
buf .req r0
len .req r1
sum .req r2
td0 .req r3
td1 .req r4 @ save before use
td2 .req r5 @ save before use
td3 .req lr
.Lzero: mov r0, sum
add sp, sp,
ldr pc, [sp],
.Lless8: teq len,
beq .Lzero
tst buf,
movne sum, sum, ror
ldrbne td0, [buf],
subne len, len,
adcsne sum, sum, td0, put_byte_1
.Lless4: tst len,
beq .Lless8_byte
.Lless8_wordlp:
ldrh td0, [buf],
sub len, len,
ldrb td0, [buf],
ldrb td3, [buf],
sub len, len,
orr td0, td0, td3, lsl
orr td0, td3, td0, lsl
adcs sum, sum, td0
tst len,
bne .Lless8_wordlp
.Lless8_byte: tst len,
ldrbne td0, [buf],
adcsne sum, sum, td0, put_byte_0 @ update checksum
.Ldone: adc r0, sum,
ldr td0, [sp],
tst td0,
movne r0, r0, ror
ldr pc, [sp],
.Lnot_aligned: tst buf,
ldrbne td0, [buf],
subne len, len,
adcsne sum, sum, td0, put_byte_1 @ update checksum
tst buf,
ldrhne td0, [buf],
subne len, len,
ldrbne td0, [buf],
ldrbne ip, [buf],
subne len, len,
orrne td0, td0, ip, lsl
orrne td0, ip, td0, lsl
adcsne sum, sum, td0 @ update checksum
ret lr
ENTRY(csum_partial)
stmfd sp!, {buf, lr}
cmp len,
blo .Lless8 @ 8 bytes to copy.
tst buf,
movne sum, sum, ror
adds sum, sum,
tst buf,
blne .Lnot_aligned @ align destination, return here
1: bics ip, len,
beq 3f
stmfd sp!, {r4 - r5}
2: ldmia buf!, {td0, td1, td2, td3}
adcs sum, sum, td0
adcs sum, sum, td1
adcs sum, sum, td2
adcs sum, sum, td3
ldmia buf!, {td0, td1, td2, td3}
adcs sum, sum, td0
adcs sum, sum, td1
adcs sum, sum, td2
adcs sum, sum, td3
sub ip, ip,
teq ip,
bne 2b
ldmfd sp!, {r4 - r5}
3: tst len,
beq .Lless4
4: ldr td0, [buf],
sub len, len,
adcs sum, sum, td0
tst len,
bne 4b
b .Lless4
ENDPROC(csum_partial)