From f652ef3d52532acdb113e6c1a05b2ab87d9e2407 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Tue, 18 Sep 2018 15:38:16 +0000 Subject: [PATCH] Revert rL342465: Added function to set a register to a particular value + tests. rL342465 is breaking the MSVC buildbots. llvm-svn: 342490 --- llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 5 + llvm/tools/llvm-exegesis/lib/Assembler.cpp | 14 +- llvm/tools/llvm-exegesis/lib/Target.cpp | 5 + llvm/tools/llvm-exegesis/lib/Target.h | 4 + llvm/tools/llvm-exegesis/lib/X86/Target.cpp | 140 +++---- .../tools/llvm-exegesis/X86/TargetTest.cpp | 410 +++++++++------------ 6 files changed, 264 insertions(+), 314 deletions(-) diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp index fe9d253..a65713b 100644 --- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp @@ -27,6 +27,11 @@ private: }; class ExegesisAArch64Target : public ExegesisTarget { + std::vector setRegToConstant(const llvm::MCSubtargetInfo &STI, + unsigned Reg) const override { + llvm_unreachable("Not yet implemented"); + } + std::vector setRegTo(const llvm::MCSubtargetInfo &STI, const llvm::APInt &Value, unsigned Reg) const override { diff --git a/llvm/tools/llvm-exegesis/lib/Assembler.cpp b/llvm/tools/llvm-exegesis/lib/Assembler.cpp index ec488d8..3b8b1d6 100644 --- a/llvm/tools/llvm-exegesis/lib/Assembler.cpp +++ b/llvm/tools/llvm-exegesis/lib/Assembler.cpp @@ -34,13 +34,13 @@ generateSnippetSetupCode(const llvm::ArrayRef RegsToDef, const llvm::LLVMTargetMachine &TM, bool &IsComplete) { IsComplete = true; std::vector Result; - // for (const unsigned Reg : RegsToDef) { - // // Load a constant in the register. - // const auto Code = ET.setRegToConstant(*TM.getMCSubtargetInfo(), Reg); - // if (Code.empty()) - // IsComplete = false; - // Result.insert(Result.end(), Code.begin(), Code.end()); - // } + for (const unsigned Reg : RegsToDef) { + // Load a constant in the register. + const auto Code = ET.setRegToConstant(*TM.getMCSubtargetInfo(), Reg); + if (Code.empty()) + IsComplete = false; + Result.insert(Result.end(), Code.begin(), Code.end()); + } return Result; } diff --git a/llvm/tools/llvm-exegesis/lib/Target.cpp b/llvm/tools/llvm-exegesis/lib/Target.cpp index ceca1fd..b45c821 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/Target.cpp @@ -89,6 +89,11 @@ namespace { // Default implementation. class ExegesisDefaultTarget : public ExegesisTarget { private: + std::vector setRegToConstant(const llvm::MCSubtargetInfo &STI, + unsigned Reg) const override { + llvm_unreachable("Not yet implemented"); + } + std::vector setRegTo(const llvm::MCSubtargetInfo &STI, const llvm::APInt &Value, unsigned Reg) const override { diff --git a/llvm/tools/llvm-exegesis/lib/Target.h b/llvm/tools/llvm-exegesis/lib/Target.h index 41d77e3..8514793 100644 --- a/llvm/tools/llvm-exegesis/lib/Target.h +++ b/llvm/tools/llvm-exegesis/lib/Target.h @@ -36,6 +36,10 @@ public: virtual void addTargetSpecificPasses(llvm::PassManagerBase &PM) const {} // Generates code to move a constant into a the given register. + virtual std::vector + setRegToConstant(const llvm::MCSubtargetInfo &STI, unsigned Reg) const = 0; + + // Generates code to move a constant into a the given register. virtual std::vector setRegTo(const llvm::MCSubtargetInfo &STI, const llvm::APInt &Value, unsigned Reg) const = 0; diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index e682b98..e55e77d 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -115,9 +115,7 @@ static unsigned GetLoadImmediateOpcode(const llvm::APInt &Value) { llvm_unreachable("Invalid Value Width"); } -static llvm::MCInst loadImmediate(unsigned Reg, const llvm::APInt &Value, - unsigned MaxBitWidth) { - assert(Value.getBitWidth() <= MaxBitWidth && "Value too big to fit register"); +static llvm::MCInst loadImmediate(unsigned Reg, const llvm::APInt &Value) { return llvm::MCInstBuilder(GetLoadImmediateOpcode(Value)) .addReg(Reg) .addImm(Value.getZExtValue()); @@ -169,59 +167,35 @@ struct ConstantInliner { explicit ConstantInliner(const llvm::APInt &Constant) : StackSize(Constant.getBitWidth() / 8) { assert(Constant.getBitWidth() % 8 == 0 && "Must be a multiple of 8"); - add(allocateStackSpace(StackSize)); + Add(allocateStackSpace(StackSize)); size_t ByteOffset = 0; for (; StackSize - ByteOffset >= 4; ByteOffset += 4) - add(fillStackSpace( + Add(fillStackSpace( llvm::X86::MOV32mi, ByteOffset, Constant.extractBits(32, ByteOffset * 8).getZExtValue())); if (StackSize - ByteOffset >= 2) { - add(fillStackSpace( + Add(fillStackSpace( llvm::X86::MOV16mi, ByteOffset, Constant.extractBits(16, ByteOffset * 8).getZExtValue())); ByteOffset += 2; } if (StackSize - ByteOffset >= 1) - add(fillStackSpace( + Add(fillStackSpace( llvm::X86::MOV8mi, ByteOffset, Constant.extractBits(8, ByteOffset * 8).getZExtValue())); } - std::vector loadAndFinalize(unsigned Reg, unsigned Opcode, - unsigned BitWidth) { - assert(StackSize * 8 == BitWidth && "Value does not have the correct size"); - add(loadToReg(Reg, Opcode)); - add(releaseStackSpace(StackSize)); - return std::move(Instructions); - } - - std::vector loadX87AndFinalize(unsigned Reg, unsigned Opcode, - unsigned BitWidth) { - assert(StackSize * 8 == BitWidth && "Value does not have the correct size"); - add(llvm::MCInstBuilder(Opcode) - .addReg(llvm::X86::RSP) // BaseReg - .addImm(1) // ScaleAmt - .addReg(0) // IndexReg - .addImm(0) // Disp - .addReg(0)); // Segment - if (Reg != llvm::X86::ST0) - add(llvm::MCInstBuilder(llvm::X86::ST_Frr).addReg(Reg)); - add(releaseStackSpace(StackSize)); - return std::move(Instructions); + ConstantInliner &Add(const llvm::MCInst &Inst) { + Instructions.push_back(Inst); + return *this; } - std::vector popFlagAndFinalize() { - assert(StackSize * 8 == 32 && "Value does not have the correct size"); - add(llvm::MCInstBuilder(llvm::X86::POPF64)); + std::vector finalize() { + Add(releaseStackSpace(StackSize)); return std::move(Instructions); } private: - ConstantInliner &add(const llvm::MCInst &Inst) { - Instructions.push_back(Inst); - return *this; - } - const size_t StackSize; std::vector Instructions; }; @@ -274,46 +248,63 @@ class ExegesisX86Target : public ExegesisTarget { } } - std::vector setRegTo(const llvm::MCSubtargetInfo &STI, - const llvm::APInt &Value, - unsigned Reg) const override { + std::vector setRegToConstant(const llvm::MCSubtargetInfo &STI, + unsigned Reg) const override { + // GPR. if (llvm::X86::GR8RegClass.contains(Reg)) - return {loadImmediate(Reg, Value, 8)}; + return {llvm::MCInstBuilder(llvm::X86::MOV8ri).addReg(Reg).addImm(1)}; if (llvm::X86::GR16RegClass.contains(Reg)) - return {loadImmediate(Reg, Value, 16)}; + return {llvm::MCInstBuilder(llvm::X86::MOV16ri).addReg(Reg).addImm(1)}; if (llvm::X86::GR32RegClass.contains(Reg)) - return {loadImmediate(Reg, Value, 32)}; + return {llvm::MCInstBuilder(llvm::X86::MOV32ri).addReg(Reg).addImm(1)}; if (llvm::X86::GR64RegClass.contains(Reg)) - return {loadImmediate(Reg, Value, 64)}; - ConstantInliner CI(Value); + return {llvm::MCInstBuilder(llvm::X86::MOV64ri32).addReg(Reg).addImm(1)}; + // MMX. if (llvm::X86::VR64RegClass.contains(Reg)) - return CI.loadAndFinalize(Reg, llvm::X86::MMX_MOVQ64rm, 64); + return setVectorRegToConstant(Reg, 8, llvm::X86::MMX_MOVQ64rm); + // {X,Y,Z}MM. if (llvm::X86::VR128XRegClass.contains(Reg)) { if (STI.getFeatureBits()[llvm::X86::FeatureAVX512]) - return CI.loadAndFinalize(Reg, llvm::X86::VMOVDQU32Z128rm, 128); + return setVectorRegToConstant(Reg, 16, llvm::X86::VMOVDQU32Z128rm); if (STI.getFeatureBits()[llvm::X86::FeatureAVX]) - return CI.loadAndFinalize(Reg, llvm::X86::VMOVDQUrm, 128); - return CI.loadAndFinalize(Reg, llvm::X86::MOVDQUrm, 128); + return setVectorRegToConstant(Reg, 16, llvm::X86::VMOVDQUrm); + return setVectorRegToConstant(Reg, 16, llvm::X86::MOVDQUrm); } if (llvm::X86::VR256XRegClass.contains(Reg)) { if (STI.getFeatureBits()[llvm::X86::FeatureAVX512]) - return CI.loadAndFinalize(Reg, llvm::X86::VMOVDQU32Z256rm, 256); - if (STI.getFeatureBits()[llvm::X86::FeatureAVX]) - return CI.loadAndFinalize(Reg, llvm::X86::VMOVDQUYrm, 256); + return setVectorRegToConstant(Reg, 32, llvm::X86::VMOVDQU32Z256rm); + return setVectorRegToConstant(Reg, 32, llvm::X86::VMOVDQUYrm); } if (llvm::X86::VR512RegClass.contains(Reg)) - if (STI.getFeatureBits()[llvm::X86::FeatureAVX512]) - return CI.loadAndFinalize(Reg, llvm::X86::VMOVDQU32Zrm, 512); - if (llvm::X86::RSTRegClass.contains(Reg)) { - if (Value.getBitWidth() == 32) - return CI.loadX87AndFinalize(Reg, llvm::X86::LD_F32m, 32); - if (Value.getBitWidth() == 64) - return CI.loadX87AndFinalize(Reg, llvm::X86::LD_F64m, 64); - if (Value.getBitWidth() == 80) - return CI.loadX87AndFinalize(Reg, llvm::X86::LD_F80m, 80); + return setVectorRegToConstant(Reg, 64, llvm::X86::VMOVDQU32Zrm); + // X87. + if (llvm::X86::RFP32RegClass.contains(Reg) || + llvm::X86::RFP64RegClass.contains(Reg) || + llvm::X86::RFP80RegClass.contains(Reg)) + return setVectorRegToConstant(Reg, 8, llvm::X86::LD_Fp64m); + if (Reg == llvm::X86::EFLAGS) { + // Set all flags to 0 but the bits that are "reserved and set to 1". + constexpr const uint32_t kImmValue = 0x00007002u; + std::vector Result; + Result.push_back(allocateStackSpace(8)); + Result.push_back(fillStackSpace(llvm::X86::MOV64mi32, 0, kImmValue)); + Result.push_back(llvm::MCInstBuilder(llvm::X86::POPF64)); // Also pops. + return Result; } - if (Reg == llvm::X86::EFLAGS) - return CI.popFlagAndFinalize(); + llvm_unreachable("Not yet implemented"); + } + + std::vector setRegTo(const llvm::MCSubtargetInfo &STI, + const llvm::APInt &Value, + unsigned Reg) const override { + if (llvm::X86::GR8RegClass.contains(Reg) || + llvm::X86::GR16RegClass.contains(Reg) || + llvm::X86::GR32RegClass.contains(Reg) || + llvm::X86::GR64RegClass.contains(Reg)) + return {loadImmediate(Reg, Value)}; + ConstantInliner CI(Value); + if (llvm::X86::VR64RegClass.contains(Reg)) + return CI.Add(loadToReg(Reg, llvm::X86::MMX_MOVQ64rm)).finalize(); llvm_unreachable("Not yet implemented"); } @@ -330,6 +321,31 @@ class ExegesisX86Target : public ExegesisTarget { bool matchesArch(llvm::Triple::ArchType Arch) const override { return Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::x86; } + +private: + // setRegToConstant() specialized for a vector register of size + // `RegSizeBytes`. `RMOpcode` is the opcode used to do a memory -> vector + // register load. + static std::vector + setVectorRegToConstant(const unsigned Reg, const unsigned RegSizeBytes, + const unsigned RMOpcode) { + // There is no instruction to directly set XMM, go through memory. + // Since vector values can be interpreted as integers of various sizes (8 + // to 64 bits) as well as floats and double, so we chose an immediate + // value that has set bits for all byte values and is a normal float/ + // double. 0x40404040 is ~32.5 when interpreted as a double and ~3.0f when + // interpreted as a float. + constexpr const uint32_t kImmValue = 0x40404040u; + std::vector Result; + Result.push_back(allocateStackSpace(RegSizeBytes)); + constexpr const unsigned kMov32NumBytes = 4; + for (unsigned Disp = 0; Disp < RegSizeBytes; Disp += kMov32NumBytes) { + Result.push_back(fillStackSpace(llvm::X86::MOV32mi, Disp, kImmValue)); + } + Result.push_back(loadToReg(Reg, RMOpcode)); + Result.push_back(releaseStackSpace(RegSizeBytes)); + return Result; + } }; } // namespace diff --git a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp index c60f003..b8533fb 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 MCOperand &a, const MCOperand &b) { +bool operator==(const llvm::MCOperand &a, const llvm::MCOperand &b) { if (a.isImm() && b.isImm()) return a.getImm() == b.getImm(); if (a.isReg() && b.isReg()) @@ -21,7 +21,7 @@ bool operator==(const MCOperand &a, const MCOperand &b) { return false; } -bool operator==(const MCInst &a, const MCInst &b) { +bool operator==(const llvm::MCInst &a, const llvm::MCInst &b) { if (a.getOpcode() != b.getOpcode()) return false; if (a.getNumOperands() != b.getNumOperands()) @@ -41,71 +41,17 @@ 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; - -Matcher IsImm(int64_t Value) { - return AllOf(Property(&MCOperand::isImm, Eq(true)), - Property(&MCOperand::getImm, Eq(Value))); -} - -Matcher IsReg(unsigned Reg) { - return AllOf(Property(&MCOperand::isReg, Eq(true)), - Property(&MCOperand::getReg, Eq(Reg))); -} - -Matcher OpcodeIs(unsigned Opcode) { - return Property(&MCInst::getOpcode, Eq(Opcode)); -} - -Matcher IsMovImmediate(unsigned Opcode, int64_t Reg, int64_t Value) { - return AllOf(OpcodeIs(Opcode), ElementsAre(IsReg(Reg), IsImm(Value))); -} - -Matcher 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 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 IsStackAllocate(unsigned Size) { - return AllOf( - OpcodeIs(llvm::X86::SUB64ri8), - ElementsAre(IsReg(llvm::X86::RSP), IsReg(llvm::X86::RSP), IsImm(Size))); -} - -Matcher IsStackDeallocate(unsigned Size) { - return AllOf( - OpcodeIs(llvm::X86::ADD64ri8), - ElementsAre(IsReg(llvm::X86::RSP), IsReg(llvm::X86::RSP), IsImm(Size))); -} constexpr const char kTriple[] = "x86_64-unknown-linux"; -constexpr const char kFeaturesEmpty[] = ""; -constexpr const char kFeaturesAvx[] = "+avx"; -constexpr const char kFeaturesAvx512VL[] = "+avx512vl"; -constexpr const char kCpuCore2[] = "core2"; -template class X86TargetTest : public ::testing::Test { protected: X86TargetTest() @@ -114,9 +60,7 @@ 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(); @@ -124,197 +68,173 @@ protected: InitializeX86ExegesisTarget(); } - std::vector setRegTo(unsigned Reg, const APInt &Value) { - return ExegesisTarget_->setRegTo(*STI_, Value, Reg); - } - const llvm::Target *Target_; const ExegesisTarget *const ExegesisTarget_; - std::unique_ptr STI_; }; -using Core2TargetTest = X86TargetTest; -using Core2AvxTargetTest = X86TargetTest; -using Core2Avx512TargetTest = X86TargetTest; - -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), - testing::A(), 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), - testing::A(), 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), - testing::A(), 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), - testing::A(), IsStackDeallocate(10))); +TEST_F(X86TargetTest, SetRegToConstantGPR) { + const std::unique_ptr 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 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 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 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 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 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 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 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 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 MRI( + Target_->createMCRegInfo(kTriple)); + const std::unique_ptr MAI( + Target_->createMCAsmInfo(*MRI, kTriple)); + const std::unique_ptr MII(Target_->createMCInstrInfo()); + const std::unique_ptr 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"; + } } } // namespace -- 2.7.4