X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=qemu%2Finclude%2Fqemu%2Fhost-utils.h;h=1cdae0d0ed4e3a2d537b922c3fc9691fc37e6a96;hb=74248cb2594babbb144e191a3fbc755200aea043;hp=d4f21c947f6733e5eaef6a5ffe26d747d3c1e409;hpb=e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb;p=kvmfornfv.git diff --git a/qemu/include/qemu/host-utils.h b/qemu/include/qemu/host-utils.h index d4f21c947..1cdae0d0e 100644 --- a/qemu/include/qemu/host-utils.h +++ b/qemu/include/qemu/host-utils.h @@ -25,8 +25,7 @@ #ifndef HOST_UTILS_H #define HOST_UTILS_H 1 -#include "qemu/compiler.h" /* QEMU_GNUC_PREREQ */ -#include +#include "qemu/bswap.h" #ifdef CONFIG_INT128 static inline void mulu64(uint64_t *plow, uint64_t *phigh, @@ -45,6 +44,12 @@ static inline void muls64(uint64_t *plow, uint64_t *phigh, *phigh = r >> 64; } +/* compute with 96 bit intermediate result: (a*b)/c */ +static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) +{ + return (__int128_t)a * b / c; +} + static inline int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor) { if (divisor == 0) { @@ -75,6 +80,29 @@ void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b); void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b); int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor); int divs128(int64_t *plow, int64_t *phigh, int64_t divisor); + +static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) +{ + union { + uint64_t ll; + struct { +#ifdef HOST_WORDS_BIGENDIAN + uint32_t high, low; +#else + uint32_t low, high; +#endif + } l; + } u, res; + uint64_t rl, rh; + + u.ll = a; + rl = (uint64_t)u.l.low * (uint64_t)b; + rh = (uint64_t)u.l.high * (uint64_t)b; + rh += (rl >> 32); + res.l.high = rh / c; + res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c; + return res.ll; +} #endif /** @@ -361,6 +389,80 @@ static inline int ctpop64(uint64_t val) #endif } +/** + * revbit8 - reverse the bits in an 8-bit value. + * @x: The value to modify. + */ +static inline uint8_t revbit8(uint8_t x) +{ + /* Assign the correct nibble position. */ + x = ((x & 0xf0) >> 4) + | ((x & 0x0f) << 4); + /* Assign the correct bit position. */ + x = ((x & 0x88) >> 3) + | ((x & 0x44) >> 1) + | ((x & 0x22) << 1) + | ((x & 0x11) << 3); + return x; +} + +/** + * revbit16 - reverse the bits in a 16-bit value. + * @x: The value to modify. + */ +static inline uint16_t revbit16(uint16_t x) +{ + /* Assign the correct byte position. */ + x = bswap16(x); + /* Assign the correct nibble position. */ + x = ((x & 0xf0f0) >> 4) + | ((x & 0x0f0f) << 4); + /* Assign the correct bit position. */ + x = ((x & 0x8888) >> 3) + | ((x & 0x4444) >> 1) + | ((x & 0x2222) << 1) + | ((x & 0x1111) << 3); + return x; +} + +/** + * revbit32 - reverse the bits in a 32-bit value. + * @x: The value to modify. + */ +static inline uint32_t revbit32(uint32_t x) +{ + /* Assign the correct byte position. */ + x = bswap32(x); + /* Assign the correct nibble position. */ + x = ((x & 0xf0f0f0f0u) >> 4) + | ((x & 0x0f0f0f0fu) << 4); + /* Assign the correct bit position. */ + x = ((x & 0x88888888u) >> 3) + | ((x & 0x44444444u) >> 1) + | ((x & 0x22222222u) << 1) + | ((x & 0x11111111u) << 3); + return x; +} + +/** + * revbit64 - reverse the bits in a 64-bit value. + * @x: The value to modify. + */ +static inline uint64_t revbit64(uint64_t x) +{ + /* Assign the correct byte position. */ + x = bswap64(x); + /* Assign the correct nibble position. */ + x = ((x & 0xf0f0f0f0f0f0f0f0ull) >> 4) + | ((x & 0x0f0f0f0f0f0f0f0full) << 4); + /* Assign the correct bit position. */ + x = ((x & 0x8888888888888888ull) >> 3) + | ((x & 0x4444444444444444ull) >> 1) + | ((x & 0x2222222222222222ull) << 1) + | ((x & 0x1111111111111111ull) << 3); + return x; +} + /* Host type specific sizes of these routines. */ #if ULONG_MAX == UINT32_MAX @@ -369,14 +471,48 @@ static inline int ctpop64(uint64_t val) # define clol clo32 # define ctol cto32 # define ctpopl ctpop32 +# define revbitl revbit32 #elif ULONG_MAX == UINT64_MAX # define clzl clz64 # define ctzl ctz64 # define clol clo64 # define ctol cto64 # define ctpopl ctpop64 +# define revbitl revbit64 #else # error Unknown sizeof long #endif +static inline bool is_power_of_2(uint64_t value) +{ + if (!value) { + return 0; + } + + return !(value & (value - 1)); +} + +/* round down to the nearest power of 2*/ +static inline int64_t pow2floor(int64_t value) +{ + if (!is_power_of_2(value)) { + value = 0x8000000000000000ULL >> clz64(value); + } + return value; +} + +/* round up to the nearest power of 2 (0 if overflow) */ +static inline uint64_t pow2ceil(uint64_t value) +{ + uint8_t nlz = clz64(value); + + if (is_power_of_2(value)) { + return value; + } + if (!nlz) { + return 0; + } + return 1ULL << (64 - nlz); +} + #endif