blob: 5c81e5c8ae3e73ad05b2fb265247c0bd0685ee50 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2008-2014 Travis Geiselbrecht
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#ifndef ZIRCON_KERNEL_INCLUDE_POW2_H_
#define ZIRCON_KERNEL_INCLUDE_POW2_H_
#include <stdint.h>
#include <sys/types.h>
#include <ktl/bit.h>
constexpr bool ispow2(uint val) { return val == 0 || cpp20::has_single_bit(val); }
// Compute floor(log2(|val|)), or 0 if |val| is 0
template <typename T>
constexpr T log2_floor(T val) {
return val == 0 ? 0 : cpp20::bit_width(val) - 1;
}
constexpr uint log2_uint_floor(uint val) { return log2_floor(val); }
constexpr ulong log2_ulong_floor(ulong val) { return log2_floor(val); }
// Compute ceil(log2(|val|)), or 0 if |val| is 0
template <typename T>
constexpr T log2_ceil(T val) {
T log2 = log2_floor(val);
if (val != 0 && val != (static_cast<T>(1) << log2)) {
++log2;
}
return log2;
}
constexpr uint log2_uint_ceil(uint val) { return log2_ceil(val); }
constexpr ulong log2_ulong_ceil(ulong val) { return log2_ceil(val); }
template <typename T>
constexpr T valpow2(T valp2) {
return static_cast<T>(1) << valp2;
}
constexpr uint divpow2(uint val, uint divp2) { return val >> divp2; }
constexpr uint modpow2(uint val, uint modp2) { return val & ((1U << modp2) - 1); }
constexpr uint64_t modpow2_u64(uint64_t val, uint modp2) { return val & ((1U << modp2) - 1); }
constexpr uint32_t round_up_pow2_u32(uint32_t v) {
return (v == 0 || v > (1u << 31)) ? 0u : cpp20::bit_ceil(v);
}
#endif // ZIRCON_KERNEL_INCLUDE_POW2_H_