blob: 0252b218de45ac0685c440de07d0d2d0891834e9 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* copy_in_user.S: Copy from userspace to userspace.
2 *
3 * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
4 */
5
David S. Milleraeb39872009-02-08 22:32:31 -08006#include <linux/linkage.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007#include <asm/asi.h>
Al Virod3867f042016-01-16 21:39:30 -05008#include <asm/export.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07009
10#define XCC xcc
11
David S. Miller0096ac92016-08-15 15:08:18 -070012#define EX(x,y,z) \
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398: x,y; \
David S. Miller4d000d52006-03-04 23:23:56 -080014 .section __ex_table,"a";\
Linus Torvalds1da177e2005-04-16 15:20:36 -070015 .align 4; \
David S. Miller0096ac92016-08-15 15:08:18 -070016 .word 98b, z; \
Linus Torvalds1da177e2005-04-16 15:20:36 -070017 .text; \
18 .align 4;
19
David S. Miller0096ac92016-08-15 15:08:18 -070020#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
Linus Torvalds1da177e2005-04-16 15:20:36 -070024 .register %g2,#scratch
25 .register %g3,#scratch
26
27 .text
David S. Miller0096ac92016-08-15 15:08:18 -070028__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
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 .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
David S. Milleraeb39872009-02-08 22:32:31 -080047ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */
Linus Torvalds1da177e2005-04-16 15:20:36 -070048 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
David S. Milleraeb39872009-02-08 22:32:31 -080058 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
60 andn %o2, 0x7, %o4
61 and %o2, 0x7, %o2
621: subcc %o4, 0x8, %o4
David S. Miller0096ac92016-08-15 15:08:18 -070063 EX_O4(ldxa [%o1] %asi, %o5)
64 EX_O4(stxa %o5, [%o0] %asi)
David S. Milleraeb39872009-02-08 22:32:31 -080065 add %o1, 0x8, %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 bgu,pt %XCC, 1b
David S. Milleraeb39872009-02-08 22:32:31 -080067 add %o0, 0x8, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 andcc %o2, 0x4, %g0
69 be,pt %XCC, 1f
70 nop
71 sub %o2, 0x4, %o2
David S. Miller0096ac92016-08-15 15:08:18 -070072 EX_O2_4(lduwa [%o1] %asi, %o5)
73 EX_O2_4(stwa %o5, [%o0] %asi)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 add %o1, 0x4, %o1
David S. Milleraeb39872009-02-08 22:32:31 -080075 add %o0, 0x4, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761: 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
David S. Milleraeb39872009-02-08 22:32:31 -080085 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
8782:
88 subcc %o2, 4, %o2
David S. Miller0096ac92016-08-15 15:08:18 -070089 EX_O2_4(lduwa [%o1] %asi, %g1)
90 EX_O2_4(stwa %g1, [%o0] %asi)
David S. Milleraeb39872009-02-08 22:32:31 -080091 add %o1, 4, %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 bgu,pt %XCC, 82b
David S. Milleraeb39872009-02-08 22:32:31 -080093 add %o0, 4, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
9585: retl
96 clr %o0
97
98 .align 32
9990:
100 subcc %o2, 1, %o2
David S. Miller0096ac92016-08-15 15:08:18 -0700101 EX_O2_1(lduba [%o1] %asi, %g1)
102 EX_O2_1(stba %g1, [%o0] %asi)
David S. Milleraeb39872009-02-08 22:32:31 -0800103 add %o1, 1, %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 bgu,pt %XCC, 90b
David S. Milleraeb39872009-02-08 22:32:31 -0800105 add %o0, 1, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 retl
107 clr %o0
David S. Milleraeb39872009-02-08 22:32:31 -0800108ENDPROC(___copy_in_user)
Al Virod3867f042016-01-16 21:39:30 -0500109EXPORT_SYMBOL(___copy_in_user)