A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 147 lines 3.7 kB view raw
1/* 2FUNCTION 3 <<memmove>>---move possibly overlapping memory 4 5INDEX 6 memmove 7 8ANSI_SYNOPSIS 9 #include <string.h> 10 void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>); 11 12TRAD_SYNOPSIS 13 #include <string.h> 14 void *memmove(<[dst]>, <[src]>, <[length]>) 15 void *<[dst]>; 16 void *<[src]>; 17 size_t <[length]>; 18 19DESCRIPTION 20 This function moves <[length]> characters from the block of 21 memory starting at <<*<[src]>>> to the memory starting at 22 <<*<[dst]>>>. <<memmove>> reproduces the characters correctly 23 at <<*<[dst]>>> even if the two areas overlap. 24 25 26RETURNS 27 The function returns <[dst]> as passed. 28 29PORTABILITY 30<<memmove>> is ANSI C. 31 32<<memmove>> requires no supporting OS subroutines. 33 34QUICKREF 35 memmove ansi pure 36*/ 37 38#include "config.h" 39#include <_ansi.h> 40#include <string.h> 41 42/* Nonzero if either X or Y is not aligned on a "long" boundary. */ 43#define ROCKBOX_UNALIGNED(X, Y) \ 44 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) 45 46/* How many bytes are copied each iteration of the 4X unrolled loop. */ 47#define BIGBLOCKSIZE (sizeof (long) << 2) 48 49/* How many bytes are copied each iteration of the word copy loop. */ 50#define LITTLEBLOCKSIZE (sizeof (long)) 51 52/* Threshhold for punting to the byte copier. */ 53#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE) 54 55_PTR 56_DEFUN (memmove, (dst_void, src_void, length), 57 _PTR dst_void _AND 58 _CONST _PTR src_void _AND 59 size_t length) ICODE_ATTR; 60 61_PTR 62_DEFUN (memmove, (dst_void, src_void, length), 63 _PTR dst_void _AND 64 _CONST _PTR src_void _AND 65 size_t length) 66{ 67#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) 68 char *dst = dst_void; 69 _CONST char *src = src_void; 70 71 if (src < dst && dst < src + length) 72 { 73 /* Have to copy backwards */ 74 src += length; 75 dst += length; 76 while (length--) 77 { 78 *--dst = *--src; 79 } 80 } 81 else 82 { 83 while (length--) 84 { 85 *dst++ = *src++; 86 } 87 } 88 89 return dst_void; 90#else 91 char *dst = dst_void; 92 _CONST char *src = src_void; 93 long *aligned_dst; 94 _CONST long *aligned_src; 95 unsigned int len = length; 96 97 if (src < dst && dst < src + len) 98 { 99 /* Destructive overlap...have to copy backwards */ 100 src += len; 101 dst += len; 102 while (len--) 103 { 104 *--dst = *--src; 105 } 106 } 107 else 108 { 109 /* Use optimizing algorithm for a non-destructive copy to closely 110 match memcpy. If the size is small or either SRC or DST is unaligned, 111 then punt into the byte copy loop. This should be rare. */ 112 if (!TOO_SMALL(len) && !ROCKBOX_UNALIGNED (src, dst)) 113 { 114 aligned_dst = (long*)dst; 115 aligned_src = (long*)src; 116 117 /* Copy 4X long words at a time if possible. */ 118 while (len >= BIGBLOCKSIZE) 119 { 120 *aligned_dst++ = *aligned_src++; 121 *aligned_dst++ = *aligned_src++; 122 *aligned_dst++ = *aligned_src++; 123 *aligned_dst++ = *aligned_src++; 124 len -= BIGBLOCKSIZE; 125 } 126 127 /* Copy one long word at a time if possible. */ 128 while (len >= LITTLEBLOCKSIZE) 129 { 130 *aligned_dst++ = *aligned_src++; 131 len -= LITTLEBLOCKSIZE; 132 } 133 134 /* Pick up any residual with a byte copier. */ 135 dst = (char*)aligned_dst; 136 src = (char*)aligned_src; 137 } 138 139 while (len--) 140 { 141 *dst++ = *src++; 142 } 143 } 144 145 return dst_void; 146#endif /* not PREFER_SIZE_OVER_SPEED */ 147}