Annotation of sys/arch/sparc64/sparc64/in_cksum.S, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: in_cksum.S,v 1.2 2005/05/01 05:42:43 brad Exp $ */
! 2: /* $NetBSD: in_cksum.S,v 1.2 2001/08/10 20:53:11 eeh Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 2001 Eduardo Horvath
! 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. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by Eduardo Horvath.
! 18: * 4. The name of the author may not be used to endorse or promote products
! 19: * derived from this software without specific prior written permission
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 22: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 23: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 24: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 25: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 26: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 27: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 28: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 29: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 30: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 31: */
! 32:
! 33: #include "assym.h"
! 34: #include <machine/asm.h>
! 35:
! 36: /*
! 37: * int in_cksum(struct mbuf *m, int len)
! 38: * int in_cksum_internal(struct mbuf *m, int len, int offset, int sum)
! 39: *
! 40: * The only fields of the mbuf we really care about
! 41: * is m_next and m_len and m_data.
! 42: *
! 43: *
! 44: * Register usage:
! 45: *
! 46: * %o0 - mbuf
! 47: * %o1 - len
! 48: * %o2 - mlen
! 49: * %o3 - sum
! 50: * %o4 - temp
! 51: * %o5 - mdata
! 52: * %g1 - swapped
! 53: * %g4 - temp
! 54: * %g5 - temp
! 55: */
! 56:
! 57: #define IALIGN .align 32
! 58:
! 59: ENTRY(in_cksum)
! 60: clr %o3 ! sum = 0;
! 61: clr %o2
! 62: _ENTRY(_C_LABEL(in_cksum_internal))
! 63: brz %o0, Lfinish ! for (; m && len > 0; m->m_next) {
! 64: clr %g1 ! swapped = 0;
! 65: brlez %o1, Lfinish
! 66: mov %o2, %o4 ! Stash this elsewhere for a bit
! 67:
! 68: lduw [%o0 + M_LEN], %o2 ! Code duplicated at Lloop
! 69: srlx %o3, 32, %g4 ! REDUCE bigtime
! 70: sethi %hi(0xffff), %g5
! 71: ldx [%o0 + M_DATA], %o5
! 72: srl %o3, 0, %o3
! 73: or %g5, %lo(0xffff), %g5
! 74:
! 75: sub %o2, %o4, %o2 ! Correct for initial offset
! 76: ba,pt %icc, 0f
! 77: add %o5, %o4, %o5
! 78:
! 79: IALIGN
! 80: Lloop:
! 81: lduw [%o0 + M_LEN], %o2
! 82: srlx %o3, 32, %g4 ! REDUCE bigtime
! 83: sethi %hi(0xffff), %g5
! 84: ldx [%o0 + M_DATA], %o5
! 85: srl %o3, 0, %o3
! 86: or %g5, %lo(0xffff), %g5
! 87: 0:
! 88: add %o3, %g4, %o3
! 89: brz %o2, Lnext ! if (m->m_len == 0) continue;
! 90:
! 91: cmp %o1, %o2 ! if (len < mlen)
! 92: movl %icc, %o1, %o2 ! mlen = len;
! 93:
! 94: btst 3, %o5 ! if (!(*w & 3)) {
! 95: bz Lint_aligned
! 96: sub %o1, %o2, %o1 ! len -= mlen
! 97:
! 98: srlx %o3, 16, %o4 ! REDUCE {sum = (sum & 0xffff) + (sum >> 16);}
! 99: and %o3, %g5, %o3
! 100:
! 101: add %o3, %o4, %o3
! 102: btst 1, %o5 ! if (!(*w & 3) &&
! 103: bz Lshort_aligned
! 104: nop
! 105:
! 106: deccc %o2
! 107: bl,a,pn %icc, Lnext ! mlen >= 1) {
! 108: inc %o2
! 109: ldub [%o5], %o4 ! ADDBYTE {ROL; sum += *w; byte_swapped ^= 1;}
! 110: sllx %o3, 8, %o3 ! ROL { sum = sum << 8; }
! 111: inc %o5 ! }
! 112: add %o3, %o4, %o3
! 113: xor %g1, 1, %g1 ! Flip byte_swapped
! 114:
! 115: Lshort_aligned:
! 116: btst 2, %o5 ! if (!(*w & 3) &&
! 117: bz Lint_aligned
! 118: nop
! 119:
! 120: deccc 2, %o2 ! mlen >= 1) {
! 121: bl,a,pn %icc, Lfinish_byte
! 122: inc 2, %o2
! 123: lduh [%o5], %o4 ! ADDSHORT {sum += *(u_short *)w;}
! 124: inc 2, %o5 ! }
! 125: add %o3, %o4, %o3 ! }
! 126: Lint_aligned:
! 127: deccc 0xc, %o2 ! while (mlen >= 12) {
! 128: ble,pn %icc, Ltoofar
! 129: clr %g5
! 130: ba,pt %icc, 0f
! 131: clr %g4
! 132: IALIGN
! 133: 0:
! 134: lduw [%o5 + 0x00], %o4
! 135: add %o3, %g4, %o3
! 136: deccc 0xc, %o2
! 137: lduw [%o5 + 0x04], %g4
! 138: add %o3, %g5, %o3
! 139: lduw [%o5 + 0x08], %g5
! 140: inc 0xc, %o5 ! ADVANCE(12) }
! 141: bg,pt %icc, 0b
! 142: add %o3, %o4, %o3
! 143: add %o3, %g4, %o3
! 144: add %o3, %g5, %o3
! 145: Ltoofar:
! 146: inc 0xc, %o2
! 147:
! 148: Ldo_int:
! 149: deccc 4, %o2
! 150: bl,pn %icc, Lfinish_short
! 151: nop
! 152: 0:
! 153: lduw [%o5], %o4
! 154: inc 4, %o5
! 155: deccc 4, %o2
! 156: bge,pt %icc, 0b
! 157: add %o3, %o4, %o3
! 158:
! 159: Lfinish_short:
! 160: btst 2, %o2
! 161: bz Lfinish_byte
! 162: nop
! 163: lduh [%o5], %o4
! 164: inc 2, %o5
! 165: add %o3, %o4, %o3
! 166:
! 167: Lfinish_byte:
! 168: btst 1, %o2
! 169: bz Lnext
! 170: nop
! 171: ldub [%o5], %o4
! 172: sllx %o3, 8, %o3 ! ROL { sum = sum << 8; }
! 173: inc %o5
! 174: xor %g1, 1, %g1 ! Flip byte_swapped
! 175: add %o3, %o4, %o3
! 176:
! 177: Lnext:
! 178: ldx [%o0 + M_NEXT], %o0
! 179: Lfinish:
! 180: srlx %o3, 32, %o4 ! Reduce to 32-bits
! 181: srl %o3, 0, %o3
! 182: brz,pt %o0, 1f ! In general there is only one mbuf
! 183: add %o3, %o4, %o3
! 184: brgz,pt %o1, Lloop ! But usually all need to be fully checksummed
! 185: nop
! 186: 1:
! 187: sethi %hi(0x0000ffff), %o5 ! data ptr not needed any more
! 188:
! 189: srlx %o3, 16, %o4
! 190: or %o5, %lo(0x0000ffff), %o5
! 191:
! 192: and %o3, %o5, %o3
! 193:
! 194: add %o3, %o4, %o3
! 195: brz,pt %g1, 0f ! if (byte_swapped) {
! 196: nop
! 197:
! 198: sllx %o3, 8, %o3 ! ROL
! 199:
! 200: srlx %o3, 16, %o4 ! REDUCE
! 201: and %o3, %o5, %o3
! 202:
! 203: add %o3, %o4, %o3
! 204: 0:
! 205: subcc %o3, %o5, %o4 ! if (sum > 0xffff)
! 206: movg %icc, %o4, %o3 ! sum -= 0xffff;
! 207:
! 208: clr %g4 ! In case we are using EMBEDANY (ick)
! 209: retl
! 210: xor %o3, %o5, %o0 ! return (0xffff ^ sum);
CVSweb