This commit is contained in:
2026-10-11 17:43:21 +02:00
parent 85cf698aae
commit 41cc7fea77
15 changed files with 125 additions and 84 deletions
+35 -58
View File
@@ -1,8 +1,8 @@
#include <zinnia/compiler.h>
#include <zinnia/string.h>
#include <zinnia/utils.h>
#include <stddef.h>
#include <stdint.h>
#include <zinnia/string.h>
[[__hot]]
size_t strlen(const char* str) {
@@ -29,45 +29,37 @@ int memcmp(const void* s1, const void* s2, size_t size) {
for (size_t i = 0; i < size; i++) {
if (s1ptr[i] != s2ptr[i])
return s1ptr[i] - s2ptr[i];
return (int)s1ptr[i] - (int)s2ptr[i];
}
return 0;
}
typedef size_t word_t [[__may_alias]]
;
[[__hot]]
void* memcpy(void* restrict dest, const void* restrict src, size_t n) {
if (__unlikely(n == 0))
return dest;
uint8_t* d = dest;
const uint8_t* s = src;
size_t d = (size_t)dest;
size_t s = (size_t)src;
if (d % sizeof(size_t) != 0 || s % sizeof(size_t) != 0) {
while (n && (d % sizeof(size_t) != 0) && (s % sizeof(size_t) != 0)) {
*((uint8_t*)d) = *((uint8_t*)s);
d++;
s++;
// Word copies are only possible if both pointers can be aligned at the same time.
if (((uintptr_t)d - (uintptr_t)s) % sizeof(word_t) == 0) {
while (n && (uintptr_t)d % sizeof(word_t) != 0) {
*d++ = *s++;
n--;
}
word_t* word_dest = (word_t*)d;
const word_t* word_src = (const word_t*)s;
for (; n >= sizeof(word_t); n -= sizeof(word_t))
*word_dest++ = *word_src++;
d = (uint8_t*)word_dest;
s = (const uint8_t*)word_src;
}
size_t* qword_dest = (size_t*)d;
const size_t* qword_src = (const size_t*)s;
const size_t word_count = n / sizeof(size_t);
for (size_t i = 0; i < word_count; i++) {
qword_dest[i] = qword_src[i];
}
size_t remaining_bytes = n % sizeof(size_t);
d = (size_t)(qword_dest + word_count);
s = (size_t)(qword_src + word_count);
while (remaining_bytes--) {
*((uint8_t*)d) = *((uint8_t*)s);
d++;
s++;
}
while (n--)
*d++ = *s++;
return dest;
}
@@ -76,7 +68,8 @@ void* memcpy(void* restrict dest, const void* restrict src, size_t n) {
void* memmove(void* dstptr, const void* srcptr, size_t size) {
uint8_t* dst = (uint8_t*)dstptr;
const uint8_t* src = (const uint8_t*)srcptr;
if (dst < src) {
if ((uintptr_t)dst < (uintptr_t)src) {
for (size_t i = 0; i < size; i++)
dst[i] = src[i];
} else {
@@ -88,38 +81,22 @@ void* memmove(void* dstptr, const void* srcptr, size_t size) {
[[__hot]]
void* memset(void* dest, int value, size_t n) {
if (__unlikely(n == 0))
return dest;
uint8_t* d = dest;
const uint8_t byte = (uint8_t)value;
size_t d = (size_t)dest;
if (d % sizeof(size_t) != 0) {
while (n && (d % sizeof(size_t) != 0)) {
*((uint8_t*)d) = value;
d++;
n--;
}
while (n && (uintptr_t)d % sizeof(word_t) != 0) {
*d++ = byte;
n--;
}
size_t* qword_dest = (size_t*)d;
size_t qword_value = (uint8_t)value;
qword_value |= (qword_value << 8);
qword_value |= (qword_value << 16);
qword_value |= (qword_value << 32);
const word_t word_value = (SIZE_MAX / 0xFF) * byte;
word_t* word_dest = (word_t*)d;
for (; n >= sizeof(word_t); n -= sizeof(word_t))
*word_dest++ = word_value;
const size_t word_count = n / sizeof(size_t);
for (size_t i = 0; i < word_count; i++) {
qword_dest[i] = qword_value;
}
size_t remaining_bytes = n % sizeof(size_t);
d = (size_t)(qword_dest + word_count);
while (remaining_bytes--) {
*((uint8_t*)d) = value;
d++;
}
d = (uint8_t*)word_dest;
while (n--)
*d++ = byte;
return dest;
}