Update to LGPL v2.1.
[kopensolaris-gnu/glibc.git] / sysdeps / ia64 / strncpy.S
1 /* Optimized version of the standard strncpy() function.
2    This file is part of the GNU C Library.
3    Copyright (C) 2000, 2001 Free Software Foundation, Inc.
4    Contributed by Dan Pop <Dan.Pop@cern.ch>.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 /* Return: dest
22
23    Inputs:
24         in0:    dest
25         in1:    src
26         in2:    char count
27
28    If n >= 24, do a memcpy(dest, src, min(strlen(src)+1, n)), followed by a
29    memset(dest + strlen(src), 0, n - strlen(src) - 1) if necessary.
30
31    Otherwise, copy characters one by one and fill with nulls if necessary.  */
32
33 #include <sysdep.h>
34 #undef ret
35
36 #define saved_b0        loc0
37 #define saved_pfs       loc1
38 #define saved_pr        loc2
39 #define saved_lc        loc3
40 #define tmp             loc4
41 #define len             loc5
42
43 #define dest            in0
44 #define src             in1
45 #define n               in2
46
47 #define rc              ret0
48
49 ENTRY(strncpy)
50         .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3)
51         alloc   saved_pfs = ar.pfs, 3, 6, 3, 0
52         mov     saved_b0 = b0
53         .save pr, saved_pr
54         mov     saved_pr = pr
55         .save ar.lc, saved_lc
56         mov     saved_lc = ar.lc
57         .body
58         cmp.gtu p6, p0 = 24, n
59 (p6)    br.cond.spnt .cpyfew
60         mov     out0 = src
61         mov     tmp = gp ;;
62         br.call.sptk.many b0 = strlen# ;;       // rc = strlen(src);
63         add     len = 1, rc                     // include the null in len
64         mov     gp = tmp
65         mov     out0 = dest ;;
66         cmp.ltu p4, p5 = len, n
67         mov     out1 = src ;;
68 (p4)    mov     out2 = len
69 (p5)    mov     out2 = n
70         br.call.sptk.many b0 = memcpy# ;;       // memcpy(dest, src, min(len, n));
71         mov     gp = tmp
72 (p4)    add     out0 = dest, len
73 (p4)    mov     out1 = r0
74 (p4)    sub     out2 = n, len
75 (p4)    br.call.sptk.many b0 = memset# ;;       // fill the rest with nulls
76 (p4)    mov     gp = tmp
77         mov     rc = dest
78         mov     b0 = saved_b0
79         mov     ar.pfs = saved_pfs
80         mov     pr = saved_pr, -1
81         br.ret.sptk.many b0
82 .cpyfew:
83         mov     rc = dest
84         cmp.eq  p6, p0 = n, r0          
85         adds    n = -1, n
86 (p6)    br.cond.spnt .restore_and_exit ;;       // do nothing if n == 0
87         mov     ar.lc = n
88         cmp.eq  p6, p0 = r0, r0 ;;              // set p6
89 .loop:
90 (p6)    ld1     tmp = [src],1 
91         ;;
92         st1     [dest] = tmp, 1
93 (p6)    cmp.ne  p6, p0 = tmp, r0        // clear p6 after encountering the
94         br.cloop.dptk .loop ;;          // null character in src
95 .restore_and_exit:
96         mov     ar.lc = saved_lc
97         mov     ar.pfs = saved_pfs
98         br.ret.sptk.many b0
99 END(strncpy)