xref: /linux/arch/sparc/lib/GENmemcpy.S (revision f3a8b6645dc2e60d11f20c1c23afd964ff4e55ae)
1/* GENmemcpy.S: Generic sparc64 memcpy.
2 *
3 * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
4 */
5
6#ifdef __KERNEL__
7#include <linux/linkage.h>
8#define GLOBAL_SPARE	%g7
9#else
10#define GLOBAL_SPARE	%g5
11#endif
12
13#ifndef EX_LD
14#define EX_LD(x,y)	x
15#endif
16
17#ifndef EX_ST
18#define EX_ST(x,y)	x
19#endif
20
21#ifndef LOAD
22#define LOAD(type,addr,dest)	type [addr], dest
23#endif
24
25#ifndef STORE
26#define STORE(type,src,addr)	type src, [addr]
27#endif
28
29#ifndef FUNC_NAME
30#define FUNC_NAME	GENmemcpy
31#endif
32
33#ifndef PREAMBLE
34#define PREAMBLE
35#endif
36
37#ifndef XCC
38#define XCC xcc
39#endif
40
41	.register	%g2,#scratch
42	.register	%g3,#scratch
43
44	.text
45
46#ifndef EX_RETVAL
47#define EX_RETVAL(x)	x
48ENTRY(GEN_retl_o4_1)
49	add	%o4, %o2, %o4
50	retl
51	 add	%o4, 1, %o0
52ENDPROC(GEN_retl_o4_1)
53ENTRY(GEN_retl_g1_8)
54	add	%g1, %o2, %g1
55	retl
56	 add	%g1, 8, %o0
57ENDPROC(GEN_retl_g1_8)
58ENTRY(GEN_retl_o2_4)
59	retl
60	 add	%o2, 4, %o0
61ENDPROC(GEN_retl_o2_4)
62ENTRY(GEN_retl_o2_1)
63	retl
64	 add	%o2, 1, %o0
65ENDPROC(GEN_retl_o2_1)
66#endif
67
68	.align		64
69
70	.globl	FUNC_NAME
71	.type	FUNC_NAME,#function
72FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
73	srlx		%o2, 31, %g2
74	cmp		%g2, 0
75	tne		%XCC, 5
76	PREAMBLE
77	mov		%o0, GLOBAL_SPARE
78
79	cmp		%o2, 0
80	be,pn		%XCC, 85f
81	 or		%o0, %o1, %o3
82	cmp		%o2, 16
83	blu,a,pn	%XCC, 80f
84	 or		%o3, %o2, %o3
85
86	xor		%o0, %o1, %o4
87	andcc		%o4, 0x7, %g0
88	bne,a,pn	%XCC, 90f
89	 sub		%o0, %o1, %o3
90
91	and		%o0, 0x7, %o4
92	sub		%o4, 0x8, %o4
93	sub		%g0, %o4, %o4
94	sub		%o2, %o4, %o2
951:	subcc		%o4, 1, %o4
96	EX_LD(LOAD(ldub, %o1, %g1),GEN_retl_o4_1)
97	EX_ST(STORE(stb, %g1, %o0),GEN_retl_o4_1)
98	add		%o1, 1, %o1
99	bne,pt		%XCC, 1b
100	add		%o0, 1, %o0
101
102	andn		%o2, 0x7, %g1
103	sub		%o2, %g1, %o2
1041:	subcc		%g1, 0x8, %g1
105	EX_LD(LOAD(ldx, %o1, %g2),GEN_retl_g1_8)
106	EX_ST(STORE(stx, %g2, %o0),GEN_retl_g1_8)
107	add		%o1, 0x8, %o1
108	bne,pt		%XCC, 1b
109	 add		%o0, 0x8, %o0
110
111	brz,pt		%o2, 85f
112	 sub		%o0, %o1, %o3
113	ba,a,pt		%XCC, 90f
114
115	.align		64
11680: /* 0 < len <= 16 */
117	andcc		%o3, 0x3, %g0
118	bne,pn		%XCC, 90f
119	 sub		%o0, %o1, %o3
120
1211:
122	subcc		%o2, 4, %o2
123	EX_LD(LOAD(lduw, %o1, %g1),GEN_retl_o2_4)
124	EX_ST(STORE(stw, %g1, %o1 + %o3),GEN_retl_o2_4)
125	bgu,pt		%XCC, 1b
126	 add		%o1, 4, %o1
127
12885:	retl
129	 mov		EX_RETVAL(GLOBAL_SPARE), %o0
130
131	.align		32
13290:
133	subcc		%o2, 1, %o2
134	EX_LD(LOAD(ldub, %o1, %g1),GEN_retl_o2_1)
135	EX_ST(STORE(stb, %g1, %o1 + %o3),GEN_retl_o2_1)
136	bgu,pt		%XCC, 90b
137	 add		%o1, 1, %o1
138	retl
139	 mov		EX_RETVAL(GLOBAL_SPARE), %o0
140
141	.size		FUNC_NAME, .-FUNC_NAME
142