rendered paste body#ifdef __cplusplus
extern "C" {
#endif
#include "vm_local.h"
#ifdef __cplusplus
}
#endif
#include "vm_llvm.h"
#define INT64_C(C) ((int64_t) C ## LL)
#define UINT64_C(C) ((uint64_t) C ## ULL)
#define __STDC_CONSTANT_MACROS
#define __STDC_LIMIT_MACROS
#include <llvm/Module.h>
#include <llvm/LLVMContext.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/PassManager.h>
#include <llvm/Target/TargetSelect.h>
#include <llvm/Target/TargetData.h>
#include <llvm/Transforms/IPO.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/JIT.h>
using namespace llvm;
#ifdef __cplusplus
extern "C" {
#endif
static ExecutionEngine *engine = NULL;
void *VM_LoadLLVM( vm_t *vm, intptr_t (*systemcalls)(intptr_t, ...) ) {
char name[MAX_QPATH];
char filename[MAX_QPATH];
int len;
char *bytes;
std::string error;
COM_StripExtension( vm->name, name, sizeof(name) );
Com_sprintf( filename, sizeof(filename), "%sllvm.bc", name );
len = FS_ReadFile( filename, (void **)&bytes );
if ( !bytes ) {
Com_Printf( "Couldn't load llvm file: %s\n", filename );
return NULL;
}
StringRef strref = StringRef(bytes, len);
MemoryBuffer *buffer = MemoryBuffer::getMemBuffer( strref );
Module *module = ParseBitcodeFile( buffer, getGlobalContext(), &error );
delete buffer;
FS_FreeFile( bytes );
if ( !module ) {
Com_Printf( "Couldn't parse llvm file: %s: %s\n", filename, error.c_str() );
return NULL;
}
PassManager p;
p.add( new TargetData( module ) );
p.add( createFunctionInliningPass() );
p.run( *module );
if ( !engine ) {
InitializeNativeTarget();
std::string str;
engine = ExecutionEngine::create( module, false, &str );
if ( !engine ) {
Com_Printf("Couldn't create ExecutionEngine: %s\n", str.c_str());
return NULL;
}
} else {
Com_Printf("Engine was non-null\n");
engine->addModule( module );
}
Function *dllEntry_ptr = module->getFunction( std::string("dllEntry") );
if ( !dllEntry_ptr ) {
Com_Printf("Couldn't get function address of dllEntry\n");
return NULL;
}
void (*dllEntry)( intptr_t (*syscallptr)(intptr_t, ...) ) = (void (*)(intptr_t (*syscallptr)(intptr_t, ...)))engine->getPointerToFunction( dllEntry_ptr );
dllEntry( systemcalls );
Com_Printf("1: got here\n");
Function *vmMain_ptr = module->getFunction( std::string("vmMain") );
Com_Printf("2: got here\n");
if ( !vmMain_ptr ) {
Com_Printf("Couldn't get function address of vmMain\n");
return NULL;
}
Com_Printf("3: got here\n");
intptr_t(*fp)(int, ...) = (intptr_t(*)(int, ...))engine->getPointerToFunction( vmMain_ptr );
Com_Printf("4: got here\n");
vm->entryPoint = fp;
if ( com_developer->integer ) {
Com_Printf("Loaded LLVM %s with module==%p\n", name, module);
}
return module;
}
void VM_UnloadLLVM( void *llvmModule ) {
if ( !llvmModule ) {
Com_Printf( "VM_UnloadLLVM called with NULL pointer\n" );
return;
}
if ( com_developer->integer ) {
Com_Printf( "Unloading LLVM with module==%p\n", llvmModule );
}
if ( !engine->removeModule( (Module *)llvmModule ) ) {
Com_Printf( "Couldn't remove llvm\n" );
return;
}
delete (Module *)llvmModule;
}
#ifdef __cplusplus
}
#endif