blob: 4c89b486fa0d7f88f04615363e6f64f48c917ac0 [file] [log] [blame]
Kyle Swenson8d8f6542021-03-15 11:02:55 -06001/* 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
9#define XCC xcc
10
11#define EX(x,y,z) \
1298: x,y; \
13 .section __ex_table,"a";\
14 .align 4; \
15 .word 98b, z; \
16 .text; \
17 .align 4;
18
19#define EX_O4(x,y) EX(x,y,__retl_o4_plus_8)
20#define EX_O2_4(x,y) EX(x,y,__retl_o2_plus_4)
21#define EX_O2_1(x,y) EX(x,y,__retl_o2_plus_1)
22
23 .register %g2,#scratch
24 .register %g3,#scratch
25
26 .text
27__retl_o4_plus_8:
28 add %o4, %o2, %o4
29 retl
30 add %o4, 8, %o0
31__retl_o2_plus_4:
32 retl
33 add %o2, 4, %o0
34__retl_o2_plus_1:
35 retl
36 add %o2, 1, %o0
37
38 .align 32
39
40 /* Don't try to get too fancy here, just nice and
41 * simple. This is predominantly used for well aligned
42 * small copies in the compat layer. It is also used
43 * to copy register windows around during thread cloning.
44 */
45
46ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */
47 cmp %o2, 0
48 be,pn %XCC, 85f
49 or %o0, %o1, %o3
50 cmp %o2, 16
51 bleu,a,pn %XCC, 80f
52 or %o3, %o2, %o3
53
54 /* 16 < len <= 64 */
55 andcc %o3, 0x7, %g0
56 bne,pn %XCC, 90f
57 nop
58
59 andn %o2, 0x7, %o4
60 and %o2, 0x7, %o2
611: subcc %o4, 0x8, %o4
62 EX_O4(ldxa [%o1] %asi, %o5)
63 EX_O4(stxa %o5, [%o0] %asi)
64 add %o1, 0x8, %o1
65 bgu,pt %XCC, 1b
66 add %o0, 0x8, %o0
67 andcc %o2, 0x4, %g0
68 be,pt %XCC, 1f
69 nop
70 sub %o2, 0x4, %o2
71 EX_O2_4(lduwa [%o1] %asi, %o5)
72 EX_O2_4(stwa %o5, [%o0] %asi)
73 add %o1, 0x4, %o1
74 add %o0, 0x4, %o0
751: cmp %o2, 0
76 be,pt %XCC, 85f
77 nop
78 ba,pt %xcc, 90f
79 nop
80
8180: /* 0 < len <= 16 */
82 andcc %o3, 0x3, %g0
83 bne,pn %XCC, 90f
84 nop
85
8682:
87 subcc %o2, 4, %o2
88 EX_O2_4(lduwa [%o1] %asi, %g1)
89 EX_O2_4(stwa %g1, [%o0] %asi)
90 add %o1, 4, %o1
91 bgu,pt %XCC, 82b
92 add %o0, 4, %o0
93
9485: retl
95 clr %o0
96
97 .align 32
9890:
99 subcc %o2, 1, %o2
100 EX_O2_1(lduba [%o1] %asi, %g1)
101 EX_O2_1(stba %g1, [%o0] %asi)
102 add %o1, 1, %o1
103 bgu,pt %XCC, 90b
104 add %o0, 1, %o0
105 retl
106 clr %o0
107ENDPROC(___copy_in_user)