Kernel calls and variables now working and tracing better.

This commit is contained in:
Ben Vanik
2013-01-28 12:36:39 -08:00
parent 5c2060af72
commit 6c4af5aa70
19 changed files with 462 additions and 51 deletions

View File

@@ -117,23 +117,26 @@ void FunctionGenerator::PopInsertPoint() {
}
void FunctionGenerator::GenerateBasicBlocks() {
IRBuilder<>& b = *builder_;
// Always add an entry block.
BasicBlock* entry = BasicBlock::Create(*context_, "entry", gen_fn_);
builder_->SetInsertPoint(entry);
b.SetInsertPoint(entry);
if (FLAGS_trace_user_calls) {
SpillRegisters();
Value* traceUserCall = gen_module_->getFunction("XeTraceUserCall");
builder_->CreateCall3(
b.CreateCall4(
traceUserCall,
gen_fn_->arg_begin(),
builder_->getInt64(fn_->start_address),
++gen_fn_->arg_begin());
b.getInt64(fn_->start_address),
++gen_fn_->arg_begin(),
b.getInt64((uint64_t)fn_));
}
// If this function is empty, abort!
if (!fn_->blocks.size()) {
builder_->CreateRetVoid();
b.CreateRetVoid();
return;
}
@@ -214,13 +217,15 @@ void FunctionGenerator::GenerateSharedBlocks() {
void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block,
BasicBlock* bb) {
IRBuilder<>& b = *builder_;
printf(" bb %.8X-%.8X:\n", block->start_address, block->end_address);
fn_block_ = block;
bb_ = bb;
// Move the builder to this block and setup.
builder_->SetInsertPoint(bb);
b.SetInsertPoint(bb);
//i->setMetadata("some.name", MDNode::get(context, MDString::get(context, pname)));
Value* invalidInstruction =
@@ -238,21 +243,21 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block,
if (FLAGS_trace_instructions) {
SpillRegisters();
builder_->CreateCall3(
b.CreateCall3(
traceInstruction,
gen_fn_->arg_begin(),
builder_->getInt32(i.address),
builder_->getInt32(i.code));
b.getInt32(i.address),
b.getInt32(i.code));
}
if (!i.type) {
XELOGCPU("Invalid instruction %.8X %.8X", ia, i.code);
SpillRegisters();
builder_->CreateCall3(
b.CreateCall3(
invalidInstruction,
gen_fn_->arg_begin(),
builder_->getInt32(i.address),
builder_->getInt32(i.code));
b.getInt32(i.address),
b.getInt32(i.code));
continue;
}
printf(" %.8X: %.8X %s\n", ia, i.code, i.type->name);
@@ -273,11 +278,11 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block,
XELOGCPU("Unimplemented instr %.8X %.8X %s",
ia, i.code, i.type->name);
SpillRegisters();
builder_->CreateCall3(
b.CreateCall3(
invalidInstruction,
gen_fn_->arg_begin(),
builder_->getInt32(i.address),
builder_->getInt32(i.code));
b.getInt32(i.address),
b.getInt32(i.code));
}
}
@@ -285,13 +290,13 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block,
if (block->outgoing_type == FunctionBlock::kTargetNone) {
BasicBlock* next_bb = GetNextBasicBlock();
XEASSERTNOTNULL(next_bb);
builder_->CreateBr(next_bb);
b.CreateBr(next_bb);
} else if (block->outgoing_type == FunctionBlock::kTargetUnknown) {
// Hrm.
// TODO(benvanik): assert this doesn't occur - means a bad sdb run!
XELOGCPU("SDB function scan error in %.8X: bb %.8X has unknown exit\n",
fn_->start_address, block->start_address);
builder_->CreateRetVoid();
b.CreateRetVoid();
}
// TODO(benvanik): finish up BB
@@ -348,7 +353,7 @@ int FunctionGenerator::GenerateIndirectionBranch(uint32_t cia, Value* target,
// after we are done with all user instructions.
if (!external_indirection_block_) {
// Setup locals in the entry block.
builder_->SetInsertPoint(&gen_fn_->getEntryBlock());
b.SetInsertPoint(&gen_fn_->getEntryBlock());
locals_.indirection_target = b.CreateAlloca(
b.getInt64Ty(), 0, "indirection_target");
locals_.indirection_cia = b.CreateAlloca(

View File

@@ -14,6 +14,7 @@
#include <llvm/PassManager.h>
#include <llvm/DebugInfo.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/IR/Attributes.h>
#include <llvm/IR/DataLayout.h>
#include <llvm/IR/DerivedTypes.h>
@@ -40,7 +41,7 @@ using namespace xe::kernel;
ModuleGenerator::ModuleGenerator(
xe_memory_ref memory, ExportResolver* export_resolver,
const char* module_name, const char* module_path, SymbolDatabase* sdb,
LLVMContext* context, Module* gen_module) {
LLVMContext* context, Module* gen_module, ExecutionEngine* engine) {
memory_ = xe_memory_retain(memory);
export_resolver_ = export_resolver;
module_name_ = xestrdupa(module_name);
@@ -48,6 +49,7 @@ ModuleGenerator::ModuleGenerator(
sdb_ = sdb;
context_ = context;
gen_module_ = gen_module;
engine_ = engine;
di_builder_ = NULL;
}
@@ -196,11 +198,12 @@ void ModuleGenerator::AddMissingImport(FunctionSymbol* fn) {
if (FLAGS_trace_kernel_calls) {
Value* traceKernelCall = m->getFunction("XeTraceKernelCall");
b.CreateCall3(
b.CreateCall4(
traceKernelCall,
f->arg_begin(),
b.getInt64(fn->start_address),
++f->arg_begin());
++f->arg_begin(),
b.getInt64((uint64_t)fn->kernel_export));
}
b.CreateRetVoid();
@@ -221,18 +224,37 @@ void ModuleGenerator::AddPresentImport(FunctionSymbol* fn) {
Module *m = gen_module_;
LLVMContext& context = m->getContext();
// Add the extern.
const DataLayout* dl = engine_->getDataLayout();
Type* intPtrTy = dl->getIntPtrType(context);
Type* int8PtrTy = PointerType::getUnqual(Type::getInt8Ty(context));
// Add the externs.
// We have both the shim function pointer and the shim data pointer.
char shim_name[256];
xesnprintfa(shim_name, XECOUNT(shim_name),
"__shim__%s", fn->kernel_export->name);
"__shim_%s", fn->kernel_export->name);
char shim_data_name[256];
xesnprintfa(shim_data_name, XECOUNT(shim_data_name),
"__shim_data_%s", fn->kernel_export->name);
std::vector<Type*> shimArgs;
shimArgs.push_back(PointerType::getUnqual(Type::getInt8Ty(context)));
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, m);
// engine_->addGlobalMapping(shim,
// (void*)fn->kernel_export->function_data.shim);
GlobalVariable* gv = new GlobalVariable(
*m, int8PtrTy, true, GlobalValue::ExternalLinkage, 0,
shim_data_name);
// TODO(benvanik): don't initialize on startup - move to exec_module
gv->setInitializer(ConstantExpr::getIntToPtr(
ConstantInt::get(intPtrTy,
(uintptr_t)fn->kernel_export->function_data.shim_data),
int8PtrTy));
engine_->addGlobalMapping(shim,
(void*)fn->kernel_export->function_data.shim);
// Create the function (and setup args/attributes/etc).
Function* f = CreateFunctionDefinition(fn->name);
@@ -242,16 +264,18 @@ void ModuleGenerator::AddPresentImport(FunctionSymbol* fn) {
if (FLAGS_trace_kernel_calls) {
Value* traceKernelCall = m->getFunction("XeTraceKernelCall");
b.CreateCall3(
b.CreateCall4(
traceKernelCall,
f->arg_begin(),
b.getInt64(fn->start_address),
++f->arg_begin());
++f->arg_begin(),
b.getInt64((uint64_t)fn->kernel_export));
}
b.CreateCall(
b.CreateCall2(
shim,
f->arg_begin());
f->arg_begin(),
b.CreateLoad(gv));
b.CreateRetVoid();