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