8
8
9
9
#ifdef AARCH64_AVAILABLE
10
10
#include " AArch64Subtarget.h"
11
+ #include " MCTargetDesc/AArch64MCTargetDesc.h"
11
12
#endif // AARCH64_AVAILABLE
12
13
13
14
#ifdef X86_AVAILABLE
19
20
#include " bolt/Rewrite/RewriteInstance.h"
20
21
#include " llvm/BinaryFormat/ELF.h"
21
22
#include " llvm/DebugInfo/DWARF/DWARFContext.h"
23
+ #include " llvm/MC/MCInstBuilder.h"
22
24
#include " llvm/Support/TargetSelect.h"
23
25
#include " gtest/gtest.h"
24
26
@@ -70,16 +72,28 @@ struct MCPlusBuilderTester : public testing::TestWithParam<Triple::ArchType> {
70
72
BC->MRI .get (), BC->STI .get ())));
71
73
}
72
74
75
+ void assertRegMask (const BitVector &RegMask,
76
+ std::initializer_list<MCPhysReg> ExpectedRegs) {
77
+ ASSERT_EQ (RegMask.count (), ExpectedRegs.size ());
78
+ for (MCPhysReg Reg : ExpectedRegs)
79
+ ASSERT_TRUE (RegMask[Reg]) << " Expected " << BC->MRI ->getName (Reg) << " ." ;
80
+ }
81
+
82
+ void assertRegMask (std::function<void (BitVector &)> FillRegMask,
83
+ std::initializer_list<MCPhysReg> ExpectedRegs) {
84
+ BitVector RegMask (BC->MRI ->getNumRegs ());
85
+ FillRegMask (RegMask);
86
+ assertRegMask (RegMask, ExpectedRegs);
87
+ }
88
+
73
89
void testRegAliases (Triple::ArchType Arch, uint64_t Register,
74
- uint64_t *Aliases, size_t Count ,
90
+ std::initializer_list<MCPhysReg> ExpectedAliases ,
75
91
bool OnlySmaller = false ) {
76
92
if (GetParam () != Arch)
77
93
GTEST_SKIP ();
78
94
79
95
const BitVector &BV = BC->MIB ->getAliases (Register, OnlySmaller);
80
- ASSERT_EQ (BV.count (), Count);
81
- for (size_t I = 0 ; I < Count; ++I)
82
- ASSERT_TRUE (BV[Aliases[I]]);
96
+ assertRegMask (BV, ExpectedAliases);
83
97
}
84
98
85
99
char ElfBuf[sizeof (typename ELF64LE::Ehdr)] = {};
@@ -94,17 +108,15 @@ INSTANTIATE_TEST_SUITE_P(AArch64, MCPlusBuilderTester,
94
108
::testing::Values (Triple::aarch64));
95
109
96
110
TEST_P (MCPlusBuilderTester, AliasX0) {
97
- uint64_t AliasesX0[] = {AArch64::W0, AArch64::W0_HI,
98
- AArch64::X0, AArch64::W0_W1,
99
- AArch64::X0_X1, AArch64::X0_X1_X2_X3_X4_X5_X6_X7};
100
- size_t AliasesX0Count = sizeof (AliasesX0) / sizeof (*AliasesX0);
101
- testRegAliases (Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count);
111
+ testRegAliases (Triple::aarch64, AArch64::X0,
112
+ {AArch64::W0, AArch64::W0_HI, AArch64::X0, AArch64::W0_W1,
113
+ AArch64::X0_X1, AArch64::X0_X1_X2_X3_X4_X5_X6_X7});
102
114
}
103
115
104
116
TEST_P (MCPlusBuilderTester, AliasSmallerX0) {
105
- uint64_t AliasesX0[] = {AArch64::W0 , AArch64::W0_HI, AArch64::X0};
106
- size_t AliasesX0Count = sizeof (AliasesX0) / sizeof (*AliasesX0);
107
- testRegAliases (Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count, true );
117
+ testRegAliases (Triple::aarch64 , AArch64::X0,
118
+ {AArch64::W0, AArch64::W0_HI, AArch64::X0},
119
+ /* OnlySmaller= */ true );
108
120
}
109
121
110
122
TEST_P (MCPlusBuilderTester, AArch64_CmpJE) {
@@ -155,6 +167,100 @@ TEST_P(MCPlusBuilderTester, AArch64_CmpJNE) {
155
167
ASSERT_EQ (Label, BB->getLabel ());
156
168
}
157
169
170
+ TEST_P (MCPlusBuilderTester, testAccessedRegsImplicitDef) {
171
+ if (GetParam () != Triple::aarch64)
172
+ GTEST_SKIP ();
173
+
174
+ // adds x0, x5, #42
175
+ MCInst Inst = MCInstBuilder (AArch64::ADDSXri)
176
+ .addReg (AArch64::X0)
177
+ .addReg (AArch64::X5)
178
+ .addImm (42 )
179
+ .addImm (0 );
180
+
181
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getClobberedRegs (Inst, BV); },
182
+ {AArch64::NZCV, AArch64::W0, AArch64::X0, AArch64::W0_HI,
183
+ AArch64::X0_X1_X2_X3_X4_X5_X6_X7, AArch64::W0_W1,
184
+ AArch64::X0_X1});
185
+
186
+ assertRegMask (
187
+ [&](BitVector &BV) { BC->MIB ->getTouchedRegs (Inst, BV); },
188
+ {AArch64::NZCV, AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5,
189
+ AArch64::W0_HI, AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7,
190
+ AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11,
191
+ AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5});
192
+
193
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getWrittenRegs (Inst, BV); },
194
+ {AArch64::NZCV, AArch64::W0, AArch64::X0, AArch64::W0_HI});
195
+
196
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getUsedRegs (Inst, BV); },
197
+ {AArch64::W5, AArch64::X5, AArch64::W5_HI});
198
+
199
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getSrcRegs (Inst, BV); },
200
+ {AArch64::W5, AArch64::X5, AArch64::W5_HI});
201
+ }
202
+
203
+ TEST_P (MCPlusBuilderTester, testAccessedRegsImplicitUse) {
204
+ if (GetParam () != Triple::aarch64)
205
+ GTEST_SKIP ();
206
+
207
+ // b.eq <label>
208
+ MCInst Inst =
209
+ MCInstBuilder (AArch64::Bcc)
210
+ .addImm (AArch64CC::EQ)
211
+ .addImm (0 ); // <label> - should be Expr, but immediate 0 works too.
212
+
213
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getClobberedRegs (Inst, BV); },
214
+ {});
215
+
216
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getTouchedRegs (Inst, BV); },
217
+ {AArch64::NZCV});
218
+
219
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getWrittenRegs (Inst, BV); }, {});
220
+
221
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getUsedRegs (Inst, BV); },
222
+ {AArch64::NZCV});
223
+
224
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getSrcRegs (Inst, BV); },
225
+ {AArch64::NZCV});
226
+ }
227
+
228
+ TEST_P (MCPlusBuilderTester, testAccessedRegsMultipleDefs) {
229
+ if (GetParam () != Triple::aarch64)
230
+ GTEST_SKIP ();
231
+
232
+ // ldr x0, [x5], #16
233
+ MCInst Inst = MCInstBuilder (AArch64::LDRXpost)
234
+ .addReg (AArch64::X5)
235
+ .addReg (AArch64::X0)
236
+ .addReg (AArch64::X5)
237
+ .addImm (16 );
238
+
239
+ assertRegMask (
240
+ [&](BitVector &BV) { BC->MIB ->getClobberedRegs (Inst, BV); },
241
+ {AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5, AArch64::W0_HI,
242
+ AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7,
243
+ AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11,
244
+ AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5});
245
+
246
+ assertRegMask (
247
+ [&](BitVector &BV) { BC->MIB ->getTouchedRegs (Inst, BV); },
248
+ {AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5, AArch64::W0_HI,
249
+ AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7,
250
+ AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11,
251
+ AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5});
252
+
253
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getWrittenRegs (Inst, BV); },
254
+ {AArch64::W0, AArch64::X0, AArch64::W0_HI, AArch64::W5,
255
+ AArch64::X5, AArch64::W5_HI});
256
+
257
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getUsedRegs (Inst, BV); },
258
+ {AArch64::W5, AArch64::X5, AArch64::W5_HI});
259
+
260
+ assertRegMask ([&](BitVector &BV) { BC->MIB ->getSrcRegs (Inst, BV); },
261
+ {AArch64::W5, AArch64::X5, AArch64::W5_HI});
262
+ }
263
+
158
264
#endif // AARCH64_AVAILABLE
159
265
160
266
#ifdef X86_AVAILABLE
@@ -163,15 +269,13 @@ INSTANTIATE_TEST_SUITE_P(X86, MCPlusBuilderTester,
163
269
::testing::Values (Triple::x86_64));
164
270
165
271
TEST_P (MCPlusBuilderTester, AliasAX) {
166
- uint64_t AliasesAX[] = {X86::RAX, X86::EAX, X86::AX, X86::AL, X86::AH};
167
- size_t AliasesAXCount = sizeof (AliasesAX) / sizeof (*AliasesAX);
168
- testRegAliases (Triple::x86_64, X86::AX, AliasesAX, AliasesAXCount);
272
+ testRegAliases (Triple::x86_64, X86::AX,
273
+ {X86::RAX, X86::EAX, X86::AX, X86::AL, X86::AH});
169
274
}
170
275
171
276
TEST_P (MCPlusBuilderTester, AliasSmallerAX) {
172
- uint64_t AliasesAX[] = {X86::AX, X86::AL, X86::AH};
173
- size_t AliasesAXCount = sizeof (AliasesAX) / sizeof (*AliasesAX);
174
- testRegAliases (Triple::x86_64, X86::AX, AliasesAX, AliasesAXCount, true );
277
+ testRegAliases (Triple::x86_64, X86::AX, {X86::AX, X86::AL, X86::AH},
278
+ /* OnlySmaller=*/ true );
175
279
}
176
280
177
281
TEST_P (MCPlusBuilderTester, ReplaceRegWithImm) {
0 commit comments