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 #define GET_AVAILABLE_OPCODE_CHECKER 13 #include "AArch64GenInstrInfo.inc" 14 15 namespace llvm { 16 namespace exegesis { 17 18 static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) { 19 switch (RegBitWidth) { 20 case 32: 21 return AArch64::MOVi32imm; 22 case 64: 23 return AArch64::MOVi64imm; 24 } 25 llvm_unreachable("Invalid Value Width"); 26 } 27 28 // Generates instruction to load an immediate value into a register. 29 static MCInst loadImmediate(MCRegister Reg, unsigned RegBitWidth, 30 const APInt &Value) { 31 if (Value.getBitWidth() > RegBitWidth) 32 llvm_unreachable("Value must fit in the Register"); 33 return MCInstBuilder(getLoadImmediateOpcode(RegBitWidth)) 34 .addReg(Reg) 35 .addImm(Value.getZExtValue()); 36 } 37 38 #include "AArch64GenExegesis.inc" 39 40 namespace { 41 42 class ExegesisAArch64Target : public ExegesisTarget { 43 public: 44 ExegesisAArch64Target() 45 : ExegesisTarget(AArch64CpuPfmCounters, AArch64_MC::isOpcodeAvailable) {} 46 47 private: 48 std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, MCRegister Reg, 49 const APInt &Value) const override { 50 if (AArch64::GPR32RegClass.contains(Reg)) 51 return {loadImmediate(Reg, 32, Value)}; 52 if (AArch64::GPR64RegClass.contains(Reg)) 53 return {loadImmediate(Reg, 64, Value)}; 54 errs() << "setRegTo is not implemented, results will be unreliable\n"; 55 return {}; 56 } 57 58 bool matchesArch(Triple::ArchType Arch) const override { 59 return Arch == Triple::aarch64 || Arch == Triple::aarch64_be; 60 } 61 62 void addTargetSpecificPasses(PassManagerBase &PM) const override { 63 // Function return is a pseudo-instruction that needs to be expanded 64 PM.add(createAArch64ExpandPseudoPass()); 65 } 66 }; 67 68 } // namespace 69 70 static ExegesisTarget *getTheExegesisAArch64Target() { 71 static ExegesisAArch64Target Target; 72 return &Target; 73 } 74 75 void InitializeAArch64ExegesisTarget() { 76 ExegesisTarget::registerTarget(getTheExegesisAArch64Target()); 77 } 78 79 } // namespace exegesis 80 } // namespace llvm 81