mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +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:
parent
d6fc26217e
commit
d6b7b8f49b
142
include/llvm-c/TargetMachine.h
Normal file
142
include/llvm-c/TargetMachine.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*===-- llvm-c/TargetMachine.h - Target Machine Library C Interface - C++ -*-=*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header declares the C interface to the Target and TargetMachine *|
|
||||
|* classes, which can be used to generate assembly or object files. *|
|
||||
|* *|
|
||||
|* Many exotic languages can interoperate with C code but have a harder time *|
|
||||
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|
||||
|* tools written in such languages. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_C_TARGETMACHINE_H
|
||||
#define LLVM_C_TARGETMACHINE_H
|
||||
|
||||
#include "llvm-c/Core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef struct LLVMTargetMachine *LLVMTargetMachineRef;
|
||||
typedef struct LLVMTarget *LLVMTargetRef;
|
||||
|
||||
typedef enum {
|
||||
LLVMCodeGenLevelNone,
|
||||
LLVMCodeGenLevelLess,
|
||||
LLVMCodeGenLevelDefault,
|
||||
LLVMCodeGenLevelAggressive
|
||||
} LLVMCodeGenOptLevel;
|
||||
|
||||
typedef enum {
|
||||
LLVMRelocDefault,
|
||||
LLVMRelocStatic,
|
||||
LLVMRelocPIC,
|
||||
LLVMRelocDynamicNoPic
|
||||
} LLVMRelocMode;
|
||||
|
||||
typedef enum {
|
||||
LLVMCodeModelDefault,
|
||||
LLVMCodeModelJITDefault,
|
||||
LLVMCodeModelSmall,
|
||||
LLVMCodeModelKernel,
|
||||
LLVMCodeModelMedium,
|
||||
LLVMCodeModelLarge
|
||||
} LLVMCodeModel;
|
||||
|
||||
typedef enum {
|
||||
LLVMAssemblyFile,
|
||||
LLVMObjectFile
|
||||
} LLVMCodeGenFileType;
|
||||
|
||||
/** Returns the first llvm::Target in the registered targets list. */
|
||||
LLVMTargetRef LLVMGetFirstTarget();
|
||||
/** Returns the next llvm::Target given a previous one (or null if there's none) */
|
||||
LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T);
|
||||
|
||||
/*===-- Target ------------------------------------------------------------===*/
|
||||
/** Returns the name of a target. See llvm::Target::getName */
|
||||
const char *LLVMGetTargetName(LLVMTargetRef T);
|
||||
|
||||
/** Returns the description of a target. See llvm::Target::getDescription */
|
||||
const char *LLVMGetTargetDescription(LLVMTargetRef T);
|
||||
|
||||
/** Returns if the target has a JIT */
|
||||
LLVMBool LLVMTargetHasJIT(LLVMTargetRef T);
|
||||
|
||||
/** Returns if the target has a TargetMachine associated */
|
||||
LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T);
|
||||
|
||||
/** Returns if the target as an ASM backend (required for emitting output) */
|
||||
LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T);
|
||||
|
||||
/*===-- Target Machine ----------------------------------------------------===*/
|
||||
/** Creates a new llvm::TargetMachine. See llvm::Target::createTargetMachine */
|
||||
LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, char *Triple,
|
||||
char *CPU, char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
|
||||
LLVMCodeModel CodeModel);
|
||||
|
||||
/** Dispose the LLVMTargetMachineRef instance generated by
|
||||
LLVMCreateTargetMachine. */
|
||||
void LLVMDisposeTargetMachine(LLVMTargetMachineRef T);
|
||||
|
||||
/** Returns the Target used in a TargetMachine */
|
||||
LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T);
|
||||
|
||||
/** Returns the triple used creating this target machine. See
|
||||
llvm::TargetMachine::getTriple. The result needs to be disposed with
|
||||
LLVMDisposeMessage. */
|
||||
char *LLVMGetTargetMachineTriple(LLVMTargetMachineRef T);
|
||||
|
||||
/** Returns the cpu used creating this target machine. See
|
||||
llvm::TargetMachine::getCPU. The result needs to be disposed with
|
||||
LLVMDisposeMessage. */
|
||||
char *LLVMGetTargetMachineCPU(LLVMTargetMachineRef T);
|
||||
|
||||
/** Returns the feature string used creating this target machine. See
|
||||
llvm::TargetMachine::getFeatureString. The result needs to be disposed with
|
||||
LLVMDisposeMessage. */
|
||||
char *LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T);
|
||||
|
||||
/** Returns the llvm::TargetData used for this llvm:TargetMachine. */
|
||||
LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T);
|
||||
|
||||
/** Emits an asm or object file for the given module to the filename. This
|
||||
wraps several c++ only classes (among them a file stream). Returns any
|
||||
error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */
|
||||
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
|
||||
char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage);
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
class TargetMachine;
|
||||
class Target;
|
||||
|
||||
inline TargetMachine *unwrap(LLVMTargetMachineRef P) {
|
||||
return reinterpret_cast<TargetMachine*>(P);
|
||||
}
|
||||
inline Target *unwrap(LLVMTargetRef P) {
|
||||
return reinterpret_cast<Target*>(P);
|
||||
}
|
||||
inline LLVMTargetMachineRef wrap(const TargetMachine *P) {
|
||||
return reinterpret_cast<LLVMTargetMachineRef>(
|
||||
const_cast<TargetMachine*>(P));
|
||||
}
|
||||
inline LLVMTargetRef wrap(const Target * P) {
|
||||
return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -9,6 +9,7 @@ add_llvm_library(LLVMTarget
|
||||
TargetLibraryInfo.cpp
|
||||
TargetLoweringObjectFile.cpp
|
||||
TargetMachine.cpp
|
||||
TargetMachineC.cpp
|
||||
TargetRegisterInfo.cpp
|
||||
TargetSubtargetInfo.cpp
|
||||
)
|
||||
|
197
lib/Target/TargetMachineC.cpp
Normal file
197
lib/Target/TargetMachineC.cpp
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user