}
/**
- * Copy (possibly overlapping) memory region forwards
+ * Copy (possibly overlapping) memory region
*
* @v dest Destination region
* @v src Source region
* @v len Length
*/
-void riscv_memmove_forwards ( void *dest, const void *src, size_t len ) {
+void riscv_memmove ( void *dest, const void *src, size_t len ) {
+ void *orig_dest = dest;
unsigned long discard_data;
/* Do nothing if length is zero */
if ( ! len )
return;
- /* Assume memmove() is not performance-critical, and perform a
- * bytewise copy for simplicity.
- */
- __asm__ __volatile__ ( "\n1:\n\t"
- "lb %2, (%1)\n\t"
- "sb %2, (%0)\n\t"
- "addi %1, %1, 1\n\t"
- "addi %0, %0, 1\n\t"
- "bne %0, %3, 1b\n\t"
- : "+r" ( dest ), "+r" ( src ),
- "=&r" ( discard_data )
- : "r" ( dest + len )
- : "memory" );
-}
-
-/**
- * Copy (possibly overlapping) memory region backwards
- *
- * @v dest Destination region
- * @v src Source region
- * @v len Length
- */
-void riscv_memmove_backwards ( void *dest, const void *src, size_t len ) {
- void *orig_dest = dest;
- unsigned long discard_data;
-
- /* Do nothing if length is zero */
- if ( ! len )
+ /* Use memcpy() if copy direction is forwards */
+ if ( dest <= src ) {
+ memcpy ( dest, src, len );
return;
+ }
/* Assume memmove() is not performance-critical, and perform a
- * bytewise copy for simplicity.
+ * bytewise copy backwards for simplicity.
*/
dest += len;
src += len;
: "r" ( orig_dest )
: "memory" );
}
-
-/**
- * Copy (possibly overlapping) memory region
- *
- * @v dest Destination region
- * @v src Source region
- * @v len Length
- */
-void riscv_memmove ( void *dest, const void *src, size_t len ) {
-
- if ( dest <= src ) {
- riscv_memmove_forwards ( dest, src, len );
- } else {
- riscv_memmove_backwards ( dest, src, len );
- }
-}
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_forwards ( void *dest, const void *src, size_t len );
-extern void riscv_memmove_backwards ( void *dest, const void *src, size_t len );
extern void riscv_memmove ( void *dest, const void *src, size_t len );
/**
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 direction of copy is known to be forwards at build time,
+ * then use variable-length memcpy().
*/
- if ( __builtin_constant_p ( offset ) ) {
- if ( offset <= 0 ) {
- riscv_memmove_forwards ( dest, src, len );
- return dest;
- } else {
- riscv_memmove_backwards ( dest, src, len );
- return dest;
- }
+ if ( __builtin_constant_p ( offset ) && ( offset <= 0 ) ) {
+ riscv_memcpy ( dest, src, len );
+ return dest;
}
/* Otherwise, use ambidirectional copy */