Kernel call thunks and cleanup on exports.
This commit is contained in:
parent
37f93d2974
commit
33e2bc01ee
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue