//===-- DynamicRegisterInfo.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 LLDB_TARGET_DYNAMICREGISTERINFO_H
#define LLDB_TARGET_DYNAMICREGISTERINFO_H

#include <map>
#include <vector>

#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

class DynamicRegisterInfo {
protected:
  DynamicRegisterInfo(DynamicRegisterInfo &) = default;
  DynamicRegisterInfo &operator=(DynamicRegisterInfo &) = default;

public:
  struct Register {
    ConstString name;
    ConstString alt_name;
    ConstString set_name;
    uint32_t byte_size = LLDB_INVALID_INDEX32;
    uint32_t byte_offset = LLDB_INVALID_INDEX32;
    lldb::Encoding encoding = lldb::eEncodingUint;
    lldb::Format format = lldb::eFormatHex;
    uint32_t regnum_dwarf = LLDB_INVALID_REGNUM;
    uint32_t regnum_ehframe = LLDB_INVALID_REGNUM;
    uint32_t regnum_generic = LLDB_INVALID_REGNUM;
    uint32_t regnum_remote = LLDB_INVALID_REGNUM;
    std::vector<uint32_t> value_regs;
    std::vector<uint32_t> invalidate_regs;
    uint32_t value_reg_offset = 0;
  };

  DynamicRegisterInfo() = default;

  DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
                      const lldb_private::ArchSpec &arch);

  virtual ~DynamicRegisterInfo() = default;

  DynamicRegisterInfo(DynamicRegisterInfo &&info);
  DynamicRegisterInfo &operator=(DynamicRegisterInfo &&info);

  size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
                         const lldb_private::ArchSpec &arch);

  size_t SetRegisterInfo(std::vector<Register> &&regs,
                         const lldb_private::ArchSpec &arch);

  size_t GetNumRegisters() const;

  size_t GetNumRegisterSets() const;

  size_t GetRegisterDataByteSize() const;

  const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(uint32_t i) const;

  const lldb_private::RegisterSet *GetRegisterSet(uint32_t i) const;

  uint32_t GetRegisterSetIndexByName(const lldb_private::ConstString &set_name,
                                     bool can_create);

  uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind,
                                               uint32_t num) const;

  const lldb_private::RegisterInfo *GetRegisterInfo(uint32_t kind,
                                                    uint32_t num) const;

  void Dump() const;

  void Clear();

  bool IsReconfigurable();

  const lldb_private::RegisterInfo *
  GetRegisterInfo(llvm::StringRef reg_name) const;

  typedef std::vector<lldb_private::RegisterInfo> reg_collection;
  llvm::iterator_range<reg_collection::const_iterator> registers() const {
    return llvm::iterator_range<reg_collection::const_iterator>(m_regs);
  }

protected:
  // Classes that inherit from DynamicRegisterInfo can see and modify these
  typedef std::vector<lldb_private::RegisterSet> set_collection;
  typedef std::vector<uint32_t> reg_num_collection;
  typedef std::vector<reg_num_collection> set_reg_num_collection;
  typedef std::vector<lldb_private::ConstString> name_collection;
  typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map;
  typedef std::map<uint32_t, uint32_t> reg_offset_map;

  llvm::Expected<uint32_t> ByteOffsetFromSlice(uint32_t index,
                                               llvm::StringRef slice_str,
                                               lldb::ByteOrder byte_order);
  llvm::Expected<uint32_t> ByteOffsetFromComposite(
      uint32_t index, lldb_private::StructuredData::Array &composite_reg_list,
      lldb::ByteOrder byte_order);
  llvm::Expected<uint32_t> ByteOffsetFromRegInfoDict(
      uint32_t index, lldb_private::StructuredData::Dictionary &reg_info_dict,
      lldb::ByteOrder byte_order);

  void MoveFrom(DynamicRegisterInfo &&info);

  void Finalize(const lldb_private::ArchSpec &arch);

  void ConfigureOffsets();

  reg_collection m_regs;
  set_collection m_sets;
  set_reg_num_collection m_set_reg_nums;
  name_collection m_set_names;
  reg_to_regs_map m_value_regs_map;
  reg_to_regs_map m_invalidate_regs_map;
  reg_offset_map m_value_reg_offset_map;
  size_t m_reg_data_byte_size = 0u; // The number of bytes required to store
                                    // all registers
  bool m_finalized = false;
  bool m_is_reconfigurable = false;
};

void addSupplementaryRegister(std::vector<DynamicRegisterInfo::Register> &regs,
                              DynamicRegisterInfo::Register new_reg_info);

} // namespace lldb_private

#endif // LLDB_TARGET_DYNAMICREGISTERINFO_H
