Executing a bunch of instructions!

Very hacky module startup code, but can now start XEXs! Time to start
implementing kernel stuff.
This commit is contained in:
Ben Vanik 2013-01-27 22:14:24 -08:00
parent 92a3e19cd9
commit 46d5a0b51d
10 changed files with 57 additions and 46 deletions

View File

@ -6,14 +6,9 @@ Not sure the way I'm doing this is right. addic/subficx/etc set it to the value
of the overflow bit from the LLVM *_with_overflow intrinsic.
```
MISDECODING: andix
rlwinmx
rlwimix
rldiclx
slwx
srawix
```
Overflow bits can be set via the intrinsics:

View File

@ -9,7 +9,7 @@ fi
./build/xenia/release/xenia-run \
private/$1 \
--optimize_ir_modules=true \
--optimize_ir_functions=false \
--optimize_ir_functions=true \
--trace_kernel_calls=true \
--trace_user_calls=false \
--trace_instructions=false \

View File

@ -539,7 +539,7 @@ XEEMITTER(andix, 0x70000000, D )(FunctionGenerator& g, IRBuilder<>& b, I
// With cr0 update.
g.update_cr_with_cond(0, v, b.getInt64(0), true);
return 1;
return 0;
}
XEEMITTER(andisx, 0x74000000, D )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
@ -805,7 +805,6 @@ XEEMITTER(rlwinmx, 0x54000000, M )(FunctionGenerator& g, IRBuilder<>& b, I
// g.update_cr_with_cond(0, v, b.getInt64(0), true);
// }
printf("rlwinmx %d %d %d\n", i.M.SH, i.M.MB, i.M.ME);
XEINSTRNOTIMPLEMENTED();
return 1;
}

View File

@ -173,6 +173,7 @@ XEEMITTER(bcx, 0x40000000, B )(FunctionGenerator& g, IRBuilder<>& b, I
// Decrement counter.
Value* ctr = g.ctr_value();
ctr = b.CreateSub(ctr, b.getInt64(1));
g.update_ctr_value(ctr);
// Ctr check.
if (XESELECTBITS(i.B.BO, 1, 1)) {
@ -520,7 +521,7 @@ int XeEmitTrap(FunctionGenerator& g, IRBuilder<>& b, InstrData& i,
b.SetInsertPoint(trap_bb);
g.SpillRegisters();
// TODO(benvanik): use @llvm.debugtrap? could make debugging better
b.CreateCall2(g.gen_module()->getGlobalVariable("XeTrap"),
b.CreateCall2(g.gen_module()->getFunction("XeTrap"),
g.gen_fn()->arg_begin(),
b.getInt32(i.address));
b.CreateBr(after_bb);

View File

@ -117,7 +117,7 @@ void FunctionGenerator::GenerateBasicBlocks() {
if (FLAGS_trace_user_calls) {
SpillRegisters();
Value* traceUserCall = gen_module_->getGlobalVariable("XeTraceUserCall");
Value* traceUserCall = gen_module_->getFunction("XeTraceUserCall");
builder_->CreateCall3(
traceUserCall,
gen_fn_->arg_begin(),
@ -162,7 +162,7 @@ void FunctionGenerator::GenerateBasicBlocks() {
void FunctionGenerator::GenerateSharedBlocks() {
IRBuilder<>& b = *builder_;
Value* indirect_branch = gen_module_->getGlobalVariable("XeIndirectBranch");
Value* indirect_branch = gen_module_->getFunction("XeIndirectBranch");
// Setup initial register fill in the entry block.
// We can only do this once all the locals have been created.
@ -218,9 +218,9 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block,
//i->setMetadata("some.name", MDNode::get(context, MDString::get(context, pname)));
Value* invalidInstruction =
gen_module_->getGlobalVariable("XeInvalidInstruction");
gen_module_->getFunction("XeInvalidInstruction");
Value* traceInstruction =
gen_module_->getGlobalVariable("XeTraceInstruction");
gen_module_->getFunction("XeTraceInstruction");
// Walk instructions in block.
uint8_t* p = xe_memory_addr(memory_, 0);
@ -390,7 +390,7 @@ int FunctionGenerator::GenerateIndirectionBranch(uint32_t cia, Value* target,
SpillRegisters();
// TODO(benvanik): keep function pointer lookup local.
Value* indirect_branch = gen_module_->getGlobalVariable("XeIndirectBranch");
Value* indirect_branch = gen_module_->getFunction("XeIndirectBranch");
b.CreateCall3(indirect_branch,
gen_fn_->arg_begin(),
target,
@ -861,6 +861,9 @@ Value* FunctionGenerator::ReadMemory(Value* addr, uint32_t size, bool extend) {
}
PointerType* pointerTy = PointerType::getUnqual(dataTy);
// Input address is always in 32-bit space.
addr = b.CreateAnd(addr, UINT_MAX);
Value* offset_addr = b.CreateAdd(addr, b.getInt64(size));
Value* address = b.CreateInBoundsGEP(GetMembase(), offset_addr);
Value* ptr = b.CreatePointerCast(address, pointerTy);
@ -890,6 +893,9 @@ void FunctionGenerator::WriteMemory(Value* addr, uint32_t size, Value* value) {
}
PointerType* pointerTy = PointerType::getUnqual(dataTy);
// Input address is always in 32-bit space.
addr = b.CreateAnd(addr, UINT_MAX);
Value* offset_addr = b.CreateAdd(addr, b.getInt64(size));
Value* address = b.CreateInBoundsGEP(GetMembase(), offset_addr);
Value* ptr = b.CreatePointerCast(address, pointerTy);

View File

@ -77,7 +77,7 @@ int ModuleGenerator::Generate() {
}
di_builder_ = new DIBuilder(*gen_module_);
di_builder_->createCompileUnit(
0,
dwarf::DW_LANG_C99, //0x8010,
StringRef(module_name_),
StringRef(dir),
StringRef("xenia"),
@ -196,7 +196,7 @@ void ModuleGenerator::AddMissingImport(FunctionSymbol* fn) {
IRBuilder<> builder(block);
if (FLAGS_trace_kernel_calls) {
Value* traceKernelCall = m->getGlobalVariable("XeTraceKernelCall");
Value* traceKernelCall = m->getFunction("XeTraceKernelCall");
builder.CreateCall3(
traceKernelCall,
f->arg_begin(),

View File

@ -240,12 +240,12 @@ void XeInvalidInstruction(xe_ppc_state_t* state, uint32_t cia, uint32_t data) {
void XeTraceKernelCall(xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia) {
// TODO(benvanik): get names
XELOGCPU("TRACE: %.8X -> k.%.8X", (uint32_t)call_ia, (uint32_t)cia);
XELOGCPU("TRACE: %.8X -> k.%.8X", (uint32_t)call_ia - 4, (uint32_t)cia);
}
void XeTraceUserCall(xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia) {
// TODO(benvanik): get names
XELOGCPU("TRACE: %.8X -> u.%.8X", (uint32_t)call_ia, (uint32_t)cia);
XELOGCPU("TRACE: %.8X -> u.%.8X", (uint32_t)call_ia - 4, (uint32_t)cia);
}
void XeTraceInstruction(xe_ppc_state_t* state, uint32_t cia, uint32_t data) {
@ -286,10 +286,9 @@ int ExecModule::InjectGlobals() {
trapArgs.push_back(Type::getInt32Ty(context));
FunctionType* trapTy = FunctionType::get(
Type::getVoidTy(context), trapArgs, false);
gv = new GlobalVariable(*gen_module_, trapTy, true,
GlobalVariable::ExternalLinkage, 0,
"XeTrap");
engine_->addGlobalMapping(gv, (void*)&XeTrap);
engine_->addGlobalMapping(Function::Create(
trapTy, Function::ExternalLinkage, "XeTrap",
gen_module_.get()), (void*)&XeTrap);
std::vector<Type*> indirectBranchArgs;
indirectBranchArgs.push_back(int8PtrTy);
@ -297,10 +296,9 @@ int ExecModule::InjectGlobals() {
indirectBranchArgs.push_back(Type::getInt64Ty(context));
FunctionType* indirectBranchTy = FunctionType::get(
Type::getVoidTy(context), indirectBranchArgs, false);
gv = new GlobalVariable(*gen_module_, indirectBranchTy, true,
GlobalVariable::ExternalLinkage, 0,
"XeIndirectBranch");
engine_->addGlobalMapping(gv, (void*)&XeIndirectBranch);
engine_->addGlobalMapping(Function::Create(
indirectBranchTy, Function::ExternalLinkage, "XeIndirectBranch",
gen_module_.get()), (void*)&XeIndirectBranch);
// Debugging methods:
std::vector<Type*> invalidInstructionArgs;
@ -309,10 +307,9 @@ int ExecModule::InjectGlobals() {
invalidInstructionArgs.push_back(Type::getInt32Ty(context));
FunctionType* invalidInstructionTy = FunctionType::get(
Type::getVoidTy(context), invalidInstructionArgs, false);
gv = new GlobalVariable(*gen_module_, invalidInstructionTy, true,
GlobalVariable::ExternalLinkage, 0,
"XeInvalidInstruction");
engine_->addGlobalMapping(gv, (void*)&XeInvalidInstruction);
engine_->addGlobalMapping(Function::Create(
invalidInstructionTy, Function::ExternalLinkage, "XeInvalidInstruction",
gen_module_.get()), (void*)&XeInvalidInstruction);
// Tracing methods:
std::vector<Type*> traceCallArgs;
@ -328,18 +325,15 @@ int ExecModule::InjectGlobals() {
FunctionType* traceInstructionTy = FunctionType::get(
Type::getVoidTy(context), traceInstructionArgs, false);
gv = new GlobalVariable(*gen_module_, traceCallTy, true,
GlobalValue::ExternalLinkage, 0,
"XeTraceKernelCall");
engine_->addGlobalMapping(gv, (void*)&XeTraceKernelCall);
gv = new GlobalVariable(*gen_module_, traceCallTy, true,
GlobalValue::ExternalLinkage, 0,
"XeTraceUserCall");
engine_->addGlobalMapping(gv, (void*)&XeTraceUserCall);
gv = new GlobalVariable(*gen_module_, traceInstructionTy, true,
GlobalValue::ExternalLinkage, 0,
"XeTraceInstruction");
engine_->addGlobalMapping(gv, (void*)&XeTraceInstruction);
engine_->addGlobalMapping(Function::Create(
traceCallTy, Function::ExternalLinkage, "XeTraceKernelCall",
gen_module_.get()), (void*)&XeTraceKernelCall);
engine_->addGlobalMapping(Function::Create(
traceCallTy, Function::ExternalLinkage, "XeTraceUserCall",
gen_module_.get()), (void*)&XeTraceUserCall);
engine_->addGlobalMapping(Function::Create(
traceInstructionTy, Function::ExternalLinkage, "XeTraceInstruction",
gen_module_.get()), (void*)&XeTraceInstruction);
return 0;
}

View File

@ -99,7 +99,7 @@ int Processor::Setup() {
std::string error_message;
engine_ = shared_ptr<ExecutionEngine>(
ExecutionEngine::create(dummy_module, false, &error_message,
CodeGenOpt::Aggressive));
CodeGenOpt::Aggressive, false));
if (!engine_) {
return 1;
}

View File

@ -13,6 +13,7 @@
using namespace xe;
using namespace xe::cpu;
using namespace xe::kernel;
@ -131,13 +132,11 @@ XECLEANUP:
}
void Runtime::LaunchModule(UserModule* user_module) {
//const xe_xex2_header_t *xex_header = xe_module_get_xex_header(module);
const xe_xex2_header_t *xex_header = user_module->xex_header();
// TODO(benvanik): set as main module/etc
// xekXexExecutableModuleHandle = xe_module_get_handle(module);
// XEEXPECTTRUE(XECPUPrepareModule(XEGetCPU(), module->xex, module->pe, module->address_space, module->address_space_size));
// Setup the heap (and TLS?).
// xex_header->exe_heap_size;
@ -149,6 +148,19 @@ void Runtime::LaunchModule(UserModule* user_module) {
// Wait until thread completes.
// XLARGE_INTEGER timeout = XINFINITE;
// xekNtWaitForSingleObjectEx(thread_handle, TRUE, &timeout);
// Simulate a thread.
uint32_t stack_size = xex_header->exe_stack_size;
if (stack_size < 16 * 1024 * 1024) {
stack_size = 16 * 1024 * 1024;
}
ThreadState* thread_state = processor_->AllocThread(
0x80000000, stack_size);
// Execute test.
processor_->Execute(thread_state, xex_header->exe_entry_point);
processor_->DeallocThread(thread_state);
}
UserModule* Runtime::GetModule(const xechar_t* path) {

View File

@ -73,6 +73,10 @@
],
'direct_dependent_settings': {
'include_dirs': [
'<!@(<(llvm_config) --includedir)',
],
'target_conditions': [
['_type=="shared_library"', {
'cflags': [