Serenity Operating System
at master 148 lines 3.3 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/StdLib.h> 8 9extern "C" { 10 11void* memcpy(void* dest_ptr, void const* src_ptr, size_t n) 12{ 13#if ARCH(X86_64) 14 size_t dest = (size_t)dest_ptr; 15 size_t src = (size_t)src_ptr; 16 // FIXME: Support starting at an unaligned address. 17 if (!(dest & 0x3) && !(src & 0x3) && n >= 12) { 18 size_t size_ts = n / sizeof(size_t); 19 asm volatile( 20 "rep movsq\n" 21 : "=S"(src), "=D"(dest) 22 : "S"(src), "D"(dest), "c"(size_ts) 23 : "memory"); 24 n -= size_ts * sizeof(size_t); 25 if (n == 0) 26 return dest_ptr; 27 } 28 asm volatile( 29 "rep movsb\n" ::"S"(src), "D"(dest), "c"(n) 30 : "memory"); 31#else 32 u8* pd = (u8*)dest_ptr; 33 u8 const* ps = (u8 const*)src_ptr; 34 for (; n--;) 35 *pd++ = *ps++; 36#endif 37 return dest_ptr; 38} 39 40void* memmove(void* dest, void const* src, size_t n) 41{ 42 if (dest < src) 43 return memcpy(dest, src, n); 44 45 u8* pd = (u8*)dest; 46 u8 const* ps = (u8 const*)src; 47 for (pd += n, ps += n; n--;) 48 *--pd = *--ps; 49 return dest; 50} 51 52void* memset(void* dest_ptr, int c, size_t n) 53{ 54#if ARCH(X86_64) 55 size_t dest = (size_t)dest_ptr; 56 // FIXME: Support starting at an unaligned address. 57 if (!(dest & 0x3) && n >= 12) { 58 size_t size_ts = n / sizeof(size_t); 59 size_t expanded_c = explode_byte((u8)c); 60 asm volatile( 61 "rep stosq\n" 62 : "=D"(dest) 63 : "D"(dest), "c"(size_ts), "a"(expanded_c) 64 : "memory"); 65 n -= size_ts * sizeof(size_t); 66 if (n == 0) 67 return dest_ptr; 68 } 69 asm volatile( 70 "rep stosb\n" 71 : "=D"(dest), "=c"(n) 72 : "0"(dest), "1"(n), "a"(c) 73 : "memory"); 74#else 75 u8* pd = (u8*)dest_ptr; 76 for (; n--;) 77 *pd++ = c; 78#endif 79 return dest_ptr; 80} 81 82size_t strlen(char const* str) 83{ 84 size_t len = 0; 85 while (*(str++)) 86 ++len; 87 return len; 88} 89 90size_t strnlen(char const* str, size_t maxlen) 91{ 92 size_t len = 0; 93 for (; len < maxlen && *str; str++) 94 len++; 95 return len; 96} 97 98int strcmp(char const* s1, char const* s2) 99{ 100 for (; *s1 == *s2; ++s1, ++s2) { 101 if (*s1 == 0) 102 return 0; 103 } 104 return *(u8 const*)s1 < *(u8 const*)s2 ? -1 : 1; 105} 106 107int memcmp(void const* v1, void const* v2, size_t n) 108{ 109 auto const* s1 = (u8 const*)v1; 110 auto const* s2 = (u8 const*)v2; 111 while (n-- > 0) { 112 if (*s1++ != *s2++) 113 return s1[-1] < s2[-1] ? -1 : 1; 114 } 115 return 0; 116} 117 118int strncmp(char const* s1, char const* s2, size_t n) 119{ 120 if (!n) 121 return 0; 122 do { 123 if (*s1 != *s2++) 124 return *(unsigned char const*)s1 - *(unsigned char const*)--s2; 125 if (*s1++ == 0) 126 break; 127 } while (--n); 128 return 0; 129} 130 131char* strstr(char const* haystack, char const* needle) 132{ 133 char nch; 134 char hch; 135 136 if ((nch = *needle++) != 0) { 137 size_t len = strlen(needle); 138 do { 139 do { 140 if ((hch = *haystack++) == 0) 141 return nullptr; 142 } while (hch != nch); 143 } while (strncmp(haystack, needle, len) != 0); 144 --haystack; 145 } 146 return const_cast<char*>(haystack); 147} 148}