1 /* 2 * include/asm-xtensa/string.h 3 * 4 * These trivial string functions are considered part of the public domain. 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 * 10 * Copyright (C) 2001 - 2005 Tensilica Inc. 11 */ 12 13 /* We should optimize these. See arch/xtensa/lib/strncpy_user.S */ 14 15 #ifndef _XTENSA_STRING_H 16 #define _XTENSA_STRING_H 17 18 #define __HAVE_ARCH_STRCPY 19 static inline char *strcpy(char *__dest, const char *__src) 20 { 21 register char *__xdest = __dest; 22 unsigned long __dummy; 23 24 __asm__ __volatile__("1:\n\t" 25 "l8ui %2, %1, 0\n\t" 26 "s8i %2, %0, 0\n\t" 27 "addi %1, %1, 1\n\t" 28 "addi %0, %0, 1\n\t" 29 "bnez %2, 1b\n\t" 30 : "=r" (__dest), "=r" (__src), "=&r" (__dummy) 31 : "0" (__dest), "1" (__src) 32 : "memory"); 33 34 return __xdest; 35 } 36 37 #define __HAVE_ARCH_STRCMP 38 static inline int strcmp(const char *__cs, const char *__ct) 39 { 40 register int __res; 41 unsigned long __dummy; 42 43 __asm__ __volatile__( 44 "1:\n\t" 45 "l8ui %3, %1, 0\n\t" 46 "addi %1, %1, 1\n\t" 47 "l8ui %2, %0, 0\n\t" 48 "addi %0, %0, 1\n\t" 49 "beqz %2, 2f\n\t" 50 "beq %2, %3, 1b\n" 51 "2:\n\t" 52 "sub %2, %2, %3" 53 : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy) 54 : "0" (__cs), "1" (__ct)); 55 56 return __res; 57 } 58 59 #define __HAVE_ARCH_STRNCMP 60 static inline int strncmp(const char *__cs, const char *__ct, size_t __n) 61 { 62 register int __res; 63 unsigned long __dummy; 64 65 __asm__ __volatile__( 66 "mov %2, %3\n" 67 "1:\n\t" 68 "beq %0, %6, 2f\n\t" 69 "l8ui %3, %1, 0\n\t" 70 "addi %1, %1, 1\n\t" 71 "l8ui %2, %0, 0\n\t" 72 "addi %0, %0, 1\n\t" 73 "beqz %2, 2f\n\t" 74 "beqz %3, 2f\n\t" 75 "beq %2, %3, 1b\n" 76 "2:\n\t" 77 "sub %2, %2, %3" 78 : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy) 79 : "0" (__cs), "1" (__ct), "r" ((uintptr_t)__cs+__n)); 80 81 return __res; 82 } 83 84 #define __HAVE_ARCH_MEMSET 85 extern void *memset(void *__s, int __c, size_t __count); 86 extern void *__memset(void *__s, int __c, size_t __count); 87 88 #define __HAVE_ARCH_MEMCPY 89 extern void *memcpy(void *__to, __const__ void *__from, size_t __n); 90 extern void *__memcpy(void *__to, __const__ void *__from, size_t __n); 91 92 #define __HAVE_ARCH_MEMMOVE 93 extern void *memmove(void *__dest, __const__ void *__src, size_t __n); 94 extern void *__memmove(void *__dest, __const__ void *__src, size_t __n); 95 96 #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) 97 98 /* 99 * For files that are not instrumented (e.g. mm/slub.c) we 100 * should use not instrumented version of mem* functions. 101 */ 102 103 #define memcpy(dst, src, len) __memcpy(dst, src, len) 104 #define memmove(dst, src, len) __memmove(dst, src, len) 105 #define memset(s, c, n) __memset(s, c, n) 106 107 #ifndef __NO_FORTIFY 108 #define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */ 109 #endif 110 #endif 111 112 #endif /* _XTENSA_STRING_H */ 113