1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <linux/linkage.h>
26
27#define ADDC(sum,reg) \
28 add sum, sum, reg; \
29 cmp.c reg, sum; \
30 bleu 9f; \
31 addi sum, 0x1; \
329:
33
34#define CSUM_BIGCHUNK(src, offset, sum) \
35 lw r8, [src, offset + 0x00]; \
36 lw r9, [src, offset + 0x04]; \
37 lw r10, [src, offset + 0x08]; \
38 lw r11, [src, offset + 0x0c]; \
39 ADDC(sum, r8); \
40 ADDC(sum, r9); \
41 ADDC(sum, r10); \
42 ADDC(sum, r11); \
43 lw r8, [src, offset + 0x10]; \
44 lw r9, [src, offset + 0x14]; \
45 lw r10, [src, offset + 0x18]; \
46 lw r11, [src, offset + 0x1c]; \
47 ADDC(sum, r8); \
48 ADDC(sum, r9); \
49 ADDC(sum, r10); \
50 ADDC(sum, r11); \
51
52#define src r4
53#define dest r5
54#define sum r27
55
56 .text
57
58small_csumcpy:
59 mv r5, r10
60 ldi r9, 0x0
61 cmpi.c r25, 0x1
62 beq pass_small_set_t7
63 andri.c r25,r4 , 0x1
64
65pass_small_set_t7:
66 beq aligned
67 cmpi.c r5, 0x0
68 beq fold
69 lbu r9, [src]
70 slli r9,r9, 0x8
71 ADDC(sum, r9)
72 addi src, 0x1
73 subi.c r5, 0x1
74
75
76aligned:
77 andri.c r8, r5, 0x4
78 beq len_less_4bytes
79
80
81 andri.c r8, src, 0x3
82 beq four_byte_aligned
83 lhu r9, [src]
84 addi src, 2
85 ADDC(sum, r9)
86 lhu r9, [src]
87 addi src, 2
88 ADDC(sum, r9)
89 b len_less_4bytes
90
91four_byte_aligned:
92 lw r9, [src]
93 addi src, 4
94 ADDC(sum, r9)
95
96len_less_4bytes:
97 andri.c r8, r5, 0x2
98 beq len_less_2bytes
99 lhu r9, [src]
100 addi src, 0x2
101 ADDC(sum, r9)
102
103len_less_2bytes:
104 andri.c r8, r5, 0x1
105 beq fold
106 lbu r9, [src]
107
108fold_ADDC:
109 ADDC(sum, r9)
110fold:
111
112 slli r26, sum, 16
113 add sum, sum, r26
114 cmp.c r26, sum
115 srli sum, sum, 16
116 bleu 1f
117 addi sum, 0x1
1181:
119
120 cmpi.c r25, 0x0
121 beq 1f
122 slli r26, sum, 8
123 srli sum, sum, 8
124 or sum, sum, r26
125 andi sum, 0xffff
1261:
127 .set optimize
128
129 ADDC(sum, r6)
130 mv r4, sum
131 br r3
132 .set volatile
133
134 .align 5
135ENTRY(csum_partial)
136 ldi sum, 0
137 ldi r25, 0
138 mv r10, r5
139 cmpi.c r5, 0x8
140 blt small_csumcpy
141 cmpi.c r5, 0x0
142 beq out
143 andri.c r25, src, 0x1
144
145 beq word_align
146hword_align:
147 lbu r8, [src]
148 subi r5, 0x1
149 slli r8, r8, 8
150 ADDC(sum, r8)
151 addi src, 0x1
152
153word_align:
154 andri.c r8, src, 0x2
155 beq dword_align
156 lhu r8, [src]
157 subi r5, 0x2
158 ADDC(sum, r8)
159 addi src, 0x2
160
161dword_align:
162 mv r26, r5
163 ldi r8, 56
164 cmp.c r8, r5
165 bgtu do_end_words
166 andri.c r26, src, 0x4
167 beq qword_align
168 lw r8, [src]
169 subi r5, 0x4
170 ADDC(sum, r8)
171 addi src, 0x4
172
173qword_align:
174 andri.c r26, src, 0x8
175 beq oword_align
176 lw r8, [src, 0x0]
177 lw r9, [src, 0x4]
178 subi r5, 0x8
179 ADDC(sum, r8)
180 ADDC(sum, r9)
181 addi src, 0x8
182
183oword_align:
184 andri.c r26, src, 0x10
185 beq begin_movement
186 lw r10, [src, 0x08]
187 lw r11, [src, 0x0c]
188 lw r8, [src, 0x00]
189 lw r9, [src, 0x04]
190 ADDC(sum, r10)
191 ADDC(sum, r11)
192 ADDC(sum, r8)
193 ADDC(sum, r9)
194 subi r5, 0x10
195 addi src, 0x10
196
197begin_movement:
198 srli.c r26, r5, 0x7
199 beq 1f
200
201
202move_128bytes:
203 CSUM_BIGCHUNK(src, 0x00, sum)
204 CSUM_BIGCHUNK(src, 0x20, sum)
205 CSUM_BIGCHUNK(src, 0x40, sum)
206 CSUM_BIGCHUNK(src, 0x60, sum)
207 subi.c r26, 0x01
208 addi src, 0x80
209 bne move_128bytes
210
2111:
212 andri.c r10, r5, 0x40
213 beq 1f
214
215move_64bytes:
216 CSUM_BIGCHUNK(src, 0x00, sum)
217 CSUM_BIGCHUNK(src, 0x20, sum)
218 addi src, 0x40
219
2201:
221 andri r26, r5, 0x1c
222 andri.c r10, r5, 0x20
223 beq do_end_words
224
225move_32bytes:
226 CSUM_BIGCHUNK(src, 0x00, sum)
227 andri r26, r5, 0x1c
228 addri src, src, 0x20
229
230do_end_words:
231
232 cmpi.c r26, 0x0
233 beq maybe_end_cruft
234 srli r26, r26, 0x2
235
236end_words:
237 lw r8, [src]
238 subi.c r26, 0x1
239 ADDC(sum, r8)
240 addi src, 0x4
241 cmpi.c r26, 0x0
242 bne end_words
243
244maybe_end_cruft:
245 andri r10, r5, 0x3
246
247small_memcpy:
248 mv r5, r10
249 j small_csumcpy
250
251out:
252 mv r4, sum
253 br r3
254
255END(csum_partial)
256