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
getLoadImmediateOpcode(unsigned RegBitWidth)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.
loadImmediate(unsigned Reg,unsigned RegBitWidth,const APInt & Value)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:
ExegesisAArch64Target()41 ExegesisAArch64Target() : ExegesisTarget(AArch64CpuPfmCounters) {}
42
43 private:
setRegTo(const MCSubtargetInfo & STI,unsigned Reg,const APInt & Value) const44 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
matchesArch(Triple::ArchType Arch) const54 bool matchesArch(Triple::ArchType Arch) const override {
55 return Arch == Triple::aarch64 || Arch == Triple::aarch64_be;
56 }
57
addTargetSpecificPasses(PassManagerBase & PM) const58 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
getTheExegesisAArch64Target()66 static ExegesisTarget *getTheExegesisAArch64Target() {
67 static ExegesisAArch64Target Target;
68 return &Target;
69 }
70
InitializeAArch64ExegesisTarget()71 void InitializeAArch64ExegesisTarget() {
72 ExegesisTarget::registerTarget(getTheExegesisAArch64Target());
73 }
74
75 } // namespace exegesis
76 } // namespace llvm
77