[llvm-exegesis][NFC] moving code around.
[llvm-complete.git] / tools / llvm-exegesis / lib / AArch64 / Target.cpp
blob90c5927ad2939a931d08fc7ed13b08ab1c0e7fc8
1 //===-- Target.cpp ----------------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include "../Target.h"
10 #include "../Latency.h"
11 #include "AArch64.h"
12 #include "AArch64RegisterInfo.h"
14 namespace exegesis {
16 namespace {
18 class AArch64LatencyBenchmarkRunner : public LatencyBenchmarkRunner {
19 public:
20 AArch64LatencyBenchmarkRunner(const LLVMState &State)
21 : LatencyBenchmarkRunner(State) {}
23 private:
24 const char *getCounterName() const override {
25 // All AArch64 subtargets have CPU_CYCLES as the cycle counter name
26 return "CPU_CYCLES";
30 namespace {
32 static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
33 switch (RegBitWidth) {
34 case 32:
35 return llvm::AArch64::MOVi32imm;
36 case 64:
37 return llvm::AArch64::MOVi64imm;
39 llvm_unreachable("Invalid Value Width");
42 // Generates instruction to load an immediate value into a register.
43 static llvm::MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
44 const llvm::APInt &Value) {
45 if (Value.getBitWidth() > RegBitWidth)
46 llvm_unreachable("Value must fit in the Register");
47 return llvm::MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
48 .addReg(Reg)
49 .addImm(Value.getZExtValue());
52 } // namespace
54 class ExegesisAArch64Target : public ExegesisTarget {
55 std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
56 unsigned Reg,
57 const llvm::APInt &Value) const override {
58 if (llvm::AArch64::GPR32RegClass.contains(Reg))
59 return {loadImmediate(Reg, 32, Value)};
60 if (llvm::AArch64::GPR64RegClass.contains(Reg))
61 return {loadImmediate(Reg, 64, Value)};
62 llvm::errs() << "setRegTo is not implemented, results will be unreliable\n";
63 return {};
66 bool matchesArch(llvm::Triple::ArchType Arch) const override {
67 return Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be;
70 void addTargetSpecificPasses(llvm::PassManagerBase &PM) const override {
71 // Function return is a pseudo-instruction that needs to be expanded
72 PM.add(llvm::createAArch64ExpandPseudoPass());
75 std::unique_ptr<BenchmarkRunner>
76 createLatencyBenchmarkRunner(const LLVMState &State) const override {
77 return llvm::make_unique<AArch64LatencyBenchmarkRunner>(State);
81 } // namespace
83 static ExegesisTarget *getTheExegesisAArch64Target() {
84 static ExegesisAArch64Target Target;
85 return &Target;
88 void InitializeAArch64ExegesisTarget() {
89 ExegesisTarget::registerTarget(getTheExegesisAArch64Target());
92 } // namespace exegesis