util.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. #if defined(CORTEX_M3) || defined(CORTEX_M7)
  12. #define FAST_ARM 1
  13. #endif
  14. void *memset(void *s, int c, size_t n)
  15. {
  16. char *p = s;
  17. #ifdef FAST_ARM
  18. /* Large aligned memset? */
  19. size_t n32 = n & ~31;
  20. if (n32 && !((uint32_t)p & 3)) {
  21. memset_fast(p, c, n32);
  22. p += n32;
  23. n &= 31;
  24. }
  25. #endif
  26. /* Remainder/unaligned memset. */
  27. while (n--)
  28. *p++ = c;
  29. return s;
  30. }
  31. void *memcpy(void *dest, const void *src, size_t n)
  32. {
  33. char *p = dest;
  34. const char *q = src;
  35. #ifdef FAST_ARM
  36. /* Large aligned copy? */
  37. size_t n32 = n & ~31;
  38. if (n32 && !(((uint32_t)p | (uint32_t)q) & 3)) {
  39. memcpy_fast(p, q, n32);
  40. p += n32;
  41. q += n32;
  42. n &= 31;
  43. }
  44. #endif
  45. /* Remainder/unaligned copy. */
  46. while (n--)
  47. *p++ = *q++;
  48. return dest;
  49. }
  50. #ifdef FAST_ARM
  51. asm (
  52. ".global memcpy_fast, memset_fast\n"
  53. "memcpy_fast:\n"
  54. " push {r4-r10}\n"
  55. "1: ldmia r1!,{r3-r10}\n"
  56. " stmia r0!,{r3-r10}\n"
  57. " subs r2,r2,#32\n"
  58. " bne 1b\n"
  59. " pop {r4-r10}\n"
  60. " bx lr\n"
  61. "memset_fast:\n"
  62. " push {r4-r10}\n"
  63. " uxtb r5, r1\n"
  64. " mov.w r4, #0x01010101\n"
  65. " muls r4, r5\n"
  66. " mov r3, r4\n"
  67. " mov r5, r4\n"
  68. " mov r6, r4\n"
  69. " mov r7, r4\n"
  70. " mov r8, r4\n"
  71. " mov r9, r4\n"
  72. " mov r10, r4\n"
  73. "1: stmia r0!,{r3-r10}\n"
  74. " subs r2,r2,#32\n"
  75. " bne 1b\n"
  76. " pop {r4-r10}\n"
  77. " bx lr\n"
  78. );
  79. #endif
  80. void *memmove(void *dest, const void *src, size_t n)
  81. {
  82. char *p;
  83. const char *q;
  84. if (dest < src)
  85. return memcpy(dest, src, n);
  86. p = dest; p += n;
  87. q = src; q += n;
  88. while (n--)
  89. *--p = *--q;
  90. return dest;
  91. }
  92. int memcmp(const void *s1, const void *s2, size_t n)
  93. {
  94. const char *_s1 = s1;
  95. const char *_s2 = s2;
  96. while (n--) {
  97. int diff = *_s1++ - *_s2++;
  98. if (diff)
  99. return diff;
  100. }
  101. return 0;
  102. }
  103. size_t strlen(const char *s)
  104. {
  105. size_t len = 0;
  106. while (*s++)
  107. len++;
  108. return len;
  109. }
  110. size_t strnlen(const char *s, size_t maxlen)
  111. {
  112. size_t len = 0;
  113. while (maxlen-- && *s++)
  114. len++;
  115. return len;
  116. }
  117. int strcmp(const char *s1, const char *s2)
  118. {
  119. return strncmp(s1, s2, INT_MAX);
  120. }
  121. int strncmp(const char *s1, const char *s2, size_t n)
  122. {
  123. while (n--) {
  124. int diff = *s1 - *s2;
  125. if (diff || !*s1)
  126. return diff;
  127. s1++; s2++;
  128. }
  129. return 0;
  130. }
  131. char *strcpy(char *dest, const char *src)
  132. {
  133. char *p = dest;
  134. const char *q = src;
  135. while ((*p++ = *q++) != '\0')
  136. continue;
  137. return dest;
  138. }
  139. /* 64:32->32q division requiring 32:32->64 multiply. Cortex M3+ */
  140. uint32_t udiv64(uint64_t dividend, uint32_t divisor)
  141. {
  142. uint32_t x, q = 0;
  143. for (x = 1u<<31; x != 0; x >>= 1) {
  144. if (((uint64_t)(q|x)*divisor) <= dividend)
  145. q |= x;
  146. }
  147. return q;
  148. }
  149. /*
  150. * Local variables:
  151. * mode: C
  152. * c-file-style: "Linux"
  153. * c-basic-offset: 4
  154. * tab-width: 4
  155. * indent-tabs-mode: nil
  156. * End:
  157. */