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