From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51339) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YPtXU-0007Dv-OO for qemu-devel@nongnu.org; Mon, 23 Feb 2015 08:59:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YPtXR-0001if-H9 for qemu-devel@nongnu.org; Mon, 23 Feb 2015 08:59:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:60011) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YPtXR-0001iX-8W for qemu-devel@nongnu.org; Mon, 23 Feb 2015 08:59:09 -0500 From: Markus Armbruster References: <1424694237-22786-1-git-send-email-aik@ozlabs.ru> Date: Mon, 23 Feb 2015 14:59:00 +0100 In-Reply-To: <1424694237-22786-1-git-send-email-aik@ozlabs.ru> (Alexey Kardashevskiy's message of "Mon, 23 Feb 2015 23:23:57 +1100") Message-ID: <877fv8sp97.fsf@blackfin.pond.sub.org> MIME-Version: 1.0 Content-Type: text/plain Subject: Re: [Qemu-devel] [PATCH v2] utils: Add pow2ceil() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexey Kardashevskiy Cc: Peter Maydell , qemu-devel@nongnu.org Alexey Kardashevskiy writes: > This adds a helper to get closest bigger power-of-two value. > > Signed-off-by: Alexey Kardashevskiy > --- > Changes: > v2: > * s/up_pow_of_two/pow2ceil/ > --- > include/qemu-common.h | 2 ++ > util/cutils.c | 9 +++++++++ > 2 files changed, 11 insertions(+) > > diff --git a/include/qemu-common.h b/include/qemu-common.h > index 644b46d..ae29748 100644 > --- a/include/qemu-common.h > +++ b/include/qemu-common.h > @@ -417,6 +417,8 @@ static inline bool is_power_of_2(uint64_t value) > > /* round down to the nearest power of 2*/ > int64_t pow2floor(int64_t value); > +/* round up to the nearest power of 2*/ > +int64_t pow2ceil(int64_t value); > > #include "qemu/module.h" > > diff --git a/util/cutils.c b/util/cutils.c > index dbe7412..ecaa440 100644 > --- a/util/cutils.c > +++ b/util/cutils.c > @@ -483,6 +483,15 @@ int64_t pow2floor(int64_t value) > return value; > } > > +/* round up to the nearest power of 2*/ > +int64_t pow2ceil(int64_t value) > +{ > + if (!is_power_of_2(value)) { > + value = 0x8000000000000000ULL >> (clz64(value) - 1); > + } > + return value; > +} > + > /* > * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128) > * Input is limited to 14-bit numbers pow2ceil(INT64_MIN) = INT64_MIN. Should be 1. pow2ceil(INT64_MAX) = INT64_MIN. Garbage. Related: "round down to the nearest power of 2" is defined only for x > 0, but our pow2floor(x) happily returns garbage then. In particular we return 0x8000000000000000ULL >> 64 when value is 0,. Undefined behavior. Here's how I'd do these functions: int64_t pow2floor(int64_t value) { assert(value > 0); return 0x8000000000000000u >> clz64(value); } int64_t pow2ceil(int64_t value) { assert(value <= 0x4000000000000000) if (value <= 1) return 1; return 0x8000000000000000u >> (clz64(value - 1) - 1); }