import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / arm / lib / getuser.S
1 /*
2  *  linux/arch/arm/lib/getuser.S
3  *
4  *  Copyright (C) 2001 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  *  Idea from x86 version, (C) Copyright 1998 Linus Torvalds
11  *
12  * These functions have a non-standard call interface to make them more
13  * efficient, especially as they return an error value in addition to
14  * the "real" return value.
15  *
16  * __get_user_X
17  *
18  * Inputs:      r0 contains the address
19  * Outputs:     r0 is the error code
20  *              r1, r2 contains the zero-extended value
21  *              lr corrupted
22  *
23  * No other registers must be altered.  (see include/asm-arm/uaccess.h
24  * for specific ASM register usage).
25  *
26  * Note that ADDR_LIMIT is either 0 or 0xc0000000.
27  * Note also that it is intended that __get_user_bad is not global.
28  */
29 #include <asm/constants.h>
30
31         .global __get_user_1
32 __get_user_1:
33         bic     r1, sp, #0x1f00
34         bic     r1, r1, #0x00ff
35         ldr     r1, [r1, #TSK_ADDR_LIMIT]
36         sub     r1, r1, #1
37         cmp     r0, r1
38 1:      ldrlsbt r1, [r0]
39         movls   r0, #0
40         movls   pc, lr
41         b       __get_user_bad
42
43         .global __get_user_2
44 __get_user_2:
45         bic     r2, sp, #0x1f00
46         bic     r2, r2, #0x00ff
47         ldr     r2, [r2, #TSK_ADDR_LIMIT]
48         sub     r2, r2, #2
49         cmp     r0, r2
50 2:      ldrlsbt r1, [r0], #1
51 3:      ldrlsbt r2, [r0]
52         orrls   r1, r1, r2, lsl #8
53         movls   r0, #0
54         movls   pc, lr
55         b       __get_user_bad
56
57         .global __get_user_4
58 __get_user_4:
59         bic     r1, sp, #0x1f00
60         bic     r1, r1, #0x00ff
61         ldr     r1, [r1, #TSK_ADDR_LIMIT]
62         sub     r1, r1, #4
63         cmp     r0, r1
64 4:      ldrlst  r1, [r0]
65         movls   r0, #0
66         movls   pc, lr
67         b       __get_user_bad
68
69         .global __get_user_8
70 __get_user_8:
71         bic     r2, sp, #0x1f00
72         bic     r2, r2, #0x00ff
73         ldr     r2, [r2, #TSK_ADDR_LIMIT]
74         sub     r2, r2, #8
75         cmp     r0, r2
76 5:      ldrlst  r1, [r0], #4
77 6:      ldrlst  r2, [r0]
78         movls   r0, #0
79         movls   pc, lr
80
81         /* fall through */
82
83 __get_user_bad_8:
84         mov     r2, #0
85 __get_user_bad:
86         mov     r1, #0
87         mov     r0, #-14
88         mov     pc, lr
89
90 .section __ex_table, "a"
91         .long   1b, __get_user_bad
92         .long   2b, __get_user_bad
93         .long   3b, __get_user_bad
94         .long   4b, __get_user_bad
95         .long   5b, __get_user_bad_8
96         .long   6b, __get_user_bad_8
97 .previous