xref: /openbsd-src/sys/arch/sh/sh/in_cksum.S (revision 7dad3e507f69d05fc76cdc8b4448b500d7aa616b)
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