You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

string.h 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #ifndef BITS_STRING_H
  2. #define BITS_STRING_H
  3. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  4. /** @file
  5. *
  6. * String functions
  7. *
  8. */
  9. extern void arm64_bzero ( void *dest, size_t len );
  10. extern void arm64_memset ( void *dest, size_t len, int character );
  11. extern void arm64_memcpy ( void *dest, const void *src, size_t len );
  12. extern void arm64_memmove_forwards ( void *dest, const void *src, size_t len );
  13. extern void arm64_memmove_backwards ( void *dest, const void *src, size_t len );
  14. extern void arm64_memmove ( void *dest, const void *src, size_t len );
  15. /**
  16. * Fill memory region
  17. *
  18. * @v dest Destination region
  19. * @v character Fill character
  20. * @v len Length
  21. * @ret dest Destination region
  22. */
  23. static inline __attribute__ (( always_inline )) void *
  24. memset ( void *dest, int character, size_t len ) {
  25. /* Allow gcc to generate inline "stX xzr" instructions for
  26. * small, constant lengths.
  27. */
  28. if ( __builtin_constant_p ( character ) && ( character == 0 ) &&
  29. __builtin_constant_p ( len ) && ( len <= 64 ) ) {
  30. __builtin_memset ( dest, 0, len );
  31. return dest;
  32. }
  33. /* For zeroing larger or non-constant lengths, use the
  34. * optimised variable-length zeroing code.
  35. */
  36. if ( __builtin_constant_p ( character ) && ( character == 0 ) ) {
  37. arm64_bzero ( dest, len );
  38. return dest;
  39. }
  40. /* Not necessarily zeroing: use basic variable-length code */
  41. arm64_memset ( dest, len, character );
  42. return dest;
  43. }
  44. /**
  45. * Copy memory region
  46. *
  47. * @v dest Destination region
  48. * @v src Source region
  49. * @v len Length
  50. * @ret dest Destination region
  51. */
  52. static inline __attribute__ (( always_inline )) void *
  53. memcpy ( void *dest, const void *src, size_t len ) {
  54. /* Allow gcc to generate inline "ldX"/"stX" instructions for
  55. * small, constant lengths.
  56. */
  57. if ( __builtin_constant_p ( len ) && ( len <= 64 ) ) {
  58. __builtin_memcpy ( dest, src, len );
  59. return dest;
  60. }
  61. /* Otherwise, use variable-length code */
  62. arm64_memcpy ( dest, src, len );
  63. return dest;
  64. }
  65. /**
  66. * Copy (possibly overlapping) memory region
  67. *
  68. * @v dest Destination region
  69. * @v src Source region
  70. * @v len Length
  71. * @ret dest Destination region
  72. */
  73. static inline __attribute__ (( always_inline )) void *
  74. memmove ( void *dest, const void *src, size_t len ) {
  75. ssize_t offset = ( dest - src );
  76. /* If required direction of copy is known at build time, then
  77. * use the appropriate forwards/backwards copy directly.
  78. */
  79. if ( __builtin_constant_p ( offset ) ) {
  80. if ( offset <= 0 ) {
  81. arm64_memmove_forwards ( dest, src, len );
  82. return dest;
  83. } else {
  84. arm64_memmove_backwards ( dest, src, len );
  85. return dest;
  86. }
  87. }
  88. /* Otherwise, use ambidirectional copy */
  89. arm64_memmove ( dest, src, len );
  90. return dest;
  91. }
  92. #endif /* BITS_STRING_H */