Program Listing for File BitOps.h#
↰ Return to documentation for file (src/util/StringUtility/BitOps.h)
#ifndef ROSE_BitOps_H
#define ROSE_BitOps_H
#include <cstddef>
#include "mlog.h"
namespace Rose {
namespace BitOps {
template<typename Unsigned>
inline size_t nBits(Unsigned x = Unsigned(0)) {
return 8*sizeof(Unsigned);
}
template<typename Unsigned>
inline Unsigned all(bool b = true) {
return Unsigned(0) - Unsigned(b ? 1 : 0);
}
template<typename Unsigned> inline Unsigned lowMask(size_t n);
template<typename Unsigned>
inline Unsigned allLsb(Unsigned src, size_t w, bool b = true) {
ASSERT_require(w <= nBits(src));
if (b) {
return src | lowMask<Unsigned>(w);
} else {
return src & ~lowMask<Unsigned>(w);
}
}
template<typename Unsigned>
inline Unsigned lowMask(size_t n) {
return n >= nBits<Unsigned>() ? all<Unsigned>(true) : (Unsigned(1) << n) - Unsigned(1);
}
template<typename Unsigned>
inline Unsigned highMask(size_t n) {
return n >= nBits<Unsigned>() ? all<Unsigned>(true) : lowMask<Unsigned>(n) << (nBits<Unsigned>() - n);
}
template<typename Unsigned>
inline Unsigned select(Unsigned cond, Unsigned a, Unsigned b) {
return (a & cond) | (b & ~cond);
}
template<typename Unsigned>
inline Unsigned shiftLeft(Unsigned src, size_t n, bool b = false) {
if (n >= nBits(src)) {
return all<Unsigned>(b);
} else {
return Unsigned(src << n) | (all<Unsigned>(b) & lowMask<Unsigned>(n));
}
}
template<typename Unsigned>
inline Unsigned shiftLeftLsb(Unsigned src, size_t w, size_t n, bool b = false) {
ASSERT_require(w <= nBits(src));
if (n >= w) {
return allLsb(src, w, b);
} else {
return select(lowMask<Unsigned>(w), shiftLeft(src, n, b), src);
}
}
template<typename Unsigned>
inline Unsigned shiftRight(Unsigned src, size_t n, bool b = false) {
if (n >= nBits(src)) {
return all<Unsigned>(b);
} else {
return Unsigned(src >> n) | (all<Unsigned>(b) & highMask<Unsigned>(n));
}
}
template<typename Unsigned>
inline Unsigned shiftRightLsb(Unsigned src, size_t w, size_t n, bool b = false) {
ASSERT_require(w <= nBits(src));
if (n >= w) {
return allLsb(src, w, b);
} else {
return select(lowMask<Unsigned>(w), shiftRight(src & lowMask<Unsigned>(w), n, b), src);
}
}
template<typename Unsigned>
inline Unsigned position(size_t i) {
return i < nBits<Unsigned>() ? shiftLeft(Unsigned(1), i) : Unsigned(0);
}
template<typename Unsigned>
inline Unsigned positionLsb(Unsigned src, size_t w, size_t i) {
ASSERT_require(w <= nBits(src));
return select(lowMask<Unsigned>(w), position<Unsigned>(i), src);
}
template<typename Unsigned>
inline Unsigned mask(size_t least, size_t greatest) {
ASSERT_require(greatest < nBits<Unsigned>());
ASSERT_require(greatest >= least);
return shiftLeft(lowMask<Unsigned>(greatest - least + 1), least);
}
template<typename Unsigned>
inline Unsigned maskLsb(Unsigned src, size_t w, size_t least, size_t greatest) {
ASSERT_require(w <= nBits(src));
return select(lowMask<Unsigned>(w), mask<Unsigned>(least, greatest), src);
}
template<typename Unsigned>
inline bool bit(Unsigned src, size_t i) {
return i < nBits(src) ? (src & position<Unsigned>(i)) != 0 : false;
}
template<typename Unsigned>
inline bool bitLsb(Unsigned src, size_t w, size_t i) {
return i < w ? (src & position<Unsigned>(i)) != 0 : false;
}
template<typename Unsigned>
inline bool msb(Unsigned src) {
return bit(src, nBits(src) - 1);
}
template<typename Unsigned>
inline bool msbLsb(Unsigned src, size_t w) {
ASSERT_require(w <= nBits(src));
return w > 0 ? bit(src, w-1) : false;
}
template<typename Unsigned>
inline Unsigned shiftRightSigned(Unsigned src, size_t n) {
return shiftRight(src, n, msb(src));
}
template<typename Unsigned>
inline Unsigned shiftRightSigned(Unsigned src, size_t w, size_t n) {
return shiftRightLsb(src, n, w, msbLsb(src, w));
}
template<typename Unsigned>
inline Unsigned bits(Unsigned src, size_t least, size_t greatest) {
return shiftRight(src & mask<Unsigned>(least, greatest), least);
}
template<typename Unsigned>
inline Unsigned bitsLsb(Unsigned src, size_t w, size_t least, size_t greatest) {
return shiftRight(src & mask<Unsigned>(least, greatest) & lowMask<Unsigned>(w), least);
}
template<typename UnsignedTarget, typename UnsignedSource>
inline UnsignedTarget convert(UnsignedSource x, bool b = false) {
if (nBits(x) < nBits<UnsignedTarget>()) {
// extending
return UnsignedTarget(x) | (all<UnsignedTarget>(b) & ~lowMask<UnsignedTarget>(nBits(x)));
} else {
// truncating
return UnsignedTarget(x & lowMask<UnsignedSource>(nBits<UnsignedTarget>()));
}
}
template<typename UnsignedTarget, typename UnsignedSource>
inline UnsignedTarget convertSigned(UnsignedSource x) {
return convert<UnsignedTarget>(x, msb(x));
}
template<typename Unsigned>
inline Unsigned signExtend(Unsigned src, size_t n) {
if (n < nBits(src)) {
if (msbLsb(src, n)) {
src |= mask<Unsigned>(n, nBits(src)-1);
} else {
src &= ~mask<Unsigned>(n, nBits(src)-1);
}
}
return src;
}
template<typename Unsigned>
inline Unsigned signExtendLsb(Unsigned src, size_t n, size_t m) {
ASSERT_require(n > 0);
ASSERT_require(m >= n);
ASSERT_require(m <= nBits(src));
if (m == n) {
return src;
} else {
Unsigned newBitsMask = mask<Unsigned>(n, m-1);
if (bit(src, n-1)) {
return src | newBitsMask;
} else {
return src & ~newBitsMask;
}
}
}
template<typename Unsigned>
inline Unsigned rotateLeft(Unsigned src, size_t n) {
n %= nBits(src);
return shiftLeft(src, n) | shiftRight(src, nBits(src)-n);
}
template<typename Unsigned>
inline Unsigned rotateLeftLsb(Unsigned src, size_t w, size_t n) {
ASSERT_require(w <= nBits(src));
n = w ? n % w : 0;
return select(lowMask<Unsigned>(w),
shiftLeftLsb(src, w, n) | shiftRightLsb(src, w-n),
src);
}
template<typename Unsigned>
inline Unsigned rotateRight(Unsigned src, size_t n) {
n %= nBits(src);
return shiftRight(src, n) | shiftLeft(src, nBits(src)-n);
}
template<typename Unsigned>
inline Unsigned rotateRightLsb(Unsigned src, size_t w, size_t n) {
ASSERT_require(w <= nBits(src));
n = w ? n % w : 0;
return select(lowMask<Unsigned>(w),
shiftRightLsb(src, w, n) | shiftLeftLsb(src, w, w-n),
src);
}
template<typename Unsigned>
inline Unsigned replicate(Unsigned src, size_t n) {
ASSERT_require(n != 0);
if (n >= nBits(src)) {
return src;
} else {
size_t ngroups = (nBits(src) + 1) / n;
Unsigned retval = 0;
for (size_t i = 0; i < ngroups; ++i)
retval |= shiftLeft(src & lowMask<Unsigned>(n), i*n);
return retval;
}
}
template<typename Unsigned>
inline Unsigned replicateLsb(Unsigned src, size_t w, size_t n) {
ASSERT_require(w <= nBits(src));
return select(lowMask<Unsigned>(w), replicate(src, n), src);
}
template<typename Unsigned>
inline size_t nSet(Unsigned src) {
size_t retval = 0;
while (src != 0) {
if ((src & 1) != 0)
++retval;
src >>= 1;
}
return retval;
}
} // namespace
} // namespace
#endif