aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2012-11-05 00:58:20 +0000
committerMichael Brown <mcb30@ipxe.org>2012-11-12 16:58:49 +0000
commit53f3deee06366dacd38974af7beb89aa7ce6c45e (patch)
treee91e14fffd8eb7b9a379fc5207c7cd9bd3a87c0d /src/arch
parentde20c526e68f7ec1155cdb7dcaeb2ff4c8c2c580 (diff)
downloadipxe-53f3deee06366dacd38974af7beb89aa7ce6c45e.zip
ipxe-53f3deee06366dacd38974af7beb89aa7ce6c45e.tar.gz
ipxe-53f3deee06366dacd38974af7beb89aa7ce6c45e.tar.bz2
[libc] Fix and externalise memswap()
Make memswap() behave correctly if called with a length of zero. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/core/x86_string.c28
-rw-r--r--src/arch/x86/include/bits/string.h17
2 files changed, 30 insertions, 15 deletions
diff --git a/src/arch/x86/core/x86_string.c b/src/arch/x86/core/x86_string.c
index 69c73f7..d48347c 100644
--- a/src/arch/x86/core/x86_string.c
+++ b/src/arch/x86/core/x86_string.c
@@ -106,6 +106,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
*
* @v string String
diff --git a/src/arch/x86/include/bits/string.h b/src/arch/x86/include/bits/string.h
index 249dd54..4d44c72 100644
--- a/src/arch/x86/include/bits/string.h
+++ b/src/arch/x86/include/bits/string.h
@@ -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