mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-24 13:18:17 +00:00
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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user