• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * A fast checksum routine using movem
4 * Copyright (c) 1998-2007 Axis Communications AB
5 *
6 * csum_partial(const unsigned char * buff, int len, unsigned int sum)
7 */
8
9	.globl	csum_partial
10	.type   csum_partial,@function
11csum_partial:
12
13	;; r10 - src
14	;; r11 - length
15	;; r12 - checksum
16
17	;; Optimized for large packets
18	subq	10*4, $r11
19	blt	_word_loop
20	move.d	$r11, $acr
21
22	subq	9*4,$sp
23	clearf	c
24	movem	$r8,[$sp]
25
26	;; do a movem checksum
27
28_mloop:	movem	[$r10+],$r9	; read 10 longwords
29	;; Loop count without touching the c flag.
30	addoq	-10*4, $acr, $acr
31	;; perform dword checksumming on the 10 longwords
32
33	addc	$r0,$r12
34	addc	$r1,$r12
35	addc	$r2,$r12
36	addc	$r3,$r12
37	addc	$r4,$r12
38	addc	$r5,$r12
39	addc	$r6,$r12
40	addc	$r7,$r12
41	addc	$r8,$r12
42	addc	$r9,$r12
43
44	;; test $acr without trashing carry.
45	move.d	$acr, $acr
46	bpl	_mloop
47	;; r11 <= acr  is not really needed in the mloop, just using the dslot
48	;; to prepare for what is needed after mloop.
49	move.d	$acr, $r11
50
51	;; fold the last carry into r13
52	addc	0, $r12
53	movem	[$sp+],$r8	; restore regs
54
55_word_loop:
56	addq	10*4,$r11	; compensate for last loop underflowing length
57
58	moveq	-1,$r9		; put 0xffff in r9, faster than move.d 0xffff,r9
59	lsrq	16,$r9
60
61	move.d	$r12,$r13
62	lsrq	16,$r13		; r13 = checksum >> 16
63	and.d	$r9,$r12	; checksum = checksum & 0xffff
64
65_no_fold:
66	subq	2,$r11
67	blt	_no_words
68	add.d	$r13,$r12	; checksum += r13
69
70	;; checksum the rest of the words
71_wloop:	subq	2,$r11
72	bge	_wloop
73	addu.w	[$r10+],$r12
74
75_no_words:
76	addq	2,$r11
77	;; see if we have one odd byte more
78	bne	_do_byte
79	nop
80	ret
81	move.d	$r12,$r10
82
83_do_byte:
84	;; copy and checksum the last byte
85	addu.b	[$r10],$r12
86	ret
87	move.d	$r12,$r10
88
89	.size   csum_partial, .-csum_partial
90