79#ifndef LLVM_ADT_BITFIELDS_H
80#define LLVM_ADT_BITFIELDS_H
97template <
typename Bitfield,
typename StorageType>
struct Impl {
98 static_assert(std::is_unsigned<StorageType>::value,
99 "Storage must be unsigned");
102 static constexpr size_t StorageBits =
sizeof(StorageType) * CHAR_BIT;
103 static_assert(Bitfield::FirstBit <
StorageBits,
"Data must fit in mask");
104 static_assert(Bitfield::LastBit <
StorageBits,
"Data must fit in mask");
111 assert(UserValue <= UserMaxValue &&
"value is too big");
112 if constexpr (std::is_unsigned_v<IntegerType>) {
115 static_assert(std::is_signed_v<IntegerType>,
116 "IntegerType must be signed");
124 checkValue(UserValue, Bitfield::UserMaxValue);
125 const StorageType StorageValue = UserValue &
LowMask;
127 Packed |= StorageValue << Bitfield::Shift;
133 const StorageType StorageValue = (Packed &
Mask) >> Bitfield::Shift;
134 if constexpr (std::is_signed_v<IntegerType>)
141 static StorageType
test(StorageType Packed) {
return Packed &
Mask; }
152template <typename T, bool = std::is_enum<T>::value>
154 using type = std::underlying_type_t<T>;
157 static_assert(!std::is_same_v<T, bool> ||
sizeof(
bool) == 1,
158 "T being bool requires sizeof(bool) == 1.");
172 template <
typename T,
unsigned Offset,
unsigned Size,
173 T MaxValue = std::is_enum<T>::value
175 : std::numeric_limits<T>::max()>
189 static_assert(
Bits > 0,
"Bits must be non zero");
190 static constexpr size_t TypeBits =
sizeof(
IntegerType) * CHAR_BIT;
191 static_assert(
Bits <= TypeBits,
"Bits may not be greater than T size");
192 static_assert(!std::is_enum<T>::value || MaxValue !=
T(0),
193 "Enum Bitfields must provide a MaxValue");
194 static_assert(!std::is_enum<T>::value ||
195 std::is_unsigned<IntegerType>::value,
196 "Enum must be unsigned");
197 static_assert(std::is_integral<IntegerType>::value &&
198 std::numeric_limits<IntegerType>::is_integer,
199 "IntegerType must be an integer type");
206 template <
typename Bitfield,
typename StorageType>
207 static typename Bitfield::Type
get(StorageType Packed) {
209 return static_cast<typename Bitfield::Type
>(I::extract(Packed));
214 template <
typename Bitfield,
typename StorageType>
215 static StorageType
test(StorageType Packed) {
217 return I::test(Packed);
222 template <
typename Bitfield,
typename StorageType>
223 static void set(StorageType &Packed,
typename Bitfield::Type
Value) {
225 I::update(Packed,
static_cast<typename Bitfield::IntegerType
>(
Value));
230 return A::LastBit >= B::FirstBit && B::LastBit >= A::FirstBit;
233 template <
typename A>
static constexpr bool areContiguous() {
return true; }
234 template <
typename A,
typename B,
typename... Others>
236 return A::NextBit == B::FirstBit &&
areContiguous<
B, Others...>();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
LLVM Value Representation.
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
Describes an element of a Bitfield.
static constexpr unsigned Shift
static constexpr unsigned Bits
typename bitfields_details::ResolveUnderlyingType< T >::type IntegerType
static constexpr unsigned FirstBit
static constexpr unsigned NextBit
static constexpr unsigned LastBit
Holds functions to get, set or test bitfields.
static constexpr bool areContiguous()
static Bitfield::Type get(StorageType Packed)
Unpacks the field from the Packed value.
static constexpr bool areContiguous()
static constexpr bool isOverlapping()
Returns whether the two bitfields share common bits.
static void set(StorageType &Packed, typename Bitfield::Type Value)
Sets the typed value in the provided Packed value.
static StorageType test(StorageType Packed)
Return a non-zero value if the field is non-zero.
Impl is where Bifield description and Storage are put together to interact with values.
static constexpr size_t StorageBits
static IntegerType extract(StorageType Packed)
Interprets bits between FirstBit and LastBit of Packed as anIntegerType.
static void checkValue(IntegerType UserValue, IntegerType UserMaxValue)
Validates that UserValue fits within the bitfield's range.
static void update(StorageType &Packed, IntegerType UserValue)
Checks UserValue is within bounds and packs it between FirstBit and LastBit of Packed leaving the res...
static constexpr StorageType LowMask
static StorageType test(StorageType Packed)
Interprets bits between FirstBit and LastBit of Packed as anIntegerType.
static constexpr StorageType Mask
typename Bitfield::IntegerType IntegerType
std::conditional_t< std::is_same_v< T, bool >, uint8_t, T > type
Bitfield deals with the following type:
std::underlying_type_t< T > type