6c48053615edd89d4fd97fa53df172e6f6fc5353
[oota-llvm.git] / lib / Target / Mips / MCTargetDesc / MipsMCTargetDesc.cpp
1 //===-- MipsMCTargetDesc.cpp - Mips 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 Mips specific target descriptions.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "MipsMCTargetDesc.h"
15 #include "InstPrinter/MipsInstPrinter.h"
16 #include "MipsMCAsmInfo.h"
17 #include "MipsTargetStreamer.h"
18 #include "llvm/MC/MCCodeGenInfo.h"
19 #include "llvm/MC/MCELF.h"
20 #include "llvm/MC/MCELFStreamer.h"
21 #include "llvm/MC/MCInstrInfo.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/MC/MachineLocation.h"
26 #include "llvm/Support/CommandLine.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/FormattedStream.h"
29 #include "llvm/Support/TargetRegistry.h"
30
31 #define GET_INSTRINFO_MC_DESC
32 #include "MipsGenInstrInfo.inc"
33
34 #define GET_SUBTARGETINFO_MC_DESC
35 #include "MipsGenSubtargetInfo.inc"
36
37 #define GET_REGINFO_MC_DESC
38 #include "MipsGenRegisterInfo.inc"
39
40 using namespace llvm;
41
42 static cl::opt<bool> PrintHackDirectives("print-hack-directives",
43                                          cl::init(false), cl::Hidden);
44
45 static std::string ParseMipsTriple(StringRef TT, StringRef CPU) {
46   std::string MipsArchFeature;
47   size_t DashPosition = 0;
48   StringRef TheTriple;
49
50   // Let's see if there is a dash, like mips-unknown-linux.
51   DashPosition = TT.find('-');
52
53   if (DashPosition == StringRef::npos) {
54     // No dash, we check the string size.
55     TheTriple = TT.substr(0);
56   } else {
57     // We are only interested in substring before dash.
58     TheTriple = TT.substr(0,DashPosition);
59   }
60
61   if (TheTriple == "mips" || TheTriple == "mipsel") {
62     if (CPU.empty() || CPU == "mips32") {
63       MipsArchFeature = "+mips32";
64     } else if (CPU == "mips32r2") {
65       MipsArchFeature = "+mips32r2";
66     }
67   } else {
68       if (CPU.empty() || CPU == "mips64") {
69         MipsArchFeature = "+mips64";
70       } else if (CPU == "mips64r2") {
71         MipsArchFeature = "+mips64r2";
72       }
73   }
74   return MipsArchFeature;
75 }
76
77 static MCInstrInfo *createMipsMCInstrInfo() {
78   MCInstrInfo *X = new MCInstrInfo();
79   InitMipsMCInstrInfo(X);
80   return X;
81 }
82
83 static MCRegisterInfo *createMipsMCRegisterInfo(StringRef TT) {
84   MCRegisterInfo *X = new MCRegisterInfo();
85   InitMipsMCRegisterInfo(X, Mips::RA);
86   return X;
87 }
88
89 static MCSubtargetInfo *createMipsMCSubtargetInfo(StringRef TT, StringRef CPU,
90                                                   StringRef FS) {
91   std::string ArchFS = ParseMipsTriple(TT,CPU);
92   if (!FS.empty()) {
93     if (!ArchFS.empty())
94       ArchFS = ArchFS + "," + FS.str();
95     else
96       ArchFS = FS;
97   }
98   MCSubtargetInfo *X = new MCSubtargetInfo();
99   InitMipsMCSubtargetInfo(X, TT, CPU, ArchFS);
100   return X;
101 }
102
103 static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
104   MCAsmInfo *MAI = new MipsMCAsmInfo(TT);
105
106   unsigned SP = MRI.getDwarfRegNum(Mips::SP, true);
107   MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, SP, 0);
108   MAI->addInitialFrameState(Inst);
109
110   return MAI;
111 }
112
113 static MCCodeGenInfo *createMipsMCCodeGenInfo(StringRef TT, Reloc::Model RM,
114                                               CodeModel::Model CM,
115                                               CodeGenOpt::Level OL) {
116   MCCodeGenInfo *X = new MCCodeGenInfo();
117   if (CM == CodeModel::JITDefault)
118     RM = Reloc::Static;
119   else if (RM == Reloc::Default)
120     RM = Reloc::PIC_;
121   X->InitMCCodeGenInfo(RM, CM, OL);
122   return X;
123 }
124
125 static MCInstPrinter *createMipsMCInstPrinter(const Target &T,
126                                               unsigned SyntaxVariant,
127                                               const MCAsmInfo &MAI,
128                                               const MCInstrInfo &MII,
129                                               const MCRegisterInfo &MRI,
130                                               const MCSubtargetInfo &STI) {
131   return new MipsInstPrinter(MAI, MII, MRI);
132 }
133
134 namespace {
135 class MipsTargetAsmStreamer : public MipsTargetStreamer {
136   formatted_raw_ostream &OS;
137
138 public:
139   MipsTargetAsmStreamer(formatted_raw_ostream &OS);
140   virtual void emitMipsHackELFFlags(unsigned Flags);
141   virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val);
142 };
143
144 MipsTargetAsmStreamer::MipsTargetAsmStreamer(formatted_raw_ostream &OS)
145     : OS(OS) {}
146
147 void MipsTargetAsmStreamer::emitMipsHackELFFlags(unsigned Flags) {
148   if (!PrintHackDirectives)
149     return;
150
151   OS << "\t.mips_hack_elf_flags 0x";
152   OS.write_hex(Flags);
153   OS << '\n';
154 }
155 void MipsTargetAsmStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) {
156   if (!PrintHackDirectives)
157     return;
158
159   OS << "\t.mips_hack_stocg ";
160   OS << Sym->getName();
161   OS << ", ";
162   OS << Val;
163   OS << '\n';
164 }
165
166 class MipsTargetELFStreamer : public MipsTargetStreamer {
167 public:
168   MCELFStreamer &getStreamer();
169   MipsTargetELFStreamer();
170   virtual void emitMipsHackELFFlags(unsigned Flags);
171   virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val);
172 };
173
174 MipsTargetELFStreamer::MipsTargetELFStreamer() {}
175
176 MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
177   return static_cast<MCELFStreamer &>(*Streamer);
178 }
179
180 void MipsTargetELFStreamer::emitMipsHackELFFlags(unsigned Flags) {
181   MCAssembler &MCA = getStreamer().getAssembler();
182   MCA.setELFHeaderEFlags(Flags);
183 }
184
185 // Set a symbol's STO flags
186 void MipsTargetELFStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) {
187   MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Sym);
188   // The "other" values are stored in the last 6 bits of the second byte
189   // The traditional defines for STO values assume the full byte and thus
190   // the shift to pack it.
191   MCELF::setOther(Data, Val >> 2);
192 }
193 }
194
195 static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
196                                     MCContext &Context, MCAsmBackend &MAB,
197                                     raw_ostream &OS, MCCodeEmitter *Emitter,
198                                     bool RelaxAll, bool NoExecStack) {
199   MipsTargetELFStreamer *S = new MipsTargetELFStreamer();
200   return createELFStreamer(Context, S, MAB, OS, Emitter, RelaxAll, NoExecStack);
201 }
202
203 static MCStreamer *
204 createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
205                     bool isVerboseAsm, bool useLoc, bool useCFI,
206                     bool useDwarfDirectory, MCInstPrinter *InstPrint,
207                     MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) {
208   MipsTargetAsmStreamer *S = new MipsTargetAsmStreamer(OS);
209
210   return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
211                                  useDwarfDirectory, InstPrint, CE, TAB,
212                                  ShowInst);
213 }
214
215 extern "C" void LLVMInitializeMipsTargetMC() {
216   // Register the MC asm info.
217   RegisterMCAsmInfoFn X(TheMipsTarget, createMipsMCAsmInfo);
218   RegisterMCAsmInfoFn Y(TheMipselTarget, createMipsMCAsmInfo);
219   RegisterMCAsmInfoFn A(TheMips64Target, createMipsMCAsmInfo);
220   RegisterMCAsmInfoFn B(TheMips64elTarget, createMipsMCAsmInfo);
221
222   // Register the MC codegen info.
223   TargetRegistry::RegisterMCCodeGenInfo(TheMipsTarget,
224                                         createMipsMCCodeGenInfo);
225   TargetRegistry::RegisterMCCodeGenInfo(TheMipselTarget,
226                                         createMipsMCCodeGenInfo);
227   TargetRegistry::RegisterMCCodeGenInfo(TheMips64Target,
228                                         createMipsMCCodeGenInfo);
229   TargetRegistry::RegisterMCCodeGenInfo(TheMips64elTarget,
230                                         createMipsMCCodeGenInfo);
231
232   // Register the MC instruction info.
233   TargetRegistry::RegisterMCInstrInfo(TheMipsTarget, createMipsMCInstrInfo);
234   TargetRegistry::RegisterMCInstrInfo(TheMipselTarget, createMipsMCInstrInfo);
235   TargetRegistry::RegisterMCInstrInfo(TheMips64Target, createMipsMCInstrInfo);
236   TargetRegistry::RegisterMCInstrInfo(TheMips64elTarget,
237                                       createMipsMCInstrInfo);
238
239   // Register the MC register info.
240   TargetRegistry::RegisterMCRegInfo(TheMipsTarget, createMipsMCRegisterInfo);
241   TargetRegistry::RegisterMCRegInfo(TheMipselTarget, createMipsMCRegisterInfo);
242   TargetRegistry::RegisterMCRegInfo(TheMips64Target, createMipsMCRegisterInfo);
243   TargetRegistry::RegisterMCRegInfo(TheMips64elTarget,
244                                     createMipsMCRegisterInfo);
245
246   // Register the MC Code Emitter
247   TargetRegistry::RegisterMCCodeEmitter(TheMipsTarget,
248                                         createMipsMCCodeEmitterEB);
249   TargetRegistry::RegisterMCCodeEmitter(TheMipselTarget,
250                                         createMipsMCCodeEmitterEL);
251   TargetRegistry::RegisterMCCodeEmitter(TheMips64Target,
252                                         createMipsMCCodeEmitterEB);
253   TargetRegistry::RegisterMCCodeEmitter(TheMips64elTarget,
254                                         createMipsMCCodeEmitterEL);
255
256   // Register the object streamer.
257   TargetRegistry::RegisterMCObjectStreamer(TheMipsTarget, createMCStreamer);
258   TargetRegistry::RegisterMCObjectStreamer(TheMipselTarget, createMCStreamer);
259   TargetRegistry::RegisterMCObjectStreamer(TheMips64Target, createMCStreamer);
260   TargetRegistry::RegisterMCObjectStreamer(TheMips64elTarget,
261                                            createMCStreamer);
262
263   // Register the asm streamer.
264   TargetRegistry::RegisterAsmStreamer(TheMipsTarget, createMCAsmStreamer);
265   TargetRegistry::RegisterAsmStreamer(TheMipselTarget, createMCAsmStreamer);
266   TargetRegistry::RegisterAsmStreamer(TheMips64Target, createMCAsmStreamer);
267   TargetRegistry::RegisterAsmStreamer(TheMips64elTarget, createMCAsmStreamer);
268
269   // Register the asm backend.
270   TargetRegistry::RegisterMCAsmBackend(TheMipsTarget,
271                                        createMipsAsmBackendEB32);
272   TargetRegistry::RegisterMCAsmBackend(TheMipselTarget,
273                                        createMipsAsmBackendEL32);
274   TargetRegistry::RegisterMCAsmBackend(TheMips64Target,
275                                        createMipsAsmBackendEB64);
276   TargetRegistry::RegisterMCAsmBackend(TheMips64elTarget,
277                                        createMipsAsmBackendEL64);
278
279   // Register the MC subtarget info.
280   TargetRegistry::RegisterMCSubtargetInfo(TheMipsTarget,
281                                           createMipsMCSubtargetInfo);
282   TargetRegistry::RegisterMCSubtargetInfo(TheMipselTarget,
283                                           createMipsMCSubtargetInfo);
284   TargetRegistry::RegisterMCSubtargetInfo(TheMips64Target,
285                                           createMipsMCSubtargetInfo);
286   TargetRegistry::RegisterMCSubtargetInfo(TheMips64elTarget,
287                                           createMipsMCSubtargetInfo);
288
289   // Register the MCInstPrinter.
290   TargetRegistry::RegisterMCInstPrinter(TheMipsTarget,
291                                         createMipsMCInstPrinter);
292   TargetRegistry::RegisterMCInstPrinter(TheMipselTarget,
293                                         createMipsMCInstPrinter);
294   TargetRegistry::RegisterMCInstPrinter(TheMips64Target,
295                                         createMipsMCInstPrinter);
296   TargetRegistry::RegisterMCInstPrinter(TheMips64elTarget,
297                                         createMipsMCInstPrinter);
298 }