1/* $NetBSD: cpu_in_cksum.S,v 1.2 2008/02/02 02:15:40 uwe Exp $ */ 2 3/*- 4 * Copyright (c) 2000 SHIMIZU Ryo <ryo@misakimix.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <machine/endian.h> 31#include <machine/asm.h> 32#include "assym.h" 33 34__KERNEL_RCSID(0, "$NetBSD: cpu_in_cksum.S,v 1.2 2008/02/02 02:15:40 uwe Exp $") 35 36 37#define reg_tmp0 r0 38#define reg_byte_swapped r1 39#define reg_mlen r2 40#define reg_tmp3 r3 41#define reg_m r4 42#define reg_len r5 43#define reg_off r6 44#define reg_w r6 /* recycle */ 45#define reg_sum r7 46 47 48#define REDUCE \ 49 swap.w reg_sum,reg_tmp0 ; \ 50 extu.w reg_sum,reg_sum ; \ 51 extu.w reg_tmp0,reg_tmp0 ; \ 52 add reg_tmp0,reg_sum 53 54#define ROL \ 55 shll8 reg_sum 56 57#if _BYTE_ORDER == BIG_ENDIAN 58#define ADDB \ 59 mov.b @reg_w+,reg_tmp0 ; \ 60 ROL ; \ 61 extu.b reg_tmp0,reg_tmp0 ; \ 62 add reg_tmp0,reg_sum ; \ 63 not reg_byte_swapped,reg_byte_swapped 64#else 65#define ADDB \ 66 mov.b @reg_w+,reg_tmp0 ; \ 67 extu.b reg_tmp0,reg_tmp0 ; \ 68 add reg_tmp0,reg_sum ; \ 69 ROL ; \ 70 not reg_byte_swapped,reg_byte_swapped 71#endif 72 73 74#define ADDS \ 75 mov.w @reg_w+,reg_tmp0 ; \ 76 extu.w reg_tmp0,reg_tmp0 ; \ 77 add reg_tmp0,reg_sum 78 79#define ADDCL \ 80 mov.l @reg_w+,reg_tmp0 ; \ 81 addc reg_tmp0,reg_sum 82 83#define FORWARD1 \ 84 add #-1,reg_mlen 85 86#define FORWARD2 \ 87 add #-2,reg_mlen 88 89 90/* 91 * LINTSTUB: include <sys/param.h> 92 * LINTSTUB: include <sys/mbuf.h> 93 * 94 * LINTSTUB: Func: int cpu_in_cksum(struct mbuf *m, int len, int off, uint32_t initial_sum); 95 */ 96ENTRY(cpu_in_cksum) 97 sts.l pr,@-sp 98 99 tst reg_len, reg_len 100 bt/s mbuf_loop_done 101 mov #0, reg_byte_swapped 102 103.L_mbuf_skip: 104 tst reg_m, reg_m 105 bt out_of_mbufs 106 107 mov.l @(M_LEN, reg_m), reg_mlen 108 cmp/gt reg_off, reg_mlen /* mlen > off ? */ 109 bt .L_mbuf_found 110 111 !! while (off >= mlen) 112 mov.l @(M_NEXT, reg_m), reg_m ! m = m->m_next 113 bra .L_mbuf_skip 114 sub reg_mlen, reg_off ! off -= mlen 115 116 117.L_mbuf_found: !! if (mlen > off) 118 mov.l @(M_DATA, reg_m), reg_tmp3 119 sub reg_off, reg_mlen ! mlen -= off 120 bra .L_mbuf_loop_enter 121 add reg_tmp3, reg_off ! w = m->m_data + off 122 123#undef reg_off /* it is dead now and we recycle it for reg_w */ 124 125 126mbuf_loop: 127 tst reg_m,reg_m 128 bt out_of_mbufs 129 130 mov.l @(M_LEN,reg_m),reg_mlen 131 tst reg_mlen,reg_mlen 132 bt/s mbuf_loop_continue 133 mov.l @(M_DATA,reg_m),reg_w 134 135 136 !! Entry point for mbuf loop. We jump here after we have 137 !! found the mbuf (reg_m) that contains data at the specified 138 !! offset. reg_mlen and reg_w were adjusted to point at the 139 !! first interesting byte of data. 140.L_mbuf_loop_enter: 141 cmp/ge reg_mlen,reg_len 142 bt 1f 143 mov reg_len,reg_mlen 1441: 145 sub reg_mlen,reg_len 146 147 148 mov reg_w,reg_tmp0 149 tst #1,reg_tmp0 150 bt/s 1f 151 REDUCE /* 1st instruction break only reg_tmp0(r0) */ 152 ADDB 153 FORWARD1 1541: 155 156 157 mov #1,reg_tmp0 158 cmp/gt reg_tmp0,reg_mlen 159 bf/s 1f 160 mov reg_w,reg_tmp0 161 tst #2,reg_tmp0 162 bt/s 1f 163 REDUCE /* 1st instruction break only reg_tmp0(r0) */ 164 ADDS 165 FORWARD2 1661: 167 168 169 170 mov #127,reg_tmp0 171 cmp/hi reg_tmp0,reg_mlen 172 bf 1f 173 174do_cksum128: 175 bsr cksum128 176 nop 177 178 mov #127,reg_tmp0 179 cmp/hi reg_tmp0,reg_mlen 180 bt do_cksum128 1811: 182 183 184 bsr cksum128mod 185 nop 186 187 REDUCE 188 189 mov #1,reg_tmp0 190 cmp/gt reg_tmp0,reg_mlen 191 bf 1f 192 ADDS 193 FORWARD2 1941: 195 196 mov reg_mlen,r0 197 tst #1,r0 198 bt 1f 199 ADDB 2001: 201 202 203mbuf_loop_continue: 204 mov.l @(M_NEXT,reg_m),reg_m 205 206 tst reg_len,reg_len 207 bf/s mbuf_loop 208mbuf_loop_done: 209 210 211 tst reg_byte_swapped,reg_byte_swapped 212 bt/s 1f 213 REDUCE /* 1st instruction break only reg_tmp0(r0) */ 214 ROL 2151: 216 217 REDUCE 218 REDUCE 219 220in_cksum_return: 221 not reg_sum,r0 222 lds.l @sp+,pr 223 rts 224 extu.w r0,r0 225 226 227out_of_mbufs: 228 mova .L_message_out_of_data,reg_tmp0 229 mov.l .L_printf,reg_tmp3 230 231 mov.l reg_sum,@-sp /* save: call clobbered register */ 232 233 jsr @reg_tmp3 234 mov reg_tmp0,r4 235 236 bra in_cksum_return 237 mov.l @sp+,reg_sum /* restore */ 238 239 .align 2 240.L_printf: 241 .long _C_LABEL(printf) 242 243 .align 2 /* mova target */ 244.L_message_out_of_data: 245 .asciz "cksum: out of data (%d byte short)\n" 246 247 SET_ENTRY_SIZE(in_cksum) 248 249 250 .align 2 251cksum128mod: 252 mov reg_mlen,reg_tmp0 253 and #124,reg_tmp0 254 sub reg_tmp0,reg_mlen 255 256 mov.l .L_cksum128_tail_p,reg_tmp3 257 sub reg_tmp0,reg_tmp3 258 jmp @reg_tmp3 259 clrt 260 261 .align 2 262.L_cksum128_tail_p: 263 .long cksum128_tail 264 265 266 .align 2 267cksum128: 268 add #-128,reg_mlen 269 clrt 270 271cksum128_unroll: 272 ADDCL 273 ADDCL 274 ADDCL 275 ADDCL 276 ADDCL 277 ADDCL 278 ADDCL 279 ADDCL 280 ADDCL 281 ADDCL 282 ADDCL 283 ADDCL 284 ADDCL 285 ADDCL 286 ADDCL 287 ADDCL 288 ADDCL 289 ADDCL 290 ADDCL 291 ADDCL 292 ADDCL 293 ADDCL 294 ADDCL 295 ADDCL 296 ADDCL 297 ADDCL 298 ADDCL 299 ADDCL 300 ADDCL 301 ADDCL 302 ADDCL 303 ADDCL 304cksum128_tail: 305 mov #0,reg_tmp0 306 rts 307 addc reg_tmp0,reg_sum 308