mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 05:16:06 +00:00
121 lines
3.9 KiB
C++
121 lines
3.9 KiB
C++
//===--------------------- BitcastBuffer.h ----------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef LLVM_CLANG_AST_INTERP_BITCAST_BUFFER_H
|
|
#define LLVM_CLANG_AST_INTERP_BITCAST_BUFFER_H
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include <cassert>
|
|
#include <cstddef>
|
|
#include <memory>
|
|
|
|
namespace clang {
|
|
namespace interp {
|
|
|
|
enum class Endian { Little, Big };
|
|
|
|
struct Bytes;
|
|
|
|
/// A quantity in bits.
|
|
struct Bits {
|
|
size_t N = 0;
|
|
Bits() = default;
|
|
static Bits zero() { return Bits(0); }
|
|
explicit Bits(size_t Quantity) : N(Quantity) {}
|
|
size_t getQuantity() const { return N; }
|
|
size_t roundToBytes() const { return N / 8; }
|
|
size_t getOffsetInByte() const { return N % 8; }
|
|
bool isFullByte() const { return N % 8 == 0; }
|
|
bool nonZero() const { return N != 0; }
|
|
bool isZero() const { return N == 0; }
|
|
Bytes toBytes() const;
|
|
|
|
Bits operator-(Bits Other) const { return Bits(N - Other.N); }
|
|
Bits operator+(Bits Other) const { return Bits(N + Other.N); }
|
|
Bits operator+=(size_t O) {
|
|
N += O;
|
|
return *this;
|
|
}
|
|
Bits operator+=(Bits O) {
|
|
N += O.N;
|
|
return *this;
|
|
}
|
|
|
|
bool operator>=(Bits Other) const { return N >= Other.N; }
|
|
bool operator<=(Bits Other) const { return N <= Other.N; }
|
|
bool operator==(Bits Other) const { return N == Other.N; }
|
|
bool operator!=(Bits Other) const { return N != Other.N; }
|
|
};
|
|
|
|
/// A quantity in bytes.
|
|
struct Bytes {
|
|
size_t N;
|
|
explicit Bytes(size_t Quantity) : N(Quantity) {}
|
|
size_t getQuantity() const { return N; }
|
|
Bits toBits() const { return Bits(N * 8); }
|
|
};
|
|
|
|
inline Bytes Bits::toBytes() const {
|
|
assert(isFullByte());
|
|
return Bytes(N / 8);
|
|
}
|
|
|
|
/// A bit range. Both Start and End are inclusive.
|
|
struct BitRange {
|
|
Bits Start;
|
|
Bits End;
|
|
|
|
BitRange(Bits Start, Bits End) : Start(Start), End(End) {}
|
|
Bits size() const { return End - Start + Bits(1); }
|
|
bool operator<(BitRange Other) const { return Start.N < Other.Start.N; }
|
|
|
|
bool contains(Bits B) { return Start <= B && End >= B; }
|
|
};
|
|
|
|
/// Track what bits have been initialized to known values and which ones
|
|
/// have indeterminate value.
|
|
struct BitcastBuffer {
|
|
Bits FinalBitSize;
|
|
std::unique_ptr<std::byte[]> Data;
|
|
llvm::SmallVector<BitRange> InitializedBits;
|
|
|
|
BitcastBuffer(Bits FinalBitSize) : FinalBitSize(FinalBitSize) {
|
|
assert(FinalBitSize.isFullByte());
|
|
unsigned ByteSize = FinalBitSize.roundToBytes();
|
|
Data = std::make_unique<std::byte[]>(ByteSize);
|
|
}
|
|
|
|
/// Returns the buffer size in bits.
|
|
Bits size() const { return FinalBitSize; }
|
|
Bytes byteSize() const { return FinalBitSize.toBytes(); }
|
|
|
|
/// Returns \c true if all bits in the buffer have been initialized.
|
|
bool allInitialized() const;
|
|
/// Marks the bits in the given range as initialized.
|
|
/// FIXME: Can we do this automatically in pushData()?
|
|
void markInitialized(Bits Start, Bits Length);
|
|
bool rangeInitialized(Bits Offset, Bits Length) const;
|
|
|
|
/// Push \p BitWidth bits at \p BitOffset from \p In into the buffer.
|
|
/// \p TargetEndianness is the endianness of the target we're compiling for.
|
|
/// \p In must hold at least \p BitWidth many bits.
|
|
void pushData(const std::byte *In, Bits BitOffset, Bits BitWidth,
|
|
Endian TargetEndianness);
|
|
|
|
/// Copy \p BitWidth bits at offset \p BitOffset from the buffer.
|
|
/// \p TargetEndianness is the endianness of the target we're compiling for.
|
|
///
|
|
/// The returned output holds exactly (\p FullBitWidth / 8) bytes.
|
|
std::unique_ptr<std::byte[]> copyBits(Bits BitOffset, Bits BitWidth,
|
|
Bits FullBitWidth,
|
|
Endian TargetEndianness) const;
|
|
};
|
|
|
|
} // namespace interp
|
|
} // namespace clang
|
|
#endif
|