Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-mmc
[linux-2.6] / arch / avr32 / lib / strnlen_user.S
1 /*
2  * Copy to/from userspace with optional address space checking.
3  *
4  * Copyright 2004-2006 Atmel Corporation
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 #include <asm/page.h>
11 #include <asm/thread_info.h>
12 #include <asm/processor.h>
13 #include <asm/asm.h>
14
15         .text
16         .align  1
17         .global strnlen_user
18         .type   strnlen_user, "function"
19 strnlen_user:
20         branch_if_kernel r8, __strnlen_user
21         sub     r8, r11, 1
22         add     r8, r12
23         retcs   0
24         brmi    adjust_length   /* do a closer inspection */
25
26         .global __strnlen_user
27         .type   __strnlen_user, "function"
28 __strnlen_user:
29         mov     r10, r12
30
31 10:     ld.ub   r8, r12++
32         cp.w    r8, 0
33         breq    2f
34         sub     r11, 1
35         brne    10b
36
37         sub     r12, -1
38 2:      sub     r12, r10
39         retal   r12
40
41
42         .type   adjust_length, "function"
43 adjust_length:
44         cp.w    r12, 0          /* addr must always be < TASK_SIZE */
45         retmi   0
46
47         pushm   lr
48         lddpc   lr, _task_size
49         sub     r11, lr, r12
50         mov     r9, r11
51         rcall   __strnlen_user
52         cp.w    r12, r9
53         brgt    1f
54         popm    pc
55 1:      popm    pc, r12=0
56
57         .align  2
58 _task_size:
59         .long   TASK_SIZE
60
61         .section .fixup, "ax"
62         .align  1
63 19:     retal   0
64
65         .section __ex_table, "a"
66         .align  2
67         .long   10b, 19b