1 #include "RegisterAliasing.h"
2
3 #include <cassert>
4 #include <memory>
5
6 #include "X86InstrInfo.h"
7 #include "llvm/Support/TargetRegistry.h"
8 #include "llvm/Support/TargetSelect.h"
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
11
12 namespace exegesis {
13 namespace {
14
15 class RegisterAliasingTest : public ::testing::Test {
16 protected:
RegisterAliasingTest()17 RegisterAliasingTest() {
18 const std::string TT = "x86_64-unknown-linux";
19 std::string error;
20 const llvm::Target *const TheTarget =
21 llvm::TargetRegistry::lookupTarget(TT, error);
22 if (!TheTarget) {
23 llvm::errs() << error << "\n";
24 return;
25 }
26 MCRegInfo.reset(TheTarget->createMCRegInfo(TT));
27 }
28
SetUpTestCase()29 static void SetUpTestCase() {
30 LLVMInitializeX86TargetInfo();
31 LLVMInitializeX86Target();
32 LLVMInitializeX86TargetMC();
33 }
34
getMCRegInfo()35 const llvm::MCRegisterInfo &getMCRegInfo() {
36 assert(MCRegInfo);
37 return *MCRegInfo;
38 }
39
40 private:
41 std::unique_ptr<const llvm::MCRegisterInfo> MCRegInfo;
42 };
43
TEST_F(RegisterAliasingTest,TrackSimpleRegister)44 TEST_F(RegisterAliasingTest, TrackSimpleRegister) {
45 const auto &RegInfo = getMCRegInfo();
46 const RegisterAliasingTracker tracker(RegInfo, llvm::X86::EAX);
47 std::set<llvm::MCPhysReg> ActualAliasedRegisters;
48 for (unsigned I : tracker.aliasedBits().set_bits())
49 ActualAliasedRegisters.insert(static_cast<llvm::MCPhysReg>(I));
50 const std::set<llvm::MCPhysReg> ExpectedAliasedRegisters = {
51 llvm::X86::AL, llvm::X86::AH, llvm::X86::AX,
52 llvm::X86::EAX, llvm::X86::HAX, llvm::X86::RAX};
53 ASSERT_THAT(ActualAliasedRegisters, ExpectedAliasedRegisters);
54 for (llvm::MCPhysReg aliased : ExpectedAliasedRegisters) {
55 ASSERT_THAT(tracker.getOrigin(aliased), llvm::X86::EAX);
56 }
57 }
58
TEST_F(RegisterAliasingTest,TrackRegisterClass)59 TEST_F(RegisterAliasingTest, TrackRegisterClass) {
60 // The alias bits for GR8_ABCD_LRegClassID are the union of the alias bits for
61 // AL, BL, CL and DL.
62 const auto &RegInfo = getMCRegInfo();
63 const llvm::BitVector NoReservedReg(RegInfo.getNumRegs());
64
65 const RegisterAliasingTracker RegClassTracker(
66 RegInfo, NoReservedReg,
67 RegInfo.getRegClass(llvm::X86::GR8_ABCD_LRegClassID));
68
69 llvm::BitVector sum(RegInfo.getNumRegs());
70 sum |= RegisterAliasingTracker(RegInfo, llvm::X86::AL).aliasedBits();
71 sum |= RegisterAliasingTracker(RegInfo, llvm::X86::BL).aliasedBits();
72 sum |= RegisterAliasingTracker(RegInfo, llvm::X86::CL).aliasedBits();
73 sum |= RegisterAliasingTracker(RegInfo, llvm::X86::DL).aliasedBits();
74
75 ASSERT_THAT(RegClassTracker.aliasedBits(), sum);
76 }
77
TEST_F(RegisterAliasingTest,TrackRegisterClassCache)78 TEST_F(RegisterAliasingTest, TrackRegisterClassCache) {
79 // Fetching twice the same tracker yields the same pointers.
80 const auto &RegInfo = getMCRegInfo();
81 const llvm::BitVector NoReservedReg(RegInfo.getNumRegs());
82 RegisterAliasingTrackerCache Cache(RegInfo, NoReservedReg);
83 ASSERT_THAT(&Cache.getRegister(llvm::X86::AX),
84 &Cache.getRegister(llvm::X86::AX));
85
86 ASSERT_THAT(&Cache.getRegisterClass(llvm::X86::GR8_ABCD_LRegClassID),
87 &Cache.getRegisterClass(llvm::X86::GR8_ABCD_LRegClassID));
88 }
89
90 } // namespace
91 } // namespace exegesis
92