diff options
| author | Jinsong Ji <jji@us.ibm.com> | 2018-11-08 16:51:42 +0000 |
|---|---|---|
| committer | Jinsong Ji <jji@us.ibm.com> | 2018-11-08 16:51:42 +0000 |
| commit | 5fd3e754786c394b735555119432e305521fe9ca (patch) | |
| tree | aa768085683cd8a8664493dd7ec8fe96d53f5889 /llvm/tools/llvm-exegesis/lib/PowerPC/Target.cpp | |
| parent | ac8279ab8bbfd0e1af2c4815391aaf90cf548a33 (diff) | |
| download | bcm5719-llvm-5fd3e754786c394b735555119432e305521fe9ca.tar.gz bcm5719-llvm-5fd3e754786c394b735555119432e305521fe9ca.zip | |
[PowerPC][llvm-exegesis] Add a PowerPC target
This is patch to add PowerPC target to llvm-exegesis.
The target does just enough to be able to run llvm-exegesis in latency mode for at least some opcodes.
Differential Revision: https://reviews.llvm.org/D54185
llvm-svn: 346411
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/PowerPC/Target.cpp')
| -rw-r--r-- | llvm/tools/llvm-exegesis/lib/PowerPC/Target.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/PowerPC/Target.cpp b/llvm/tools/llvm-exegesis/lib/PowerPC/Target.cpp new file mode 100644 index 00000000000..b4c7ce64a50 --- /dev/null +++ b/llvm/tools/llvm-exegesis/lib/PowerPC/Target.cpp @@ -0,0 +1,92 @@ +//===-- Target.cpp ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +// The PowerPC ExegesisTarget. +//===----------------------------------------------------------------------===// +#include "../Target.h" +#include "../Latency.h" +#include "PPC.h" +#include "PPCRegisterInfo.h" + +namespace llvm { +namespace exegesis { + +namespace { +class PowerPCLatencyBenchmarkRunner : public LatencyBenchmarkRunner { +public: + PowerPCLatencyBenchmarkRunner(const LLVMState &State) + : LatencyBenchmarkRunner(State) {} + +private: + const char *getCounterName() const override { + // All PowerPC subtargets have CYCLES as the cycle counter name + return "CYCLES"; + } +}; +} // end anonymous namespace + +namespace { +class ExegesisPowerPCTarget : public ExegesisTarget { +public: + ExegesisPowerPCTarget() : ExegesisTarget({}) {} + +private: + std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI, + unsigned Reg, + const llvm::APInt &Value) const override; + bool matchesArch(llvm::Triple::ArchType Arch) const override { + return Arch == llvm::Triple::ppc64le; + } + std::unique_ptr<BenchmarkRunner> + createLatencyBenchmarkRunner(const LLVMState &State) const override { + return llvm::make_unique<PowerPCLatencyBenchmarkRunner>(State); + } +}; +} // end anonymous namespace + +static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) { + switch (RegBitWidth) { + case 32: + return llvm::PPC::LI; + case 64: + return llvm::PPC::LI8; + } + llvm_unreachable("Invalid Value Width"); +} + +// 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()); +} + +std::vector<llvm::MCInst> +ExegesisPowerPCTarget::setRegTo(const llvm::MCSubtargetInfo &STI, unsigned Reg, + const llvm::APInt &Value) const { + if (llvm::PPC::GPRCRegClass.contains(Reg)) + return {loadImmediate(Reg, 32, Value)}; + if (llvm::PPC::G8RCRegClass.contains(Reg)) + return {loadImmediate(Reg, 64, Value)}; + llvm::errs() << "setRegTo is not implemented, results will be unreliable\n"; + return {}; +} + +static ExegesisTarget *getTheExegesisPowerPCTarget() { + static ExegesisPowerPCTarget Target; + return &Target; +} + +void InitializePowerPCExegesisTarget() { + ExegesisTarget::registerTarget(getTheExegesisPowerPCTarget()); +} + +} // namespace exegesis +} // namespace llvm |

