MiniStdLib.cpp 3.7 KB

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