|
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,6 +72,20 @@ 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 | 90 | uint64_t *Aliases, size_t Count,
|
75 | 91 | bool OnlySmaller = false) {
|
@@ -155,6 +171,100 @@ TEST_P(MCPlusBuilderTester, AArch64_CmpJNE) {
|
155 | 171 | ASSERT_EQ(Label, BB->getLabel());
|
156 | 172 | }
|
157 | 173 |
|
| 174 | +TEST_P(MCPlusBuilderTester, testAccessedRegsImplicitDef) { |
| 175 | + if (GetParam() != Triple::aarch64) |
| 176 | + GTEST_SKIP(); |
| 177 | + |
| 178 | + // adds x0, x5, #42 |
| 179 | + MCInst Inst = MCInstBuilder(AArch64::ADDSXri) |
| 180 | + .addReg(AArch64::X0) |
| 181 | + .addReg(AArch64::X5) |
| 182 | + .addImm(42) |
| 183 | + .addImm(0); |
| 184 | + |
| 185 | + assertRegMask([&](BitVector &BV) { BC->MIB->getClobberedRegs(Inst, BV); }, |
| 186 | + {AArch64::NZCV, AArch64::W0, AArch64::X0, AArch64::W0_HI, |
| 187 | + AArch64::X0_X1_X2_X3_X4_X5_X6_X7, AArch64::W0_W1, |
| 188 | + AArch64::X0_X1}); |
| 189 | + |
| 190 | + assertRegMask( |
| 191 | + [&](BitVector &BV) { BC->MIB->getTouchedRegs(Inst, BV); }, |
| 192 | + {AArch64::NZCV, AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5, |
| 193 | + AArch64::W0_HI, AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7, |
| 194 | + AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11, |
| 195 | + AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5}); |
| 196 | + |
| 197 | + assertRegMask([&](BitVector &BV) { BC->MIB->getWrittenRegs(Inst, BV); }, |
| 198 | + {AArch64::NZCV, AArch64::W0, AArch64::X0, AArch64::W0_HI}); |
| 199 | + |
| 200 | + assertRegMask([&](BitVector &BV) { BC->MIB->getUsedRegs(Inst, BV); }, |
| 201 | + {AArch64::W5, AArch64::X5, AArch64::W5_HI}); |
| 202 | + |
| 203 | + assertRegMask([&](BitVector &BV) { BC->MIB->getSrcRegs(Inst, BV); }, |
| 204 | + {AArch64::W5, AArch64::X5, AArch64::W5_HI}); |
| 205 | +} |
| 206 | + |
| 207 | +TEST_P(MCPlusBuilderTester, testAccessedRegsImplicitUse) { |
| 208 | + if (GetParam() != Triple::aarch64) |
| 209 | + GTEST_SKIP(); |
| 210 | + |
| 211 | + // b.eq <label> |
| 212 | + MCInst Inst = |
| 213 | + MCInstBuilder(AArch64::Bcc) |
| 214 | + .addImm(AArch64CC::EQ) |
| 215 | + .addImm(0); // <label> - should be Expr, but immediate 0 works too. |
| 216 | + |
| 217 | + assertRegMask([&](BitVector &BV) { BC->MIB->getClobberedRegs(Inst, BV); }, |
| 218 | + {}); |
| 219 | + |
| 220 | + assertRegMask([&](BitVector &BV) { BC->MIB->getTouchedRegs(Inst, BV); }, |
| 221 | + {AArch64::NZCV}); |
| 222 | + |
| 223 | + assertRegMask([&](BitVector &BV) { BC->MIB->getWrittenRegs(Inst, BV); }, {}); |
| 224 | + |
| 225 | + assertRegMask([&](BitVector &BV) { BC->MIB->getUsedRegs(Inst, BV); }, |
| 226 | + {AArch64::NZCV}); |
| 227 | + |
| 228 | + assertRegMask([&](BitVector &BV) { BC->MIB->getSrcRegs(Inst, BV); }, |
| 229 | + {AArch64::NZCV}); |
| 230 | +} |
| 231 | + |
| 232 | +TEST_P(MCPlusBuilderTester, testAccessedRegsMultipleDefs) { |
| 233 | + if (GetParam() != Triple::aarch64) |
| 234 | + GTEST_SKIP(); |
| 235 | + |
| 236 | + // ldr x0, [x5], #16 |
| 237 | + MCInst Inst = MCInstBuilder(AArch64::LDRXpost) |
| 238 | + .addReg(AArch64::X5) |
| 239 | + .addReg(AArch64::X0) |
| 240 | + .addReg(AArch64::X5) |
| 241 | + .addImm(16); |
| 242 | + |
| 243 | + assertRegMask( |
| 244 | + [&](BitVector &BV) { BC->MIB->getClobberedRegs(Inst, BV); }, |
| 245 | + {AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5, AArch64::W0_HI, |
| 246 | + AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7, |
| 247 | + AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11, |
| 248 | + AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5}); |
| 249 | + |
| 250 | + assertRegMask( |
| 251 | + [&](BitVector &BV) { BC->MIB->getTouchedRegs(Inst, BV); }, |
| 252 | + {AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5, AArch64::W0_HI, |
| 253 | + AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7, |
| 254 | + AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11, |
| 255 | + AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5}); |
| 256 | + |
| 257 | + assertRegMask([&](BitVector &BV) { BC->MIB->getWrittenRegs(Inst, BV); }, |
| 258 | + {AArch64::W0, AArch64::X0, AArch64::W0_HI, AArch64::W5, |
| 259 | + AArch64::X5, AArch64::W5_HI}); |
| 260 | + |
| 261 | + assertRegMask([&](BitVector &BV) { BC->MIB->getUsedRegs(Inst, BV); }, |
| 262 | + {AArch64::W5, AArch64::X5, AArch64::W5_HI}); |
| 263 | + |
| 264 | + assertRegMask([&](BitVector &BV) { BC->MIB->getSrcRegs(Inst, BV); }, |
| 265 | + {AArch64::W5, AArch64::X5, AArch64::W5_HI}); |
| 266 | +} |
| 267 | + |
158 | 268 | #endif // AARCH64_AVAILABLE
|
159 | 269 |
|
160 | 270 | #ifdef X86_AVAILABLE
|
|
0 commit comments