diff options
Diffstat (limited to 'src/arch/riscv/include/bits/string.h')
| -rw-r--r-- | src/arch/riscv/include/bits/string.h | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/arch/riscv/include/bits/string.h b/src/arch/riscv/include/bits/string.h new file mode 100644 index 000000000..87834d91a --- /dev/null +++ b/src/arch/riscv/include/bits/string.h @@ -0,0 +1,82 @@ +#ifndef _BITS_STRING_H +#define _BITS_STRING_H + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * String functions + * + */ + +extern void riscv_bzero ( void *dest, size_t len ); +extern void riscv_memset ( void *dest, size_t len, int character ); +extern void riscv_memcpy ( void *dest, const void *src, size_t len ); +extern void riscv_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 ) { + + /* For zeroing larger or non-constant lengths, use the + * optimised variable-length zeroing code. + */ + if ( __builtin_constant_p ( character ) && ( character == 0 ) ) { + riscv_bzero ( dest, len ); + return dest; + } + + /* Not necessarily zeroing: use basic variable-length code */ + riscv_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 ) { + + /* Otherwise, use variable-length code */ + riscv_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 direction of copy is known to be forwards at build time, + * then use variable-length memcpy(). + */ + if ( __builtin_constant_p ( offset ) && ( offset <= 0 ) ) { + riscv_memcpy ( dest, src, len ); + return dest; + } + + /* Otherwise, use ambidirectional copy */ + riscv_memmove ( dest, src, len ); + return dest; +} + +#endif /* _BITS_STRING_H */ |
