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