xref: /openbmc/linux/arch/sparc/lib/copy_in_user.S (revision fcc8487d)
1/* copy_in_user.S: Copy from userspace to userspace.
2 *
3 * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
4 */
5
6#include <linux/linkage.h>
7#include <asm/asi.h>
8#include <asm/export.h>
9
10#define XCC xcc
11
12#define EX(x,y,z)		\
1398:	x,y;			\
14	.section __ex_table,"a";\
15	.align 4;		\
16	.word 98b, z;		\
17	.text;			\
18	.align 4;
19
20#define EX_O4(x,y) EX(x,y,__retl_o4_plus_8)
21#define EX_O2_4(x,y) EX(x,y,__retl_o2_plus_4)
22#define EX_O2_1(x,y) EX(x,y,__retl_o2_plus_1)
23
24	.register	%g2,#scratch
25	.register	%g3,#scratch
26
27	.text
28__retl_o4_plus_8:
29	add	%o4, %o2, %o4
30	retl
31	 add	%o4, 8, %o0
32__retl_o2_plus_4:
33	retl
34	 add	%o2, 4, %o0
35__retl_o2_plus_1:
36	retl
37	 add	%o2, 1, %o0
38
39	.align	32
40
41	/* Don't try to get too fancy here, just nice and
42	 * simple.  This is predominantly used for well aligned
43	 * small copies in the compat layer.  It is also used
44	 * to copy register windows around during thread cloning.
45	 */
46
47ENTRY(raw_copy_in_user)	/* %o0=dst, %o1=src, %o2=len */
48	cmp		%o2, 0
49	be,pn		%XCC, 85f
50	 or		%o0, %o1, %o3
51	cmp		%o2, 16
52	bleu,a,pn	%XCC, 80f
53	 or		%o3, %o2, %o3
54
55	/* 16 < len <= 64 */
56	andcc		%o3, 0x7, %g0
57	bne,pn		%XCC, 90f
58	 nop
59
60	andn		%o2, 0x7, %o4
61	and		%o2, 0x7, %o2
621:	subcc		%o4, 0x8, %o4
63	EX_O4(ldxa [%o1] %asi, %o5)
64	EX_O4(stxa %o5, [%o0] %asi)
65	add		%o1, 0x8, %o1
66	bgu,pt		%XCC, 1b
67	 add		%o0, 0x8, %o0
68	andcc		%o2, 0x4, %g0
69	be,pt		%XCC, 1f
70	 nop
71	sub		%o2, 0x4, %o2
72	EX_O2_4(lduwa [%o1] %asi, %o5)
73	EX_O2_4(stwa %o5, [%o0] %asi)
74	add		%o1, 0x4, %o1
75	add		%o0, 0x4, %o0
761:	cmp		%o2, 0
77	be,pt		%XCC, 85f
78	 nop
79	ba,pt		%xcc, 90f
80	 nop
81
8280:	/* 0 < len <= 16 */
83	andcc		%o3, 0x3, %g0
84	bne,pn		%XCC, 90f
85	 nop
86
8782:
88	subcc		%o2, 4, %o2
89	EX_O2_4(lduwa [%o1] %asi, %g1)
90	EX_O2_4(stwa %g1, [%o0] %asi)
91	add		%o1, 4, %o1
92	bgu,pt		%XCC, 82b
93	 add		%o0, 4, %o0
94
9585:	retl
96	 clr		%o0
97
98	.align	32
9990:
100	subcc		%o2, 1, %o2
101	EX_O2_1(lduba [%o1] %asi, %g1)
102	EX_O2_1(stba %g1, [%o0] %asi)
103	add		%o1, 1, %o1
104	bgu,pt		%XCC, 90b
105	 add		%o0, 1, %o0
106	retl
107	 clr		%o0
108ENDPROC(raw_copy_in_user)
109EXPORT_SYMBOL(raw_copy_in_user)
110