1 //===-- LanaiMCTargetDesc.cpp - Lanai Target Descriptions -----------------===//
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 //===----------------------------------------------------------------------===//
9 //
10 // This file provides Lanai specific target descriptions.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "LanaiMCTargetDesc.h"
15
16 #include "InstPrinter/LanaiInstPrinter.h"
17 #include "LanaiMCAsmInfo.h"
18 #include "llvm/MC/MCInstrAnalysis.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCStreamer.h"
21 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/TargetRegistry.h"
24
25 #define GET_INSTRINFO_MC_DESC
26 #include "LanaiGenInstrInfo.inc"
27
28 #define GET_SUBTARGETINFO_MC_DESC
29 #include "LanaiGenSubtargetInfo.inc"
30
31 #define GET_REGINFO_MC_DESC
32 #include "LanaiGenRegisterInfo.inc"
33
34 using namespace llvm;
35
createLanaiMCInstrInfo()36 static MCInstrInfo *createLanaiMCInstrInfo() {
37 MCInstrInfo *X = new MCInstrInfo();
38 InitLanaiMCInstrInfo(X);
39 return X;
40 }
41
createLanaiMCRegisterInfo(const Triple & TT)42 static MCRegisterInfo *createLanaiMCRegisterInfo(const Triple &TT) {
43 MCRegisterInfo *X = new MCRegisterInfo();
44 InitLanaiMCRegisterInfo(X, Lanai::RCA, 0, 0, Lanai::PC);
45 return X;
46 }
47
48 static MCSubtargetInfo *
createLanaiMCSubtargetInfo(const Triple & TT,StringRef CPU,StringRef FS)49 createLanaiMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
50 std::string CPUName = CPU;
51 if (CPUName.empty())
52 CPUName = "generic";
53
54 return createLanaiMCSubtargetInfoImpl(TT, CPUName, FS);
55 }
56
createMCStreamer(const Triple & T,MCContext & Context,MCAsmBackend & MAB,raw_pwrite_stream & OS,MCCodeEmitter * Emitter,bool RelaxAll)57 static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
58 MCAsmBackend &MAB, raw_pwrite_stream &OS,
59 MCCodeEmitter *Emitter, bool RelaxAll) {
60 if (!T.isOSBinFormatELF())
61 llvm_unreachable("OS not supported");
62
63 return createELFStreamer(Context, MAB, OS, Emitter, RelaxAll);
64 }
65
createLanaiMCInstPrinter(const Triple & T,unsigned SyntaxVariant,const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)66 static MCInstPrinter *createLanaiMCInstPrinter(const Triple &T,
67 unsigned SyntaxVariant,
68 const MCAsmInfo &MAI,
69 const MCInstrInfo &MII,
70 const MCRegisterInfo &MRI) {
71 if (SyntaxVariant == 0)
72 return new LanaiInstPrinter(MAI, MII, MRI);
73 return 0;
74 }
75
createLanaiElfRelocation(const Triple & TheTriple,MCContext & Ctx)76 MCRelocationInfo *createLanaiElfRelocation(const Triple &TheTriple,
77 MCContext &Ctx) {
78 return createMCRelocationInfo(TheTriple, Ctx);
79 }
80
81 class LanaiMCInstrAnalysis : public MCInstrAnalysis {
82 public:
LanaiMCInstrAnalysis(const MCInstrInfo * Info)83 explicit LanaiMCInstrAnalysis(const MCInstrInfo *Info)
84 : MCInstrAnalysis(Info) {}
85
evaluateBranch(const MCInst & Inst,uint64_t Addr,uint64_t Size,uint64_t & Target) const86 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
87 uint64_t &Target) const override {
88 if (Inst.getNumOperands() == 0)
89 return false;
90
91 if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType ==
92 MCOI::OPERAND_PCREL) {
93 int64_t Imm = Inst.getOperand(0).getImm();
94 Target = Addr + Size + Imm;
95 return true;
96 } else {
97 int64_t Imm = Inst.getOperand(0).getImm();
98
99 // Skip case where immediate is 0 as that occurs in file that isn't linked
100 // and the branch target inferred would be wrong.
101 if (Imm == 0)
102 return false;
103
104 Target = Imm;
105 return true;
106 }
107 }
108 };
109
createLanaiInstrAnalysis(const MCInstrInfo * Info)110 static MCInstrAnalysis *createLanaiInstrAnalysis(const MCInstrInfo *Info) {
111 return new LanaiMCInstrAnalysis(Info);
112 }
113
LLVMInitializeLanaiTargetMC()114 extern "C" void LLVMInitializeLanaiTargetMC() {
115 // Register the MC asm info.
116 RegisterMCAsmInfo<LanaiMCAsmInfo> X(TheLanaiTarget);
117
118 // Register the MC instruction info.
119 TargetRegistry::RegisterMCInstrInfo(TheLanaiTarget, createLanaiMCInstrInfo);
120
121 // Register the MC register info.
122 TargetRegistry::RegisterMCRegInfo(TheLanaiTarget, createLanaiMCRegisterInfo);
123
124 // Register the MC subtarget info.
125 TargetRegistry::RegisterMCSubtargetInfo(TheLanaiTarget,
126 createLanaiMCSubtargetInfo);
127
128 // Register the MC code emitter
129 TargetRegistry::RegisterMCCodeEmitter(TheLanaiTarget,
130 llvm::createLanaiMCCodeEmitter);
131
132 // Register the ASM Backend
133 TargetRegistry::RegisterMCAsmBackend(TheLanaiTarget, createLanaiAsmBackend);
134
135 // Register the MCInstPrinter.
136 TargetRegistry::RegisterMCInstPrinter(TheLanaiTarget,
137 createLanaiMCInstPrinter);
138
139 // Register the ELF streamer.
140 TargetRegistry::RegisterELFStreamer(TheLanaiTarget, createMCStreamer);
141
142 // Register the MC relocation info.
143 TargetRegistry::RegisterMCRelocationInfo(TheLanaiTarget,
144 createLanaiElfRelocation);
145
146 // Register the MC instruction analyzer.
147 TargetRegistry::RegisterMCInstrAnalysis(TheLanaiTarget,
148 createLanaiInstrAnalysis);
149 }
150