#include #include #include 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 }