162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * include/asm-xtensa/string.h
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * These trivial string functions are considered part of the public domain.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
762306a36Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
862306a36Sopenharmony_ci * for more details.
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * Copyright (C) 2001 - 2005 Tensilica Inc.
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci/* We should optimize these. See arch/xtensa/lib/strncpy_user.S */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#ifndef _XTENSA_STRING_H
1662306a36Sopenharmony_ci#define _XTENSA_STRING_H
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define __HAVE_ARCH_STRCPY
1962306a36Sopenharmony_cistatic inline char *strcpy(char *__dest, const char *__src)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	register char *__xdest = __dest;
2262306a36Sopenharmony_ci	unsigned long __dummy;
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	__asm__ __volatile__("1:\n\t"
2562306a36Sopenharmony_ci		"l8ui	%2, %1, 0\n\t"
2662306a36Sopenharmony_ci		"s8i	%2, %0, 0\n\t"
2762306a36Sopenharmony_ci		"addi	%1, %1, 1\n\t"
2862306a36Sopenharmony_ci		"addi	%0, %0, 1\n\t"
2962306a36Sopenharmony_ci		"bnez	%2, 1b\n\t"
3062306a36Sopenharmony_ci		: "=r" (__dest), "=r" (__src), "=&r" (__dummy)
3162306a36Sopenharmony_ci		: "0" (__dest), "1" (__src)
3262306a36Sopenharmony_ci		: "memory");
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	return __xdest;
3562306a36Sopenharmony_ci}
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define __HAVE_ARCH_STRNCPY
3862306a36Sopenharmony_cistatic inline char *strncpy(char *__dest, const char *__src, size_t __n)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	register char *__xdest = __dest;
4162306a36Sopenharmony_ci	unsigned long __dummy;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	if (__n == 0)
4462306a36Sopenharmony_ci		return __xdest;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	__asm__ __volatile__(
4762306a36Sopenharmony_ci		"1:\n\t"
4862306a36Sopenharmony_ci		"l8ui	%2, %1, 0\n\t"
4962306a36Sopenharmony_ci		"s8i	%2, %0, 0\n\t"
5062306a36Sopenharmony_ci		"addi	%1, %1, 1\n\t"
5162306a36Sopenharmony_ci		"addi	%0, %0, 1\n\t"
5262306a36Sopenharmony_ci		"beqz	%2, 2f\n\t"
5362306a36Sopenharmony_ci		"bne	%1, %5, 1b\n"
5462306a36Sopenharmony_ci		"2:"
5562306a36Sopenharmony_ci		: "=r" (__dest), "=r" (__src), "=&r" (__dummy)
5662306a36Sopenharmony_ci		: "0" (__dest), "1" (__src), "r" ((uintptr_t)__src+__n)
5762306a36Sopenharmony_ci		: "memory");
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	return __xdest;
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#define __HAVE_ARCH_STRCMP
6362306a36Sopenharmony_cistatic inline int strcmp(const char *__cs, const char *__ct)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	register int __res;
6662306a36Sopenharmony_ci	unsigned long __dummy;
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	__asm__ __volatile__(
6962306a36Sopenharmony_ci		"1:\n\t"
7062306a36Sopenharmony_ci		"l8ui	%3, %1, 0\n\t"
7162306a36Sopenharmony_ci		"addi	%1, %1, 1\n\t"
7262306a36Sopenharmony_ci		"l8ui	%2, %0, 0\n\t"
7362306a36Sopenharmony_ci		"addi	%0, %0, 1\n\t"
7462306a36Sopenharmony_ci		"beqz	%2, 2f\n\t"
7562306a36Sopenharmony_ci		"beq	%2, %3, 1b\n"
7662306a36Sopenharmony_ci		"2:\n\t"
7762306a36Sopenharmony_ci		"sub	%2, %2, %3"
7862306a36Sopenharmony_ci		: "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy)
7962306a36Sopenharmony_ci		: "0" (__cs), "1" (__ct));
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	return __res;
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci#define __HAVE_ARCH_STRNCMP
8562306a36Sopenharmony_cistatic inline int strncmp(const char *__cs, const char *__ct, size_t __n)
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	register int __res;
8862306a36Sopenharmony_ci	unsigned long __dummy;
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	__asm__ __volatile__(
9162306a36Sopenharmony_ci		"mov	%2, %3\n"
9262306a36Sopenharmony_ci		"1:\n\t"
9362306a36Sopenharmony_ci		"beq	%0, %6, 2f\n\t"
9462306a36Sopenharmony_ci		"l8ui	%3, %1, 0\n\t"
9562306a36Sopenharmony_ci		"addi	%1, %1, 1\n\t"
9662306a36Sopenharmony_ci		"l8ui	%2, %0, 0\n\t"
9762306a36Sopenharmony_ci		"addi	%0, %0, 1\n\t"
9862306a36Sopenharmony_ci		"beqz	%2, 2f\n\t"
9962306a36Sopenharmony_ci		"beqz	%3, 2f\n\t"
10062306a36Sopenharmony_ci		"beq	%2, %3, 1b\n"
10162306a36Sopenharmony_ci		"2:\n\t"
10262306a36Sopenharmony_ci		"sub	%2, %2, %3"
10362306a36Sopenharmony_ci		: "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy)
10462306a36Sopenharmony_ci		: "0" (__cs), "1" (__ct), "r" ((uintptr_t)__cs+__n));
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	return __res;
10762306a36Sopenharmony_ci}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci#define __HAVE_ARCH_MEMSET
11062306a36Sopenharmony_ciextern void *memset(void *__s, int __c, size_t __count);
11162306a36Sopenharmony_ciextern void *__memset(void *__s, int __c, size_t __count);
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci#define __HAVE_ARCH_MEMCPY
11462306a36Sopenharmony_ciextern void *memcpy(void *__to, __const__ void *__from, size_t __n);
11562306a36Sopenharmony_ciextern void *__memcpy(void *__to, __const__ void *__from, size_t __n);
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci#define __HAVE_ARCH_MEMMOVE
11862306a36Sopenharmony_ciextern void *memmove(void *__dest, __const__ void *__src, size_t __n);
11962306a36Sopenharmony_ciextern void *__memmove(void *__dest, __const__ void *__src, size_t __n);
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/*
12462306a36Sopenharmony_ci * For files that are not instrumented (e.g. mm/slub.c) we
12562306a36Sopenharmony_ci * should use not instrumented version of mem* functions.
12662306a36Sopenharmony_ci */
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci#define memcpy(dst, src, len) __memcpy(dst, src, len)
12962306a36Sopenharmony_ci#define memmove(dst, src, len) __memmove(dst, src, len)
13062306a36Sopenharmony_ci#define memset(s, c, n) __memset(s, c, n)
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci#ifndef __NO_FORTIFY
13362306a36Sopenharmony_ci#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
13462306a36Sopenharmony_ci#endif
13562306a36Sopenharmony_ci#endif
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci#endif	/* _XTENSA_STRING_H */
138