Skip to content
This repository was archived by the owner on Jan 26, 2024. It is now read-only.

Commit c6d7f24

Browse files
committed
[lldb] [ABI/X86] Refactor ABIX86::AugmentRegisterInfo()
Refactor ABIX86::AugmentRegisterInfo() and helper functions for better readability. This also fixes listing eax & co. as potential subregs on 32-bit systems. Differential Revision: https://reviews.llvm.org/D108937
1 parent 39f2b05 commit c6d7f24

File tree

1 file changed

+118
-91
lines changed

1 file changed

+118
-91
lines changed

lldb/source/Plugins/ABI/X86/ABIX86.cpp

+118-91
Original file line numberDiff line numberDiff line change
@@ -33,36 +33,40 @@ void ABIX86::Terminate() {
3333
ABIWindows_x86_64::Terminate();
3434
}
3535

36-
enum class RegKind {
37-
GPR32 = 0,
36+
namespace {
37+
enum RegKind {
38+
GPR32,
3839
GPR16,
3940
GPR8h,
4041
GPR8,
42+
MM,
43+
YMM_YMMh,
44+
YMM_XMM,
4145

42-
MM = 0,
46+
RegKindCount
47+
};
48+
}
49+
50+
struct RegData {
51+
RegKind subreg_kind;
52+
llvm::StringRef subreg_name;
53+
llvm::Optional<uint32_t> base_index;
4354
};
4455

45-
typedef llvm::SmallDenseMap<llvm::StringRef,
46-
llvm::SmallVector<llvm::StringRef, 4>, 16>
47-
RegisterMap;
48-
49-
static void addPartialRegisters(
50-
std::vector<DynamicRegisterInfo::Register> &regs,
51-
llvm::ArrayRef<uint32_t> base_reg_indices, const RegisterMap &reg_names,
52-
uint32_t base_size, RegKind name_index, lldb::Encoding encoding,
53-
lldb::Format format, uint32_t subreg_size, uint32_t subreg_offset = 0) {
54-
for (uint32_t base_index : base_reg_indices) {
55-
if (base_index == LLDB_INVALID_REGNUM)
56-
break;
57-
assert(base_index < regs.size());
56+
static void
57+
addPartialRegisters(std::vector<DynamicRegisterInfo::Register> &regs,
58+
llvm::ArrayRef<RegData *> subregs, uint32_t base_size,
59+
lldb::Encoding encoding, lldb::Format format,
60+
uint32_t subreg_size, uint32_t subreg_offset = 0) {
61+
for (const RegData *subreg : subregs) {
62+
assert(subreg);
63+
uint32_t base_index = subreg->base_index.getValue();
5864
DynamicRegisterInfo::Register &full_reg = regs[base_index];
59-
llvm::StringRef subreg_name = reg_names.lookup(
60-
full_reg.name.GetStringRef())[static_cast<int>(name_index)];
61-
if (subreg_name.empty() || full_reg.byte_size != base_size)
65+
if (full_reg.byte_size != base_size)
6266
continue;
6367

64-
lldb_private::DynamicRegisterInfo::Register subreg{
65-
lldb_private::ConstString(subreg_name),
68+
lldb_private::DynamicRegisterInfo::Register new_reg{
69+
lldb_private::ConstString(subreg->subreg_name),
6670
lldb_private::ConstString(),
6771
lldb_private::ConstString("supplementary registers"),
6872
subreg_size,
@@ -77,10 +81,65 @@ static void addPartialRegisters(
7781
{},
7882
subreg_offset};
7983

80-
addSupplementaryRegister(regs, subreg);
84+
addSupplementaryRegister(regs, new_reg);
8185
}
8286
}
8387

88+
typedef llvm::SmallDenseMap<llvm::StringRef, llvm::SmallVector<RegData, 4>, 64>
89+
BaseRegToRegsMap;
90+
91+
#define GPRh(l) \
92+
{ \
93+
is64bit \
94+
? BaseRegToRegsMap::value_type("r" l "x", \
95+
{{GPR32, "e" l "x", llvm::None}, \
96+
{GPR16, l "x", llvm::None}, \
97+
{GPR8h, l "h", llvm::None}, \
98+
{GPR8, l "l", llvm::None}}) \
99+
: BaseRegToRegsMap::value_type("e" l "x", {{GPR16, l "x", llvm::None}, \
100+
{GPR8h, l "h", llvm::None}, \
101+
{GPR8, l "l", llvm::None}}) \
102+
}
103+
104+
#define GPR(r16) \
105+
{ \
106+
is64bit \
107+
? BaseRegToRegsMap::value_type("r" r16, {{GPR32, "e" r16, llvm::None}, \
108+
{GPR16, r16, llvm::None}, \
109+
{GPR8, r16 "l", llvm::None}}) \
110+
: BaseRegToRegsMap::value_type("e" r16, {{GPR16, r16, llvm::None}, \
111+
{GPR8, r16 "l", llvm::None}}) \
112+
}
113+
114+
#define GPR64(n) \
115+
{ \
116+
BaseRegToRegsMap::value_type("r" #n, {{GPR32, "r" #n "d", llvm::None}, \
117+
{GPR16, "r" #n "w", llvm::None}, \
118+
{GPR8, "r" #n "l", llvm::None}}) \
119+
}
120+
121+
#define STMM(n) \
122+
{ BaseRegToRegsMap::value_type("st" #n, {{MM, "mm" #n, llvm::None}}) }
123+
124+
BaseRegToRegsMap makeBaseRegMap(bool is64bit) {
125+
BaseRegToRegsMap out{{// GPRs common to amd64 & i386
126+
GPRh("a"), GPRh("b"), GPRh("c"), GPRh("d"), GPR("si"),
127+
GPR("di"), GPR("bp"), GPR("sp"),
128+
129+
// ST/MM registers
130+
STMM(0), STMM(1), STMM(2), STMM(3), STMM(4), STMM(5),
131+
STMM(6), STMM(7)}};
132+
133+
if (is64bit) {
134+
BaseRegToRegsMap amd64_regs{{// GPRs specific to amd64
135+
GPR64(8), GPR64(9), GPR64(10), GPR64(11),
136+
GPR64(12), GPR64(13), GPR64(14), GPR64(15)}};
137+
out.insert(amd64_regs.begin(), amd64_regs.end());
138+
}
139+
140+
return out;
141+
}
142+
84143
void ABIX86::AugmentRegisterInfo(
85144
std::vector<DynamicRegisterInfo::Register> &regs) {
86145
MCBasedABI::AugmentRegisterInfo(regs);
@@ -91,83 +150,51 @@ void ABIX86::AugmentRegisterInfo(
91150

92151
uint32_t gpr_base_size =
93152
process_sp->GetTarget().GetArchitecture().GetAddressByteSize();
94-
bool is64bit = gpr_base_size == 8;
95-
96-
typedef RegisterMap::value_type RegPair;
97-
#define GPR_BASE(basename) (is64bit ? "r" basename : "e" basename)
98-
RegisterMap gpr_regs{{
99-
RegPair(GPR_BASE("ax"), {"eax", "ax", "ah", "al"}),
100-
RegPair(GPR_BASE("bx"), {"ebx", "bx", "bh", "bl"}),
101-
RegPair(GPR_BASE("cx"), {"ecx", "cx", "ch", "cl"}),
102-
RegPair(GPR_BASE("dx"), {"edx", "dx", "dh", "dl"}),
103-
RegPair(GPR_BASE("si"), {"esi", "si", "", "sil"}),
104-
RegPair(GPR_BASE("di"), {"edi", "di", "", "dil"}),
105-
RegPair(GPR_BASE("bp"), {"ebp", "bp", "", "bpl"}),
106-
RegPair(GPR_BASE("sp"), {"esp", "sp", "", "spl"}),
107-
}};
108-
#undef GPR_BASE
109-
if (is64bit) {
110-
#define R(base) RegPair(base, {base "d", base "w", "", base "l"})
111-
RegisterMap amd64_regs{{
112-
R("r8"),
113-
R("r9"),
114-
R("r10"),
115-
R("r11"),
116-
R("r12"),
117-
R("r13"),
118-
R("r14"),
119-
R("r15"),
120-
}};
121-
#undef R
122-
gpr_regs.insert(amd64_regs.begin(), amd64_regs.end());
123-
}
124153

125-
RegisterMap st_regs{{
126-
RegPair("st0", {"mm0"}),
127-
RegPair("st1", {"mm1"}),
128-
RegPair("st2", {"mm2"}),
129-
RegPair("st3", {"mm3"}),
130-
RegPair("st4", {"mm4"}),
131-
RegPair("st5", {"mm5"}),
132-
RegPair("st6", {"mm6"}),
133-
RegPair("st7", {"mm7"}),
134-
}};
135-
136-
// regs from gpr_basenames, in list order
137-
std::vector<uint32_t> gpr_base_reg_indices;
138-
// st0..st7, in list order
139-
std::vector<uint32_t> st_reg_indices;
140-
// map used for fast register lookups
154+
// primary map from a base register to its subregisters
155+
BaseRegToRegsMap base_reg_map = makeBaseRegMap(gpr_base_size == 8);
156+
// set used for fast matching of register names to subregisters
141157
llvm::SmallDenseSet<llvm::StringRef, 64> subreg_name_set;
142-
143-
// put all subreg names into the lookup set
144-
for (const RegisterMap &regset : {gpr_regs, st_regs}) {
145-
for (const RegPair &kv : regset)
146-
subreg_name_set.insert(kv.second.begin(), kv.second.end());
158+
// convenience array providing access to all subregisters of given kind,
159+
// sorted by base register index
160+
std::array<llvm::SmallVector<RegData *, 16>, RegKindCount> subreg_by_kind;
161+
162+
// prepare the set of all known subregisters
163+
for (const auto &x : base_reg_map) {
164+
for (const auto &subreg : x.second)
165+
subreg_name_set.insert(subreg.subreg_name);
147166
}
148167

168+
// iterate over all registers
149169
for (const auto &x : llvm::enumerate(regs)) {
150170
llvm::StringRef reg_name = x.value().name.GetStringRef();
151-
// find expected base registers
152-
if (gpr_regs.find(reg_name) != gpr_regs.end())
153-
gpr_base_reg_indices.push_back(x.index());
154-
else if (st_regs.find(reg_name) != st_regs.end())
155-
st_reg_indices.push_back(x.index());
156171
// abort if at least one sub-register is already present
157-
else if (llvm::is_contained(subreg_name_set, reg_name))
172+
if (llvm::is_contained(subreg_name_set, reg_name))
158173
return;
174+
175+
auto found = base_reg_map.find(reg_name);
176+
if (found == base_reg_map.end())
177+
continue;
178+
179+
for (auto &subreg : found->second) {
180+
// fill in base register indices
181+
subreg.base_index = x.index();
182+
// fill subreg_by_kind map-array
183+
subreg_by_kind[static_cast<size_t>(subreg.subreg_kind)].push_back(
184+
&subreg);
185+
}
159186
}
160187

161-
if (is64bit)
162-
addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
163-
RegKind::GPR32, eEncodingUint, eFormatHex, 4);
164-
addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
165-
RegKind::GPR16, eEncodingUint, eFormatHex, 2);
166-
addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
167-
RegKind::GPR8h, eEncodingUint, eFormatHex, 1, 1);
168-
addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
169-
RegKind::GPR8, eEncodingUint, eFormatHex, 1);
170-
171-
addPartialRegisters(regs, st_reg_indices, st_regs, 10, RegKind::MM,
172-
eEncodingUint, eFormatHex, 8);
188+
// now add registers by kind
189+
addPartialRegisters(regs, subreg_by_kind[GPR32], gpr_base_size, eEncodingUint,
190+
eFormatHex, 4);
191+
addPartialRegisters(regs, subreg_by_kind[GPR16], gpr_base_size, eEncodingUint,
192+
eFormatHex, 2);
193+
addPartialRegisters(regs, subreg_by_kind[GPR8h], gpr_base_size, eEncodingUint,
194+
eFormatHex, 1, 1);
195+
addPartialRegisters(regs, subreg_by_kind[GPR8], gpr_base_size, eEncodingUint,
196+
eFormatHex, 1);
197+
198+
addPartialRegisters(regs, subreg_by_kind[MM], 10, eEncodingUint, eFormatHex,
199+
8);
173200
}

0 commit comments

Comments
 (0)