//===-- 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, 'gcc' : 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::eRegisterKindGDB] = i;
        reg_info_dict->GetValueForKeyAsInteger("gcc", reg_info.kinds[lldb::eRegisterKindGCC], LLDB_INVALID_REGNUM);
        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[eRegisterKindGDB] != LLDB_INVALID_REGNUM)
            s.Printf(", gdb = %3u", m_regs[i].kinds[eRegisterKindGDB]);
        if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
            s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
        if (m_regs[i].kinds[eRegisterKindGCC] != LLDB_INVALID_REGNUM)
            s.Printf(", gcc = %3u", m_regs[i].kinds[eRegisterKindGCC]);
        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;
}
