Rename TargetAsmBackend to MCAsmBackend; rename createAsmBackend to createMCAsmBackend.
[oota-llvm.git] / lib / Target / ARM / MCTargetDesc / ARMMCTargetDesc.cpp
1 //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions -----------*- 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 //===----------------------------------------------------------------------===//
9 //
10 // This file provides ARM specific target descriptions.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ARMMCTargetDesc.h"
15 #include "ARMMCAsmInfo.h"
16 #include "InstPrinter/ARMInstPrinter.h"
17 #include "llvm/MC/MCInstrInfo.h"
18 #include "llvm/MC/MCRegisterInfo.h"
19 #include "llvm/MC/MCStreamer.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/Target/TargetRegistry.h"
22 #include "llvm/Support/ErrorHandling.h"
23
24 #define GET_REGINFO_MC_DESC
25 #include "ARMGenRegisterInfo.inc"
26
27 #define GET_INSTRINFO_MC_DESC
28 #include "ARMGenInstrInfo.inc"
29
30 #define GET_SUBTARGETINFO_MC_DESC
31 #include "ARMGenSubtargetInfo.inc"
32
33 using namespace llvm;
34
35 std::string ARM_MC::ParseARMTriple(StringRef TT) {
36   // Set the boolean corresponding to the current target triple, or the default
37   // if one cannot be determined, to true.
38   unsigned Len = TT.size();
39   unsigned Idx = 0;
40
41   // FIXME: Enahnce Triple helper class to extract ARM version.
42   bool isThumb = false;
43   if (Len >= 5 && TT.substr(0, 4) == "armv")
44     Idx = 4;
45   else if (Len >= 6 && TT.substr(0, 5) == "thumb") {
46     isThumb = true;
47     if (Len >= 7 && TT[5] == 'v')
48       Idx = 6;
49   }
50
51   std::string ARMArchFeature;
52   if (Idx) {
53     unsigned SubVer = TT[Idx];
54     if (SubVer >= '7' && SubVer <= '9') {
55       if (Len >= Idx+2 && TT[Idx+1] == 'm') {
56         // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv
57         ARMArchFeature = "+v7,+noarm,+db,+hwdiv";
58       } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') {
59         // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2,
60         //       FeatureT2XtPk
61         ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk";
62       } else
63         // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2
64         ARMArchFeature = "+v7,+neon,+db,+t2dsp";
65     } else if (SubVer == '6') {
66       if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
67         ARMArchFeature = "+v6t2";
68       else
69         ARMArchFeature = "+v6";
70     } else if (SubVer == '5') {
71       if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
72         ARMArchFeature = "+v5te";
73       else
74         ARMArchFeature = "+v5t";
75     } else if (SubVer == '4' && Len >= Idx+2 && TT[Idx+1] == 't')
76       ARMArchFeature = "+v4t";
77   }
78
79   if (isThumb) {
80     if (ARMArchFeature.empty())
81       ARMArchFeature = "+thumb-mode";
82     else
83       ARMArchFeature += ",+thumb-mode";
84   }
85
86   return ARMArchFeature;
87 }
88
89 MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU,
90                                                   StringRef FS) {
91   std::string ArchFS = ARM_MC::ParseARMTriple(TT);
92   if (!FS.empty()) {
93     if (!ArchFS.empty())
94       ArchFS = ArchFS + "," + FS.str();
95     else
96       ArchFS = FS;
97   }
98
99   MCSubtargetInfo *X = new MCSubtargetInfo();
100   InitARMMCSubtargetInfo(X, TT, CPU, ArchFS);
101   return X;
102 }
103
104 static MCInstrInfo *createARMMCInstrInfo() {
105   MCInstrInfo *X = new MCInstrInfo();
106   InitARMMCInstrInfo(X);
107   return X;
108 }
109
110 static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) {
111   MCRegisterInfo *X = new MCRegisterInfo();
112   InitARMMCRegisterInfo(X, ARM::LR);
113   return X;
114 }
115
116 static MCAsmInfo *createARMMCAsmInfo(const Target &T, StringRef TT) {
117   Triple TheTriple(TT);
118
119   if (TheTriple.isOSDarwin())
120     return new ARMMCAsmInfoDarwin();
121
122   return new ARMELFMCAsmInfo();
123 }
124
125 static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM,
126                                              CodeModel::Model CM) {
127   MCCodeGenInfo *X = new MCCodeGenInfo();
128   if (RM == Reloc::Default)
129     RM = Reloc::DynamicNoPIC;
130   X->InitMCCodeGenInfo(RM, CM);
131   return X;
132 }
133
134 // This is duplicated code. Refactor this.
135 static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
136                                     MCContext &Ctx, MCAsmBackend &MAB,
137                                     raw_ostream &OS,
138                                     MCCodeEmitter *Emitter,
139                                     bool RelaxAll,
140                                     bool NoExecStack) {
141   Triple TheTriple(TT);
142
143   if (TheTriple.isOSDarwin())
144     return createMachOStreamer(Ctx, MAB, OS, Emitter, RelaxAll);
145
146   if (TheTriple.isOSWindows()) {
147     llvm_unreachable("ARM does not support Windows COFF format");
148     return NULL;
149   }
150
151   return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack);
152 }
153
154 static MCInstPrinter *createARMMCInstPrinter(const Target &T,
155                                              unsigned SyntaxVariant,
156                                              const MCAsmInfo &MAI) {
157   if (SyntaxVariant == 0)
158     return new ARMInstPrinter(MAI);
159   return 0;
160 }
161
162
163 // Force static initialization.
164 extern "C" void LLVMInitializeARMTargetMC() {
165   // Register the MC asm info.
166   RegisterMCAsmInfoFn A(TheARMTarget, createARMMCAsmInfo);
167   RegisterMCAsmInfoFn B(TheThumbTarget, createARMMCAsmInfo);
168
169   // Register the MC codegen info.
170   TargetRegistry::RegisterMCCodeGenInfo(TheARMTarget, createARMMCCodeGenInfo);
171   TargetRegistry::RegisterMCCodeGenInfo(TheThumbTarget, createARMMCCodeGenInfo);
172
173   // Register the MC instruction info.
174   TargetRegistry::RegisterMCInstrInfo(TheARMTarget, createARMMCInstrInfo);
175   TargetRegistry::RegisterMCInstrInfo(TheThumbTarget, createARMMCInstrInfo);
176
177   // Register the MC register info.
178   TargetRegistry::RegisterMCRegInfo(TheARMTarget, createARMMCRegisterInfo);
179   TargetRegistry::RegisterMCRegInfo(TheThumbTarget, createARMMCRegisterInfo);
180
181   // Register the MC subtarget info.
182   TargetRegistry::RegisterMCSubtargetInfo(TheARMTarget,
183                                           ARM_MC::createARMMCSubtargetInfo);
184   TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget,
185                                           ARM_MC::createARMMCSubtargetInfo);
186
187   // Register the MC Code Emitter
188   TargetRegistry::RegisterCodeEmitter(TheARMTarget, createARMMCCodeEmitter);
189   TargetRegistry::RegisterCodeEmitter(TheThumbTarget, createARMMCCodeEmitter);
190
191   // Register the asm backend.
192   TargetRegistry::RegisterMCAsmBackend(TheARMTarget, createARMAsmBackend);
193   TargetRegistry::RegisterMCAsmBackend(TheThumbTarget, createARMAsmBackend);
194
195   // Register the object streamer.
196   TargetRegistry::RegisterObjectStreamer(TheARMTarget, createMCStreamer);
197   TargetRegistry::RegisterObjectStreamer(TheThumbTarget, createMCStreamer);
198
199   // Register the MCInstPrinter.
200   TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
201   TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
202 }