xref: /llvm-project/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp (revision fa29bee9d0c0734d0c698a7e7899fc92ef5acd24)
1 //===-- MipsMCTargetDesc.cpp - Mips Target Descriptions -------------------===//
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 //
9 // This file provides Mips specific target descriptions.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MipsMCTargetDesc.h"
14 #include "MipsAsmBackend.h"
15 #include "MipsELFStreamer.h"
16 #include "MipsInstPrinter.h"
17 #include "MipsMCAsmInfo.h"
18 #include "MipsMCNaCl.h"
19 #include "MipsTargetStreamer.h"
20 #include "llvm/ADT/Triple.h"
21 #include "llvm/MC/MCCodeEmitter.h"
22 #include "llvm/MC/MCELFStreamer.h"
23 #include "llvm/MC/MCInstrAnalysis.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCObjectWriter.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCSubtargetInfo.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/MC/MachineLocation.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/FormattedStream.h"
32 #include "llvm/Support/TargetRegistry.h"
33 
34 using namespace llvm;
35 
36 #define GET_INSTRINFO_MC_DESC
37 #include "MipsGenInstrInfo.inc"
38 
39 #define GET_SUBTARGETINFO_MC_DESC
40 #include "MipsGenSubtargetInfo.inc"
41 
42 #define GET_REGINFO_MC_DESC
43 #include "MipsGenRegisterInfo.inc"
44 
45 /// Select the Mips CPU for the given triple and cpu name.
46 /// FIXME: Merge with the copy in MipsSubtarget.cpp
47 StringRef MIPS_MC::selectMipsCPU(const Triple &TT, StringRef CPU) {
48   if (CPU.empty() || CPU == "generic") {
49     if (TT.getSubArch() == llvm::Triple::MipsSubArch_r6) {
50       if (TT.isMIPS32())
51         CPU = "mips32r6";
52       else
53         CPU = "mips64r6";
54     } else {
55       if (TT.isMIPS32())
56         CPU = "mips32";
57       else
58         CPU = "mips64";
59     }
60   }
61   return CPU;
62 }
63 
64 static MCInstrInfo *createMipsMCInstrInfo() {
65   MCInstrInfo *X = new MCInstrInfo();
66   InitMipsMCInstrInfo(X);
67   return X;
68 }
69 
70 static MCRegisterInfo *createMipsMCRegisterInfo(const Triple &TT) {
71   MCRegisterInfo *X = new MCRegisterInfo();
72   InitMipsMCRegisterInfo(X, Mips::RA);
73   return X;
74 }
75 
76 static MCSubtargetInfo *createMipsMCSubtargetInfo(const Triple &TT,
77                                                   StringRef CPU, StringRef FS) {
78   CPU = MIPS_MC::selectMipsCPU(TT, CPU);
79   return createMipsMCSubtargetInfoImpl(TT, CPU, FS);
80 }
81 
82 static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI,
83                                       const Triple &TT) {
84   MCAsmInfo *MAI = new MipsMCAsmInfo(TT);
85 
86   unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
87   MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, SP, 0);
88   MAI->addInitialFrameState(Inst);
89 
90   return MAI;
91 }
92 
93 static MCInstPrinter *createMipsMCInstPrinter(const Triple &T,
94                                               unsigned SyntaxVariant,
95                                               const MCAsmInfo &MAI,
96                                               const MCInstrInfo &MII,
97                                               const MCRegisterInfo &MRI) {
98   return new MipsInstPrinter(MAI, MII, MRI);
99 }
100 
101 static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
102                                     std::unique_ptr<MCAsmBackend> &&MAB,
103                                     std::unique_ptr<MCObjectWriter> &&OW,
104                                     std::unique_ptr<MCCodeEmitter> &&Emitter,
105                                     bool RelaxAll) {
106   MCStreamer *S;
107   if (!T.isOSNaCl())
108     S = createMipsELFStreamer(Context, std::move(MAB), std::move(OW),
109                               std::move(Emitter), RelaxAll);
110   else
111     S = createMipsNaClELFStreamer(Context, std::move(MAB), std::move(OW),
112                                   std::move(Emitter), RelaxAll);
113   return S;
114 }
115 
116 static MCTargetStreamer *createMipsAsmTargetStreamer(MCStreamer &S,
117                                                      formatted_raw_ostream &OS,
118                                                      MCInstPrinter *InstPrint,
119                                                      bool isVerboseAsm) {
120   return new MipsTargetAsmStreamer(S, OS);
121 }
122 
123 static MCTargetStreamer *createMipsNullTargetStreamer(MCStreamer &S) {
124   return new MipsTargetStreamer(S);
125 }
126 
127 static MCTargetStreamer *
128 createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
129   return new MipsTargetELFStreamer(S, STI);
130 }
131 
132 namespace {
133 
134 class MipsMCInstrAnalysis : public MCInstrAnalysis {
135 public:
136   MipsMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
137 
138   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
139                       uint64_t &Target) const override {
140     unsigned NumOps = Inst.getNumOperands();
141     if (NumOps == 0)
142       return false;
143     switch (Info->get(Inst.getOpcode()).OpInfo[NumOps - 1].OperandType) {
144     case MCOI::OPERAND_UNKNOWN:
145     case MCOI::OPERAND_IMMEDIATE:
146       // jal, bal ...
147       Target = Inst.getOperand(NumOps - 1).getImm();
148       return true;
149     case MCOI::OPERAND_PCREL:
150       // b, j, beq ...
151       Target = Addr + Inst.getOperand(NumOps - 1).getImm();
152       return true;
153     default:
154       return false;
155     }
156   }
157 };
158 }
159 
160 static MCInstrAnalysis *createMipsMCInstrAnalysis(const MCInstrInfo *Info) {
161   return new MipsMCInstrAnalysis(Info);
162 }
163 
164 extern "C" void LLVMInitializeMipsTargetMC() {
165   for (Target *T : {&getTheMipsTarget(), &getTheMipselTarget(),
166                     &getTheMips64Target(), &getTheMips64elTarget()}) {
167     // Register the MC asm info.
168     RegisterMCAsmInfoFn X(*T, createMipsMCAsmInfo);
169 
170     // Register the MC instruction info.
171     TargetRegistry::RegisterMCInstrInfo(*T, createMipsMCInstrInfo);
172 
173     // Register the MC register info.
174     TargetRegistry::RegisterMCRegInfo(*T, createMipsMCRegisterInfo);
175 
176     // Register the elf streamer.
177     TargetRegistry::RegisterELFStreamer(*T, createMCStreamer);
178 
179     // Register the asm target streamer.
180     TargetRegistry::RegisterAsmTargetStreamer(*T, createMipsAsmTargetStreamer);
181 
182     TargetRegistry::RegisterNullTargetStreamer(*T,
183                                                createMipsNullTargetStreamer);
184 
185     // Register the MC subtarget info.
186     TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo);
187 
188     // Register the MC instruction analyzer.
189     TargetRegistry::RegisterMCInstrAnalysis(*T, createMipsMCInstrAnalysis);
190 
191     // Register the MCInstPrinter.
192     TargetRegistry::RegisterMCInstPrinter(*T, createMipsMCInstPrinter);
193 
194     TargetRegistry::RegisterObjectTargetStreamer(
195         *T, createMipsObjectTargetStreamer);
196 
197     // Register the asm backend.
198     TargetRegistry::RegisterMCAsmBackend(*T, createMipsAsmBackend);
199   }
200 
201   // Register the MC Code Emitter
202   for (Target *T : {&getTheMipsTarget(), &getTheMips64Target()})
203     TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEB);
204 
205   for (Target *T : {&getTheMipselTarget(), &getTheMips64elTarget()})
206     TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEL);
207 }
208