Fix relocation selection for foo-. on mips.
[oota-llvm.git] / lib / Target / TargetMachineC.cpp
1 //===-- TargetMachine.cpp -------------------------------------------------===//
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 implements the LLVM-C part of TargetMachine.h
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm-c/TargetMachine.h"
15 #include "llvm-c/Core.h"
16 #include "llvm-c/Target.h"
17 #include "llvm/Analysis/TargetTransformInfo.h"
18 #include "llvm/IR/DataLayout.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/IR/LegacyPassManager.h"
21 #include "llvm/Support/CodeGen.h"
22 #include "llvm/Support/FileSystem.h"
23 #include "llvm/Support/FormattedStream.h"
24 #include "llvm/Support/Host.h"
25 #include "llvm/Support/TargetRegistry.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "llvm/Target/TargetMachine.h"
28 #include "llvm/Target/TargetSubtargetInfo.h"
29 #include <cassert>
30 #include <cstdlib>
31 #include <cstring>
32
33 using namespace llvm;
34
35 inline TargetMachine *unwrap(LLVMTargetMachineRef P) {
36   return reinterpret_cast<TargetMachine*>(P);
37 }
38 inline Target *unwrap(LLVMTargetRef P) {
39   return reinterpret_cast<Target*>(P);
40 }
41 inline LLVMTargetMachineRef wrap(const TargetMachine *P) {
42   return
43     reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
44 }
45 inline LLVMTargetRef wrap(const Target * P) {
46   return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
47 }
48
49 LLVMTargetRef LLVMGetFirstTarget() {
50   if (TargetRegistry::targets().begin() == TargetRegistry::targets().end()) {
51     return nullptr;
52   }
53
54   const Target *target = &*TargetRegistry::targets().begin();
55   return wrap(target);
56 }
57 LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
58   return wrap(unwrap(T)->getNext());
59 }
60
61 LLVMTargetRef LLVMGetTargetFromName(const char *Name) {
62   StringRef NameRef = Name;
63   auto I = std::find_if(
64       TargetRegistry::targets().begin(), TargetRegistry::targets().end(),
65       [&](const Target &T) { return T.getName() == NameRef; });
66   return I != TargetRegistry::targets().end() ? wrap(&*I) : nullptr;
67 }
68
69 LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,
70                                  char **ErrorMessage) {
71   std::string Error;
72   
73   *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));
74   
75   if (!*T) {
76     if (ErrorMessage)
77       *ErrorMessage = strdup(Error.c_str());
78
79     return 1;
80   }
81   
82   return 0;
83 }
84
85 const char * LLVMGetTargetName(LLVMTargetRef T) {
86   return unwrap(T)->getName();
87 }
88
89 const char * LLVMGetTargetDescription(LLVMTargetRef T) {
90   return unwrap(T)->getShortDescription();
91 }
92
93 LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
94   return unwrap(T)->hasJIT();
95 }
96
97 LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
98   return unwrap(T)->hasTargetMachine();
99 }
100
101 LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
102   return unwrap(T)->hasMCAsmBackend();
103 }
104
105 LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T,
106         const char* Triple, const char* CPU, const char* Features,
107         LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
108         LLVMCodeModel CodeModel) {
109   Reloc::Model RM;
110   switch (Reloc){
111     case LLVMRelocStatic:
112       RM = Reloc::Static;
113       break;
114     case LLVMRelocPIC:
115       RM = Reloc::PIC_;
116       break;
117     case LLVMRelocDynamicNoPic:
118       RM = Reloc::DynamicNoPIC;
119       break;
120     default:
121       RM = Reloc::Default;
122       break;
123   }
124
125   CodeModel::Model CM = unwrap(CodeModel);
126
127   CodeGenOpt::Level OL;
128   switch (Level) {
129     case LLVMCodeGenLevelNone:
130       OL = CodeGenOpt::None;
131       break;
132     case LLVMCodeGenLevelLess:
133       OL = CodeGenOpt::Less;
134       break;
135     case LLVMCodeGenLevelAggressive:
136       OL = CodeGenOpt::Aggressive;
137       break;
138     default:
139       OL = CodeGenOpt::Default;
140       break;
141   }
142
143   TargetOptions opt;
144   return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM,
145     CM, OL));
146 }
147
148
149 void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) {
150   delete unwrap(T);
151 }
152
153 LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
154   const Target* target = &(unwrap(T)->getTarget());
155   return wrap(target);
156 }
157
158 char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
159   std::string StringRep = unwrap(T)->getTargetTriple();
160   return strdup(StringRep.c_str());
161 }
162
163 char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
164   std::string StringRep = unwrap(T)->getTargetCPU();
165   return strdup(StringRep.c_str());
166 }
167
168 char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
169   std::string StringRep = unwrap(T)->getTargetFeatureString();
170   return strdup(StringRep.c_str());
171 }
172
173 LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) {
174   return wrap(unwrap(T)->getDataLayout());
175 }
176
177 void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
178                                       LLVMBool VerboseAsm) {
179   unwrap(T)->Options.MCOptions.AsmVerbose = VerboseAsm;
180 }
181
182 static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
183                                       raw_pwrite_stream &OS,
184                                       LLVMCodeGenFileType codegen,
185                                       char **ErrorMessage) {
186   TargetMachine* TM = unwrap(T);
187   Module* Mod = unwrap(M);
188
189   legacy::PassManager pass;
190
191   std::string error;
192
193   const DataLayout *td = TM->getDataLayout();
194
195   if (!td) {
196     error = "No DataLayout in TargetMachine";
197     *ErrorMessage = strdup(error.c_str());
198     return true;
199   }
200   Mod->setDataLayout(*td);
201
202   TargetMachine::CodeGenFileType ft;
203   switch (codegen) {
204     case LLVMAssemblyFile:
205       ft = TargetMachine::CGFT_AssemblyFile;
206       break;
207     default:
208       ft = TargetMachine::CGFT_ObjectFile;
209       break;
210   }
211   if (TM->addPassesToEmitFile(pass, OS, ft)) {
212     error = "TargetMachine can't emit a file of this type";
213     *ErrorMessage = strdup(error.c_str());
214     return true;
215   }
216
217   pass.run(*Mod);
218
219   OS.flush();
220   return false;
221 }
222
223 LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
224   char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) {
225   std::error_code EC;
226   raw_fd_ostream dest(Filename, EC, sys::fs::F_None);
227   if (EC) {
228     *ErrorMessage = strdup(EC.message().c_str());
229     return true;
230   }
231   bool Result = LLVMTargetMachineEmit(T, M, dest, codegen, ErrorMessage);
232   dest.flush();
233   return Result;
234 }
235
236 LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
237   LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,
238   LLVMMemoryBufferRef *OutMemBuf) {
239   SmallString<0> CodeString;
240   raw_svector_ostream OStream(CodeString);
241   bool Result = LLVMTargetMachineEmit(T, M, OStream, codegen, ErrorMessage);
242   OStream.flush();
243
244   StringRef Data = OStream.str();
245   *OutMemBuf =
246       LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.data(), Data.size(), "");
247   return Result;
248 }
249
250 char *LLVMGetDefaultTargetTriple(void) {
251   return strdup(sys::getDefaultTargetTriple().c_str());
252 }
253
254 void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {
255   unwrap(PM)->add(
256       createTargetTransformInfoWrapperPass(unwrap(T)->getTargetIRAnalysis()));
257 }