diff --git a/llvm/_core.cpp b/llvm/_core.cpp index 3366d58..9fc776c 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -993,6 +993,43 @@ _wrap_pass( UnifyFunctionExitNodes ) _wrap_pass( Internalize2 ) */ + + +/*===----------------------------------------------------------------------===*/ +/* Target Machine */ +/*===----------------------------------------------------------------------===*/ + +_wrap_obj2obj(LLVMTargetMachineFromEngineBuilder, LLVMEngineBuilderRef, + LLVMTargetMachineRef) +_wrap_obj2none(LLVMDisposeTargetMachine, LLVMTargetMachineRef) + + +static PyObject * +_wLLVMTargetMachineEmitFile(PyObject * self, PyObject * args) +{ + PyObject * ret; + unsigned len; + unsigned char * bytes; + LLVMTargetMachineRef tm; + LLVMModuleRef m; + + PyObject *arg_tm, *arg_m; + int arg_use_asm; + + if (!PyArg_ParseTuple(args, "OOi", &arg_tm, &arg_m, &arg_use_asm)) + return NULL; + + tm = (LLVMTargetMachineRef) PyCapsule_GetPointer(arg_tm, NULL); + m = (LLVMModuleRef) PyCapsule_GetPointer(arg_m, NULL); + + if ( !(bytes = LLVMTargetMachineEmitFile(tm, m, arg_use_asm, &len)) ) + Py_RETURN_NONE; + + ret = PyBytes_FromStringAndSize((char *)bytes, (Py_ssize_t)len); + delete [] bytes; + return ret; +} + /*===----------------------------------------------------------------------===*/ /* Target Data */ /*===----------------------------------------------------------------------===*/ @@ -1835,6 +1872,11 @@ static PyMethodDef core_methods[] = { _pass( Internalize2 ) */ + /* Target Machine */ + _method( LLVMTargetMachineFromEngineBuilder ) + _method( LLVMDisposeTargetMachine ) + _method( LLVMTargetMachineEmitFile ) + /* Target Data */ _method( LLVMCreateTargetData ) _method( LLVMDisposeTargetData ) diff --git a/llvm/ee.py b/llvm/ee.py index 904716e..384c220 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -293,3 +293,31 @@ class ExecutionEngine(object): td._own(self) return td + +#===----------------------------------------------------------------------=== +# Target machine +#===----------------------------------------------------------------------=== + +class TargetMachine(object): + @staticmethod + def from_engine_builder(eb): + '''Construct a TargetMachine from an EngineBuilder + ''' + ptr = _core.LLVMTargetMachineFromEngineBuilder(eb.ptr) + return TargetMachine(ptr) + + def __init__(self, ptr): + self.ptr = ptr + + def __del__(self): + _core.LLVMDisposeTargetMachine(self.ptr) + + def emit_assembly(self, module): + '''returns byte string of the module as assembly code of the target machine + ''' + return _core.LLVMTargetMachineEmitFile(self.ptr, module.ptr, True) + + def emit_object(self, module): + '''returns byte string of the module as assembly code of the target machine + ''' + return _core.LLVMTargetMachineEmitFile(self.ptr, module.ptr, False) diff --git a/llvm/extra.cpp b/llvm/extra.cpp index 5d22200..b11dd1e 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -84,6 +84,7 @@ namespace llvm{ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(EngineBuilder, LLVMEngineBuilderRef) +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) } /* * For use in LLVMDumpPasses to dump passes. @@ -113,15 +114,29 @@ char *do_print(W obj) return strdup(buf.str().c_str()); } -unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, - unsigned * lenp) + +LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb) +{ + using namespace llvm; + TargetMachine * tm = unwrap(eb)->selectTarget(); + return wrap(tm); +} + +void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm){ + delete llvm::unwrap(tm); +} + + +unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, + LLVMModuleRef modref, + int assembly, unsigned * lenp) { using namespace llvm; assert(lenp); InitializeNativeTargetAsmPrinter(); - Module *modulep = unwrap(module); + Module *modulep = unwrap(modref); assert(modulep); // get objectcode into a string @@ -130,17 +145,15 @@ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, formatted_raw_ostream fso(buf); - TargetMachine * tm = EngineBuilder(modulep).selectTarget(); + TargetMachine * tm = unwrap(tmref); PassManager pm; if (!tm->getTargetData()){ - printf("No target data in target machine"); + fprintf(stderr, "No target data in target machine"); return NULL; } - //printf("%s\n", modulep->getDataLayout().c_str()); - pm.add(new TargetData(*tm->getTargetData())); bool failed; @@ -151,8 +164,8 @@ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, } if ( failed ) { - printf("No support\n"); - printf("%s\n", tm->getTargetData()->getStringRepresentation().c_str()); + fprintf(stderr, "No support\n"); + fprintf(stderr, "%s\n", tm->getTargetData()->getStringRepresentation().c_str()); return NULL; } @@ -177,6 +190,21 @@ unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, return bytes; } +unsigned char* LLVMGetNativeCodeFromModule(LLVMModuleRef module, int assembly, + unsigned * lenp) +{ + using namespace llvm; + assert(lenp); + + Module *modulep = unwrap(module); + assert(modulep); + + // select native default machine + TargetMachine * tm = EngineBuilder(modulep).selectTarget(); + + return LLVMTargetMachineEmitFile(wrap(tm), module, assembly, lenp); +} + static llvm::AtomicOrdering atomic_ordering_from_string(const char * ordering) diff --git a/llvm/extra.h b/llvm/extra.h index f405679..f3f5bda 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -45,6 +45,20 @@ extern "C" { #endif +/* + * Wraps EngineBuilder::selectTarget + */ +LLVMTargetMachineRef LLVMTargetMachineFromEngineBuilder(LLVMEngineBuilderRef eb); + +/* + * Wraps operator delete + */ +void LLVMDisposeTargetMachine(LLVMTargetMachineRef tm); + +unsigned char* LLVMTargetMachineEmitFile(LLVMTargetMachineRef tmref, + LLVMModuleRef modref, + int assembly, unsigned * lenp); + /* * Wraps TargetMachine::addPassesToEmitFile */ diff --git a/llvm/llvm_c_extra.h b/llvm/llvm_c_extra.h index fc2b711..53fe71c 100644 --- a/llvm/llvm_c_extra.h +++ b/llvm/llvm_c_extra.h @@ -19,6 +19,7 @@ inline ref wrap(const ty *P) { \ } typedef struct LLVMOpaqueEngineBuilder *LLVMEngineBuilderRef; +typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef; #ifdef __cplusplus diff --git a/llvm/wrap.cpp b/llvm/wrap.cpp index 4527912..6ccd443 100644 --- a/llvm/wrap.cpp +++ b/llvm/wrap.cpp @@ -60,6 +60,7 @@ _define_std_ctor(LLVMGenericValueRef) _define_std_ctor(LLVMPassManagerBuilderRef) _define_std_ctor(LLVMEngineBuilderRef) +_define_std_ctor(LLVMTargetMachineRef) PyObject *ctor_int(int i) { diff --git a/llvm/wrap.h b/llvm/wrap.h index bceca87..4a4dd53 100644 --- a/llvm/wrap.h +++ b/llvm/wrap.h @@ -93,6 +93,7 @@ _declare_std_ctor(LLVMGenericValueRef) // extra LLVM classes _declare_std_ctor(LLVMPassManagerBuilderRef) _declare_std_ctor(LLVMEngineBuilderRef) +_declare_std_ctor(LLVMTargetMachineRef) /* standard types */ _declare_std_ctor(int)