1/* GENmemcpy.S: Generic sparc64 memcpy.
2 *
3 * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
4 */
5
6#ifdef __KERNEL__
7#define GLOBAL_SPARE	%g7
8#else
9#define GLOBAL_SPARE	%g5
10#endif
11
12#ifndef EX_LD
13#define EX_LD(x)	x
14#endif
15
16#ifndef EX_ST
17#define EX_ST(x)	x
18#endif
19
20#ifndef EX_RETVAL
21#define EX_RETVAL(x)	x
22#endif
23
24#ifndef LOAD
25#define LOAD(type,addr,dest)	type [addr], dest
26#endif
27
28#ifndef STORE
29#define STORE(type,src,addr)	type src, [addr]
30#endif
31
32#ifndef FUNC_NAME
33#define FUNC_NAME	GENmemcpy
34#endif
35
36#ifndef PREAMBLE
37#define PREAMBLE
38#endif
39
40#ifndef XCC
41#define XCC xcc
42#endif
43
44	.register	%g2,#scratch
45	.register	%g3,#scratch
46
47	.text
48	.align		64
49
50	.globl	FUNC_NAME
51	.type	FUNC_NAME,#function
52FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
53	srlx		%o2, 31, %g2
54	cmp		%g2, 0
55	tne		%XCC, 5
56	PREAMBLE
57	mov		%o0, GLOBAL_SPARE
58
59	cmp		%o2, 0
60	be,pn		%XCC, 85f
61	 or		%o0, %o1, %o3
62	cmp		%o2, 16
63	blu,a,pn	%XCC, 80f
64	 or		%o3, %o2, %o3
65
66	xor		%o0, %o1, %o4
67	andcc		%o4, 0x7, %g0
68	bne,a,pn	%XCC, 90f
69	 sub		%o0, %o1, %o3
70
71	and		%o0, 0x7, %o4
72	sub		%o4, 0x8, %o4
73	sub		%g0, %o4, %o4
74	sub		%o2, %o4, %o2
751:	subcc		%o4, 1, %o4
76	EX_LD(LOAD(ldub, %o1, %g1))
77	EX_ST(STORE(stb, %g1, %o0))
78	add		%o1, 1, %o1
79	bne,pt		%XCC, 1b
80	add		%o0, 1, %o0
81
82	andn		%o2, 0x7, %g1
83	sub		%o2, %g1, %o2
841:	subcc		%g1, 0x8, %g1
85	EX_LD(LOAD(ldx, %o1, %g2))
86	EX_ST(STORE(stx, %g2, %o0))
87	add		%o1, 0x8, %o1
88	bne,pt		%XCC, 1b
89	 add		%o0, 0x8, %o0
90
91	brz,pt		%o2, 85f
92	 sub		%o0, %o1, %o3
93	ba,a,pt		%XCC, 90f
94
95	.align		64
9680: /* 0 < len <= 16 */
97	andcc		%o3, 0x3, %g0
98	bne,pn		%XCC, 90f
99	 sub		%o0, %o1, %o3
100
1011:
102	subcc		%o2, 4, %o2
103	EX_LD(LOAD(lduw, %o1, %g1))
104	EX_ST(STORE(stw, %g1, %o1 + %o3))
105	bgu,pt		%XCC, 1b
106	 add		%o1, 4, %o1
107
10885:	retl
109	 mov		EX_RETVAL(GLOBAL_SPARE), %o0
110
111	.align		32
11290:
113	subcc		%o2, 1, %o2
114	EX_LD(LOAD(ldub, %o1, %g1))
115	EX_ST(STORE(stb, %g1, %o1 + %o3))
116	bgu,pt		%XCC, 90b
117	 add		%o1, 1, %o1
118	retl
119	 mov		EX_RETVAL(GLOBAL_SPARE), %o0
120
121	.size		FUNC_NAME, .-FUNC_NAME
122