Better handling of invalid/unimplemented instructions.

This commit is contained in:
Ben Vanik 2013-01-25 00:51:56 -08:00
parent dcb958de54
commit ebda245773
3 changed files with 38 additions and 2 deletions

View File

@ -20,6 +20,7 @@ andix
orx orx
rlwinmx rlwinmx
rlwimix
rldiclx rldiclx
extsbx extsbx
slwx slwx

View File

@ -199,6 +199,8 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block,
builder_->SetInsertPoint(bb); builder_->SetInsertPoint(bb);
//i->setMetadata("some.name", MDNode::get(context, MDString::get(context, pname))); //i->setMetadata("some.name", MDNode::get(context, MDString::get(context, pname)));
Value* invalidInstruction =
gen_module_->getGlobalVariable("XeInvalidInstruction");
Value* traceInstruction = Value* traceInstruction =
gen_module_->getGlobalVariable("XeTraceInstruction"); gen_module_->getGlobalVariable("XeTraceInstruction");
@ -220,7 +222,13 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block,
} }
if (!i.type) { if (!i.type) {
XELOGCPU("Invalid instruction at %.8X: %.8X\n", ia, i.code); XELOGCPU("Invalid instruction %.8X %.8X", ia, i.code);
SpillRegisters();
builder_->CreateCall3(
invalidInstruction,
gen_fn_->arg_begin(),
builder_->getInt32(i.address),
builder_->getInt32(i.code));
continue; continue;
} }
printf(" %.8X: %.8X %s\n", ia, i.code, i.type->name); printf(" %.8X: %.8X %s\n", ia, i.code, i.type->name);
@ -235,7 +243,17 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block,
XEASSERTNOTNULL(emit); XEASSERTNOTNULL(emit);
int result = emit(*this, *builder_, i); int result = emit(*this, *builder_, i);
if (result) { if (result) {
printf("---- error generating instruction: %.8X\n", ia); // This printf is handy for sort/uniquify to find instructions.
//printf("unimplinstr %s\n", i.type->name);
XELOGCPU("Unimplemented instr %.8X %.8X %s",
ia, i.code, i.type->name);
SpillRegisters();
builder_->CreateCall3(
invalidInstruction,
gen_fn_->arg_begin(),
builder_->getInt32(i.address),
builder_->getInt32(i.code));
} }
} }

View File

@ -207,6 +207,11 @@ void XeIndirectBranch(xe_ppc_state_t* state, uint64_t target, uint64_t br_ia) {
XEASSERTALWAYS(); XEASSERTALWAYS();
} }
void XeInvalidInstruction(xe_ppc_state_t* state, uint32_t cia, uint32_t data) {
// TODO(benvanik): handle better
XELOGCPU("INVALID INSTRUCTION %.8X %.8X", cia, data);
}
void XeTraceKernelCall(xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia) { void XeTraceKernelCall(xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia) {
// TODO(benvanik): get names // 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, (uint32_t)cia);
@ -261,6 +266,18 @@ int ExecModule::InjectGlobals() {
"XeIndirectBranch"); "XeIndirectBranch");
engine_->addGlobalMapping(gv, (void*)&XeIndirectBranch); engine_->addGlobalMapping(gv, (void*)&XeIndirectBranch);
// Debugging methods:
std::vector<Type*> invalidInstructionArgs;
invalidInstructionArgs.push_back(int8PtrTy);
invalidInstructionArgs.push_back(Type::getInt32Ty(context));
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);
// Tracing methods: // Tracing methods:
std::vector<Type*> traceCallArgs; std::vector<Type*> traceCallArgs;
traceCallArgs.push_back(int8PtrTy); traceCallArgs.push_back(int8PtrTy);