//===-- DynamicRegisterInfo.cpp -------------------------------------------===//
//
// 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 "lldb/Target/DynamicRegisterInfo.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/StreamFile.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/StringExtractor.h"
#include "lldb/Utility/StructuredData.h"

using namespace lldb;
using namespace lldb_private;

std::unique_ptr<DynamicRegisterInfo>
DynamicRegisterInfo::Create(const StructuredData::Dictionary &dict,
                            const ArchSpec &arch) {
  auto dyn_reg_info = std::make_unique<DynamicRegisterInfo>();
  if (!dyn_reg_info)
    return nullptr;

  if (dyn_reg_info->SetRegisterInfo(dict, arch) == 0)
    return nullptr;

  return dyn_reg_info;
}

DynamicRegisterInfo::DynamicRegisterInfo(DynamicRegisterInfo &&info) {
  MoveFrom(std::move(info));
}

DynamicRegisterInfo &
DynamicRegisterInfo::operator=(DynamicRegisterInfo &&info) {
  MoveFrom(std::move(info));
  return *this;
}

void DynamicRegisterInfo::MoveFrom(DynamicRegisterInfo &&info) {
  m_regs = std::move(info.m_regs);
  m_sets = std::move(info.m_sets);
  m_set_reg_nums = std::move(info.m_set_reg_nums);
  m_value_regs_map = std::move(info.m_value_regs_map);
  m_invalidate_regs_map = std::move(info.m_invalidate_regs_map);

  m_reg_data_byte_size = info.m_reg_data_byte_size;
  m_finalized = info.m_finalized;

  if (m_finalized) {
    const size_t num_sets = m_sets.size();
    for (size_t set = 0; set < num_sets; ++set)
      m_sets[set].m_set.registers = m_set_reg_nums[set].data();
  }

  info.Clear();
}

llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromSlice(
    uint32_t index, llvm::StringRef slice_str, lldb::ByteOrder byte_order) {
  // Slices use the following format:
  //  REGNAME[MSBIT:LSBIT]
  // REGNAME - name of the register to grab a slice of
  // MSBIT - the most significant bit at which the current register value
  // starts at
  // LSBIT - the least significant bit at which the current register value
  // ends at
  static llvm::Regex g_bitfield_regex(
      "([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]");
  llvm::SmallVector<llvm::StringRef, 4> matches;
  if (!g_bitfield_regex.match(slice_str, &matches))
    return llvm::createStringError(
        llvm::inconvertibleErrorCode(),
        "failed to match against register bitfield regex (slice: %s)",
        slice_str.str().c_str());

  llvm::StringRef reg_name_str = matches[1];
  llvm::StringRef msbit_str = matches[2];
  llvm::StringRef lsbit_str = matches[3];
  uint32_t msbit;
  uint32_t lsbit;
  if (!llvm::to_integer(msbit_str, msbit) ||
      !llvm::to_integer(lsbit_str, lsbit))
    return llvm::createStringError(
        llvm::inconvertibleErrorCode(), "msbit (%s) or lsbit (%s) are invalid",
        msbit_str.str().c_str(), lsbit_str.str().c_str());

  if (msbit <= lsbit)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "msbit (%u) must be greater than lsbit (%u)",
                                   msbit, lsbit);

  const uint32_t msbyte = msbit / 8;
  const uint32_t lsbyte = lsbit / 8;

  const RegisterInfo *containing_reg_info = GetRegisterInfo(reg_name_str);
  if (!containing_reg_info)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "invalid concrete register \"%s\"",
                                   reg_name_str.str().c_str());

  const uint32_t max_bit = containing_reg_info->byte_size * 8;

  if (msbit > max_bit)
    return llvm::createStringError(
        llvm::inconvertibleErrorCode(),
        "msbit (%u) must be less than the bitsize of the register \"%s\" (%u)",
        msbit, reg_name_str.str().c_str(), max_bit);
  if (lsbit > max_bit)
    return llvm::createStringError(
        llvm::inconvertibleErrorCode(),
        "lsbit (%u) must be less than the bitsize of the register \"%s\" (%u)",
        lsbit, reg_name_str.str().c_str(), max_bit);

  m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]]
      .push_back(index);
  m_value_regs_map[index].push_back(
      containing_reg_info->kinds[eRegisterKindLLDB]);
  m_invalidate_regs_map[index].push_back(
      containing_reg_info->kinds[eRegisterKindLLDB]);

  if (byte_order == eByteOrderLittle)
    return containing_reg_info->byte_offset + lsbyte;
  if (byte_order == eByteOrderBig)
    return containing_reg_info->byte_offset + msbyte;
  llvm_unreachable("Invalid byte order");
}

llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromComposite(
    uint32_t index, StructuredData::Array &composite_reg_list,
    lldb::ByteOrder byte_order) {
  const size_t num_composite_regs = composite_reg_list.GetSize();
  if (num_composite_regs == 0)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "\"composite\" list is empty");

  uint32_t composite_offset = UINT32_MAX;
  for (uint32_t composite_idx = 0; composite_idx < num_composite_regs;
       ++composite_idx) {
    std::optional<llvm::StringRef> maybe_composite_reg_name =
        composite_reg_list.GetItemAtIndexAsString(composite_idx);
    if (!maybe_composite_reg_name)
      return llvm::createStringError(
          llvm::inconvertibleErrorCode(),
          "\"composite\" list value is not a Python string at index %d",
          composite_idx);

    const RegisterInfo *composite_reg_info =
        GetRegisterInfo(*maybe_composite_reg_name);
    if (!composite_reg_info)
      return llvm::createStringError(
          llvm::inconvertibleErrorCode(),
          "failed to find composite register by name: \"%s\"",
          maybe_composite_reg_name->str().c_str());

    composite_offset =
        std::min(composite_offset, composite_reg_info->byte_offset);
    m_value_regs_map[index].push_back(
        composite_reg_info->kinds[eRegisterKindLLDB]);
    m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]]
        .push_back(index);
    m_invalidate_regs_map[index].push_back(
        composite_reg_info->kinds[eRegisterKindLLDB]);
  }

  return composite_offset;
}

llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromRegInfoDict(
    uint32_t index, StructuredData::Dictionary &reg_info_dict,
    lldb::ByteOrder byte_order) {
  uint32_t byte_offset;
  if (reg_info_dict.GetValueForKeyAsInteger("offset", byte_offset))
    return byte_offset;

  // No offset for this register, see if the register has a value
  // expression which indicates this register is part of another register.
  // Value expressions are things like "rax[31:0]" which state that the
  // current register's value is in a concrete register "rax" in bits 31:0.
  // If there is a value expression we can calculate the offset
  llvm::StringRef slice_str;
  if (reg_info_dict.GetValueForKeyAsString("slice", slice_str, nullptr))
    return ByteOffsetFromSlice(index, slice_str, byte_order);

  StructuredData::Array *composite_reg_list;
  if (reg_info_dict.GetValueForKeyAsArray("composite", composite_reg_list))
    return ByteOffsetFromComposite(index, *composite_reg_list, byte_order);

  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "insufficient data to calculate byte offset");
}

size_t
DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
                                     const ArchSpec &arch) {
  Log *log = GetLog(LLDBLog::Object);
  assert(!m_finalized);
  StructuredData::Array *sets = nullptr;
  if (dict.GetValueForKeyAsArray("sets", sets)) {
    const uint32_t num_sets = sets->GetSize();
    for (uint32_t i = 0; i < num_sets; ++i) {
      std::optional<llvm::StringRef> maybe_set_name =
          sets->GetItemAtIndexAsString(i);
      if (maybe_set_name && !maybe_set_name->empty()) {
        m_sets.push_back({maybe_set_name->str(), std::string(), 0, nullptr});
      } else {
        Clear();
        printf("error: register sets must have valid names\n");
        return 0;
      }
    }
    m_set_reg_nums.resize(m_sets.size());
  }

  StructuredData::Array *regs = nullptr;
  if (!dict.GetValueForKeyAsArray("registers", regs))
    return 0;

  const ByteOrder byte_order = arch.GetByteOrder();

  const uint32_t num_regs = regs->GetSize();
  //        typedef std::map<std::string, std::vector<std::string> >
  //        InvalidateNameMap;
  //        InvalidateNameMap invalidate_map;
  for (uint32_t i = 0; i < num_regs; ++i) {
    std::optional<StructuredData::Dictionary *> maybe_reg_info_dict =
        regs->GetItemAtIndexAsDictionary(i);
    if (!maybe_reg_info_dict) {
      Clear();
      printf("error: items in the 'registers' array must be dictionaries\n");
      regs->DumpToStdout();
      return 0;
    }
    StructuredData::Dictionary *reg_info_dict = *maybe_reg_info_dict;

    // { 'name':'rcx'       , 'bitsize' :  64, 'offset' :  16,
    // 'encoding':'uint' , 'format':'hex'         , 'set': 0, 'ehframe' : 2,
    // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
    RegisterInfo reg_info;
    memset(&reg_info, 0, sizeof(reg_info));

    llvm::StringRef name_val;
    if (!reg_info_dict->GetValueForKeyAsString("name", name_val)) {
      Clear();
      printf("error: registers must have valid names and offsets\n");
      reg_info_dict->DumpToStdout();
      return 0;
    }
    reg_info.name = ConstString(name_val).GetCString();

    llvm::StringRef alt_name_val;
    if (reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val))
      reg_info.alt_name = ConstString(alt_name_val).GetCString();
    else
      reg_info.alt_name = nullptr;

    llvm::Expected<uint32_t> byte_offset =
        ByteOffsetFromRegInfoDict(i, *reg_info_dict, byte_order);
    if (byte_offset)
      reg_info.byte_offset = byte_offset.get();
    else {
      LLDB_LOG_ERROR(log, byte_offset.takeError(),
                     "error while parsing register {1}: {0}", reg_info.name);
      Clear();
      reg_info_dict->DumpToStdout();
      return 0;
    }

    uint64_t bitsize = 0;
    if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) {
      Clear();
      printf("error: invalid or missing 'bitsize' key/value pair in register "
             "dictionary\n");
      reg_info_dict->DumpToStdout();
      return 0;
    }

    reg_info.byte_size = bitsize / 8;

    llvm::StringRef format_str;
    if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) {
      if (OptionArgParser::ToFormat(format_str.str().c_str(), reg_info.format,
                                    nullptr)
              .Fail()) {
        Clear();
        printf("error: invalid 'format' value in register dictionary\n");
        reg_info_dict->DumpToStdout();
        return 0;
      }
    } else {
      reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format,
                                             eFormatHex);
    }

    llvm::StringRef encoding_str;
    if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))
      reg_info.encoding = Args::StringToEncoding(encoding_str, eEncodingUint);
    else
      reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding,
                                             eEncodingUint);

    size_t set = 0;
    if (!reg_info_dict->GetValueForKeyAsInteger("set", set) ||
        set >= m_sets.size()) {
      Clear();
      printf("error: invalid 'set' value in register dictionary, valid values "
             "are 0 - %i\n",
             (int)set);
      reg_info_dict->DumpToStdout();
      return 0;
    }

    // Fill in the register numbers
    reg_info.kinds[lldb::eRegisterKindLLDB] = i;
    reg_info.kinds[lldb::eRegisterKindProcessPlugin] = i;
    uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;
    reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno,
                                           LLDB_INVALID_REGNUM);
    if (eh_frame_regno == LLDB_INVALID_REGNUM)
      reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno,
                                             LLDB_INVALID_REGNUM);
    reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;
    reg_info_dict->GetValueForKeyAsInteger(
        "dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
    llvm::StringRef generic_str;
    if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
      reg_info.kinds[lldb::eRegisterKindGeneric] =
          Args::StringToGenericRegister(generic_str);
    else
      reg_info_dict->GetValueForKeyAsInteger(
          "generic", reg_info.kinds[lldb::eRegisterKindGeneric],
          LLDB_INVALID_REGNUM);

    // Check if this register invalidates any other register values when it is
    // modified
    StructuredData::Array *invalidate_reg_list = nullptr;
    if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs",
                                             invalidate_reg_list)) {
      const size_t num_regs = invalidate_reg_list->GetSize();
      if (num_regs > 0) {
        for (uint32_t idx = 0; idx < num_regs; ++idx) {
          if (auto maybe_invalidate_reg_name =
                  invalidate_reg_list->GetItemAtIndexAsString(idx)) {
            const RegisterInfo *invalidate_reg_info =
                GetRegisterInfo(*maybe_invalidate_reg_name);
            if (invalidate_reg_info) {
              m_invalidate_regs_map[i].push_back(
                  invalidate_reg_info->kinds[eRegisterKindLLDB]);
            } else {
              // TODO: print error invalid slice string that doesn't follow the
              // format
              printf("error: failed to find a 'invalidate-regs' register for "
                     "\"%s\" while parsing register \"%s\"\n",
                     maybe_invalidate_reg_name->str().c_str(), reg_info.name);
            }
          } else if (auto maybe_invalidate_reg_num =
                         invalidate_reg_list->GetItemAtIndexAsInteger<uint64_t>(
                             idx)) {
            if (*maybe_invalidate_reg_num != UINT64_MAX)
              m_invalidate_regs_map[i].push_back(*maybe_invalidate_reg_num);
            else
              printf("error: 'invalidate-regs' list value wasn't a valid "
                     "integer\n");
          } else {
            printf("error: 'invalidate-regs' list value wasn't a python string "
                   "or integer\n");
          }
        }
      } else {
        printf("error: 'invalidate-regs' contained an empty list\n");
      }
    }

    // Calculate the register offset
    const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
    if (m_reg_data_byte_size < end_reg_offset)
      m_reg_data_byte_size = end_reg_offset;

    m_regs.push_back(reg_info);
    m_set_reg_nums[set].push_back(i);
  }
  Finalize(arch);
  return m_regs.size();
}

size_t DynamicRegisterInfo::SetRegisterInfo(
    std::vector<DynamicRegisterInfo::Register> &&regs,
    const ArchSpec &arch) {
  assert(!m_finalized);

  llvm::StringMap<uint32_t> set_name_to_idx;
  uint32_t next_idx = 0;

  for (auto it : llvm::enumerate(regs)) {
    uint32_t local_regnum = it.index();
    const DynamicRegisterInfo::Register &reg = it.value();

    assert(reg.name);
    assert(reg.set_name);

    if (!reg.value_regs.empty())
      m_value_regs_map[local_regnum] = std::move(reg.value_regs);
    if (!reg.invalidate_regs.empty())
      m_invalidate_regs_map[local_regnum] = std::move(reg.invalidate_regs);
    if (reg.value_reg_offset != 0) {
      assert(reg.value_regs.size() == 1);
      m_value_reg_offset_map[local_regnum] = reg.value_reg_offset;
    }

    struct RegisterInfo reg_info{
        reg.name.AsCString(nullptr),
        reg.alt_name.AsCString(nullptr),
        reg.byte_size,
        reg.byte_offset,
        reg.encoding,
        reg.format,
        {reg.regnum_ehframe, reg.regnum_dwarf, reg.regnum_generic,
         reg.regnum_remote, local_regnum},
        // value_regs and invalidate_regs are filled by Finalize()
        nullptr,
        nullptr,
        reg.register_type};

    m_regs.push_back(reg_info);

    uint32_t set_idx;
    if (!set_name_to_idx.contains(reg.set_name)) {
      set_idx = next_idx;

      set_name_to_idx.insert({reg.set_name, next_idx++});
      m_set_reg_nums.resize(m_set_reg_nums.size() + 1);
      m_sets.push_back(
          {reg.set_name.GetStringRef().str(), std::string(), 0, nullptr});
    } else {
      set_idx = set_name_to_idx.lookup(reg.set_name);
    }

    assert(set_idx < m_sets.size());
    assert(set_idx < m_set_reg_nums.size());
    m_set_reg_nums[set_idx].push_back(local_regnum);
  }

  Finalize(arch);
  return m_regs.size();
}

void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
  if (m_finalized)
    return;

  m_finalized = true;
  const size_t num_sets = m_sets.size();
  for (size_t set = 0; set < num_sets; ++set) {
    assert(m_sets.size() == m_set_reg_nums.size());
    m_sets[set].m_set.num_registers = m_set_reg_nums[set].size();
    m_sets[set].m_set.registers = m_set_reg_nums[set].data();
  }

  // make sure value_regs are terminated with LLDB_INVALID_REGNUM

  for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(),
                                 end = m_value_regs_map.end();
       pos != end; ++pos) {
    if (pos->second.back() != LLDB_INVALID_REGNUM)
      pos->second.push_back(LLDB_INVALID_REGNUM);
  }

  // Now update all value_regs with each register info as needed
  const size_t num_regs = m_regs.size();
  for (size_t i = 0; i < num_regs; ++i) {
    if (auto it = m_value_regs_map.find(i); it != m_value_regs_map.end())
      m_regs[i].value_regs = it->second.data();
    else
      m_regs[i].value_regs = nullptr;
  }

  // Expand all invalidation dependencies
  for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
                                 end = m_invalidate_regs_map.end();
       pos != end; ++pos) {
    const uint32_t reg_num = pos->first;

    if (m_regs[reg_num].value_regs) {
      reg_num_collection extra_invalid_regs;
      for (const uint32_t invalidate_reg_num : pos->second) {
        reg_to_regs_map::iterator invalidate_pos =
            m_invalidate_regs_map.find(invalidate_reg_num);
        if (invalidate_pos != m_invalidate_regs_map.end()) {
          for (const uint32_t concrete_invalidate_reg_num :
               invalidate_pos->second) {
            if (concrete_invalidate_reg_num != reg_num)
              extra_invalid_regs.push_back(concrete_invalidate_reg_num);
          }
        }
      }
      pos->second.insert(pos->second.end(), extra_invalid_regs.begin(),
                         extra_invalid_regs.end());
    }
  }

  // sort and unique all invalidate registers and make sure each is terminated
  // with LLDB_INVALID_REGNUM
  for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(),
                                 end = m_invalidate_regs_map.end();
       pos != end; ++pos) {
    if (pos->second.size() > 1) {
      llvm::sort(pos->second);
      pos->second.erase(llvm::unique(pos->second), pos->second.end());
    }
    assert(!pos->second.empty());
    if (pos->second.back() != LLDB_INVALID_REGNUM)
      pos->second.push_back(LLDB_INVALID_REGNUM);
  }

  // Now update all invalidate_regs with each register info as needed
  for (size_t i = 0; i < num_regs; ++i) {
    if (auto it = m_invalidate_regs_map.find(i);
        it != m_invalidate_regs_map.end())
      m_regs[i].invalidate_regs = it->second.data();
    else
      m_regs[i].invalidate_regs = nullptr;
  }

  // Check if we need to automatically set the generic registers in case they
  // weren't set
  bool generic_regs_specified = false;
  for (const auto &reg : m_regs) {
    if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {
      generic_regs_specified = true;
      break;
    }
  }

  if (!generic_regs_specified) {
    switch (arch.GetMachine()) {
    case llvm::Triple::aarch64:
    case llvm::Triple::aarch64_32:
    case llvm::Triple::aarch64_be:
      for (auto &reg : m_regs) {
        if (strcmp(reg.name, "pc") == 0)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
        else if ((strcmp(reg.name, "fp") == 0) ||
                 (strcmp(reg.name, "x29") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if ((strcmp(reg.name, "lr") == 0) ||
                 (strcmp(reg.name, "x30") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
        else if ((strcmp(reg.name, "sp") == 0) ||
                 (strcmp(reg.name, "x31") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
        else if (strcmp(reg.name, "cpsr") == 0)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
      }
      break;

    case llvm::Triple::arm:
    case llvm::Triple::armeb:
    case llvm::Triple::thumb:
    case llvm::Triple::thumbeb:
      for (auto &reg : m_regs) {
        if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
        else if ((strcmp(reg.name, "sp") == 0) ||
                 (strcmp(reg.name, "r13") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
        else if ((strcmp(reg.name, "lr") == 0) ||
                 (strcmp(reg.name, "r14") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
        else if ((strcmp(reg.name, "r7") == 0) &&
                 arch.GetTriple().getVendor() == llvm::Triple::Apple)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if ((strcmp(reg.name, "r11") == 0) &&
                 arch.GetTriple().getVendor() != llvm::Triple::Apple)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if (strcmp(reg.name, "fp") == 0)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if (strcmp(reg.name, "cpsr") == 0)
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
      }
      break;

    case llvm::Triple::x86:
      for (auto &reg : m_regs) {
        if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
        else if ((strcmp(reg.name, "esp") == 0) ||
                 (strcmp(reg.name, "sp") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
        else if ((strcmp(reg.name, "ebp") == 0) ||
                 (strcmp(reg.name, "fp") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if ((strcmp(reg.name, "eflags") == 0) ||
                 (strcmp(reg.name, "flags") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
      }
      break;

    case llvm::Triple::x86_64:
      for (auto &reg : m_regs) {
        if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
        else if ((strcmp(reg.name, "rsp") == 0) ||
                 (strcmp(reg.name, "sp") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
        else if ((strcmp(reg.name, "rbp") == 0) ||
                 (strcmp(reg.name, "fp") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
        else if ((strcmp(reg.name, "rflags") == 0) ||
                 (strcmp(reg.name, "eflags") == 0) ||
                 (strcmp(reg.name, "flags") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
      }
      break;

    default:
      break;
    }
  }

  // At this stage call ConfigureOffsets to calculate register offsets for
  // targets supporting dynamic offset calculation. It also calculates
  // total byte size of register data.
  ConfigureOffsets();

  // Check if register info is reconfigurable
  // AArch64 SVE register set has configurable register sizes, as does the ZA
  // register that SME added (the streaming state of SME reuses the SVE state).
  if (arch.GetTriple().isAArch64()) {
    for (const auto &reg : m_regs) {
      if ((strcmp(reg.name, "vg") == 0) || (strcmp(reg.name, "svg") == 0)) {
        m_is_reconfigurable = true;
        break;
      }
    }
  }
}

void DynamicRegisterInfo::ConfigureOffsets() {
  // We are going to create a map between remote (eRegisterKindProcessPlugin)
  // and local (eRegisterKindLLDB) register numbers. This map will give us
  // remote register numbers in increasing order for offset calculation.
  std::map<uint32_t, uint32_t> remote_to_local_regnum_map;
  for (const auto &reg : m_regs)
    remote_to_local_regnum_map[reg.kinds[eRegisterKindProcessPlugin]] =
        reg.kinds[eRegisterKindLLDB];

  // At this stage we manually calculate g/G packet offsets of all primary
  // registers, only if target XML or qRegisterInfo packet did not send
  // an offset explicitly.
  uint32_t reg_offset = 0;
  for (auto const &regnum_pair : remote_to_local_regnum_map) {
    if (m_regs[regnum_pair.second].byte_offset == LLDB_INVALID_INDEX32 &&
        m_regs[regnum_pair.second].value_regs == nullptr) {
      m_regs[regnum_pair.second].byte_offset = reg_offset;

      reg_offset = m_regs[regnum_pair.second].byte_offset +
                   m_regs[regnum_pair.second].byte_size;
    }
  }

  // Now update all value_regs with each register info as needed
  for (auto &reg : m_regs) {
    if (reg.value_regs != nullptr) {
      // Assign a valid offset to all pseudo registers that have only a single
      // parent register in value_regs list, if not assigned by stub.  Pseudo
      // registers with value_regs list populated will share same offset as
      // that of their corresponding parent register.
      if (reg.byte_offset == LLDB_INVALID_INDEX32) {
        uint32_t value_regnum = reg.value_regs[0];
        if (value_regnum != LLDB_INVALID_INDEX32 &&
            reg.value_regs[1] == LLDB_INVALID_INDEX32) {
          reg.byte_offset =
              GetRegisterInfoAtIndex(value_regnum)->byte_offset;
          auto it = m_value_reg_offset_map.find(reg.kinds[eRegisterKindLLDB]);
          if (it != m_value_reg_offset_map.end())
            reg.byte_offset += it->second;
        }
      }
    }

    reg_offset = reg.byte_offset + reg.byte_size;
    if (m_reg_data_byte_size < reg_offset)
      m_reg_data_byte_size = reg_offset;
  }
}

bool DynamicRegisterInfo::IsReconfigurable() { return m_is_reconfigurable; }

size_t DynamicRegisterInfo::GetNumRegisters() const { return m_regs.size(); }

size_t DynamicRegisterInfo::GetNumRegisterSets() const { return m_sets.size(); }

size_t DynamicRegisterInfo::GetRegisterDataByteSize() const {
  return m_reg_data_byte_size;
}

const RegisterInfo *
DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) const {
  if (i < m_regs.size())
    return &m_regs[i];
  return nullptr;
}

const RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(uint32_t kind,
                                                         uint32_t num) const {
  uint32_t reg_index = ConvertRegisterKindToRegisterNumber(kind, num);
  if (reg_index != LLDB_INVALID_REGNUM)
    return &m_regs[reg_index];
  return nullptr;
}

const RegisterSet *DynamicRegisterInfo::GetRegisterSet(uint32_t i) const {
  if (i < m_sets.size())
    return &(m_sets[i].m_set);
  return nullptr;
}

uint32_t
DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber(uint32_t kind,
                                                         uint32_t num) const {
  reg_collection::const_iterator pos, end = m_regs.end();
  for (pos = m_regs.begin(); pos != end; ++pos) {
    if (pos->kinds[kind] == num)
      return std::distance(m_regs.begin(), pos);
  }

  return LLDB_INVALID_REGNUM;
}

void DynamicRegisterInfo::Clear() {
  m_regs.clear();
  m_sets.clear();
  m_set_reg_nums.clear();
  m_value_regs_map.clear();
  m_invalidate_regs_map.clear();
  m_reg_data_byte_size = 0;
  m_finalized = false;
}

void DynamicRegisterInfo::Dump(Stream &s) const {
  const size_t num_regs = m_regs.size();
  s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",
           static_cast<const void *>(this), static_cast<uint64_t>(num_regs));
  for (size_t i = 0; i < num_regs; ++i) {
    s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);
    s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
             m_regs[i].byte_size, m_regs[i].byte_offset, m_regs[i].encoding,
             FormatManager::GetFormatAsCString(m_regs[i].format));
    if (m_regs[i].kinds[eRegisterKindProcessPlugin] != LLDB_INVALID_REGNUM)
      s.Printf(", process plugin = %3u",
               m_regs[i].kinds[eRegisterKindProcessPlugin]);
    if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
      s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
    if (m_regs[i].kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
      s.Printf(", ehframe = %3u", m_regs[i].kinds[eRegisterKindEHFrame]);
    if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
      s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);
    if (m_regs[i].alt_name)
      s.Printf(", alt-name = %s", m_regs[i].alt_name);
    if (m_regs[i].value_regs) {
      s.PutCString(", value_regs = [ ");
      for (size_t j = 0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j) {
        s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);
      }
      s.PutCString("]");
    }
    if (m_regs[i].invalidate_regs) {
      s.PutCString(", invalidate_regs = [ ");
      for (size_t j = 0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM;
           ++j) {
        s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);
      }
      s.PutCString("]");
    }
    s.EOL();
  }

  const size_t num_sets = m_sets.size();
  s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",
           static_cast<const void *>(this), static_cast<uint64_t>(num_sets));
  for (size_t i = 0; i < num_sets; ++i) {
    s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i,
             m_sets[i].m_name.c_str());
    for (size_t idx = 0; idx < m_sets[i].m_set.num_registers; ++idx) {
      s.Printf("%s ", m_regs[m_sets[i].m_set.registers[idx]].name);
    }
    s.PutCString("]\n");
  }
}

const lldb_private::RegisterInfo *
DynamicRegisterInfo::GetRegisterInfo(llvm::StringRef reg_name) const {
  for (auto &reg_info : m_regs)
    if (reg_info.name == reg_name)
      return &reg_info;
  return nullptr;
}

void lldb_private::addSupplementaryRegister(
    std::vector<DynamicRegisterInfo::Register> &regs,
    DynamicRegisterInfo::Register new_reg_info) {
  assert(!new_reg_info.value_regs.empty());
  const uint32_t reg_num = regs.size();
  regs.push_back(new_reg_info);

  std::map<uint32_t, std::vector<uint32_t>> new_invalidates;
  for (uint32_t value_reg : new_reg_info.value_regs) {
    // copy value_regs to invalidate_regs
    new_invalidates[reg_num].push_back(value_reg);

    // copy invalidate_regs from the parent register
    llvm::append_range(new_invalidates[reg_num],
                       regs[value_reg].invalidate_regs);

    // add reverse invalidate entries
    for (uint32_t x : new_invalidates[reg_num])
      new_invalidates[x].push_back(reg_num);
  }

  for (const auto &x : new_invalidates)
    llvm::append_range(regs[x.first].invalidate_regs, x.second);
}
