blob: f773d4d936096cd87b17c4c61c6f1555efec7480 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Mikael Starvik51533b62005-07-27 11:44:44 -07002/*
3 * A fast checksum routine using movem
Jesper Nilsson41f94122008-01-25 17:54:14 +01004 * Copyright (c) 1998-2007 Axis Communications AB
Mikael Starvik51533b62005-07-27 11:44:44 -07005 *
6 * csum_partial(const unsigned char * buff, int len, unsigned int sum)
7 */
8
9 .globl csum_partial
Jesper Nilsson3a381252010-08-03 16:16:45 +020010 .type csum_partial,@function
Mikael Starvik51533b62005-07-27 11:44:44 -070011csum_partial:
12
13 ;; r10 - src
14 ;; r11 - length
15 ;; r12 - checksum
16
Jesper Nilsson41f94122008-01-25 17:54:14 +010017 ;; Optimized for large packets
18 subq 10*4, $r11
19 blt _word_loop
20 move.d $r11, $acr
Mikael Starvik51533b62005-07-27 11:44:44 -070021
22 subq 9*4,$sp
Jesper Nilsson41f94122008-01-25 17:54:14 +010023 clearf c
Mikael Starvik51533b62005-07-27 11:44:44 -070024 movem $r8,[$sp]
25
26 ;; do a movem checksum
27
28_mloop: movem [$r10+],$r9 ; read 10 longwords
Jesper Nilsson41f94122008-01-25 17:54:14 +010029 ;; Loop count without touching the c flag.
30 addoq -10*4, $acr, $acr
Mikael Starvik51533b62005-07-27 11:44:44 -070031 ;; perform dword checksumming on the 10 longwords
32
Jesper Nilsson41f94122008-01-25 17:54:14 +010033 addc $r0,$r12
Mikael Starvik51533b62005-07-27 11:44:44 -070034 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
43
Jesper Nilsson41f94122008-01-25 17:54:14 +010044 ;; 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
Mikael Starvik51533b62005-07-27 11:44:44 -070050
Jesper Nilsson41f94122008-01-25 17:54:14 +010051 ;; fold the last carry into r13
52 addc 0, $r12
Mikael Starvik51533b62005-07-27 11:44:44 -070053 movem [$sp+],$r8 ; restore regs
54
55_word_loop:
Jesper Nilsson41f94122008-01-25 17:54:14 +010056 addq 10*4,$r11 ; compensate for last loop underflowing length
Mikael Starvik51533b62005-07-27 11:44:44 -070057
58 moveq -1,$r9 ; put 0xffff in r9, faster than move.d 0xffff,r9
59 lsrq 16,$r9
60
61 move.d $r12,$r13
62 lsrq 16,$r13 ; r13 = checksum >> 16
Jesper Nilsson41f94122008-01-25 17:54:14 +010063 and.d $r9,$r12 ; checksum = checksum & 0xffff
Mikael Starvik51533b62005-07-27 11:44:44 -070064
65_no_fold:
Jesper Nilsson41f94122008-01-25 17:54:14 +010066 subq 2,$r11
Mikael Starvik51533b62005-07-27 11:44:44 -070067 blt _no_words
Jesper Nilsson41f94122008-01-25 17:54:14 +010068 add.d $r13,$r12 ; checksum += r13
Mikael Starvik51533b62005-07-27 11:44:44 -070069
70 ;; checksum the rest of the words
Mikael Starvik51533b62005-07-27 11:44:44 -070071_wloop: subq 2,$r11
72 bge _wloop
73 addu.w [$r10+],$r12
74
Mikael Starvik51533b62005-07-27 11:44:44 -070075_no_words:
Jesper Nilsson41f94122008-01-25 17:54:14 +010076 addq 2,$r11
Mikael Starvik51533b62005-07-27 11:44:44 -070077 ;; see if we have one odd byte more
Jesper Nilsson41f94122008-01-25 17:54:14 +010078 bne _do_byte
Mikael Starvik51533b62005-07-27 11:44:44 -070079 nop
80 ret
81 move.d $r12,$r10
82
83_do_byte:
84 ;; copy and checksum the last byte
85 addu.b [$r10],$r12
86 ret
87 move.d $r12,$r10
Jesper Nilsson3a381252010-08-03 16:16:45 +020088
89 .size csum_partial, .-csum_partial