void CJitWindow::Compare(u32 em_address) { u8 *xDis = new u8[1<<18]; memset(xDis, 0, 1<<18); disassembler x64disasm; x64disasm.set_syntax_intel(); int block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(em_address); if (block_num < 0) { for (int i = 0; i < 500; i++) { block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(em_address - 4 * i); if (block_num >= 0) break; } if (block_num >= 0) { JitBlock *block = jit->GetBlockCache()->GetBlock(block_num); if (!(block->originalAddress <= em_address && block->originalSize + block->originalAddress >= em_address)) block_num = -1; } // Do not merge this "if" with the above - block_num changes inside it. if (block_num < 0) { ppc_box->SetValue(_(StringFromFormat("(non-code address: %08x)", em_address))); x86_box->SetValue(_("(no translation)")); delete[] xDis; return; } } JitBlock *block = jit->GetBlockCache()->GetBlock(block_num); // 800031f0 // == Fill in x86 box const u8 *code = (const u8 *)jit->GetBlockCache()->GetCompiledCodeFromBlock(block_num); u64 disasmPtr = (u64)code; const u8 *end = code + block->codeSize; char *sptr = (char*)xDis; int num_x86_instructions = 0; while ((u8*)disasmPtr < end) { disasmPtr += x64disasm.disasm64(disasmPtr, disasmPtr, (u8*)disasmPtr, sptr); sptr += strlen(sptr); *sptr++ = 13; *sptr++ = 10; num_x86_instructions++; } x86_box->SetValue(StrToWxStr((char*)xDis)); // == Fill in ppc box u32 ppc_addr = block->originalAddress; PPCAnalyst::CodeBuffer code_buffer(32000); PPCAnalyst::BlockStats st; PPCAnalyst::BlockRegStats gpa; PPCAnalyst::BlockRegStats fpa; PPCAnalyst::CodeBlock code_block; PPCAnalyst::PPCAnalyzer analyzer; code_block.m_stats = &st; code_block.m_gpa = &gpa; code_block.m_fpa = &fpa; if (analyzer.Analyze(ppc_addr, &code_block, &code_buffer, block->codeSize) != 0xFFFFFFFF) { sptr = (char*)xDis; for (u32 i = 0; i < code_block.m_num_instructions; i++) { const PPCAnalyst::CodeOp &op = code_buffer.codebuffer[i]; std::string temp = GekkoDisassembler::Disassemble(op.inst.hex, op.address); sptr += sprintf(sptr, "%08x %s\n", op.address, temp.c_str()); } // Add stats to the end of the ppc box since it's generally the shortest. sptr += sprintf(sptr, "\n"); // Add some generic analysis if (st.isFirstBlockOfFunction) sptr += sprintf(sptr, "(first block of function)\n"); if (st.isLastBlockOfFunction) sptr += sprintf(sptr, "(last block of function)\n"); sptr += sprintf(sptr, "%i estimated cycles\n", st.numCycles); sptr += sprintf(sptr, "Num instr: PPC: %i x86: %i (blowup: %i%%)\n", code_block.m_num_instructions, num_x86_instructions, 100 * num_x86_instructions / code_block.m_num_instructions - 100); sptr += sprintf(sptr, "Num bytes: PPC: %i x86: %i (blowup: %i%%)\n", code_block.m_num_instructions * 4, block->codeSize, 100 * block->codeSize / (4 * code_block.m_num_instructions) - 100); ppc_box->SetValue(StrToWxStr((char*)xDis)); } else { ppc_box->SetValue(StrToWxStr(StringFromFormat( "(non-code address: %08x)", em_address))); x86_box->SetValue("---"); } delete[] xDis; }
void CJitWindow::Compare(u32 em_address) { u8 *xDis = new u8[1<<18]; memset(xDis, 0, 1<<18); disassembler x64disasm; x64disasm.set_syntax_intel(); int block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(em_address); if (block_num < 0) { for (int i = 0; i < 500; i++) { block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(em_address - 4 * i); if (block_num >= 0) break; } if (block_num >= 0) { JitBlock *block = jit->GetBlockCache()->GetBlock(block_num); if (!(block->originalAddress <= em_address && block->originalSize + block->originalAddress >= em_address)) block_num = -1; } // Do not merge this "if" with the above - block_num changes inside it. if (block_num < 0) { ppc_box->SetValue(StrToWxStr(StringFromFormat("(non-code address: %08x)", em_address))); x86_box->SetValue(StrToWxStr(StringFromFormat("(no translation)"))); delete[] xDis; return; } } JitBlock *block = jit->GetBlockCache()->GetBlock(block_num); // 800031f0 // == Fill in x86 box const u8 *code = (const u8 *)jit->GetBlockCache()->GetCompiledCodeFromBlock(block_num); u64 disasmPtr = (u64)code; int size = block->codeSize; const u8 *end = code + size; char *sptr = (char*)xDis; int num_x86_instructions = 0; while ((u8*)disasmPtr < end) { #if _M_X86_64 disasmPtr += x64disasm.disasm64(disasmPtr, disasmPtr, (u8*)disasmPtr, sptr); #else disasmPtr += x64disasm.disasm32(disasmPtr, disasmPtr, (u8*)disasmPtr, sptr); #endif sptr += strlen(sptr); *sptr++ = 13; *sptr++ = 10; num_x86_instructions++; } x86_box->SetValue(StrToWxStr((char*)xDis)); // == Fill in ppc box u32 ppc_addr = block->originalAddress; PPCAnalyst::CodeBuffer code_buffer(32000); PPCAnalyst::BlockStats st; PPCAnalyst::BlockRegStats gpa; PPCAnalyst::BlockRegStats fpa; bool broken_block = false; u32 merged_addresses[32]; const int capacity_of_merged_addresses = sizeof(merged_addresses) / sizeof(merged_addresses[0]); int size_of_merged_addresses; if (PPCAnalyst::Flatten(ppc_addr, &size, &st, &gpa, &fpa, broken_block, &code_buffer, size, merged_addresses, capacity_of_merged_addresses, size_of_merged_addresses) != 0xffffffff) { sptr = (char*)xDis; for (int i = 0; i < size; i++) { const PPCAnalyst::CodeOp &op = code_buffer.codebuffer[i]; char temp[256]; DisassembleGekko(op.inst.hex, op.address, temp, 256); sptr += sprintf(sptr, "%08x %s\n", op.address, temp); } // Add stats to the end of the ppc box since it's generally the shortest. sptr += sprintf(sptr, "\n"); // Add some generic analysis if (st.isFirstBlockOfFunction) sptr += sprintf(sptr, "(first block of function)\n"); if (st.isLastBlockOfFunction) sptr += sprintf(sptr, "(first block of function)\n"); sptr += sprintf(sptr, "%i estimated cycles\n", st.numCycles); sptr += sprintf(sptr, "Num instr: PPC: %i x86: %i (blowup: %i%%)\n", size, num_x86_instructions, 100 * (num_x86_instructions / size - 1)); sptr += sprintf(sptr, "Num bytes: PPC: %i x86: %i (blowup: %i%%)\n", size * 4, block->codeSize, 100 * (block->codeSize / (4 * size) - 1)); ppc_box->SetValue(StrToWxStr((char*)xDis)); } else { ppc_box->SetValue(StrToWxStr(StringFromFormat( "(non-code address: %08x)", em_address))); x86_box->SetValue("---"); } delete[] xDis; }
void CJitWindow::Compare(u32 em_address) { // Get host side code disassembly u32 host_instructions_count = 0; u32 host_code_size = 0; std::string host_instructions_disasm; host_instructions_disasm = DisassembleBlock(m_disassembler.get(), &em_address, &host_instructions_count, &host_code_size); x86_box->SetValue(host_instructions_disasm); // == Fill in ppc box u32 ppc_addr = em_address; PPCAnalyst::CodeBuffer code_buffer(32000); PPCAnalyst::BlockStats st; PPCAnalyst::BlockRegStats gpa; PPCAnalyst::BlockRegStats fpa; PPCAnalyst::CodeBlock code_block; PPCAnalyst::PPCAnalyzer analyzer; analyzer.SetOption(PPCAnalyst::PPCAnalyzer::OPTION_CONDITIONAL_CONTINUE); code_block.m_stats = &st; code_block.m_gpa = &gpa; code_block.m_fpa = &fpa; if (analyzer.Analyze(ppc_addr, &code_block, &code_buffer, 32000) != 0xFFFFFFFF) { std::ostringstream ppc_disasm; for (u32 i = 0; i < code_block.m_num_instructions; i++) { const PPCAnalyst::CodeOp& op = code_buffer.codebuffer[i]; std::string opcode = GekkoDisassembler::Disassemble(op.inst.hex, op.address); ppc_disasm << std::setfill('0') << std::setw(8) << std::hex << op.address; ppc_disasm << " " << opcode << std::endl; } // Add stats to the end of the ppc box since it's generally the shortest. ppc_disasm << std::dec << std::endl; // Add some generic analysis if (st.isFirstBlockOfFunction) ppc_disasm << "(first block of function)" << std::endl; if (st.isLastBlockOfFunction) ppc_disasm << "(last block of function)" << std::endl; ppc_disasm << st.numCycles << " estimated cycles" << std::endl; ppc_disasm << "Num instr: PPC: " << code_block.m_num_instructions << " x86: " << host_instructions_count << " (blowup: " << 100 * host_instructions_count / code_block.m_num_instructions - 100 << "%)" << std::endl; ppc_disasm << "Num bytes: PPC: " << code_block.m_num_instructions * 4 << " x86: " << host_code_size << " (blowup: " << 100 * host_code_size / (4 * code_block.m_num_instructions) - 100 << "%)" << std::endl; ppc_box->SetValue(ppc_disasm.str()); } else { ppc_box->SetValue(StringFromFormat("(non-code address: %08x)", em_address)); x86_box->SetValue("---"); } }