aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-06-19 16:08:15 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-06-19 16:08:15 +0100
commit0edf82adb3f1f2f60c40b0e73ba3b967a7ec5554 (patch)
tree36849edc8d25b33b73710137849729d6827b58d3 /tools
parent310da2e9892f9b56c5f0b8cd9eb746c5e1ad4b78 (diff)
downloadxen-0edf82adb3f1f2f60c40b0e73ba3b967a7ec5554.tar.gz
xen-0edf82adb3f1f2f60c40b0e73ba3b967a7ec5554.tar.bz2
xen-0edf82adb3f1f2f60c40b0e73ba3b967a7ec5554.zip
ioemu: Assembler memcpy() for x86, and lowest-common-denominator
memcpy() function for all others, avoiding noisy longword copies on ia64. Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/ioemu/target-i386-dm/exec-dm.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/tools/ioemu/target-i386-dm/exec-dm.c b/tools/ioemu/target-i386-dm/exec-dm.c
index 3c66f06476..50df679873 100644
--- a/tools/ioemu/target-i386-dm/exec-dm.c
+++ b/tools/ioemu/target-i386-dm/exec-dm.c
@@ -443,19 +443,40 @@ extern unsigned long logdirty_bitmap_size;
* Forcing a word-sized read/write prevents the guest from seeing a partially
* written word-sized atom.
*/
-void memcpy_words(void *dst, void *src, size_t n)
+#if defined(__x86_64__) || defined(__i386__)
+static void memcpy_words(void *dst, void *src, size_t n)
{
- while (n >= sizeof(long)) {
- *((long *)dst) = *((long *)src);
- dst = ((long *)dst) + 1;
- src = ((long *)src) + 1;
- n -= sizeof(long);
- }
-
- if (n & 4) {
+ asm (
+ " movl %%edx,%%ecx \n"
+#ifdef __x86_64
+ " shrl $3,%%ecx \n"
+ " andl $7,%%edx \n"
+ " rep movsq \n"
+ " test $4,%%edx \n"
+ " jz 1f \n"
+ " movsl \n"
+#else /* __i386__ */
+ " shrl $2,%%ecx \n"
+ " andl $3,%%edx \n"
+ " rep movsl \n"
+#endif
+ "1: test $2,%%edx \n"
+ " jz 1f \n"
+ " movsw \n"
+ "1: test $1,%%edx \n"
+ " jz 1f \n"
+ " movsb \n"
+ "1: \n"
+ : : "S" (src), "D" (dst), "d" (n) : "ecx" );
+}
+#else
+static void memcpy_words(void *dst, void *src, size_t n)
+{
+ while (n >= sizeof(uint32_t)) {
*((uint32_t *)dst) = *((uint32_t *)src);
dst = ((uint32_t *)dst) + 1;
src = ((uint32_t *)src) + 1;
+ n -= sizeof(uint32_t);
}
if (n & 2) {
@@ -470,6 +491,7 @@ void memcpy_words(void *dst, void *src, size_t n)
src = ((uint8_t *)src) + 1;
}
}
+#endif
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
int len, int is_write)