|  | //===-- Target.cpp ----------------------------------------------*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | #include "../Target.h" | 
|  | #include "../Latency.h" | 
|  | #include "AArch64.h" | 
|  | #include "AArch64RegisterInfo.h" | 
|  |  | 
|  | namespace llvm { | 
|  | namespace exegesis { | 
|  |  | 
|  | static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) { | 
|  | switch (RegBitWidth) { | 
|  | case 32: | 
|  | return llvm::AArch64::MOVi32imm; | 
|  | case 64: | 
|  | return llvm::AArch64::MOVi64imm; | 
|  | } | 
|  | 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()); | 
|  | } | 
|  |  | 
|  | #include "AArch64GenExegesis.inc" | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | class ExegesisAArch64Target : public ExegesisTarget { | 
|  | public: | 
|  | ExegesisAArch64Target() : ExegesisTarget(AArch64CpuPfmCounters) {} | 
|  |  | 
|  | private: | 
|  | 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()); | 
|  | } | 
|  | }; | 
|  |  | 
|  | } // namespace | 
|  |  | 
|  | static ExegesisTarget *getTheExegesisAArch64Target() { | 
|  | static ExegesisAArch64Target Target; | 
|  | return &Target; | 
|  | } | 
|  |  | 
|  | void InitializeAArch64ExegesisTarget() { | 
|  | ExegesisTarget::registerTarget(getTheExegesisAArch64Target()); | 
|  | } | 
|  |  | 
|  | } // namespace exegesis | 
|  | } // namespace llvm |