LLDB mainline
RegisterTypeFlags.h
Go to the documentation of this file.
1//===------------------------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_UTILITY_REGISTERTYPEFLAGS_H
10#define LLDB_UTILITY_REGISTERTYPEFLAGS_H
11
12#include <stdint.h>
13#include <string>
14#include <vector>
15
17#include "llvm/ADT/StringSet.h"
18
19namespace lldb_private {
20
21class Stream;
22class Log;
23
25public:
26 struct Enumerator {
27 uint64_t m_value;
28 // Short name for the value. Shown in tables and when printing the field's
29 // value. For example "RZ".
30 std::string m_name;
31
32 Enumerator(uint64_t value, std::string name)
33 : m_value(value), m_name(std::move(name)) {}
34
35 void DumpToLog(Log *log) const;
36
37 void ToXMLElement(Stream &strm) const;
38 };
39
40 typedef std::vector<Enumerator> Enumerators;
41
42 // GDB also includes a "size" that is the size of the underlying register.
43 // We will not store that here but instead use the size of the register
44 // this gets attached to when emitting XML.
45 RegisterTypeEnum(std::string id, const Enumerators &enumerators);
46
47 const Enumerators &GetEnumerators() const { return m_enumerators; }
48
49 void DumpToLog(Log *log) const;
50
51 virtual void ToXMLElement(Stream &strm,
52 const RegisterType *user = nullptr) const override;
53
54 static bool classof(const RegisterType *register_type) {
55 return register_type->getKind() == RegisterType::eRegisterTypeKindEnum;
56 }
57
58private:
60};
61
63public:
64 class Field {
65 public:
66 /// Where start is the least significant bit and end is the most
67 /// significant bit. The start bit must be <= the end bit.
68 Field(std::string name, unsigned start, unsigned end);
69
70 /// Construct a field that also has some known enum values.
71 Field(std::string name, unsigned start, unsigned end,
72 const RegisterTypeEnum *enum_type);
73
74 /// Construct a field that occupies a single bit.
75 Field(std::string name, unsigned bit_position);
76
77 /// Get size of the field in bits. Will always be at least 1.
78 unsigned GetSizeInBits() const;
79
80 /// Identical to GetSizeInBits, but for the GDB client to use.
81 static unsigned GetSizeInBits(unsigned start, unsigned end);
82
83 /// A mask that covers all bits of the field.
84 uint64_t GetMask() const;
85
86 /// The maximum unsigned value that could be contained in this field.
87 uint64_t GetMaxValue() const;
88
89 /// Identical to GetMaxValue but for the GDB client to use.
90 static uint64_t GetMaxValue(unsigned start, unsigned end);
91
92 /// Extract value of the field from a whole register value.
93 uint64_t GetValue(uint64_t register_value) const {
94 return (register_value & GetMask()) >> m_start;
95 }
96
97 const std::string &GetName() const { return m_name; }
98 unsigned GetStart() const { return m_start; }
99 unsigned GetEnd() const { return m_end; }
100 const RegisterTypeEnum *GetEnum() const { return m_enum_type; }
101 bool Overlaps(const Field &other) const;
102 void DumpToLog(Log *log) const;
103
104 /// Return the number of bits between this field and the other, that are not
105 /// covered by either field.
106 unsigned PaddingDistance(const Field &other) const;
107
108 void ToXMLElement(Stream &strm) const;
109
110 bool operator<(const Field &rhs) const {
111 return GetStart() < rhs.GetStart();
112 }
113
114 bool operator==(const Field &rhs) const {
115 return (m_name == rhs.m_name) && (m_start == rhs.m_start) &&
116 (m_end == rhs.m_end);
117 }
118
119 private:
120 std::string m_name;
121
122 /// Start/end bit positions. Where start N, end N means a single bit
123 /// field at position N. We expect that start <= end. Bit positions begin
124 /// at 0.
125 /// Start is the LSB, end is the MSB.
126 unsigned m_start;
127 unsigned m_end;
128
130 };
131
132 /// This assumes that:
133 /// * There is at least one field.
134 /// * The fields are sorted in descending order.
135 /// Gaps are allowed, they will be filled with anonymous padding fields.
136 RegisterTypeFlags(std::string id, unsigned size,
137 const std::vector<Field> &fields);
138
139 /// Replace all the fields with the new set of fields. All the assumptions
140 /// and checks apply as when you use the constructor. Intended to only be used
141 /// when runtime field detection is needed.
142 void SetFields(const std::vector<Field> &fields);
143
144 /// Make a string where each line contains the name of a field that has
145 /// enum values, and lists what those values are.
146 std::string DumpEnums(uint32_t max_width) const;
147
148 // Reverse the order of the fields, keeping their values the same.
149 // For example a field from bit 31 to 30 with value 0b10 will become bits
150 // 1 to 0, with the same 0b10 value.
151 // Use this when you are going to show the register using a bitfield struct
152 // type. If that struct expects MSB first and you are on little endian where
153 // LSB would be first, this corrects that (and vice versa for big endian).
154 template <typename T> T ReverseFieldOrder(T value) const {
155 T ret = 0;
156 unsigned shift = 0;
157 for (auto field : GetFields()) {
158 ret |= field.GetValue(value) << shift;
159 shift += field.GetSizeInBits();
160 }
161
162 return ret;
163 }
164
165 const std::vector<Field> &GetFields() const { return m_fields; }
166 unsigned GetSize() const { return m_size; }
167
168 void DumpToLog(Log *log) const;
169
170 /// Produce a text table showing the layout of all the fields. Unnamed/padding
171 /// fields will be included, with only their positions shown.
172 /// max_width will be the width in characters of the terminal you are
173 /// going to print the table to. If the table would exceed this width, it will
174 /// be split into many tables as needed.
175 std::string AsTable(uint32_t max_width) const;
176
177 virtual void ToXMLElement(Stream &strm,
178 const RegisterType *user = nullptr) const override;
179
180 static bool classof(const RegisterType *register_type) {
181 return register_type->getKind() == RegisterType::eRegisterTypeKindFlags;
182 }
183
184private:
185 /// Size in bytes
186 const unsigned m_size;
187 std::vector<Field> m_fields;
188};
189
190} // namespace lldb_private
191
192#endif // LLDB_UTILITY_REGISTERTYPEFLAGS_H
std::vector< Enumerator > Enumerators
const Enumerators & GetEnumerators() const
RegisterTypeEnum(std::string id, const Enumerators &enumerators)
virtual void ToXMLElement(Stream &strm, const RegisterType *user=nullptr) const override
Output the register type as an XML element.
static bool classof(const RegisterType *register_type)
const std::string & GetName() const
unsigned PaddingDistance(const Field &other) const
Return the number of bits between this field and the other, that are not covered by either field.
unsigned m_start
Start/end bit positions.
bool Overlaps(const Field &other) const
unsigned GetSizeInBits() const
Get size of the field in bits. Will always be at least 1.
uint64_t GetMaxValue() const
The maximum unsigned value that could be contained in this field.
bool operator==(const Field &rhs) const
uint64_t GetValue(uint64_t register_value) const
Extract value of the field from a whole register value.
bool operator<(const Field &rhs) const
uint64_t GetMask() const
A mask that covers all bits of the field.
Field(std::string name, unsigned start, unsigned end)
Where start is the least significant bit and end is the most significant bit.
const RegisterTypeEnum * GetEnum() const
std::string DumpEnums(uint32_t max_width) const
Make a string where each line contains the name of a field that has enum values, and lists what those...
void SetFields(const std::vector< Field > &fields)
Replace all the fields with the new set of fields.
std::string AsTable(uint32_t max_width) const
Produce a text table showing the layout of all the fields.
virtual void ToXMLElement(Stream &strm, const RegisterType *user=nullptr) const override
Output the register type as an XML element.
const std::vector< Field > & GetFields() const
RegisterTypeFlags(std::string id, unsigned size, const std::vector< Field > &fields)
This assumes that:
const unsigned m_size
Size in bytes.
static bool classof(const RegisterType *register_type)
RegisterTypeKind getKind() const
RegisterType(RegisterTypeKind kind, std::string id)
A stream class that can stream formatted output to a file.
Definition Stream.h:28
A class that represents a running process on the host machine.
Enumerator(uint64_t value, std::string name)