Annotation of sys/arch/i386/i386/in_cksum.s, Revision 1.1.1.1
1.1 nbrk 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"
CVSweb