xref: /netbsd-src/sys/arch/sh3/sh3/cpu_in_cksum.S (revision d25ffa98a4bfca1fe272f3c182496ec9934faac7)
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