blob: 302c0e60dc2ceb48a3212840ac7891f337419d14 [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>
8
9#define XCC xcc
10
11#define EX(x,y) \
1298: x,y; \
David S. Miller4d000d52006-03-04 23:23:56 -080013 .section __ex_table,"a";\
Linus Torvalds1da177e2005-04-16 15:20:36 -070014 .align 4; \
David S. Miller40bdac72009-02-08 22:00:55 -080015 .word 98b, __retl_one; \
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 .text; \
17 .align 4;
18
19 .register %g2,#scratch
20 .register %g3,#scratch
21
22 .text
23 .align 32
24
25 /* Don't try to get too fancy here, just nice and
26 * simple. This is predominantly used for well aligned
27 * small copies in the compat layer. It is also used
28 * to copy register windows around during thread cloning.
29 */
30
David S. Milleraeb39872009-02-08 22:32:31 -080031ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */
Linus Torvalds1da177e2005-04-16 15:20:36 -070032 cmp %o2, 0
33 be,pn %XCC, 85f
34 or %o0, %o1, %o3
35 cmp %o2, 16
36 bleu,a,pn %XCC, 80f
37 or %o3, %o2, %o3
38
39 /* 16 < len <= 64 */
40 andcc %o3, 0x7, %g0
41 bne,pn %XCC, 90f
David S. Milleraeb39872009-02-08 22:32:31 -080042 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
44 andn %o2, 0x7, %o4
45 and %o2, 0x7, %o2
461: subcc %o4, 0x8, %o4
47 EX(ldxa [%o1] %asi, %o5)
David S. Milleraeb39872009-02-08 22:32:31 -080048 EX(stxa %o5, [%o0] %asi)
49 add %o1, 0x8, %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -070050 bgu,pt %XCC, 1b
David S. Milleraeb39872009-02-08 22:32:31 -080051 add %o0, 0x8, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 andcc %o2, 0x4, %g0
53 be,pt %XCC, 1f
54 nop
55 sub %o2, 0x4, %o2
56 EX(lduwa [%o1] %asi, %o5)
David S. Milleraeb39872009-02-08 22:32:31 -080057 EX(stwa %o5, [%o0] %asi)
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 add %o1, 0x4, %o1
David S. Milleraeb39872009-02-08 22:32:31 -080059 add %o0, 0x4, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601: cmp %o2, 0
61 be,pt %XCC, 85f
62 nop
63 ba,pt %xcc, 90f
64 nop
65
6680: /* 0 < len <= 16 */
67 andcc %o3, 0x3, %g0
68 bne,pn %XCC, 90f
David S. Milleraeb39872009-02-08 22:32:31 -080069 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
7182:
72 subcc %o2, 4, %o2
73 EX(lduwa [%o1] %asi, %g1)
David S. Milleraeb39872009-02-08 22:32:31 -080074 EX(stwa %g1, [%o0] %asi)
75 add %o1, 4, %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -070076 bgu,pt %XCC, 82b
David S. Milleraeb39872009-02-08 22:32:31 -080077 add %o0, 4, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
7985: retl
80 clr %o0
81
82 .align 32
8390:
84 subcc %o2, 1, %o2
85 EX(lduba [%o1] %asi, %g1)
David S. Milleraeb39872009-02-08 22:32:31 -080086 EX(stba %g1, [%o0] %asi)
87 add %o1, 1, %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 bgu,pt %XCC, 90b
David S. Milleraeb39872009-02-08 22:32:31 -080089 add %o0, 1, %o0
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 retl
91 clr %o0
David S. Milleraeb39872009-02-08 22:32:31 -080092ENDPROC(___copy_in_user)