summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-exegesis/lib/X86
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/X86')
-rw-r--r--llvm/tools/llvm-exegesis/lib/X86/Target.cpp66
1 files changed, 36 insertions, 30 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
index e682b98bd86..2d8f9582d43 100644
--- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
@@ -101,8 +101,8 @@ protected:
}
};
-static unsigned GetLoadImmediateOpcode(const llvm::APInt &Value) {
- switch (Value.getBitWidth()) {
+static unsigned GetLoadImmediateOpcode(unsigned RegBitWidth) {
+ switch (RegBitWidth) {
case 8:
return llvm::X86::MOV8ri;
case 16:
@@ -115,10 +115,12 @@ 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");
- return llvm::MCInstBuilder(GetLoadImmediateOpcode(Value))
+// Generates instruction to load an immediate value into a register.
+static llvm::MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
+ const llvm::APInt &Value) {
+ if (Value.getBitWidth() > RegBitWidth)
+ llvm_unreachable("Value must fit in the Register");
+ return llvm::MCInstBuilder(GetLoadImmediateOpcode(RegBitWidth))
.addReg(Reg)
.addImm(Value.getZExtValue());
}
@@ -165,6 +167,8 @@ static llvm::MCInst releaseStackSpace(unsigned Bytes) {
.addImm(Bytes);
}
+// Reserves some space on the stack, fills it with the content of the provided
+// constant and provide methods to load the stack value into a register.
struct ConstantInliner {
explicit ConstantInliner(const llvm::APInt &Constant)
: StackSize(Constant.getBitWidth() / 8) {
@@ -187,17 +191,19 @@ struct ConstantInliner {
Constant.extractBits(8, ByteOffset * 8).getZExtValue()));
}
- std::vector<llvm::MCInst> loadAndFinalize(unsigned Reg, unsigned Opcode,
- unsigned BitWidth) {
- assert(StackSize * 8 == BitWidth && "Value does not have the correct size");
+ std::vector<llvm::MCInst> loadAndFinalize(unsigned Reg, unsigned RegBitWidth,
+ unsigned Opcode) {
+ assert(StackSize * 8 == RegBitWidth &&
+ "Value does not have the correct size");
add(loadToReg(Reg, Opcode));
add(releaseStackSpace(StackSize));
return std::move(Instructions);
}
- std::vector<llvm::MCInst> loadX87AndFinalize(unsigned Reg, unsigned Opcode,
- unsigned BitWidth) {
- assert(StackSize * 8 == BitWidth && "Value does not have the correct size");
+ std::vector<llvm::MCInst>
+ loadX87AndFinalize(unsigned Reg, unsigned RegBitWidth, unsigned Opcode) {
+ assert(StackSize * 8 == RegBitWidth &&
+ "Value does not have the correct size");
add(llvm::MCInstBuilder(Opcode)
.addReg(llvm::X86::RSP) // BaseReg
.addImm(1) // ScaleAmt
@@ -211,7 +217,7 @@ struct ConstantInliner {
}
std::vector<llvm::MCInst> popFlagAndFinalize() {
- assert(StackSize * 8 == 32 && "Value does not have the correct size");
+ assert(StackSize * 8 == 64 && "Value does not have the correct size");
add(llvm::MCInstBuilder(llvm::X86::POPF64));
return std::move(Instructions);
}
@@ -275,46 +281,46 @@ class ExegesisX86Target : public ExegesisTarget {
}
std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
- const llvm::APInt &Value,
- unsigned Reg) const override {
+ unsigned Reg,
+ const llvm::APInt &Value) const override {
if (llvm::X86::GR8RegClass.contains(Reg))
- return {loadImmediate(Reg, Value, 8)};
+ return {loadImmediate(Reg, 8, Value)};
if (llvm::X86::GR16RegClass.contains(Reg))
- return {loadImmediate(Reg, Value, 16)};
+ return {loadImmediate(Reg, 16, Value)};
if (llvm::X86::GR32RegClass.contains(Reg))
- return {loadImmediate(Reg, Value, 32)};
+ return {loadImmediate(Reg, 32, Value)};
if (llvm::X86::GR64RegClass.contains(Reg))
- return {loadImmediate(Reg, Value, 64)};
+ return {loadImmediate(Reg, 64, Value)};
ConstantInliner CI(Value);
if (llvm::X86::VR64RegClass.contains(Reg))
- return CI.loadAndFinalize(Reg, llvm::X86::MMX_MOVQ64rm, 64);
+ return CI.loadAndFinalize(Reg, 64, llvm::X86::MMX_MOVQ64rm);
if (llvm::X86::VR128XRegClass.contains(Reg)) {
if (STI.getFeatureBits()[llvm::X86::FeatureAVX512])
- return CI.loadAndFinalize(Reg, llvm::X86::VMOVDQU32Z128rm, 128);
+ return CI.loadAndFinalize(Reg, 128, 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 CI.loadAndFinalize(Reg, 128, llvm::X86::VMOVDQUrm);
+ return CI.loadAndFinalize(Reg, 128, llvm::X86::MOVDQUrm);
}
if (llvm::X86::VR256XRegClass.contains(Reg)) {
if (STI.getFeatureBits()[llvm::X86::FeatureAVX512])
- return CI.loadAndFinalize(Reg, llvm::X86::VMOVDQU32Z256rm, 256);
+ return CI.loadAndFinalize(Reg, 256, llvm::X86::VMOVDQU32Z256rm);
if (STI.getFeatureBits()[llvm::X86::FeatureAVX])
- return CI.loadAndFinalize(Reg, llvm::X86::VMOVDQUYrm, 256);
+ return CI.loadAndFinalize(Reg, 256, llvm::X86::VMOVDQUYrm);
}
if (llvm::X86::VR512RegClass.contains(Reg))
if (STI.getFeatureBits()[llvm::X86::FeatureAVX512])
- return CI.loadAndFinalize(Reg, llvm::X86::VMOVDQU32Zrm, 512);
+ return CI.loadAndFinalize(Reg, 512, llvm::X86::VMOVDQU32Zrm);
if (llvm::X86::RSTRegClass.contains(Reg)) {
if (Value.getBitWidth() == 32)
- return CI.loadX87AndFinalize(Reg, llvm::X86::LD_F32m, 32);
+ return CI.loadX87AndFinalize(Reg, 32, llvm::X86::LD_F32m);
if (Value.getBitWidth() == 64)
- return CI.loadX87AndFinalize(Reg, llvm::X86::LD_F64m, 64);
+ return CI.loadX87AndFinalize(Reg, 64, llvm::X86::LD_F64m);
if (Value.getBitWidth() == 80)
- return CI.loadX87AndFinalize(Reg, llvm::X86::LD_F80m, 80);
+ return CI.loadX87AndFinalize(Reg, 80, llvm::X86::LD_F80m);
}
if (Reg == llvm::X86::EFLAGS)
return CI.popFlagAndFinalize();
- llvm_unreachable("Not yet implemented");
+ return {}; // Not yet implemented.
}
std::unique_ptr<SnippetGenerator>
OpenPOWER on IntegriCloud