79#ifndef LLVM_ADT_BITFIELDS_H
80#define LLVM_ADT_BITFIELDS_H
91namespace bitfields_details {
100 static_assert(
sizeof(
Unsigned) ==
sizeof(
T),
"Types must have same size");
103 static_assert(
TypeBits >= Bits,
"n-bit must fit in T");
120template <typename T, unsigned Bits, bool = std::is_unsigned<T>::value>
122 static_assert(std::is_unsigned<T>::value,
"T must be unsigned");
126 assert(UserValue <= UserMaxValue &&
"value is too big");
131 static T unpack(
T StorageValue) {
return StorageValue; }
135 static_assert(std::is_signed<T>::value,
"T must be signed");
139 assert(UserValue <= UserMaxValue &&
"value is too big");
143 UserValue &=
~BP::SignExtend;
156template <
typename Bitfield,
typename StorageType>
struct Impl {
157 static_assert(std::is_unsigned<StorageType>::value,
158 "Storage must be unsigned");
163 static constexpr size_t StorageBits =
sizeof(StorageType) * CHAR_BIT;
164 static_assert(Bitfield::FirstBit <=
StorageBits,
"Data must fit in mask");
165 static_assert(Bitfield::LastBit <=
StorageBits,
"Data must fit in mask");
171 const StorageType StorageValue =
C::pack(UserValue, Bitfield::UserMaxValue);
173 Packed |= StorageValue << Bitfield::Shift;
179 const StorageType StorageValue = (Packed &
Mask) >> Bitfield::Shift;
185 static StorageType
test(StorageType Packed) {
return Packed &
Mask; }
196template <typename T, bool = std::is_enum<T>::value>
198 using type = std::underlying_type_t<T>;
206 using type = std::conditional_t<
sizeof(
bool) == 1, uint8_t,
void>;
219 template <
typename T,
unsigned Offset,
unsigned Size,
220 T MaxValue = std::is_enum<T>::value
222 : std::numeric_limits<T>::max()>
236 static_assert(
Bits > 0,
"Bits must be non zero");
237 static constexpr size_t TypeBits =
sizeof(
IntegerType) * CHAR_BIT;
238 static_assert(
Bits <= TypeBits,
"Bits may not be greater than T size");
239 static_assert(!std::is_enum<T>::value || MaxValue !=
T(0),
240 "Enum Bitfields must provide a MaxValue");
241 static_assert(!std::is_enum<T>::value ||
242 std::is_unsigned<IntegerType>::value,
243 "Enum must be unsigned");
244 static_assert(std::is_integral<IntegerType>::value &&
245 std::numeric_limits<IntegerType>::is_integer,
246 "IntegerType must be an integer type");
253 template <
typename Bitfield,
typename StorageType>
254 static typename Bitfield::Type
get(StorageType Packed) {
256 return static_cast<typename Bitfield::Type
>(I::extract(Packed));
261 template <
typename Bitfield,
typename StorageType>
262 static StorageType
test(StorageType Packed) {
264 return I::test(Packed);
269 template <
typename Bitfield,
typename StorageType>
270 static void set(StorageType &Packed,
typename Bitfield::Type
Value) {
272 I::update(Packed,
static_cast<typename Bitfield::IntegerType
>(
Value));
277 return A::LastBit >= B::FirstBit && B::LastBit >= A::FirstBit;
280 template <
typename A>
static constexpr bool areContiguous() {
return true; }
281 template <
typename A,
typename B,
typename... Others>
283 return A::NextBit == B::FirstBit &&
areContiguous<
B, Others...>();
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
This is an optimization pass for GlobalISel generic memory operations.
Describes an element of a Bitfield.
typename bitfields_details::ResolveUnderlyingType< T >::type IntegerType
static constexpr unsigned Shift
static constexpr unsigned Bits
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.
A struct defining useful bit patterns for n-bits integer types.
std::make_unsigned_t< T > Unsigned
Bit patterns are forged using the equivalent Unsigned type because of undefined operations over signe...
static constexpr Unsigned AllOnes
static constexpr Unsigned Smax
static constexpr Unsigned SignExtend
static constexpr Unsigned Smin
static constexpr Unsigned Umin
static constexpr unsigned TypeBits
static constexpr Unsigned SignBitMask
static constexpr Unsigned Umax
static constexpr Unsigned AllZeros
e.g. with TypeBits == 8 and Bits == 6.
static T pack(T UserValue, T UserMaxValue)
static T unpack(T StorageValue)
Compressor is used to manipulate the bits of a (possibly signed) integer type so it can be packed and...
static T pack(T UserValue, T UserMaxValue)
static T unpack(T StorageValue)
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 update(StorageType &Packed, IntegerType UserValue)
Checks UserValue is within bounds and packs it between FirstBit and LastBit of Packed leaving the res...
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< sizeof(bool)==1, uint8_t, void > type
In case sizeof(bool) != 1, replace void by an additionnal std::conditional.
Bitfield deals with the following type:
std::underlying_type_t< T > type