OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [s390/] [lib/] [string.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *  arch/s390/lib/string.c
3
 *    Optimized string functions
4
 *
5
 *  S390 version
6
 *    Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation
7
 *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
8
 */
9
 
10
#define IN_ARCH_STRING_C 1
11
 
12
#include <linux/types.h>
13
#include <linux/module.h>
14
 
15
/*
16
 * Helper functions to find the end of a string
17
 */
18
static inline char *__strend(const char *s)
19
{
20
        register unsigned long r0 asm("0") = 0;
21
 
22
        asm volatile ("0: srst  %0,%1\n"
23
                      "   jo    0b"
24
                      : "+d" (r0), "+a" (s) :  : "cc" );
25
        return (char *) r0;
26
}
27
 
28
static inline char *__strnend(const char *s, size_t n)
29
{
30
        register unsigned long r0 asm("0") = 0;
31
        const char *p = s + n;
32
 
33
        asm volatile ("0: srst  %0,%1\n"
34
                      "   jo    0b"
35
                      : "+d" (p), "+a" (s) : "d" (r0) : "cc" );
36
        return (char *) p;
37
}
38
 
39
/**
40
 * strlen - Find the length of a string
41
 * @s: The string to be sized
42
 *
43
 * returns the length of @s
44
 */
45
size_t strlen(const char *s)
46
{
47
        return __strend(s) - s;
48
}
49
EXPORT_SYMBOL(strlen);
50
 
51
/**
52
 * strnlen - Find the length of a length-limited string
53
 * @s: The string to be sized
54
 * @n: The maximum number of bytes to search
55
 *
56
 * returns the minimum of the length of @s and @n
57
 */
58
size_t strnlen(const char * s, size_t n)
59
{
60
        return __strnend(s, n) - s;
61
}
62
EXPORT_SYMBOL(strnlen);
63
 
64
/**
65
 * strcpy - Copy a %NUL terminated string
66
 * @dest: Where to copy the string to
67
 * @src: Where to copy the string from
68
 *
69
 * returns a pointer to @dest
70
 */
71
char *strcpy(char *dest, const char *src)
72
{
73
        register int r0 asm("0") = 0;
74
        char *ret = dest;
75
 
76
        asm volatile ("0: mvst  %0,%1\n"
77
                      "   jo    0b"
78
                      : "+&a" (dest), "+&a" (src) : "d" (r0)
79
                      : "cc", "memory" );
80
        return ret;
81
}
82
EXPORT_SYMBOL(strcpy);
83
 
84
/**
85
 * strlcpy - Copy a %NUL terminated string into a sized buffer
86
 * @dest: Where to copy the string to
87
 * @src: Where to copy the string from
88
 * @size: size of destination buffer
89
 *
90
 * Compatible with *BSD: the result is always a valid
91
 * NUL-terminated string that fits in the buffer (unless,
92
 * of course, the buffer size is zero). It does not pad
93
 * out the result like strncpy() does.
94
 */
95
size_t strlcpy(char *dest, const char *src, size_t size)
96
{
97
        size_t ret = __strend(src) - src;
98
 
99
        if (size) {
100
                size_t len = (ret >= size) ? size-1 : ret;
101
                dest[len] = '\0';
102
                __builtin_memcpy(dest, src, len);
103
        }
104
        return ret;
105
}
106
EXPORT_SYMBOL(strlcpy);
107
 
108
/**
109
 * strncpy - Copy a length-limited, %NUL-terminated string
110
 * @dest: Where to copy the string to
111
 * @src: Where to copy the string from
112
 * @n: The maximum number of bytes to copy
113
 *
114
 * The result is not %NUL-terminated if the source exceeds
115
 * @n bytes.
116
 */
117
char *strncpy(char *dest, const char *src, size_t n)
118
{
119
        size_t len = __strnend(src, n) - src;
120
        __builtin_memset(dest + len, 0, n - len);
121
        __builtin_memcpy(dest, src, len);
122
        return dest;
123
}
124
EXPORT_SYMBOL(strncpy);
125
 
126
/**
127
 * strcat - Append one %NUL-terminated string to another
128
 * @dest: The string to be appended to
129
 * @src: The string to append to it
130
 *
131
 * returns a pointer to @dest
132
 */
133
char *strcat(char *dest, const char *src)
134
{
135
        register int r0 asm("0") = 0;
136
        unsigned long dummy;
137
        char *ret = dest;
138
 
139
        asm volatile ("0: srst  %0,%1\n"
140
                      "   jo    0b\n"
141
                      "1: mvst  %0,%2\n"
142
                      "   jo    1b"
143
                      : "=&a" (dummy), "+a" (dest), "+a" (src)
144
                      : "d" (r0), "0" (0UL) : "cc", "memory" );
145
        return ret;
146
}
147
EXPORT_SYMBOL(strcat);
148
 
149
/**
150
 * strlcat - Append a length-limited, %NUL-terminated string to another
151
 * @dest: The string to be appended to
152
 * @src: The string to append to it
153
 * @n: The size of the destination buffer.
154
 */
155
size_t strlcat(char *dest, const char *src, size_t n)
156
{
157
        size_t dsize = __strend(dest) - dest;
158
        size_t len = __strend(src) - src;
159
        size_t res = dsize + len;
160
 
161
        if (dsize < n) {
162
                dest += dsize;
163
                n -= dsize;
164
                if (len >= n)
165
                        len = n - 1;
166
                dest[len] = '\0';
167
                __builtin_memcpy(dest, src, len);
168
        }
169
        return res;
170
}
171
EXPORT_SYMBOL(strlcat);
172
 
173
/**
174
 * strncat - Append a length-limited, %NUL-terminated string to another
175
 * @dest: The string to be appended to
176
 * @src: The string to append to it
177
 * @n: The maximum numbers of bytes to copy
178
 *
179
 * returns a pointer to @dest
180
 *
181
 * Note that in contrast to strncpy, strncat ensures the result is
182
 * terminated.
183
 */
184
char *strncat(char *dest, const char *src, size_t n)
185
{
186
        size_t len = __strnend(src, n) - src;
187
        char *p = __strend(dest);
188
 
189
        p[len] = '\0';
190
        __builtin_memcpy(p, src, len);
191
        return dest;
192
}
193
EXPORT_SYMBOL(strncat);
194
 
195
/**
196
 * strcmp - Compare two strings
197
 * @cs: One string
198
 * @ct: Another string
199
 *
200
 * returns   0 if @cs and @ct are equal,
201
 *         < 0 if @cs is less than @ct
202
 *         > 0 if @cs is greater than @ct
203
 */
204
int strcmp(const char *cs, const char *ct)
205
{
206
        register int r0 asm("0") = 0;
207
        int ret = 0;
208
 
209
        asm volatile ("0: clst %2,%3\n"
210
                      "   jo   0b\n"
211
                      "   je   1f\n"
212
                      "   ic   %0,0(%2)\n"
213
                      "   ic   %1,0(%3)\n"
214
                      "   sr   %0,%1\n"
215
                      "1:"
216
                      : "+d" (ret), "+d" (r0), "+a" (cs), "+a" (ct)
217
                      : : "cc" );
218
        return ret;
219
}
220
EXPORT_SYMBOL(strcmp);
221
 
222
/**
223
 * strrchr - Find the last occurrence of a character in a string
224
 * @s: The string to be searched
225
 * @c: The character to search for
226
 */
227
char * strrchr(const char * s, int c)
228
{
229
       size_t len = __strend(s) - s;
230
 
231
       if (len)
232
               do {
233
                       if (s[len] == (char) c)
234
                               return (char *) s + len;
235
               } while (--len > 0);
236
       return NULL;
237
}
238
EXPORT_SYMBOL(strrchr);
239
 
240
/**
241
 * strstr - Find the first substring in a %NUL terminated string
242
 * @s1: The string to be searched
243
 * @s2: The string to search for
244
 */
245
char * strstr(const char * s1,const char * s2)
246
{
247
        int l1, l2;
248
 
249
        l2 = __strend(s2) - s2;
250
        if (!l2)
251
                return (char *) s1;
252
        l1 = __strend(s1) - s1;
253
        while (l1-- >= l2) {
254
                register unsigned long r2 asm("2") = (unsigned long) s1;
255
                register unsigned long r3 asm("3") = (unsigned long) l2;
256
                register unsigned long r4 asm("4") = (unsigned long) s2;
257
                register unsigned long r5 asm("5") = (unsigned long) l2;
258
                int cc;
259
 
260
                asm volatile ("0: clcle %1,%3,0\n"
261
                              "   jo    0b\n"
262
                              "   ipm   %0\n"
263
                              "   srl   %0,28"
264
                              : "=&d" (cc), "+a" (r2), "+a" (r3),
265
                                "+a" (r4), "+a" (r5) : : "cc" );
266
                if (!cc)
267
                        return (char *) s1;
268
                s1++;
269
        }
270
        return NULL;
271
}
272
EXPORT_SYMBOL(strstr);
273
 
274
/**
275
 * memchr - Find a character in an area of memory.
276
 * @s: The memory area
277
 * @c: The byte to search for
278
 * @n: The size of the area.
279
 *
280
 * returns the address of the first occurrence of @c, or %NULL
281
 * if @c is not found
282
 */
283
void *memchr(const void *s, int c, size_t n)
284
{
285
        register int r0 asm("0") = (char) c;
286
        const void *ret = s + n;
287
 
288
        asm volatile ("0: srst  %0,%1\n"
289
                      "   jo    0b\n"
290
                      "   jl    1f\n"
291
                      "   la    %0,0\n"
292
                      "1:"
293
                      : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
294
        return (void *) ret;
295
}
296
EXPORT_SYMBOL(memchr);
297
 
298
/**
299
 * memcmp - Compare two areas of memory
300
 * @cs: One area of memory
301
 * @ct: Another area of memory
302
 * @count: The size of the area.
303
 */
304
int memcmp(const void *cs, const void *ct, size_t n)
305
{
306
        register unsigned long r2 asm("2") = (unsigned long) cs;
307
        register unsigned long r3 asm("3") = (unsigned long) n;
308
        register unsigned long r4 asm("4") = (unsigned long) ct;
309
        register unsigned long r5 asm("5") = (unsigned long) n;
310
        int ret;
311
 
312
        asm volatile ("0: clcle %1,%3,0\n"
313
                      "   jo    0b\n"
314
                      "   ipm   %0\n"
315
                      "   srl   %0,28"
316
                      : "=&d" (ret), "+a" (r2), "+a" (r3), "+a" (r4), "+a" (r5)
317
                      : : "cc" );
318
        if (ret)
319
                ret = *(char *) r2 - *(char *) r4;
320
        return ret;
321
}
322
EXPORT_SYMBOL(memcmp);
323
 
324
/**
325
 * memscan - Find a character in an area of memory.
326
 * @s: The memory area
327
 * @c: The byte to search for
328
 * @n: The size of the area.
329
 *
330
 * returns the address of the first occurrence of @c, or 1 byte past
331
 * the area if @c is not found
332
 */
333
void *memscan(void *s, int c, size_t n)
334
{
335
        register int r0 asm("0") = (char) c;
336
        const void *ret = s + n;
337
 
338
        asm volatile ("0: srst  %0,%1\n"
339
                      "   jo    0b\n"
340
                      : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
341
        return (void *) ret;
342
}
343
EXPORT_SYMBOL(memscan);
344
 
345
/**
346
 * memcpy - Copy one area of memory to another
347
 * @dest: Where to copy to
348
 * @src: Where to copy from
349
 * @n: The size of the area.
350
 *
351
 * returns a pointer to @dest
352
 */
353
void *memcpy(void *dest, const void *src, size_t n)
354
{
355
        return __builtin_memcpy(dest, src, n);
356
}
357
EXPORT_SYMBOL(memcpy);
358
 
359
/**
360
 * memset - Fill a region of memory with the given value
361
 * @s: Pointer to the start of the area.
362
 * @c: The byte to fill the area with
363
 * @n: The size of the area.
364
 *
365
 * returns a pointer to @s
366
 */
367
void *memset(void *s, int c, size_t n)
368
{
369
        char *xs;
370
 
371
        if (c == 0)
372
                return __builtin_memset(s, 0, n);
373
 
374
        xs = (char *) s;
375
        if (n > 0)
376
                do {
377
                        *xs++ = c;
378
                } while (--n > 0);
379
        return s;
380
}
381
EXPORT_SYMBOL(memset);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.