18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/* GENmemcpy.S: Generic sparc64 memcpy.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#ifdef __KERNEL__
88c2ecf20Sopenharmony_ci#include <linux/linkage.h>
98c2ecf20Sopenharmony_ci#define GLOBAL_SPARE	%g7
108c2ecf20Sopenharmony_ci#else
118c2ecf20Sopenharmony_ci#define GLOBAL_SPARE	%g5
128c2ecf20Sopenharmony_ci#endif
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#ifndef EX_LD
158c2ecf20Sopenharmony_ci#define EX_LD(x,y)	x
168c2ecf20Sopenharmony_ci#endif
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#ifndef EX_ST
198c2ecf20Sopenharmony_ci#define EX_ST(x,y)	x
208c2ecf20Sopenharmony_ci#endif
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#ifndef LOAD
238c2ecf20Sopenharmony_ci#define LOAD(type,addr,dest)	type [addr], dest
248c2ecf20Sopenharmony_ci#endif
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#ifndef STORE
278c2ecf20Sopenharmony_ci#define STORE(type,src,addr)	type src, [addr]
288c2ecf20Sopenharmony_ci#endif
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#ifndef FUNC_NAME
318c2ecf20Sopenharmony_ci#define FUNC_NAME	GENmemcpy
328c2ecf20Sopenharmony_ci#endif
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#ifndef PREAMBLE
358c2ecf20Sopenharmony_ci#define PREAMBLE
368c2ecf20Sopenharmony_ci#endif
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#ifndef XCC
398c2ecf20Sopenharmony_ci#define XCC xcc
408c2ecf20Sopenharmony_ci#endif
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	.register	%g2,#scratch
438c2ecf20Sopenharmony_ci	.register	%g3,#scratch
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	.text
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#ifndef EX_RETVAL
488c2ecf20Sopenharmony_ci#define EX_RETVAL(x)	x
498c2ecf20Sopenharmony_ciENTRY(GEN_retl_o4_1)
508c2ecf20Sopenharmony_ci	add	%o4, %o2, %o4
518c2ecf20Sopenharmony_ci	retl
528c2ecf20Sopenharmony_ci	 add	%o4, 1, %o0
538c2ecf20Sopenharmony_ciENDPROC(GEN_retl_o4_1)
548c2ecf20Sopenharmony_ciENTRY(GEN_retl_g1_8)
558c2ecf20Sopenharmony_ci	add	%g1, %o2, %g1
568c2ecf20Sopenharmony_ci	retl
578c2ecf20Sopenharmony_ci	 add	%g1, 8, %o0
588c2ecf20Sopenharmony_ciENDPROC(GEN_retl_g1_8)
598c2ecf20Sopenharmony_ciENTRY(GEN_retl_o2_4)
608c2ecf20Sopenharmony_ci	retl
618c2ecf20Sopenharmony_ci	 add	%o2, 4, %o0
628c2ecf20Sopenharmony_ciENDPROC(GEN_retl_o2_4)
638c2ecf20Sopenharmony_ciENTRY(GEN_retl_o2_1)
648c2ecf20Sopenharmony_ci	retl
658c2ecf20Sopenharmony_ci	 add	%o2, 1, %o0
668c2ecf20Sopenharmony_ciENDPROC(GEN_retl_o2_1)
678c2ecf20Sopenharmony_ci#endif
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	.align		64
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	.globl	FUNC_NAME
728c2ecf20Sopenharmony_ci	.type	FUNC_NAME,#function
738c2ecf20Sopenharmony_ciFUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
748c2ecf20Sopenharmony_ci	srlx		%o2, 31, %g2
758c2ecf20Sopenharmony_ci	cmp		%g2, 0
768c2ecf20Sopenharmony_ci	tne		%XCC, 5
778c2ecf20Sopenharmony_ci	PREAMBLE
788c2ecf20Sopenharmony_ci	mov		%o0, GLOBAL_SPARE
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	cmp		%o2, 0
818c2ecf20Sopenharmony_ci	be,pn		%XCC, 85f
828c2ecf20Sopenharmony_ci	 or		%o0, %o1, %o3
838c2ecf20Sopenharmony_ci	cmp		%o2, 16
848c2ecf20Sopenharmony_ci	blu,a,pn	%XCC, 80f
858c2ecf20Sopenharmony_ci	 or		%o3, %o2, %o3
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	xor		%o0, %o1, %o4
888c2ecf20Sopenharmony_ci	andcc		%o4, 0x7, %g0
898c2ecf20Sopenharmony_ci	bne,a,pn	%XCC, 90f
908c2ecf20Sopenharmony_ci	 sub		%o0, %o1, %o3
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	and		%o0, 0x7, %o4
938c2ecf20Sopenharmony_ci	sub		%o4, 0x8, %o4
948c2ecf20Sopenharmony_ci	sub		%g0, %o4, %o4
958c2ecf20Sopenharmony_ci	sub		%o2, %o4, %o2
968c2ecf20Sopenharmony_ci1:	subcc		%o4, 1, %o4
978c2ecf20Sopenharmony_ci	EX_LD(LOAD(ldub, %o1, %g1),GEN_retl_o4_1)
988c2ecf20Sopenharmony_ci	EX_ST(STORE(stb, %g1, %o0),GEN_retl_o4_1)
998c2ecf20Sopenharmony_ci	add		%o1, 1, %o1
1008c2ecf20Sopenharmony_ci	bne,pt		%XCC, 1b
1018c2ecf20Sopenharmony_ci	add		%o0, 1, %o0
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	andn		%o2, 0x7, %g1
1048c2ecf20Sopenharmony_ci	sub		%o2, %g1, %o2
1058c2ecf20Sopenharmony_ci1:	subcc		%g1, 0x8, %g1
1068c2ecf20Sopenharmony_ci	EX_LD(LOAD(ldx, %o1, %g2),GEN_retl_g1_8)
1078c2ecf20Sopenharmony_ci	EX_ST(STORE(stx, %g2, %o0),GEN_retl_g1_8)
1088c2ecf20Sopenharmony_ci	add		%o1, 0x8, %o1
1098c2ecf20Sopenharmony_ci	bne,pt		%XCC, 1b
1108c2ecf20Sopenharmony_ci	 add		%o0, 0x8, %o0
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	brz,pt		%o2, 85f
1138c2ecf20Sopenharmony_ci	 sub		%o0, %o1, %o3
1148c2ecf20Sopenharmony_ci	ba,a,pt		%XCC, 90f
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	.align		64
1178c2ecf20Sopenharmony_ci80: /* 0 < len <= 16 */
1188c2ecf20Sopenharmony_ci	andcc		%o3, 0x3, %g0
1198c2ecf20Sopenharmony_ci	bne,pn		%XCC, 90f
1208c2ecf20Sopenharmony_ci	 sub		%o0, %o1, %o3
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci1:
1238c2ecf20Sopenharmony_ci	subcc		%o2, 4, %o2
1248c2ecf20Sopenharmony_ci	EX_LD(LOAD(lduw, %o1, %g1),GEN_retl_o2_4)
1258c2ecf20Sopenharmony_ci	EX_ST(STORE(stw, %g1, %o1 + %o3),GEN_retl_o2_4)
1268c2ecf20Sopenharmony_ci	bgu,pt		%XCC, 1b
1278c2ecf20Sopenharmony_ci	 add		%o1, 4, %o1
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci85:	retl
1308c2ecf20Sopenharmony_ci	 mov		EX_RETVAL(GLOBAL_SPARE), %o0
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci	.align		32
1338c2ecf20Sopenharmony_ci90:
1348c2ecf20Sopenharmony_ci	subcc		%o2, 1, %o2
1358c2ecf20Sopenharmony_ci	EX_LD(LOAD(ldub, %o1, %g1),GEN_retl_o2_1)
1368c2ecf20Sopenharmony_ci	EX_ST(STORE(stb, %g1, %o1 + %o3),GEN_retl_o2_1)
1378c2ecf20Sopenharmony_ci	bgu,pt		%XCC, 90b
1388c2ecf20Sopenharmony_ci	 add		%o1, 1, %o1
1398c2ecf20Sopenharmony_ci	retl
1408c2ecf20Sopenharmony_ci	 mov		EX_RETVAL(GLOBAL_SPARE), %o0
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	.size		FUNC_NAME, .-FUNC_NAME
143