xref: /OK3568_Linux_fs/kernel/arch/c6x/lib/csum_64plus.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun; SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun;
3*4882a593Smuzhiyun;  linux/arch/c6x/lib/csum_64plus.s
4*4882a593Smuzhiyun;
5*4882a593Smuzhiyun;  Port on Texas Instruments TMS320C6x architecture
6*4882a593Smuzhiyun;
7*4882a593Smuzhiyun;  Copyright (C) 2006, 2009, 2010, 2011 Texas Instruments Incorporated
8*4882a593Smuzhiyun;  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
9*4882a593Smuzhiyun;
10*4882a593Smuzhiyun#include <linux/linkage.h>
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun;
13*4882a593Smuzhiyun;unsigned int csum_partial_copy_nocheck(const char *src, char * dst,
14*4882a593Smuzhiyun;					int len, int sum)
15*4882a593Smuzhiyun;
16*4882a593Smuzhiyun; A4:	src
17*4882a593Smuzhiyun; B4:	dst
18*4882a593Smuzhiyun; A6:	len
19*4882a593Smuzhiyun; B6:	sum
20*4882a593Smuzhiyun; return csum in A4
21*4882a593Smuzhiyun;
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun	.text
24*4882a593SmuzhiyunENTRY(csum_partial_copy_nocheck)
25*4882a593Smuzhiyun	MVC	.S2	ILC,B30
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun	ZERO	.D1	A9		; csum (a side)
28*4882a593Smuzhiyun||	ZERO	.D2	B9		; csum (b side)
29*4882a593Smuzhiyun||	SHRU	.S2X	A6,2,B5		; len / 4
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun	;; Check alignment and size
32*4882a593Smuzhiyun	AND	.S1	3,A4,A1
33*4882a593Smuzhiyun||	AND	.S2	3,B4,B0
34*4882a593Smuzhiyun	OR	.L2X	B0,A1,B0	; non aligned condition
35*4882a593Smuzhiyun||	MVC	.S2	B5,ILC
36*4882a593Smuzhiyun||	MVK	.D2	1,B2
37*4882a593Smuzhiyun||	MV	.D1X	B5,A1		; words condition
38*4882a593Smuzhiyun  [!A1]	B	.S1	L8
39*4882a593Smuzhiyun   [B0] BNOP	.S1	L6,5
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun	SPLOOP		1
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun	;; Main loop for aligned words
44*4882a593Smuzhiyun	LDW	.D1T1	*A4++,A7
45*4882a593Smuzhiyun	NOP	4
46*4882a593Smuzhiyun	MV	.S2X	A7,B7
47*4882a593Smuzhiyun||	EXTU	.S1	A7,0,16,A16
48*4882a593Smuzhiyun	STW	.D2T2	B7,*B4++
49*4882a593Smuzhiyun||	MPYU	.M2	B7,B2,B8
50*4882a593Smuzhiyun||	ADD	.L1	A16,A9,A9
51*4882a593Smuzhiyun	NOP
52*4882a593Smuzhiyun	SPKERNEL	8,0
53*4882a593Smuzhiyun||	ADD	.L2	B8,B9,B9
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun	ZERO	.D1	A1
56*4882a593Smuzhiyun||	ADD	.L1X	A9,B9,A9	;  add csum from a and b sides
57*4882a593Smuzhiyun
58*4882a593SmuzhiyunL6:
59*4882a593Smuzhiyun  [!A1]	BNOP	.S1	L8,5
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun	;; Main loop for non-aligned words
62*4882a593Smuzhiyun	SPLOOP		2
63*4882a593Smuzhiyun ||	MVK	.L1	1,A2
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun	LDNW	.D1T1	*A4++,A7
66*4882a593Smuzhiyun	NOP		3
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun	NOP
69*4882a593Smuzhiyun	MV	.S2X	A7,B7
70*4882a593Smuzhiyun ||	EXTU	.S1	A7,0,16,A16
71*4882a593Smuzhiyun ||	MPYU	.M1	A7,A2,A8
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun	ADD	.L1	A16,A9,A9
74*4882a593Smuzhiyun	SPKERNEL	6,0
75*4882a593Smuzhiyun ||	STNW	.D2T2	B7,*B4++
76*4882a593Smuzhiyun ||	ADD	.L1	A8,A9,A9
77*4882a593Smuzhiyun
78*4882a593SmuzhiyunL8:	AND	.S2X	2,A6,B5
79*4882a593Smuzhiyun	CMPGT	.L2	B5,0,B0
80*4882a593Smuzhiyun  [!B0]	BNOP	.S1	L82,4
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun	;; Manage half-word
83*4882a593Smuzhiyun	ZERO	.L1	A7
84*4882a593Smuzhiyun||	ZERO	.D1	A8
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun#ifdef CONFIG_CPU_BIG_ENDIAN
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun	LDBU	.D1T1	*A4++,A7
89*4882a593Smuzhiyun	LDBU	.D1T1	*A4++,A8
90*4882a593Smuzhiyun	NOP		3
91*4882a593Smuzhiyun	SHL	.S1	A7,8,A0
92*4882a593Smuzhiyun	ADD	.S1	A8,A9,A9
93*4882a593Smuzhiyun	STB	.D2T1	A7,*B4++
94*4882a593Smuzhiyun||	ADD	.S1	A0,A9,A9
95*4882a593Smuzhiyun	STB	.D2T1	A8,*B4++
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun#else
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun	LDBU	.D1T1	*A4++,A7
100*4882a593Smuzhiyun	LDBU	.D1T1	*A4++,A8
101*4882a593Smuzhiyun	NOP		3
102*4882a593Smuzhiyun	ADD	.S1	A7,A9,A9
103*4882a593Smuzhiyun	SHL	.S1	A8,8,A0
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun	STB	.D2T1	A7,*B4++
106*4882a593Smuzhiyun||	ADD	.S1	A0,A9,A9
107*4882a593Smuzhiyun	STB	.D2T1	A8,*B4++
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun#endif
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun	;; Manage eventually the last byte
112*4882a593SmuzhiyunL82:	AND	.S2X	1,A6,B0
113*4882a593Smuzhiyun  [!B0]	BNOP	.S1	L9,5
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun||	ZERO	.L1	A7
116*4882a593Smuzhiyun
117*4882a593SmuzhiyunL83:	LDBU	.D1T1	*A4++,A7
118*4882a593Smuzhiyun	NOP		4
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun	MV	.L2X	A7,B7
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun#ifdef CONFIG_CPU_BIG_ENDIAN
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun	STB	.D2T2	B7,*B4++
125*4882a593Smuzhiyun||	SHL	.S1	A7,8,A7
126*4882a593Smuzhiyun	ADD	.S1	A7,A9,A9
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun#else
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun	STB	.D2T2	B7,*B4++
131*4882a593Smuzhiyun||	ADD	.S1	A7,A9,A9
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun#endif
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun	;; Fold the csum
136*4882a593SmuzhiyunL9:	SHRU	.S2X	A9,16,B0
137*4882a593Smuzhiyun  [!B0]	BNOP	.S1	L10,5
138*4882a593Smuzhiyun
139*4882a593SmuzhiyunL91:	SHRU	.S2X	A9,16,B4
140*4882a593Smuzhiyun||	EXTU	.S1	A9,16,16,A3
141*4882a593Smuzhiyun	ADD	.D1X	A3,B4,A9
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun	SHRU	.S1	A9,16,A0
144*4882a593Smuzhiyun   [A0]	BNOP	.S1	L91,5
145*4882a593Smuzhiyun
146*4882a593SmuzhiyunL10:	MV	.D1	A9,A4
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun	BNOP	.S2	B3,4
149*4882a593Smuzhiyun	MVC	.S2	B30,ILC
150*4882a593SmuzhiyunENDPROC(csum_partial_copy_nocheck)
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun;
153*4882a593Smuzhiyun;unsigned short
154*4882a593Smuzhiyun;ip_fast_csum(unsigned char *iph, unsigned int ihl)
155*4882a593Smuzhiyun;{
156*4882a593Smuzhiyun;	unsigned int checksum = 0;
157*4882a593Smuzhiyun;	unsigned short *tosum = (unsigned short *) iph;
158*4882a593Smuzhiyun;	int len;
159*4882a593Smuzhiyun;
160*4882a593Smuzhiyun;	len = ihl*4;
161*4882a593Smuzhiyun;
162*4882a593Smuzhiyun;	if (len <= 0)
163*4882a593Smuzhiyun;		return 0;
164*4882a593Smuzhiyun;
165*4882a593Smuzhiyun;	while(len) {
166*4882a593Smuzhiyun;		len -= 2;
167*4882a593Smuzhiyun;		checksum += *tosum++;
168*4882a593Smuzhiyun;	}
169*4882a593Smuzhiyun;	if (len & 1)
170*4882a593Smuzhiyun;		checksum += *(unsigned char*) tosum;
171*4882a593Smuzhiyun;
172*4882a593Smuzhiyun;	while(checksum >> 16)
173*4882a593Smuzhiyun;		checksum = (checksum & 0xffff) + (checksum >> 16);
174*4882a593Smuzhiyun;
175*4882a593Smuzhiyun;	return ~checksum;
176*4882a593Smuzhiyun;}
177*4882a593Smuzhiyun;
178*4882a593Smuzhiyun; A4:	iph
179*4882a593Smuzhiyun; B4:	ihl
180*4882a593Smuzhiyun; return checksum in A4
181*4882a593Smuzhiyun;
182*4882a593Smuzhiyun	.text
183*4882a593Smuzhiyun
184*4882a593SmuzhiyunENTRY(ip_fast_csum)
185*4882a593Smuzhiyun	ZERO	.D1	A5
186*4882a593Smuzhiyun ||	MVC	.S2	ILC,B30
187*4882a593Smuzhiyun	SHL	.S2	B4,2,B0
188*4882a593Smuzhiyun	CMPGT	.L2	B0,0,B1
189*4882a593Smuzhiyun  [!B1] BNOP	.S1	L15,4
190*4882a593Smuzhiyun  [!B1]	ZERO	.D1	A3
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun  [!B0]	B	.S1	L12
193*4882a593Smuzhiyun	SHRU	.S2	B0,1,B0
194*4882a593Smuzhiyun	MVC	.S2	B0,ILC
195*4882a593Smuzhiyun	NOP	3
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun	SPLOOP	1
198*4882a593Smuzhiyun	LDHU	.D1T1	*A4++,A3
199*4882a593Smuzhiyun	NOP	3
200*4882a593Smuzhiyun	NOP
201*4882a593Smuzhiyun	SPKERNEL	5,0
202*4882a593Smuzhiyun ||	ADD	.L1	A3,A5,A5
203*4882a593Smuzhiyun
204*4882a593SmuzhiyunL12:	SHRU	.S1	A5,16,A0
205*4882a593Smuzhiyun  [!A0]	BNOP	.S1	L14,5
206*4882a593Smuzhiyun
207*4882a593SmuzhiyunL13:	SHRU	.S2X	A5,16,B4
208*4882a593Smuzhiyun	EXTU	.S1	A5,16,16,A3
209*4882a593Smuzhiyun	ADD	.D1X	A3,B4,A5
210*4882a593Smuzhiyun	SHRU	.S1	A5,16,A0
211*4882a593Smuzhiyun  [A0]	BNOP	.S1	L13,5
212*4882a593Smuzhiyun
213*4882a593SmuzhiyunL14:	NOT	.D1	A5,A3
214*4882a593Smuzhiyun	EXTU	.S1	A3,16,16,A3
215*4882a593Smuzhiyun
216*4882a593SmuzhiyunL15:	BNOP	.S2	B3,3
217*4882a593Smuzhiyun	MVC	.S2	B30,ILC
218*4882a593Smuzhiyun	MV	.D1	A3,A4
219*4882a593SmuzhiyunENDPROC(ip_fast_csum)
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun;
222*4882a593Smuzhiyun;unsigned short
223*4882a593Smuzhiyun;do_csum(unsigned char *buff, unsigned int len)
224*4882a593Smuzhiyun;{
225*4882a593Smuzhiyun;	int odd, count;
226*4882a593Smuzhiyun;	unsigned int result = 0;
227*4882a593Smuzhiyun;
228*4882a593Smuzhiyun;	if (len <= 0)
229*4882a593Smuzhiyun;		goto out;
230*4882a593Smuzhiyun;	odd = 1 & (unsigned long) buff;
231*4882a593Smuzhiyun;	if (odd) {
232*4882a593Smuzhiyun;#ifdef __LITTLE_ENDIAN
233*4882a593Smuzhiyun;		result += (*buff << 8);
234*4882a593Smuzhiyun;#else
235*4882a593Smuzhiyun;		result = *buff;
236*4882a593Smuzhiyun;#endif
237*4882a593Smuzhiyun;		len--;
238*4882a593Smuzhiyun;		buff++;
239*4882a593Smuzhiyun;	}
240*4882a593Smuzhiyun;	count = len >> 1;		/* nr of 16-bit words.. */
241*4882a593Smuzhiyun;	if (count) {
242*4882a593Smuzhiyun;		if (2 & (unsigned long) buff) {
243*4882a593Smuzhiyun;			result += *(unsigned short *) buff;
244*4882a593Smuzhiyun;			count--;
245*4882a593Smuzhiyun;			len -= 2;
246*4882a593Smuzhiyun;			buff += 2;
247*4882a593Smuzhiyun;		}
248*4882a593Smuzhiyun;		count >>= 1;		/* nr of 32-bit words.. */
249*4882a593Smuzhiyun;		if (count) {
250*4882a593Smuzhiyun;			unsigned int carry = 0;
251*4882a593Smuzhiyun;			do {
252*4882a593Smuzhiyun;				unsigned int w = *(unsigned int *) buff;
253*4882a593Smuzhiyun;				count--;
254*4882a593Smuzhiyun;				buff += 4;
255*4882a593Smuzhiyun;				result += carry;
256*4882a593Smuzhiyun;				result += w;
257*4882a593Smuzhiyun;				carry = (w > result);
258*4882a593Smuzhiyun;			} while (count);
259*4882a593Smuzhiyun;			result += carry;
260*4882a593Smuzhiyun;			result = (result & 0xffff) + (result >> 16);
261*4882a593Smuzhiyun;		}
262*4882a593Smuzhiyun;		if (len & 2) {
263*4882a593Smuzhiyun;			result += *(unsigned short *) buff;
264*4882a593Smuzhiyun;			buff += 2;
265*4882a593Smuzhiyun;		}
266*4882a593Smuzhiyun;	}
267*4882a593Smuzhiyun;	if (len & 1)
268*4882a593Smuzhiyun;#ifdef __LITTLE_ENDIAN
269*4882a593Smuzhiyun;		result += *buff;
270*4882a593Smuzhiyun;#else
271*4882a593Smuzhiyun;		result += (*buff << 8);
272*4882a593Smuzhiyun;#endif
273*4882a593Smuzhiyun;	result = (result & 0xffff) + (result >> 16);
274*4882a593Smuzhiyun;	/* add up carry.. */
275*4882a593Smuzhiyun;	result = (result & 0xffff) + (result >> 16);
276*4882a593Smuzhiyun;	if (odd)
277*4882a593Smuzhiyun;		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
278*4882a593Smuzhiyun;out:
279*4882a593Smuzhiyun;	return result;
280*4882a593Smuzhiyun;}
281*4882a593Smuzhiyun;
282*4882a593Smuzhiyun; A4:	buff
283*4882a593Smuzhiyun; B4:	len
284*4882a593Smuzhiyun; return checksum in A4
285*4882a593Smuzhiyun;
286*4882a593Smuzhiyun
287*4882a593SmuzhiyunENTRY(do_csum)
288*4882a593Smuzhiyun	   CMPGT   .L2	   B4,0,B0
289*4882a593Smuzhiyun   [!B0]   BNOP    .S1	   L26,3
290*4882a593Smuzhiyun	   EXTU    .S1	   A4,31,31,A0
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun	   MV	   .L1	   A0,A3
293*4882a593Smuzhiyun||	   MV	   .S1X    B3,A5
294*4882a593Smuzhiyun||	   MV	   .L2	   B4,B3
295*4882a593Smuzhiyun||	   ZERO    .D1	   A1
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun#ifdef CONFIG_CPU_BIG_ENDIAN
298*4882a593Smuzhiyun   [A0]    SUB	   .L2	   B3,1,B3
299*4882a593Smuzhiyun|| [A0]    LDBU    .D1T1   *A4++,A1
300*4882a593Smuzhiyun#else
301*4882a593Smuzhiyun   [!A0]   BNOP    .S1	   L21,5
302*4882a593Smuzhiyun|| [A0]    LDBU    .D1T1   *A4++,A0
303*4882a593Smuzhiyun	   SUB	   .L2	   B3,1,B3
304*4882a593Smuzhiyun||	   SHL	   .S1	   A0,8,A1
305*4882a593SmuzhiyunL21:
306*4882a593Smuzhiyun#endif
307*4882a593Smuzhiyun	   SHR	   .S2	   B3,1,B0
308*4882a593Smuzhiyun   [!B0]   BNOP    .S1	   L24,3
309*4882a593Smuzhiyun	   MVK	   .L1	   2,A0
310*4882a593Smuzhiyun	   AND	   .L1	   A4,A0,A0
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun   [!A0]   BNOP    .S1	   L22,5
313*4882a593Smuzhiyun|| [A0]    LDHU    .D1T1   *A4++,A0
314*4882a593Smuzhiyun	   SUB	   .L2	   B0,1,B0
315*4882a593Smuzhiyun||	   SUB	   .S2	   B3,2,B3
316*4882a593Smuzhiyun||	   ADD	   .L1	   A0,A1,A1
317*4882a593SmuzhiyunL22:
318*4882a593Smuzhiyun	   SHR	   .S2	   B0,1,B0
319*4882a593Smuzhiyun||	   ZERO    .L1	   A0
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun   [!B0]   BNOP    .S1	   L23,5
322*4882a593Smuzhiyun|| [B0]    MVC	   .S2	   B0,ILC
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun	   SPLOOP  3
325*4882a593Smuzhiyun	   SPMASK  L1
326*4882a593Smuzhiyun||	   MV	   .L1	   A1,A2
327*4882a593Smuzhiyun||	   LDW	   .D1T1   *A4++,A1
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun	   NOP	   4
330*4882a593Smuzhiyun	   ADD	   .L1	   A0,A1,A0
331*4882a593Smuzhiyun	   ADD	   .L1	   A2,A0,A2
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun	   SPKERNEL 1,2
334*4882a593Smuzhiyun||	   CMPGTU  .L1	   A1,A2,A0
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun	   ADD	   .L1	   A0,A2,A6
337*4882a593Smuzhiyun	   EXTU    .S1	   A6,16,16,A7
338*4882a593Smuzhiyun	   SHRU    .S2X    A6,16,B0
339*4882a593Smuzhiyun	   NOP		   1
340*4882a593Smuzhiyun	   ADD	   .L1X    A7,B0,A1
341*4882a593SmuzhiyunL23:
342*4882a593Smuzhiyun	   MVK	   .L2	   2,B0
343*4882a593Smuzhiyun	   AND	   .L2	   B3,B0,B0
344*4882a593Smuzhiyun   [B0]    LDHU    .D1T1   *A4++,A0
345*4882a593Smuzhiyun	   NOP	   4
346*4882a593Smuzhiyun   [B0]    ADD	   .L1	   A0,A1,A1
347*4882a593SmuzhiyunL24:
348*4882a593Smuzhiyun	   EXTU    .S2	   B3,31,31,B0
349*4882a593Smuzhiyun#ifdef CONFIG_CPU_BIG_ENDIAN
350*4882a593Smuzhiyun   [!B0]   BNOP    .S1	   L25,4
351*4882a593Smuzhiyun|| [B0]    LDBU    .D1T1   *A4,A0
352*4882a593Smuzhiyun	   SHL	   .S1	   A0,8,A0
353*4882a593Smuzhiyun	   ADD	   .L1	   A0,A1,A1
354*4882a593SmuzhiyunL25:
355*4882a593Smuzhiyun#else
356*4882a593Smuzhiyun   [B0]    LDBU    .D1T1   *A4,A0
357*4882a593Smuzhiyun	   NOP	   4
358*4882a593Smuzhiyun   [B0]    ADD	   .L1	   A0,A1,A1
359*4882a593Smuzhiyun#endif
360*4882a593Smuzhiyun	   EXTU    .S1	   A1,16,16,A0
361*4882a593Smuzhiyun	   SHRU    .S2X    A1,16,B0
362*4882a593Smuzhiyun	   NOP	   1
363*4882a593Smuzhiyun	   ADD	   .L1X    A0,B0,A0
364*4882a593Smuzhiyun	   SHRU    .S1	   A0,16,A1
365*4882a593Smuzhiyun	   ADD	   .L1	   A0,A1,A0
366*4882a593Smuzhiyun	   EXTU    .S1	   A0,16,16,A1
367*4882a593Smuzhiyun	   EXTU    .S1	   A1,16,24,A2
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun	   EXTU    .S1	   A1,24,16,A0
370*4882a593Smuzhiyun||	   MV	   .L2X    A3,B0
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun   [B0]    OR	   .L1	   A0,A2,A1
373*4882a593SmuzhiyunL26:
374*4882a593Smuzhiyun	   NOP	   1
375*4882a593Smuzhiyun	   BNOP    .S2X    A5,4
376*4882a593Smuzhiyun	   MV	   .L1	   A1,A4
377*4882a593SmuzhiyunENDPROC(do_csum)
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun;__wsum csum_partial(const void *buff, int len, __wsum wsum)
380*4882a593Smuzhiyun;{
381*4882a593Smuzhiyun;	unsigned int sum = (__force unsigned int)wsum;
382*4882a593Smuzhiyun;	unsigned int result = do_csum(buff, len);
383*4882a593Smuzhiyun;
384*4882a593Smuzhiyun;	/* add in old sum, and carry.. */
385*4882a593Smuzhiyun;	result += sum;
386*4882a593Smuzhiyun;	if (sum > result)
387*4882a593Smuzhiyun;		result += 1;
388*4882a593Smuzhiyun;	return (__force __wsum)result;
389*4882a593Smuzhiyun;}
390*4882a593Smuzhiyun;
391*4882a593SmuzhiyunENTRY(csum_partial)
392*4882a593Smuzhiyun	   MV	   .L1X    B3,A9
393*4882a593Smuzhiyun||	   CALLP   .S2	   do_csum,B3
394*4882a593Smuzhiyun||	   MV	   .S1	   A6,A8
395*4882a593Smuzhiyun	   BNOP    .S2X    A9,2
396*4882a593Smuzhiyun	   ADD	   .L1	   A8,A4,A1
397*4882a593Smuzhiyun	   CMPGTU  .L1	   A8,A1,A0
398*4882a593Smuzhiyun	   ADD	   .L1	   A1,A0,A4
399*4882a593SmuzhiyunENDPROC(csum_partial)
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun;unsigned short
402*4882a593Smuzhiyun;ip_compute_csum(unsigned char *buff, unsigned int len)
403*4882a593Smuzhiyun;
404*4882a593Smuzhiyun; A4:	buff
405*4882a593Smuzhiyun; B4:	len
406*4882a593Smuzhiyun; return checksum in A4
407*4882a593Smuzhiyun
408*4882a593SmuzhiyunENTRY(ip_compute_csum)
409*4882a593Smuzhiyun	   MV	   .L1X    B3,A9
410*4882a593Smuzhiyun||	   CALLP   .S2	   do_csum,B3
411*4882a593Smuzhiyun	   BNOP    .S2X    A9,3
412*4882a593Smuzhiyun	   NOT	   .S1	   A4,A4
413*4882a593Smuzhiyun	   CLR     .S1	   A4,16,31,A4
414*4882a593SmuzhiyunENDPROC(ip_compute_csum)
415