summaryrefslogtreecommitdiffstats
path: root/src/arch/x86/core
diff options
context:
space:
mode:
authorMichael Brown2012-11-05 01:58:20 +0100
committerMichael Brown2012-11-12 17:58:49 +0100
commit53f3deee06366dacd38974af7beb89aa7ce6c45e (patch)
treee91e14fffd8eb7b9a379fc5207c7cd9bd3a87c0d /src/arch/x86/core
parent[libc] Reduce overall code size by externalising strlen() (diff)
downloadipxe-53f3deee06366dacd38974af7beb89aa7ce6c45e.tar.gz
ipxe-53f3deee06366dacd38974af7beb89aa7ce6c45e.tar.xz
ipxe-53f3deee06366dacd38974af7beb89aa7ce6c45e.zip
[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/x86/core')
-rw-r--r--src/arch/x86/core/x86_string.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/arch/x86/core/x86_string.c b/src/arch/x86/core/x86_string.c
index 69c73f704..d48347c96 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