Provide BitField64 utility class.
R=svenpanne@chromium.org TEST=cctest/test-conversions/BitField64 Review URL: https://codereview.chromium.org/14643004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14681 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
a025371c4a
commit
3d5b800943
40
src/utils.h
40
src/utils.h
@ -242,42 +242,52 @@ inline int StrLength(const char* string) {
|
||||
// ----------------------------------------------------------------------------
|
||||
// BitField is a help template for encoding and decode bitfield with
|
||||
// unsigned content.
|
||||
template<class T, int shift, int size>
|
||||
class BitField {
|
||||
|
||||
template<class T, int shift, int size, class U>
|
||||
class BitFieldBase {
|
||||
public:
|
||||
// A uint32_t mask of bit field. To use all bits of a uint32 in a
|
||||
// bitfield without compiler warnings we have to compute 2^32 without
|
||||
// using a shift count of 32.
|
||||
static const uint32_t kMask = ((1U << shift) << size) - (1U << shift);
|
||||
static const uint32_t kShift = shift;
|
||||
static const uint32_t kSize = size;
|
||||
// A type U mask of bit field. To use all bits of a type U of x bits
|
||||
// in a bitfield without compiler warnings we have to compute 2^x
|
||||
// without using a shift count of x in the computation.
|
||||
static const U kOne = static_cast<U>(1U);
|
||||
static const U kMask = ((kOne << shift) << size) - (kOne << shift);
|
||||
static const U kShift = shift;
|
||||
static const U kSize = size;
|
||||
|
||||
// Value for the field with all bits set.
|
||||
static const T kMax = static_cast<T>((1U << size) - 1);
|
||||
|
||||
// Tells whether the provided value fits into the bit field.
|
||||
static bool is_valid(T value) {
|
||||
return (static_cast<uint32_t>(value) & ~static_cast<uint32_t>(kMax)) == 0;
|
||||
return (static_cast<U>(value) & ~static_cast<U>(kMax)) == 0;
|
||||
}
|
||||
|
||||
// Returns a uint32_t with the bit field value encoded.
|
||||
static uint32_t encode(T value) {
|
||||
// Returns a type U with the bit field value encoded.
|
||||
static U encode(T value) {
|
||||
ASSERT(is_valid(value));
|
||||
return static_cast<uint32_t>(value) << shift;
|
||||
return static_cast<U>(value) << shift;
|
||||
}
|
||||
|
||||
// Returns a uint32_t with the bit field value updated.
|
||||
static uint32_t update(uint32_t previous, T value) {
|
||||
// Returns a type U with the bit field value updated.
|
||||
static U update(U previous, T value) {
|
||||
return (previous & ~kMask) | encode(value);
|
||||
}
|
||||
|
||||
// Extracts the bit field from the value.
|
||||
static T decode(uint32_t value) {
|
||||
static T decode(U value) {
|
||||
return static_cast<T>((value & kMask) >> shift);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class T, int shift, int size>
|
||||
class BitField : public BitFieldBase<T, shift, size, uint32_t> { };
|
||||
|
||||
|
||||
template<class T, int shift, int size>
|
||||
class BitField64 : public BitFieldBase<T, shift, size, uint64_t> { };
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Hash function.
|
||||
|
||||
|
@ -249,15 +249,13 @@ TEST(ExponentNumberStr) {
|
||||
CHECK_EQ(1e-106, StringToDouble(&uc, ".000001e-100", NO_FLAGS));
|
||||
}
|
||||
|
||||
class OneBit1: public BitField<uint32_t, 0, 1> {};
|
||||
class OneBit2: public BitField<uint32_t, 7, 1> {};
|
||||
class EightBit1: public BitField<uint32_t, 0, 8> {};
|
||||
class EightBit2: public BitField<uint32_t, 13, 8> {};
|
||||
|
||||
TEST(BitField) {
|
||||
uint32_t x;
|
||||
|
||||
// One bit bit field can hold values 0 and 1.
|
||||
class OneBit1: public BitField<uint32_t, 0, 1> {};
|
||||
class OneBit2: public BitField<uint32_t, 7, 1> {};
|
||||
CHECK(!OneBit1::is_valid(static_cast<uint32_t>(-1)));
|
||||
CHECK(!OneBit2::is_valid(static_cast<uint32_t>(-1)));
|
||||
for (int i = 0; i < 2; i++) {
|
||||
@ -273,6 +271,8 @@ TEST(BitField) {
|
||||
CHECK(!OneBit2::is_valid(2));
|
||||
|
||||
// Eight bit bit field can hold values from 0 tp 255.
|
||||
class EightBit1: public BitField<uint32_t, 0, 8> {};
|
||||
class EightBit2: public BitField<uint32_t, 13, 8> {};
|
||||
CHECK(!EightBit1::is_valid(static_cast<uint32_t>(-1)));
|
||||
CHECK(!EightBit2::is_valid(static_cast<uint32_t>(-1)));
|
||||
for (int i = 0; i < 256; i++) {
|
||||
@ -286,3 +286,20 @@ TEST(BitField) {
|
||||
CHECK(!EightBit1::is_valid(256));
|
||||
CHECK(!EightBit2::is_valid(256));
|
||||
}
|
||||
|
||||
|
||||
TEST(BitField64) {
|
||||
uint64_t x;
|
||||
|
||||
// Test most significant bits.
|
||||
class UpperBits: public BitField64<int, 61, 3> {};
|
||||
x = V8_2PART_UINT64_C(0xE0000000, 00000000);
|
||||
CHECK(x == UpperBits::encode(7));
|
||||
CHECK_EQ(7, UpperBits::decode(x));
|
||||
|
||||
// Test the 32/64-bit boundary bits.
|
||||
class MiddleBits: public BitField64<int, 31, 2> {};
|
||||
x = V8_2PART_UINT64_C(0x00000001, 80000000);
|
||||
CHECK(x == MiddleBits::encode(3));
|
||||
CHECK_EQ(3, MiddleBits::decode(x));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user