Revision: 14681
Author:   [email protected]
Date:     Wed May 15 05:29:13 2013
Log:      Provide BitField64 utility class.

[email protected]
TEST=cctest/test-conversions/BitField64

Review URL: https://codereview.chromium.org/14643004
http://code.google.com/p/v8/source/detail?r=14681

Modified:
 /branches/bleeding_edge/src/utils.h
 /branches/bleeding_edge/test/cctest/test-conversions.cc

=======================================
--- /branches/bleeding_edge/src/utils.h Wed Apr 24 04:20:16 2013
+++ /branches/bleeding_edge/src/utils.h Wed May 15 05:29:13 2013
@@ -242,42 +242,52 @@
// ----------------------------------------------------------------------------
 // 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.

=======================================
--- /branches/bleeding_edge/test/cctest/test-conversions.cc Fri Apr 19 07:20:36 2013 +++ /branches/bleeding_edge/test/cctest/test-conversions.cc Wed May 15 05:29:13 2013
@@ -249,15 +249,13 @@
   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 @@
   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 @@
   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));
+}

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to