123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- #ifndef BITS_STRING_H
- #define BITS_STRING_H
-
- FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
- /** @file
- *
- * String functions
- *
- */
-
- extern void arm64_bzero ( void *dest, size_t len );
- extern void arm64_memset ( void *dest, size_t len, int character );
- extern void arm64_memcpy ( void *dest, const void *src, size_t len );
- extern void arm64_memmove_forwards ( void *dest, const void *src, size_t len );
- extern void arm64_memmove_backwards ( void *dest, const void *src, size_t len );
- extern void arm64_memmove ( void *dest, const void *src, size_t len );
-
- /**
- * Fill memory region
- *
- * @v dest Destination region
- * @v character Fill character
- * @v len Length
- * @ret dest Destination region
- */
- static inline __attribute__ (( always_inline )) void *
- memset ( void *dest, int character, size_t len ) {
-
- /* Allow gcc to generate inline "stX xzr" instructions for
- * small, constant lengths.
- */
- if ( __builtin_constant_p ( character ) && ( character == 0 ) &&
- __builtin_constant_p ( len ) && ( len <= 64 ) ) {
- __builtin_memset ( dest, 0, len );
- return dest;
- }
-
- /* For zeroing larger or non-constant lengths, use the
- * optimised variable-length zeroing code.
- */
- if ( __builtin_constant_p ( character ) && ( character == 0 ) ) {
- arm64_bzero ( dest, len );
- return dest;
- }
-
- /* Not necessarily zeroing: use basic variable-length code */
- arm64_memset ( dest, len, character );
- return dest;
- }
-
- /**
- * Copy memory region
- *
- * @v dest Destination region
- * @v src Source region
- * @v len Length
- * @ret dest Destination region
- */
- static inline __attribute__ (( always_inline )) void *
- memcpy ( void *dest, const void *src, size_t len ) {
-
- /* Allow gcc to generate inline "ldX"/"stX" instructions for
- * small, constant lengths.
- */
- if ( __builtin_constant_p ( len ) && ( len <= 64 ) ) {
- __builtin_memcpy ( dest, src, len );
- return dest;
- }
-
- /* Otherwise, use variable-length code */
- arm64_memcpy ( dest, src, len );
- return dest;
- }
-
- /**
- * Copy (possibly overlapping) memory region
- *
- * @v dest Destination region
- * @v src Source region
- * @v len Length
- * @ret dest Destination region
- */
- static inline __attribute__ (( always_inline )) void *
- memmove ( void *dest, const void *src, size_t len ) {
- ssize_t offset = ( dest - src );
-
- /* If required direction of copy is known at build time, then
- * use the appropriate forwards/backwards copy directly.
- */
- if ( __builtin_constant_p ( offset ) ) {
- if ( offset <= 0 ) {
- arm64_memmove_forwards ( dest, src, len );
- return dest;
- } else {
- arm64_memmove_backwards ( dest, src, len );
- return dest;
- }
- }
-
- /* Otherwise, use ambidirectional copy */
- arm64_memmove ( dest, src, len );
- return dest;
- }
-
- #endif /* BITS_STRING_H */
|