diff options
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp')
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp index fe9d253f80f..90c5927ad29 100644 --- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp @@ -9,6 +9,7 @@ #include "../Target.h" #include "../Latency.h" #include "AArch64.h" +#include "AArch64RegisterInfo.h" namespace exegesis { @@ -26,33 +27,51 @@ private: } }; -class ExegesisAArch64Target : public ExegesisTarget { - std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI, - const llvm::APInt &Value, - unsigned Reg) const override { - llvm_unreachable("Not yet implemented"); - } +namespace { - unsigned getScratchMemoryRegister(const llvm::Triple &) const override { - llvm_unreachable("Not yet implemented"); +static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) { + switch (RegBitWidth) { + case 32: + return llvm::AArch64::MOVi32imm; + case 64: + return llvm::AArch64::MOVi64imm; } + llvm_unreachable("Invalid Value Width"); +} - void fillMemoryOperands(InstructionBuilder &IB, unsigned Reg, - unsigned Offset) const override { - llvm_unreachable("Not yet implemented"); - } +// 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()); +} - unsigned getMaxMemoryAccessSize() const override { - llvm_unreachable("Not yet implemented"); +} // namespace + +class ExegesisAArch64Target : public ExegesisTarget { + std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI, + unsigned Reg, + const llvm::APInt &Value) const override { + if (llvm::AArch64::GPR32RegClass.contains(Reg)) + return {loadImmediate(Reg, 32, Value)}; + if (llvm::AArch64::GPR64RegClass.contains(Reg)) + return {loadImmediate(Reg, 64, Value)}; + llvm::errs() << "setRegTo is not implemented, results will be unreliable\n"; + return {}; } bool matchesArch(llvm::Triple::ArchType Arch) const override { return Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be; } + void addTargetSpecificPasses(llvm::PassManagerBase &PM) const override { // Function return is a pseudo-instruction that needs to be expanded PM.add(llvm::createAArch64ExpandPseudoPass()); } + std::unique_ptr<BenchmarkRunner> createLatencyBenchmarkRunner(const LLVMState &State) const override { return llvm::make_unique<AArch64LatencyBenchmarkRunner>(State); |