[llvm] [llvm-exegesis] Add explicit support for setting DF in X86 (PR #115644)
Aiden Grossman via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 10 01:32:42 PST 2024
https://github.com/boomanaiden154 created https://github.com/llvm/llvm-project/pull/115644
While llvm-exegesis has explicit support for setting EFLAGS which contains DF, it can be nice sometimes to explicitly set DF, especially given that it is modeled as a separate register within LLVM. This patch adds the ability to do that by lowering setting the value to 0 or 1 to cld and std respectively.
>From eaf78574bd6e2d16bd6fb5b5dc7d7288cd8a8a12 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Sun, 10 Nov 2024 08:06:37 +0000
Subject: [PATCH] [llvm-exegesis] Add explicit support for setting DF in X86
While llvm-exegesis has explicit support for setting EFLAGS which
contains DF, it can be nice sometimes to explicitly set DF, especially
given that it is modeled as a separate register within LLVM. This patch
adds the ability to do that by lowering setting the value to 0 or 1 to
cld and std respectively.
---
llvm/tools/llvm-exegesis/lib/X86/Target.cpp | 13 +++++++++++++
.../tools/llvm-exegesis/X86/TargetTest.cpp | 8 ++++++++
2 files changed, 21 insertions(+)
diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
index 0a70321fab7818..3c3bff76fb6812 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<MCInst> loadImplicitRegAndFinalize(unsigned Opcode,
unsigned Value);
+ std::vector<MCInst> 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<MCInst> 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<MCInst> 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 921d7d7975f6ae..3dff50c44798d7 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);
More information about the llvm-commits
mailing list