Revert "base: Add more bit utils and bit struct class"
Tests fail on device.
This reverts commit c60f75d6d6f229fa7b5494d54189e974883dafa2.
Change-Id: I2d8f919df154b700854d78993c460e3aab7cf0c3
diff --git a/runtime/Android.bp b/runtime/Android.bp
index ea776e7..711bc65 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -530,7 +530,6 @@
"barrier_test.cc",
"base/arena_allocator_test.cc",
"base/bit_field_test.cc",
- "base/bit_struct_test.cc",
"base/bit_utils_test.cc",
"base/bit_vector_test.cc",
"base/hash_set_test.cc",
diff --git a/runtime/base/bit_struct.h b/runtime/base/bit_struct.h
deleted file mode 100644
index 1f86ee1..0000000
--- a/runtime/base/bit_struct.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_BASE_BIT_STRUCT_H_
-#define ART_RUNTIME_BASE_BIT_STRUCT_H_
-
-#include "bit_struct_detail.h"
-#include "bit_utils.h"
-
-//
-// Zero-cost, type-safe, well-defined "structs" of bit fields.
-//
-// ---------------------------------------------
-// Usage example:
-// ---------------------------------------------
-//
-// // Definition for type 'Example'
-// BITSTRUCT_DEFINE_START(Example, 10)
-// BitStructUint<0, 2> u2; // Every field must be a BitStruct[*].
-// BitStructInt<2, 7> i7;
-// BitStructUint<9, 1> i1;
-// BITSTRUCT_DEFINE_END(Example);
-//
-// Would define a bit struct with this layout:
-// <- 1 -> <-- 7 --> <- 2 ->
-// +--------+---------------+-----+
-// | i1 | i7 | u2 +
-// +--------+---------------+-----+
-// 10 9 2 0
-//
-// // Read-write just like regular values.
-// Example ex;
-// ex.u2 = 3;
-// ex.i7 = -25;
-// ex.i1 = true;
-// size_t u2 = ex.u2;
-// int i7 = ex.i7;
-// bool i1 = ex.i1;
-//
-// // It's packed down to the smallest # of machine words.
-// assert(sizeof(Example) == 2);
-// // The exact bit pattern is well-defined by the template parameters.
-// uint16_t cast = *reinterpret_cast<uint16_t*>(ex);
-// assert(cast == ((3) | (0b100111 << 2) | (true << 9);
-//
-// ---------------------------------------------
-// Why not just use C++ bitfields?
-// ---------------------------------------------
-//
-// The layout is implementation-defined.
-// We do not know whether the fields are packed left-to-right or
-// right-to-left, so it makes it useless when the memory layout needs to be
-// precisely controlled.
-//
-// ---------------------------------------------
-// More info:
-// ---------------------------------------------
-// Currently uintmax_t is the largest supported underlying storage type,
-// all (kBitOffset + kBitWidth) must fit into BitSizeOf<uintmax_t>();
-//
-// Using BitStruct[U]int will automatically select an underlying type
-// that's the smallest to fit your (offset + bitwidth).
-//
-// BitStructNumber can be used to manually select an underlying type.
-//
-// BitStructField can be used with custom standard-layout structs,
-// thus allowing for arbitrary nesting of bit structs.
-//
-namespace art {
-// Zero-cost wrapper around a struct 'T', allowing it to be stored as a bitfield
-// at offset 'kBitOffset' and width 'kBitWidth'.
-// The storage is plain unsigned int, whose size is the smallest required to fit
-// 'kBitOffset + kBitWidth'. All operations to this become BitFieldExtract/BitFieldInsert
-// operations to the underlying uint.
-//
-// Field memory representation:
-//
-// MSB <-- width --> LSB
-// +--------+------------+--------+
-// | ?????? | u bitfield | ?????? +
-// +--------+------------+--------+
-// offset 0
-//
-// Reading/writing the bitfield (un)packs it into a temporary T:
-//
-// MSB <-- width --> LSB
-// +-----------------+------------+
-// | 0.............0 | T bitfield |
-// +-----------------+------------+
-// 0
-//
-// It's the responsibility of the StorageType to ensure the bit representation
-// of T can be represented by kBitWidth.
-template <typename T,
- size_t kBitOffset,
- size_t kBitWidth = BitStructSizeOf<T>(),
- typename StorageType = typename detail::MinimumTypeUnsignedHelper<kBitOffset + kBitWidth>::type>
-struct BitStructField {
- static_assert(std::is_standard_layout<T>::value, "T must be standard layout");
-
- operator T() const {
- return Get();
- }
-
- // Exclude overload when T==StorageType.
- template <typename _ = void,
- typename = std::enable_if_t<std::is_same<T, StorageType>::value, _>>
- explicit operator StorageType() const {
- return GetStorage();
- }
-
- BitStructField& operator=(T value) {
- return Assign(*this, value);
- }
-
- static constexpr size_t BitStructSizeOf() {
- return kBitWidth;
- }
-
- protected:
- template <typename T2>
- T2& Assign(T2& what, T value) {
- // Since C++ doesn't allow the type of operator= to change out
- // in the subclass, reimplement operator= in each subclass
- // manually and call this helper function.
- static_assert(std::is_base_of<BitStructField, T2>::value, "T2 must inherit BitStructField");
- what.Set(value);
- return what;
- }
-
- T Get() const {
- ValueStorage vs;
- vs.pod_.val_ = GetStorage();
- return vs.value_;
- }
-
- void Set(T value) {
- ValueStorage value_as_storage;
- value_as_storage.value_ = value;
-
- storage_.pod_.val_ = BitFieldInsert(storage_.pod_.val_,
- value_as_storage.pod_.val_,
- kBitOffset,
- kBitWidth);
- }
-
- private:
- StorageType GetStorage() const {
- return BitFieldExtract(storage_.pod_.val_, kBitOffset, kBitWidth);
- }
-
- // Underlying value must be wrapped in a separate standard-layout struct.
- // See below for more details.
- struct PodWrapper {
- StorageType val_;
- };
-
- union ValueStorage {
- // Safely alias pod_ and value_ together.
- //
- // See C++ 9.5.1 [class.union]:
- // If a standard-layout union contains several standard-layout structs that share a common
- // initial sequence ... it is permitted to inspect the common initial sequence of any of
- // standard-layout struct members.
- PodWrapper pod_;
- T value_;
- } storage_;
-
- // Future work: In theory almost non-standard layout can be supported here,
- // assuming they don't rely on the address of (this).
- // We just have to use memcpy since the union-aliasing would not work.
-};
-
-// Base class for number-like BitStruct fields.
-// T is the type to store in as a bit field.
-// kBitOffset, kBitWidth define the position and length of the bitfield.
-//
-// (Common usage should be BitStructInt, BitStructUint -- this
-// intermediate template allows a user-defined integer to be used.)
-template <typename T, size_t kBitOffset, size_t kBitWidth>
-struct BitStructNumber : public BitStructField<T, kBitOffset, kBitWidth, /*StorageType*/T> {
- using StorageType = T;
-
- BitStructNumber& operator=(T value) {
- return BaseType::Assign(*this, value);
- }
-
- /*implicit*/ operator T() const {
- return Get();
- }
-
- explicit operator bool() const {
- return static_cast<bool>(Get());
- }
-
- BitStructNumber& operator++() {
- *this = Get() + 1u;
- return *this;
- }
-
- StorageType operator++(int) {
- return Get() + 1u;
- }
-
- BitStructNumber& operator--() {
- *this = Get() - 1u;
- return *this;
- }
-
- StorageType operator--(int) {
- return Get() - 1u;
- }
-
- private:
- using BaseType = BitStructField<T, kBitOffset, kBitWidth, /*StorageType*/T>;
- using BaseType::Get;
-};
-
-// Create a BitStruct field which uses the smallest underlying int storage type,
-// in order to be large enough to fit (kBitOffset + kBitWidth).
-//
-// Values are sign-extended when they are read out.
-template <size_t kBitOffset, size_t kBitWidth>
-using BitStructInt =
- BitStructNumber<typename detail::MinimumTypeHelper<int, kBitOffset + kBitWidth>::type,
- kBitOffset,
- kBitWidth>;
-
-// Create a BitStruct field which uses the smallest underlying uint storage type,
-// in order to be large enough to fit (kBitOffset + kBitWidth).
-//
-// Values are zero-extended when they are read out.
-template <size_t kBitOffset, size_t kBitWidth>
-using BitStructUint =
- BitStructNumber<typename detail::MinimumTypeHelper<unsigned int, kBitOffset + kBitWidth>::type,
- kBitOffset,
- kBitWidth>;
-
-// Start a definition for a bitstruct.
-// A bitstruct is defined to be a union with a common initial subsequence
-// that we call 'DefineBitStructSize<bitwidth>'.
-//
-// See top of file for usage example.
-//
-// This marker is required by the C++ standard in order to
-// have a "common initial sequence".
-//
-// See C++ 9.5.1 [class.union]:
-// If a standard-layout union contains several standard-layout structs that share a common
-// initial sequence ... it is permitted to inspect the common initial sequence of any of
-// standard-layout struct members.
-#define BITSTRUCT_DEFINE_START(name, bitwidth) \
- union name { \
- art::detail::DefineBitStructSize<(bitwidth)> _; \
- static constexpr size_t BitStructSizeOf() { return (bitwidth); }
-
-// End the definition of a bitstruct, and insert a sanity check
-// to ensure that the bitstruct did not exceed the specified size.
-//
-// See top of file for usage example.
-#define BITSTRUCT_DEFINE_END(name) \
- }; /* NOLINT [readability/braces] [4] */ \
- static_assert(art::detail::ValidateBitStructSize<name>(), \
- #name "bitsize incorrect: " \
- "did you insert extra fields that weren't BitStructX, " \
- "and does the size match the sum of the field widths?")
-
-// Determine the minimal bit size for a user-defined type T.
-// Used by BitStructField to determine how small a custom type is.
-template <typename T>
-static constexpr size_t BitStructSizeOf() {
- return T::BitStructSizeOf();
-}
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_BIT_STRUCT_H_
diff --git a/runtime/base/bit_struct_detail.h b/runtime/base/bit_struct_detail.h
deleted file mode 100644
index 9f629c0..0000000
--- a/runtime/base/bit_struct_detail.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_BASE_BIT_STRUCT_DETAIL_H_
-#define ART_RUNTIME_BASE_BIT_STRUCT_DETAIL_H_
-
-#include "bit_utils.h"
-#include "globals.h"
-
-#include <type_traits>
-
-// Implementation details for bit_struct.h
-// Not intended to be used stand-alone.
-
-namespace art {
-
-template <typename T>
-static constexpr size_t BitStructSizeOf();
-
-namespace detail {
- // Select the smallest uintX_t that will fit kBitSize bits.
- template <size_t kBitSize>
- struct MinimumTypeUnsignedHelper {
- using type =
- typename std::conditional<kBitSize == 0, void,
- typename std::conditional<kBitSize <= 8, uint8_t,
- typename std::conditional<kBitSize <= 16, uint16_t,
- typename std::conditional<kBitSize <= 32, uint32_t,
- typename std::conditional<kBitSize <= 64, uint64_t,
- typename std::conditional<kBitSize <= BitSizeOf<uintmax_t>(), uintmax_t,
- void>::type>::type>::type>::type>::type>::type;
- };
-
- // Select the smallest [u]intX_t that will fit kBitSize bits.
- // Automatically picks intX_t or uintX_t based on the sign-ness of T.
- template <typename T, size_t kBitSize>
- struct MinimumTypeHelper {
- using type_unsigned = typename MinimumTypeUnsignedHelper<kBitSize>::type;
-
- using type =
- typename std::conditional</* if */ std::is_signed<T>::value,
- /* then */ typename std::make_signed<type_unsigned>::type,
- /* else */ type_unsigned>::type;
- };
-
- // Ensure the minimal type storage for 'T' matches its declared BitStructSizeOf.
- // Nominally used by the BITSTRUCT_DEFINE_END macro.
- template <typename T>
- static constexpr bool ValidateBitStructSize() {
- const size_t kBitStructSizeOf = BitStructSizeOf<T>();
- const size_t kExpectedSize = (BitStructSizeOf<T>() < kBitsPerByte)
- ? kBitsPerByte
- : RoundUpToPowerOfTwo(kBitStructSizeOf);
-
- // Ensure no extra fields were added in between START/END.
- const size_t kActualSize = sizeof(T) * kBitsPerByte;
- return kExpectedSize == kActualSize;
- }
-
- // Denotes the beginning of a bit struct.
- //
- // This marker is required by the C++ standard in order to
- // have a "common initial sequence".
- //
- // See C++ 9.5.1 [class.union]:
- // If a standard-layout union contains several standard-layout structs that share a common
- // initial sequence ... it is permitted to inspect the common initial sequence of any of
- // standard-layout struct members.
- template <size_t kSize>
- struct DefineBitStructSize {
- private:
- typename MinimumTypeUnsignedHelper<kSize>::type _;
- };
-} // namespace detail
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_BIT_STRUCT_DETAIL_H_
diff --git a/runtime/base/bit_struct_test.cc b/runtime/base/bit_struct_test.cc
deleted file mode 100644
index 949d631..0000000
--- a/runtime/base/bit_struct_test.cc
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "bit_struct.h"
-
-#include "gtest/gtest.h"
-
-namespace art {
-
-// A copy of detail::ValidateBitStructSize that uses EXPECT for a more
-// human-readable message.
-template <typename T>
-static constexpr bool ValidateBitStructSize(const char* name) {
- const size_t kBitStructSizeOf = BitStructSizeOf<T>();
- const size_t kExpectedSize = (BitStructSizeOf<T>() < kBitsPerByte)
- ? kBitsPerByte
- : RoundUpToPowerOfTwo(kBitStructSizeOf);
-
- // Ensure no extra fields were added in between START/END.
- const size_t kActualSize = sizeof(T) * kBitsPerByte;
- EXPECT_EQ(kExpectedSize, kActualSize) << name;
- return true;
-}
-
-#define VALIDATE_BITSTRUCT_SIZE(type) ValidateBitStructSize<type>(#type)
-
-TEST(BitStructs, MinimumType) {
- EXPECT_EQ(1u, sizeof(typename detail::MinimumTypeUnsignedHelper<1>::type));
- EXPECT_EQ(1u, sizeof(typename detail::MinimumTypeUnsignedHelper<2>::type));
- EXPECT_EQ(1u, sizeof(typename detail::MinimumTypeUnsignedHelper<3>::type));
- EXPECT_EQ(1u, sizeof(typename detail::MinimumTypeUnsignedHelper<8>::type));
- EXPECT_EQ(2u, sizeof(typename detail::MinimumTypeUnsignedHelper<9>::type));
- EXPECT_EQ(2u, sizeof(typename detail::MinimumTypeUnsignedHelper<10>::type));
- EXPECT_EQ(2u, sizeof(typename detail::MinimumTypeUnsignedHelper<15>::type));
- EXPECT_EQ(2u, sizeof(typename detail::MinimumTypeUnsignedHelper<16>::type));
- EXPECT_EQ(4u, sizeof(typename detail::MinimumTypeUnsignedHelper<17>::type));
- EXPECT_EQ(4u, sizeof(typename detail::MinimumTypeUnsignedHelper<32>::type));
- EXPECT_EQ(8u, sizeof(typename detail::MinimumTypeUnsignedHelper<33>::type));
- EXPECT_EQ(8u, sizeof(typename detail::MinimumTypeUnsignedHelper<64>::type));
-}
-
-template <typename T>
-size_t AsUint(const T& value) {
- size_t uint_value = 0;
- memcpy(&uint_value, &value, sizeof(value));
- return uint_value;
-}
-
-struct CustomBitStruct {
- CustomBitStruct() = default;
- explicit CustomBitStruct(int8_t data) : data(data) {}
-
- static constexpr size_t BitStructSizeOf() {
- return 4;
- }
-
- int8_t data;
-};
-
-TEST(BitStructs, Custom) {
- CustomBitStruct expected(0b1111);
-
- BitStructField<CustomBitStruct, /*lsb*/4, /*width*/4> f;
-
- EXPECT_EQ(1u, sizeof(f));
-
- f = CustomBitStruct(0b1111);
-
- CustomBitStruct read_out = f;
- EXPECT_EQ(read_out.data, 0b1111);
-
- EXPECT_EQ(AsUint(f), 0b11110000u);
-}
-
-BITSTRUCT_DEFINE_START(TestTwoCustom, /* size */ 8)
- BitStructField<CustomBitStruct, /*lsb*/0, /*width*/4> f4_a;
- BitStructField<CustomBitStruct, /*lsb*/4, /*width*/4> f4_b;
-BITSTRUCT_DEFINE_END(TestTwoCustom);
-
-TEST(BitStructs, TwoCustom) {
- EXPECT_EQ(sizeof(TestTwoCustom), 1u);
-
- VALIDATE_BITSTRUCT_SIZE(TestTwoCustom);
-
- TestTwoCustom cst;
- // Test the write to most-significant field doesn't clobber least-significant.
- cst.f4_a = CustomBitStruct(0b0110);
- cst.f4_b = CustomBitStruct(0b0101);
-
- int8_t read_out = static_cast<CustomBitStruct>(cst.f4_a).data;
- int8_t read_out_b = static_cast<CustomBitStruct>(cst.f4_b).data;
-
- EXPECT_EQ(0b0110, static_cast<int>(read_out));
- EXPECT_EQ(0b0101, static_cast<int>(read_out_b));
-
- EXPECT_EQ(AsUint(cst), 0b01010110u);
-
- // Test write to least-significant field doesn't clobber most-significant.
- cst.f4_a = CustomBitStruct(0);
-
- read_out = static_cast<CustomBitStruct>(cst.f4_a).data;
- read_out_b = static_cast<CustomBitStruct>(cst.f4_b).data;
-
- EXPECT_EQ(0b0, static_cast<int>(read_out));
- EXPECT_EQ(0b0101, static_cast<int>(read_out_b));
-
- EXPECT_EQ(AsUint(cst), 0b01010000u);
-}
-
-TEST(BitStructs, Number) {
- BitStructNumber<uint16_t, /*lsb*/4, /*width*/4> bsn;
- EXPECT_EQ(2u, sizeof(bsn));
-
- bsn = 0b1111;
-
- uint32_t read_out = static_cast<uint32_t>(bsn);
- uint32_t read_out_impl = bsn;
-
- EXPECT_EQ(read_out, read_out_impl);
- EXPECT_EQ(read_out, 0b1111u);
- EXPECT_EQ(AsUint(bsn), 0b11110000u);
-}
-
-BITSTRUCT_DEFINE_START(TestBitStruct, /* size */ 8)
- BitStructInt</*lsb*/0, /*width*/3> i3;
- BitStructUint</*lsb*/3, /*width*/4> u4;
-
- BitStructUint</*lsb*/0, /*width*/7> alias_all;
-BITSTRUCT_DEFINE_END(TestBitStruct);
-
-TEST(BitStructs, Test1) {
- {
- // Check minimal size selection is correct.
- BitStructInt</*lsb*/0, /*width*/3> i3;
- BitStructUint</*lsb*/3, /*width*/4> u4;
-
- BitStructUint</*lsb*/0, /*width*/7> alias_all;
-
- EXPECT_EQ(1u, sizeof(i3));
- EXPECT_EQ(1u, sizeof(u4));
- EXPECT_EQ(1u, sizeof(alias_all));
- }
- TestBitStruct tst;
-
- // Check minimal size selection is correct.
- EXPECT_EQ(1u, sizeof(TestBitStruct));
- EXPECT_EQ(1u, sizeof(tst._));
- EXPECT_EQ(1u, sizeof(tst.i3));
- EXPECT_EQ(1u, sizeof(tst.u4));
- EXPECT_EQ(1u, sizeof(tst.alias_all));
-
- // Check operator assignment.
- tst.i3 = -1;
- tst.u4 = 0b1010;
-
- // Check implicit operator conversion.
- int8_t read_i3 = tst.i3;
- uint8_t read_u4 = tst.u4;
-
- // Ensure read-out values were correct.
- EXPECT_EQ(static_cast<int8_t>(-1), read_i3);
- EXPECT_EQ(0b1010, read_u4);
-
- // Ensure aliasing is working.
- EXPECT_EQ(0b1010111, static_cast<uint8_t>(tst.alias_all));
-
- // Ensure the bit pattern is correct.
- EXPECT_EQ(0b1010111u, AsUint(tst));
-
- // Math operator checks
- {
- // In-place
- ++tst.u4;
- EXPECT_EQ(static_cast<uint8_t>(0b1011), static_cast<uint8_t>(tst.u4));
- --tst.u4;
- EXPECT_EQ(static_cast<uint8_t>(0b1010), static_cast<uint8_t>(tst.u4));
-
- // Copy
- uint8_t read_and_convert = tst.u4++;
- EXPECT_EQ(static_cast<uint8_t>(0b1011), read_and_convert);
- EXPECT_EQ(static_cast<uint8_t>(0b1010), static_cast<uint8_t>(tst.u4));
- read_and_convert = tst.u4--;
- EXPECT_EQ(static_cast<uint8_t>(0b1001), read_and_convert);
- EXPECT_EQ(static_cast<uint8_t>(0b1010), static_cast<uint8_t>(tst.u4));
-
- // Check boolean operator conversion.
- tst.u4 = 0b1010;
- EXPECT_TRUE(static_cast<bool>(tst.u4));
- bool succ = tst.u4 ? true : false;
- EXPECT_TRUE(succ);
-
- tst.u4 = 0;
- EXPECT_FALSE(static_cast<bool>(tst.u4));
-
-/*
- // Disabled: Overflow is caught by the BitFieldInsert DCHECKs.
- // Check overflow for uint.
- tst.u4 = 0b1111;
- ++tst.u4;
- EXPECT_EQ(static_cast<uint8_t>(0), static_cast<uint8_t>(tst.u4));
-*/
- }
-}
-
-BITSTRUCT_DEFINE_START(MixedSizeBitStruct, /* size */ 32)
- BitStructUint</*lsb*/0, /*width*/3> u3;
- BitStructUint</*lsb*/3, /*width*/10> u10;
- BitStructUint</*lsb*/13, /*width*/19> u19;
-
- BitStructUint</*lsb*/0, /*width*/32> alias_all;
-BITSTRUCT_DEFINE_END(MixedSizeBitStruct);
-
-// static_assert(sizeof(MixedSizeBitStruct) == sizeof(uint32_t), "TestBitStructs#MixedSize");
-
-TEST(BitStructs, Mixed) {
- EXPECT_EQ(4u, sizeof(MixedSizeBitStruct));
-
- MixedSizeBitStruct tst;
-
- // Check operator assignment.
- tst.u3 = 0b111u;
- tst.u10 = 0b1111010100u;
- tst.u19 = 0b1010101010101010101u;
-
- // Check implicit operator conversion.
- uint8_t read_u3 = tst.u3;
- uint16_t read_u10 = tst.u10;
- uint32_t read_u19 = tst.u19;
-
- // Ensure read-out values were correct.
- EXPECT_EQ(0b111u, read_u3);
- EXPECT_EQ(0b1111010100u, read_u10);
- EXPECT_EQ(0b1010101010101010101u, read_u19);
-
- uint32_t read_all = tst.alias_all;
-
- // Ensure aliasing is working.
- EXPECT_EQ(0b10101010101010101011111010100111u, read_all);
-
- // Ensure the bit pattern is correct.
- EXPECT_EQ(0b10101010101010101011111010100111u, AsUint(tst));
-}
-
-} // namespace art
diff --git a/runtime/base/bit_utils.h b/runtime/base/bit_utils.h
index da3c704..87dac02 100644
--- a/runtime/base/bit_utils.h
+++ b/runtime/base/bit_utils.h
@@ -371,128 +371,6 @@
return opnd;
}
-// Create a mask for the least significant "bits"
-// The returned value is always unsigned to prevent undefined behavior for bitwise ops.
-//
-// Given 'bits',
-// Returns:
-// <--- bits --->
-// +-----------------+------------+
-// | 0 ............0 | 1.....1 |
-// +-----------------+------------+
-// msb lsb
-template <typename T = size_t>
-inline static constexpr std::make_unsigned_t<T> MaskLeastSignificant(size_t bits) {
- DCHECK_GE(BitSizeOf<T>(), bits) << "Bits out of range for type T";
- using unsigned_T = std::make_unsigned_t<T>;
- if (bits >= BitSizeOf<T>()) {
- return std::numeric_limits<unsigned_T>::max();
- } else {
- return static_cast<unsigned_T>((1 << bits) - 1);
- }
-}
-
-// Clears the bitfield starting at the least significant bit "lsb" with a bitwidth of 'width'.
-// (Equivalent of ARM BFC instruction).
-//
-// Given:
-// <-- width -->
-// +--------+------------+--------+
-// | ABC... | bitfield | XYZ... +
-// +--------+------------+--------+
-// lsb 0
-// Returns:
-// <-- width -->
-// +--------+------------+--------+
-// | ABC... | 0........0 | XYZ... +
-// +--------+------------+--------+
-// lsb 0
-template <typename T>
-inline static constexpr T BitFieldClear(T value, size_t lsb, size_t width) {
- DCHECK_GE(BitSizeOf(value), lsb + width) << "Bit field out of range for value";
- const auto val = static_cast<std::make_unsigned_t<T>>(value);
- const auto mask = MaskLeastSignificant<T>(width);
-
- return static_cast<T>(val & ~(mask << lsb));
-}
-
-// Inserts the contents of 'data' into bitfield of 'value' starting
-// at the least significant bit "lsb" with a bitwidth of 'width'.
-// Note: data must be within range of [MinInt(width), MaxInt(width)].
-// (Equivalent of ARM BFI instruction).
-//
-// Given (data):
-// <-- width -->
-// +--------+------------+--------+
-// | ABC... | bitfield | XYZ... +
-// +--------+------------+--------+
-// lsb 0
-// Returns:
-// <-- width -->
-// +--------+------------+--------+
-// | ABC... | 0...data | XYZ... +
-// +--------+------------+--------+
-// lsb 0
-
-template <typename T, typename T2>
-inline static constexpr T BitFieldInsert(T value, T2 data, size_t lsb, size_t width) {
- DCHECK_GE(BitSizeOf(value), lsb + width) << "Bit field out of range for value";
- if (width != 0u) {
- DCHECK_GE(MaxInt<T2>(width), data) << "Data out of range [too large] for bitwidth";
- DCHECK_LE(MinInt<T2>(width), data) << "Data out of range [too small] for bitwidth";
- } else {
- DCHECK_EQ(static_cast<T2>(0), data) << "Data out of range [nonzero] for bitwidth 0";
- }
- const auto data_mask = MaskLeastSignificant<T2>(width);
- const auto value_cleared = BitFieldClear(value, lsb, width);
-
- return static_cast<T>(value_cleared | ((data & data_mask) << lsb));
-}
-
-// Extracts the bitfield starting at the least significant bit "lsb" with a bitwidth of 'width'.
-// Signed types are sign-extended during extraction. (Equivalent of ARM UBFX/SBFX instruction).
-//
-// Given:
-// <-- width -->
-// +--------+-------------+-------+
-// | | bitfield | +
-// +--------+-------------+-------+
-// lsb 0
-// (Unsigned) Returns:
-// <-- width -->
-// +----------------+-------------+
-// | 0... 0 | bitfield |
-// +----------------+-------------+
-// 0
-// (Signed) Returns:
-// <-- width -->
-// +----------------+-------------+
-// | S... S | bitfield |
-// +----------------+-------------+
-// 0
-// where S is the highest bit in 'bitfield'.
-template <typename T>
-inline static constexpr T BitFieldExtract(T value, size_t lsb, size_t width) {
- DCHECK_GE(BitSizeOf(value), lsb + width) << "Bit field out of range for value";
- const auto val = static_cast<std::make_unsigned_t<T>>(value);
-
- const T bitfield_unsigned =
- static_cast<T>((val >> lsb) & MaskLeastSignificant<T>(width));
- if (std::is_signed<T>::value) {
- // Perform sign extension
- if (width == 0) { // Avoid underflow.
- return static_cast<T>(0);
- } else if (bitfield_unsigned & (1 << (width - 1))) { // Detect if sign bit was set.
- // MSB <width> LSB
- // 0b11111...100...000000
- const auto ones_negmask = ~MaskLeastSignificant<T>(width);
- return static_cast<T>(bitfield_unsigned | ones_negmask);
- }
- }
- // Skip sign extension.
- return bitfield_unsigned;
-}
-
} // namespace art
#endif // ART_RUNTIME_BASE_BIT_UTILS_H_
diff --git a/runtime/base/bit_utils_test.cc b/runtime/base/bit_utils_test.cc
index 0276d8d..c96c6dc 100644
--- a/runtime/base/bit_utils_test.cc
+++ b/runtime/base/bit_utils_test.cc
@@ -345,97 +345,6 @@
"TestIsAbsoluteUint64#27");
static_assert(!IsAbsoluteUint<32, int64_t>(kUint32MaxPlus1), "TestIsAbsoluteUint64#28");
-static_assert(MaskLeastSignificant(0) == 0b0, "TestMaskLeastSignificant#1");
-static_assert(MaskLeastSignificant(1) == 0b1, "TestMaskLeastSignificant#2");
-static_assert(MaskLeastSignificant(2) == 0b11, "TestMaskLeastSignificant#3");
-static_assert(MaskLeastSignificant<uint8_t>(8) == 0xFF, "TestMaskLeastSignificant#4");
-static_assert(MaskLeastSignificant<int8_t>(8) == 0xFF, "TestMaskLeastSignificant#5");
-
-static_assert(BitFieldClear(0xFF, /*lsb*/0, /*width*/0) == 0xFF, "TestBitFieldClear#1");
-static_assert(BitFieldClear(std::numeric_limits<uint32_t>::max(), /*lsb*/0, /*width*/32) == 0x0,
- "TestBitFieldClear#2");
-static_assert(BitFieldClear(std::numeric_limits<int32_t>::max(), /*lsb*/0, /*width*/32) == 0x0,
- "TestBitFieldClear#3");
-static_assert(BitFieldClear(0xFF, /*lsb*/0, /*width*/2) == 0b11111100, "TestBitFieldClear#4");
-static_assert(BitFieldClear(0xFF, /*lsb*/0, /*width*/3) == 0b11111000, "TestBitFieldClear#5");
-static_assert(BitFieldClear(0xFF, /*lsb*/1, /*width*/3) == 0b11110001, "TestBitFieldClear#6");
-static_assert(BitFieldClear(0xFF, /*lsb*/2, /*width*/3) == 0b11100011, "TestBitFieldClear#7");
-
-static_assert(BitFieldExtract(0xFF, /*lsb*/0, /*width*/0) == 0x0, "TestBitFieldExtract#1");
-static_assert(BitFieldExtract(std::numeric_limits<uint32_t>::max(), /*lsb*/0, /*width*/32)
- == std::numeric_limits<uint32_t>::max(),
- "TestBitFieldExtract#2");
-static_assert(BitFieldExtract(std::numeric_limits<int32_t>::max(), /*lsb*/0, /*width*/32)
- == std::numeric_limits<int32_t>::max(),
- "TestBitFieldExtract#3");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/0, /*width*/2) == 0b00000011,
- "TestBitFieldExtract#4");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/0, /*width*/3) == 0b00000111,
- "TestBitFieldExtract#5");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/1, /*width*/3) == 0b00000111,
- "TestBitFieldExtract#6");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/2, /*width*/3) == 0b00000111,
- "TestBitFieldExtract#7");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/3, /*width*/3) == 0b00000111,
- "TestBitFieldExtract#8");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/8, /*width*/3) == 0b00000000,
- "TestBitFieldExtract#9");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/7, /*width*/3) == 0b00000001,
- "TestBitFieldExtract#10");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/6, /*width*/3) == 0b00000011,
- "TestBitFieldExtract#11");
-static_assert(BitFieldExtract(0xFF, /*lsb*/0, /*width*/2) == -1, "TestBitFieldExtract#12");
-static_assert(BitFieldExtract(0xFF, /*lsb*/0, /*width*/3) == -1, "TestBitFieldExtract#13");
-static_assert(BitFieldExtract(0xFF, /*lsb*/1, /*width*/3) == -1, "TestBitFieldExtract#14");
-static_assert(BitFieldExtract(0xFF, /*lsb*/2, /*width*/3) == -1, "TestBitFieldExtract#15");
-static_assert(BitFieldExtract(0xFF, /*lsb*/3, /*width*/3) == -1, "TestBitFieldExtract#16");
-static_assert(BitFieldExtract(0xFF, /*lsb*/8, /*width*/3) == 0b00000000, "TestBitFieldExtract#17");
-static_assert(BitFieldExtract(0xFF, /*lsb*/7, /*width*/3) == 0b00000001, "TestBitFieldExtract#18");
-static_assert(BitFieldExtract(0xFF, /*lsb*/6, /*width*/3) == 0b00000011, "TestBitFieldExtract#19");
-static_assert(BitFieldExtract(static_cast<uint8_t>(0b01101010), /*lsb*/2, /*width*/4)
- == 0b00001010,
- "TestBitFieldExtract#20");
-static_assert(BitFieldExtract(static_cast<int8_t>(0b01101010), /*lsb*/2, /*width*/4)
- == static_cast<int8_t>(0b11111010),
- "TestBitFieldExtract#21");
-
-static_assert(BitFieldInsert(0xFF, /*data*/0x0, /*lsb*/0, /*width*/0) == 0xFF,
- "TestBitFieldInsert#1");
-static_assert(BitFieldInsert(std::numeric_limits<uint32_t>::max(),
- /*data*/std::numeric_limits<uint32_t>::max(),
- /*lsb*/0,
- /*width*/32)
- == std::numeric_limits<uint32_t>::max(),
- "TestBitFieldInsert#2");
-static_assert(BitFieldInsert(std::numeric_limits<int32_t>::max(),
- /*data*/std::numeric_limits<uint32_t>::max(),
- /*lsb*/0,
- /*width*/32)
- == std::numeric_limits<uint32_t>::max(),
- "TestBitFieldInsert#3");
-static_assert(BitFieldInsert(0u,
- /*data*/std::numeric_limits<uint32_t>::max(),
- /*lsb*/0,
- /*width*/32)
- == std::numeric_limits<uint32_t>::max(),
- "TestBitFieldInsert#4");
-static_assert(BitFieldInsert(-(-0),
- /*data*/std::numeric_limits<uint32_t>::max(),
- /*lsb*/0,
- /*width*/32)
- == std::numeric_limits<uint32_t>::max(),
- "TestBitFieldInsert#5");
-static_assert(BitFieldInsert(0x00, /*data*/0b11u, /*lsb*/0, /*width*/2) == 0b00000011,
- "TestBitFieldInsert#6");
-static_assert(BitFieldInsert(0x00, /*data*/0b111u, /*lsb*/0, /*width*/3) == 0b00000111,
- "TestBitFieldInsert#7");
-static_assert(BitFieldInsert(0x00, /*data*/0b111u, /*lsb*/1, /*width*/3) == 0b00001110,
- "TestBitFieldInsert#8");
-static_assert(BitFieldInsert(0x00, /*data*/0b111u, /*lsb*/2, /*width*/3) == 0b00011100,
- "TestBitFieldInsert#9");
-static_assert(BitFieldInsert(0b01011100, /*data*/0b1101u, /*lsb*/4, /*width*/4) == 0b11011100,
- "TestBitFieldInsert#10");
-
template <typename Container>
void CheckElements(const std::initializer_list<uint32_t>& expected, const Container& elements) {
auto expected_it = expected.begin();