#include "RegisterAliasing.h" #include #include #include "X86InstrInfo.h" #include "llvm/Support/Host.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "gmock/gmock.h" #include "gtest/gtest.h" namespace exegesis { namespace { class RegisterAliasingTest : public ::testing::Test { protected: RegisterAliasingTest() { const std::string TT = llvm::sys::getProcessTriple(); std::string error; const llvm::Target *const TheTarget = llvm::TargetRegistry::lookupTarget(TT, error); assert(TheTarget); MCRegInfo.reset(TheTarget->createMCRegInfo(TT)); } static void SetUpTestCase() { llvm::InitializeNativeTarget(); } const llvm::MCRegisterInfo &getMCRegInfo() { return *MCRegInfo; } private: std::unique_ptr MCRegInfo; }; TEST_F(RegisterAliasingTest, TrackSimpleRegister) { const auto &RegInfo = getMCRegInfo(); const RegisterAliasingTracker tracker(RegInfo, llvm::X86::EAX); const std::set ActualAliasedRegisters( tracker.aliasedBits().set_bits().begin(), tracker.aliasedBits().set_bits().end()); const std::set ExpectedAliasedRegisters = { llvm::X86::AL, llvm::X86::AH, llvm::X86::AX, llvm::X86::EAX, llvm::X86::HAX, llvm::X86::RAX}; ASSERT_THAT(ActualAliasedRegisters, ExpectedAliasedRegisters); for (llvm::MCPhysReg aliased : ExpectedAliasedRegisters) { ASSERT_THAT(tracker.getOrigin(aliased), llvm::X86::EAX); } } TEST_F(RegisterAliasingTest, TrackRegisterClass) { // The alias bits for GR8_ABCD_LRegClassID are the union of the alias bits for // AL, BL, CL and DL. const auto &RegInfo = getMCRegInfo(); const llvm::BitVector NoReservedReg(RegInfo.getNumRegs()); const RegisterAliasingTracker RegClassTracker( RegInfo, NoReservedReg, RegInfo.getRegClass(llvm::X86::GR8_ABCD_LRegClassID)); llvm::BitVector sum(RegInfo.getNumRegs()); sum |= RegisterAliasingTracker(RegInfo, llvm::X86::AL).aliasedBits(); sum |= RegisterAliasingTracker(RegInfo, llvm::X86::BL).aliasedBits(); sum |= RegisterAliasingTracker(RegInfo, llvm::X86::CL).aliasedBits(); sum |= RegisterAliasingTracker(RegInfo, llvm::X86::DL).aliasedBits(); ASSERT_THAT(RegClassTracker.aliasedBits(), sum); } TEST_F(RegisterAliasingTest, TrackRegisterClassCache) { // Fetching twice the same tracker yields the same pointers. const auto &RegInfo = getMCRegInfo(); const llvm::BitVector NoReservedReg(RegInfo.getNumRegs()); RegisterAliasingTrackerCache Cache(RegInfo, NoReservedReg); ASSERT_THAT(&Cache.getRegister(llvm::X86::AX), &Cache.getRegister(llvm::X86::AX)); ASSERT_THAT(&Cache.getRegisterClass(llvm::X86::GR8_ABCD_LRegClassID), &Cache.getRegisterClass(llvm::X86::GR8_ABCD_LRegClassID)); } } // namespace } // namespace exegesis