summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/X86/Target.cpp')
-rw-r--r--llvm/tools/llvm-exegesis/lib/X86/Target.cpp63
1 files changed, 35 insertions, 28 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
index 2d8f9582d43..6a63e24168c 100644
--- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
@@ -170,40 +170,23 @@ static llvm::MCInst releaseStackSpace(unsigned 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) {
- assert(Constant.getBitWidth() % 8 == 0 && "Must be a multiple of 8");
- add(allocateStackSpace(StackSize));
- size_t ByteOffset = 0;
- for (; StackSize - ByteOffset >= 4; ByteOffset += 4)
- add(fillStackSpace(
- llvm::X86::MOV32mi, ByteOffset,
- Constant.extractBits(32, ByteOffset * 8).getZExtValue()));
- if (StackSize - ByteOffset >= 2) {
- add(fillStackSpace(
- llvm::X86::MOV16mi, ByteOffset,
- Constant.extractBits(16, ByteOffset * 8).getZExtValue()));
- ByteOffset += 2;
- }
- if (StackSize - ByteOffset >= 1)
- add(fillStackSpace(
- llvm::X86::MOV8mi, ByteOffset,
- Constant.extractBits(8, ByteOffset * 8).getZExtValue()));
- }
+ explicit ConstantInliner(const llvm::APInt &Constant) : Constant_(Constant) {}
std::vector<llvm::MCInst> loadAndFinalize(unsigned Reg, unsigned RegBitWidth,
unsigned Opcode) {
- assert(StackSize * 8 == RegBitWidth &&
- "Value does not have the correct size");
+ assert((RegBitWidth & 7) == 0 &&
+ "RegBitWidth must be a multiple of 8 bits");
+ initStack(RegBitWidth / 8);
add(loadToReg(Reg, Opcode));
- add(releaseStackSpace(StackSize));
+ add(releaseStackSpace(RegBitWidth / 8));
return std::move(Instructions);
}
std::vector<llvm::MCInst>
loadX87AndFinalize(unsigned Reg, unsigned RegBitWidth, unsigned Opcode) {
- assert(StackSize * 8 == RegBitWidth &&
- "Value does not have the correct size");
+ assert((RegBitWidth & 7) == 0 &&
+ "RegBitWidth must be a multiple of 8 bits");
+ initStack(RegBitWidth / 8);
add(llvm::MCInstBuilder(Opcode)
.addReg(llvm::X86::RSP) // BaseReg
.addImm(1) // ScaleAmt
@@ -212,12 +195,12 @@ struct ConstantInliner {
.addReg(0)); // Segment
if (Reg != llvm::X86::ST0)
add(llvm::MCInstBuilder(llvm::X86::ST_Frr).addReg(Reg));
- add(releaseStackSpace(StackSize));
+ add(releaseStackSpace(RegBitWidth / 8));
return std::move(Instructions);
}
std::vector<llvm::MCInst> popFlagAndFinalize() {
- assert(StackSize * 8 == 64 && "Value does not have the correct size");
+ initStack(8);
add(llvm::MCInstBuilder(llvm::X86::POPF64));
return std::move(Instructions);
}
@@ -228,7 +211,31 @@ private:
return *this;
}
- const size_t StackSize;
+ void initStack(unsigned Bytes) {
+ assert(Constant_.getBitWidth() <= Bytes * 8 &&
+ "Value does not have the correct size");
+ const llvm::APInt WideConstant = Constant_.getBitWidth() < Bytes * 8
+ ? Constant_.sext(Bytes * 8)
+ : Constant_;
+ add(allocateStackSpace(Bytes));
+ size_t ByteOffset = 0;
+ for (; Bytes - ByteOffset >= 4; ByteOffset += 4)
+ add(fillStackSpace(
+ llvm::X86::MOV32mi, ByteOffset,
+ WideConstant.extractBits(32, ByteOffset * 8).getZExtValue()));
+ if (Bytes - ByteOffset >= 2) {
+ add(fillStackSpace(
+ llvm::X86::MOV16mi, ByteOffset,
+ WideConstant.extractBits(16, ByteOffset * 8).getZExtValue()));
+ ByteOffset += 2;
+ }
+ if (Bytes - ByteOffset >= 1)
+ add(fillStackSpace(
+ llvm::X86::MOV8mi, ByteOffset,
+ WideConstant.extractBits(8, ByteOffset * 8).getZExtValue()));
+ }
+
+ llvm::APInt Constant_;
std::vector<llvm::MCInst> Instructions;
};
OpenPOWER on IntegriCloud