diff options
| author | Guillaume Chatelet <gchatelet@google.com> | 2018-09-20 12:22:18 +0000 |
|---|---|---|
| committer | Guillaume Chatelet <gchatelet@google.com> | 2018-09-20 12:22:18 +0000 |
| commit | c96a97bac7296b11800866b1ccbadadfe0e6bd4b (patch) | |
| tree | 95199ea352a3c7d3a68b90a16a3734af31157405 /llvm/unittests/tools/llvm-exegesis | |
| parent | b00e0714e621fcf1cc56a46624f90cf15507a8db (diff) | |
| download | bcm5719-llvm-c96a97bac7296b11800866b1ccbadadfe0e6bd4b.tar.gz bcm5719-llvm-c96a97bac7296b11800866b1ccbadadfe0e6bd4b.zip | |
[llvm-exegesis] Improve Register Setup (roll forward of D51856).
Summary:
Added function to set a register to a particular value + tests.
Add EFLAGS test, use new setRegTo instead of setRegToConstant.
Reviewers: courbet, javed.absar
Subscribers: llvm-commits, tschuett, mgorny
Differential Revision: https://reviews.llvm.org/D52297
llvm-svn: 342644
Diffstat (limited to 'llvm/unittests/tools/llvm-exegesis')
6 files changed, 311 insertions, 204 deletions
diff --git a/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp index 9efa3561fff..b3066df4dfe 100644 --- a/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp @@ -15,11 +15,16 @@ void InitializeAArch64ExegesisTarget(); namespace { +using llvm::APInt; +using llvm::MCInst; using testing::Gt; +using testing::IsEmpty; +using testing::Not; using testing::NotNull; -using testing::SizeIs; -constexpr const char kTriple[] = "aarch64-unknown-linux"; +static const char kTriple[] = "aarch64-unknown-linux"; +static const char kGenericCpu[] = "generic"; +static const char kNoFeatures[] = ""; class AArch64TargetTest : public ::testing::Test { protected: @@ -29,7 +34,10 @@ protected: std::string error; Target_ = llvm::TargetRegistry::lookupTarget(kTriple, error); EXPECT_THAT(Target_, NotNull()); + STI_.reset( + Target_->createMCSubtargetInfo(kTriple, kGenericCpu, kNoFeatures)); } + static void SetUpTestCase() { LLVMInitializeAArch64TargetInfo(); LLVMInitializeAArch64Target(); @@ -37,9 +45,20 @@ protected: InitializeAArch64ExegesisTarget(); } + std::vector<MCInst> setRegTo(unsigned Reg, const APInt &Value) { + return ExegesisTarget_->setRegTo(*STI_, Reg, Value); + } + const llvm::Target *Target_; const ExegesisTarget *const ExegesisTarget_; + std::unique_ptr<llvm::MCSubtargetInfo> STI_; }; +TEST_F(AArch64TargetTest, SetRegToConstant) { + // The AArch64 target currently doesn't know how to set register values. + const auto Insts = setRegTo(llvm::AArch64::X0, llvm::APInt()); + EXPECT_THAT(Insts, Not(IsEmpty())); +} + } // namespace } // namespace exegesis diff --git a/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp b/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp index cca846354df..db8b9dfc3b7 100644 --- a/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp @@ -30,12 +30,11 @@ protected: }; TEST_F(ARMMachineFunctionGeneratorTest, DISABLED_JitFunction) { - Check(ExegesisTarget::getDefault(), {}, llvm::MCInst(), 0x1e, 0xff, 0x2f, - 0xe1); + Check({}, llvm::MCInst(), 0x1e, 0xff, 0x2f, 0xe1); } TEST_F(ARMMachineFunctionGeneratorTest, DISABLED_JitFunctionADDrr) { - Check(ExegesisTarget::getDefault(), {llvm::ARM::R0}, + Check({{llvm::ARM::R0, llvm::APInt()}}, MCInstBuilder(llvm::ARM::ADDrr) .addReg(llvm::ARM::R0) .addReg(llvm::ARM::R0) diff --git a/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h b/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h index 9265e3e5be9..cc00cee58e3 100644 --- a/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h +++ b/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h @@ -32,7 +32,9 @@ protected: const std::string &CpuName) : TT(TT), CpuName(CpuName), CanExecute(llvm::Triple(TT).getArch() == - llvm::Triple(llvm::sys::getProcessTriple()).getArch()) { + llvm::Triple(llvm::sys::getProcessTriple()).getArch()), + ET(ExegesisTarget::lookup(llvm::Triple(TT))) { + assert(ET); if (!CanExecute) { llvm::outs() << "Skipping execution, host:" << llvm::sys::getProcessTriple() << ", target:" << TT @@ -41,12 +43,12 @@ protected: } template <class... Bs> - inline void Check(const ExegesisTarget &ET, - llvm::ArrayRef<unsigned> RegsToDef, llvm::MCInst MCInst, - Bs... Bytes) { + inline void Check(llvm::ArrayRef<RegisterValue> RegisterInitialValues, + llvm::MCInst MCInst, Bs... Bytes) { ExecutableFunction Function = - (MCInst.getOpcode() == 0) ? assembleToFunction(ET, RegsToDef, {}) - : assembleToFunction(ET, RegsToDef, {MCInst}); + (MCInst.getOpcode() == 0) + ? assembleToFunction(RegisterInitialValues, {}) + : assembleToFunction(RegisterInitialValues, {MCInst}); ASSERT_THAT(Function.getFunctionBytes().str(), testing::ElementsAre(Bytes...)); if (CanExecute) { @@ -70,14 +72,12 @@ private: } ExecutableFunction - assembleToFunction(const ExegesisTarget &ET, - llvm::ArrayRef<unsigned> RegsToDef, + assembleToFunction(llvm::ArrayRef<RegisterValue> RegisterInitialValues, llvm::ArrayRef<llvm::MCInst> Instructions) { llvm::SmallString<256> Buffer; llvm::raw_svector_ostream AsmStream(Buffer); - assembleToStream(ET, createTargetMachine(), /*LiveIns=*/{}, - RegsToDef, Instructions, - AsmStream); + assembleToStream(*ET, createTargetMachine(), /*LiveIns=*/{}, + RegisterInitialValues, Instructions, AsmStream); return ExecutableFunction(createTargetMachine(), getObjectFromBuffer(AsmStream.str())); } @@ -85,6 +85,7 @@ private: const std::string TT; const std::string CpuName; const bool CanExecute; + const ExegesisTarget *const ET; }; } // namespace exegesis diff --git a/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp index e83d004e8a6..8e81106db8d 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp @@ -39,19 +39,12 @@ protected: }; TEST_F(X86MachineFunctionGeneratorTest, DISABLED_JitFunction) { - Check(ExegesisTarget::getDefault(), {}, llvm::MCInst(), 0xc3); -} - -TEST_F(X86MachineFunctionGeneratorTest, DISABLED_JitFunctionXOR32rr_Default) { - Check(ExegesisTarget::getDefault(), {EAX}, - MCInstBuilder(XOR32rr).addReg(EAX).addReg(EAX).addReg(EAX), 0x31, 0xc0, - 0xc3); + Check({}, llvm::MCInst(), 0xc3); } TEST_F(X86MachineFunctionGeneratorTest, DISABLED_JitFunctionXOR32rr_X86) { - const auto *ET = ExegesisTarget::lookup(llvm::Triple("x86_64-unknown-linux")); - ASSERT_NE(ET, nullptr); - Check(*ET, {EAX}, MCInstBuilder(XOR32rr).addReg(EAX).addReg(EAX).addReg(EAX), + Check({{EAX, llvm::APInt(32, 1)}}, + MCInstBuilder(XOR32rr).addReg(EAX).addReg(EAX).addReg(EAX), // mov eax, 1 0xb8, 0x01, 0x00, 0x00, 0x00, // xor eax, eax @@ -59,15 +52,13 @@ TEST_F(X86MachineFunctionGeneratorTest, DISABLED_JitFunctionXOR32rr_X86) { } TEST_F(X86MachineFunctionGeneratorTest, DISABLED_JitFunctionMOV64ri) { - Check(ExegesisTarget::getDefault(), {}, - MCInstBuilder(MOV64ri32).addReg(RAX).addImm(42), 0x48, 0xc7, 0xc0, 0x2a, - 0x00, 0x00, 0x00, 0xc3); + Check({}, MCInstBuilder(MOV64ri32).addReg(RAX).addImm(42), 0x48, 0xc7, 0xc0, + 0x2a, 0x00, 0x00, 0x00, 0xc3); } TEST_F(X86MachineFunctionGeneratorTest, DISABLED_JitFunctionMOV32ri) { - Check(ExegesisTarget::getDefault(), {}, - MCInstBuilder(MOV32ri).addReg(EAX).addImm(42), 0xb8, 0x2a, 0x00, 0x00, - 0x00, 0xc3); + Check({}, MCInstBuilder(MOV32ri).addReg(EAX).addImm(42), 0xb8, 0x2a, 0x00, + 0x00, 0x00, 0xc3); } } // namespace diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp index 0c255ac74e3..0ef2a707993 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp @@ -261,7 +261,13 @@ private: using FakeSnippetGeneratorTest = SnippetGeneratorTest<FakeSnippetGenerator>; -TEST_F(FakeSnippetGeneratorTest, ComputeRegsToDefAdd16ri) { +testing::Matcher<const RegisterValue &> IsRegisterValue(unsigned Reg, + llvm::APInt Value) { + return testing::AllOf(testing::Field(&RegisterValue::Register, Reg), + testing::Field(&RegisterValue::Value, Value)); +} + +TEST_F(FakeSnippetGeneratorTest, ComputeRegisterInitialValuesAdd16ri) { // ADD16ri: // explicit def 0 : reg RegClass=GR16 // explicit use 1 : reg RegClass=GR16 | TIED_TO:0 @@ -272,11 +278,11 @@ TEST_F(FakeSnippetGeneratorTest, ComputeRegsToDefAdd16ri) { llvm::MCOperand::createReg(llvm::X86::AX); std::vector<InstructionBuilder> Snippet; Snippet.push_back(std::move(IB)); - const auto RegsToDef = Generator.computeRegsToDef(Snippet); - EXPECT_THAT(RegsToDef, UnorderedElementsAre(llvm::X86::AX)); + const auto RIV = Generator.computeRegisterInitialValues(Snippet); + EXPECT_THAT(RIV, ElementsAre(IsRegisterValue(llvm::X86::AX, llvm::APInt()))); } -TEST_F(FakeSnippetGeneratorTest, ComputeRegsToDefAdd64rr) { +TEST_F(FakeSnippetGeneratorTest, ComputeRegisterInitialValuesAdd64rr) { // ADD64rr: // mov64ri rax, 42 // add64rr rax, rax, rbx @@ -298,8 +304,8 @@ TEST_F(FakeSnippetGeneratorTest, ComputeRegsToDefAdd64rr) { Snippet.push_back(std::move(Add)); } - const auto RegsToDef = Generator.computeRegsToDef(Snippet); - EXPECT_THAT(RegsToDef, UnorderedElementsAre(llvm::X86::RBX)); + const auto RIV = Generator.computeRegisterInitialValues(Snippet); + EXPECT_THAT(RIV, ElementsAre(IsRegisterValue(llvm::X86::RBX, llvm::APInt()))); } } // namespace diff --git a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp index b8533fb1116..bf5d57e116d 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp @@ -13,7 +13,7 @@ namespace llvm { -bool operator==(const llvm::MCOperand &a, const llvm::MCOperand &b) { +bool operator==(const MCOperand &a, const MCOperand &b) { if (a.isImm() && b.isImm()) return a.getImm() == b.getImm(); if (a.isReg() && b.isReg()) @@ -21,7 +21,7 @@ bool operator==(const llvm::MCOperand &a, const llvm::MCOperand &b) { return false; } -bool operator==(const llvm::MCInst &a, const llvm::MCInst &b) { +bool operator==(const MCInst &a, const MCInst &b) { if (a.getOpcode() != b.getOpcode()) return false; if (a.getNumOperands() != b.getNumOperands()) @@ -41,17 +41,71 @@ void InitializeX86ExegesisTarget(); namespace { +using testing::AllOf; using testing::ElementsAre; +using testing::ElementsAreArray; +using testing::Eq; using testing::Gt; +using testing::Matcher; using testing::NotNull; +using testing::Property; using testing::SizeIs; using llvm::APInt; using llvm::MCInst; using llvm::MCInstBuilder; +using llvm::MCOperand; -constexpr const char kTriple[] = "x86_64-unknown-linux"; +Matcher<MCOperand> IsImm(int64_t Value) { + return AllOf(Property(&MCOperand::isImm, Eq(true)), + Property(&MCOperand::getImm, Eq(Value))); +} + +Matcher<MCOperand> IsReg(unsigned Reg) { + return AllOf(Property(&MCOperand::isReg, Eq(true)), + Property(&MCOperand::getReg, Eq(Reg))); +} + +Matcher<MCInst> OpcodeIs(unsigned Opcode) { + return Property(&MCInst::getOpcode, Eq(Opcode)); +} + +Matcher<MCInst> IsMovImmediate(unsigned Opcode, int64_t Reg, int64_t Value) { + return AllOf(OpcodeIs(Opcode), ElementsAre(IsReg(Reg), IsImm(Value))); +} + +Matcher<MCInst> IsMovValueToStack(unsigned Opcode, int64_t Value, + size_t Offset) { + return AllOf(OpcodeIs(Opcode), + ElementsAre(IsReg(llvm::X86::RSP), IsImm(1), IsReg(0), + IsImm(Offset), IsReg(0), IsImm(Value))); +} + +Matcher<MCInst> IsMovValueFromStack(unsigned Opcode, unsigned Reg) { + return AllOf(OpcodeIs(Opcode), + ElementsAre(IsReg(Reg), IsReg(llvm::X86::RSP), IsImm(1), + IsReg(0), IsImm(0), IsReg(0))); +} + +Matcher<MCInst> IsStackAllocate(unsigned Size) { + return AllOf( + OpcodeIs(llvm::X86::SUB64ri8), + ElementsAre(IsReg(llvm::X86::RSP), IsReg(llvm::X86::RSP), IsImm(Size))); +} +Matcher<MCInst> IsStackDeallocate(unsigned Size) { + return AllOf( + OpcodeIs(llvm::X86::ADD64ri8), + ElementsAre(IsReg(llvm::X86::RSP), IsReg(llvm::X86::RSP), IsImm(Size))); +} + +static const char kTriple[] = "x86_64-unknown-linux"; +static const char kFeaturesEmpty[] = ""; +static const char kFeaturesAvx[] = "+avx"; +static const char kFeaturesAvx512VL[] = "+avx512vl"; +static const char kCpuCore2[] = "core2"; + +template <const char *CPU, const char *Features> class X86TargetTest : public ::testing::Test { protected: X86TargetTest() @@ -60,7 +114,9 @@ protected: std::string error; Target_ = llvm::TargetRegistry::lookupTarget(kTriple, error); EXPECT_THAT(Target_, NotNull()); + STI_.reset(Target_->createMCSubtargetInfo(kTriple, kCpuCore2, Features)); } + static void SetUpTestCase() { LLVMInitializeX86TargetInfo(); LLVMInitializeX86Target(); @@ -68,173 +124,208 @@ protected: InitializeX86ExegesisTarget(); } + std::vector<MCInst> setRegTo(unsigned Reg, const APInt &Value) { + return ExegesisTarget_->setRegTo(*STI_, Reg, Value); + } + const llvm::Target *Target_; const ExegesisTarget *const ExegesisTarget_; + std::unique_ptr<llvm::MCSubtargetInfo> STI_; }; -TEST_F(X86TargetTest, SetRegToConstantGPR) { - const std::unique_ptr<llvm::MCSubtargetInfo> STI( - Target_->createMCSubtargetInfo(kTriple, "core2", "")); - const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::EAX); - EXPECT_THAT(Insts, SizeIs(1)); - EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::MOV32ri); - EXPECT_EQ(Insts[0].getOperand(0).getReg(), llvm::X86::EAX); -} - -TEST_F(X86TargetTest, SetRegToConstantXMM_SSE2) { - const std::unique_ptr<llvm::MCSubtargetInfo> STI( - Target_->createMCSubtargetInfo(kTriple, "core2", "")); - const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1); - EXPECT_THAT(Insts, SizeIs(7U)); - EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8); - EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOVDQUrm); - EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8); -} - -TEST_F(X86TargetTest, SetRegToConstantXMM_AVX) { - const std::unique_ptr<llvm::MCSubtargetInfo> STI( - Target_->createMCSubtargetInfo(kTriple, "core2", "+avx")); - const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1); - EXPECT_THAT(Insts, SizeIs(7U)); - EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8); - EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::VMOVDQUrm); - EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8); -} - -TEST_F(X86TargetTest, SetRegToConstantXMM_AVX512) { - const std::unique_ptr<llvm::MCSubtargetInfo> STI( - Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl")); - const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1); - EXPECT_THAT(Insts, SizeIs(7U)); - EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8); - EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::VMOVDQU32Z128rm); - EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8); -} - -TEST_F(X86TargetTest, SetRegToConstantMMX) { - const std::unique_ptr<llvm::MCSubtargetInfo> STI( - Target_->createMCSubtargetInfo(kTriple, "core2", "")); - const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::MM1); - EXPECT_THAT(Insts, SizeIs(5U)); - EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8); - EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MMX_MOVQ64rm); - EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::ADD64ri8); -} - -TEST_F(X86TargetTest, SetRegToConstantYMM_AVX) { - const std::unique_ptr<llvm::MCSubtargetInfo> STI( - Target_->createMCSubtargetInfo(kTriple, "core2", "+avx")); - const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::YMM1); - EXPECT_THAT(Insts, SizeIs(11U)); - EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8); - EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::VMOVDQUYrm); - EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::ADD64ri8); -} - -TEST_F(X86TargetTest, SetRegToConstantYMM_AVX512) { - const std::unique_ptr<llvm::MCSubtargetInfo> STI( - Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl")); - const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::YMM1); - EXPECT_THAT(Insts, SizeIs(11U)); - EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8); - EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::VMOVDQU32Z256rm); - EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::ADD64ri8); -} - -TEST_F(X86TargetTest, SetRegToConstantZMM_AVX512) { - const std::unique_ptr<llvm::MCSubtargetInfo> STI( - Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl")); - const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::ZMM1); - EXPECT_THAT(Insts, SizeIs(19U)); - EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8); - EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[11].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[12].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[13].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[14].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[15].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[16].getOpcode(), llvm::X86::MOV32mi); - EXPECT_EQ(Insts[17].getOpcode(), llvm::X86::VMOVDQU32Zrm); - EXPECT_EQ(Insts[18].getOpcode(), llvm::X86::ADD64ri8); -} - -TEST_F(X86TargetTest, SetToAPInt) { - const std::unique_ptr<llvm::MCSubtargetInfo> STI( - Target_->createMCSubtargetInfo(kTriple, "core2", "")); - // EXPECT_THAT(ExegesisTarget_->setRegTo(*STI, APInt(8, 0xFFU), - // llvm::X86::AL), - // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV8ri) - // .addReg(llvm::X86::AL) - // .addImm(0xFFU))); - // EXPECT_THAT( - // ExegesisTarget_->setRegTo(*STI, APInt(16, 0xFFFFU), llvm::X86::BX), - // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV16ri) - // .addReg(llvm::X86::BX) - // .addImm(0xFFFFU))); - // EXPECT_THAT( - // ExegesisTarget_->setRegTo(*STI, APInt(32, 0x7FFFFU), llvm::X86::ECX), - // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV32ri) - // .addReg(llvm::X86::ECX) - // .addImm(0x7FFFFU))); - // EXPECT_THAT(ExegesisTarget_->setRegTo(*STI, APInt(64, - // 0x7FFFFFFFFFFFFFFFULL), - // llvm::X86::RDX), - // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV64ri) - // .addReg(llvm::X86::RDX) - // .addImm(0x7FFFFFFFFFFFFFFFULL))); - - const std::unique_ptr<llvm::MCRegisterInfo> MRI( - Target_->createMCRegInfo(kTriple)); - const std::unique_ptr<llvm::MCAsmInfo> MAI( - Target_->createMCAsmInfo(*MRI, kTriple)); - const std::unique_ptr<llvm::MCInstrInfo> MII(Target_->createMCInstrInfo()); - const std::unique_ptr<llvm::MCInstPrinter> MIP( - Target_->createMCInstPrinter(llvm::Triple(kTriple), 1, *MAI, *MII, *MRI)); - - for (const auto M : ExegesisTarget_->setRegTo( - *STI, APInt(80, "ABCD1234123456785678", 16), llvm::X86::MM0)) { - MIP->printInst(&M, llvm::errs(), "", *STI); - llvm::errs() << "\n"; - } +using Core2TargetTest = X86TargetTest<kCpuCore2, kFeaturesEmpty>; +using Core2AvxTargetTest = X86TargetTest<kCpuCore2, kFeaturesAvx>; +using Core2Avx512TargetTest = X86TargetTest<kCpuCore2, kFeaturesAvx512VL>; + +TEST_F(Core2TargetTest, SetFlags) { + const unsigned Reg = llvm::X86::EFLAGS; + EXPECT_THAT( + setRegTo(Reg, APInt(64, 0x1111222233334444ULL)), + ElementsAre(IsStackAllocate(8), + IsMovValueToStack(llvm::X86::MOV32mi, 0x33334444UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 4), + OpcodeIs(llvm::X86::POPF64))); +} + +TEST_F(Core2TargetTest, SetRegToGR8Value) { + const uint8_t Value = 0xFFU; + const unsigned Reg = llvm::X86::AL; + EXPECT_THAT(setRegTo(Reg, APInt(8, Value)), + ElementsAre(IsMovImmediate(llvm::X86::MOV8ri, Reg, Value))); +} + +TEST_F(Core2TargetTest, SetRegToGR16Value) { + const uint16_t Value = 0xFFFFU; + const unsigned Reg = llvm::X86::BX; + EXPECT_THAT(setRegTo(Reg, APInt(16, Value)), + ElementsAre(IsMovImmediate(llvm::X86::MOV16ri, Reg, Value))); +} + +TEST_F(Core2TargetTest, SetRegToGR32Value) { + const uint32_t Value = 0x7FFFFU; + const unsigned Reg = llvm::X86::ECX; + EXPECT_THAT(setRegTo(Reg, APInt(32, Value)), + ElementsAre(IsMovImmediate(llvm::X86::MOV32ri, Reg, Value))); +} + +TEST_F(Core2TargetTest, SetRegToGR64Value) { + const uint64_t Value = 0x7FFFFFFFFFFFFFFFULL; + const unsigned Reg = llvm::X86::RDX; + EXPECT_THAT(setRegTo(Reg, APInt(64, Value)), + ElementsAre(IsMovImmediate(llvm::X86::MOV64ri, Reg, Value))); +} + +TEST_F(Core2TargetTest, SetRegToVR64Value) { + EXPECT_THAT( + setRegTo(llvm::X86::MM0, APInt(64, 0x1111222233334444ULL)), + ElementsAre(IsStackAllocate(8), + IsMovValueToStack(llvm::X86::MOV32mi, 0x33334444UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 4), + IsMovValueFromStack(llvm::X86::MMX_MOVQ64rm, llvm::X86::MM0), + IsStackDeallocate(8))); +} + +TEST_F(Core2TargetTest, SetRegToVR128Value_Use_MOVDQUrm) { + EXPECT_THAT( + setRegTo(llvm::X86::XMM0, + APInt(128, "11112222333344445555666677778888", 16)), + ElementsAre(IsStackAllocate(16), + IsMovValueToStack(llvm::X86::MOV32mi, 0x77778888UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x55556666UL, 4), + IsMovValueToStack(llvm::X86::MOV32mi, 0x33334444UL, 8), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 12), + IsMovValueFromStack(llvm::X86::MOVDQUrm, llvm::X86::XMM0), + IsStackDeallocate(16))); +} + +TEST_F(Core2AvxTargetTest, SetRegToVR128Value_Use_VMOVDQUrm) { + EXPECT_THAT( + setRegTo(llvm::X86::XMM0, + APInt(128, "11112222333344445555666677778888", 16)), + ElementsAre(IsStackAllocate(16), + IsMovValueToStack(llvm::X86::MOV32mi, 0x77778888UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x55556666UL, 4), + IsMovValueToStack(llvm::X86::MOV32mi, 0x33334444UL, 8), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 12), + IsMovValueFromStack(llvm::X86::VMOVDQUrm, llvm::X86::XMM0), + IsStackDeallocate(16))); +} + +TEST_F(Core2Avx512TargetTest, SetRegToVR128Value_Use_VMOVDQU32Z128rm) { + EXPECT_THAT( + setRegTo(llvm::X86::XMM0, + APInt(128, "11112222333344445555666677778888", 16)), + ElementsAre( + IsStackAllocate(16), + IsMovValueToStack(llvm::X86::MOV32mi, 0x77778888UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x55556666UL, 4), + IsMovValueToStack(llvm::X86::MOV32mi, 0x33334444UL, 8), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 12), + IsMovValueFromStack(llvm::X86::VMOVDQU32Z128rm, llvm::X86::XMM0), + IsStackDeallocate(16))); +} + +TEST_F(Core2AvxTargetTest, SetRegToVR256Value_Use_VMOVDQUYrm) { + const char ValueStr[] = + "1111111122222222333333334444444455555555666666667777777788888888"; + EXPECT_THAT(setRegTo(llvm::X86::YMM0, APInt(256, ValueStr, 16)), + ElementsAreArray( + {IsStackAllocate(32), + IsMovValueToStack(llvm::X86::MOV32mi, 0x88888888UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x77777777UL, 4), + IsMovValueToStack(llvm::X86::MOV32mi, 0x66666666UL, 8), + IsMovValueToStack(llvm::X86::MOV32mi, 0x55555555UL, 12), + IsMovValueToStack(llvm::X86::MOV32mi, 0x44444444UL, 16), + IsMovValueToStack(llvm::X86::MOV32mi, 0x33333333UL, 20), + IsMovValueToStack(llvm::X86::MOV32mi, 0x22222222UL, 24), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11111111UL, 28), + IsMovValueFromStack(llvm::X86::VMOVDQUYrm, llvm::X86::YMM0), + IsStackDeallocate(32)})); +} + +TEST_F(Core2Avx512TargetTest, SetRegToVR256Value_Use_VMOVDQU32Z256rm) { + const char ValueStr[] = + "1111111122222222333333334444444455555555666666667777777788888888"; + EXPECT_THAT( + setRegTo(llvm::X86::YMM0, APInt(256, ValueStr, 16)), + ElementsAreArray( + {IsStackAllocate(32), + IsMovValueToStack(llvm::X86::MOV32mi, 0x88888888UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x77777777UL, 4), + IsMovValueToStack(llvm::X86::MOV32mi, 0x66666666UL, 8), + IsMovValueToStack(llvm::X86::MOV32mi, 0x55555555UL, 12), + IsMovValueToStack(llvm::X86::MOV32mi, 0x44444444UL, 16), + IsMovValueToStack(llvm::X86::MOV32mi, 0x33333333UL, 20), + IsMovValueToStack(llvm::X86::MOV32mi, 0x22222222UL, 24), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11111111UL, 28), + IsMovValueFromStack(llvm::X86::VMOVDQU32Z256rm, llvm::X86::YMM0), + IsStackDeallocate(32)})); +} + +TEST_F(Core2Avx512TargetTest, SetRegToVR512Value) { + const char ValueStr[] = + "1111111122222222333333334444444455555555666666667777777788888888" + "99999999AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDEEEEEEEEFFFFFFFF00000000"; + EXPECT_THAT( + setRegTo(llvm::X86::ZMM0, APInt(512, ValueStr, 16)), + ElementsAreArray( + {IsStackAllocate(64), + IsMovValueToStack(llvm::X86::MOV32mi, 0x00000000UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0xFFFFFFFFUL, 4), + IsMovValueToStack(llvm::X86::MOV32mi, 0xEEEEEEEEUL, 8), + IsMovValueToStack(llvm::X86::MOV32mi, 0xDDDDDDDDUL, 12), + IsMovValueToStack(llvm::X86::MOV32mi, 0xCCCCCCCCUL, 16), + IsMovValueToStack(llvm::X86::MOV32mi, 0xBBBBBBBBUL, 20), + IsMovValueToStack(llvm::X86::MOV32mi, 0xAAAAAAAAUL, 24), + IsMovValueToStack(llvm::X86::MOV32mi, 0x99999999UL, 28), + IsMovValueToStack(llvm::X86::MOV32mi, 0x88888888UL, 32), + IsMovValueToStack(llvm::X86::MOV32mi, 0x77777777UL, 36), + IsMovValueToStack(llvm::X86::MOV32mi, 0x66666666UL, 40), + IsMovValueToStack(llvm::X86::MOV32mi, 0x55555555UL, 44), + IsMovValueToStack(llvm::X86::MOV32mi, 0x44444444UL, 48), + IsMovValueToStack(llvm::X86::MOV32mi, 0x33333333UL, 52), + IsMovValueToStack(llvm::X86::MOV32mi, 0x22222222UL, 56), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11111111UL, 60), + IsMovValueFromStack(llvm::X86::VMOVDQU32Zrm, llvm::X86::ZMM0), + IsStackDeallocate(64)})); +} + +TEST_F(Core2TargetTest, SetRegToST0_32Bits) { + EXPECT_THAT( + setRegTo(llvm::X86::ST0, APInt(32, 0x11112222ULL)), + ElementsAre(IsStackAllocate(4), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 0), + OpcodeIs(llvm::X86::LD_F32m), IsStackDeallocate(4))); +} + +TEST_F(Core2TargetTest, SetRegToST1_32Bits) { + const MCInst CopySt0ToSt1 = + llvm::MCInstBuilder(llvm::X86::ST_Frr).addReg(llvm::X86::ST1); + EXPECT_THAT( + setRegTo(llvm::X86::ST1, APInt(32, 0x11112222ULL)), + ElementsAre(IsStackAllocate(4), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 0), + OpcodeIs(llvm::X86::LD_F32m), CopySt0ToSt1, + IsStackDeallocate(4))); +} + +TEST_F(Core2TargetTest, SetRegToST0_64Bits) { + EXPECT_THAT( + setRegTo(llvm::X86::ST0, APInt(64, 0x1111222233334444ULL)), + ElementsAre(IsStackAllocate(8), + IsMovValueToStack(llvm::X86::MOV32mi, 0x33334444UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x11112222UL, 4), + OpcodeIs(llvm::X86::LD_F64m), IsStackDeallocate(8))); +} + +TEST_F(Core2TargetTest, SetRegToST0_80Bits) { + EXPECT_THAT( + setRegTo(llvm::X86::ST0, APInt(80, "11112222333344445555", 16)), + ElementsAre(IsStackAllocate(10), + IsMovValueToStack(llvm::X86::MOV32mi, 0x44445555UL, 0), + IsMovValueToStack(llvm::X86::MOV32mi, 0x22223333UL, 4), + IsMovValueToStack(llvm::X86::MOV16mi, 0x1111UL, 8), + OpcodeIs(llvm::X86::LD_F80m), IsStackDeallocate(10))); } } // namespace |

