qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 3/3] virtio: optimize virtio_access_is_big_endian()


From: Greg Kurz
Subject: [Qemu-devel] [PATCH 3/3] virtio: optimize virtio_access_is_big_endian() for little-endian targets
Date: Mon, 09 Nov 2015 18:58:34 +0100
User-agent: StGit/0.17.1-dirty

When adding cross-endian support, we introduced the TARGET_IS_BIENDIAN macro
and the virtio_access_is_big_endian() helper to have a branchless fast path
in the virtio memory accessors for targets that don't switch endian.

This was considered as a strong requirement at the time.

Now we have added a runtime check for virtio 1.0, which ruins the benefit
of the virtio_access_is_big_endian() helper for always little-endian targets.

With this patch, fixed little-endian targets stop checking for virtio 1.0,
since the result is little-endian in all cases. The helper also gets renamed
so it is clear it is optimized for fast paths.

Signed-off-by: Greg Kurz <address@hidden>
---
 include/hw/virtio/virtio-access.h |   43 ++++++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/include/hw/virtio/virtio-access.h 
b/include/hw/virtio/virtio-access.h
index ba1530619939..ff013519b9dc 100644
--- a/include/hw/virtio/virtio-access.h
+++ b/include/hw/virtio/virtio-access.h
@@ -17,12 +17,15 @@
 #include "hw/virtio/virtio.h"
 #include "exec/address-spaces.h"
 
-static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
+static inline bool virtio_is_big_endian_fast(VirtIODevice *vdev)
 {
+#if defined(TARGET_IS_BIENDIAN) || defined(TARGET_WORDS_BIGENDIAN)
     if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
         /* Devices conforming to VIRTIO 1.0 or later are always LE. */
         return false;
     }
+#endif
+
 #if defined(TARGET_IS_BIENDIAN)
     return virtio_is_big_endian(vdev);
 #elif defined(TARGET_WORDS_BIGENDIAN)
@@ -34,7 +37,7 @@ static inline bool virtio_access_is_big_endian(VirtIODevice 
*vdev)
 
 static inline uint16_t virtio_lduw_phys(VirtIODevice *vdev, hwaddr pa)
 {
-    if (virtio_access_is_big_endian(vdev)) {
+    if (virtio_is_big_endian_fast(vdev)) {
         return lduw_be_phys(&address_space_memory, pa);
     }
     return lduw_le_phys(&address_space_memory, pa);
@@ -42,7 +45,7 @@ static inline uint16_t virtio_lduw_phys(VirtIODevice *vdev, 
hwaddr pa)
 
 static inline uint32_t virtio_ldl_phys(VirtIODevice *vdev, hwaddr pa)
 {
-    if (virtio_access_is_big_endian(vdev)) {
+    if (virtio_is_big_endian_fast(vdev)) {
         return ldl_be_phys(&address_space_memory, pa);
     }
     return ldl_le_phys(&address_space_memory, pa);
@@ -50,7 +53,7 @@ static inline uint32_t virtio_ldl_phys(VirtIODevice *vdev, 
hwaddr pa)
 
 static inline uint64_t virtio_ldq_phys(VirtIODevice *vdev, hwaddr pa)
 {
-    if (virtio_access_is_big_endian(vdev)) {
+    if (virtio_is_big_endian_fast(vdev)) {
         return ldq_be_phys(&address_space_memory, pa);
     }
     return ldq_le_phys(&address_space_memory, pa);
@@ -59,7 +62,7 @@ static inline uint64_t virtio_ldq_phys(VirtIODevice *vdev, 
hwaddr pa)
 static inline void virtio_stw_phys(VirtIODevice *vdev, hwaddr pa,
                                    uint16_t value)
 {
-    if (virtio_access_is_big_endian(vdev)) {
+    if (virtio_is_big_endian_fast(vdev)) {
         stw_be_phys(&address_space_memory, pa, value);
     } else {
         stw_le_phys(&address_space_memory, pa, value);
@@ -69,7 +72,7 @@ static inline void virtio_stw_phys(VirtIODevice *vdev, hwaddr 
pa,
 static inline void virtio_stl_phys(VirtIODevice *vdev, hwaddr pa,
                                    uint32_t value)
 {
-    if (virtio_access_is_big_endian(vdev)) {
+    if (virtio_is_big_endian_fast(vdev)) {
         stl_be_phys(&address_space_memory, pa, value);
     } else {
         stl_le_phys(&address_space_memory, pa, value);
@@ -78,7 +81,7 @@ static inline void virtio_stl_phys(VirtIODevice *vdev, hwaddr 
pa,
 
 static inline void virtio_stw_p(VirtIODevice *vdev, void *ptr, uint16_t v)
 {
-    if (virtio_access_is_big_endian(vdev)) {
+    if (virtio_is_big_endian_fast(vdev)) {
         stw_be_p(ptr, v);
     } else {
         stw_le_p(ptr, v);
@@ -87,7 +90,7 @@ static inline void virtio_stw_p(VirtIODevice *vdev, void 
*ptr, uint16_t v)
 
 static inline void virtio_stl_p(VirtIODevice *vdev, void *ptr, uint32_t v)
 {
-    if (virtio_access_is_big_endian(vdev)) {
+    if (virtio_is_big_endian_fast(vdev)) {
         stl_be_p(ptr, v);
     } else {
         stl_le_p(ptr, v);
@@ -96,7 +99,7 @@ static inline void virtio_stl_p(VirtIODevice *vdev, void 
*ptr, uint32_t v)
 
 static inline void virtio_stq_p(VirtIODevice *vdev, void *ptr, uint64_t v)
 {
-    if (virtio_access_is_big_endian(vdev)) {
+    if (virtio_is_big_endian_fast(vdev)) {
         stq_be_p(ptr, v);
     } else {
         stq_le_p(ptr, v);
@@ -105,7 +108,7 @@ static inline void virtio_stq_p(VirtIODevice *vdev, void 
*ptr, uint64_t v)
 
 static inline int virtio_lduw_p(VirtIODevice *vdev, const void *ptr)
 {
-    if (virtio_access_is_big_endian(vdev)) {
+    if (virtio_is_big_endian_fast(vdev)) {
         return lduw_be_p(ptr);
     } else {
         return lduw_le_p(ptr);
@@ -114,7 +117,7 @@ static inline int virtio_lduw_p(VirtIODevice *vdev, const 
void *ptr)
 
 static inline int virtio_ldl_p(VirtIODevice *vdev, const void *ptr)
 {
-    if (virtio_access_is_big_endian(vdev)) {
+    if (virtio_is_big_endian_fast(vdev)) {
         return ldl_be_p(ptr);
     } else {
         return ldl_le_p(ptr);
@@ -123,7 +126,7 @@ static inline int virtio_ldl_p(VirtIODevice *vdev, const 
void *ptr)
 
 static inline uint64_t virtio_ldq_p(VirtIODevice *vdev, const void *ptr)
 {
-    if (virtio_access_is_big_endian(vdev)) {
+    if (virtio_is_big_endian_fast(vdev)) {
         return ldq_be_p(ptr);
     } else {
         return ldq_le_p(ptr);
@@ -133,18 +136,18 @@ static inline uint64_t virtio_ldq_p(VirtIODevice *vdev, 
const void *ptr)
 static inline bool virtio_needs_swap(VirtIODevice *vdev)
 {
 #ifdef HOST_WORDS_BIGENDIAN
-    return virtio_access_is_big_endian(vdev) ? false : true;
+    return virtio_is_big_endian_fast(vdev) ? false : true;
 #else
-    return virtio_access_is_big_endian(vdev) ? true : false;
+    return virtio_is_big_endian_fast(vdev) ? true : false;
 #endif
 }
 
 static inline uint16_t virtio_tswap16(VirtIODevice *vdev, uint16_t s)
 {
 #ifdef HOST_WORDS_BIGENDIAN
-    return virtio_access_is_big_endian(vdev) ? s : bswap16(s);
+    return virtio_is_big_endian_fast(vdev) ? s : bswap16(s);
 #else
-    return virtio_access_is_big_endian(vdev) ? bswap16(s) : s;
+    return virtio_is_big_endian_fast(vdev) ? bswap16(s) : s;
 #endif
 }
 
@@ -156,9 +159,9 @@ static inline void virtio_tswap16s(VirtIODevice *vdev, 
uint16_t *s)
 static inline uint32_t virtio_tswap32(VirtIODevice *vdev, uint32_t s)
 {
 #ifdef HOST_WORDS_BIGENDIAN
-    return virtio_access_is_big_endian(vdev) ? s : bswap32(s);
+    return virtio_is_big_endian_fast(vdev) ? s : bswap32(s);
 #else
-    return virtio_access_is_big_endian(vdev) ? bswap32(s) : s;
+    return virtio_is_big_endian_fast(vdev) ? bswap32(s) : s;
 #endif
 }
 
@@ -170,9 +173,9 @@ static inline void virtio_tswap32s(VirtIODevice *vdev, 
uint32_t *s)
 static inline uint64_t virtio_tswap64(VirtIODevice *vdev, uint64_t s)
 {
 #ifdef HOST_WORDS_BIGENDIAN
-    return virtio_access_is_big_endian(vdev) ? s : bswap64(s);
+    return virtio_is_big_endian_fast(vdev) ? s : bswap64(s);
 #else
-    return virtio_access_is_big_endian(vdev) ? bswap64(s) : s;
+    return virtio_is_big_endian_fast(vdev) ? bswap64(s) : s;
 #endif
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]