1367b8112SChris Zankel /*
2367b8112SChris Zankel * include/asm-xtensa/string.h
3367b8112SChris Zankel *
4367b8112SChris Zankel * These trivial string functions are considered part of the public domain.
5367b8112SChris Zankel *
6367b8112SChris Zankel * This file is subject to the terms and conditions of the GNU General Public
7367b8112SChris Zankel * License. See the file "COPYING" in the main directory of this archive
8367b8112SChris Zankel * for more details.
9367b8112SChris Zankel *
10367b8112SChris Zankel * Copyright (C) 2001 - 2005 Tensilica Inc.
11367b8112SChris Zankel */
12367b8112SChris Zankel
13367b8112SChris Zankel /* We should optimize these. See arch/xtensa/lib/strncpy_user.S */
14367b8112SChris Zankel
15367b8112SChris Zankel #ifndef _XTENSA_STRING_H
16367b8112SChris Zankel #define _XTENSA_STRING_H
17367b8112SChris Zankel
18367b8112SChris Zankel #define __HAVE_ARCH_STRCPY
strcpy(char * __dest,const char * __src)19367b8112SChris Zankel static inline char *strcpy(char *__dest, const char *__src)
20367b8112SChris Zankel {
21367b8112SChris Zankel register char *__xdest = __dest;
22367b8112SChris Zankel unsigned long __dummy;
23367b8112SChris Zankel
24367b8112SChris Zankel __asm__ __volatile__("1:\n\t"
25367b8112SChris Zankel "l8ui %2, %1, 0\n\t"
26367b8112SChris Zankel "s8i %2, %0, 0\n\t"
27367b8112SChris Zankel "addi %1, %1, 1\n\t"
28367b8112SChris Zankel "addi %0, %0, 1\n\t"
29367b8112SChris Zankel "bnez %2, 1b\n\t"
30367b8112SChris Zankel : "=r" (__dest), "=r" (__src), "=&r" (__dummy)
31367b8112SChris Zankel : "0" (__dest), "1" (__src)
32367b8112SChris Zankel : "memory");
33367b8112SChris Zankel
34367b8112SChris Zankel return __xdest;
35367b8112SChris Zankel }
36367b8112SChris Zankel
37367b8112SChris Zankel #define __HAVE_ARCH_STRNCPY
strncpy(char * __dest,const char * __src,size_t __n)38367b8112SChris Zankel static inline char *strncpy(char *__dest, const char *__src, size_t __n)
39367b8112SChris Zankel {
40367b8112SChris Zankel register char *__xdest = __dest;
41367b8112SChris Zankel unsigned long __dummy;
42367b8112SChris Zankel
43367b8112SChris Zankel if (__n == 0)
44367b8112SChris Zankel return __xdest;
45367b8112SChris Zankel
46367b8112SChris Zankel __asm__ __volatile__(
47367b8112SChris Zankel "1:\n\t"
48367b8112SChris Zankel "l8ui %2, %1, 0\n\t"
49367b8112SChris Zankel "s8i %2, %0, 0\n\t"
50367b8112SChris Zankel "addi %1, %1, 1\n\t"
51367b8112SChris Zankel "addi %0, %0, 1\n\t"
52367b8112SChris Zankel "beqz %2, 2f\n\t"
53367b8112SChris Zankel "bne %1, %5, 1b\n"
54367b8112SChris Zankel "2:"
55367b8112SChris Zankel : "=r" (__dest), "=r" (__src), "=&r" (__dummy)
56*32bb954dSArnd Bergmann : "0" (__dest), "1" (__src), "r" ((uintptr_t)__src+__n)
57367b8112SChris Zankel : "memory");
58367b8112SChris Zankel
59367b8112SChris Zankel return __xdest;
60367b8112SChris Zankel }
61367b8112SChris Zankel
62367b8112SChris Zankel #define __HAVE_ARCH_STRCMP
strcmp(const char * __cs,const char * __ct)63367b8112SChris Zankel static inline int strcmp(const char *__cs, const char *__ct)
64367b8112SChris Zankel {
65367b8112SChris Zankel register int __res;
66367b8112SChris Zankel unsigned long __dummy;
67367b8112SChris Zankel
68367b8112SChris Zankel __asm__ __volatile__(
69367b8112SChris Zankel "1:\n\t"
70367b8112SChris Zankel "l8ui %3, %1, 0\n\t"
71367b8112SChris Zankel "addi %1, %1, 1\n\t"
72367b8112SChris Zankel "l8ui %2, %0, 0\n\t"
73367b8112SChris Zankel "addi %0, %0, 1\n\t"
74367b8112SChris Zankel "beqz %2, 2f\n\t"
75367b8112SChris Zankel "beq %2, %3, 1b\n"
76367b8112SChris Zankel "2:\n\t"
77c5a285bbSMax Filippov "sub %2, %2, %3"
78367b8112SChris Zankel : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy)
79367b8112SChris Zankel : "0" (__cs), "1" (__ct));
80367b8112SChris Zankel
81367b8112SChris Zankel return __res;
82367b8112SChris Zankel }
83367b8112SChris Zankel
84367b8112SChris Zankel #define __HAVE_ARCH_STRNCMP
strncmp(const char * __cs,const char * __ct,size_t __n)85367b8112SChris Zankel static inline int strncmp(const char *__cs, const char *__ct, size_t __n)
86367b8112SChris Zankel {
87367b8112SChris Zankel register int __res;
88367b8112SChris Zankel unsigned long __dummy;
89367b8112SChris Zankel
90367b8112SChris Zankel __asm__ __volatile__(
91367b8112SChris Zankel "mov %2, %3\n"
92367b8112SChris Zankel "1:\n\t"
93367b8112SChris Zankel "beq %0, %6, 2f\n\t"
94367b8112SChris Zankel "l8ui %3, %1, 0\n\t"
95367b8112SChris Zankel "addi %1, %1, 1\n\t"
96367b8112SChris Zankel "l8ui %2, %0, 0\n\t"
97367b8112SChris Zankel "addi %0, %0, 1\n\t"
98367b8112SChris Zankel "beqz %2, 2f\n\t"
99367b8112SChris Zankel "beqz %3, 2f\n\t"
100367b8112SChris Zankel "beq %2, %3, 1b\n"
101367b8112SChris Zankel "2:\n\t"
102c5a285bbSMax Filippov "sub %2, %2, %3"
103367b8112SChris Zankel : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy)
104*32bb954dSArnd Bergmann : "0" (__cs), "1" (__ct), "r" ((uintptr_t)__cs+__n));
105367b8112SChris Zankel
106367b8112SChris Zankel return __res;
107367b8112SChris Zankel }
108367b8112SChris Zankel
109367b8112SChris Zankel #define __HAVE_ARCH_MEMSET
110367b8112SChris Zankel extern void *memset(void *__s, int __c, size_t __count);
111c633544aSMax Filippov extern void *__memset(void *__s, int __c, size_t __count);
112367b8112SChris Zankel
113367b8112SChris Zankel #define __HAVE_ARCH_MEMCPY
114367b8112SChris Zankel extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
115c633544aSMax Filippov extern void *__memcpy(void *__to, __const__ void *__from, size_t __n);
116367b8112SChris Zankel
117367b8112SChris Zankel #define __HAVE_ARCH_MEMMOVE
118367b8112SChris Zankel extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
119c633544aSMax Filippov extern void *__memmove(void *__dest, __const__ void *__src, size_t __n);
120367b8112SChris Zankel
121c633544aSMax Filippov #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
122c633544aSMax Filippov
123c633544aSMax Filippov /*
124c633544aSMax Filippov * For files that are not instrumented (e.g. mm/slub.c) we
125c633544aSMax Filippov * should use not instrumented version of mem* functions.
126c633544aSMax Filippov */
127c633544aSMax Filippov
128c633544aSMax Filippov #define memcpy(dst, src, len) __memcpy(dst, src, len)
129c633544aSMax Filippov #define memmove(dst, src, len) __memmove(dst, src, len)
130c633544aSMax Filippov #define memset(s, c, n) __memset(s, c, n)
131c633544aSMax Filippov
132c633544aSMax Filippov #ifndef __NO_FORTIFY
133c633544aSMax Filippov #define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
134c633544aSMax Filippov #endif
135c633544aSMax Filippov #endif
136c633544aSMax Filippov
137367b8112SChris Zankel #endif /* _XTENSA_STRING_H */
138