IA64 strncpy implementation.
[kopensolaris-gnu/glibc.git] / sysdeps / ia64 / strncpy.S
1 /*
2  * Optimized version of the standard strncpy() function
3  *
4  * Contributed by Dan Pop <Dan.Pop@cern.ch>
5  *
6  * Return: dest
7  *
8  * Inputs:
9  *      in0:    dest
10  *      in1:    src
11  *      in2:    char count
12  *
13  * If n >= 24, do a memcpy(dest, src, min(strlen(src)+1, n)), followed by a
14  * memset(dest + strlen(src), 0, n - strlen(src) - 1) if necessary.
15  *
16  * Otherwise, copy characters one by one and fill with nulls if necessary.
17  *
18  */
19
20 #include <sysdep.h>
21 #undef ret
22
23 #define saved_pfs       loc0
24 #define saved_b0        loc1
25 #define saved_pr        loc2
26 #define saved_lc        loc3
27 #define tmp             loc4
28 #define len             loc5
29
30 #define dest            in0
31 #define src             in1
32 #define n               in2
33
34 #define rc              ret0
35
36 ENTRY(strncpy)
37         alloc   saved_pfs = ar.pfs, 3, 6, 3, 0
38         mov     saved_b0 = b0
39         mov     saved_pr = pr
40         mov     saved_lc = ar.lc
41         cmp.gtu p6, p0 = 24, n
42 (p6)    br.cond.spnt .cpyfew
43         mov     out0 = src
44         mov     tmp = gp ;;
45         br.call.sptk.many b0 = strlen# ;;       // rc = strlen(src);
46         add     len = 1, rc                     // include the null in len
47         mov     gp = tmp
48         mov     out0 = dest ;;
49         cmp.ltu p4, p5 = len, n
50         mov     out1 = src ;;
51 (p4)    mov     out2 = len
52 (p5)    mov     out2 = n
53         br.call.sptk.many b0 = memcpy# ;;       // memcpy(dest, src, min(len, n));
54         mov     gp = tmp
55 (p4)    add     out0 = dest, len
56 (p4)    mov     out1 = r0
57 (p4)    sub     out2 = n, len
58 (p4)    br.call.sptk.many b0 = memset# ;;       // fill the rest with nulls
59 (p4)    mov     gp = tmp
60         mov     rc = dest
61         mov     b0 = saved_b0
62         mov     ar.pfs = saved_pfs
63         mov     pr = saved_pr, -1
64         br.ret.sptk.many b0
65 .cpyfew:
66         mov     rc = dest
67         cmp.eq  p6, p0 = n, r0          
68         adds    n = -1, n
69 (p6)    br.cond.spnt .restore_and_exit ;;       // do nothing if n == 0
70         mov     ar.lc = n
71         cmp.eq  p6, p0 = r0, r0 ;;              // set p6
72 .loop:
73 (p6)    ld1     tmp = [src],1 
74         ;;
75         st1     [dest] = tmp, 1
76 (p6)    cmp.ne  p6, p0 = tmp, r0        // clear p6 after encountering the
77         br.cloop.dptk .loop ;;          // null character in src
78 .restore_and_exit:
79         mov     ar.lc = saved_lc
80         mov     ar.pfs = saved_pfs
81         br.ret.sptk.many b0
82 END(strncpy)