Annotation of sys/arch/sparc64/sparc64/in_cksum.S, Revision 1.1.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