1#pragma once
2#include <stdarg.h>
3#include <stddef.h>
4#include <stdint.h>
5void *memcpy(void *dest, const void *src, size_t n);
6void *memset(void *s, int c, size_t n);
7void *memmove(void *dest, const void *src, size_t n);
8int memcmp(const void *s1, const void *s2, size_t n);
9void *memchr(const void *s, int c, size_t n);
10void *memrchr(const void *s, int c, size_t n);
11
12#define __STRING_FAST static inline __attribute__((always_inline, artificial))
13
14__STRING_FAST void *__memset_inline(void *s, int c, size_t n) {
15 void *ret = s;
16 uint64_t word = (uint64_t) (uint8_t) c * 0x0101010101010101ULL;
17 size_t qwords = n >> 3;
18 size_t rem = n & 7;
19
20 asm volatile("rep stosq" : "+D"(s), "+c"(qwords) : "a"(word) : "memory");
21 asm volatile("rep stosb" : "+D"(s), "+c"(rem) : "a"(word) : "memory");
22
23 return ret;
24}
25
26__STRING_FAST void *__memcpy_inline(void *dest, const void *src, size_t n) {
27 void *ret = dest;
28 size_t qwords = n >> 3;
29 size_t rem = n & 7;
30
31 asm volatile("rep movsq"
32 : "+D"(dest), "+S"(src), "+c"(qwords)
33 :
34 : "memory");
35 asm volatile("rep movsb" : "+D"(dest), "+S"(src), "+c"(rem) : : "memory");
36
37 return ret;
38}
39
40__STRING_FAST void *__memmove_inline(void *dest, const void *src, size_t n) {
41 if ((uintptr_t) dest - (uintptr_t) src >= n)
42 return __memcpy_inline(dest, src, n);
43
44 uint8_t *d = (uint8_t *) dest + n;
45 const uint8_t *s = (const uint8_t *) src + n;
46 while (n--)
47 *--d = *--s;
48
49 return dest;
50}
51
52__STRING_FAST int __memcmp_inline(const void *s1, const void *s2, size_t n) {
53 if (!n)
54 return 0;
55
56 const unsigned char *p1 = (const unsigned char *) s1;
57 const unsigned char *p2 = (const unsigned char *) s2;
58
59 asm volatile("repe cmpsb" : "+D"(p1), "+S"(p2), "+c"(n) : : "memory", "cc");
60
61 return (int) p1[-1] - (int) p2[-1];
62}
63
64#define memset(s, c, n) __memset_inline((s), (c), (n))
65#define memcpy(d, s, n) __memcpy_inline((d), (s), (n))
66#define memmove(d, s, n) __memmove_inline((d), (s), (n))
67#define memcmp(a, b, n) __memcmp_inline((a), (b), (n))
68
69size_t strlen(const char *str);
70char *strcpy(char *dest, const char *src);
71char *strcat(char *dest, const char *src);
72int strncmp(const char *s1, const char *s2, size_t n);
73int strcmp(const char *str1, const char *str2);
74char *strncpy(char *dest, const char *src, size_t n);
75char *strchr(const char *s, int c);
76char *strrchr(const char *s, int c);
77size_t strspn(const char *s, const char *accept);
78size_t strcspn(const char *s, const char *reject);
79char *strpbrk(const char *s, const char *accept);
80char *strstr(const char *haystack, const char *needle);
81
82char *strtok(char *str, const char *delim);
83char *strtok_r(char *str, const char *delim, char **saveptr);
84
85char *strncat(char *dest, const char *src, size_t n);
86size_t strnlen(const char *s, size_t maxlen);
87
88int islower(int c);
89int isupper(int c);
90int isdigit(int c);
91int isalpha(int c);
92int isalnum(int c);
93int isspace(int c);
94int isprint(int c);
95int toupper(int c);
96int tolower(int c);
97
98char *strdup(const char *str);
99char *strndup(const char *str, size_t n);
100int strcasecmp(const char *s1, const char *s2);
101int strncasecmp(const char *s1, const char *s2, size_t n);
102
103char *strrev(char *s);
104char *strtoupper(char *s);
105char *strtolower(char *s);
106
107int64_t atoi(const char *str);
108size_t atoui(const char *str);
109size_t atohex(const char *str);
110
111char *itoa(int64_t value, char *buf, int base);
112char *utoa(size_t value, char *buf, int base);
113
114long strtol(const char *nptr, char **endptr, int base);
115long long strtoll(const char *nptr, char **endptr, int base);
116unsigned long strtoul(const char *nptr, char **endptr, int base);
117unsigned long long strtoull(const char *nptr, char **endptr, int base);
118
119size_t strlcpy(char *dst, const char *src, size_t size);
120size_t strlcat(char *dst, const char *src, size_t size);
121char *strsep(char **stringp, const char *delim);
122char *strchrnul(const char *s, int c);
123
124int vsnprintf(char *buffer, int buffer_len, const char *format, va_list args);
125int snprintf(char *buffer, int buffer_len, const char *format, ...);
126