Example #1
0
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;
}
Example #2
0
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("---");
  }
}