Import changeset
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / lib / strnlen_user.S
1 /*
2  * Returns 0 if exception before NUL or reaching the supplied limit (N),
3  * a value greater than N if the string is longer than the limit, else
4  * strlen.
5  *
6  * Inputs:
7  *      in0:    address of buffer
8  *      in1:    string length limit N
9  * Outputs:
10  *      r8:     0 in case of fault, strlen(buffer)+1 otherwise
11  * 
12  * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
13  */
14
15 #include <asm/asmmacro.h>
16
17 /* If a fault occurs, r8 gets set to -EFAULT and r9 gets cleared.  */
18 #define EX(x...)                                \
19         .section __ex_table,"a";                \
20         data4 @gprel(99f);                      \
21         data4 (.Lexit-99f)|1;                   \
22         .previous                               \
23 99:     x;
24
25         .text
26         .psr abi64
27         .psr lsb
28         .lsb
29
30 GLOBAL_ENTRY(__strnlen_user)
31         UNW(.prologue)
32         alloc r2=ar.pfs,2,0,0,0
33         UNW(.save ar.lc, r16)
34         mov r16=ar.lc                   // preserve ar.lc
35
36         UNW(.body)
37
38         add r3=-1,in1
39         ;;
40         mov ar.lc=r3
41         mov r9=0
42
43         // XXX braindead strlen loop---this needs to be optimized
44 .Loop1:
45         EX(ld1 r8=[in0],1)
46         add r9=1,r9
47         ;;
48         cmp.eq p6,p0=r8,r0
49 (p6)    br.dpnt.few .Lexit
50         br.cloop.dptk.few .Loop1
51
52         add r9=1,in1                    // NUL not found---return N+1
53         ;;
54 .Lexit:
55         mov r8=r9
56         mov ar.lc=r16                   // restore ar.lc
57         br.ret.sptk.few rp
58 END(__strnlen_user)