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 // The PowerPC ExegesisTarget.
8 //===----------------------------------------------------------------------===//
9 #include "../Target.h"
10 #include "../Latency.h"
11 #include "PPC.h"
12 #include "PPCRegisterInfo.h"
13 
14 namespace llvm {
15 namespace exegesis {
16 
17 #include "PPCGenExegesis.inc"
18 
19 namespace {
20 class ExegesisPowerPCTarget : public ExegesisTarget {
21 public:
22   ExegesisPowerPCTarget() : ExegesisTarget(PPCCpuPfmCounters) {}
23 
24 private:
25   std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
26                                      unsigned Reg,
27                                      const llvm::APInt &Value) const override;
28   bool matchesArch(llvm::Triple::ArchType Arch) const override {
29     return Arch == llvm::Triple::ppc64le;
30   }
31 };
32 } // end anonymous namespace
33 
34 static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
35   switch (RegBitWidth) {
36   case 32:
37     return llvm::PPC::LI;
38   case 64:
39     return llvm::PPC::LI8;
40   }
41   llvm_unreachable("Invalid Value Width");
42 }
43 
44 // Generates instruction to load an immediate value into a register.
45 static llvm::MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
46                                   const llvm::APInt &Value) {
47   if (Value.getBitWidth() > RegBitWidth)
48     llvm_unreachable("Value must fit in the Register");
49   return llvm::MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
50       .addReg(Reg)
51       .addImm(Value.getZExtValue());
52 }
53 
54 std::vector<llvm::MCInst>
55 ExegesisPowerPCTarget::setRegTo(const llvm::MCSubtargetInfo &STI, unsigned Reg,
56                                 const llvm::APInt &Value) const {
57   if (llvm::PPC::GPRCRegClass.contains(Reg))
58     return {loadImmediate(Reg, 32, Value)};
59   if (llvm::PPC::G8RCRegClass.contains(Reg))
60     return {loadImmediate(Reg, 64, Value)};
61   llvm::errs() << "setRegTo is not implemented, results will be unreliable\n";
62   return {};
63 }
64 
65 static ExegesisTarget *getTheExegesisPowerPCTarget() {
66   static ExegesisPowerPCTarget Target;
67   return &Target;
68 }
69 
70 void InitializePowerPCExegesisTarget() {
71   ExegesisTarget::registerTarget(getTheExegesisPowerPCTarget());
72 }
73 
74 } // namespace exegesis
75 } // namespace llvm
76