mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 23:37:46 -04:00
minor changes
This commit is contained in:
parent
b1a047c926
commit
32feba7458
9 changed files with 151 additions and 78 deletions
|
@ -53,70 +53,5 @@ void *memmove (void *dest, const void *src, size_t n)
|
|||
return dest;
|
||||
}
|
||||
#else
|
||||
/* memcpy/memmove in C with some simple optimizations.
|
||||
* ATTN does dirty aliasing tricks with undefined behaviour by standard.
|
||||
* (this works fine with gcc, though...)
|
||||
*/
|
||||
void *memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
struct _16 { uint32_t a[4]; };
|
||||
union { const void *v; char *c; uint64_t *l; struct _16 *s; }
|
||||
ss = { src }, ds = { dest };
|
||||
const int lm = sizeof(uint32_t)-1;
|
||||
|
||||
if ((((unsigned)ss.c ^ (unsigned)ds.c) & lm) == 0) {
|
||||
/* fast copy if pointers have the same aligment */
|
||||
while (((unsigned)ss.c & lm) && n > 0) /* align to word */
|
||||
*ds.c++ = *ss.c++, n--;
|
||||
while (n >= sizeof(struct _16)) /* copy 16 bytes blocks */
|
||||
*ds.s++ = *ss.s++, n -= sizeof(struct _16);
|
||||
if (n >= sizeof(uint64_t)) /* copy leftover 8 byte block */
|
||||
*ds.l++ = *ss.l++, n -= sizeof(uint64_t);
|
||||
} else {
|
||||
/* byte copy if pointers are unaligned */
|
||||
while (n >= 8) { /* copy 8 byte blocks */
|
||||
*ds.c++ = *ss.c++, n--; *ds.c++ = *ss.c++, n--;
|
||||
*ds.c++ = *ss.c++, n--; *ds.c++ = *ss.c++, n--;
|
||||
*ds.c++ = *ss.c++, n--; *ds.c++ = *ss.c++, n--;
|
||||
*ds.c++ = *ss.c++, n--; *ds.c++ = *ss.c++, n--;
|
||||
}
|
||||
}
|
||||
/* copy max. 8 leftover bytes */
|
||||
while (n > 0)
|
||||
*ds.c++ = *ss.c++, n--;
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memmove (void *dest, const void *src, size_t n)
|
||||
{
|
||||
struct _16 { uint32_t a[4]; };
|
||||
union { const void *v; char *c; uint64_t *l; struct _16 *s; }
|
||||
ss = { src+n }, ds = { dest+n };
|
||||
const int lm = sizeof(uint32_t)-1;
|
||||
|
||||
if (dest <= src || dest >= src+n)
|
||||
return memcpy(dest, src, n);
|
||||
|
||||
if ((((unsigned)ss.c ^ (unsigned)ds.c) & lm) == 0) {
|
||||
/* fast copy if pointers have the same aligment */
|
||||
while (((unsigned)ss.c & lm) && n > 0)
|
||||
*--ds.c = *--ss.c, n--;
|
||||
while (n >= sizeof(struct _16))
|
||||
*--ds.s = *--ss.s, n -= sizeof(struct _16);
|
||||
if (n >= sizeof(uint64_t))
|
||||
*--ds.l = *--ss.l, n -= sizeof(uint64_t);
|
||||
} else {
|
||||
/* byte copy if pointers are unaligned */
|
||||
while (n >= 8) {
|
||||
*--ds.c = *--ss.c, n--; *--ds.c = *--ss.c, n--;
|
||||
*--ds.c = *--ss.c, n--; *--ds.c = *--ss.c, n--;
|
||||
*--ds.c = *--ss.c, n--; *--ds.c = *--ss.c, n--;
|
||||
*--ds.c = *--ss.c, n--; *--ds.c = *--ss.c, n--;
|
||||
}
|
||||
}
|
||||
/* copy max. 8 leftover bytes */
|
||||
while (n > 0)
|
||||
*--ds.c = *--ss.c, n--;
|
||||
return dest;
|
||||
}
|
||||
#include "../memcpy.c"
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue