diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-06-19 16:08:15 +0100 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-06-19 16:08:15 +0100 |
commit | 0edf82adb3f1f2f60c40b0e73ba3b967a7ec5554 (patch) | |
tree | 36849edc8d25b33b73710137849729d6827b58d3 /tools | |
parent | 310da2e9892f9b56c5f0b8cd9eb746c5e1ad4b78 (diff) | |
download | xen-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.c | 40 |
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) |