source: trunk/libs/newlib/src/newlib/libc/machine/microblaze/strcpy.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 6.0 KB
Line 
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
31FUNCTION
32        <<strcpy>>---copy string
33
34INDEX
35        strcpy
36
37SYNOPSIS
38        #include <string.h>
39        char *strcpy(char *restrict <[dst]>, const char *restrict <[src]>);
40
41DESCRIPTION
42        <<strcpy>> copies the string pointed to by <[src]>
43        (including the terminating null character) to the array
44        pointed to by <[dst]>.
45
46RETURNS
47        This function returns the initial value of <[dst]>.
48
49PORTABILITY
50<<strcpy>> is ANSI C.
51
52<<strcpy>> requires no supporting OS subroutines.
53
54QUICKREF
55        strcpy ansi pure
56*/
57
58#include <string.h>
59#include <limits.h>
60
61/*SUPPRESS 560*/
62/*SUPPRESS 530*/
63
64/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
65#define UNALIGNED(X, Y) \
66  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
67
68#if LONG_MAX == 2147483647L
69#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
70#else
71#if LONG_MAX == 9223372036854775807L
72/* Nonzero if X (a long int) contains a NULL byte. */
73#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
74#else
75#error long int is not a 32bit or 64bit type.
76#endif
77#endif
78
79#ifndef DETECTNULL
80#error long int is not a 32bit or 64bit byte
81#endif
82
83char*
84strcpy (char *__restrict dst0,
85        const char *__restrict src0)
86{
87
88#ifndef HAVE_HW_PCMP
89
90#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
91  char *s = dst0;
92
93  while (*dst0++ = *src0++)
94    ;
95
96  return s;
97#else
98  char *dst = dst0;
99  const char *src = src0;
100  long *aligned_dst;
101  const long *aligned_src;
102
103  /* If SRC or DEST is unaligned, then copy bytes.  */
104  if (!UNALIGNED (src, dst))
105    {
106      aligned_dst = (long*)dst;
107      aligned_src = (long*)src;
108
109      /* SRC and DEST are both "long int" aligned, try to do "long int"
110         sized copies.  */
111      while (!DETECTNULL(*aligned_src))
112        {
113          *aligned_dst++ = *aligned_src++;
114        }
115
116      dst = (char*)aligned_dst;
117      src = (char*)aligned_src;
118    }
119
120  while (*dst++ = *src++)
121    ;
122  return dst0;
123#endif /* not PREFER_SIZE_OVER_SPEED */
124
125#else   
126
127#include "mb_endian.h"
128
129  asm volatile ("                                                   \n\
130        or      r9, r0, r0              /* Index register */        \n\
131check_alignment:                                                    \n\
132        andi    r3, r5, 3                                           \n\
133        andi    r4, r6, 3                                           \n\
134        bnei    r3, try_align_args                                  \n\
135        bnei    r4, regular_strcpy      /* At this point we dont have a choice */       \n\
136cpy_loop:                                   \n"
137        LOAD4BYTES("r3", "r6", "r9")
138"                                           \n\
139        pcmpbf  r4, r0, r3                  \n\
140        bnei    r4, cpy_bytes           /* If r4 != 0, then null present within string */\n"
141        STORE4BYTES("r3", "r5", "r9")
142"                                           \n\
143        brid    cpy_loop                    \n\
144        addik   r9, r9, 4                   \n\
145cpy_bytes:                                  \n\
146        lbu     r3, r6, r9                  \n\
147        sb      r3, r5, r9                  \n\
148        addik   r4, r4, -1                  \n\
149        bneid   r4, cpy_bytes               \n\
150        addik   r9, r9, 1               /* delay slot */\n\
151cpy_null:                                   \n\
152        rtsd    r15, 8                      \n\
153        or      r3, r0, r5              /* Return strcpy result */\n\
154try_align_args:                             \n\
155        xor     r7, r4, r3                  \n\
156        bnei    r7, regular_strcpy      /* cannot align args */\n\
157        rsubik  r10, r3, 4              /* Number of initial bytes to align */\n\
158align_loop:                                 \n\
159        lbu     r3, r6, r9                  \n\
160        sb      r3, r5, r9                  \n\
161        beqid   r3, end_cpy             /* Break if we have seen null character */\n\
162        addik   r10, r10, -1                \n\
163        bneid   r10, align_loop             \n\
164        addik   r9, r9, 1                   \n\
165        bri     cpy_loop                    \n\
166regular_strcpy:                             \n\
167        lbu     r3, r6, r9                  \n\
168        sb      r3, r5, r9                  \n\
169        bneid   r3, regular_strcpy          \n\
170        addik   r9, r9, 1                   \n\
171end_cpy:                                    \n\
172        rtsd    r15, 8                      \n\
173        or      r3, r0, r5              /* Return strcpy result */");
174#endif /* ! HAVE_HW_PCMP */
175}
176
177
178
179
180
Note: See TracBrowser for help on using the repository browser.