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"