1 /* $OpenBSD: in_cksum.s,v 1.7 2005/05/21 19:13:55 brad Exp $ */
2 /* $NetBSD: in_cksum.S,v 1.2 2003/08/07 16:27:54 agc Exp $ */
3
4 /*-
5 * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Charles M. Hannum.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*-
41 * Copyright (c) 1990 The Regents of the University of California.
42 * All rights reserved.
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 * 3. Neither the name of the University nor the names of its contributors
53 * may be used to endorse or promote products derived from this software
54 * without specific prior written permission.
55 *
56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 * SUCH DAMAGE.
67 */
68
69 #include <machine/asm.h>
70 #include "assym.h"
71
72 /* LINTSTUB: include <sys/types.h> */
73 /* LINTSTUB: include <machine/param.h> */
74 /* LINTSTUB: include <sys/mbuf.h> */
75 /* LINTSTUB: include <netinet/in.h> */
76
77 /*
78 * Checksum routine for Internet Protocol family headers.
79 *
80 * in_cksum(m, len)
81 *
82 * Registers used:
83 * %eax = sum
84 * %ebx = m->m_data
85 * %cl = rotation count to unswap
86 * %edx = m->m_len
87 * %ebp = m
88 * %esi = len
89 */
90
91 #define SWAP \
92 roll $8, %eax ; \
93 xorb $8, %cl
94
95 #define UNSWAP \
96 roll %cl, %eax
97
98 #define MOP \
99 adcl $0, %eax
100
101 #define ADVANCE(n) \
102 leal n(%ebx), %ebx ; \
103 leal -n(%edx), %edx ; \
104
105 #define ADDBYTE \
106 SWAP ; \
107 addb (%ebx), %ah
108
109 #define ADDWORD \
110 addw (%ebx), %ax
111
112 #define ADD(n) \
113 addl n(%ebx), %eax
114
115 #define ADC(n) \
116 adcl n(%ebx), %eax
117
118 #define REDUCE \
119 movzwl %ax, %edx ; \
120 shrl $16, %eax ; \
121 addw %dx, %ax ; \
122 adcw $0, %ax
123
124
125 /* LINTSTUB: Func: int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len) */
126 ENTRY(in4_cksum)
127 pushl %ebp
128 pushl %ebx
129 pushl %esi
130
131 movl 16(%esp), %ebp
132 movzbl 20(%esp), %eax /* sum = nxt */
133 movl 24(%esp), %edx /* %edx = off */
134 movl 28(%esp), %esi /* %esi = len */
135 testl %eax, %eax
136 jz .Lmbuf_loop_0 /* skip if nxt == 0 */
137 movl M_DATA(%ebp), %ebx
138 addl %esi, %eax /* sum += len */
139 shll $8, %eax /* sum = htons(sum) */
140
141 ADD(IP_SRC) /* sum += ip->ip_src */
142 ADC(IP_DST) /* sum += ip->ip_dst */
143 MOP
144 .Lmbuf_loop_0:
145 testl %ebp, %ebp
146 jz .Lout_of_mbufs
147
148 movl M_DATA(%ebp), %ebx /* %ebx = m_data */
149 movl M_LEN(%ebp), %ecx /* %ecx = m_len */
150 movl M_NEXT(%ebp), %ebp
151
152 subl %ecx, %edx /* %edx = off - m_len */
153 jnb .Lmbuf_loop_0
154
155 addl %edx, %ebx /* %ebx = m_data + off - m_len */
156 negl %edx /* %edx = m_len - off */
157 addl %ecx, %ebx /* %ebx = m_data + off */
158 xorb %cl, %cl
159
160 /*
161 * The len == 0 case is handled really inefficiently, by going through
162 * the whole short_mbuf path once to get back to mbuf_loop_1 -- but
163 * this case never happens in practice, so it's sufficient that it
164 * doesn't explode.
165 */
166 jmp .Lin4_entry
167
168
169 /* LINTSTUB: Func: int in_cksum(struct mbuf *m, int len) */
170 ENTRY(in_cksum)
171 pushl %ebp
172 pushl %ebx
173 pushl %esi
174
175 movl 16(%esp), %ebp
176 movl 20(%esp), %esi
177 xorl %eax, %eax
178 xorb %cl, %cl
179
180 .Lmbuf_loop_1:
181 testl %esi, %esi
182 jz .Ldone
183
184 .Lmbuf_loop_2:
185 testl %ebp, %ebp
186 jz .Lout_of_mbufs
187
188 movl M_DATA(%ebp), %ebx
189 movl M_LEN(%ebp), %edx
190 movl M_NEXT(%ebp), %ebp
191
192 .Lin4_entry:
193 cmpl %esi, %edx
194 jbe 1f
195 movl %esi, %edx
196
197 1:
198 subl %edx, %esi
199
200 cmpl $32, %edx
201 jb .Lshort_mbuf
202
203 testb $3, %bl
204 jz .Ldword_aligned
205
206 testb $1, %bl
207 jz .Lbyte_aligned
208
209 ADDBYTE
210 ADVANCE(1)
211 MOP
212
213 testb $2, %bl
214 jz .Lword_aligned
215
216 .Lbyte_aligned:
217 ADDWORD
218 ADVANCE(2)
219 MOP
220
221 .Lword_aligned:
222 .Ldword_aligned:
223 testb $4, %bl
224 jnz .Lqword_aligned
225
226 ADD(0)
227 ADVANCE(4)
228 MOP
229
230 .Lqword_aligned:
231 testb $8, %bl
232 jz .Loword_aligned
233
234 ADD(0)
235 ADC(4)
236 ADVANCE(8)
237 MOP
238
239 .Loword_aligned:
240 subl $128, %edx
241 jb .Lfinished_128
242
243 .Lloop_128:
244 ADD(12)
245 ADC(0)
246 ADC(4)
247 ADC(8)
248 ADC(28)
249 ADC(16)
250 ADC(20)
251 ADC(24)
252 ADC(44)
253 ADC(32)
254 ADC(36)
255 ADC(40)
256 ADC(60)
257 ADC(48)
258 ADC(52)
259 ADC(56)
260 ADC(76)
261 ADC(64)
262 ADC(68)
263 ADC(72)
264 ADC(92)
265 ADC(80)
266 ADC(84)
267 ADC(88)
268 ADC(108)
269 ADC(96)
270 ADC(100)
271 ADC(104)
272 ADC(124)
273 ADC(112)
274 ADC(116)
275 ADC(120)
276 leal 128(%ebx), %ebx
277 MOP
278
279 subl $128, %edx
280 jnb .Lloop_128
281
282 .Lfinished_128:
283 subl $32-128, %edx
284 jb .Lfinished_32
285
286 .Lloop_32:
287 ADD(12)
288 ADC(0)
289 ADC(4)
290 ADC(8)
291 ADC(28)
292 ADC(16)
293 ADC(20)
294 ADC(24)
295 leal 32(%ebx), %ebx
296 MOP
297
298 subl $32, %edx
299 jnb .Lloop_32
300
301 .Lfinished_32:
302 .Lshort_mbuf:
303 testb $16, %dl
304 jz .Lfinished_16
305
306 ADD(12)
307 ADC(0)
308 ADC(4)
309 ADC(8)
310 leal 16(%ebx), %ebx
311 MOP
312
313 .Lfinished_16:
314 testb $8, %dl
315 jz .Lfinished_8
316
317 ADD(0)
318 ADC(4)
319 leal 8(%ebx), %ebx
320 MOP
321
322 .Lfinished_8:
323 testb $4, %dl
324 jz .Lfinished_4
325
326 ADD(0)
327 leal 4(%ebx), %ebx
328 MOP
329
330 .Lfinished_4:
331 testb $3, %dl
332 jz .Lmbuf_loop_1
333
334 testb $2, %dl
335 jz .Lfinished_2
336
337 ADDWORD
338 leal 2(%ebx), %ebx
339 MOP
340
341 testb $1, %dl
342 jz .Lfinished_1
343
344 .Lfinished_2:
345 ADDBYTE
346 MOP
347
348 .Lfinished_1:
349 .Lmbuf_done:
350 testl %esi, %esi
351 jnz .Lmbuf_loop_2
352
353 .Ldone:
354 UNSWAP
355 REDUCE
356 notw %ax
357
358 .Lreturn:
359 popl %esi
360 popl %ebx
361 popl %ebp
362 ret
363
364 .Lout_of_mbufs:
365 pushl $1f
366 call _C_LABEL(printf)
367 leal 4(%esp), %esp
368 jmp .Lreturn
369 1:
370 .asciz "cksum: out of data\n"