#ifndef _LOCORE
#define _LOCORE
#endif
#include <machine/endian.h>
#include <machine/asm.h>
#include "assym.h"
__KERNEL_RCSID(0, "$NetBSD: cpu_in_cksum.S,v 1.12 2024/02/07 04:20:27 msaitoh Exp $")
#define reg_byte_swapped r1
#define reg_mlen r2
#define reg_tmp3 r3
#define reg_m r4
#define reg_len r5
#define reg_off r6
#define reg_w r6
#define reg_sum r7
#define REDUCE \
swap.w reg_sum, r0 ; \
extu.w reg_sum, reg_sum ; \
extu.w r0, r0 ; \
add r0, reg_sum
#define ROL \
shll8 reg_sum
#if _BYTE_ORDER == BIG_ENDIAN
#define ADDB \
mov.b @reg_w+, r0 ; \
ROL ; \
extu.b r0, r0 ; \
add r0, reg_sum ; \
not reg_byte_swapped, reg_byte_swapped
#else
#define ADDB \
mov.b @reg_w+, r0 ; \
extu.b r0, r0 ; \
add r0, reg_sum ; \
ROL ; \
not reg_byte_swapped, reg_byte_swapped
#endif
#define ADDS \
mov.w @reg_w+, r0 ; \
extu.w r0, r0 ; \
add r0, reg_sum
#define ADDCL \
mov.l @reg_w+, r0 ; \
addc r0, reg_sum
#define FORWARD1 \
add #-1, reg_mlen
#define FORWARD2 \
add #-2, reg_mlen
ENTRY(cpu_in_cksum)
sts.l pr, @-sp
PIC_PROLOGUE(.L_got)
tst reg_len, reg_len
bt/s mbuf_loop_done
mov #0, reg_byte_swapped
.L_mbuf_skip:
tst reg_m, reg_m
bt out_of_mbufs
mov.l @(M_LEN, reg_m), reg_mlen
cmp/gt reg_off, reg_mlen
bt .L_mbuf_found
!! while (off >= mlen)
mov.l @(M_NEXT, reg_m), reg_m ! m = m->m_next
bra .L_mbuf_skip
sub reg_mlen, reg_off ! off -= mlen
.L_mbuf_found: !! if (mlen > off)
mov.l @(M_DATA, reg_m), reg_tmp3
sub reg_off, reg_mlen ! mlen -= off
bra .L_mbuf_loop_enter
add reg_tmp3, reg_off ! w = m->m_data + off
#undef reg_off
mbuf_loop:
tst reg_m, reg_m
bt out_of_mbufs
mov.l @(M_LEN, reg_m), reg_mlen
tst reg_mlen, reg_mlen
bt/s mbuf_loop_continue
mov.l @(M_DATA, reg_m), reg_w
!! Entry point for mbuf loop. We jump here after we have
!! found the mbuf (reg_m) that contains data at the specified
!! offset. reg_mlen and reg_w were adjusted to point at the
!! first interesting byte of data.
.L_mbuf_loop_enter:
cmp/ge reg_mlen, reg_len
bt 1f
mov reg_len, reg_mlen
1:
sub reg_mlen, reg_len
mov reg_w, r0
tst #1, r0
bt/s 1f
REDUCE
ADDB
FORWARD1
1:
mov #1, r0
cmp/gt r0, reg_mlen
bf/s 1f
mov reg_w, r0
tst #2, r0
bt/s 1f
REDUCE
ADDS
FORWARD2
1:
mov #127, r0
cmp/hi r0, reg_mlen
bf 1f
do_cksum128:
bsr cksum128
nop
mov #127, r0
cmp/hi r0, reg_mlen
bt do_cksum128
1:
bsr cksum128mod
nop
REDUCE
mov #1, r0
cmp/gt r0, reg_mlen
bf 1f
ADDS
FORWARD2
1:
mov reg_mlen, r0
tst #1, r0
bt 1f
ADDB
1:
mbuf_loop_continue:
mov.l @(M_NEXT, reg_m), reg_m
tst reg_len, reg_len
bf/s mbuf_loop
mbuf_loop_done:
tst reg_byte_swapped, reg_byte_swapped
bt/s 1f
REDUCE
ROL
1:
REDUCE
REDUCE
in_cksum_return:
not reg_sum, r0
PIC_EPILOGUE
lds.l @sp+, pr
rts
extu.w r0, r0
out_of_mbufs:
mova .L_message_out_of_data, r0
mov.l .L_printf, reg_tmp3
mov.l reg_sum, @-sp
1: CALL reg_tmp3
mov r0, r4
bra in_cksum_return
mov.l @sp+, reg_sum
.align 2
.L_got:
PIC_GOT_DATUM
.L_printf:
CALL_DATUM(_C_LABEL(printf), 1b)
.align 2
.L_message_out_of_data:
.asciz "cksum: out of data (%d byte short)\n"
SET_ENTRY_SIZE(cpu_in_cksum)
.align 2
cksum128mod:
mov reg_mlen, r0
and #124, r0
sub r0, reg_mlen
mov r0, reg_tmp3
mova cksum128_tail, r0
sub reg_tmp3, r0
jmp @r0
clrt
.align 2
cksum128:
add #-128, reg_mlen
clrt
cksum128_unroll:
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
ADDCL
cksum128_tail:
mov #0, r0
rts
addc r0, reg_sum