Home | History | Annotate | Line # | Download | only in sh3
      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  */
     98 ENTRY(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 
    129 mbuf_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
    147 1:
    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
    157 1:
    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
    169 1:
    170 
    171 
    172 
    173 	mov	#127, r0
    174 	cmp/hi	r0, reg_mlen
    175 	bf	1f
    176 
    177 do_cksum128:
    178 	bsr	cksum128
    179 	 nop
    180 
    181 	mov	#127, r0
    182 	cmp/hi	r0, reg_mlen
    183 	bt	do_cksum128
    184 1:
    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
    197 1:
    198 
    199 	mov	reg_mlen, r0
    200 	tst	#1, r0
    201 	bt	1f
    202 	ADDB
    203 1:
    204 
    205 
    206 mbuf_loop_continue:
    207 	mov.l	@(M_NEXT, reg_m), reg_m
    208 
    209 	tst	reg_len, reg_len
    210 	bf/s	mbuf_loop
    211 mbuf_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
    218 1:
    219 
    220 	REDUCE
    221 	REDUCE
    222 
    223 in_cksum_return:
    224 	not	reg_sum, r0
    225 	PIC_EPILOGUE
    226 	lds.l	@sp+, pr
    227 	rts
    228 	 extu.w	r0, r0
    229 
    230 
    231 out_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 
    237 1:	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
    257 cksum128mod:
    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
    269 cksum128:
    270 	add	#-128, reg_mlen
    271 	clrt
    272 
    273 cksum128_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
    306 cksum128_tail:
    307 	mov	#0, r0
    308 	rts
    309 	 addc	r0, reg_sum
    310