blob: 87f3fd71ab10514c342b4dc9a971ceb67ea1349d [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
9csum_partial:
10
11 ;; r10 - src
12 ;; r11 - length
13 ;; r12 - checksum
14
Jesper Nilsson41f94122008-01-25 17:54:14 +010015 ;; Optimized for large packets
16 subq 10*4, $r11
17 blt _word_loop
18 move.d $r11, $acr
Mikael Starvik51533b62005-07-27 11:44:44 -070019
20 subq 9*4,$sp
Jesper Nilsson41f94122008-01-25 17:54:14 +010021 clearf c
Mikael Starvik51533b62005-07-27 11:44:44 -070022 movem $r8,[$sp]
23
24 ;; do a movem checksum
25
26_mloop: movem [$r10+],$r9 ; read 10 longwords
Jesper Nilsson41f94122008-01-25 17:54:14 +010027 ;; Loop count without touching the c flag.
28 addoq -10*4, $acr, $acr
Mikael Starvik51533b62005-07-27 11:44:44 -070029 ;; perform dword checksumming on the 10 longwords
30
Jesper Nilsson41f94122008-01-25 17:54:14 +010031 addc $r0,$r12
Mikael Starvik51533b62005-07-27 11:44:44 -070032 addc $r1,$r12
33 addc $r2,$r12
34 addc $r3,$r12
35 addc $r4,$r12
36 addc $r5,$r12
37 addc $r6,$r12
38 addc $r7,$r12
39 addc $r8,$r12
40 addc $r9,$r12
41
Jesper Nilsson41f94122008-01-25 17:54:14 +010042 ;; test $acr without trashing carry.
43 move.d $acr, $acr
44 bpl _mloop
45 ;; r11 <= acr is not really needed in the mloop, just using the dslot
46 ;; to prepare for what is needed after mloop.
47 move.d $acr, $r11
Mikael Starvik51533b62005-07-27 11:44:44 -070048
Jesper Nilsson41f94122008-01-25 17:54:14 +010049 ;; fold the last carry into r13
50 addc 0, $r12
Mikael Starvik51533b62005-07-27 11:44:44 -070051 movem [$sp+],$r8 ; restore regs
52
53_word_loop:
Jesper Nilsson41f94122008-01-25 17:54:14 +010054 addq 10*4,$r11 ; compensate for last loop underflowing length
Mikael Starvik51533b62005-07-27 11:44:44 -070055
56 moveq -1,$r9 ; put 0xffff in r9, faster than move.d 0xffff,r9
57 lsrq 16,$r9
58
59 move.d $r12,$r13
60 lsrq 16,$r13 ; r13 = checksum >> 16
Jesper Nilsson41f94122008-01-25 17:54:14 +010061 and.d $r9,$r12 ; checksum = checksum & 0xffff
Mikael Starvik51533b62005-07-27 11:44:44 -070062
63_no_fold:
Jesper Nilsson41f94122008-01-25 17:54:14 +010064 subq 2,$r11
Mikael Starvik51533b62005-07-27 11:44:44 -070065 blt _no_words
Jesper Nilsson41f94122008-01-25 17:54:14 +010066 add.d $r13,$r12 ; checksum += r13
Mikael Starvik51533b62005-07-27 11:44:44 -070067
68 ;; checksum the rest of the words
Mikael Starvik51533b62005-07-27 11:44:44 -070069_wloop: subq 2,$r11
70 bge _wloop
71 addu.w [$r10+],$r12
72
Mikael Starvik51533b62005-07-27 11:44:44 -070073_no_words:
Jesper Nilsson41f94122008-01-25 17:54:14 +010074 addq 2,$r11
Mikael Starvik51533b62005-07-27 11:44:44 -070075 ;; see if we have one odd byte more
Jesper Nilsson41f94122008-01-25 17:54:14 +010076 bne _do_byte
Mikael Starvik51533b62005-07-27 11:44:44 -070077 nop
78 ret
79 move.d $r12,$r10
80
81_do_byte:
82 ;; copy and checksum the last byte
83 addu.b [$r10],$r12
84 ret
85 move.d $r12,$r10