xref: /netbsd-src/sys/arch/sh3/sh3/cpu_in_cksum.S (revision 90313c06e62e910bf0d1bb24faa9d17dcefd0ab6)
1/*	$NetBSD: cpu_in_cksum.S,v 1.12 2024/02/07 04:20:27 msaitoh Exp $	*/
2
3/*-
4 * Copyright (c) 2000 SHIMIZU Ryo
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#ifndef _LOCORE
31#define _LOCORE
32#endif
33#include <machine/endian.h>
34#include <machine/asm.h>
35#include "assym.h"
36
37__KERNEL_RCSID(0, "$NetBSD: cpu_in_cksum.S,v 1.12 2024/02/07 04:20:27 msaitoh Exp $")
38
39
40#define	reg_byte_swapped	r1
41#define	reg_mlen		r2
42#define	reg_tmp3		r3
43#define	reg_m			r4
44#define	reg_len			r5
45#define	reg_off			r6
46#define	reg_w			r6	/* recycle */
47#define	reg_sum			r7
48
49
50#define	REDUCE	\
51	swap.w	reg_sum, r0		; \
52	extu.w	reg_sum, reg_sum	; \
53	extu.w	r0, r0			; \
54	add	r0, reg_sum
55
56#define	ROL	\
57	shll8	reg_sum
58
59#if _BYTE_ORDER == BIG_ENDIAN
60#define	ADDB	\
61	mov.b	@reg_w+, r0	; \
62	ROL			; \
63	extu.b	r0, r0		; \
64	add	r0, reg_sum	; \
65	not	reg_byte_swapped, reg_byte_swapped
66#else
67#define	ADDB	\
68	mov.b	@reg_w+, r0	; \
69	extu.b	r0, r0		; \
70	add	r0, reg_sum	; \
71	ROL			; \
72	not	reg_byte_swapped, reg_byte_swapped
73#endif
74
75
76#define	ADDS	\
77	mov.w	@reg_w+, r0	; \
78	extu.w	r0, r0		; \
79	add	r0, reg_sum
80
81#define	ADDCL	\
82	mov.l	@reg_w+, r0	; \
83	addc	r0, reg_sum
84
85#define	FORWARD1	\
86	add	#-1, reg_mlen
87
88#define	FORWARD2	\
89	add	#-2, reg_mlen
90
91
92/*
93 * LINTSTUB: include <sys/param.h>
94 * LINTSTUB: include <sys/mbuf.h>
95 *
96 * LINTSTUB: Func: int cpu_in_cksum(struct mbuf *m, int len, int off, uint32_t initial_sum);
97 */
98ENTRY(cpu_in_cksum)
99	sts.l	pr, @-sp
100	PIC_PROLOGUE(.L_got)
101
102	tst	reg_len, reg_len
103	bt/s	mbuf_loop_done
104	 mov	#0, reg_byte_swapped
105
106.L_mbuf_skip:
107	tst	reg_m, reg_m
108	bt	out_of_mbufs
109
110	mov.l	@(M_LEN, reg_m), reg_mlen
111	cmp/gt	reg_off, reg_mlen	/* mlen > off ? */
112	bt	.L_mbuf_found
113
114	!! while (off >= mlen)
115	mov.l	@(M_NEXT, reg_m), reg_m	! m = m->m_next
116	bra	.L_mbuf_skip
117	 sub	reg_mlen, reg_off	! off -= mlen
118
119
120.L_mbuf_found: !! if (mlen > off)
121	mov.l	@(M_DATA, reg_m), reg_tmp3
122	sub	reg_off, reg_mlen	! mlen -= off
123	bra	.L_mbuf_loop_enter
124	 add	reg_tmp3, reg_off	! w = m->m_data + off
125
126#undef	reg_off /* it is dead now and we recycle it for reg_w */
127
128
129mbuf_loop:
130	tst	reg_m, reg_m
131	bt	out_of_mbufs
132
133	mov.l	@(M_LEN, reg_m), reg_mlen
134	tst	reg_mlen, reg_mlen
135	bt/s	mbuf_loop_continue
136	mov.l	@(M_DATA, reg_m), reg_w
137
138
139	!! Entry point for mbuf loop.  We jump here after we have
140	!! found the mbuf (reg_m) that contains data at the specified
141	!! offset.  reg_mlen and reg_w were adjusted to point at the
142	!! first interesting byte of data.
143.L_mbuf_loop_enter:
144	cmp/ge	reg_mlen, reg_len
145	bt	1f
146	mov	reg_len, reg_mlen
1471:
148	sub	reg_mlen, reg_len
149
150
151	mov	reg_w, r0
152	tst	#1, r0
153	bt/s	1f
154	REDUCE		/* 1st instruction break only r0 */
155	ADDB
156	FORWARD1
1571:
158
159
160	mov	#1, r0
161	cmp/gt	r0, reg_mlen
162	bf/s	1f
163	mov	reg_w, r0
164	tst	#2, r0
165	bt/s	1f
166	REDUCE		/* 1st instruction break only r0 */
167	ADDS
168	FORWARD2
1691:
170
171
172
173	mov	#127, r0
174	cmp/hi	r0, reg_mlen
175	bf	1f
176
177do_cksum128:
178	bsr	cksum128
179	 nop
180
181	mov	#127, r0
182	cmp/hi	r0, reg_mlen
183	bt	do_cksum128
1841:
185
186
187	bsr	cksum128mod
188	 nop
189
190	REDUCE
191
192	mov	#1, r0
193	cmp/gt	r0, reg_mlen
194	bf	1f
195	ADDS
196	FORWARD2
1971:
198
199	mov	reg_mlen, r0
200	tst	#1, r0
201	bt	1f
202	ADDB
2031:
204
205
206mbuf_loop_continue:
207	mov.l	@(M_NEXT, reg_m), reg_m
208
209	tst	reg_len, reg_len
210	bf/s	mbuf_loop
211mbuf_loop_done:
212
213
214	tst	reg_byte_swapped, reg_byte_swapped
215	bt/s	1f
216	REDUCE		/* 1st instruction break only r0 */
217	ROL
2181:
219
220	REDUCE
221	REDUCE
222
223in_cksum_return:
224	not	reg_sum, r0
225	PIC_EPILOGUE
226	lds.l	@sp+, pr
227	rts
228	 extu.w	r0, r0
229
230
231out_of_mbufs:
232	mova	.L_message_out_of_data, r0
233	mov.l	.L_printf, reg_tmp3
234
235	mov.l	reg_sum, @-sp	/* save: call clobbered register */
236
2371:	CALL	reg_tmp3
238	 mov	r0, r4
239
240	bra	in_cksum_return
241	 mov.l	@sp+, reg_sum	/* restore */
242
243	.align 2
244.L_got:
245	PIC_GOT_DATUM
246.L_printf:
247	CALL_DATUM(_C_LABEL(printf), 1b)
248
249	.align 2	/* mova target */
250.L_message_out_of_data:
251	.asciz "cksum: out of data (%d byte short)\n"
252
253	SET_ENTRY_SIZE(cpu_in_cksum)
254
255
256	.align	2
257cksum128mod:
258	mov	reg_mlen, r0
259	and	#124, r0
260	sub	r0, reg_mlen
261	mov	r0, reg_tmp3
262
263	mova	cksum128_tail, r0
264	sub	reg_tmp3, r0
265	jmp	@r0
266	 clrt
267
268	.align	2
269cksum128:
270	add	#-128, reg_mlen
271	clrt
272
273cksum128_unroll:
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
304	ADDCL
305	ADDCL
306cksum128_tail:
307	mov	#0, r0
308	rts
309	 addc	r0, reg_sum
310