From: Sergiy Kibrik' via OSv Development <osv-dev@googlegroups.com>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master

osv: generic bitops

Semantics of bsrq()/fls() differs on x64 and aarch64, e.g. following sample
inputs produce different results:

x64:                            aarch64:

bsrq(0x1) = 0                   bsrq(0x1) = 63
bsrq(0xffffffffffffffff) = 63   bsrq(0xffffffffffffffff) = 0
bsrq(0x8000000000000000) = 63   bsrq(0x8000000000000000) = 0
bsrq(0x80000000) = 31           bsrq(0x80000000) = 32
bsrq(0x8008) = 15               bsrq(0x8008) = 48

bsrl(0x1) = 0                   bsrl(0x1) = 63
bsrl(0xffffffff) = 31           bsrl(0xffffffff) = 32
bsrl(0x80000000) = 31           bsrl(0x80000000) = 32
bsrl(0x8008) = 15               bsrl(0x8008) = 48

fsl(0x1) = 1                    fsl(0x1) = 64
fsl(0xffffffff) = 32            fsl(0xffffffff) = 33
fsl(0x80000000) = 32            fsl(0x80000000) = 33
fsl(0x8008) = 16                fsl(0x8008) = 49

Which is not quite a behaviour bitops user expects.
Use GCC built-ins to overcome this, which provide consistent behaviour across
all platforms. Arch-specific instructions generated to avoid loops, so this
should not hurt performance.

Signed-off-by: Sergiy Kibrik <sergiy.kib...@globallogic.com>
Message-Id: <1487597529-28580-6-git-send-email-sergiy.kib...@globallogic.com>

---
diff --git a/arch/aarch64/bitops.h b/arch/aarch64/bitops.h
--- a/arch/aarch64/bitops.h
+++ b/arch/aarch64/bitops.h
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2014 Huawei Technologies Duesseldorf GmbH
- *
- * This work is open source software, licensed under the terms of the
- * BSD license as described in the LICENSE file in the top-level directory.
- */
-
-#ifndef ARCH_BITOPS_H_
-#define ARCH_BITOPS_H_
-static inline unsigned int
-bsrl(unsigned int mask)
-{
-    unsigned int result;
-    asm volatile("clz %1,%0" : "=r" (result) : "r" (mask));
-    return result;
-}
-
-static inline unsigned long
-bsrq(unsigned long mask)
-{
-    unsigned long result;
-    asm volatile("clz %1,%0" : "=r" (result) : "r" (mask));
-    return result;
-}
-
-static inline int
-fls(int mask)
-{
-    return (mask == 0 ? mask : (int)bsrl((unsigned int)mask) + 1);
-}
-#endif /* ARCH_BITOPS_H */
diff --git a/bsd/porting/netport.h b/bsd/porting/netport.h
--- a/bsd/porting/netport.h
+++ b/bsd/porting/netport.h
@@ -19,7 +19,7 @@
 #include <osv/debug.h>
 #define __NEED_socklen_t
 #include <bits/alltypes.h>
-#include "bitops.h"
+#include <osv/bitops.h>

 __BEGIN_DECLS

diff --git a/core/xen_intr.cc b/core/xen_intr.cc
--- a/core/xen_intr.cc
+++ b/core/xen_intr.cc
@@ -9,7 +9,7 @@
 #include <osv/xen_intr.hh>
 #include <bsd/porting/bus.h>
 #include <machine/intr_machdep.h>
-#include "bitops.h"
+#include <osv/bitops.h>
 #include <osv/debug.hh>

 #include <osv/trace.hh>
diff --git a/include/osv/bitops.h b/include/osv/bitops.h
--- a/include/osv/bitops.h
+++ b/include/osv/bitops.h
@@ -7,20 +7,16 @@

 #ifndef ARCH_BITOPS_H_
 #define ARCH_BITOPS_H_
-static inline unsigned int
+static inline unsigned int
 bsrl(unsigned int mask)
 {
-    unsigned int result;
-    asm volatile("bsrl %1,%0" : "=r" (result) : "rm" (mask));
-    return result;
+    return sizeof(mask) * 8 - __builtin_clz(mask) - 1;
 }

 static inline unsigned long
 bsrq(unsigned long mask)
 {
-    unsigned long result;
-    asm volatile("bsrq %1,%0" : "=r" (result) : "rm" (mask));
-    return result;
+    return sizeof(mask) * 8 - __builtin_clzl(mask) - 1;
 }

 static inline int

--
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to