blob: 4a72a94a49ad6d5a60718e6fc19eec59bc268fd1 [file] [log] [blame]
Mikael Starvik51533b62005-07-27 11:44:44 -07001/*
2 * A fast checksum routine using movem
Jesper Nilsson41f94122008-01-25 17:54:14 +01003 * Copyright (c) 1998-2007 Axis Communications AB
Mikael Starvik51533b62005-07-27 11:44:44 -07004 *
5 * csum_partial(const unsigned char * buff, int len, unsigned int sum)
6 */
7
8 .globl csum_partial
Jesper Nilsson3a381252010-08-03 16:16:45 +02009 .type csum_partial,@function
Mikael Starvik51533b62005-07-27 11:44:44 -070010csum_partial:
11
12 ;; r10 - src
13 ;; r11 - length
14 ;; r12 - checksum
15
Jesper Nilsson41f94122008-01-25 17:54:14 +010016 ;; Optimized for large packets
17 subq 10*4, $r11
18 blt _word_loop
19 move.d $r11, $acr
Mikael Starvik51533b62005-07-27 11:44:44 -070020
21 subq 9*4,$sp
Jesper Nilsson41f94122008-01-25 17:54:14 +010022 clearf c
Mikael Starvik51533b62005-07-27 11:44:44 -070023 movem $r8,[$sp]
24
25 ;; do a movem checksum
26
27_mloop: movem [$r10+],$r9 ; read 10 longwords
Jesper Nilsson41f94122008-01-25 17:54:14 +010028 ;; Loop count without touching the c flag.
29 addoq -10*4, $acr, $acr
Mikael Starvik51533b62005-07-27 11:44:44 -070030 ;; perform dword checksumming on the 10 longwords
31
Jesper Nilsson41f94122008-01-25 17:54:14 +010032 addc $r0,$r12
Mikael Starvik51533b62005-07-27 11:44:44 -070033 addc $r1,$r12
34 addc $r2,$r12
35 addc $r3,$r12
36 addc $r4,$r12
37 addc $r5,$r12
38 addc $r6,$r12
39 addc $r7,$r12
40 addc $r8,$r12
41 addc $r9,$r12
42
Jesper Nilsson41f94122008-01-25 17:54:14 +010043 ;; test $acr without trashing carry.
44 move.d $acr, $acr
45 bpl _mloop
46 ;; r11 <= acr is not really needed in the mloop, just using the dslot
47 ;; to prepare for what is needed after mloop.
48 move.d $acr, $r11
Mikael Starvik51533b62005-07-27 11:44:44 -070049
Jesper Nilsson41f94122008-01-25 17:54:14 +010050 ;; fold the last carry into r13
51 addc 0, $r12
Mikael Starvik51533b62005-07-27 11:44:44 -070052 movem [$sp+],$r8 ; restore regs
53
54_word_loop:
Jesper Nilsson41f94122008-01-25 17:54:14 +010055 addq 10*4,$r11 ; compensate for last loop underflowing length
Mikael Starvik51533b62005-07-27 11:44:44 -070056
57 moveq -1,$r9 ; put 0xffff in r9, faster than move.d 0xffff,r9
58 lsrq 16,$r9
59
60 move.d $r12,$r13
61 lsrq 16,$r13 ; r13 = checksum >> 16
Jesper Nilsson41f94122008-01-25 17:54:14 +010062 and.d $r9,$r12 ; checksum = checksum & 0xffff
Mikael Starvik51533b62005-07-27 11:44:44 -070063
64_no_fold:
Jesper Nilsson41f94122008-01-25 17:54:14 +010065 subq 2,$r11
Mikael Starvik51533b62005-07-27 11:44:44 -070066 blt _no_words
Jesper Nilsson41f94122008-01-25 17:54:14 +010067 add.d $r13,$r12 ; checksum += r13
Mikael Starvik51533b62005-07-27 11:44:44 -070068
69 ;; checksum the rest of the words
Mikael Starvik51533b62005-07-27 11:44:44 -070070_wloop: subq 2,$r11
71 bge _wloop
72 addu.w [$r10+],$r12
73
Mikael Starvik51533b62005-07-27 11:44:44 -070074_no_words:
Jesper Nilsson41f94122008-01-25 17:54:14 +010075 addq 2,$r11
Mikael Starvik51533b62005-07-27 11:44:44 -070076 ;; see if we have one odd byte more
Jesper Nilsson41f94122008-01-25 17:54:14 +010077 bne _do_byte
Mikael Starvik51533b62005-07-27 11:44:44 -070078 nop
79 ret
80 move.d $r12,$r10
81
82_do_byte:
83 ;; copy and checksum the last byte
84 addu.b [$r10],$r12
85 ret
86 move.d $r12,$r10
Jesper Nilsson3a381252010-08-03 16:16:45 +020087
88 .size csum_partial, .-csum_partial