1/* $OpenBSD: in_cksum.S,v 1.2 2006/11/10 19:23:35 miod Exp $ */ 2/* $NetBSD: in_cksum.S,v 1.10 2006/04/11 23:45:13 uwe Exp $ */ 3 4/*- 5 * Copyright (c) 2000 SHIMIZU Ryo <ryo@misakimix.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <machine/asm.h> 32#include "assym.h" 33 34 35#define reg_tmp0 r0 36#define reg_byte_swapped r1 37#define reg_mlen r2 38#define reg_tmp3 r3 39#define reg_m r4 40#define reg_len r5 41#define reg_sum r6 42#define reg_w r7 43 44 45#define REDUCE \ 46 swap.w reg_sum,reg_tmp0 ; \ 47 extu.w reg_sum,reg_sum ; \ 48 extu.w reg_tmp0,reg_tmp0 ; \ 49 add reg_tmp0,reg_sum 50 51#define ROL \ 52 shll8 reg_sum 53 54#ifndef __LITTLE_ENDIAN__ 55#define ADDB \ 56 mov.b @reg_w+,reg_tmp0 ; \ 57 ROL ; \ 58 extu.b reg_tmp0,reg_tmp0 ; \ 59 add reg_tmp0,reg_sum ; \ 60 not reg_byte_swapped,reg_byte_swapped 61#else 62#define ADDB \ 63 mov.b @reg_w+,reg_tmp0 ; \ 64 extu.b reg_tmp0,reg_tmp0 ; \ 65 add reg_tmp0,reg_sum ; \ 66 ROL ; \ 67 not reg_byte_swapped,reg_byte_swapped 68#endif 69 70 71#define ADDS \ 72 mov.w @reg_w+,reg_tmp0 ; \ 73 extu.w reg_tmp0,reg_tmp0 ; \ 74 add reg_tmp0,reg_sum 75 76#define ADDCL \ 77 mov.l @reg_w+,reg_tmp0 ; \ 78 addc reg_tmp0,reg_sum 79 80#define FORWARD1 \ 81 add #-1,reg_mlen 82 83#define FORWARD2 \ 84 add #-2,reg_mlen 85 86 87/* 88 * LINTSTUB: include <sys/param.h> 89 * LINTSTUB: include <sys/mbuf.h> 90 * 91 * LINTSTUB: Func: int in_cksum(struct mbuf *m, int len); 92 */ 93ENTRY(in_cksum) 94 sts.l pr,@-sp 95 96 97 mov #0,reg_sum 98 mov #0,reg_byte_swapped 99 100 101 tst reg_len,reg_len 102 bt/s mbuf_loop_done 103mbuf_loop: 104 tst reg_m,reg_m 105 bt mbuf_loop_done 106 107 mov.l @(M_LEN,reg_m),reg_mlen 108 tst reg_mlen,reg_mlen 109 bt/s mbuf_loop_continue 110 mov.l @(M_DATA,reg_m),reg_w 111 112 113 cmp/ge reg_mlen,reg_len 114 bt 1f 115 mov reg_len,reg_mlen 1161: 117 sub reg_mlen,reg_len 118 119 120 mov reg_w,reg_tmp0 121 tst #1,reg_tmp0 122 bt/s 1f 123 REDUCE /* 1st instruction break only reg_tmp0(r0) */ 124 ADDB 125 FORWARD1 1261: 127 128 129 mov #1,reg_tmp0 130 cmp/gt reg_tmp0,reg_mlen 131 bf/s 1f 132 mov reg_w,reg_tmp0 133 tst #2,reg_tmp0 134 bt/s 1f 135 REDUCE /* 1st instruction break only reg_tmp0(r0) */ 136 ADDS 137 FORWARD2 1381: 139 140 141 142 mov #127,reg_tmp0 143 cmp/hi reg_tmp0,reg_mlen 144 bf 1f 145 146do_cksum128: 147 bsr cksum128 148 nop 149 150 mov #127,reg_tmp0 151 cmp/hi reg_tmp0,reg_mlen 152 bt do_cksum128 1531: 154 155 156 bsr cksum128mod 157 nop 158 159 REDUCE 160 161 mov #1,reg_tmp0 162 cmp/gt reg_tmp0,reg_mlen 163 bf 1f 164 ADDS 165 FORWARD2 1661: 167 168 mov reg_mlen,r0 169 tst #1,r0 170 bt 1f 171 ADDB 1721: 173 174 175mbuf_loop_continue: 176 mov.l @(M_NEXT,reg_m),reg_m 177 178 tst reg_len,reg_len 179 bf/s mbuf_loop 180mbuf_loop_done: 181 182 183 tst reg_byte_swapped,reg_byte_swapped 184 bt/s 1f 185 REDUCE /* 1st instruction break only reg_tmp0(r0) */ 186 ROL 1871: 188 189 REDUCE 190 REDUCE 191 192in_cksum_return: 193 not reg_sum,r0 194 lds.l @sp+,pr 195 rts 196 extu.w r0,r0 197 198 199 SET_ENTRY_SIZE(in_cksum) 200 201 202 .align 2 203cksum128mod: 204 mov reg_mlen,reg_tmp0 205 and #124,reg_tmp0 206 sub reg_tmp0,reg_mlen 207 208 mov.l .L_cksum128_tail_p,reg_tmp3 209 sub reg_tmp0,reg_tmp3 210 jmp @reg_tmp3 211 clrt 212 213 .align 2 214.L_cksum128_tail_p: 215 .long cksum128_tail 216 217 218 .align 2 219cksum128: 220 add #-128,reg_mlen 221 clrt 222 223cksum128_unroll: 224 ADDCL 225 ADDCL 226 ADDCL 227 ADDCL 228 ADDCL 229 ADDCL 230 ADDCL 231 ADDCL 232 ADDCL 233 ADDCL 234 ADDCL 235 ADDCL 236 ADDCL 237 ADDCL 238 ADDCL 239 ADDCL 240 ADDCL 241 ADDCL 242 ADDCL 243 ADDCL 244 ADDCL 245 ADDCL 246 ADDCL 247 ADDCL 248 ADDCL 249 ADDCL 250 ADDCL 251 ADDCL 252 ADDCL 253 ADDCL 254 ADDCL 255 ADDCL 256cksum128_tail: 257 mov #0,reg_tmp0 258 rts 259 addc reg_tmp0,reg_sum 260