xref: /linux/arch/sparc/lib/NG4memcpy.S (revision 0ae2d26ffe70c32d4a7fe77593f0a55ce416c09e)
1ae2c6ca6SDavid S. Miller/* NG4memcpy.S: Niagara-4 optimized memcpy.
2ae2c6ca6SDavid S. Miller *
3ae2c6ca6SDavid S. Miller * Copyright (C) 2012 David S. Miller (davem@davemloft.net)
4ae2c6ca6SDavid S. Miller */
5ae2c6ca6SDavid S. Miller
6ae2c6ca6SDavid S. Miller#ifdef __KERNEL__
795707704SDavid S. Miller#include <linux/linkage.h>
8ae2c6ca6SDavid S. Miller#include <asm/visasm.h>
9ae2c6ca6SDavid S. Miller#include <asm/asi.h>
10ae2c6ca6SDavid S. Miller#define GLOBAL_SPARE	%g7
11ae2c6ca6SDavid S. Miller#else
12ae2c6ca6SDavid S. Miller#define ASI_BLK_INIT_QUAD_LDD_P 0xe2
13ae2c6ca6SDavid S. Miller#define FPRS_FEF  0x04
14ae2c6ca6SDavid S. Miller
15ae2c6ca6SDavid S. Miller/* On T4 it is very expensive to access ASRs like %fprs and
16ae2c6ca6SDavid S. Miller * %asi, avoiding a read or a write can save ~50 cycles.
17ae2c6ca6SDavid S. Miller */
18ae2c6ca6SDavid S. Miller#define FPU_ENTER			\
19ae2c6ca6SDavid S. Miller	rd	%fprs, %o5;		\
20ae2c6ca6SDavid S. Miller	andcc	%o5, FPRS_FEF, %g0;	\
21ae2c6ca6SDavid S. Miller	be,a,pn	%icc, 999f;		\
22ae2c6ca6SDavid S. Miller	 wr	%g0, FPRS_FEF, %fprs;	\
23ae2c6ca6SDavid S. Miller	999:
24ae2c6ca6SDavid S. Miller
25ae2c6ca6SDavid S. Miller#ifdef MEMCPY_DEBUG
26ae2c6ca6SDavid S. Miller#define VISEntryHalf FPU_ENTER; \
27ae2c6ca6SDavid S. Miller		     clr %g1; clr %g2; clr %g3; clr %g5; subcc %g0, %g0, %g0;
28ae2c6ca6SDavid S. Miller#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs
29ae2c6ca6SDavid S. Miller#else
30ae2c6ca6SDavid S. Miller#define VISEntryHalf FPU_ENTER
31ae2c6ca6SDavid S. Miller#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs
32ae2c6ca6SDavid S. Miller#endif
33ae2c6ca6SDavid S. Miller
34ae2c6ca6SDavid S. Miller#define GLOBAL_SPARE	%g5
35ae2c6ca6SDavid S. Miller#endif
36ae2c6ca6SDavid S. Miller
37ae2c6ca6SDavid S. Miller#ifndef STORE_ASI
38ae2c6ca6SDavid S. Miller#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA
39ae2c6ca6SDavid S. Miller#define STORE_ASI	ASI_BLK_INIT_QUAD_LDD_P
40ae2c6ca6SDavid S. Miller#else
41ae2c6ca6SDavid S. Miller#define STORE_ASI	0x80		/* ASI_P */
42ae2c6ca6SDavid S. Miller#endif
43ae2c6ca6SDavid S. Miller#endif
44ae2c6ca6SDavid S. Miller
45f4da3628SDavid S. Miller#if !defined(EX_LD) && !defined(EX_ST)
46f4da3628SDavid S. Miller#define NON_USER_COPY
47f4da3628SDavid S. Miller#endif
48f4da3628SDavid S. Miller
49ae2c6ca6SDavid S. Miller#ifndef EX_LD
5095707704SDavid S. Miller#define EX_LD(x,y)	x
51ae2c6ca6SDavid S. Miller#endif
52a7c5724bSRob Gardner#ifndef EX_LD_FP
5395707704SDavid S. Miller#define EX_LD_FP(x,y)	x
54a7c5724bSRob Gardner#endif
55ae2c6ca6SDavid S. Miller
56ae2c6ca6SDavid S. Miller#ifndef EX_ST
5795707704SDavid S. Miller#define EX_ST(x,y)	x
58ae2c6ca6SDavid S. Miller#endif
59a7c5724bSRob Gardner#ifndef EX_ST_FP
6095707704SDavid S. Miller#define EX_ST_FP(x,y)	x
61a7c5724bSRob Gardner#endif
62ae2c6ca6SDavid S. Miller
63ae2c6ca6SDavid S. Miller
64ae2c6ca6SDavid S. Miller#ifndef LOAD
65ae2c6ca6SDavid S. Miller#define LOAD(type,addr,dest)	type [addr], dest
66ae2c6ca6SDavid S. Miller#endif
67ae2c6ca6SDavid S. Miller
68ae2c6ca6SDavid S. Miller#ifndef STORE
69ae2c6ca6SDavid S. Miller#ifndef MEMCPY_DEBUG
70ae2c6ca6SDavid S. Miller#define STORE(type,src,addr)	type src, [addr]
71ae2c6ca6SDavid S. Miller#else
72ae2c6ca6SDavid S. Miller#define STORE(type,src,addr)	type##a src, [addr] %asi
73ae2c6ca6SDavid S. Miller#endif
74ae2c6ca6SDavid S. Miller#endif
75ae2c6ca6SDavid S. Miller
76ae2c6ca6SDavid S. Miller#ifndef STORE_INIT
77ae2c6ca6SDavid S. Miller#define STORE_INIT(src,addr)	stxa src, [addr] STORE_ASI
78ae2c6ca6SDavid S. Miller#endif
79ae2c6ca6SDavid S. Miller
80ae2c6ca6SDavid S. Miller#ifndef FUNC_NAME
81ae2c6ca6SDavid S. Miller#define FUNC_NAME	NG4memcpy
82ae2c6ca6SDavid S. Miller#endif
83ae2c6ca6SDavid S. Miller#ifndef PREAMBLE
84ae2c6ca6SDavid S. Miller#define PREAMBLE
85ae2c6ca6SDavid S. Miller#endif
86ae2c6ca6SDavid S. Miller
87ae2c6ca6SDavid S. Miller#ifndef XCC
88ae2c6ca6SDavid S. Miller#define XCC xcc
89ae2c6ca6SDavid S. Miller#endif
90ae2c6ca6SDavid S. Miller
91ae2c6ca6SDavid S. Miller	.register	%g2,#scratch
92ae2c6ca6SDavid S. Miller	.register	%g3,#scratch
93ae2c6ca6SDavid S. Miller
94ae2c6ca6SDavid S. Miller	.text
9595707704SDavid S. Miller#ifndef EX_RETVAL
9695707704SDavid S. Miller#define EX_RETVAL(x)	x
9795707704SDavid S. Miller__restore_asi_fp:
9895707704SDavid S. Miller	VISExitHalf
9995707704SDavid S. Miller__restore_asi:
10095707704SDavid S. Miller	retl
10195707704SDavid S. Miller	 wr	%g0, ASI_AIUS, %asi
10295707704SDavid S. Miller
10395707704SDavid S. MillerENTRY(NG4_retl_o2)
10495707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
10595707704SDavid S. Miller	 mov	%o2, %o0
10695707704SDavid S. MillerENDPROC(NG4_retl_o2)
10795707704SDavid S. MillerENTRY(NG4_retl_o2_plus_1)
10895707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
10995707704SDavid S. Miller	 add	%o2, 1, %o0
11095707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_1)
11195707704SDavid S. MillerENTRY(NG4_retl_o2_plus_4)
11295707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
11395707704SDavid S. Miller	 add	%o2, 4, %o0
11495707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_4)
11595707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5)
11695707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
11795707704SDavid S. Miller	 add	%o2, %o5, %o0
11895707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5)
11995707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5_plus_4)
12095707704SDavid S. Miller	add	%o5, 4, %o5
12195707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
12295707704SDavid S. Miller	 add	%o2, %o5, %o0
12395707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5_plus_4)
12495707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5_plus_8)
12595707704SDavid S. Miller	add	%o5, 8, %o5
12695707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
12795707704SDavid S. Miller	 add	%o2, %o5, %o0
12895707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5_plus_8)
12995707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5_plus_16)
13095707704SDavid S. Miller	add	%o5, 16, %o5
13195707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
13295707704SDavid S. Miller	 add	%o2, %o5, %o0
13395707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5_plus_16)
13495707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5_plus_24)
13595707704SDavid S. Miller	add	%o5, 24, %o5
13695707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
13795707704SDavid S. Miller	 add	%o2, %o5, %o0
13895707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5_plus_24)
13995707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o5_plus_32)
14095707704SDavid S. Miller	add	%o5, 32, %o5
14195707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
14295707704SDavid S. Miller	 add	%o2, %o5, %o0
14395707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o5_plus_32)
14495707704SDavid S. MillerENTRY(NG4_retl_o2_plus_g1)
14595707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
14695707704SDavid S. Miller	 add	%o2, %g1, %o0
14795707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_g1)
14895707704SDavid S. MillerENTRY(NG4_retl_o2_plus_g1_plus_1)
14995707704SDavid S. Miller	add	%g1, 1, %g1
15095707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
15195707704SDavid S. Miller	 add	%o2, %g1, %o0
15295707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_g1_plus_1)
15395707704SDavid S. MillerENTRY(NG4_retl_o2_plus_g1_plus_8)
15495707704SDavid S. Miller	add	%g1, 8, %g1
15595707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
15695707704SDavid S. Miller	 add	%o2, %g1, %o0
15795707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_g1_plus_8)
15895707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4)
15995707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
16095707704SDavid S. Miller	 add	%o2, %o4, %o0
16195707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4)
16295707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_8)
16395707704SDavid S. Miller	add	%o4, 8, %o4
16495707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
16595707704SDavid S. Miller	 add	%o2, %o4, %o0
16695707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_8)
16795707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_16)
16895707704SDavid S. Miller	add	%o4, 16, %o4
16995707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
17095707704SDavid S. Miller	 add	%o2, %o4, %o0
17195707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_16)
17295707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_24)
17395707704SDavid S. Miller	add	%o4, 24, %o4
17495707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
17595707704SDavid S. Miller	 add	%o2, %o4, %o0
17695707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_24)
17795707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_32)
17895707704SDavid S. Miller	add	%o4, 32, %o4
17995707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
18095707704SDavid S. Miller	 add	%o2, %o4, %o0
18195707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_32)
18295707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_40)
18395707704SDavid S. Miller	add	%o4, 40, %o4
18495707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
18595707704SDavid S. Miller	 add	%o2, %o4, %o0
18695707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_40)
18795707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_48)
18895707704SDavid S. Miller	add	%o4, 48, %o4
18995707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
19095707704SDavid S. Miller	 add	%o2, %o4, %o0
19195707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_48)
19295707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_56)
19395707704SDavid S. Miller	add	%o4, 56, %o4
19495707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
19595707704SDavid S. Miller	 add	%o2, %o4, %o0
19695707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_56)
19795707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_64)
19895707704SDavid S. Miller	add	%o4, 64, %o4
19995707704SDavid S. Miller	ba,pt	%xcc, __restore_asi
20095707704SDavid S. Miller	 add	%o2, %o4, %o0
20195707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_64)
20295707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_fp)
20395707704SDavid S. Miller	ba,pt	%xcc, __restore_asi_fp
20495707704SDavid S. Miller	 add	%o2, %o4, %o0
20595707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_fp)
20695707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_8_fp)
20795707704SDavid S. Miller	add	%o4, 8, %o4
20895707704SDavid S. Miller	ba,pt	%xcc, __restore_asi_fp
20995707704SDavid S. Miller	 add	%o2, %o4, %o0
21095707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_8_fp)
21195707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_16_fp)
21295707704SDavid S. Miller	add	%o4, 16, %o4
21395707704SDavid S. Miller	ba,pt	%xcc, __restore_asi_fp
21495707704SDavid S. Miller	 add	%o2, %o4, %o0
21595707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_16_fp)
21695707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_24_fp)
21795707704SDavid S. Miller	add	%o4, 24, %o4
21895707704SDavid S. Miller	ba,pt	%xcc, __restore_asi_fp
21995707704SDavid S. Miller	 add	%o2, %o4, %o0
22095707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_24_fp)
22195707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_32_fp)
22295707704SDavid S. Miller	add	%o4, 32, %o4
22395707704SDavid S. Miller	ba,pt	%xcc, __restore_asi_fp
22495707704SDavid S. Miller	 add	%o2, %o4, %o0
22595707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_32_fp)
22695707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_40_fp)
22795707704SDavid S. Miller	add	%o4, 40, %o4
22895707704SDavid S. Miller	ba,pt	%xcc, __restore_asi_fp
22995707704SDavid S. Miller	 add	%o2, %o4, %o0
23095707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_40_fp)
23195707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_48_fp)
23295707704SDavid S. Miller	add	%o4, 48, %o4
23395707704SDavid S. Miller	ba,pt	%xcc, __restore_asi_fp
23495707704SDavid S. Miller	 add	%o2, %o4, %o0
23595707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_48_fp)
23695707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_56_fp)
23795707704SDavid S. Miller	add	%o4, 56, %o4
23895707704SDavid S. Miller	ba,pt	%xcc, __restore_asi_fp
23995707704SDavid S. Miller	 add	%o2, %o4, %o0
24095707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_56_fp)
24195707704SDavid S. MillerENTRY(NG4_retl_o2_plus_o4_plus_64_fp)
24295707704SDavid S. Miller	add	%o4, 64, %o4
24395707704SDavid S. Miller	ba,pt	%xcc, __restore_asi_fp
24495707704SDavid S. Miller	 add	%o2, %o4, %o0
24595707704SDavid S. MillerENDPROC(NG4_retl_o2_plus_o4_plus_64_fp)
24695707704SDavid S. Miller#endif
247ae2c6ca6SDavid S. Miller	.align		64
248ae2c6ca6SDavid S. Miller
249ae2c6ca6SDavid S. Miller	.globl	FUNC_NAME
250ae2c6ca6SDavid S. Miller	.type	FUNC_NAME,#function
251ae2c6ca6SDavid S. MillerFUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
252ae2c6ca6SDavid S. Miller#ifdef MEMCPY_DEBUG
253ae2c6ca6SDavid S. Miller	wr		%g0, 0x80, %asi
254ae2c6ca6SDavid S. Miller#endif
255ae2c6ca6SDavid S. Miller	srlx		%o2, 31, %g2
256ae2c6ca6SDavid S. Miller	cmp		%g2, 0
257ae2c6ca6SDavid S. Miller	tne		%XCC, 5
258ae2c6ca6SDavid S. Miller	PREAMBLE
259ae2c6ca6SDavid S. Miller	mov		%o0, %o3
260ae2c6ca6SDavid S. Miller	brz,pn		%o2, .Lexit
261ae2c6ca6SDavid S. Miller	 cmp		%o2, 3
262ae2c6ca6SDavid S. Miller	ble,pn		%icc, .Ltiny
263ae2c6ca6SDavid S. Miller	 cmp		%o2, 19
264ae2c6ca6SDavid S. Miller	ble,pn		%icc, .Lsmall
265ae2c6ca6SDavid S. Miller	 or		%o0, %o1, %g2
266ae2c6ca6SDavid S. Miller	cmp		%o2, 128
267ae2c6ca6SDavid S. Miller	bl,pn		%icc, .Lmedium
268ae2c6ca6SDavid S. Miller	 nop
269ae2c6ca6SDavid S. Miller
270ae2c6ca6SDavid S. Miller.Llarge:/* len >= 0x80 */
271ae2c6ca6SDavid S. Miller	/* First get dest 8 byte aligned.  */
272ae2c6ca6SDavid S. Miller	sub		%g0, %o0, %g1
273ae2c6ca6SDavid S. Miller	and		%g1, 0x7, %g1
274ae2c6ca6SDavid S. Miller	brz,pt		%g1, 51f
275ae2c6ca6SDavid S. Miller	 sub		%o2, %g1, %o2
276ae2c6ca6SDavid S. Miller
27795707704SDavid S. Miller
27895707704SDavid S. Miller1:	EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1)
279ae2c6ca6SDavid S. Miller	add		%o1, 1, %o1
280ae2c6ca6SDavid S. Miller	subcc		%g1, 1, %g1
281ae2c6ca6SDavid S. Miller	add		%o0, 1, %o0
282ae2c6ca6SDavid S. Miller	bne,pt		%icc, 1b
28395707704SDavid S. Miller	 EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1)
284ae2c6ca6SDavid S. Miller
285ae2c6ca6SDavid S. Miller51:	LOAD(prefetch, %o1 + 0x040, #n_reads_strong)
286ae2c6ca6SDavid S. Miller	LOAD(prefetch, %o1 + 0x080, #n_reads_strong)
287ae2c6ca6SDavid S. Miller	LOAD(prefetch, %o1 + 0x0c0, #n_reads_strong)
288ae2c6ca6SDavid S. Miller	LOAD(prefetch, %o1 + 0x100, #n_reads_strong)
289ae2c6ca6SDavid S. Miller	LOAD(prefetch, %o1 + 0x140, #n_reads_strong)
290ae2c6ca6SDavid S. Miller	LOAD(prefetch, %o1 + 0x180, #n_reads_strong)
291ae2c6ca6SDavid S. Miller	LOAD(prefetch, %o1 + 0x1c0, #n_reads_strong)
292ae2c6ca6SDavid S. Miller	LOAD(prefetch, %o1 + 0x200, #n_reads_strong)
293ae2c6ca6SDavid S. Miller
294ae2c6ca6SDavid S. Miller	/* Check if we can use the straight fully aligned
295ae2c6ca6SDavid S. Miller	 * loop, or we require the alignaddr/faligndata variant.
296ae2c6ca6SDavid S. Miller	 */
297ae2c6ca6SDavid S. Miller	andcc		%o1, 0x7, %o5
298ae2c6ca6SDavid S. Miller	bne,pn		%icc, .Llarge_src_unaligned
299ae2c6ca6SDavid S. Miller	 sub		%g0, %o0, %g1
300ae2c6ca6SDavid S. Miller
301ae2c6ca6SDavid S. Miller	/* Legitimize the use of initializing stores by getting dest
302ae2c6ca6SDavid S. Miller	 * to be 64-byte aligned.
303ae2c6ca6SDavid S. Miller	 */
304ae2c6ca6SDavid S. Miller	and		%g1, 0x3f, %g1
305ae2c6ca6SDavid S. Miller	brz,pt		%g1, .Llarge_aligned
306ae2c6ca6SDavid S. Miller	 sub		%o2, %g1, %o2
307ae2c6ca6SDavid S. Miller
30895707704SDavid S. Miller1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1)
309ae2c6ca6SDavid S. Miller	add		%o1, 8, %o1
310ae2c6ca6SDavid S. Miller	subcc		%g1, 8, %g1
311ae2c6ca6SDavid S. Miller	add		%o0, 8, %o0
312ae2c6ca6SDavid S. Miller	bne,pt		%icc, 1b
31395707704SDavid S. Miller	 EX_ST(STORE(stx, %g2, %o0 - 0x08), NG4_retl_o2_plus_g1_plus_8)
314ae2c6ca6SDavid S. Miller
315ae2c6ca6SDavid S. Miller.Llarge_aligned:
316ae2c6ca6SDavid S. Miller	/* len >= 0x80 && src 8-byte aligned && dest 8-byte aligned */
317ae2c6ca6SDavid S. Miller	andn		%o2, 0x3f, %o4
318ae2c6ca6SDavid S. Miller	sub		%o2, %o4, %o2
319ae2c6ca6SDavid S. Miller
32095707704SDavid S. Miller1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o4)
321ae2c6ca6SDavid S. Miller	add		%o1, 0x40, %o1
32295707704SDavid S. Miller	EX_LD(LOAD(ldx, %o1 - 0x38, %g2), NG4_retl_o2_plus_o4)
323ae2c6ca6SDavid S. Miller	subcc		%o4, 0x40, %o4
32495707704SDavid S. Miller	EX_LD(LOAD(ldx, %o1 - 0x30, %g3), NG4_retl_o2_plus_o4_plus_64)
32595707704SDavid S. Miller	EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_64)
32695707704SDavid S. Miller	EX_LD(LOAD(ldx, %o1 - 0x20, %o5), NG4_retl_o2_plus_o4_plus_64)
32795707704SDavid S. Miller	EX_ST(STORE_INIT(%g1, %o0), NG4_retl_o2_plus_o4_plus_64)
328ae2c6ca6SDavid S. Miller	add		%o0, 0x08, %o0
32995707704SDavid S. Miller	EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_56)
330ae2c6ca6SDavid S. Miller	add		%o0, 0x08, %o0
33195707704SDavid S. Miller	EX_LD(LOAD(ldx, %o1 - 0x18, %g2), NG4_retl_o2_plus_o4_plus_48)
33295707704SDavid S. Miller	EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_48)
333ae2c6ca6SDavid S. Miller	add		%o0, 0x08, %o0
33495707704SDavid S. Miller	EX_LD(LOAD(ldx, %o1 - 0x10, %g3), NG4_retl_o2_plus_o4_plus_40)
33595707704SDavid S. Miller	EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_40)
336ae2c6ca6SDavid S. Miller	add		%o0, 0x08, %o0
33795707704SDavid S. Miller	EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_32)
33895707704SDavid S. Miller	EX_ST(STORE_INIT(%o5, %o0), NG4_retl_o2_plus_o4_plus_32)
339ae2c6ca6SDavid S. Miller	add		%o0, 0x08, %o0
34095707704SDavid S. Miller	EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_24)
341ae2c6ca6SDavid S. Miller	add		%o0, 0x08, %o0
34295707704SDavid S. Miller	EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_16)
343ae2c6ca6SDavid S. Miller	add		%o0, 0x08, %o0
34495707704SDavid S. Miller	EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_8)
345ae2c6ca6SDavid S. Miller	add		%o0, 0x08, %o0
346ae2c6ca6SDavid S. Miller	bne,pt		%icc, 1b
347ae2c6ca6SDavid S. Miller	 LOAD(prefetch, %o1 + 0x200, #n_reads_strong)
348ae2c6ca6SDavid S. Miller
349ae2c6ca6SDavid S. Miller	membar		#StoreLoad | #StoreStore
350ae2c6ca6SDavid S. Miller
351ae2c6ca6SDavid S. Miller	brz,pn		%o2, .Lexit
352ae2c6ca6SDavid S. Miller	 cmp		%o2, 19
353ae2c6ca6SDavid S. Miller	ble,pn		%icc, .Lsmall_unaligned
354ae2c6ca6SDavid S. Miller	 nop
355ae2c6ca6SDavid S. Miller	ba,a,pt		%icc, .Lmedium_noprefetch
356ae2c6ca6SDavid S. Miller
357ae2c6ca6SDavid S. Miller.Lexit:	retl
358ae2c6ca6SDavid S. Miller	 mov		EX_RETVAL(%o3), %o0
359ae2c6ca6SDavid S. Miller
360ae2c6ca6SDavid S. Miller.Llarge_src_unaligned:
361f4da3628SDavid S. Miller#ifdef NON_USER_COPY
362f4da3628SDavid S. Miller	VISEntryHalfFast(.Lmedium_vis_entry_fail)
363f4da3628SDavid S. Miller#else
364f4da3628SDavid S. Miller	VISEntryHalf
365f4da3628SDavid S. Miller#endif
366ae2c6ca6SDavid S. Miller	andn		%o2, 0x3f, %o4
367ae2c6ca6SDavid S. Miller	sub		%o2, %o4, %o2
368ae2c6ca6SDavid S. Miller	alignaddr	%o1, %g0, %g1
369ae2c6ca6SDavid S. Miller	add		%o1, %o4, %o1
37095707704SDavid S. Miller	EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0), NG4_retl_o2_plus_o4)
37195707704SDavid S. Miller1:	EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2), NG4_retl_o2_plus_o4)
372ae2c6ca6SDavid S. Miller	subcc		%o4, 0x40, %o4
37395707704SDavid S. Miller	EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4), NG4_retl_o2_plus_o4_plus_64)
37495707704SDavid S. Miller	EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6), NG4_retl_o2_plus_o4_plus_64)
37595707704SDavid S. Miller	EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8), NG4_retl_o2_plus_o4_plus_64)
37695707704SDavid S. Miller	EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10), NG4_retl_o2_plus_o4_plus_64)
37795707704SDavid S. Miller	EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12), NG4_retl_o2_plus_o4_plus_64)
37895707704SDavid S. Miller	EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14), NG4_retl_o2_plus_o4_plus_64)
379ae2c6ca6SDavid S. Miller	faligndata	%f0, %f2, %f16
38095707704SDavid S. Miller	EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0), NG4_retl_o2_plus_o4_plus_64)
381ae2c6ca6SDavid S. Miller	faligndata	%f2, %f4, %f18
382ae2c6ca6SDavid S. Miller	add		%g1, 0x40, %g1
383ae2c6ca6SDavid S. Miller	faligndata	%f4, %f6, %f20
384ae2c6ca6SDavid S. Miller	faligndata	%f6, %f8, %f22
385ae2c6ca6SDavid S. Miller	faligndata	%f8, %f10, %f24
386ae2c6ca6SDavid S. Miller	faligndata	%f10, %f12, %f26
387ae2c6ca6SDavid S. Miller	faligndata	%f12, %f14, %f28
388ae2c6ca6SDavid S. Miller	faligndata	%f14, %f0, %f30
38995707704SDavid S. Miller	EX_ST_FP(STORE(std, %f16, %o0 + 0x00), NG4_retl_o2_plus_o4_plus_64)
39095707704SDavid S. Miller	EX_ST_FP(STORE(std, %f18, %o0 + 0x08), NG4_retl_o2_plus_o4_plus_56)
39195707704SDavid S. Miller	EX_ST_FP(STORE(std, %f20, %o0 + 0x10), NG4_retl_o2_plus_o4_plus_48)
39295707704SDavid S. Miller	EX_ST_FP(STORE(std, %f22, %o0 + 0x18), NG4_retl_o2_plus_o4_plus_40)
39395707704SDavid S. Miller	EX_ST_FP(STORE(std, %f24, %o0 + 0x20), NG4_retl_o2_plus_o4_plus_32)
39495707704SDavid S. Miller	EX_ST_FP(STORE(std, %f26, %o0 + 0x28), NG4_retl_o2_plus_o4_plus_24)
39595707704SDavid S. Miller	EX_ST_FP(STORE(std, %f28, %o0 + 0x30), NG4_retl_o2_plus_o4_plus_16)
39695707704SDavid S. Miller	EX_ST_FP(STORE(std, %f30, %o0 + 0x38), NG4_retl_o2_plus_o4_plus_8)
397ae2c6ca6SDavid S. Miller	add		%o0, 0x40, %o0
398ae2c6ca6SDavid S. Miller	bne,pt		%icc, 1b
399ae2c6ca6SDavid S. Miller	 LOAD(prefetch, %g1 + 0x200, #n_reads_strong)
40044922150SDavid S. Miller#ifdef NON_USER_COPY
40144922150SDavid S. Miller	VISExitHalfFast
40244922150SDavid S. Miller#else
403ae2c6ca6SDavid S. Miller	VISExitHalf
40444922150SDavid S. Miller#endif
405ae2c6ca6SDavid S. Miller	brz,pn		%o2, .Lexit
406ae2c6ca6SDavid S. Miller	 cmp		%o2, 19
407ae2c6ca6SDavid S. Miller	ble,pn		%icc, .Lsmall_unaligned
408ae2c6ca6SDavid S. Miller	 nop
409ae2c6ca6SDavid S. Miller	ba,a,pt		%icc, .Lmedium_unaligned
410ae2c6ca6SDavid S. Miller
411f4da3628SDavid S. Miller#ifdef NON_USER_COPY
412f4da3628SDavid S. Miller.Lmedium_vis_entry_fail:
413f4da3628SDavid S. Miller	 or		%o0, %o1, %g2
414f4da3628SDavid S. Miller#endif
415ae2c6ca6SDavid S. Miller.Lmedium:
416ae2c6ca6SDavid S. Miller	LOAD(prefetch, %o1 + 0x40, #n_reads_strong)
417ae2c6ca6SDavid S. Miller	andcc		%g2, 0x7, %g0
418ae2c6ca6SDavid S. Miller	bne,pn		%icc, .Lmedium_unaligned
419ae2c6ca6SDavid S. Miller	 nop
420ae2c6ca6SDavid S. Miller.Lmedium_noprefetch:
421ae2c6ca6SDavid S. Miller	andncc		%o2, 0x20 - 1, %o5
422ae2c6ca6SDavid S. Miller	be,pn		%icc, 2f
423ae2c6ca6SDavid S. Miller	 sub		%o2, %o5, %o2
42495707704SDavid S. Miller1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5)
42595707704SDavid S. Miller	EX_LD(LOAD(ldx, %o1 + 0x08, %g2), NG4_retl_o2_plus_o5)
42695707704SDavid S. Miller	EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE), NG4_retl_o2_plus_o5)
42795707704SDavid S. Miller	EX_LD(LOAD(ldx, %o1 + 0x18, %o4), NG4_retl_o2_plus_o5)
428ae2c6ca6SDavid S. Miller	add		%o1, 0x20, %o1
429ae2c6ca6SDavid S. Miller	subcc		%o5, 0x20, %o5
43095707704SDavid S. Miller	EX_ST(STORE(stx, %g1, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_32)
43195707704SDavid S. Miller	EX_ST(STORE(stx, %g2, %o0 + 0x08), NG4_retl_o2_plus_o5_plus_24)
43295707704SDavid S. Miller	EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), NG4_retl_o2_plus_o5_plus_24)
43395707704SDavid S. Miller	EX_ST(STORE(stx, %o4, %o0 + 0x18), NG4_retl_o2_plus_o5_plus_8)
434ae2c6ca6SDavid S. Miller	bne,pt		%icc, 1b
435ae2c6ca6SDavid S. Miller	 add		%o0, 0x20, %o0
436ae2c6ca6SDavid S. Miller2:	andcc		%o2, 0x18, %o5
437ae2c6ca6SDavid S. Miller	be,pt		%icc, 3f
438ae2c6ca6SDavid S. Miller	 sub		%o2, %o5, %o2
43995707704SDavid S. Miller
44095707704SDavid S. Miller1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5)
441ae2c6ca6SDavid S. Miller	add		%o1, 0x08, %o1
442ae2c6ca6SDavid S. Miller	add		%o0, 0x08, %o0
443ae2c6ca6SDavid S. Miller	subcc		%o5, 0x08, %o5
444ae2c6ca6SDavid S. Miller	bne,pt		%icc, 1b
44595707704SDavid S. Miller	 EX_ST(STORE(stx, %g1, %o0 - 0x08), NG4_retl_o2_plus_o5_plus_8)
446ae2c6ca6SDavid S. Miller3:	brz,pt		%o2, .Lexit
447ae2c6ca6SDavid S. Miller	 cmp		%o2, 0x04
448ae2c6ca6SDavid S. Miller	bl,pn		%icc, .Ltiny
449ae2c6ca6SDavid S. Miller	 nop
45095707704SDavid S. Miller	EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2)
451ae2c6ca6SDavid S. Miller	add		%o1, 0x04, %o1
452ae2c6ca6SDavid S. Miller	add		%o0, 0x04, %o0
453ae2c6ca6SDavid S. Miller	subcc		%o2, 0x04, %o2
454ae2c6ca6SDavid S. Miller	bne,pn		%icc, .Ltiny
45595707704SDavid S. Miller	 EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_4)
456ae2c6ca6SDavid S. Miller	ba,a,pt		%icc, .Lexit
457ae2c6ca6SDavid S. Miller.Lmedium_unaligned:
458ae2c6ca6SDavid S. Miller	/* First get dest 8 byte aligned.  */
459ae2c6ca6SDavid S. Miller	sub		%g0, %o0, %g1
460ae2c6ca6SDavid S. Miller	and		%g1, 0x7, %g1
461ae2c6ca6SDavid S. Miller	brz,pt		%g1, 2f
462ae2c6ca6SDavid S. Miller	 sub		%o2, %g1, %o2
463ae2c6ca6SDavid S. Miller
46495707704SDavid S. Miller1:	EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1)
465ae2c6ca6SDavid S. Miller	add		%o1, 1, %o1
466ae2c6ca6SDavid S. Miller	subcc		%g1, 1, %g1
467ae2c6ca6SDavid S. Miller	add		%o0, 1, %o0
468ae2c6ca6SDavid S. Miller	bne,pt		%icc, 1b
46995707704SDavid S. Miller	 EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1)
470ae2c6ca6SDavid S. Miller2:
471ae2c6ca6SDavid S. Miller	and		%o1, 0x7, %g1
472ae2c6ca6SDavid S. Miller	brz,pn		%g1, .Lmedium_noprefetch
473ae2c6ca6SDavid S. Miller	 sll		%g1, 3, %g1
474ae2c6ca6SDavid S. Miller	mov		64, %g2
475ae2c6ca6SDavid S. Miller	sub		%g2, %g1, %g2
476ae2c6ca6SDavid S. Miller	andn		%o1, 0x7, %o1
47795707704SDavid S. Miller	EX_LD(LOAD(ldx, %o1 + 0x00, %o4), NG4_retl_o2)
478ae2c6ca6SDavid S. Miller	sllx		%o4, %g1, %o4
479ae2c6ca6SDavid S. Miller	andn		%o2, 0x08 - 1, %o5
480ae2c6ca6SDavid S. Miller	sub		%o2, %o5, %o2
48195707704SDavid S. Miller1:	EX_LD(LOAD(ldx, %o1 + 0x08, %g3), NG4_retl_o2_plus_o5)
482ae2c6ca6SDavid S. Miller	add		%o1, 0x08, %o1
483ae2c6ca6SDavid S. Miller	subcc		%o5, 0x08, %o5
484ae2c6ca6SDavid S. Miller	srlx		%g3, %g2, GLOBAL_SPARE
485ae2c6ca6SDavid S. Miller	or		GLOBAL_SPARE, %o4, GLOBAL_SPARE
48695707704SDavid S. Miller	EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_8)
487ae2c6ca6SDavid S. Miller	add		%o0, 0x08, %o0
488ae2c6ca6SDavid S. Miller	bne,pt		%icc, 1b
489ae2c6ca6SDavid S. Miller	 sllx		%g3, %g1, %o4
490ae2c6ca6SDavid S. Miller	srl		%g1, 3, %g1
491ae2c6ca6SDavid S. Miller	add		%o1, %g1, %o1
492ae2c6ca6SDavid S. Miller	brz,pn		%o2, .Lexit
493ae2c6ca6SDavid S. Miller	 nop
494ae2c6ca6SDavid S. Miller	ba,pt		%icc, .Lsmall_unaligned
495ae2c6ca6SDavid S. Miller
496ae2c6ca6SDavid S. Miller.Ltiny:
49795707704SDavid S. Miller	EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2)
498ae2c6ca6SDavid S. Miller	subcc		%o2, 1, %o2
499ae2c6ca6SDavid S. Miller	be,pn		%icc, .Lexit
50095707704SDavid S. Miller	 EX_ST(STORE(stb, %g1, %o0 + 0x00), NG4_retl_o2_plus_1)
50195707704SDavid S. Miller	EX_LD(LOAD(ldub, %o1 + 0x01, %g1), NG4_retl_o2)
502ae2c6ca6SDavid S. Miller	subcc		%o2, 1, %o2
503ae2c6ca6SDavid S. Miller	be,pn		%icc, .Lexit
50495707704SDavid S. Miller	 EX_ST(STORE(stb, %g1, %o0 + 0x01), NG4_retl_o2_plus_1)
50595707704SDavid S. Miller	EX_LD(LOAD(ldub, %o1 + 0x02, %g1), NG4_retl_o2)
506ae2c6ca6SDavid S. Miller	ba,pt		%icc, .Lexit
50795707704SDavid S. Miller	 EX_ST(STORE(stb, %g1, %o0 + 0x02), NG4_retl_o2)
508ae2c6ca6SDavid S. Miller
509ae2c6ca6SDavid S. Miller.Lsmall:
510ae2c6ca6SDavid S. Miller	andcc		%g2, 0x3, %g0
511ae2c6ca6SDavid S. Miller	bne,pn		%icc, .Lsmall_unaligned
512ae2c6ca6SDavid S. Miller	 andn		%o2, 0x4 - 1, %o5
513ae2c6ca6SDavid S. Miller	sub		%o2, %o5, %o2
514ae2c6ca6SDavid S. Miller1:
51595707704SDavid S. Miller	EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5)
516ae2c6ca6SDavid S. Miller	add		%o1, 0x04, %o1
517ae2c6ca6SDavid S. Miller	subcc		%o5, 0x04, %o5
518ae2c6ca6SDavid S. Miller	add		%o0, 0x04, %o0
519ae2c6ca6SDavid S. Miller	bne,pt		%icc, 1b
52095707704SDavid S. Miller	 EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_o5_plus_4)
521ae2c6ca6SDavid S. Miller	brz,pt		%o2, .Lexit
522ae2c6ca6SDavid S. Miller	 nop
523ae2c6ca6SDavid S. Miller	ba,a,pt		%icc, .Ltiny
524ae2c6ca6SDavid S. Miller
525ae2c6ca6SDavid S. Miller.Lsmall_unaligned:
52695707704SDavid S. Miller1:	EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2)
527ae2c6ca6SDavid S. Miller	add		%o1, 1, %o1
528ae2c6ca6SDavid S. Miller	add		%o0, 1, %o0
529ae2c6ca6SDavid S. Miller	subcc		%o2, 1, %o2
530ae2c6ca6SDavid S. Miller	bne,pt		%icc, 1b
53195707704SDavid S. Miller	 EX_ST(STORE(stb, %g1, %o0 - 0x01), NG4_retl_o2_plus_1)
532ae2c6ca6SDavid S. Miller	ba,a,pt		%icc, .Lexit
533*0ae2d26fSBabu Moger	 nop
534ae2c6ca6SDavid S. Miller	.size		FUNC_NAME, .-FUNC_NAME
535