# HG changeset patch # User kfraser@localhost.localdomain # Date 1182265695 -3600 # Node ID 896b536d66c9952fac4bd1c9a6e3f562debec19d # Parent cb747a35e057ad2536fc560d21d43a1ade1faae5 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 Index: xen-3.1-testing/tools/ioemu/target-i386-dm/exec-dm.c =================================================================== --- xen-3.1-testing.orig/tools/ioemu/target-i386-dm/exec-dm.c +++ xen-3.1-testing/tools/ioemu/target-i386-dm/exec-dm.c @@ -442,19 +442,40 @@ extern unsigned long logdirty_bitmap_siz * 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) { @@ -469,6 +490,7 @@ void memcpy_words(void *dst, void *src, src = ((uint8_t *)src) + 1; } } +#endif void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, int len, int is_write)