xref: /openbmc/linux/arch/xtensa/include/asm/string.h (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
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