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: 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 29 static void SetUpTestCase() { 30 LLVMInitializeX86TargetInfo(); 31 LLVMInitializeX86Target(); 32 LLVMInitializeX86TargetMC(); 33 } 34 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 44 TEST_F(RegisterAliasingTest, TrackSimpleRegister) { 45 const auto &RegInfo = getMCRegInfo(); 46 const RegisterAliasingTracker tracker(RegInfo, llvm::X86::EAX); 47 const std::set<llvm::MCPhysReg> ActualAliasedRegisters( 48 tracker.aliasedBits().set_bits().begin(), 49 tracker.aliasedBits().set_bits().end()); 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 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 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