1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

Given that the idea of D15374 was to "make memmove a first class citizen",

provide a _MEMMOVE extension of _MEMCPY that deals with overlap based on
the previous bcopy(9) implementation and use the former for bcopy(9) and
memmove(9). This addresses my D15374 review comment, avoiding extra MOVs
in case of memmove(9) and trashing the stack pointer.
This commit is contained in:
Marius Strobl 2018-11-20 00:08:33 +00:00
parent d1f84ec0a7
commit 3d62bdba63
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=340656

View File

@ -206,6 +206,30 @@ __FBSDID("$FreeBSD$");
inc dst ; \
6:
/*
* Extension of _MEMCPY dealing with overlap, but unaware of ASIs.
* Used for bcopy() and memmove().
*/
#define _MEMMOVE(dst, src, len) \
/* Check for overlap, and copy backwards if so. */ \
sub dst, src, %g1 ; \
cmp %g1, len ; \
bgeu,a,pt %xcc, 2f ; \
nop ; \
/* Copy backwards. */ \
add src, len, src ; \
add dst, len, dst ; \
1: deccc 1, len ; \
bl,pn %xcc, 3f ; \
dec 1, src ; \
ldub [src], %g1 ; \
dec 1, dst ; \
ba %xcc, 1b ; \
stb %g1, [dst] ; \
2: /* Do the fast version. */ \
_MEMCPY(dst, src, len, EMPTY, EMPTY, EMPTY, EMPTY) ; \
3:
/*
* void ascopy(u_long asi, vm_offset_t src, vm_offset_t dst, size_t len)
*/
@ -265,48 +289,13 @@ ENTRY(bcmp)
END(bcmp)
/*
* void *memmove(void *dst, const void *src, size_t len)
* void bcopy(const void *src, void *dst, size_t len)
*/
ENTRY(memmove)
/*
* Swap src/dst for memmove/bcopy differences
*/
mov %o0, %o6
mov %o1, %o0
mov %o6, %o1
ALTENTRY(bcopy)
/*
* Check for overlap, and copy backwards if so.
*/
sub %o1, %o0, %g1
cmp %g1, %o2
bgeu,a,pt %xcc, 3f
nop
/*
* Copy backwards.
*/
add %o0, %o2, %o0
add %o1, %o2, %o1
1: deccc 1, %o2
bl,a,pn %xcc, 2f
nop
dec 1, %o0
ldub [%o0], %g1
dec 1, %o1
ba %xcc, 1b
stb %g1, [%o1]
2: retl
mov %o6, %o0
/*
* Do the fast version.
*/
3: _MEMCPY(%o1, %o0, %o2, EMPTY, EMPTY, EMPTY, EMPTY)
ENTRY(bcopy)
_MEMMOVE(%o1, %o0, %o2)
retl
mov %o6, %o0
END(memmove)
nop
END(bcopy)
/*
* void bzero(void *b, size_t len)
@ -336,6 +325,16 @@ ENTRY(memcpy)
nop
END(memcpy)
/*
* void *memmove(void *dst, const void *src, size_t len)
*/
ENTRY(memmove)
mov %o0, %o3
_MEMMOVE(%o3, %o1, %o2)
retl
nop
END(memmove)
/*
* void *memset(void *b, int c, size_t len)
*/