@@ -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,65 @@ static void addPartialRegisters(
77
81
{},
78
82
subreg_offset};
79
83
80
- addSupplementaryRegister (regs, subreg );
84
+ addSupplementaryRegister (regs, new_reg );
81
85
}
82
86
}
83
87
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
+
84
143
void ABIX86::AugmentRegisterInfo (
85
144
std::vector<DynamicRegisterInfo::Register> ®s) {
86
145
MCBasedABI::AugmentRegisterInfo (regs);
@@ -91,83 +150,51 @@ void ABIX86::AugmentRegisterInfo(
91
150
92
151
uint32_t gpr_base_size =
93
152
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
153
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
141
157
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 ());
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 );
147
166
}
148
167
168
+ // iterate over all registers
149
169
for (const auto &x : llvm::enumerate (regs)) {
150
170
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
171
// 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))
158
173
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
+ }
159
186
}
160
187
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 );
173
200
}
0 commit comments