Index: llvm/trunk/tools/llvm-exegesis/lib/LlvmState.h =================================================================== --- llvm/trunk/tools/llvm-exegesis/lib/LlvmState.h +++ llvm/trunk/tools/llvm-exegesis/lib/LlvmState.h @@ -40,7 +40,8 @@ LLVMState(const std::string &CpuName); LLVMState(const std::string &Triple, - const std::string &CpuName); // For tests. + const std::string &CpuName, + const std::string &Features = ""); // For tests. const llvm::TargetMachine &getTargetMachine() const { return *TargetMachine; } std::unique_ptr createTargetMachine() const; Index: llvm/trunk/tools/llvm-exegesis/lib/LlvmState.cpp =================================================================== --- llvm/trunk/tools/llvm-exegesis/lib/LlvmState.cpp +++ llvm/trunk/tools/llvm-exegesis/lib/LlvmState.cpp @@ -22,15 +22,16 @@ namespace llvm { namespace exegesis { -LLVMState::LLVMState(const std::string &Triple, const std::string &CpuName) { +LLVMState::LLVMState(const std::string &Triple, const std::string &CpuName, + const std::string &Features) { std::string Error; const llvm::Target *const TheTarget = llvm::TargetRegistry::lookupTarget(Triple, Error); assert(TheTarget && "unknown target for host"); const llvm::TargetOptions Options; - TargetMachine.reset(static_cast( - TheTarget->createTargetMachine(Triple, CpuName, /*Features*/ "", Options, - llvm::Reloc::Model::Static))); + TargetMachine.reset( + static_cast(TheTarget->createTargetMachine( + Triple, CpuName, Features, Options, llvm::Reloc::Model::Static))); TheExegesisTarget = ExegesisTarget::lookup(TargetMachine->getTargetTriple()); if (!TheExegesisTarget) { llvm::errs() << "no exegesis target for " << Triple << ", using default\n"; @@ -45,8 +46,8 @@ LLVMState::LLVMState(const std::string &CpuName) : LLVMState(llvm::sys::getProcessTriple(), - CpuName.empty() ? llvm::sys::getHostCPUName().str() : CpuName) { -} + CpuName.empty() ? llvm::sys::getHostCPUName().str() : CpuName, + "") {} std::unique_ptr LLVMState::createTargetMachine() const { Index: llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp =================================================================== --- llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp +++ llvm/trunk/unittests/tools/llvm-exegesis/X86/TargetTest.cpp @@ -104,14 +104,7 @@ class X86TargetTest : public ::testing::Test { protected: - X86TargetTest(const char *Features) - : ExegesisTarget_(ExegesisTarget::lookup(llvm::Triple(kTriple))) { - EXPECT_THAT(ExegesisTarget_, NotNull()); - std::string error; - Target_ = llvm::TargetRegistry::lookupTarget(kTriple, error); - EXPECT_THAT(Target_, NotNull()); - STI_.reset(Target_->createMCSubtargetInfo(kTriple, "core2", Features)); - } + X86TargetTest(const char *Features) : State(kTriple, "core2", Features) {} static void SetUpTestCase() { LLVMInitializeX86TargetInfo(); @@ -121,12 +114,11 @@ } std::vector setRegTo(unsigned Reg, const APInt &Value) { - return ExegesisTarget_->setRegTo(*STI_, Reg, Value); + return State.getExegesisTarget().setRegTo(State.getSubtargetInfo(), Reg, + Value); } - const llvm::Target *Target_; - const ExegesisTarget *const ExegesisTarget_; - std::unique_ptr STI_; + LLVMState State; }; class Core2TargetTest : public X86TargetTest { @@ -360,8 +352,7 @@ IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 0), IsMovValueToStack(llvm::X86::MOV32mi, 0x00000000UL, 4), IsMovValueToStack(llvm::X86::MOV16mi, 0x0000UL, 8), - OpcodeIs(llvm::X86::LD_Fp80m), - IsStackDeallocate(10))); + OpcodeIs(llvm::X86::LD_Fp80m), IsStackDeallocate(10))); } TEST_F(Core2TargetTest, SetRegToFP1_4Bits) { @@ -371,8 +362,33 @@ IsMovValueToStack(llvm::X86::MOV32mi, 0x00000001UL, 0), IsMovValueToStack(llvm::X86::MOV32mi, 0x00000000UL, 4), IsMovValueToStack(llvm::X86::MOV16mi, 0x0000UL, 8), - OpcodeIs(llvm::X86::LD_Fp80m), - IsStackDeallocate(10))); + OpcodeIs(llvm::X86::LD_Fp80m), IsStackDeallocate(10))); +} + +TEST_F(Core2Avx512TargetTest, FillMemoryOperands_ADD64rm) { + Instruction I(State.getInstrInfo(), State.getRATC(), X86::ADD64rm); + InstructionTemplate IT(I); + constexpr const int kOffset = 42; + State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset); + // Memory is operands 2-6. + EXPECT_THAT(IT.getValueFor(I.Operands[2]), IsReg(X86::RDI)); + EXPECT_THAT(IT.getValueFor(I.Operands[3]), IsImm(1)); + EXPECT_THAT(IT.getValueFor(I.Operands[4]), IsReg(0)); + EXPECT_THAT(IT.getValueFor(I.Operands[5]), IsImm(kOffset)); + EXPECT_THAT(IT.getValueFor(I.Operands[6]), IsReg(0)); +} + +TEST_F(Core2Avx512TargetTest, FillMemoryOperands_VGATHERDPSZ128rm) { + Instruction I(State.getInstrInfo(), State.getRATC(), X86::VGATHERDPSZ128rm); + InstructionTemplate IT(I); + constexpr const int kOffset = 42; + State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset); + // Memory is operands 4-8. + EXPECT_THAT(IT.getValueFor(I.Operands[4]), IsReg(X86::RDI)); + EXPECT_THAT(IT.getValueFor(I.Operands[5]), IsImm(1)); + EXPECT_THAT(IT.getValueFor(I.Operands[6]), IsReg(0)); + EXPECT_THAT(IT.getValueFor(I.Operands[7]), IsImm(kOffset)); + EXPECT_THAT(IT.getValueFor(I.Operands[8]), IsReg(0)); } } // namespace