//===-------------------- Bitcastbuffer.cpp ---------------------*- 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
//
//===----------------------------------------------------------------------===//
#include "BitcastBuffer.h"
#include "llvm/ADT/STLExtras.h"

using namespace clang;
using namespace clang::interp;

/// Returns the value of the bit in the given sequence of bytes.
static inline bool bitof(const std::byte *B, Bits BitIndex) {
  return (B[BitIndex.roundToBytes()] &
          (std::byte{1} << BitIndex.getOffsetInByte())) != std::byte{0};
}

void BitcastBuffer::pushData(const std::byte *In, Bits BitOffset, Bits BitWidth,
                             Endian TargetEndianness) {
  for (unsigned It = 0; It != BitWidth.getQuantity(); ++It) {
    bool BitValue = bitof(In, Bits(It));
    if (!BitValue)
      continue;

    Bits DstBit;
    if (TargetEndianness == Endian::Little)
      DstBit = BitOffset + Bits(It);
    else
      DstBit = size() - BitOffset - BitWidth + Bits(It);

    size_t DstByte = DstBit.roundToBytes();
    Data[DstByte] |= std::byte{1} << DstBit.getOffsetInByte();
  }
}

std::unique_ptr<std::byte[]>
BitcastBuffer::copyBits(Bits BitOffset, Bits BitWidth, Bits FullBitWidth,
                        Endian TargetEndianness) const {
  assert(BitWidth.getQuantity() <= FullBitWidth.getQuantity());
  assert(FullBitWidth.isFullByte());
  auto Out = std::make_unique<std::byte[]>(FullBitWidth.roundToBytes());

  for (unsigned It = 0; It != BitWidth.getQuantity(); ++It) {
    Bits BitIndex;
    if (TargetEndianness == Endian::Little)
      BitIndex = BitOffset + Bits(It);
    else
      BitIndex = size() - BitWidth - BitOffset + Bits(It);

    bool BitValue = bitof(Data.get(), BitIndex);
    if (!BitValue)
      continue;

    Bits DstBit = Bits(It);
    size_t DstByte = DstBit.roundToBytes();
    Out[DstByte] |= std::byte{1} << DstBit.getOffsetInByte();
  }

  return Out;
}

bool BitcastBuffer::allInitialized() const {
  return rangeInitialized(Bits::zero(), FinalBitSize);
}

void BitcastBuffer::markInitialized(Bits Offset, Bits Length) {
  if (Length.isZero())
    return;

  BitRange Element(Offset, Offset + Length - Bits(1));
  if (InitializedBits.empty()) {
    InitializedBits.push_back(Element);
    return;
  }

  assert(InitializedBits.size() >= 1);
  // Common case of just appending.
  Bits End = InitializedBits.back().End;
  if (End <= Offset) {
    // Merge this range with the last one.
    // In the best-case scenario, this means we only ever have
    // one single bit range covering all bits.
    if (End == (Offset - Bits(1))) {
      InitializedBits.back().End = Element.End;
      return;
    }

    // Otherwise, we can simply append.
    InitializedBits.push_back(Element);
  } else {
    // Insert sorted.
    auto It = llvm::upper_bound(InitializedBits, Element);
    InitializedBits.insert(It, Element);
  }

#ifndef NDEBUG
  // Ensure ranges are sorted and non-overlapping.
  assert(llvm::is_sorted(InitializedBits));
  for (unsigned I = 1; I != InitializedBits.size(); ++I) {
    [[maybe_unused]] auto Prev = InitializedBits[I - 1];
    [[maybe_unused]] auto Cur = InitializedBits[I];
    assert(Prev.End.N < Cur.Start.N);
  }
#endif
}

bool BitcastBuffer::rangeInitialized(Bits Offset, Bits Length) const {
  if (Length.isZero())
    return true;

  BitRange Range(Offset, Offset + Length - Bits(1));
  Bits Sum;
  bool FoundStart = false;
  for (BitRange BR : InitializedBits) {
    if (FoundStart) {
      if (BR.contains(Range.End)) {
        Sum += (Range.End - BR.Start + Bits(1));
        break;
      }

      // Else, BR is completely inside Range.
      Sum += BR.size();
    }
    if (BR.contains(Range.Start)) {
      Sum += (BR.End - Range.Start + Bits(1));
      FoundStart = true;
    }
  }

  // Note that Sum can be larger than Range, e.g. when Range is fully
  // contained in one range.
  return Sum >= Range.size();
}

#if 0
  template<typename T>
  static std::string hex(T t) {
    std::stringstream stream;
    stream << std::hex << (int)t;
    return std::string(stream.str());
  }


  void BitcastBuffer::dump(bool AsHex = true) const {
    llvm::errs() << "LSB\n  ";
    unsigned LineLength = 0;
    for (unsigned I = 0; I != (FinalBitSize / 8); ++I) {
      std::byte B = Data[I];
      if (AsHex) {
        std::stringstream stream;
        stream << std::hex << (int)B;
        llvm::errs() << stream.str();
        LineLength += stream.str().size() + 1;
      } else {
        llvm::errs() << std::bitset<8>((int)B).to_string();
        LineLength += 8 + 1;
        // llvm::errs() << (int)B;
      }
      llvm::errs() << ' ';
    }
    llvm::errs() << '\n';

    for (unsigned I = 0; I != LineLength; ++I)
      llvm::errs() << ' ';
    llvm::errs() << "MSB\n";
  }
#endif
