|
| 1 | +#ifdef AARCH64_AVAILABLE |
| 2 | +#include "AArch64Subtarget.h" |
| 3 | +#endif // AARCH64_AVAILABLE |
| 4 | + |
| 5 | +#ifdef X86_AVAILABLE |
| 6 | +#include "X86Subtarget.h" |
| 7 | +#endif // X86_AVAILABLE |
| 8 | + |
| 9 | +#include "bolt/Rewrite/RewriteInstance.h" |
| 10 | +#include "llvm/BinaryFormat/ELF.h" |
| 11 | +#include "llvm/DebugInfo/DWARF/DWARFContext.h" |
| 12 | +#include "llvm/Object/ELFObjectFile.h" |
| 13 | +#include "llvm/Support/TargetSelect.h" |
| 14 | +#include "gtest/gtest.h" |
| 15 | + |
| 16 | +using namespace llvm; |
| 17 | +using namespace llvm::object; |
| 18 | +using namespace llvm::ELF; |
| 19 | +using namespace bolt; |
| 20 | + |
| 21 | +namespace { |
| 22 | +struct MCPlusBuilderTester : public testing::TestWithParam<Triple::ArchType> { |
| 23 | + void SetUp() override { |
| 24 | + initalizeLLVM(); |
| 25 | + prepareElf(); |
| 26 | + initializeBolt(); |
| 27 | + } |
| 28 | + |
| 29 | +protected: |
| 30 | + void initalizeLLVM() { |
| 31 | + llvm::InitializeAllTargetInfos(); |
| 32 | + llvm::InitializeAllTargetMCs(); |
| 33 | + llvm::InitializeAllAsmParsers(); |
| 34 | + llvm::InitializeAllDisassemblers(); |
| 35 | + llvm::InitializeAllTargets(); |
| 36 | + llvm::InitializeAllAsmPrinters(); |
| 37 | + } |
| 38 | + |
| 39 | + void prepareElf() { |
| 40 | + memcpy(ElfBuf, "\177ELF", 4); |
| 41 | + ELF64LE::Ehdr *EHdr = reinterpret_cast<typename ELF64LE::Ehdr *>(ElfBuf); |
| 42 | + EHdr->e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS64; |
| 43 | + EHdr->e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB; |
| 44 | + EHdr->e_machine = GetParam() == Triple::aarch64 ? EM_AARCH64 : EM_X86_64; |
| 45 | + MemoryBufferRef Source(StringRef(ElfBuf, sizeof(ElfBuf)), "ELF"); |
| 46 | + ObjFile = cantFail(ObjectFile::createObjectFile(Source)); |
| 47 | + } |
| 48 | + |
| 49 | + void initializeBolt() { |
| 50 | + BC = BinaryContext::createBinaryContext( |
| 51 | + ObjFile.get(), true, DWARFContext::create(*ObjFile.get())); |
| 52 | + ASSERT_FALSE(!BC); |
| 53 | + BC->initializeTarget(std::unique_ptr<MCPlusBuilder>(createMCPlusBuilder( |
| 54 | + GetParam(), BC->MIA.get(), BC->MII.get(), BC->MRI.get()))); |
| 55 | + } |
| 56 | + |
| 57 | + void testRegAliases(Triple::ArchType Arch, uint64_t Register, |
| 58 | + uint64_t *Aliases, size_t Count, |
| 59 | + bool OnlySmaller = false) { |
| 60 | + if (GetParam() != Arch) |
| 61 | + GTEST_SKIP(); |
| 62 | + |
| 63 | + const BitVector &BV = BC->MIB->getAliases(Register, OnlySmaller); |
| 64 | + ASSERT_EQ(BV.count(), Count); |
| 65 | + for (size_t I = 0; I < Count; ++I) |
| 66 | + ASSERT_TRUE(BV[Aliases[I]]); |
| 67 | + } |
| 68 | + |
| 69 | + char ElfBuf[sizeof(typename ELF64LE::Ehdr)] = {}; |
| 70 | + std::unique_ptr<ObjectFile> ObjFile; |
| 71 | + std::unique_ptr<BinaryContext> BC; |
| 72 | +}; |
| 73 | +} // namespace |
| 74 | + |
| 75 | +#ifdef AARCH64_AVAILABLE |
| 76 | + |
| 77 | +INSTANTIATE_TEST_SUITE_P(AArch64, MCPlusBuilderTester, |
| 78 | + ::testing::Values(Triple::aarch64)); |
| 79 | + |
| 80 | +TEST_P(MCPlusBuilderTester, AliasX0) { |
| 81 | + uint64_t AliasesX0[] = {AArch64::W0, AArch64::X0, AArch64::W0_W1, |
| 82 | + AArch64::X0_X1, AArch64::X0_X1_X2_X3_X4_X5_X6_X7}; |
| 83 | + size_t AliasesX0Count = sizeof(AliasesX0) / sizeof(*AliasesX0); |
| 84 | + testRegAliases(Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count); |
| 85 | +} |
| 86 | + |
| 87 | +TEST_P(MCPlusBuilderTester, AliasSmallerX0) { |
| 88 | + uint64_t AliasesX0[] = {AArch64::W0, AArch64::X0}; |
| 89 | + size_t AliasesX0Count = sizeof(AliasesX0) / sizeof(*AliasesX0); |
| 90 | + testRegAliases(Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count, true); |
| 91 | +} |
| 92 | + |
| 93 | +#endif // AARCH64_AVAILABLE |
| 94 | + |
| 95 | +#ifdef X86_AVAILABLE |
| 96 | + |
| 97 | +INSTANTIATE_TEST_SUITE_P(X86, MCPlusBuilderTester, |
| 98 | + ::testing::Values(Triple::x86_64)); |
| 99 | + |
| 100 | +TEST_P(MCPlusBuilderTester, AliasAX) { |
| 101 | + uint64_t AliasesAX[] = {X86::RAX, X86::EAX, X86::AX, X86::AL, X86::AH}; |
| 102 | + size_t AliasesAXCount = sizeof(AliasesAX) / sizeof(*AliasesAX); |
| 103 | + testRegAliases(Triple::x86_64, X86::AX, AliasesAX, AliasesAXCount); |
| 104 | +} |
| 105 | + |
| 106 | +TEST_P(MCPlusBuilderTester, AliasSmallerAX) { |
| 107 | + uint64_t AliasesAX[] = {X86::AX, X86::AL, X86::AH}; |
| 108 | + size_t AliasesAXCount = sizeof(AliasesAX) / sizeof(*AliasesAX); |
| 109 | + testRegAliases(Triple::x86_64, X86::AX, AliasesAX, AliasesAXCount, true); |
| 110 | +} |
| 111 | + |
| 112 | +#endif // X86_AVAILABLE |
0 commit comments