//===-- Target.cpp ----------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "../Target.h" #include "AArch64.h" #include "AArch64RegisterInfo.h" namespace llvm { namespace exegesis { static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) { switch (RegBitWidth) { case 32: return AArch64::MOVi32imm; case 64: return AArch64::MOVi64imm; } llvm_unreachable("Invalid Value Width"); } // Generates instruction to load an immediate value into a register. static MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth, const APInt &Value) { if (Value.getBitWidth() > RegBitWidth) llvm_unreachable("Value must fit in the Register"); return MCInstBuilder(getLoadImmediateOpcode(RegBitWidth)) .addReg(Reg) .addImm(Value.getZExtValue()); } #include "AArch64GenExegesis.inc" namespace { class ExegesisAArch64Target : public ExegesisTarget { public: ExegesisAArch64Target() : ExegesisTarget(AArch64CpuPfmCounters) {} private: std::vector setRegTo(const MCSubtargetInfo &STI, unsigned Reg, const APInt &Value) const override { if (AArch64::GPR32RegClass.contains(Reg)) return {loadImmediate(Reg, 32, Value)}; if (AArch64::GPR64RegClass.contains(Reg)) return {loadImmediate(Reg, 64, Value)}; errs() << "setRegTo is not implemented, results will be unreliable\n"; return {}; } bool matchesArch(Triple::ArchType Arch) const override { return Arch == Triple::aarch64 || Arch == Triple::aarch64_be; } void addTargetSpecificPasses(PassManagerBase &PM) const override { // Function return is a pseudo-instruction that needs to be expanded PM.add(createAArch64ExpandPseudoPass()); } }; } // namespace static ExegesisTarget *getTheExegesisAArch64Target() { static ExegesisAArch64Target Target; return &Target; } void InitializeAArch64ExegesisTarget() { ExegesisTarget::registerTarget(getTheExegesisAArch64Target()); } } // namespace exegesis } // namespace llvm