Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[libc] Fix and externalise memswap()
Make memswap() behave correctly if called with a length of zero.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Nov 12, 2012
1 parent de20c52 commit 53f3dee
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 15 deletions.
28 changes: 28 additions & 0 deletions src/arch/x86/core/x86_string.c
Expand Up @@ -105,6 +105,34 @@ void * __memmove ( void *dest, const void *src, size_t len ) {
}
}

/**
* Swap memory areas
*
* @v dest Destination address
* @v src Source address
* @v len Length
* @ret dest Destination address
*/
void * memswap ( void *dest, void *src, size_t len ) {
size_t discard_c;
int discard;

__asm__ __volatile__ ( "\n1:\n\t"
"dec %2\n\t"
"js 2f\n\t"
"movb (%0,%2), %b3\n\t"
"xchgb (%1,%2), %b3\n\t"
"movb %b3, (%0,%2)\n\t"
"jmp 1b\n\t"
"2:\n\t"
: "=r" ( src ), "=r" ( dest ),
"=&c" ( discard_c ), "=&q" ( discard )
: "0" ( src ), "1" ( dest ), "2" ( len )
: "memory" );

return dest;
}

/**
* Calculate length of string
*
Expand Down
17 changes: 2 additions & 15 deletions src/arch/x86/include/bits/string.h
Expand Up @@ -213,21 +213,8 @@ static inline void * memset ( void *dest, int fill, size_t len ) {
}

#define __HAVE_ARCH_MEMSWAP
static inline void * memswap(void *dest, void *src, size_t n)
{
long d0, d1, d2, d3;
__asm__ __volatile__(
"\n1:\t"
"movb (%2),%%al\n\t"
"xchgb (%1),%%al\n\t"
"inc %1\n\t"
"stosb\n\t"
"loop 1b"
: "=&c" (d0), "=&S" (d1), "=&D" (d2), "=&a" (d3)
: "0" (n), "1" (src), "2" (dest)
: "memory" );
return dest;
}

extern void * memswap ( void *dest, void *src, size_t len );

#define __HAVE_ARCH_STRNCMP

Expand Down

0 comments on commit 53f3dee

Please sign in to comment.