StdLib.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include "types.h"
  2. #include "Assertions.h"
  3. #include "kmalloc.h"
  4. #include <AK/StdLibExtras.h>
  5. #include <AK/Types.h>
  6. extern "C" {
  7. void* memcpy(void* dest_ptr, const void* src_ptr, size_t n)
  8. {
  9. if (n >= 1024) {
  10. return mmx_memcpy(dest_ptr, src_ptr, n);
  11. }
  12. size_t dest = (size_t)dest_ptr;
  13. size_t src = (size_t)src_ptr;
  14. // FIXME: Support starting at an unaligned address.
  15. if (!(dest & 0x3) && !(src & 0x3) && n >= 12) {
  16. size_t size_ts = n / sizeof(size_t);
  17. asm volatile(
  18. "rep movsl\n"
  19. : "=S"(src), "=D"(dest)
  20. : "S"(src), "D"(dest), "c"(size_ts)
  21. : "memory"
  22. );
  23. n -= size_ts * sizeof(size_t);
  24. if (n == 0)
  25. return dest_ptr;
  26. }
  27. asm volatile(
  28. "rep movsb\n"
  29. :: "S"(src), "D"(dest), "c"(n)
  30. : "memory"
  31. );
  32. return dest_ptr;
  33. }
  34. void* memmove(void* dest, const void* src, size_t n)
  35. {
  36. if (dest < src)
  37. return memcpy(dest, src, n);
  38. byte *pd = (byte*)dest;
  39. const byte *ps = (const byte*)src;
  40. for (pd += n, ps += n; n--;)
  41. *--pd = *--ps;
  42. return dest;
  43. }
  44. char* strcpy(char* dest, const char *src)
  45. {
  46. auto* dest_ptr = dest;
  47. auto* src_ptr = src;
  48. while ((*dest_ptr++ = *src_ptr++) != '\0');
  49. return dest;
  50. }
  51. char* strncpy(char* dest, const char* src, size_t n)
  52. {
  53. size_t i;
  54. for (i = 0; i < n && src[i] != '\0'; ++i)
  55. dest[i] = src[i];
  56. for ( ; i < n; ++i)
  57. dest[i] = '\0';
  58. return dest;
  59. }
  60. void* memset(void* dest_ptr, int c, size_t n)
  61. {
  62. size_t dest = (size_t)dest_ptr;
  63. // FIXME: Support starting at an unaligned address.
  64. if (!(dest & 0x3) && n >= 12) {
  65. size_t size_ts = n / sizeof(size_t);
  66. size_t expanded_c = (byte)c;
  67. expanded_c |= expanded_c << 8;
  68. expanded_c |= expanded_c << 16;
  69. asm volatile(
  70. "rep stosl\n"
  71. : "=D"(dest)
  72. : "D"(dest), "c"(size_ts), "a"(expanded_c)
  73. : "memory"
  74. );
  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. );
  85. return dest_ptr;
  86. }
  87. char* strrchr(const char* str, int ch)
  88. {
  89. char *last = nullptr;
  90. char c;
  91. for (; (c = *str); ++str) {
  92. if (c == ch)
  93. last = const_cast<char*>(str);
  94. }
  95. return last;
  96. }
  97. size_t strlen(const char* str)
  98. {
  99. size_t len = 0;
  100. while (*(str++))
  101. ++len;
  102. return len;
  103. }
  104. int strcmp(const char *s1, const char *s2)
  105. {
  106. for (; *s1 == *s2; ++s1, ++s2) {
  107. if (*s1 == 0)
  108. return 0;
  109. }
  110. return *(const byte*)s1 < *(const byte*)s2 ? -1 : 1;
  111. }
  112. char* strdup(const char *str)
  113. {
  114. size_t len = strlen(str);
  115. char* new_str = (char*)kmalloc(len + 1);
  116. strcpy(new_str, str);
  117. return new_str;
  118. }
  119. int memcmp(const void* v1, const void* v2, size_t n)
  120. {
  121. auto* s1 = (const byte*)v1;
  122. auto* s2 = (const byte*)v2;
  123. while (n-- > 0) {
  124. if (*s1++ != *s2++)
  125. return s1[-1] < s2[-1] ? -1 : 1;
  126. }
  127. return 0;
  128. }
  129. [[noreturn]] void __cxa_pure_virtual()
  130. {
  131. ASSERT_NOT_REACHED();
  132. }
  133. }