diff options
author | Duncan Sands <baldrick@free.fr> | 2012-04-11 10:25:24 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2012-04-11 10:25:24 +0000 |
commit | d6b7b8f49b0554b82165ecef07de7e9c0c5eeb42 (patch) | |
tree | 903a38f0719838f16e7d408def178543abb06d12 /lib/Target | |
parent | d6fc26217e194372cabe4ef9e2514beac511a943 (diff) |
Add a C binding to the Target and TargetMachine classes to allow for emitting
binary and assembly. Patch by Carlo Kok. Emitting was inspired by but not based
on the D llvm bindings.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154493 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Target/TargetMachineC.cpp | 197 |
2 files changed, 198 insertions, 0 deletions
diff --git a/lib/Target/CMakeLists.txt b/lib/Target/CMakeLists.txt index d8bc7439f6..5913a9c4cc 100644 --- a/lib/Target/CMakeLists.txt +++ b/lib/Target/CMakeLists.txt @@ -9,6 +9,7 @@ add_llvm_library(LLVMTarget TargetLibraryInfo.cpp TargetLoweringObjectFile.cpp TargetMachine.cpp + TargetMachineC.cpp TargetRegisterInfo.cpp TargetSubtargetInfo.cpp ) diff --git a/lib/Target/TargetMachineC.cpp b/lib/Target/TargetMachineC.cpp new file mode 100644 index 0000000000..d6bba8b0dd --- /dev/null +++ b/lib/Target/TargetMachineC.cpp @@ -0,0 +1,197 @@ +//===-- TargetMachine.cpp -------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the LLVM-C part of TargetMachine.h +// +//===----------------------------------------------------------------------===// + +#include "llvm-c/Core.h" +#include "llvm-c/Target.h" +#include "llvm-c/TargetMachine.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/CodeGen.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Module.h" +#include "llvm/PassManager.h" +#include <cassert> +#include <cstdlib> +#include <cstring> + +using namespace llvm; + + + +LLVMTargetRef LLVMGetFirstTarget() { + const Target* target = &*TargetRegistry::begin(); + return wrap(target); +} +LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) { + return wrap(unwrap(T)->getNext()); +} + +const char * LLVMGetTargetName(LLVMTargetRef T) { + return unwrap(T)->getName(); +} + +const char * LLVMGetTargetDescription(LLVMTargetRef T) { + return unwrap(T)->getShortDescription(); +} + +LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) { + return unwrap(T)->hasJIT(); +} + +LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) { + return unwrap(T)->hasTargetMachine(); +} + +LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) { + return unwrap(T)->hasMCAsmBackend(); +} + +LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, char* Triple, + char* CPU, char* Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, + LLVMCodeModel CodeModel) { + Reloc::Model RM; + switch (Reloc){ + case LLVMRelocStatic: + RM = Reloc::Static; + break; + case LLVMRelocPIC: + RM = Reloc::PIC_; + break; + case LLVMRelocDynamicNoPic: + RM = Reloc::DynamicNoPIC; + break; + default: + RM = Reloc::Default; + break; + } + + CodeModel::Model CM; + switch (CodeModel) { + case LLVMCodeModelJITDefault: + CM = CodeModel::JITDefault; + break; + case LLVMCodeModelSmall: + CM = CodeModel::Small; + break; + case LLVMCodeModelKernel: + CM = CodeModel::Kernel; + break; + case LLVMCodeModelMedium: + CM = CodeModel::Medium; + break; + case LLVMCodeModelLarge: + CM = CodeModel::Large; + break; + default: + CM = CodeModel::Default; + break; + } + CodeGenOpt::Level OL; + + switch (Level) { + case LLVMCodeGenLevelNone: + OL = CodeGenOpt::None; + break; + case LLVMCodeGenLevelLess: + OL = CodeGenOpt::Less; + break; + case LLVMCodeGenLevelAggressive: + OL = CodeGenOpt::Aggressive; + break; + default: + OL = CodeGenOpt::Default; + break; + } + + TargetOptions opt; + return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM, + CM, OL)); +} + + +void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { + delete unwrap(T); +} + +LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) { + const Target* target = &(unwrap(T)->getTarget()); + return wrap(target); +} + +char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) { + std::string StringRep = unwrap(T)->getTargetTriple(); + return strdup(StringRep.c_str()); +} + +char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) { + std::string StringRep = unwrap(T)->getTargetCPU(); + return strdup(StringRep.c_str()); +} + +char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) { + std::string StringRep = unwrap(T)->getTargetFeatureString(); + return strdup(StringRep.c_str()); +} + +LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) { + return wrap(unwrap(T)->getTargetData()); +} + +LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, + char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) { + TargetMachine* TM = unwrap(T); + Module* Mod = unwrap(M); + + PassManager pass; + + std::string error; + + const TargetData* td = TM->getTargetData(); + + if (!td) { + error = "No TargetData in TargetMachine"; + *ErrorMessage = strdup(error.c_str()); + return true; + } + pass.add(new TargetData(*td)); + + TargetMachine::CodeGenFileType ft; + switch (codegen) { + case LLVMAssemblyFile: + ft = TargetMachine::CGFT_AssemblyFile; + break; + default: + ft = TargetMachine::CGFT_ObjectFile; + break; + } + raw_fd_ostream dest(Filename, error, raw_fd_ostream::F_Binary); + formatted_raw_ostream destf(dest); + if (!error.empty()) { + *ErrorMessage = strdup(error.c_str()); + return true; + } + + if (TM->addPassesToEmitFile(pass, destf, ft)) { + error = "No TargetData in TargetMachine"; + *ErrorMessage = strdup(error.c_str()); + return true; + } + + pass.run(*Mod); + + destf.flush(); + dest.flush(); + return false; +} |