1234285Sdim//===-- TargetMachine.cpp -------------------------------------------------===// 2234285Sdim// 3234285Sdim// The LLVM Compiler Infrastructure 4234285Sdim// 5234285Sdim// This file is distributed under the University of Illinois Open Source 6234285Sdim// License. See LICENSE.TXT for details. 7234285Sdim// 8234285Sdim//===----------------------------------------------------------------------===// 9234285Sdim// 10234285Sdim// This file implements the LLVM-C part of TargetMachine.h 11234285Sdim// 12234285Sdim//===----------------------------------------------------------------------===// 13234285Sdim 14252723Sdim#include "llvm-c/TargetMachine.h" 15234285Sdim#include "llvm-c/Core.h" 16234285Sdim#include "llvm-c/Target.h" 17252723Sdim#include "llvm/IR/DataLayout.h" 18252723Sdim#include "llvm/IR/Module.h" 19252723Sdim#include "llvm/PassManager.h" 20252723Sdim#include "llvm/Support/CodeGen.h" 21252723Sdim#include "llvm/Support/FormattedStream.h" 22234285Sdim#include "llvm/Support/TargetRegistry.h" 23234285Sdim#include "llvm/Support/raw_ostream.h" 24263509Sdim#include "llvm/Support/Host.h" 25252723Sdim#include "llvm/Target/TargetMachine.h" 26234285Sdim#include <cassert> 27234285Sdim#include <cstdlib> 28234285Sdim#include <cstring> 29234285Sdim 30234285Sdimusing namespace llvm; 31234285Sdim 32252723Sdiminline DataLayout *unwrap(LLVMTargetDataRef P) { 33252723Sdim return reinterpret_cast<DataLayout*>(P); 34252723Sdim} 35234285Sdim 36252723Sdiminline LLVMTargetDataRef wrap(const DataLayout *P) { 37252723Sdim return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P)); 38252723Sdim} 39234285Sdim 40252723Sdiminline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) { 41252723Sdim return reinterpret_cast<TargetLibraryInfo*>(P); 42252723Sdim} 43252723Sdim 44252723Sdiminline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) { 45252723Sdim TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P); 46252723Sdim return reinterpret_cast<LLVMTargetLibraryInfoRef>(X); 47252723Sdim} 48252723Sdim 49252723Sdiminline TargetMachine *unwrap(LLVMTargetMachineRef P) { 50252723Sdim return reinterpret_cast<TargetMachine*>(P); 51252723Sdim} 52252723Sdiminline Target *unwrap(LLVMTargetRef P) { 53252723Sdim return reinterpret_cast<Target*>(P); 54252723Sdim} 55252723Sdiminline LLVMTargetMachineRef wrap(const TargetMachine *P) { 56252723Sdim return 57252723Sdim reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P)); 58252723Sdim} 59252723Sdiminline LLVMTargetRef wrap(const Target * P) { 60252723Sdim return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P)); 61252723Sdim} 62252723Sdim 63234285SdimLLVMTargetRef LLVMGetFirstTarget() { 64263509Sdim if(TargetRegistry::begin() == TargetRegistry::end()) { 65263509Sdim return NULL; 66263509Sdim } 67263509Sdim 68263509Sdim const Target* target = &*TargetRegistry::begin(); 69263509Sdim return wrap(target); 70234285Sdim} 71234285SdimLLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) { 72234285Sdim return wrap(unwrap(T)->getNext()); 73234285Sdim} 74234285Sdim 75263509SdimLLVMTargetRef LLVMGetTargetFromName(const char *Name) { 76263509Sdim StringRef NameRef = Name; 77263509Sdim for (TargetRegistry::iterator IT = TargetRegistry::begin(), 78263509Sdim IE = TargetRegistry::end(); IT != IE; ++IT) { 79263509Sdim if (IT->getName() == NameRef) 80263509Sdim return wrap(&*IT); 81263509Sdim } 82263509Sdim 83263509Sdim return NULL; 84263509Sdim} 85263509Sdim 86263509SdimLLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T, 87263509Sdim char **ErrorMessage) { 88263509Sdim std::string Error; 89263509Sdim 90263509Sdim *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error)); 91263509Sdim 92263509Sdim if (!*T) { 93263509Sdim if (ErrorMessage) 94263509Sdim *ErrorMessage = strdup(Error.c_str()); 95263509Sdim 96263509Sdim return 1; 97263509Sdim } 98263509Sdim 99263509Sdim return 0; 100263509Sdim} 101263509Sdim 102234285Sdimconst char * LLVMGetTargetName(LLVMTargetRef T) { 103234285Sdim return unwrap(T)->getName(); 104234285Sdim} 105234285Sdim 106234285Sdimconst char * LLVMGetTargetDescription(LLVMTargetRef T) { 107234285Sdim return unwrap(T)->getShortDescription(); 108234285Sdim} 109234285Sdim 110234285SdimLLVMBool LLVMTargetHasJIT(LLVMTargetRef T) { 111234285Sdim return unwrap(T)->hasJIT(); 112234285Sdim} 113234285Sdim 114234285SdimLLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) { 115234285Sdim return unwrap(T)->hasTargetMachine(); 116234285Sdim} 117234285Sdim 118234285SdimLLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) { 119234285Sdim return unwrap(T)->hasMCAsmBackend(); 120234285Sdim} 121234285Sdim 122263509SdimLLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, 123263509Sdim const char* Triple, const char* CPU, const char* Features, 124263509Sdim LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, 125263509Sdim LLVMCodeModel CodeModel) { 126234285Sdim Reloc::Model RM; 127234285Sdim switch (Reloc){ 128234285Sdim case LLVMRelocStatic: 129234285Sdim RM = Reloc::Static; 130234285Sdim break; 131234285Sdim case LLVMRelocPIC: 132234285Sdim RM = Reloc::PIC_; 133234285Sdim break; 134234285Sdim case LLVMRelocDynamicNoPic: 135234285Sdim RM = Reloc::DynamicNoPIC; 136234285Sdim break; 137234285Sdim default: 138234285Sdim RM = Reloc::Default; 139234285Sdim break; 140234285Sdim } 141234285Sdim 142252723Sdim CodeModel::Model CM = unwrap(CodeModel); 143252723Sdim 144234285Sdim CodeGenOpt::Level OL; 145234285Sdim switch (Level) { 146234285Sdim case LLVMCodeGenLevelNone: 147234285Sdim OL = CodeGenOpt::None; 148234285Sdim break; 149234285Sdim case LLVMCodeGenLevelLess: 150234285Sdim OL = CodeGenOpt::Less; 151234285Sdim break; 152234285Sdim case LLVMCodeGenLevelAggressive: 153234285Sdim OL = CodeGenOpt::Aggressive; 154234285Sdim break; 155234285Sdim default: 156234285Sdim OL = CodeGenOpt::Default; 157234285Sdim break; 158234285Sdim } 159234285Sdim 160234285Sdim TargetOptions opt; 161234285Sdim return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM, 162234285Sdim CM, OL)); 163234285Sdim} 164234285Sdim 165234285Sdim 166234285Sdimvoid LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { 167234285Sdim delete unwrap(T); 168234285Sdim} 169234285Sdim 170234285SdimLLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) { 171234285Sdim const Target* target = &(unwrap(T)->getTarget()); 172234285Sdim return wrap(target); 173234285Sdim} 174234285Sdim 175234285Sdimchar* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) { 176234285Sdim std::string StringRep = unwrap(T)->getTargetTriple(); 177234285Sdim return strdup(StringRep.c_str()); 178234285Sdim} 179234285Sdim 180234285Sdimchar* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) { 181234285Sdim std::string StringRep = unwrap(T)->getTargetCPU(); 182234285Sdim return strdup(StringRep.c_str()); 183234285Sdim} 184234285Sdim 185234285Sdimchar* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) { 186234285Sdim std::string StringRep = unwrap(T)->getTargetFeatureString(); 187234285Sdim return strdup(StringRep.c_str()); 188234285Sdim} 189234285Sdim 190234285SdimLLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) { 191245431Sdim return wrap(unwrap(T)->getDataLayout()); 192234285Sdim} 193234285Sdim 194263509Sdimvoid LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T, 195263509Sdim LLVMBool VerboseAsm) { 196263509Sdim unwrap(T)->setAsmVerbosityDefault(VerboseAsm); 197263509Sdim} 198263509Sdim 199252723Sdimstatic LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M, 200252723Sdim formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) { 201234285Sdim TargetMachine* TM = unwrap(T); 202234285Sdim Module* Mod = unwrap(M); 203234285Sdim 204234285Sdim PassManager pass; 205234285Sdim 206234285Sdim std::string error; 207234285Sdim 208245431Sdim const DataLayout* td = TM->getDataLayout(); 209234285Sdim 210234285Sdim if (!td) { 211245431Sdim error = "No DataLayout in TargetMachine"; 212234285Sdim *ErrorMessage = strdup(error.c_str()); 213234285Sdim return true; 214234285Sdim } 215245431Sdim pass.add(new DataLayout(*td)); 216234285Sdim 217234285Sdim TargetMachine::CodeGenFileType ft; 218234285Sdim switch (codegen) { 219234285Sdim case LLVMAssemblyFile: 220234285Sdim ft = TargetMachine::CGFT_AssemblyFile; 221234285Sdim break; 222234285Sdim default: 223234285Sdim ft = TargetMachine::CGFT_ObjectFile; 224234285Sdim break; 225234285Sdim } 226252723Sdim if (TM->addPassesToEmitFile(pass, OS, ft)) { 227252723Sdim error = "TargetMachine can't emit a file of this type"; 228234285Sdim *ErrorMessage = strdup(error.c_str()); 229234285Sdim return true; 230234285Sdim } 231234285Sdim 232252723Sdim pass.run(*Mod); 233252723Sdim 234252723Sdim OS.flush(); 235252723Sdim return false; 236252723Sdim} 237252723Sdim 238252723SdimLLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, 239252723Sdim char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) { 240252723Sdim std::string error; 241263509Sdim raw_fd_ostream dest(Filename, error, sys::fs::F_Binary); 242252723Sdim if (!error.empty()) { 243234285Sdim *ErrorMessage = strdup(error.c_str()); 244234285Sdim return true; 245234285Sdim } 246263509Sdim formatted_raw_ostream destf(dest); 247252723Sdim bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage); 248252723Sdim dest.flush(); 249252723Sdim return Result; 250252723Sdim} 251234285Sdim 252252723SdimLLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, 253252723Sdim LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage, 254252723Sdim LLVMMemoryBufferRef *OutMemBuf) { 255252723Sdim std::string CodeString; 256252723Sdim raw_string_ostream OStream(CodeString); 257252723Sdim formatted_raw_ostream Out(OStream); 258252723Sdim bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage); 259252723Sdim OStream.flush(); 260234285Sdim 261252723Sdim std::string &Data = OStream.str(); 262252723Sdim *OutMemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.c_str(), 263252723Sdim Data.length(), ""); 264252723Sdim return Result; 265234285Sdim} 266263509Sdim 267263509Sdimchar *LLVMGetDefaultTargetTriple(void) { 268263509Sdim return strdup(sys::getDefaultTargetTriple().c_str()); 269263509Sdim} 270