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_STRNCPY 38 static inline char *strncpy(char *__dest, const char *__src, size_t __n) 39 { 40 register char *__xdest = __dest; 41 unsigned long __dummy; 42 43 if (__n == 0) 44 return __xdest; 45 46 __asm__ __volatile__( 47 "1:\n\t" 48 "l8ui %2, %1, 0\n\t" 49 "s8i %2, %0, 0\n\t" 50 "addi %1, %1, 1\n\t" 51 "addi %0, %0, 1\n\t" 52 "beqz %2, 2f\n\t" 53 "bne %1, %5, 1b\n" 54 "2:" 55 : "=r" (__dest), "=r" (__src), "=&r" (__dummy) 56 : "0" (__dest), "1" (__src), "r" ((uintptr_t)__src+__n) 57 : "memory"); 58 59 return __xdest; 60 } 61 62 #define __HAVE_ARCH_STRCMP 63 static inline int strcmp(const char *__cs, const char *__ct) 64 { 65 register int __res; 66 unsigned long __dummy; 67 68 __asm__ __volatile__( 69 "1:\n\t" 70 "l8ui %3, %1, 0\n\t" 71 "addi %1, %1, 1\n\t" 72 "l8ui %2, %0, 0\n\t" 73 "addi %0, %0, 1\n\t" 74 "beqz %2, 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)); 80 81 return __res; 82 } 83 84 #define __HAVE_ARCH_STRNCMP 85 static inline int strncmp(const char *__cs, const char *__ct, size_t __n) 86 { 87 register int __res; 88 unsigned long __dummy; 89 90 __asm__ __volatile__( 91 "mov %2, %3\n" 92 "1:\n\t" 93 "beq %0, %6, 2f\n\t" 94 "l8ui %3, %1, 0\n\t" 95 "addi %1, %1, 1\n\t" 96 "l8ui %2, %0, 0\n\t" 97 "addi %0, %0, 1\n\t" 98 "beqz %2, 2f\n\t" 99 "beqz %3, 2f\n\t" 100 "beq %2, %3, 1b\n" 101 "2:\n\t" 102 "sub %2, %2, %3" 103 : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy) 104 : "0" (__cs), "1" (__ct), "r" ((uintptr_t)__cs+__n)); 105 106 return __res; 107 } 108 109 #define __HAVE_ARCH_MEMSET 110 extern void *memset(void *__s, int __c, size_t __count); 111 extern void *__memset(void *__s, int __c, size_t __count); 112 113 #define __HAVE_ARCH_MEMCPY 114 extern void *memcpy(void *__to, __const__ void *__from, size_t __n); 115 extern void *__memcpy(void *__to, __const__ void *__from, size_t __n); 116 117 #define __HAVE_ARCH_MEMMOVE 118 extern void *memmove(void *__dest, __const__ void *__src, size_t __n); 119 extern void *__memmove(void *__dest, __const__ void *__src, size_t __n); 120 121 #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) 122 123 /* 124 * For files that are not instrumented (e.g. mm/slub.c) we 125 * should use not instrumented version of mem* functions. 126 */ 127 128 #define memcpy(dst, src, len) __memcpy(dst, src, len) 129 #define memmove(dst, src, len) __memmove(dst, src, len) 130 #define memset(s, c, n) __memset(s, c, n) 131 132 #ifndef __NO_FORTIFY 133 #define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */ 134 #endif 135 #endif 136 137 #endif /* _XTENSA_STRING_H */ 138