^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef __ALPHA_STRING_H__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __ALPHA_STRING_H__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #ifdef __KERNEL__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * GCC of any recent vintage doesn't do stupid things with bcopy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * EGCS 1.1 knows all about expanding memcpy inline, others don't.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Similarly for a memset with data = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define __HAVE_ARCH_MEMCPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) extern void * memcpy(void *, const void *, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define __HAVE_ARCH_MEMMOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) extern void * memmove(void *, const void *, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* For backward compatibility with modules. Unused otherwise. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) extern void * __memcpy(void *, const void *, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define memcpy __builtin_memcpy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define __HAVE_ARCH_MEMSET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) extern void * __constant_c_memset(void *, unsigned long, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) extern void * ___memset(void *, int, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) extern void * __memset(void *, int, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) extern void * memset(void *, int, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* For gcc 3.x, we cannot have the inline function named "memset" because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) the __builtin_memset will attempt to resolve to the inline as well,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) leading to a "sorry" about unimplemented recursive inlining. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) extern inline void *__memset(void *s, int c, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (__builtin_constant_p(c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (__builtin_constant_p(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return __builtin_memset(s, c, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) unsigned long c8 = (c & 0xff) * 0x0101010101010101UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return __constant_c_memset(s, c8, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return ___memset(s, c, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define memset __memset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define __HAVE_ARCH_STRCPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) extern char * strcpy(char *,const char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define __HAVE_ARCH_STRNCPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) extern char * strncpy(char *, const char *, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define __HAVE_ARCH_STRCAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) extern char * strcat(char *, const char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define __HAVE_ARCH_STRNCAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) extern char * strncat(char *, const char *, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define __HAVE_ARCH_STRCHR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) extern char * strchr(const char *,int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define __HAVE_ARCH_STRRCHR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) extern char * strrchr(const char *,int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define __HAVE_ARCH_STRLEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) extern size_t strlen(const char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define __HAVE_ARCH_MEMCHR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) extern void * memchr(const void *, int, size_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* The following routine is like memset except that it writes 16-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) aligned values. The DEST and COUNT parameters must be even for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) correct operation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define __HAVE_ARCH_MEMSET16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) extern void * __memset16(void *dest, unsigned short, size_t count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static inline void *memset16(uint16_t *p, uint16_t v, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (__builtin_constant_p(v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return __constant_c_memset(p, 0x0001000100010001UL * v, n * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return __memset16(p, v, n * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #endif /* __KERNEL__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #endif /* __ALPHA_STRING_H__ */