diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp index 0a70321fab781..3c3bff76fb681 100644 --- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp @@ -537,6 +537,8 @@ struct ConstantInliner { std::vector loadImplicitRegAndFinalize(unsigned Opcode, unsigned Value); + std::vector loadDirectionFlagAndFinalize(); + private: ConstantInliner &add(const MCInst &Inst) { Instructions.push_back(Inst); @@ -612,6 +614,15 @@ ConstantInliner::loadImplicitRegAndFinalize(unsigned Opcode, unsigned Value) { return std::move(Instructions); } +std::vector ConstantInliner::loadDirectionFlagAndFinalize() { + if (Constant_.isZero()) + add(MCInstBuilder(X86::CLD)); + else if (Constant_.isOne()) + add(MCInstBuilder(X86::STD)); + + return std::move(Instructions); +} + void ConstantInliner::initStack(unsigned Bytes) { assert(Constant_.getBitWidth() <= Bytes * 8 && "Value does not have the correct size"); @@ -1089,6 +1100,8 @@ std::vector ExegesisX86Target::setRegTo(const MCSubtargetInfo &STI, 0x1f80); if (Reg == X86::FPCW) return CI.loadImplicitRegAndFinalize(X86::FLDCW16m, 0x37f); + if (Reg == X86::DF) + return CI.loadDirectionFlagAndFinalize(); return {}; // Not yet implemented. } diff --git a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp index 921d7d7975f6a..3dff50c44798d 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp @@ -585,6 +585,14 @@ TEST_F(X86Core2TargetTest, SetRegToFP1_4Bits) { OpcodeIs(X86::LD_Fp80m), IsStackDeallocate(10))); } +TEST_F(X86Core2TargetTest, SetRegToDf1) { + EXPECT_THAT(setRegTo(X86::DF, APInt(1, 1)), ElementsAre(OpcodeIs(X86::STD))); +} + +TEST_F(X86Core2TargetTest, SetRegToDf0) { + EXPECT_THAT(setRegTo(X86::DF, APInt(1, 0)), ElementsAre(OpcodeIs(X86::CLD))); +} + TEST_F(X86Core2Avx512TargetTest, FillMemoryOperands_ADD64rm) { const Instruction &I = getInstr(X86::ADD64rm); InstructionTemplate IT(&I);