18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * arch/alpha/lib/csum_ipv6_magic.S
48c2ecf20Sopenharmony_ci * Contributed by Richard Henderson <rth@tamu.edu>
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * unsigned short csum_ipv6_magic(struct in6_addr *saddr,
78c2ecf20Sopenharmony_ci *                                struct in6_addr *daddr,
88c2ecf20Sopenharmony_ci *                                __u32 len,
98c2ecf20Sopenharmony_ci *                                unsigned short proto,
108c2ecf20Sopenharmony_ci *                                unsigned int csum);
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * Misalignment handling (which costs 16 instructions / 8 cycles)
138c2ecf20Sopenharmony_ci * added by Ivan Kokshaysky <ink@jurassic.park.msu.ru>
148c2ecf20Sopenharmony_ci */
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include <asm/export.h>
178c2ecf20Sopenharmony_ci	.globl csum_ipv6_magic
188c2ecf20Sopenharmony_ci	.align 4
198c2ecf20Sopenharmony_ci	.ent csum_ipv6_magic
208c2ecf20Sopenharmony_ci	.frame $30,0,$26,0
218c2ecf20Sopenharmony_cicsum_ipv6_magic:
228c2ecf20Sopenharmony_ci	.prologue 0
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci	ldq_u	$0,0($16)	# e0    : load src & dst addr words
258c2ecf20Sopenharmony_ci	zapnot	$20,15,$20	# .. e1 : zero extend incoming csum
268c2ecf20Sopenharmony_ci	extqh	$18,1,$4	# e0    : byte swap len & proto while we wait
278c2ecf20Sopenharmony_ci	ldq_u	$21,7($16)	# .. e1 : handle misalignment
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	extbl	$18,1,$5	# e0	:
308c2ecf20Sopenharmony_ci	ldq_u	$1,8($16)	# .. e1 :
318c2ecf20Sopenharmony_ci	extbl	$18,2,$6	# e0 	:
328c2ecf20Sopenharmony_ci	ldq_u	$22,15($16)	# .. e1 :
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci	extbl	$18,3,$18	# e0	:
358c2ecf20Sopenharmony_ci	ldq_u	$2,0($17)	# .. e1 :
368c2ecf20Sopenharmony_ci	sra	$4,32,$4	# e0	:
378c2ecf20Sopenharmony_ci	ldq_u	$23,7($17)	# .. e1 :
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	extql	$0,$16,$0	# e0	:
408c2ecf20Sopenharmony_ci	ldq_u	$3,8($17)	# .. e1 :
418c2ecf20Sopenharmony_ci	extqh	$21,$16,$21	# e0	:
428c2ecf20Sopenharmony_ci	ldq_u	$24,15($17)	# .. e1 :
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	sll	$5,16,$5	# e0	:
458c2ecf20Sopenharmony_ci	or	$0,$21,$0	# .. e1 : 1st src word complete
468c2ecf20Sopenharmony_ci	extql	$1,$16,$1	# e0	:
478c2ecf20Sopenharmony_ci	addq	$20,$0,$20	# .. e1 : begin summing the words
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	extqh	$22,$16,$22	# e0	:
508c2ecf20Sopenharmony_ci	cmpult	$20,$0,$0	# .. e1 :
518c2ecf20Sopenharmony_ci	sll	$6,8,$6		# e0	:
528c2ecf20Sopenharmony_ci	or	$1,$22,$1	# .. e1 : 2nd src word complete
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	extql	$2,$17,$2	# e0	:
558c2ecf20Sopenharmony_ci	or	$4,$18,$18	# .. e1 :
568c2ecf20Sopenharmony_ci	extqh	$23,$17,$23	# e0	:
578c2ecf20Sopenharmony_ci	or	$5,$6,$5	# .. e1 :
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	extql	$3,$17,$3	# e0	:
608c2ecf20Sopenharmony_ci	or	$2,$23,$2	# .. e1 : 1st dst word complete
618c2ecf20Sopenharmony_ci	extqh	$24,$17,$24	# e0	:
628c2ecf20Sopenharmony_ci	or	$18,$5,$18	# .. e1 : len complete
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	extwh	$19,7,$7	# e0    :
658c2ecf20Sopenharmony_ci	or	$3,$24,$3	# .. e1 : 2nd dst word complete
668c2ecf20Sopenharmony_ci	extbl	$19,1,$19	# e0    :
678c2ecf20Sopenharmony_ci	addq	$20,$1,$20	# .. e1 :
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	or	$19,$7,$19	# e0    :
708c2ecf20Sopenharmony_ci	cmpult	$20,$1,$1	# .. e1 :
718c2ecf20Sopenharmony_ci	sll	$19,48,$19	# e0    :
728c2ecf20Sopenharmony_ci	nop			# .. e0 :
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	sra	$19,32,$19	# e0    : proto complete
758c2ecf20Sopenharmony_ci	addq	$20,$2,$20	# .. e1 :
768c2ecf20Sopenharmony_ci	cmpult	$20,$2,$2	# e0    :
778c2ecf20Sopenharmony_ci	addq	$20,$3,$20	# .. e1 :
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci	cmpult	$20,$3,$3	# e0    :
808c2ecf20Sopenharmony_ci	addq	$20,$18,$20	# .. e1 :
818c2ecf20Sopenharmony_ci	cmpult	$20,$18,$18	# e0    :
828c2ecf20Sopenharmony_ci	addq	$20,$19,$20	# .. e1 :
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	cmpult	$20,$19,$19	# e0    :
858c2ecf20Sopenharmony_ci	addq	$0,$1,$0	# .. e1 : merge the carries back into the csum
868c2ecf20Sopenharmony_ci	addq	$2,$3,$2	# e0    :
878c2ecf20Sopenharmony_ci	addq	$18,$19,$18	# .. e1 :
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	addq	$0,$2,$0	# e0    :
908c2ecf20Sopenharmony_ci	addq	$20,$18,$20	# .. e1 :
918c2ecf20Sopenharmony_ci	addq	$0,$20,$0	# e0    :
928c2ecf20Sopenharmony_ci	unop			#       :
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	extwl	$0,2,$2		# e0    : begin folding the 64-bit value
958c2ecf20Sopenharmony_ci	zapnot	$0,3,$3		# .. e1 :
968c2ecf20Sopenharmony_ci	extwl	$0,4,$1		# e0    :
978c2ecf20Sopenharmony_ci	addq	$2,$3,$3	# .. e1 :
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	extwl	$0,6,$0		# e0    :
1008c2ecf20Sopenharmony_ci	addq	$3,$1,$3	# .. e1 :
1018c2ecf20Sopenharmony_ci	addq	$0,$3,$0	# e0    :
1028c2ecf20Sopenharmony_ci	unop			#       :
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	extwl	$0,2,$1		# e0    : fold 18-bit value
1058c2ecf20Sopenharmony_ci	zapnot	$0,3,$0		# .. e1 :
1068c2ecf20Sopenharmony_ci	addq	$0,$1,$0	# e0    :
1078c2ecf20Sopenharmony_ci	unop			#       :
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	extwl	$0,2,$1		# e0    : fold 17-bit value
1108c2ecf20Sopenharmony_ci	zapnot	$0,3,$0		# .. e1 :
1118c2ecf20Sopenharmony_ci	addq	$0,$1,$0	# e0    :
1128c2ecf20Sopenharmony_ci	not	$0,$0		# .. e1 : and complement.
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	zapnot	$0,3,$0		# e0    :
1158c2ecf20Sopenharmony_ci	ret			# .. e1 :
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	.end csum_ipv6_magic
1188c2ecf20Sopenharmony_ci	EXPORT_SYMBOL(csum_ipv6_magic)
119