//===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "DynamicRegisterInfo.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/StringExtractor.h"
#include "lldb/Utility/StructuredData.h"

using namespace lldb;
using namespace lldb_private;

DynamicRegisterInfo::DynamicRegisterInfo()
    : m_regs(), m_sets(), m_set_reg_nums(), m_set_names(), m_value_regs_map(),
      m_invalidate_regs_map(), m_dynamic_reg_size_map(),
      m_reg_data_byte_size(0), m_finalized(false) {}

DynamicRegisterInfo::DynamicRegisterInfo(
    const lldb_private::StructuredData::Dictionary &dict,
    const lldb_private::ArchSpec &arch)
    : m_regs(), m_sets(), m_set_reg_nums(), m_set_names(), m_value_regs_map(),
      m_invalidate_regs_map(), m_dynamic_reg_size_map(),
      m_reg_data_byte_size(0), m_finalized(false) {
  SetRegisterInfo(dict, arch);
}

DynamicRegisterInfo::~DynamicRegisterInfo() {}

size_t
DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict,
                                     const ArchSpec &arch) {
  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) {
      llvm::StringRef set_name_str;
      ConstString set_name;
      if (sets->GetItemAtIndexAsString(i, set_name_str))
        set_name.SetString(set_name_str);
      if (set_name) {
        RegisterSet new_set = {set_name.AsCString(), NULL, 0, NULL};
        m_sets.push_back(new_set);
      } 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 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) {
    StructuredData::Dictionary *reg_info_dict = nullptr;
    if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict)) {
      Clear();
      printf("error: items in the 'registers' array must be dictionaries\n");
      regs->DumpToStdout();
      return 0;
    }

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

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

    reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset,
                                           UINT32_MAX);

    const ByteOrder byte_order = arch.GetByteOrder();

    if (reg_info.byte_offset == UINT32_MAX) {
      // 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
      bool success = false;
      llvm::StringRef slice_str;
      if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr)) {
        // 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 RegularExpression g_bitfield_regex(
            llvm::StringRef("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"));
        RegularExpression::Match regex_match(3);
        if (g_bitfield_regex.Execute(slice_str, &regex_match)) {
          llvm::StringRef reg_name_str;
          std::string msbit_str;
          std::string lsbit_str;
          if (regex_match.GetMatchAtIndex(slice_str, 1, reg_name_str) &&
              regex_match.GetMatchAtIndex(slice_str, 2, msbit_str) &&
              regex_match.GetMatchAtIndex(slice_str, 3, lsbit_str)) {
            const uint32_t msbit =
                StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
            const uint32_t lsbit =
                StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
            if (msbit != UINT32_MAX && lsbit != UINT32_MAX) {
              if (msbit > lsbit) {
                const uint32_t msbyte = msbit / 8;
                const uint32_t lsbyte = lsbit / 8;

                ConstString containing_reg_name(reg_name_str);

                RegisterInfo *containing_reg_info =
                    GetRegisterInfo(containing_reg_name);
                if (containing_reg_info) {
                  const uint32_t max_bit = containing_reg_info->byte_size * 8;
                  if (msbit < max_bit && lsbit < max_bit) {
                    m_invalidate_regs_map[containing_reg_info
                                              ->kinds[eRegisterKindLLDB]]
                        .push_back(i);
                    m_value_regs_map[i].push_back(
                        containing_reg_info->kinds[eRegisterKindLLDB]);
                    m_invalidate_regs_map[i].push_back(
                        containing_reg_info->kinds[eRegisterKindLLDB]);

                    if (byte_order == eByteOrderLittle) {
                      success = true;
                      reg_info.byte_offset =
                          containing_reg_info->byte_offset + lsbyte;
                    } else if (byte_order == eByteOrderBig) {
                      success = true;
                      reg_info.byte_offset =
                          containing_reg_info->byte_offset + msbyte;
                    } else {
                      llvm_unreachable("Invalid byte order");
                    }
                  } else {
                    if (msbit > max_bit)
                      printf("error: msbit (%u) must be less than the bitsize "
                             "of the register (%u)\n",
                             msbit, max_bit);
                    else
                      printf("error: lsbit (%u) must be less than the bitsize "
                             "of the register (%u)\n",
                             lsbit, max_bit);
                  }
                } else {
                  printf("error: invalid concrete register \"%s\"\n",
                         containing_reg_name.GetCString());
                }
              } else {
                printf("error: msbit (%u) must be greater than lsbit (%u)\n",
                       msbit, lsbit);
              }
            } else {
              printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit,
                     lsbit);
            }
          } else {
            // TODO: print error invalid slice string that doesn't follow the
            // format
            printf("error: failed to extract regex matches for parsing the "
                   "register bitfield regex\n");
          }
        } else {
          // TODO: print error invalid slice string that doesn't follow the
          // format
          printf("error: failed to match against register bitfield regex\n");
        }
      } else {
        StructuredData::Array *composite_reg_list = nullptr;
        if (reg_info_dict->GetValueForKeyAsArray("composite",
                                                 composite_reg_list)) {
          const size_t num_composite_regs = composite_reg_list->GetSize();
          if (num_composite_regs > 0) {
            uint32_t composite_offset = UINT32_MAX;
            for (uint32_t composite_idx = 0; composite_idx < num_composite_regs;
                 ++composite_idx) {
              ConstString composite_reg_name;
              if (composite_reg_list->GetItemAtIndexAsString(
                      composite_idx, composite_reg_name, nullptr)) {
                RegisterInfo *composite_reg_info =
                    GetRegisterInfo(composite_reg_name);
                if (composite_reg_info) {
                  composite_offset = std::min(composite_offset,
                                              composite_reg_info->byte_offset);
                  m_value_regs_map[i].push_back(
                      composite_reg_info->kinds[eRegisterKindLLDB]);
                  m_invalidate_regs_map[composite_reg_info
                                            ->kinds[eRegisterKindLLDB]]
                      .push_back(i);
                  m_invalidate_regs_map[i].push_back(
                      composite_reg_info->kinds[eRegisterKindLLDB]);
                } else {
                  // TODO: print error invalid slice string that doesn't follow
                  // the format
                  printf("error: failed to find composite register by name: "
                         "\"%s\"\n",
                         composite_reg_name.GetCString());
                }
              } else {
                printf(
                    "error: 'composite' list value wasn't a python string\n");
              }
            }
            if (composite_offset != UINT32_MAX) {
              reg_info.byte_offset = composite_offset;
              success = m_value_regs_map.find(i) != m_value_regs_map.end();
            } else {
              printf("error: 'composite' registers must specify at least one "
                     "real register\n");
            }
          } else {
            printf("error: 'composite' list was empty\n");
          }
        }
      }

      if (!success) {
        Clear();
        reg_info_dict->DumpToStdout();
        return 0;
      }
    }

    int64_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 dwarf_opcode_string;
    if (reg_info_dict->GetValueForKeyAsString("dynamic_size_dwarf_expr_bytes",
                                              dwarf_opcode_string)) {
      reg_info.dynamic_size_dwarf_len = dwarf_opcode_string.size() / 2;
      assert(reg_info.dynamic_size_dwarf_len > 0);

      std::vector<uint8_t> dwarf_opcode_bytes(reg_info.dynamic_size_dwarf_len);
      uint32_t j;
      StringExtractor opcode_extractor(dwarf_opcode_string);
      uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
      UNUSED_IF_ASSERT_DISABLED(ret_val);
      assert(ret_val == reg_info.dynamic_size_dwarf_len);

      for (j = 0; j < reg_info.dynamic_size_dwarf_len; ++j)
        m_dynamic_reg_size_map[i].push_back(dwarf_opcode_bytes[j]);

      reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[i].data();
    }

    llvm::StringRef format_str;
    if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) {
      if (Args::StringToFormat(format_str.str().c_str(), reg_info.format, NULL)
              .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<size_t>("set", set, -1) ||
        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) {
          ConstString invalidate_reg_name;
          uint64_t invalidate_reg_num;
          if (invalidate_reg_list->GetItemAtIndexAsString(
                  idx, invalidate_reg_name)) {
            RegisterInfo *invalidate_reg_info =
                GetRegisterInfo(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",
                     invalidate_reg_name.GetCString(), reg_info.name);
            }
          } else if (invalidate_reg_list->GetItemAtIndexAsInteger(
                         idx, invalidate_reg_num)) {
            if (invalidate_reg_num != UINT64_MAX)
              m_invalidate_regs_map[i].push_back(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();
}

void DynamicRegisterInfo::AddRegister(RegisterInfo &reg_info,
                                      ConstString &reg_name,
                                      ConstString &reg_alt_name,
                                      ConstString &set_name) {
  assert(!m_finalized);
  const uint32_t reg_num = m_regs.size();
  reg_info.name = reg_name.AsCString();
  assert(reg_info.name);
  reg_info.alt_name = reg_alt_name.AsCString(NULL);
  uint32_t i;
  if (reg_info.value_regs) {
    for (i = 0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
      m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
  }
  if (reg_info.invalidate_regs) {
    for (i = 0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
      m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
  }
  if (reg_info.dynamic_size_dwarf_expr_bytes) {
    for (i = 0; i < reg_info.dynamic_size_dwarf_len; ++i)
      m_dynamic_reg_size_map[reg_num].push_back(
          reg_info.dynamic_size_dwarf_expr_bytes[i]);

    reg_info.dynamic_size_dwarf_expr_bytes =
        m_dynamic_reg_size_map[reg_num].data();
  }

  m_regs.push_back(reg_info);
  uint32_t set = GetRegisterSetIndexByName(set_name, true);
  assert(set < m_sets.size());
  assert(set < m_set_reg_nums.size());
  assert(set < m_set_names.size());
  m_set_reg_nums[set].push_back(reg_num);
  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;
}

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].num_registers = m_set_reg_nums[set].size();
    m_sets[set].registers = &m_set_reg_nums[set][0];
  }

  // sort and unique all value registers and make sure each is 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.size() > 1) {
      std::sort(pos->second.begin(), pos->second.end());
      reg_num_collection::iterator unique_end =
          std::unique(pos->second.begin(), pos->second.end());
      if (unique_end != pos->second.end())
        pos->second.erase(unique_end, pos->second.end());
    }
    assert(!pos->second.empty());
    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 (m_value_regs_map.find(i) != m_value_regs_map.end())
      m_regs[i].value_regs = m_value_regs_map[i].data();
    else
      m_regs[i].value_regs = NULL;
  }

  // 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) {
      std::sort(pos->second.begin(), pos->second.end());
      reg_num_collection::iterator unique_end =
          std::unique(pos->second.begin(), pos->second.end());
      if (unique_end != pos->second.end())
        pos->second.erase(unique_end, 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 (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
      m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
    else
      m_regs[i].invalidate_regs = NULL;
  }

  // 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_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, "flags") == 0))
          reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
      }
      break;

    default:
      break;
    }
  }
}

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 NULL;
}

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

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

uint32_t DynamicRegisterInfo::GetRegisterSetIndexByName(ConstString &set_name,
                                                        bool can_create) {
  name_collection::iterator pos, end = m_set_names.end();
  for (pos = m_set_names.begin(); pos != end; ++pos) {
    if (*pos == set_name)
      return std::distance(m_set_names.begin(), pos);
  }

  m_set_names.push_back(set_name);
  m_set_reg_nums.resize(m_set_reg_nums.size() + 1);
  RegisterSet new_set = {set_name.AsCString(), NULL, 0, NULL};
  m_sets.push_back(new_set);
  return m_sets.size() - 1;
}

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_set_names.clear();
  m_value_regs_map.clear();
  m_invalidate_regs_map.clear();
  m_dynamic_reg_size_map.clear();
  m_reg_data_byte_size = 0;
  m_finalized = false;
}

void DynamicRegisterInfo::Dump() const {
  StreamFile s(stdout, false);
  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.Printf(", 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.Printf("]");
    }
    if (m_regs[i].invalidate_regs) {
      s.Printf(", 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.Printf("]");
    }
    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].name);
    for (size_t idx = 0; idx < m_sets[i].num_registers; ++idx) {
      s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);
    }
    s.Printf("]\n");
  }
}

lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(
    const lldb_private::ConstString &reg_name) {
  for (auto &reg_info : m_regs) {
    // We can use pointer comparison since we used a ConstString to set
    // the "name" member in AddRegister()
    if (reg_info.name == reg_name.GetCString()) {
      return &reg_info;
    }
  }
  return NULL;
}
