]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/newlib-tumbl.git/blob - newlib/libc/machine/mbtumbl/strcpy.c
Update cond. branching to BRC/BRCI
[fpga/lx-cpu1/newlib-tumbl.git] / newlib / libc / machine / mbtumbl / strcpy.c
1 /* Copyright (c) 2009 Xilinx, Inc.  All rights reserved. 
2
3    Redistribution and use in source and binary forms, with or without
4    modification, are permitted provided that the following conditions are
5    met:
6    
7    1.  Redistributions source code must retain the above copyright notice,
8    this list of conditions and the following disclaimer. 
9    
10    2.  Redistributions in binary form must reproduce the above copyright
11    notice, this list of conditions and the following disclaimer in the
12    documentation and/or other materials provided with the distribution. 
13    
14    3.  Neither the name of Xilinx nor the names of its contributors may be
15    used to endorse or promote products derived from this software without
16    specific prior written permission. 
17    
18    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
19    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24    TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29   
30
31 FUNCTION
32         <<strcpy>>---copy string
33
34 INDEX
35         strcpy
36
37 ANSI_SYNOPSIS
38         #include <string.h>
39         char *strcpy(char *<[dst]>, const char *<[src]>);
40
41 TRAD_SYNOPSIS
42         #include <string.h>
43         char *strcpy(<[dst]>, <[src]>)
44         char *<[dst]>;
45         char *<[src]>;
46
47 DESCRIPTION
48         <<strcpy>> copies the string pointed to by <[src]>
49         (including the terminating null character) to the array
50         pointed to by <[dst]>.
51
52 RETURNS
53         This function returns the initial value of <[dst]>.
54
55 PORTABILITY
56 <<strcpy>> is ANSI C.
57
58 <<strcpy>> requires no supporting OS subroutines.
59
60 QUICKREF
61         strcpy ansi pure
62 */
63
64 #include <string.h>
65 #include <limits.h>
66
67 /*SUPPRESS 560*/
68 /*SUPPRESS 530*/
69
70 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
71 #define UNALIGNED(X, Y) \
72   (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
73
74 #if LONG_MAX == 2147483647L
75 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
76 #else
77 #if LONG_MAX == 9223372036854775807L
78 /* Nonzero if X (a long int) contains a NULL byte. */
79 #define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
80 #else
81 #error long int is not a 32bit or 64bit type.
82 #endif
83 #endif
84
85 #ifndef DETECTNULL
86 #error long int is not a 32bit or 64bit byte
87 #endif
88
89 char*
90 _DEFUN (strcpy, (dst0, src0),
91         char *dst0 _AND
92         _CONST char *src0)
93 {
94
95 #ifndef HAVE_HW_PCMP
96
97 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
98   char *s = dst0;
99
100   while (*dst0++ = *src0++)
101     ;
102
103   return s;
104 #else
105   char *dst = dst0;
106   _CONST char *src = src0;
107   long *aligned_dst;
108   _CONST long *aligned_src;
109
110   /* If SRC or DEST is unaligned, then copy bytes.  */
111   if (!UNALIGNED (src, dst))
112     {
113       aligned_dst = (long*)dst;
114       aligned_src = (long*)src;
115
116       /* SRC and DEST are both "long int" aligned, try to do "long int"
117          sized copies.  */
118       while (!DETECTNULL(*aligned_src))
119         {
120           *aligned_dst++ = *aligned_src++;
121         }
122
123       dst = (char*)aligned_dst;
124       src = (char*)aligned_src;
125     }
126
127   while (*dst++ = *src++)
128     ;
129   return dst0;
130 #endif /* not PREFER_SIZE_OVER_SPEED */
131
132 #else    
133
134   asm volatile ("                                                     \
135             or      r9, r0, r0              /* Index register */    \n\
136 check_alignment:                                                    \n\
137         andi    r3, r5, 3                                           \n\
138         andi    r4, r6, 3                                           \n\
139         brci    ne, r3, try_align_args                              \n\
140         brci    ne, r4, regular_strcpy      /* At this point we dont have a choice */      \n\
141 cpy_loop:                                   \n\
142         lw      r3, r6, r9                  \n\
143         pcmpbf  r4, r0, r3                  \n\
144         brci    ne, r4, cpy_bytes           /* If r4 != 0, then null present within string */\n\
145         sw      r3, r5, r9                  \n\
146         brid    cpy_loop                    \n\
147         addik   r9, r9, 4                   \n\
148 cpy_bytes:                                  \n\
149         lbu     r3, r6, r9                  \n\
150         sb      r3, r5, r9                  \n\
151         addik   r4, r4, -1                  \n\
152         brcid   ne, r4, cpy_bytes           \n\
153         addik   r9, r9, 1               /* delay slot */\n\
154 cpy_null:                                   \n\
155         rtsd    r15, 4                      \n\
156         or      r3, r0, r5              /* Return strcpy result */\n\
157 try_align_args:                             \n\
158         xor     r7, r4, r3                  \n\
159         brci    ne, r7, regular_strcpy  /* cannot align args */\n\
160         rsubik  r10, r3, 4              /* Number of initial bytes to align */\n\
161 align_loop:                                 \n\
162         lbu     r3, r6, r9                  \n\
163         sb      r3, r5, r9                  \n\
164         brcid   eq, r3, end_cpy         /* Break if we have seen null character */\n\
165         addik   r10, r10, -1                \n\
166         brcid   ne, r10, align_loop         \n\
167         addik   r9, r9, 1                   \n\
168         bri     cpy_loop                    \n\
169 regular_strcpy:                             \n\
170         lbu     r3, r6, r9                  \n\
171         sb      r3, r5, r9                  \n\
172         brcid   ne, r3, regular_strcpy      \n\
173         addik   r9, r9, 1                   \n\
174 end_cpy:                                    \n\
175         rtsd    r15, 4                      \n\
176         or      r3, r0, r5              /* Return strcpy result */");
177 #endif /* ! HAVE_HW_PCMP */
178 }
179
180
181
182
183