util.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * util.c
  3. *
  4. * General-purpose utility functions.
  5. *
  6. * Written & released by Keir Fraser <keir.xen@gmail.com>
  7. *
  8. * This is free and unencumbered software released into the public domain.
  9. * See the file COPYING for more details, or visit <http://unlicense.org>.
  10. */
  11. void *memset(void *s, int c, size_t n)
  12. {
  13. char *p = s;
  14. /* Large aligned memset? */
  15. size_t n32 = n & ~31;
  16. if (n32 && !((uint32_t)p & 3)) {
  17. memset_fast(p, c, n32);
  18. p += n32;
  19. n &= 31;
  20. }
  21. /* Remainder/unaligned memset. */
  22. while (n--)
  23. *p++ = c;
  24. return s;
  25. }
  26. void *memcpy(void *dest, const void *src, size_t n)
  27. {
  28. char *p = dest;
  29. const char *q = src;
  30. /* Large aligned copy? */
  31. size_t n32 = n & ~31;
  32. if (n32 && !(((uint32_t)p | (uint32_t)q) & 3)) {
  33. memcpy_fast(p, q, n32);
  34. p += n32;
  35. q += n32;
  36. n &= 31;
  37. }
  38. /* Remainder/unaligned copy. */
  39. while (n--)
  40. *p++ = *q++;
  41. return dest;
  42. }
  43. asm (
  44. ".global memcpy_fast, memset_fast\n"
  45. "memcpy_fast:\n"
  46. " push {r4-r10}\n"
  47. "1: ldmia r1!,{r3-r10}\n"
  48. " stmia r0!,{r3-r10}\n"
  49. " subs r2,r2,#32\n"
  50. " bne 1b\n"
  51. " pop {r4-r10}\n"
  52. " bx lr\n"
  53. "memset_fast:\n"
  54. " push {r4-r10}\n"
  55. " uxtb r5, r1\n"
  56. " mov.w r4, #0x01010101\n"
  57. " muls r4, r5\n"
  58. " mov r3, r4\n"
  59. " mov r5, r4\n"
  60. " mov r6, r4\n"
  61. " mov r7, r4\n"
  62. " mov r8, r4\n"
  63. " mov r9, r4\n"
  64. " mov r10, r4\n"
  65. "1: stmia r0!,{r3-r10}\n"
  66. " subs r2,r2,#32\n"
  67. " bne 1b\n"
  68. " pop {r4-r10}\n"
  69. " bx lr\n"
  70. );
  71. void *memmove(void *dest, const void *src, size_t n)
  72. {
  73. char *p;
  74. const char *q;
  75. if (dest < src)
  76. return memcpy(dest, src, n);
  77. p = dest; p += n;
  78. q = src; q += n;
  79. while (n--)
  80. *--p = *--q;
  81. return dest;
  82. }
  83. int memcmp(const void *s1, const void *s2, size_t n)
  84. {
  85. const char *_s1 = s1;
  86. const char *_s2 = s2;
  87. while (n--) {
  88. int diff = *_s1++ - *_s2++;
  89. if (diff)
  90. return diff;
  91. }
  92. return 0;
  93. }
  94. size_t strlen(const char *s)
  95. {
  96. size_t len = 0;
  97. while (*s++)
  98. len++;
  99. return len;
  100. }
  101. size_t strnlen(const char *s, size_t maxlen)
  102. {
  103. size_t len = 0;
  104. while (maxlen-- && *s++)
  105. len++;
  106. return len;
  107. }
  108. int strcmp(const char *s1, const char *s2)
  109. {
  110. return strncmp(s1, s2, INT_MAX);
  111. }
  112. int strncmp(const char *s1, const char *s2, size_t n)
  113. {
  114. while (n--) {
  115. int diff = *s1 - *s2;
  116. if (diff || !*s1)
  117. return diff;
  118. s1++; s2++;
  119. }
  120. return 0;
  121. }
  122. char *strcpy(char *dest, const char *src)
  123. {
  124. char *p = dest;
  125. const char *q = src;
  126. while ((*p++ = *q++) != '\0')
  127. continue;
  128. return dest;
  129. }
  130. /*
  131. * Local variables:
  132. * mode: C
  133. * c-file-style: "Linux"
  134. * c-basic-offset: 4
  135. * tab-width: 4
  136. * indent-tabs-mode: nil
  137. * End:
  138. */