Luna/libs/libc/src/string.cpp
apio ce6ec3585c Kernel, libc: Add ENOSYS
This error is returned by the kernel/C Library when an attempt is made to use a system call that doesn't exist.
2022-10-08 14:18:25 +02:00

129 lines
3.4 KiB
C++

#include <errno.h>
#include <luna.h>
#include <string.h>
extern "C"
{
void* memcpy(void* dest, const void* src, size_t n)
{
for (size_t i = 0; i < n; ++i) { *((char*)dest + i) = *((const char*)src + i); }
return dest;
}
void* memset(void* dest, int c, size_t n)
{
for (size_t i = 0; i < n; ++i) { *((char*)dest + i) = (char)c; }
return dest;
}
size_t strlen(const char* s)
{
const char* i = s;
for (; *i; ++i)
;
return (i - s);
}
char* strcpy(char* dest, const char* src)
{
memcpy(dest, src, strlen(src) + 1);
return dest;
}
char* strncpy(char* dest, const char* src, size_t n)
{
size_t src_len = strlen(src) + 1; // NULL byte
memcpy(dest, src, src_len > n ? n : src_len);
return dest;
}
char* strcat(char* dest, const char* src)
{
size_t dest_len = strlen(dest);
size_t i;
for (i = 0; *(src + i); i++) *(char*)(dest + dest_len + i) = *(const char*)(src + i);
*(char*)(dest + dest_len + i) = '\0';
return dest;
}
char* strncat(char* dest, const char* src, size_t n)
{
size_t dest_len = strlen(dest);
size_t i;
for (i = 0; i < n && *(src + i); i++) *(char*)(dest + dest_len + i) = *(const char*)(src + i);
*(char*)(dest + dest_len + i) = '\0';
return dest;
}
char* strchr(const char*, int)
{
NOT_IMPLEMENTED("strchr");
}
void* memclr(void* start, size_t count)
{
// "i" is our counter of how many bytes we've cleared
size_t i;
// find out if "m_start" is aligned on a SSE_XMM_SIZE boundary
if ((size_t)start & (15))
{
i = 0;
// we need to clear byte-by-byte until "m_start" is aligned on an SSE_XMM_SIZE boundary
// ... and lets make sure we don't copy 'too' many bytes (i < m_count)
while (((size_t)start + i) & (15) && i < count)
{
asm("stosb;" ::"D"((size_t)start + i), "a"(0));
i++;
}
}
else
{
// if "m_start" was aligned, set our count to 0
i = 0;
}
// clear 64-byte chunks of memory (4 16-byte operations)
for (; i + 64 <= count; i += 64)
{
asm volatile(" pxor %%xmm0, %%xmm0; " // set XMM0 to 0
" movdqa %%xmm0, 0(%0); " // move 16 bytes from XMM0 to %0 + 0
" movdqa %%xmm0, 16(%0); "
" movdqa %%xmm0, 32(%0); "
" movdqa %%xmm0, 48(%0); " ::"r"((size_t)start + i));
}
// copy the remaining bytes (if any)
asm(" rep stosb; " ::"a"((size_t)(0)), "D"(((size_t)start) + i), "c"(count - i));
// "i" will contain the total amount of bytes that were actually transfered
i += count - i;
// we return "m_start" + the amount of bytes that were transfered
return (void*)(((size_t)start) + i);
}
#pragma GCC push_options
#pragma GCC diagnostic ignored "-Wwrite-strings"
char* strerror(int errnum)
{
switch (errnum)
{
case EPERM: return "Operation not permitted";
case EINVAL: return "Invalid argument";
case ENOMEM: return "Out of memory";
case ENOSYS: return "Function not implemented";
default: return 0;
}
}
#pragma GCC pop_options
}