Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[cris-mirror.git] / arch / cris / arch-v32 / lib / checksum.S
blobf773d4d936096cd87b17c4c61c6f1555efec7480
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * A fast checksum routine using movem
4  * Copyright (c) 1998-2007 Axis Communications AB
5  *
6  * csum_partial(const unsigned char * buff, int len, unsigned int sum)
7  */
9         .globl  csum_partial
10         .type   csum_partial,@function
11 csum_partial:
13         ;; r10 - src
14         ;; r11 - length
15         ;; r12 - checksum
17         ;; Optimized for large packets
18         subq    10*4, $r11
19         blt     _word_loop
20         move.d  $r11, $acr
22         subq    9*4,$sp
23         clearf  c
24         movem   $r8,[$sp]
26         ;; do a movem checksum
28 _mloop: movem   [$r10+],$r9     ; read 10 longwords
29         ;; Loop count without touching the c flag.
30         addoq   -10*4, $acr, $acr
31         ;; perform dword checksumming on the 10 longwords
33         addc    $r0,$r12
34         addc    $r1,$r12
35         addc    $r2,$r12
36         addc    $r3,$r12
37         addc    $r4,$r12
38         addc    $r5,$r12
39         addc    $r6,$r12
40         addc    $r7,$r12
41         addc    $r8,$r12
42         addc    $r9,$r12
44         ;; test $acr without trashing carry.
45         move.d  $acr, $acr
46         bpl     _mloop
47         ;; r11 <= acr  is not really needed in the mloop, just using the dslot
48         ;; to prepare for what is needed after mloop.
49         move.d  $acr, $r11
51         ;; fold the last carry into r13
52         addc    0, $r12
53         movem   [$sp+],$r8      ; restore regs
55 _word_loop:
56         addq    10*4,$r11       ; compensate for last loop underflowing length
58         moveq   -1,$r9          ; put 0xffff in r9, faster than move.d 0xffff,r9
59         lsrq    16,$r9
61         move.d  $r12,$r13
62         lsrq    16,$r13         ; r13 = checksum >> 16
63         and.d   $r9,$r12        ; checksum = checksum & 0xffff
65 _no_fold:
66         subq    2,$r11
67         blt     _no_words
68         add.d   $r13,$r12       ; checksum += r13
70         ;; checksum the rest of the words
71 _wloop: subq    2,$r11
72         bge     _wloop
73         addu.w  [$r10+],$r12
75 _no_words:
76         addq    2,$r11
77         ;; see if we have one odd byte more
78         bne     _do_byte
79         nop
80         ret
81         move.d  $r12,$r10
83 _do_byte:
84         ;; copy and checksum the last byte
85         addu.b  [$r10],$r12
86         ret
87         move.d  $r12,$r10
89         .size   csum_partial, .-csum_partial