@@ -33,36 +33,40 @@ void ABIX86::Terminate() {
33
33
ABIWindows_x86_64::Terminate ();
34
34
}
35
35
36
- enum class RegKind {
37
- GPR32 = 0 ,
36
+ namespace {
37
+ enum RegKind {
38
+ GPR32,
38
39
GPR16,
39
40
GPR8h,
40
41
GPR8,
42
+ MM,
43
+ YMM_YMMh,
44
+ YMM_XMM,
41
45
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;
43
54
};
44
55
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> ®s,
51
- llvm::ArrayRef<uint32_t > base_reg_indices, const RegisterMap ®_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> ®s,
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 ();
58
64
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)
62
66
continue ;
63
67
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 ),
66
70
lldb_private::ConstString (),
67
71
lldb_private::ConstString (" supplementary registers" ),
68
72
subreg_size,
@@ -77,10 +81,112 @@ static void addPartialRegisters(
77
81
{},
78
82
subreg_offset};
79
83
80
- addSupplementaryRegister (regs, subreg);
84
+ addSupplementaryRegister (regs, new_reg);
85
+ }
86
+ }
87
+
88
+ static void
89
+ addCombinedRegisters (std::vector<DynamicRegisterInfo::Register> ®s,
90
+ llvm::ArrayRef<RegData *> subregs1,
91
+ llvm::ArrayRef<RegData *> subregs2, uint32_t base_size,
92
+ lldb::Encoding encoding, lldb::Format format) {
93
+ for (auto it : llvm::zip (subregs1, subregs2)) {
94
+ RegData *regdata1, *regdata2;
95
+ std::tie (regdata1, regdata2) = it;
96
+ assert (regdata1);
97
+ assert (regdata2);
98
+
99
+ // verify that we've got matching target registers
100
+ if (regdata1->subreg_name != regdata2->subreg_name )
101
+ continue ;
102
+
103
+ uint32_t base_index1 = regdata1->base_index .getValue ();
104
+ uint32_t base_index2 = regdata2->base_index .getValue ();
105
+ if (regs[base_index1].byte_size != base_size ||
106
+ regs[base_index2].byte_size != base_size)
107
+ continue ;
108
+
109
+ lldb_private::DynamicRegisterInfo::Register new_reg{
110
+ lldb_private::ConstString (regdata1->subreg_name ),
111
+ lldb_private::ConstString (),
112
+ lldb_private::ConstString (" supplementary registers" ),
113
+ base_size * 2 ,
114
+ LLDB_INVALID_INDEX32,
115
+ encoding,
116
+ format,
117
+ LLDB_INVALID_REGNUM,
118
+ LLDB_INVALID_REGNUM,
119
+ LLDB_INVALID_REGNUM,
120
+ LLDB_INVALID_REGNUM,
121
+ {base_index1, base_index2},
122
+ {}};
123
+
124
+ addSupplementaryRegister (regs, new_reg);
81
125
}
82
126
}
83
127
128
+ typedef llvm::SmallDenseMap<llvm::StringRef, llvm::SmallVector<RegData, 4 >, 64 >
129
+ BaseRegToRegsMap;
130
+
131
+ #define GPRh (l ) \
132
+ { \
133
+ is64bit ? BaseRegToRegsMap::value_type (" r" l " x" , {{GPR32, " e" l " x" }, \
134
+ {GPR16, l " x" }, \
135
+ {GPR8h, l " h" }, \
136
+ {GPR8, l " l" }}) \
137
+ : BaseRegToRegsMap::value_type ( \
138
+ " e" l " x" , {{GPR16, l " x" }, {GPR8h, l " h" }, {GPR8, l " l" }}) \
139
+ }
140
+
141
+ #define GPR (r16 ) \
142
+ { \
143
+ is64bit ? BaseRegToRegsMap::value_type ( \
144
+ " r" r16, {{GPR32, " e" r16}, {GPR16, r16}, {GPR8, r16 " l" }}) \
145
+ : BaseRegToRegsMap::value_type (" e" r16, \
146
+ {{GPR16, r16}, {GPR8, r16 " l" }}) \
147
+ }
148
+
149
+ #define GPR64 (n ) \
150
+ { \
151
+ BaseRegToRegsMap::value_type ( \
152
+ " r" #n, \
153
+ {{GPR32, " r" #n " d" }, {GPR16, " r" #n " w" }, {GPR8, " r" #n " l" }}) \
154
+ }
155
+
156
+ #define STMM (n ) \
157
+ { BaseRegToRegsMap::value_type (" st" #n, {{MM, " mm" #n}}) }
158
+
159
+ #define YMM (n ) \
160
+ {BaseRegToRegsMap::value_type (" ymm" #n " h" , {{YMM_YMMh, " ymm" #n}})}, { \
161
+ BaseRegToRegsMap::value_type (" xmm" #n, {{YMM_XMM, " ymm" #n}}) \
162
+ }
163
+
164
+ BaseRegToRegsMap makeBaseRegMap (bool is64bit) {
165
+ BaseRegToRegsMap out{
166
+ {// GPRs common to amd64 & i386
167
+ GPRh (" a" ), GPRh (" b" ), GPRh (" c" ), GPRh (" d" ), GPR (" si" ), GPR (" di" ),
168
+ GPR (" bp" ), GPR (" sp" ),
169
+
170
+ // ST/MM registers
171
+ STMM (0 ), STMM (1 ), STMM (2 ), STMM (3 ), STMM (4 ), STMM (5 ), STMM (6 ), STMM (7 ),
172
+
173
+ // lower YMM registers (common to amd64 & i386)
174
+ YMM (0 ), YMM (1 ), YMM (2 ), YMM (3 ), YMM (4 ), YMM (5 ), YMM (6 ), YMM (7 )}};
175
+
176
+ if (is64bit) {
177
+ BaseRegToRegsMap amd64_regs{{// GPRs specific to amd64
178
+ GPR64 (8 ), GPR64 (9 ), GPR64 (10 ), GPR64 (11 ),
179
+ GPR64 (12 ), GPR64 (13 ), GPR64 (14 ), GPR64 (15 ),
180
+
181
+ // higher YMM registers (specific to amd64)
182
+ YMM (8 ), YMM (9 ), YMM (10 ), YMM (11 ), YMM (12 ),
183
+ YMM (13 ), YMM (14 ), YMM (15 )}};
184
+ out.insert (amd64_regs.begin (), amd64_regs.end ());
185
+ }
186
+
187
+ return out;
188
+ }
189
+
84
190
void ABIX86::AugmentRegisterInfo (
85
191
std::vector<DynamicRegisterInfo::Register> ®s) {
86
192
MCBasedABI::AugmentRegisterInfo (regs);
@@ -91,83 +197,54 @@ void ABIX86::AugmentRegisterInfo(
91
197
92
198
uint32_t gpr_base_size =
93
199
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
- }
124
200
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
201
+ // primary map from a base register to its subregisters
202
+ BaseRegToRegsMap base_reg_map = makeBaseRegMap (gpr_base_size == 8 );
203
+ // set used for fast matching of register names to subregisters
141
204
llvm::SmallDenseSet<llvm::StringRef, 64 > subreg_name_set;
142
-
143
- // put all subreg names into the lookup set
144
- for (const RegisterMap ®set : {gpr_regs, st_regs}) {
145
- for (const RegPair &kv : regset)
146
- subreg_name_set.insert (kv.second .begin (), kv.second .end ());
205
+ // convenience array providing access to all subregisters of given kind,
206
+ // sorted by base register index
207
+ std::array<llvm::SmallVector<RegData *, 16 >, RegKindCount> subreg_by_kind;
208
+
209
+ // prepare the set of all known subregisters
210
+ for (const auto &x : base_reg_map) {
211
+ for (const auto &subreg : x.second )
212
+ subreg_name_set.insert (subreg.subreg_name );
147
213
}
148
214
215
+ // iterate over all registers
149
216
for (const auto &x : llvm::enumerate (regs)) {
150
217
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 ());
156
218
// abort if at least one sub-register is already present
157
- else if (llvm::is_contained (subreg_name_set, reg_name))
219
+ if (llvm::is_contained (subreg_name_set, reg_name))
158
220
return ;
221
+
222
+ auto found = base_reg_map.find (reg_name);
223
+ if (found == base_reg_map.end ())
224
+ continue ;
225
+
226
+ for (auto &subreg : found->second ) {
227
+ // fill in base register indices
228
+ subreg.base_index = x.index ();
229
+ // fill subreg_by_kind map-array
230
+ subreg_by_kind[static_cast <size_t >(subreg.subreg_kind )].push_back (
231
+ &subreg);
232
+ }
159
233
}
160
234
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 );
235
+ // now add registers by kind
236
+ addPartialRegisters (regs, subreg_by_kind[GPR32], gpr_base_size, eEncodingUint,
237
+ eFormatHex, 4 );
238
+ addPartialRegisters (regs, subreg_by_kind[GPR16], gpr_base_size, eEncodingUint,
239
+ eFormatHex, 2 );
240
+ addPartialRegisters (regs, subreg_by_kind[GPR8h], gpr_base_size, eEncodingUint,
241
+ eFormatHex, 1 , 1 );
242
+ addPartialRegisters (regs, subreg_by_kind[GPR8], gpr_base_size, eEncodingUint,
243
+ eFormatHex, 1 );
244
+
245
+ addPartialRegisters (regs, subreg_by_kind[MM], 10 , eEncodingUint, eFormatHex,
246
+ 8 );
247
+
248
+ addCombinedRegisters (regs, subreg_by_kind[YMM_XMM], subreg_by_kind[YMM_YMMh],
249
+ 16 , eEncodingVector, eFormatVectorOfUInt8);
173
250
}
0 commit comments