1254721Semaste//===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste#include "DynamicRegisterInfo.h"
13254721Semaste
14254721Semaste// C Includes
15254721Semaste// C++ Includes
16254721Semaste// Other libraries and framework includes
17254721Semaste// Project includes
18254721Semaste#include "lldb/Interpreter/Args.h"
19263363Semaste#include "lldb/Core/RegularExpression.h"
20263363Semaste#include "lldb/Core/StreamFile.h"
21263363Semaste#include "lldb/DataFormatters/FormatManager.h"
22254721Semaste
23254721Semaste#ifndef LLDB_DISABLE_PYTHON
24254721Semaste#include "lldb/Interpreter/PythonDataObjects.h"
25254721Semaste#endif
26254721Semaste
27254721Semasteusing namespace lldb;
28254721Semasteusing namespace lldb_private;
29254721Semaste
30254721SemasteDynamicRegisterInfo::DynamicRegisterInfo () :
31254721Semaste    m_regs (),
32254721Semaste    m_sets (),
33254721Semaste    m_set_reg_nums (),
34254721Semaste    m_set_names (),
35263363Semaste    m_value_regs_map (),
36263363Semaste    m_invalidate_regs_map (),
37263363Semaste    m_reg_data_byte_size (0),
38263363Semaste    m_finalized (false)
39254721Semaste{
40254721Semaste}
41254721Semaste
42263363SemasteDynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict, ByteOrder byte_order) :
43254721Semaste    m_regs (),
44254721Semaste    m_sets (),
45254721Semaste    m_set_reg_nums (),
46254721Semaste    m_set_names (),
47263363Semaste    m_value_regs_map (),
48263363Semaste    m_invalidate_regs_map (),
49263363Semaste    m_reg_data_byte_size (0),
50263363Semaste    m_finalized (false)
51254721Semaste{
52263363Semaste    SetRegisterInfo (dict, byte_order);
53254721Semaste}
54254721Semaste
55254721SemasteDynamicRegisterInfo::~DynamicRegisterInfo ()
56254721Semaste{
57254721Semaste}
58254721Semaste
59254721Semaste
60254721Semastesize_t
61263363SemasteDynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict,
62263363Semaste                                      ByteOrder byte_order)
63254721Semaste{
64263363Semaste    assert(!m_finalized);
65254721Semaste#ifndef LLDB_DISABLE_PYTHON
66254721Semaste    PythonList sets (dict.GetItemForKey("sets"));
67254721Semaste    if (sets)
68254721Semaste    {
69254721Semaste        const uint32_t num_sets = sets.GetSize();
70254721Semaste        for (uint32_t i=0; i<num_sets; ++i)
71254721Semaste        {
72254721Semaste            PythonString py_set_name(sets.GetItemAtIndex(i));
73254721Semaste            ConstString set_name;
74254721Semaste            if (py_set_name)
75254721Semaste                set_name.SetCString(py_set_name.GetString());
76254721Semaste            if (set_name)
77254721Semaste            {
78254721Semaste                RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
79254721Semaste                m_sets.push_back (new_set);
80254721Semaste            }
81254721Semaste            else
82254721Semaste            {
83254721Semaste                Clear();
84254721Semaste                return 0;
85254721Semaste            }
86254721Semaste        }
87254721Semaste        m_set_reg_nums.resize(m_sets.size());
88254721Semaste    }
89254721Semaste    PythonList regs (dict.GetItemForKey("registers"));
90254721Semaste    if (regs)
91254721Semaste    {
92254721Semaste        const uint32_t num_regs = regs.GetSize();
93254721Semaste        PythonString name_pystr("name");
94254721Semaste        PythonString altname_pystr("alt-name");
95254721Semaste        PythonString bitsize_pystr("bitsize");
96254721Semaste        PythonString offset_pystr("offset");
97254721Semaste        PythonString encoding_pystr("encoding");
98254721Semaste        PythonString format_pystr("format");
99254721Semaste        PythonString set_pystr("set");
100254721Semaste        PythonString gcc_pystr("gcc");
101254721Semaste        PythonString dwarf_pystr("dwarf");
102254721Semaste        PythonString generic_pystr("generic");
103263363Semaste        PythonString slice_pystr("slice");
104263363Semaste        PythonString composite_pystr("composite");
105263363Semaste        PythonString invalidate_regs_pystr("invalidate-regs");
106263363Semaste
107263363Semaste//        typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap;
108263363Semaste//        InvalidateNameMap invalidate_map;
109254721Semaste        for (uint32_t i=0; i<num_regs; ++i)
110254721Semaste        {
111254721Semaste            PythonDictionary reg_info_dict(regs.GetItemAtIndex(i));
112254721Semaste            if (reg_info_dict)
113254721Semaste            {
114254721Semaste                // { 'name':'rcx'       , 'bitsize' :  64, 'offset' :  16, 'encoding':'uint'  , 'format':'hex'         , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
115254721Semaste                RegisterInfo reg_info;
116263363Semaste                std::vector<uint32_t> value_regs;
117263363Semaste                std::vector<uint32_t> invalidate_regs;
118254721Semaste                bzero (&reg_info, sizeof(reg_info));
119254721Semaste
120254721Semaste                reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString();
121254721Semaste                if (reg_info.name == NULL)
122254721Semaste                {
123254721Semaste                    Clear();
124254721Semaste                    return 0;
125254721Semaste                }
126254721Semaste
127254721Semaste                reg_info.alt_name = ConstString (reg_info_dict.GetItemForKeyAsString(altname_pystr)).GetCString();
128254721Semaste
129254721Semaste                reg_info.byte_offset = reg_info_dict.GetItemForKeyAsInteger(offset_pystr, UINT32_MAX);
130254721Semaste
131254721Semaste                if (reg_info.byte_offset == UINT32_MAX)
132254721Semaste                {
133263363Semaste                    // No offset for this register, see if the register has a value expression
134263363Semaste                    // which indicates this register is part of another register. Value expressions
135263363Semaste                    // are things like "rax[31:0]" which state that the current register's value
136263363Semaste                    // is in a concrete register "rax" in bits 31:0. If there is a value expression
137263363Semaste                    // we can calculate the offset
138263363Semaste                    bool success = false;
139263363Semaste                    const char *slice_cstr = reg_info_dict.GetItemForKeyAsString(slice_pystr);
140263363Semaste                    if (slice_cstr)
141263363Semaste                    {
142263363Semaste                        // Slices use the following format:
143263363Semaste                        //  REGNAME[MSBIT:LSBIT]
144263363Semaste                        // REGNAME - name of the register to grab a slice of
145263363Semaste                        // MSBIT - the most significant bit at which the current register value starts at
146263363Semaste                        // LSBIT - the least significant bit at which the current register value ends at
147263363Semaste                        static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]");
148263363Semaste                        RegularExpression::Match regex_match(3);
149263363Semaste                        if (g_bitfield_regex.Execute(slice_cstr, &regex_match))
150263363Semaste                        {
151263363Semaste                            llvm::StringRef reg_name_str;
152263363Semaste                            std::string msbit_str;
153263363Semaste                            std::string lsbit_str;
154263363Semaste                            if (regex_match.GetMatchAtIndex(slice_cstr, 1, reg_name_str) &&
155263363Semaste                                regex_match.GetMatchAtIndex(slice_cstr, 2, msbit_str) &&
156263363Semaste                                regex_match.GetMatchAtIndex(slice_cstr, 3, lsbit_str))
157263363Semaste                            {
158263363Semaste                                const uint32_t msbit = Args::StringToUInt32(msbit_str.c_str(), UINT32_MAX);
159263363Semaste                                const uint32_t lsbit = Args::StringToUInt32(lsbit_str.c_str(), UINT32_MAX);
160263363Semaste                                if (msbit != UINT32_MAX && lsbit != UINT32_MAX)
161263363Semaste                                {
162263363Semaste                                    if (msbit > lsbit)
163263363Semaste                                    {
164263363Semaste                                        const uint32_t msbyte = msbit / 8;
165263363Semaste                                        const uint32_t lsbyte = lsbit / 8;
166263363Semaste
167263363Semaste                                        ConstString containing_reg_name(reg_name_str);
168263363Semaste
169263363Semaste                                        RegisterInfo *containing_reg_info = GetRegisterInfo (containing_reg_name);
170263363Semaste                                        if (containing_reg_info)
171263363Semaste                                        {
172263363Semaste                                            const uint32_t max_bit = containing_reg_info->byte_size * 8;
173263363Semaste                                            if (msbit < max_bit && lsbit < max_bit)
174263363Semaste                                            {
175263363Semaste                                                m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i);
176263363Semaste                                                m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]);
177263363Semaste                                                m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]);
178263363Semaste
179263363Semaste                                                if (byte_order == eByteOrderLittle)
180263363Semaste                                                {
181263363Semaste                                                    success = true;
182263363Semaste                                                    reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte;
183263363Semaste                                                }
184263363Semaste                                                else if (byte_order == eByteOrderBig)
185263363Semaste                                                {
186263363Semaste                                                    success = true;
187263363Semaste                                                    reg_info.byte_offset = containing_reg_info->byte_offset + msbyte;
188263363Semaste                                                }
189263363Semaste                                                else
190263363Semaste                                                {
191263363Semaste                                                    assert(!"Invalid byte order");
192263363Semaste                                                }
193263363Semaste                                            }
194263363Semaste                                            else
195263363Semaste                                            {
196263363Semaste                                                if (msbit > max_bit)
197263363Semaste                                                    printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit, max_bit);
198263363Semaste                                                else
199263363Semaste                                                    printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit, max_bit);
200263363Semaste                                            }
201263363Semaste                                        }
202263363Semaste                                        else
203263363Semaste                                        {
204263363Semaste                                            printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString());
205263363Semaste                                        }
206263363Semaste                                    }
207263363Semaste                                    else
208263363Semaste                                    {
209263363Semaste                                        printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit);
210263363Semaste                                    }
211263363Semaste                                }
212263363Semaste                                else
213263363Semaste                                {
214263363Semaste                                    printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit);
215263363Semaste                                }
216263363Semaste                            }
217263363Semaste                            else
218263363Semaste                            {
219263363Semaste                                // TODO: print error invalid slice string that doesn't follow the format
220263363Semaste                                printf("error: failed to extract regex matches for parsing the register bitfield regex\n");
221263363Semaste
222263363Semaste                            }
223263363Semaste                        }
224263363Semaste                        else
225263363Semaste                        {
226263363Semaste                            // TODO: print error invalid slice string that doesn't follow the format
227263363Semaste                            printf("error: failed to match against register bitfield regex\n");
228263363Semaste                        }
229263363Semaste                    }
230263363Semaste                    else
231263363Semaste                    {
232263363Semaste                        PythonList composite_reg_list (reg_info_dict.GetItemForKey(composite_pystr));
233263363Semaste                        if (composite_reg_list)
234263363Semaste                        {
235263363Semaste                            const size_t num_composite_regs = composite_reg_list.GetSize();
236263363Semaste                            if (num_composite_regs > 0)
237263363Semaste                            {
238263363Semaste                                uint32_t composite_offset = UINT32_MAX;
239263363Semaste                                for (uint32_t composite_idx=0; composite_idx<num_composite_regs; ++composite_idx)
240263363Semaste                                {
241263363Semaste                                    PythonString composite_reg_name_pystr(composite_reg_list.GetItemAtIndex(composite_idx));
242263363Semaste                                    if (composite_reg_name_pystr)
243263363Semaste                                    {
244263363Semaste                                        ConstString composite_reg_name(composite_reg_name_pystr.GetString());
245263363Semaste                                        if (composite_reg_name)
246263363Semaste                                        {
247263363Semaste                                            RegisterInfo *composite_reg_info = GetRegisterInfo (composite_reg_name);
248263363Semaste                                            if (composite_reg_info)
249263363Semaste                                            {
250263363Semaste                                                if (composite_offset > composite_reg_info->byte_offset)
251263363Semaste                                                    composite_offset = composite_reg_info->byte_offset;
252263363Semaste                                                m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]);
253263363Semaste                                                m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i);
254263363Semaste                                                m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]);
255263363Semaste                                            }
256263363Semaste                                            else
257263363Semaste                                            {
258263363Semaste                                                // TODO: print error invalid slice string that doesn't follow the format
259263363Semaste                                                printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString());
260263363Semaste                                            }
261263363Semaste                                        }
262263363Semaste                                        else
263263363Semaste                                        {
264263363Semaste                                            printf("error: 'composite' key contained an empty string\n");
265263363Semaste                                        }
266263363Semaste                                    }
267263363Semaste                                    else
268263363Semaste                                    {
269263363Semaste                                        printf("error: 'composite' list value wasn't a python string\n");
270263363Semaste                                    }
271263363Semaste                                }
272263363Semaste                                if (composite_offset != UINT32_MAX)
273263363Semaste                                {
274263363Semaste                                    reg_info.byte_offset = composite_offset;
275263363Semaste                                    success = m_value_regs_map.find(i) != m_value_regs_map.end();
276263363Semaste                                }
277263363Semaste                                else
278263363Semaste                                {
279263363Semaste                                    printf("error: 'composite' registers must specify at least one real register\n");
280263363Semaste                                }
281263363Semaste                            }
282263363Semaste                            else
283263363Semaste                            {
284263363Semaste                                printf("error: 'composite' list was empty\n");
285263363Semaste                            }
286263363Semaste                        }
287263363Semaste                    }
288263363Semaste
289263363Semaste
290263363Semaste                    if (!success)
291263363Semaste                    {
292263363Semaste                        Clear();
293263363Semaste                        return 0;
294263363Semaste                    }
295254721Semaste                }
296263363Semaste                const int64_t bitsize = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0);
297263363Semaste                if (bitsize == 0)
298254721Semaste                {
299254721Semaste                    Clear();
300254721Semaste                    return 0;
301254721Semaste                }
302263363Semaste
303263363Semaste                reg_info.byte_size =  bitsize / 8;
304254721Semaste
305254721Semaste                const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr);
306254721Semaste                if (format_cstr)
307254721Semaste                {
308254721Semaste                    if (Args::StringToFormat(format_cstr, reg_info.format, NULL).Fail())
309254721Semaste                    {
310254721Semaste                        Clear();
311254721Semaste                        return 0;
312254721Semaste                    }
313254721Semaste                }
314254721Semaste                else
315263363Semaste                {
316263363Semaste                    reg_info.format = (Format)reg_info_dict.GetItemForKeyAsInteger (format_pystr, eFormatHex);
317263363Semaste                }
318263363Semaste
319254721Semaste                const char *encoding_cstr = reg_info_dict.GetItemForKeyAsString(encoding_pystr);
320254721Semaste                if (encoding_cstr)
321254721Semaste                    reg_info.encoding = Args::StringToEncoding (encoding_cstr, eEncodingUint);
322254721Semaste                else
323263363Semaste                    reg_info.encoding = (Encoding)reg_info_dict.GetItemForKeyAsInteger (encoding_pystr, eEncodingUint);
324254721Semaste
325254721Semaste                const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1);
326254721Semaste                if (set >= m_sets.size())
327254721Semaste                {
328254721Semaste                    Clear();
329254721Semaste                    return 0;
330254721Semaste                }
331254721Semaste
332263363Semaste                // Fill in the register numbers
333254721Semaste                reg_info.kinds[lldb::eRegisterKindLLDB]    = i;
334254721Semaste                reg_info.kinds[lldb::eRegisterKindGDB]     = i;
335254721Semaste                reg_info.kinds[lldb::eRegisterKindGCC]     = reg_info_dict.GetItemForKeyAsInteger(gcc_pystr, LLDB_INVALID_REGNUM);
336254721Semaste                reg_info.kinds[lldb::eRegisterKindDWARF]   = reg_info_dict.GetItemForKeyAsInteger(dwarf_pystr, LLDB_INVALID_REGNUM);
337263363Semaste                const char *generic_cstr = reg_info_dict.GetItemForKeyAsString(generic_pystr);
338263363Semaste                if (generic_cstr)
339263363Semaste                    reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (generic_cstr);
340263363Semaste                else
341263363Semaste                    reg_info.kinds[lldb::eRegisterKindGeneric] = reg_info_dict.GetItemForKeyAsInteger(generic_pystr, LLDB_INVALID_REGNUM);
342263363Semaste
343263363Semaste                // Check if this register invalidates any other register values when it is modified
344263363Semaste                PythonList invalidate_reg_list (reg_info_dict.GetItemForKey(invalidate_regs_pystr));
345263363Semaste                if (invalidate_reg_list)
346263363Semaste                {
347263363Semaste                    const size_t num_regs = invalidate_reg_list.GetSize();
348263363Semaste                    if (num_regs > 0)
349263363Semaste                    {
350263363Semaste                        for (uint32_t idx=0; idx<num_regs; ++idx)
351263363Semaste                        {
352263363Semaste                            PythonObject invalidate_reg_object (invalidate_reg_list.GetItemAtIndex(idx));
353263363Semaste                            PythonString invalidate_reg_name_pystr(invalidate_reg_object);
354263363Semaste                            if (invalidate_reg_name_pystr)
355263363Semaste                            {
356263363Semaste                                ConstString invalidate_reg_name(invalidate_reg_name_pystr.GetString());
357263363Semaste                                if (invalidate_reg_name)
358263363Semaste                                {
359263363Semaste                                    RegisterInfo *invalidate_reg_info = GetRegisterInfo (invalidate_reg_name);
360263363Semaste                                    if (invalidate_reg_info)
361263363Semaste                                    {
362263363Semaste                                        m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]);
363263363Semaste                                    }
364263363Semaste                                    else
365263363Semaste                                    {
366263363Semaste                                        // TODO: print error invalid slice string that doesn't follow the format
367263363Semaste                                        printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n", invalidate_reg_name.GetCString(), reg_info.name);
368263363Semaste                                    }
369263363Semaste                                }
370263363Semaste                                else
371263363Semaste                                {
372263363Semaste                                    printf("error: 'invalidate-regs' list value was an empty string\n");
373263363Semaste                                }
374263363Semaste                            }
375263363Semaste                            else
376263363Semaste                            {
377263363Semaste                                PythonInteger invalidate_reg_num(invalidate_reg_object);
378263363Semaste
379263363Semaste                                if (invalidate_reg_num)
380263363Semaste                                {
381263363Semaste                                    const int64_t r = invalidate_reg_num.GetInteger();
382263363Semaste                                    if (r != UINT64_MAX)
383263363Semaste                                        m_invalidate_regs_map[i].push_back(r);
384263363Semaste                                    else
385263363Semaste                                        printf("error: 'invalidate-regs' list value wasn't a valid integer\n");
386263363Semaste                                }
387263363Semaste                                else
388263363Semaste                                {
389263363Semaste                                    printf("error: 'invalidate-regs' list value wasn't a python string or integer\n");
390263363Semaste                                }
391263363Semaste                            }
392263363Semaste                        }
393263363Semaste                    }
394263363Semaste                    else
395263363Semaste                    {
396263363Semaste                        printf("error: 'invalidate-regs' contained an empty list\n");
397263363Semaste                    }
398263363Semaste                }
399263363Semaste
400263363Semaste                // Calculate the register offset
401254721Semaste                const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
402254721Semaste                if (m_reg_data_byte_size < end_reg_offset)
403254721Semaste                    m_reg_data_byte_size = end_reg_offset;
404254721Semaste
405254721Semaste                m_regs.push_back (reg_info);
406254721Semaste                m_set_reg_nums[set].push_back(i);
407254721Semaste
408254721Semaste            }
409254721Semaste            else
410254721Semaste            {
411254721Semaste                Clear();
412254721Semaste                return 0;
413254721Semaste            }
414254721Semaste        }
415254721Semaste        Finalize ();
416254721Semaste    }
417254721Semaste#endif
418263363Semaste    return m_regs.size();
419254721Semaste}
420254721Semaste
421254721Semaste
422254721Semastevoid
423254721SemasteDynamicRegisterInfo::AddRegister (RegisterInfo &reg_info,
424254721Semaste                                  ConstString &reg_name,
425254721Semaste                                  ConstString &reg_alt_name,
426254721Semaste                                  ConstString &set_name)
427254721Semaste{
428263363Semaste    assert(!m_finalized);
429254721Semaste    const uint32_t reg_num = m_regs.size();
430254721Semaste    reg_info.name = reg_name.AsCString();
431254721Semaste    assert (reg_info.name);
432254721Semaste    reg_info.alt_name = reg_alt_name.AsCString(NULL);
433263363Semaste    uint32_t i;
434263363Semaste    if (reg_info.value_regs)
435263363Semaste    {
436263363Semaste        for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
437263363Semaste            m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
438263363Semaste    }
439263363Semaste    if (reg_info.invalidate_regs)
440263363Semaste    {
441263363Semaste        for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
442263363Semaste            m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
443263363Semaste    }
444254721Semaste    m_regs.push_back (reg_info);
445254721Semaste    uint32_t set = GetRegisterSetIndexByName (set_name, true);
446254721Semaste    assert (set < m_sets.size());
447254721Semaste    assert (set < m_set_reg_nums.size());
448254721Semaste    assert (set < m_set_names.size());
449254721Semaste    m_set_reg_nums[set].push_back(reg_num);
450254721Semaste    size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
451254721Semaste    if (m_reg_data_byte_size < end_reg_offset)
452254721Semaste        m_reg_data_byte_size = end_reg_offset;
453254721Semaste}
454254721Semaste
455254721Semastevoid
456254721SemasteDynamicRegisterInfo::Finalize ()
457254721Semaste{
458263363Semaste    if (m_finalized)
459263363Semaste        return;
460263363Semaste
461263363Semaste    m_finalized = true;
462263363Semaste    const size_t num_sets = m_sets.size();
463263363Semaste    for (size_t set = 0; set < num_sets; ++set)
464254721Semaste    {
465254721Semaste        assert (m_sets.size() == m_set_reg_nums.size());
466254721Semaste        m_sets[set].num_registers = m_set_reg_nums[set].size();
467254721Semaste        m_sets[set].registers = &m_set_reg_nums[set][0];
468254721Semaste    }
469263363Semaste
470263363Semaste    // sort and unique all value registers and make sure each is terminated with
471263363Semaste    // LLDB_INVALID_REGNUM
472263363Semaste
473263363Semaste    for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), end = m_value_regs_map.end();
474263363Semaste         pos != end;
475263363Semaste         ++pos)
476263363Semaste    {
477263363Semaste        if (pos->second.size() > 1)
478263363Semaste        {
479263363Semaste            std::sort (pos->second.begin(), pos->second.end());
480263363Semaste            reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end());
481263363Semaste            if (unique_end != pos->second.end())
482263363Semaste                pos->second.erase(unique_end, pos->second.end());
483263363Semaste        }
484263363Semaste        assert (!pos->second.empty());
485263363Semaste        if (pos->second.back() != LLDB_INVALID_REGNUM)
486263363Semaste            pos->second.push_back(LLDB_INVALID_REGNUM);
487263363Semaste    }
488263363Semaste
489263363Semaste    // Now update all value_regs with each register info as needed
490263363Semaste    const size_t num_regs = m_regs.size();
491263363Semaste    for (size_t i=0; i<num_regs; ++i)
492263363Semaste    {
493263363Semaste        if (m_value_regs_map.find(i) != m_value_regs_map.end())
494263363Semaste            m_regs[i].value_regs = m_value_regs_map[i].data();
495263363Semaste        else
496263363Semaste            m_regs[i].value_regs = NULL;
497263363Semaste    }
498263363Semaste
499263363Semaste    // Expand all invalidation dependencies
500263363Semaste    for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
501263363Semaste         pos != end;
502263363Semaste         ++pos)
503263363Semaste    {
504263363Semaste        const uint32_t reg_num = pos->first;
505263363Semaste
506263363Semaste        if (m_regs[reg_num].value_regs)
507263363Semaste        {
508263363Semaste            reg_num_collection extra_invalid_regs;
509263363Semaste            for (const uint32_t invalidate_reg_num : pos->second)
510263363Semaste            {
511263363Semaste                reg_to_regs_map::iterator invalidate_pos = m_invalidate_regs_map.find(invalidate_reg_num);
512263363Semaste                if (invalidate_pos != m_invalidate_regs_map.end())
513263363Semaste                {
514263363Semaste                    for (const uint32_t concrete_invalidate_reg_num : invalidate_pos->second)
515263363Semaste                    {
516263363Semaste                        if (concrete_invalidate_reg_num != reg_num)
517263363Semaste                            extra_invalid_regs.push_back(concrete_invalidate_reg_num);
518263363Semaste                    }
519263363Semaste                }
520263363Semaste            }
521263363Semaste            pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), extra_invalid_regs.end());
522263363Semaste        }
523263363Semaste    }
524263363Semaste
525263363Semaste    // sort and unique all invalidate registers and make sure each is terminated with
526263363Semaste    // LLDB_INVALID_REGNUM
527263363Semaste    for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
528263363Semaste         pos != end;
529263363Semaste         ++pos)
530263363Semaste    {
531263363Semaste        if (pos->second.size() > 1)
532263363Semaste        {
533263363Semaste            std::sort (pos->second.begin(), pos->second.end());
534263363Semaste            reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end());
535263363Semaste            if (unique_end != pos->second.end())
536263363Semaste                pos->second.erase(unique_end, pos->second.end());
537263363Semaste        }
538263363Semaste        assert (!pos->second.empty());
539263363Semaste        if (pos->second.back() != LLDB_INVALID_REGNUM)
540263363Semaste            pos->second.push_back(LLDB_INVALID_REGNUM);
541263363Semaste    }
542263363Semaste
543263363Semaste    // Now update all invalidate_regs with each register info as needed
544263363Semaste    for (size_t i=0; i<num_regs; ++i)
545263363Semaste    {
546263363Semaste        if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
547263363Semaste            m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
548263363Semaste        else
549263363Semaste            m_regs[i].invalidate_regs = NULL;
550263363Semaste    }
551254721Semaste}
552254721Semaste
553254721Semastesize_t
554254721SemasteDynamicRegisterInfo::GetNumRegisters() const
555254721Semaste{
556254721Semaste    return m_regs.size();
557254721Semaste}
558254721Semaste
559254721Semastesize_t
560254721SemasteDynamicRegisterInfo::GetNumRegisterSets() const
561254721Semaste{
562254721Semaste    return m_sets.size();
563254721Semaste}
564254721Semaste
565254721Semastesize_t
566254721SemasteDynamicRegisterInfo::GetRegisterDataByteSize() const
567254721Semaste{
568254721Semaste    return m_reg_data_byte_size;
569254721Semaste}
570254721Semaste
571254721Semasteconst RegisterInfo *
572254721SemasteDynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const
573254721Semaste{
574254721Semaste    if (i < m_regs.size())
575254721Semaste        return &m_regs[i];
576254721Semaste    return NULL;
577254721Semaste}
578254721Semaste
579254721Semasteconst RegisterSet *
580254721SemasteDynamicRegisterInfo::GetRegisterSet (uint32_t i) const
581254721Semaste{
582254721Semaste    if (i < m_sets.size())
583254721Semaste        return &m_sets[i];
584254721Semaste    return NULL;
585254721Semaste}
586254721Semaste
587254721Semasteuint32_t
588254721SemasteDynamicRegisterInfo::GetRegisterSetIndexByName (ConstString &set_name, bool can_create)
589254721Semaste{
590254721Semaste    name_collection::iterator pos, end = m_set_names.end();
591254721Semaste    for (pos = m_set_names.begin(); pos != end; ++pos)
592254721Semaste    {
593254721Semaste        if (*pos == set_name)
594254721Semaste            return std::distance (m_set_names.begin(), pos);
595254721Semaste    }
596254721Semaste
597254721Semaste    m_set_names.push_back(set_name);
598254721Semaste    m_set_reg_nums.resize(m_set_reg_nums.size()+1);
599254721Semaste    RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
600254721Semaste    m_sets.push_back (new_set);
601254721Semaste    return m_sets.size() - 1;
602254721Semaste}
603254721Semaste
604254721Semasteuint32_t
605254721SemasteDynamicRegisterInfo::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
606254721Semaste{
607254721Semaste    reg_collection::const_iterator pos, end = m_regs.end();
608254721Semaste    for (pos = m_regs.begin(); pos != end; ++pos)
609254721Semaste    {
610254721Semaste        if (pos->kinds[kind] == num)
611254721Semaste            return std::distance (m_regs.begin(), pos);
612254721Semaste    }
613254721Semaste
614254721Semaste    return LLDB_INVALID_REGNUM;
615254721Semaste}
616254721Semaste
617254721Semastevoid
618254721SemasteDynamicRegisterInfo::Clear()
619254721Semaste{
620254721Semaste    m_regs.clear();
621254721Semaste    m_sets.clear();
622254721Semaste    m_set_reg_nums.clear();
623254721Semaste    m_set_names.clear();
624263363Semaste    m_value_regs_map.clear();
625263363Semaste    m_invalidate_regs_map.clear();
626263363Semaste    m_reg_data_byte_size = 0;
627263363Semaste    m_finalized = false;
628254721Semaste}
629263363Semaste
630263363Semastevoid
631263363SemasteDynamicRegisterInfo::Dump () const
632263363Semaste{
633263363Semaste    StreamFile s(stdout, false);
634263363Semaste    const size_t num_regs = m_regs.size();
635263363Semaste    s.Printf("%p: DynamicRegisterInfo contains %zu registers:\n", this, num_regs);
636263363Semaste    for (size_t i=0; i<num_regs; ++i)
637263363Semaste    {
638263363Semaste        s.Printf("[%3zu] name = %-10s", i, m_regs[i].name);
639263363Semaste        s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
640263363Semaste                 m_regs[i].byte_size,
641263363Semaste                 m_regs[i].byte_offset,
642263363Semaste                 m_regs[i].encoding,
643263363Semaste                 FormatManager::GetFormatAsCString (m_regs[i].format));
644263363Semaste        if (m_regs[i].kinds[eRegisterKindGDB] != LLDB_INVALID_REGNUM)
645263363Semaste            s.Printf(", gdb = %3u", m_regs[i].kinds[eRegisterKindGDB]);
646263363Semaste        if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
647263363Semaste            s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
648263363Semaste        if (m_regs[i].kinds[eRegisterKindGCC] != LLDB_INVALID_REGNUM)
649263363Semaste            s.Printf(", gcc = %3u", m_regs[i].kinds[eRegisterKindGCC]);
650263363Semaste        if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
651263363Semaste            s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);
652263363Semaste        if (m_regs[i].alt_name)
653263363Semaste            s.Printf(", alt-name = %s", m_regs[i].alt_name);
654263363Semaste        if (m_regs[i].value_regs)
655263363Semaste        {
656263363Semaste            s.Printf(", value_regs = [ ");
657263363Semaste            for (size_t j=0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j)
658263363Semaste            {
659263363Semaste                s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);
660263363Semaste            }
661263363Semaste            s.Printf("]");
662263363Semaste        }
663263363Semaste        if (m_regs[i].invalidate_regs)
664263363Semaste        {
665263363Semaste            s.Printf(", invalidate_regs = [ ");
666263363Semaste            for (size_t j=0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM; ++j)
667263363Semaste            {
668263363Semaste                s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);
669263363Semaste            }
670263363Semaste            s.Printf("]");
671263363Semaste        }
672263363Semaste        s.EOL();
673263363Semaste    }
674263363Semaste
675263363Semaste    const size_t num_sets = m_sets.size();
676263363Semaste    s.Printf("%p: DynamicRegisterInfo contains %zu register sets:\n", this, num_sets);
677263363Semaste    for (size_t i=0; i<num_sets; ++i)
678263363Semaste    {
679263363Semaste        s.Printf("set[%zu] name = %s, regs = [", i, m_sets[i].name);
680263363Semaste        for (size_t idx=0; idx<m_sets[i].num_registers; ++idx)
681263363Semaste        {
682263363Semaste            s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);
683263363Semaste        }
684263363Semaste        s.Printf("]\n");
685263363Semaste    }
686263363Semaste}
687263363Semaste
688263363Semaste
689263363Semaste
690263363Semastelldb_private::RegisterInfo *
691263363SemasteDynamicRegisterInfo::GetRegisterInfo (const lldb_private::ConstString &reg_name)
692263363Semaste{
693263363Semaste    for (auto &reg_info : m_regs)
694263363Semaste    {
695263363Semaste        // We can use pointer comparison since we used a ConstString to set
696263363Semaste        // the "name" member in AddRegister()
697263363Semaste        if (reg_info.name == reg_name.GetCString())
698263363Semaste        {
699263363Semaste            return &reg_info;
700263363Semaste        }
701263363Semaste    }
702263363Semaste    return NULL;
703263363Semaste}
704