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