diff --git a/TODO.md b/TODO.md index 76aee0383..c3e77707d 100644 --- a/TODO.md +++ b/TODO.md @@ -20,6 +20,7 @@ andix orx rlwinmx +rlwimix rldiclx extsbx slwx diff --git a/src/cpu/codegen/function_generator.cc b/src/cpu/codegen/function_generator.cc index 98fd4d8ad..433db45dd 100644 --- a/src/cpu/codegen/function_generator.cc +++ b/src/cpu/codegen/function_generator.cc @@ -199,6 +199,8 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block, builder_->SetInsertPoint(bb); //i->setMetadata("some.name", MDNode::get(context, MDString::get(context, pname))); + Value* invalidInstruction = + gen_module_->getGlobalVariable("XeInvalidInstruction"); Value* traceInstruction = gen_module_->getGlobalVariable("XeTraceInstruction"); @@ -220,7 +222,13 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block, } 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; } printf(" %.8X: %.8X %s\n", ia, i.code, i.type->name); @@ -235,7 +243,17 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block, XEASSERTNOTNULL(emit); int result = emit(*this, *builder_, i); 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)); } } diff --git a/src/cpu/exec_module.cc b/src/cpu/exec_module.cc index 01170e22e..7de1fda40 100644 --- a/src/cpu/exec_module.cc +++ b/src/cpu/exec_module.cc @@ -207,6 +207,11 @@ void XeIndirectBranch(xe_ppc_state_t* state, uint64_t target, uint64_t br_ia) { 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) { // TODO(benvanik): get names XELOGCPU("TRACE: %.8X -> k.%.8X", (uint32_t)call_ia, (uint32_t)cia); @@ -261,6 +266,18 @@ int ExecModule::InjectGlobals() { "XeIndirectBranch"); engine_->addGlobalMapping(gv, (void*)&XeIndirectBranch); + // Debugging methods: + std::vector 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: std::vector traceCallArgs; traceCallArgs.push_back(int8PtrTy);