copy_in_user.S 2.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5
/* copy_in_user.S: Copy from userspace to userspace.
 *
 * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
 */

6
#include <linux/linkage.h>
L
Linus Torvalds 已提交
7
#include <asm/asi.h>
A
Al Viro 已提交
8
#include <asm/export.h>
L
Linus Torvalds 已提交
9 10 11

#define XCC xcc

12
#define EX(x,y,z)		\
L
Linus Torvalds 已提交
13
98:	x,y;			\
14
	.section __ex_table,"a";\
L
Linus Torvalds 已提交
15
	.align 4;		\
16
	.word 98b, z;		\
L
Linus Torvalds 已提交
17 18 19
	.text;			\
	.align 4;

20 21 22 23
#define EX_O4(x,y) EX(x,y,__retl_o4_plus_8)
#define EX_O2_4(x,y) EX(x,y,__retl_o2_plus_4)
#define EX_O2_1(x,y) EX(x,y,__retl_o2_plus_1)

L
Linus Torvalds 已提交
24 25 26 27
	.register	%g2,#scratch
	.register	%g3,#scratch

	.text
28 29 30 31 32 33 34 35 36 37 38
__retl_o4_plus_8:
	add	%o4, %o2, %o4
	retl
	 add	%o4, 8, %o0
__retl_o2_plus_4:
	retl
	 add	%o2, 4, %o0
__retl_o2_plus_1:
	retl
	 add	%o2, 1, %o0

L
Linus Torvalds 已提交
39 40 41 42 43 44 45 46
	.align	32

	/* Don't try to get too fancy here, just nice and
	 * simple.  This is predominantly used for well aligned
	 * small copies in the compat layer.  It is also used
	 * to copy register windows around during thread cloning.
	 */

47
ENTRY(___copy_in_user)	/* %o0=dst, %o1=src, %o2=len */
L
Linus Torvalds 已提交
48 49 50 51 52 53 54 55 56 57
	cmp		%o2, 0
	be,pn		%XCC, 85f
	 or		%o0, %o1, %o3
	cmp		%o2, 16
	bleu,a,pn	%XCC, 80f
	 or		%o3, %o2, %o3

	/* 16 < len <= 64 */
	andcc		%o3, 0x7, %g0
	bne,pn		%XCC, 90f
58
	 nop
L
Linus Torvalds 已提交
59 60 61 62

	andn		%o2, 0x7, %o4
	and		%o2, 0x7, %o2
1:	subcc		%o4, 0x8, %o4
63 64
	EX_O4(ldxa [%o1] %asi, %o5)
	EX_O4(stxa %o5, [%o0] %asi)
65
	add		%o1, 0x8, %o1
L
Linus Torvalds 已提交
66
	bgu,pt		%XCC, 1b
67
	 add		%o0, 0x8, %o0
L
Linus Torvalds 已提交
68 69 70 71
	andcc		%o2, 0x4, %g0
	be,pt		%XCC, 1f
	 nop
	sub		%o2, 0x4, %o2
72 73
	EX_O2_4(lduwa [%o1] %asi, %o5)
	EX_O2_4(stwa %o5, [%o0] %asi)
L
Linus Torvalds 已提交
74
	add		%o1, 0x4, %o1
75
	add		%o0, 0x4, %o0
L
Linus Torvalds 已提交
76 77 78 79 80 81 82 83 84
1:	cmp		%o2, 0
	be,pt		%XCC, 85f
	 nop
	ba,pt		%xcc, 90f
	 nop

80:	/* 0 < len <= 16 */
	andcc		%o3, 0x3, %g0
	bne,pn		%XCC, 90f
85
	 nop
L
Linus Torvalds 已提交
86 87 88

82:
	subcc		%o2, 4, %o2
89 90
	EX_O2_4(lduwa [%o1] %asi, %g1)
	EX_O2_4(stwa %g1, [%o0] %asi)
91
	add		%o1, 4, %o1
L
Linus Torvalds 已提交
92
	bgu,pt		%XCC, 82b
93
	 add		%o0, 4, %o0
L
Linus Torvalds 已提交
94 95 96 97 98 99 100

85:	retl
	 clr		%o0

	.align	32
90:
	subcc		%o2, 1, %o2
101 102
	EX_O2_1(lduba [%o1] %asi, %g1)
	EX_O2_1(stba %g1, [%o0] %asi)
103
	add		%o1, 1, %o1
L
Linus Torvalds 已提交
104
	bgu,pt		%XCC, 90b
105
	 add		%o0, 1, %o0
L
Linus Torvalds 已提交
106 107
	retl
	 clr		%o0
108
ENDPROC(___copy_in_user)
A
Al Viro 已提交
109
EXPORT_SYMBOL(___copy_in_user)