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