Home | History | Annotate | Download | only in Target
      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/Target/TargetMachine.h"
     25 #include <cassert>
     26 #include <cstdlib>
     27 #include <cstring>
     28 
     29 using namespace llvm;
     30 
     31 
     32 
     33 LLVMTargetRef LLVMGetFirstTarget() {
     34    const Target* target = &*TargetRegistry::begin();
     35    return wrap(target);
     36 }
     37 LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
     38   return wrap(unwrap(T)->getNext());
     39 }
     40 
     41 const char * LLVMGetTargetName(LLVMTargetRef T) {
     42   return unwrap(T)->getName();
     43 }
     44 
     45 const char * LLVMGetTargetDescription(LLVMTargetRef T) {
     46   return unwrap(T)->getShortDescription();
     47 }
     48 
     49 LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
     50   return unwrap(T)->hasJIT();
     51 }
     52 
     53 LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
     54   return unwrap(T)->hasTargetMachine();
     55 }
     56 
     57 LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
     58   return unwrap(T)->hasMCAsmBackend();
     59 }
     60 
     61 LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, char* Triple,
     62   char* CPU, char* Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
     63   LLVMCodeModel CodeModel) {
     64   Reloc::Model RM;
     65   switch (Reloc){
     66     case LLVMRelocStatic:
     67       RM = Reloc::Static;
     68       break;
     69     case LLVMRelocPIC:
     70       RM = Reloc::PIC_;
     71       break;
     72     case LLVMRelocDynamicNoPic:
     73       RM = Reloc::DynamicNoPIC;
     74       break;
     75     default:
     76       RM = Reloc::Default;
     77       break;
     78   }
     79 
     80   CodeModel::Model CM;
     81   switch (CodeModel) {
     82     case LLVMCodeModelJITDefault:
     83       CM = CodeModel::JITDefault;
     84       break;
     85     case LLVMCodeModelSmall:
     86       CM = CodeModel::Small;
     87       break;
     88     case LLVMCodeModelKernel:
     89       CM = CodeModel::Kernel;
     90       break;
     91     case LLVMCodeModelMedium:
     92       CM = CodeModel::Medium;
     93       break;
     94     case LLVMCodeModelLarge:
     95       CM = CodeModel::Large;
     96       break;
     97     default:
     98       CM = CodeModel::Default;
     99       break;
    100   }
    101   CodeGenOpt::Level OL;
    102 
    103   switch (Level) {
    104     case LLVMCodeGenLevelNone:
    105       OL = CodeGenOpt::None;
    106       break;
    107     case LLVMCodeGenLevelLess:
    108       OL = CodeGenOpt::Less;
    109       break;
    110     case LLVMCodeGenLevelAggressive:
    111       OL = CodeGenOpt::Aggressive;
    112       break;
    113     default:
    114       OL = CodeGenOpt::Default;
    115       break;
    116   }
    117 
    118   TargetOptions opt;
    119   return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM,
    120     CM, OL));
    121 }
    122 
    123 
    124 void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) {
    125   delete unwrap(T);
    126 }
    127 
    128 LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
    129   const Target* target = &(unwrap(T)->getTarget());
    130   return wrap(target);
    131 }
    132 
    133 char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
    134   std::string StringRep = unwrap(T)->getTargetTriple();
    135   return strdup(StringRep.c_str());
    136 }
    137 
    138 char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
    139   std::string StringRep = unwrap(T)->getTargetCPU();
    140   return strdup(StringRep.c_str());
    141 }
    142 
    143 char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
    144   std::string StringRep = unwrap(T)->getTargetFeatureString();
    145   return strdup(StringRep.c_str());
    146 }
    147 
    148 LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) {
    149   return wrap(unwrap(T)->getDataLayout());
    150 }
    151 
    152 LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
    153   char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) {
    154   TargetMachine* TM = unwrap(T);
    155   Module* Mod = unwrap(M);
    156 
    157   PassManager pass;
    158 
    159   std::string error;
    160 
    161   const DataLayout* td = TM->getDataLayout();
    162 
    163   if (!td) {
    164     error = "No DataLayout in TargetMachine";
    165     *ErrorMessage = strdup(error.c_str());
    166     return true;
    167   }
    168   pass.add(new DataLayout(*td));
    169 
    170   TargetMachine::CodeGenFileType ft;
    171   switch (codegen) {
    172     case LLVMAssemblyFile:
    173       ft = TargetMachine::CGFT_AssemblyFile;
    174       break;
    175     default:
    176       ft = TargetMachine::CGFT_ObjectFile;
    177       break;
    178   }
    179   raw_fd_ostream dest(Filename, error, raw_fd_ostream::F_Binary);
    180   formatted_raw_ostream destf(dest);
    181   if (!error.empty()) {
    182     *ErrorMessage = strdup(error.c_str());
    183     return true;
    184   }
    185 
    186   if (TM->addPassesToEmitFile(pass, destf, ft)) {
    187     error = "TargetMachine can't emit a file of this type";
    188     *ErrorMessage = strdup(error.c_str());
    189     return true;
    190   }
    191 
    192   pass.run(*Mod);
    193 
    194   destf.flush();
    195   dest.flush();
    196   return false;
    197 }
    198