//===-- 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/RegularExpression.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/StringConvert.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_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_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)
        {
            std::string set_name_str;
            ConstString set_name;
            if (sets->GetItemAtIndexAsString(i, set_name_str))
                set_name.SetCString(set_name_str.c_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;
            std::string 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("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]");
                RegularExpression::Match regex_match(3);
                if (g_bitfield_regex.Execute(slice_str.c_str(), &regex_match))
                {
                    llvm::StringRef reg_name_str;
                    std::string msbit_str;
                    std::string lsbit_str;
                    if (regex_match.GetMatchAtIndex(slice_str.c_str(), 1, reg_name_str) &&
                        regex_match.GetMatchAtIndex(slice_str.c_str(), 2, msbit_str) &&
                        regex_match.GetMatchAtIndex(slice_str.c_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
                                        {
                                            assert(!"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;

        std::string format_str;
        if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr))
        {
            if (Args::StringToFormat(format_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);
        }

        std::string encoding_str;
        if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))
            reg_info.encoding = Args::StringToEncoding(encoding_str.c_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);
        std::string generic_str;
        if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
            reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister(generic_str.c_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]);
    }
    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;
}

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