Linux-2.6.12-rc2
[linux-3.10.git] / arch / i386 / lib / putuser.S
1 /*
2  * __put_user functions.
3  *
4  * (C) Copyright 2005 Linus Torvalds
5  *
6  * These functions have a non-standard call interface
7  * to make them more efficient, especially as they
8  * return an error value in addition to the "real"
9  * return value.
10  */
11 #include <asm/thread_info.h>
12
13
14 /*
15  * __put_user_X
16  *
17  * Inputs:      %eax[:%edx] contains the data
18  *              %ecx contains the address
19  *
20  * Outputs:     %eax is error code (0 or -EFAULT)
21  *
22  * These functions should not modify any other registers,
23  * as they get called from within inline assembly.
24  */
25
26 #define ENTER   pushl %ebx ; GET_THREAD_INFO(%ebx)
27 #define EXIT    popl %ebx ; ret
28
29 .text
30 .align 4
31 .globl __put_user_1
32 __put_user_1:
33         ENTER
34         cmpl TI_addr_limit(%ebx),%ecx
35         jae bad_put_user
36 1:      movb %al,(%ecx)
37         xorl %eax,%eax
38         EXIT
39
40 .align 4
41 .globl __put_user_2
42 __put_user_2:
43         ENTER
44         movl TI_addr_limit(%ebx),%ebx
45         subl $1,%ebx
46         cmpl %ebx,%ecx
47         jae bad_put_user
48 2:      movw %ax,(%ecx)
49         xorl %eax,%eax
50         EXIT
51
52 .align 4
53 .globl __put_user_4
54 __put_user_4:
55         ENTER
56         movl TI_addr_limit(%ebx),%ebx
57         subl $3,%ebx
58         cmpl %ebx,%ecx
59         jae bad_put_user
60 3:      movl %eax,(%ecx)
61         xorl %eax,%eax
62         EXIT
63
64 .align 4
65 .globl __put_user_8
66 __put_user_8:
67         ENTER
68         movl TI_addr_limit(%ebx),%ebx
69         subl $7,%ebx
70         cmpl %ebx,%ecx
71         jae bad_put_user
72 4:      movl %eax,(%ecx)
73 5:      movl %edx,4(%ecx)
74         xorl %eax,%eax
75         EXIT
76
77 bad_put_user:
78         movl $-14,%eax
79         EXIT
80
81 .section __ex_table,"a"
82         .long 1b,bad_put_user
83         .long 2b,bad_put_user
84         .long 3b,bad_put_user
85         .long 4b,bad_put_user
86         .long 5b,bad_put_user
87 .previous