blob: 54e209f18b06bd1a9f7fc9ddc2d703351e64048d [file] [log] [blame]
Mikael Starvik51533b62005-07-27 11:44:44 -07001/*
2 * A fast checksum+copy 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 * Authors: Bjorn Wesen
6 *
7 * csum_partial_copy_nocheck(const char *src, char *dst,
8 * int len, unsigned int sum)
9 */
10
11 .globl csum_partial_copy_nocheck
Jesper Nilsson5f9ac922010-08-03 16:13:37 +020012 .type csum_partial_copy_nocheck,@function
Mikael Starvik51533b62005-07-27 11:44:44 -070013csum_partial_copy_nocheck:
14
15 ;; r10 - src
16 ;; r11 - dst
17 ;; r12 - length
18 ;; r13 - checksum
19
Jesper Nilsson41f94122008-01-25 17:54:14 +010020 ;; Optimized for large packets
21 subq 10*4, $r12
22 blt _word_loop
23 move.d $r12, $acr
Mikael Starvik51533b62005-07-27 11:44:44 -070024
25 subq 9*4,$sp
Jesper Nilsson41f94122008-01-25 17:54:14 +010026 clearf c
Mikael Starvik51533b62005-07-27 11:44:44 -070027 movem $r8,[$sp]
28
29 ;; do a movem copy and checksum
Mikael Starvik51533b62005-07-27 11:44:44 -0700301: ;; A failing userspace access (the read) will have this as PC.
31_mloop: movem [$r10+],$r9 ; read 10 longwords
Jesper Nilsson41f94122008-01-25 17:54:14 +010032 addoq -10*4, $acr, $acr ; loop counter in latency cycle
Mikael Starvik51533b62005-07-27 11:44:44 -070033 movem $r9,[$r11+] ; write 10 longwords
34
35 ;; perform dword checksumming on the 10 longwords
Jesper Nilsson41f94122008-01-25 17:54:14 +010036 addc $r0,$r13
Mikael Starvik51533b62005-07-27 11:44:44 -070037 addc $r1,$r13
38 addc $r2,$r13
39 addc $r3,$r13
40 addc $r4,$r13
41 addc $r5,$r13
42 addc $r6,$r13
43 addc $r7,$r13
44 addc $r8,$r13
45 addc $r9,$r13
46
Jesper Nilsson41f94122008-01-25 17:54:14 +010047 ;; test $acr, without trashing carry.
48 move.d $acr, $acr
49 bpl _mloop
50 ;; r12 <= acr is needed after mloop and in the exception handlers.
51 move.d $acr, $r12
Mikael Starvik51533b62005-07-27 11:44:44 -070052
Jesper Nilsson41f94122008-01-25 17:54:14 +010053 ;; fold the last carry into r13
54 addc 0, $r13
Mikael Starvik51533b62005-07-27 11:44:44 -070055 movem [$sp+],$r8 ; restore regs
56
57_word_loop:
Jesper Nilsson41f94122008-01-25 17:54:14 +010058 addq 10*4,$r12 ; compensate for last loop underflowing length
Mikael Starvik51533b62005-07-27 11:44:44 -070059
60 ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
61 ;; r9 can be used as temporary.
Mikael Starvik51533b62005-07-27 11:44:44 -070062 move.d $r13,$r9
63 lsrq 16,$r9 ; r0 = checksum >> 16
64 and.d 0xffff,$r13 ; checksum = checksum & 0xffff
Mikael Starvik51533b62005-07-27 11:44:44 -070065
Jesper Nilsson41f94122008-01-25 17:54:14 +010066 subq 2, $r12
Mikael Starvik51533b62005-07-27 11:44:44 -070067 blt _no_words
Jesper Nilsson41f94122008-01-25 17:54:14 +010068 add.d $r9,$r13 ; checksum += r0
Mikael Starvik51533b62005-07-27 11:44:44 -070069
70 ;; copy and checksum the rest of the words
Mikael Starvik51533b62005-07-27 11:44:44 -0700712: ;; A failing userspace access for the read below will have this as PC.
72_wloop: move.w [$r10+],$r9
73 addu.w $r9,$r13
74 subq 2,$r12
75 bge _wloop
76 move.w $r9,[$r11+]
77
Mikael Starvik51533b62005-07-27 11:44:44 -070078_no_words:
Jesper Nilsson41f94122008-01-25 17:54:14 +010079 addq 2,$r12
80 bne _do_byte
Mikael Starvik51533b62005-07-27 11:44:44 -070081 nop
82 ret
83 move.d $r13,$r10
84
85_do_byte:
86 ;; copy and checksum the last byte
873: ;; A failing userspace access for the read below will have this as PC.
88 move.b [$r10],$r9
89 addu.b $r9,$r13
90 move.b $r9,[$r11]
91 ret
92 move.d $r13,$r10
Jesper Nilsson5f9ac922010-08-03 16:13:37 +020093
94 .size csum_partial_copy_nocheck, . - csum_partial_copy_nocheck