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