Kernel call thunks and cleanup on exports.

This commit is contained in:
Ben Vanik 2013-05-22 11:30:53 -07:00
parent 37f93d2974
commit 33e2bc01ee
5 changed files with 73 additions and 111 deletions

View File

@ -25,23 +25,20 @@ namespace {
void _cdecl XeTrap( void _cdecl XeTrap(
xe_ppc_state_t* state, uint64_t cia, uint64_t unused1, xe_ppc_state_t* state, uint64_t cia) {
void* unused2) {
XELOGE("TRAP"); XELOGE("TRAP");
XEASSERTALWAYS(); XEASSERTALWAYS();
} }
void _cdecl XeIndirectBranch( void _cdecl XeIndirectBranch(
xe_ppc_state_t* state, uint64_t target, uint64_t br_ia, xe_ppc_state_t* state, uint64_t target, uint64_t br_ia) {
void* unused) {
XELOGCPU("INDIRECT BRANCH %.8X -> %.8X", XELOGCPU("INDIRECT BRANCH %.8X -> %.8X",
(uint32_t)br_ia, (uint32_t)target); (uint32_t)br_ia, (uint32_t)target);
XEASSERTALWAYS(); XEASSERTALWAYS();
} }
void _cdecl XeInvalidInstruction( void _cdecl XeInvalidInstruction(
xe_ppc_state_t* state, uint64_t cia, uint64_t data, xe_ppc_state_t* state, uint64_t cia, uint64_t data) {
void* unused) {
ppc::InstrData i; ppc::InstrData i;
i.address = (uint32_t)cia; i.address = (uint32_t)cia;
i.code = (uint32_t)data; i.code = (uint32_t)data;
@ -64,8 +61,7 @@ void _cdecl XeInvalidInstruction(
} }
void _cdecl XeAccessViolation( void _cdecl XeAccessViolation(
xe_ppc_state_t* state, uint64_t cia, uint64_t ea, xe_ppc_state_t* state, uint64_t cia, uint64_t ea) {
void* unused) {
XELOGE("INVALID ACCESS %.8X: tried to touch %.8X", XELOGE("INVALID ACCESS %.8X: tried to touch %.8X",
cia, (uint32_t)ea); cia, (uint32_t)ea);
XEASSERTALWAYS(); XEASSERTALWAYS();
@ -87,8 +83,7 @@ void _cdecl XeTraceUserCall(
} }
void _cdecl XeTraceInstruction( void _cdecl XeTraceInstruction(
xe_ppc_state_t* state, uint64_t cia, uint64_t data, xe_ppc_state_t* state, uint64_t cia, uint64_t data) {
void* unused) {
ppc::InstrType* type = ppc::GetInstrType((uint32_t)data); ppc::InstrType* type = ppc::GetInstrType((uint32_t)data);
XELOGCPU("TRACE: %.8X %.8X %s %s", XELOGCPU("TRACE: %.8X %.8X %s %s",
cia, data, cia, data,

View File

@ -24,13 +24,13 @@ namespace cpu {
typedef struct { typedef struct {
void (_cdecl *XeTrap)( void (_cdecl *XeTrap)(
xe_ppc_state_t* state, uint64_t cia, uint64_t unused1, void* unused2); xe_ppc_state_t* state, uint64_t cia);
void (_cdecl *XeIndirectBranch)( void (_cdecl *XeIndirectBranch)(
xe_ppc_state_t* state, uint64_t target, uint64_t br_ia, void* unused); xe_ppc_state_t* state, uint64_t target, uint64_t br_ia);
void (_cdecl *XeInvalidInstruction)( void (_cdecl *XeInvalidInstruction)(
xe_ppc_state_t* state, uint64_t cia, uint64_t data, void* unused); xe_ppc_state_t* state, uint64_t cia, uint64_t data);
void (_cdecl *XeAccessViolation)( void (_cdecl *XeAccessViolation)(
xe_ppc_state_t* state, uint64_t cia, uint64_t ea, void* unused); xe_ppc_state_t* state, uint64_t cia, uint64_t ea);
void (_cdecl *XeTraceKernelCall)( void (_cdecl *XeTraceKernelCall)(
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia, xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
kernel::KernelExport* kernel_export); kernel::KernelExport* kernel_export);
@ -38,7 +38,7 @@ typedef struct {
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia, xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
sdb::FunctionSymbol* fn); sdb::FunctionSymbol* fn);
void (_cdecl *XeTraceInstruction)( void (_cdecl *XeTraceInstruction)(
xe_ppc_state_t* state, uint64_t cia, uint64_t data, void* unused); xe_ppc_state_t* state, uint64_t cia, uint64_t data);
} GlobalExports; } GlobalExports;

View File

@ -63,22 +63,54 @@ LibjitEmitter::LibjitEmitter(xe_memory_ref memory, jit_context_t context) {
fn_params, XECOUNT(fn_params), fn_params, XECOUNT(fn_params),
0); 0);
jit_type_t global_export_params[] = { jit_type_t shim_params[] = {
jit_type_void_ptr,
jit_type_void_ptr,
};
shim_signature_ = jit_type_create_signature(
jit_abi_cdecl,
jit_type_void,
shim_params, XECOUNT(shim_params),
0);
jit_type_t global_export_params_2[] = {
jit_type_void_ptr,
jit_type_ulong,
};
global_export_signature_2_ = jit_type_create_signature(
jit_abi_cdecl,
jit_type_void,
global_export_params_2, XECOUNT(global_export_params_2),
0);
jit_type_t global_export_params_3[] = {
jit_type_void_ptr,
jit_type_ulong,
jit_type_ulong,
};
global_export_signature_3_ = jit_type_create_signature(
jit_abi_cdecl,
jit_type_void,
global_export_params_3, XECOUNT(global_export_params_3),
0);
jit_type_t global_export_params_4[] = {
jit_type_void_ptr, jit_type_void_ptr,
jit_type_ulong, jit_type_ulong,
jit_type_ulong, jit_type_ulong,
jit_type_void_ptr, jit_type_void_ptr,
}; };
global_export_signature_ = jit_type_create_signature( global_export_signature_4_ = jit_type_create_signature(
jit_abi_cdecl, jit_abi_cdecl,
jit_type_void, jit_type_void,
global_export_params, XECOUNT(global_export_params), global_export_params_4, XECOUNT(global_export_params_4),
0); 0);
} }
LibjitEmitter::~LibjitEmitter() { LibjitEmitter::~LibjitEmitter() {
jit_type_free(fn_signature_); jit_type_free(fn_signature_);
jit_type_free(global_export_signature_); jit_type_free(shim_signature_);
jit_type_free(global_export_signature_2_);
jit_type_free(global_export_signature_3_);
jit_type_free(global_export_signature_4_);
} }
jit_context_t LibjitEmitter::context() { jit_context_t LibjitEmitter::context() {
@ -209,8 +241,9 @@ int LibjitEmitter::MakeUserFunction() {
}; };
jit_insn_call_native( jit_insn_call_native(
gen_fn_, gen_fn_,
"XeTraceUserCall", global_exports_.XeTraceUserCall, "XeTraceUserCall",
global_export_signature_, global_exports_.XeTraceUserCall,
global_export_signature_4_,
trace_args, XECOUNT(trace_args), trace_args, XECOUNT(trace_args),
0); 0);
} }
@ -222,65 +255,6 @@ int LibjitEmitter::MakeUserFunction() {
} }
int LibjitEmitter::MakePresentImportFunction() { int LibjitEmitter::MakePresentImportFunction() {
// LLVMContext& context = *context_;
// Generate the function.
// Function* fn = NULL;
// result_code = cub_->MakeFunction(symbol, &fn);
// if (result_code) {
// XELOGE("Unable to generate import %s", symbol->name());
// return result_code;
// }
// // Set global mappings for shim and data.
// char shim_name[256];
// xesnprintfa(shim_name, XECOUNT(shim_name),
// "__shim_%s", symbol->kernel_export->name);
// Function* shim = cub_module->getFunction(shim_name);
// if (shim) {
// engine_->updateGlobalMapping(
// shim, (void*)symbol->kernel_export->function_data.shim);
// }
// char shim_data_name[256];
// xesnprintfa(shim_data_name, XECOUNT(shim_data_name),
// "__shim_data_%s", symbol->kernel_export->name);
// GlobalVariable* shim_data = cub_module->getGlobalVariable(shim_data_name);
// if (shim_data) {
// engine_->updateGlobalMapping(
// shim_data, (void*)symbol->kernel_export->function_data.shim_data);
// }
// // Pick names.
// // We have both the shim function pointer and the shim data pointer.
// char shim_name[256];
// xesnprintfa(shim_name, XECOUNT(shim_name),
// "__shim_%s", symbol->kernel_export->name);
// char shim_data_name[256];
// xesnprintfa(shim_data_name, XECOUNT(shim_data_name),
// "__shim_data_%s", symbol->kernel_export->name);
// // Hardcoded to 64bits.
// Type* intPtrTy = IntegerType::get(context, 64);
// Type* int8PtrTy = PointerType::getUnqual(Type::getInt8Ty(context));
// // Declare shim function.
// std::vector<Type*> shimArgs;
// shimArgs.push_back(int8PtrTy);
// shimArgs.push_back(int8PtrTy);
// FunctionType* shimTy = FunctionType::get(
// Type::getVoidTy(context), shimArgs, false);
// Function* shim = Function::Create(
// shimTy, Function::ExternalLinkage, shim_name, module_);
// GlobalVariable* shim_data = new GlobalVariable(
// *module_, int8PtrTy, false, GlobalValue::ExternalLinkage, 0,
// shim_data_name);
// shim_data->setInitializer(ConstantExpr::getIntToPtr(
// ConstantInt::get(intPtrTy, 0), int8PtrTy));
// BasicBlock* block = BasicBlock::Create(context, "entry", fn);
// IRBuilder<> b(block);
if (FLAGS_trace_kernel_calls) { if (FLAGS_trace_kernel_calls) {
jit_value_t trace_args[] = { jit_value_t trace_args[] = {
jit_value_get_param(gen_fn_, 0), jit_value_get_param(gen_fn_, 0),
@ -292,16 +266,26 @@ int LibjitEmitter::MakePresentImportFunction() {
}; };
jit_insn_call_native( jit_insn_call_native(
gen_fn_, gen_fn_,
"XeTraceKernelCall", global_exports_.XeTraceKernelCall, "XeTraceKernelCall",
global_export_signature_, global_exports_.XeTraceKernelCall,
global_export_signature_4_,
trace_args, XECOUNT(trace_args), trace_args, XECOUNT(trace_args),
0); 0);
} }
// b.CreateCall2( // void shim(ppc_state*, shim_data*)
// shim, jit_value_t shim_args[] = {
// fn->arg_begin(), jit_value_get_param(gen_fn_, 0),
// b.CreateLoad(shim_data)); jit_value_create_long_constant(gen_fn_, jit_type_ulong,
(jit_ulong)fn_->kernel_export->function_data.shim_data),
};
jit_insn_call_native(
gen_fn_,
fn_->kernel_export->name,
fn_->kernel_export->function_data.shim,
shim_signature_,
shim_args, XECOUNT(shim_args),
0);
jit_insn_return(gen_fn_, NULL); jit_insn_return(gen_fn_, NULL);
@ -320,8 +304,9 @@ int LibjitEmitter::MakeMissingImportFunction() {
}; };
jit_insn_call_native( jit_insn_call_native(
gen_fn_, gen_fn_,
"XeTraceKernelCall", global_exports_.XeTraceKernelCall, "XeTraceKernelCall",
global_export_signature_, global_exports_.XeTraceKernelCall,
global_export_signature_4_,
trace_args, XECOUNT(trace_args), trace_args, XECOUNT(trace_args),
0); 0);
} }

View File

@ -102,7 +102,10 @@ private:
jit_context_t context_; jit_context_t context_;
GlobalExports global_exports_; GlobalExports global_exports_;
jit_type_t fn_signature_; jit_type_t fn_signature_;
jit_type_t global_export_signature_; jit_type_t shim_signature_;
jit_type_t global_export_signature_2_;
jit_type_t global_export_signature_3_;
jit_type_t global_export_signature_4_;
sdb::FunctionSymbol* fn_; sdb::FunctionSymbol* fn_;
jit_function_t gen_fn_; jit_function_t gen_fn_;

View File

@ -51,27 +51,6 @@ XECLEANUP:
} }
int LibjitJIT::InjectGlobals() { int LibjitJIT::InjectGlobals() {
// LLVMContext& context = *context_;
// const DataLayout* dl = engine_->getDataLayout();
// Type* intPtrTy = dl->getIntPtrType(context);
// Type* int8PtrTy = PointerType::getUnqual(Type::getInt8Ty(context));
// GlobalVariable* gv;
// // xe_memory_base
// // This is the base void* pointer to the memory space.
// gv = new GlobalVariable(
// *module_,
// int8PtrTy,
// true,
// GlobalValue::ExternalLinkage,
// 0,
// "xe_memory_base");
// // Align to 64b - this makes SSE faster.
// gv->setAlignment(64);
// gv->setInitializer(ConstantExpr::getIntToPtr(
// ConstantInt::get(intPtrTy, (uintptr_t)xe_memory_addr(memory_, 0)),
// int8PtrTy));
return 0; return 0;
} }
@ -99,7 +78,7 @@ int LibjitJIT::Execute(xe_ppc_state_t* ppc_state, FunctionSymbol* fn_symbol) {
XEASSERTNOTNULL(jit_fn); XEASSERTNOTNULL(jit_fn);
} }
// TODO(benvanik): replace generic apply with special trampoline. // Call into the function. This will compile it if needed.
intptr_t args[] = {(intptr_t)ppc_state, ppc_state->lr}; intptr_t args[] = {(intptr_t)ppc_state, ppc_state->lr};
uint64_t return_value; uint64_t return_value;
int apply_result = jit_function_apply(jit_fn, (void**)&args, &return_value); int apply_result = jit_function_apply(jit_fn, (void**)&args, &return_value);