summaryrefslogtreecommitdiff
path: root/lib/libc/string
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/string')
-rw-r--r--lib/libc/string/memcpy.c98
-rw-r--r--lib/libc/string/memmem.c3
-rw-r--r--lib/libc/string/strcoll.c1
-rw-r--r--lib/libc/string/strerror.c2
-rw-r--r--lib/libc/string/strtok_r.c3
5 files changed, 97 insertions, 10 deletions
diff --git a/lib/libc/string/memcpy.c b/lib/libc/string/memcpy.c
index f87d95cd..83a29170 100644
--- a/lib/libc/string/memcpy.c
+++ b/lib/libc/string/memcpy.c
@@ -1,5 +1,6 @@
#include <errno.h> // for EINVAL, ERANGE
#include <stddef.h> // for NULL, errno_t
+#include <stdint.h>
#include <string.h> // for rsize_t, memcpy, size_t, memcpy_s
#include <sys/cdefs.h>
@@ -7,12 +8,101 @@ __weak void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
void *memcpy(void *restrict s1, const void *restrict s2, size_t n)
{
- unsigned char *dest = (unsigned char *)s1;
- const unsigned char *src = (const unsigned char *)s2;
+ unsigned char *d = (unsigned char *)s1;
+ const unsigned char *s = (const unsigned char *)s2;
- while (n--) {
- *dest++ = *src++;
+ if (n == 0)
+ return s1;
+
+ if (n < 16) {
+ if (n >= 8) {
+ *(uint64_t *)d = *(const uint64_t *)s;
+ d += 8;
+ s += 8;
+ n -= 8;
+ }
+ if (n >= 4) {
+ *(uint32_t *)d = *(const uint32_t *)s;
+ d += 4;
+ s += 4;
+ n -= 4;
+ }
+ if (n >= 2) {
+ *(uint16_t *)d = *(const uint16_t *)s;
+ d += 2;
+ s += 2;
+ n -= 2;
+ }
+ if (n)
+ *d = *s;
+ return s1;
+ }
+
+ uintptr_t align_mask = 15;
+ size_t misalign = (uintptr_t)d & align_mask;
+ if (misalign) {
+ size_t to_align = 16 - misalign;
+ if (to_align > n)
+ to_align = n;
+ for (size_t i = 0; i < to_align; ++i)
+ *d++ = *s++;
+ n -= to_align;
+ }
+
+ while (n >= 128) {
+#pragma unroll
+ for (int i = 0; i < 8; ++i) {
+ ((i128 *)d)[i] = ((const i128 *)s)[i];
+ }
+ d += 128;
+ s += 128;
+ n -= 128;
+ }
+ while (n >= 64) {
+#pragma unroll
+ for (int i = 0; i < 4; ++i) {
+ ((i128 *)d)[i] = ((const i128 *)s)[i];
+ }
+ d += 64;
+ s += 64;
+ n -= 64;
+ }
+ while (n >= 32) {
+#pragma unroll
+ for (int i = 0; i < 2; ++i) {
+ ((i128 *)d)[i] = ((const i128 *)s)[i];
+ }
+ d += 32;
+ s += 32;
+ n -= 32;
+ }
+ while (n >= 16) {
+ *(i128 *)d = *(const i128 *)s;
+ d += 16;
+ s += 16;
+ n -= 16;
+ }
+
+ if (n >= 8) {
+ *(uint64_t *)d = *(const uint64_t *)s;
+ d += 8;
+ s += 8;
+ n -= 8;
+ }
+ if (n >= 4) {
+ *(uint32_t *)d = *(const uint32_t *)s;
+ d += 4;
+ s += 4;
+ n -= 4;
+ }
+ if (n >= 2) {
+ *(uint16_t *)d = *(const uint16_t *)s;
+ d += 2;
+ s += 2;
+ n -= 2;
}
+ if (n)
+ *d = *s;
return s1;
}
diff --git a/lib/libc/string/memmem.c b/lib/libc/string/memmem.c
index 4f55cf41..ab9f5398 100644
--- a/lib/libc/string/memmem.c
+++ b/lib/libc/string/memmem.c
@@ -2,8 +2,7 @@
#include <string.h> // for memcmp, size_t, memmem
-void *memmem(const void *haystack, size_t haystacklen, const void *needle,
- size_t needlelen)
+void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)
{
const unsigned char *p1 = haystack;
const unsigned char *p2 = needle;
diff --git a/lib/libc/string/strcoll.c b/lib/libc/string/strcoll.c
index 2a4a3473..334f470c 100644
--- a/lib/libc/string/strcoll.c
+++ b/lib/libc/string/strcoll.c
@@ -1,4 +1,3 @@
-#include <libc.h> // for __unused
#include <string.h> // for strcmp, locale_t, strcoll, strcoll_l
#include <sys/cdefs.h>
diff --git a/lib/libc/string/strerror.c b/lib/libc/string/strerror.c
index b96884ea..6607ab2e 100644
--- a/lib/libc/string/strerror.c
+++ b/lib/libc/string/strerror.c
@@ -1,5 +1,5 @@
+#include "stddef.h"
#include <errno.h> // for ERANGE, E2BIG, EACCES, EADDRINUSE, EADDRNOTAVAIL
-#include <libc.h> // for __unused
#include <string.h> // for memcpy, size_t, strerror, strlen, locale_t
#include <sys/cdefs.h>
diff --git a/lib/libc/string/strtok_r.c b/lib/libc/string/strtok_r.c
index 274f6f08..e0cb4cac 100644
--- a/lib/libc/string/strtok_r.c
+++ b/lib/libc/string/strtok_r.c
@@ -2,8 +2,7 @@
#include <string.h> // for strchr, strtok_r
-char *strtok_r(char *restrict s, const char *restrict sep,
- char **restrict state)
+char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state)
{
if (s == NULL) {
s = *state;