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