]> git.proxmox.com Git - mirror_qemu.git/commitdiff
optionrom: do not rely on compiler's bswap optimization
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 2 Sep 2016 15:36:23 +0000 (17:36 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 13 Sep 2016 17:09:44 +0000 (19:09 +0200)
Recent compilers can detect and inline manually-written bswap code,
but GCC 4.2.1 (the last GPLv2 version) cannot and generates really
awful code.  Depending on how the compiler is configured, it might
also not want to generate bswap because it was not in i386.  Using
asm is fine because TCG knows about bswap and all processors with
virtualization extensions also do.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
pc-bios/linuxboot_dma.bin
pc-bios/optionrom/linuxboot_dma.c

index 238a195d3869995067f158d243d852778d38a736..218d3ab4a29bfb5ab7125ec7a4d29dad1860c673 100644 (file)
Binary files a/pc-bios/linuxboot_dma.bin and b/pc-bios/linuxboot_dma.bin differ
index 754979773220289a2fbac29b4fe24fb57774d2c4..4754282ad736ac3be6459d59dcca6edb64d3f4ed 100644 (file)
@@ -122,24 +122,14 @@ static inline void writel_es(uint16_t offset, uint32_t val)
 
 static inline uint32_t bswap32(uint32_t x)
 {
-    return
-        ((x & 0x000000ffU) << 24) |
-        ((x & 0x0000ff00U) <<  8) |
-        ((x & 0x00ff0000U) >>  8) |
-        ((x & 0xff000000U) >> 24);
+    asm("bswapl %0" : "=r" (x) : "0" (x));
+    return x;
 }
 
 static inline uint64_t bswap64(uint64_t x)
 {
-    return
-        ((x & 0x00000000000000ffULL) << 56) |
-        ((x & 0x000000000000ff00ULL) << 40) |
-        ((x & 0x0000000000ff0000ULL) << 24) |
-        ((x & 0x00000000ff000000ULL) <<  8) |
-        ((x & 0x000000ff00000000ULL) >>  8) |
-        ((x & 0x0000ff0000000000ULL) >> 24) |
-        ((x & 0x00ff000000000000ULL) >> 40) |
-        ((x & 0xff00000000000000ULL) >> 56);
+    asm("bswapl %%eax; bswapl %%edx; xchg %%eax, %%edx" : "=A" (x) : "0" (x));
+    return x;
 }
 
 static inline uint64_t cpu_to_be64(uint64_t x)