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

View File

@ -24,13 +24,13 @@ namespace cpu {
typedef struct {
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)(
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)(
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)(
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)(
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
kernel::KernelExport* kernel_export);
@ -38,7 +38,7 @@ typedef struct {
xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
sdb::FunctionSymbol* fn);
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;

View File

@ -63,22 +63,54 @@ LibjitEmitter::LibjitEmitter(xe_memory_ref memory, jit_context_t context) {
fn_params, XECOUNT(fn_params),
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_ulong,
jit_type_ulong,
jit_type_void_ptr,
};
global_export_signature_ = jit_type_create_signature(
global_export_signature_4_ = jit_type_create_signature(
jit_abi_cdecl,
jit_type_void,
global_export_params, XECOUNT(global_export_params),
global_export_params_4, XECOUNT(global_export_params_4),
0);
}
LibjitEmitter::~LibjitEmitter() {
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() {
@ -209,8 +241,9 @@ int LibjitEmitter::MakeUserFunction() {
};
jit_insn_call_native(
gen_fn_,
"XeTraceUserCall", global_exports_.XeTraceUserCall,
global_export_signature_,
"XeTraceUserCall",
global_exports_.XeTraceUserCall,
global_export_signature_4_,
trace_args, XECOUNT(trace_args),
0);
}
@ -222,65 +255,6 @@ int LibjitEmitter::MakeUserFunction() {
}
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) {
jit_value_t trace_args[] = {
jit_value_get_param(gen_fn_, 0),
@ -292,16 +266,26 @@ int LibjitEmitter::MakePresentImportFunction() {
};
jit_insn_call_native(
gen_fn_,
"XeTraceKernelCall", global_exports_.XeTraceKernelCall,
global_export_signature_,
"XeTraceKernelCall",
global_exports_.XeTraceKernelCall,
global_export_signature_4_,
trace_args, XECOUNT(trace_args),
0);
}
// b.CreateCall2(
// shim,
// fn->arg_begin(),
// b.CreateLoad(shim_data));
// void shim(ppc_state*, shim_data*)
jit_value_t shim_args[] = {
jit_value_get_param(gen_fn_, 0),
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);
@ -320,8 +304,9 @@ int LibjitEmitter::MakeMissingImportFunction() {
};
jit_insn_call_native(
gen_fn_,
"XeTraceKernelCall", global_exports_.XeTraceKernelCall,
global_export_signature_,
"XeTraceKernelCall",
global_exports_.XeTraceKernelCall,
global_export_signature_4_,
trace_args, XECOUNT(trace_args),
0);
}

View File

@ -102,7 +102,10 @@ private:
jit_context_t context_;
GlobalExports global_exports_;
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_;
jit_function_t gen_fn_;

View File

@ -51,27 +51,6 @@ XECLEANUP:
}
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;
}
@ -99,7 +78,7 @@ int LibjitJIT::Execute(xe_ppc_state_t* ppc_state, FunctionSymbol* fn_symbol) {
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};
uint64_t return_value;
int apply_result = jit_function_apply(jit_fn, (void**)&args, &return_value);