162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * arch/alpha/lib/csum_ipv6_magic.S
462306a36Sopenharmony_ci * Contributed by Richard Henderson <rth@tamu.edu>
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * unsigned short csum_ipv6_magic(struct in6_addr *saddr,
762306a36Sopenharmony_ci *                                struct in6_addr *daddr,
862306a36Sopenharmony_ci *                                __u32 len,
962306a36Sopenharmony_ci *                                unsigned short proto,
1062306a36Sopenharmony_ci *                                unsigned int csum);
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * Misalignment handling (which costs 16 instructions / 8 cycles)
1362306a36Sopenharmony_ci * added by Ivan Kokshaysky <ink@jurassic.park.msu.ru>
1462306a36Sopenharmony_ci */
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <linux/export.h>
1762306a36Sopenharmony_ci	.globl csum_ipv6_magic
1862306a36Sopenharmony_ci	.align 4
1962306a36Sopenharmony_ci	.ent csum_ipv6_magic
2062306a36Sopenharmony_ci	.frame $30,0,$26,0
2162306a36Sopenharmony_cicsum_ipv6_magic:
2262306a36Sopenharmony_ci	.prologue 0
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	ldq_u	$0,0($16)	# e0    : load src & dst addr words
2562306a36Sopenharmony_ci	zapnot	$20,15,$20	# .. e1 : zero extend incoming csum
2662306a36Sopenharmony_ci	extqh	$18,1,$4	# e0    : byte swap len & proto while we wait
2762306a36Sopenharmony_ci	ldq_u	$21,7($16)	# .. e1 : handle misalignment
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	extbl	$18,1,$5	# e0	:
3062306a36Sopenharmony_ci	ldq_u	$1,8($16)	# .. e1 :
3162306a36Sopenharmony_ci	extbl	$18,2,$6	# e0 	:
3262306a36Sopenharmony_ci	ldq_u	$22,15($16)	# .. e1 :
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	extbl	$18,3,$18	# e0	:
3562306a36Sopenharmony_ci	ldq_u	$2,0($17)	# .. e1 :
3662306a36Sopenharmony_ci	sra	$4,32,$4	# e0	:
3762306a36Sopenharmony_ci	ldq_u	$23,7($17)	# .. e1 :
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	extql	$0,$16,$0	# e0	:
4062306a36Sopenharmony_ci	ldq_u	$3,8($17)	# .. e1 :
4162306a36Sopenharmony_ci	extqh	$21,$16,$21	# e0	:
4262306a36Sopenharmony_ci	ldq_u	$24,15($17)	# .. e1 :
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	sll	$5,16,$5	# e0	:
4562306a36Sopenharmony_ci	or	$0,$21,$0	# .. e1 : 1st src word complete
4662306a36Sopenharmony_ci	extql	$1,$16,$1	# e0	:
4762306a36Sopenharmony_ci	addq	$20,$0,$20	# .. e1 : begin summing the words
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	extqh	$22,$16,$22	# e0	:
5062306a36Sopenharmony_ci	cmpult	$20,$0,$0	# .. e1 :
5162306a36Sopenharmony_ci	sll	$6,8,$6		# e0	:
5262306a36Sopenharmony_ci	or	$1,$22,$1	# .. e1 : 2nd src word complete
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	extql	$2,$17,$2	# e0	:
5562306a36Sopenharmony_ci	or	$4,$18,$18	# .. e1 :
5662306a36Sopenharmony_ci	extqh	$23,$17,$23	# e0	:
5762306a36Sopenharmony_ci	or	$5,$6,$5	# .. e1 :
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	extql	$3,$17,$3	# e0	:
6062306a36Sopenharmony_ci	or	$2,$23,$2	# .. e1 : 1st dst word complete
6162306a36Sopenharmony_ci	extqh	$24,$17,$24	# e0	:
6262306a36Sopenharmony_ci	or	$18,$5,$18	# .. e1 : len complete
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	extwh	$19,7,$7	# e0    :
6562306a36Sopenharmony_ci	or	$3,$24,$3	# .. e1 : 2nd dst word complete
6662306a36Sopenharmony_ci	extbl	$19,1,$19	# e0    :
6762306a36Sopenharmony_ci	addq	$20,$1,$20	# .. e1 :
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	or	$19,$7,$19	# e0    :
7062306a36Sopenharmony_ci	cmpult	$20,$1,$1	# .. e1 :
7162306a36Sopenharmony_ci	sll	$19,48,$19	# e0    :
7262306a36Sopenharmony_ci	nop			# .. e0 :
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	sra	$19,32,$19	# e0    : proto complete
7562306a36Sopenharmony_ci	addq	$20,$2,$20	# .. e1 :
7662306a36Sopenharmony_ci	cmpult	$20,$2,$2	# e0    :
7762306a36Sopenharmony_ci	addq	$20,$3,$20	# .. e1 :
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	cmpult	$20,$3,$3	# e0    :
8062306a36Sopenharmony_ci	addq	$20,$18,$20	# .. e1 :
8162306a36Sopenharmony_ci	cmpult	$20,$18,$18	# e0    :
8262306a36Sopenharmony_ci	addq	$20,$19,$20	# .. e1 :
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	cmpult	$20,$19,$19	# e0    :
8562306a36Sopenharmony_ci	addq	$0,$1,$0	# .. e1 : merge the carries back into the csum
8662306a36Sopenharmony_ci	addq	$2,$3,$2	# e0    :
8762306a36Sopenharmony_ci	addq	$18,$19,$18	# .. e1 :
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	addq	$0,$2,$0	# e0    :
9062306a36Sopenharmony_ci	addq	$20,$18,$20	# .. e1 :
9162306a36Sopenharmony_ci	addq	$0,$20,$0	# e0    :
9262306a36Sopenharmony_ci	unop			#       :
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	extwl	$0,2,$2		# e0    : begin folding the 64-bit value
9562306a36Sopenharmony_ci	zapnot	$0,3,$3		# .. e1 :
9662306a36Sopenharmony_ci	extwl	$0,4,$1		# e0    :
9762306a36Sopenharmony_ci	addq	$2,$3,$3	# .. e1 :
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	extwl	$0,6,$0		# e0    :
10062306a36Sopenharmony_ci	addq	$3,$1,$3	# .. e1 :
10162306a36Sopenharmony_ci	addq	$0,$3,$0	# e0    :
10262306a36Sopenharmony_ci	unop			#       :
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	extwl	$0,2,$1		# e0    : fold 18-bit value
10562306a36Sopenharmony_ci	zapnot	$0,3,$0		# .. e1 :
10662306a36Sopenharmony_ci	addq	$0,$1,$0	# e0    :
10762306a36Sopenharmony_ci	unop			#       :
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	extwl	$0,2,$1		# e0    : fold 17-bit value
11062306a36Sopenharmony_ci	zapnot	$0,3,$0		# .. e1 :
11162306a36Sopenharmony_ci	addq	$0,$1,$0	# e0    :
11262306a36Sopenharmony_ci	not	$0,$0		# .. e1 : and complement.
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	zapnot	$0,3,$0		# e0    :
11562306a36Sopenharmony_ci	ret			# .. e1 :
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	.end csum_ipv6_magic
11862306a36Sopenharmony_ci	EXPORT_SYMBOL(csum_ipv6_magic)
119