1 //===-- Target.cpp ----------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 #include "../Target.h" 9 #include "AArch64.h" 10 #include "AArch64RegisterInfo.h" 11 12 namespace llvm { 13 namespace exegesis { 14 15 static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) { 16 switch (RegBitWidth) { 17 case 32: 18 return AArch64::MOVi32imm; 19 case 64: 20 return AArch64::MOVi64imm; 21 } 22 llvm_unreachable("Invalid Value Width"); 23 } 24 25 // Generates instruction to load an immediate value into a register. 26 static MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth, 27 const APInt &Value) { 28 if (Value.getBitWidth() > RegBitWidth) 29 llvm_unreachable("Value must fit in the Register"); 30 return MCInstBuilder(getLoadImmediateOpcode(RegBitWidth)) 31 .addReg(Reg) 32 .addImm(Value.getZExtValue()); 33 } 34 35 #include "AArch64GenExegesis.inc" 36 37 namespace { 38 39 class ExegesisAArch64Target : public ExegesisTarget { 40 public: 41 ExegesisAArch64Target() : ExegesisTarget(AArch64CpuPfmCounters) {} 42 43 private: 44 std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg, 45 const APInt &Value) const override { 46 if (AArch64::GPR32RegClass.contains(Reg)) 47 return {loadImmediate(Reg, 32, Value)}; 48 if (AArch64::GPR64RegClass.contains(Reg)) 49 return {loadImmediate(Reg, 64, Value)}; 50 errs() << "setRegTo is not implemented, results will be unreliable\n"; 51 return {}; 52 } 53 54 bool matchesArch(Triple::ArchType Arch) const override { 55 return Arch == Triple::aarch64 || Arch == Triple::aarch64_be; 56 } 57 58 void addTargetSpecificPasses(PassManagerBase &PM) const override { 59 // Function return is a pseudo-instruction that needs to be expanded 60 PM.add(createAArch64ExpandPseudoPass()); 61 } 62 }; 63 64 } // namespace 65 66 static ExegesisTarget *getTheExegesisAArch64Target() { 67 static ExegesisAArch64Target Target; 68 return &Target; 69 } 70 71 void InitializeAArch64ExegesisTarget() { 72 ExegesisTarget::registerTarget(getTheExegesisAArch64Target()); 73 } 74 75 } // namespace exegesis 76 } // namespace llvm 77