const char *MIPSDebugInterface::disasm(unsigned int address, unsigned int align) { MIPSState *x = currentCPU; currentCPU = cpu; static char mojs[256]; if (Memory::IsValidAddress(address)) MIPSDisAsm(Memory::Read_Opcode_JIT(address), address, mojs); else strcpy(mojs, "-"); currentCPU = x; return mojs; }
bool TestJit() { SetupJitHarness(); currentMIPS->pc = PSP_GetUserMemoryBase(); u32 *p = (u32 *)Memory::GetPointer(currentMIPS->pc); // TODO: Smarter way of seeding in the code sequence. static const char *lines[] = { //"vcrsp.t C000, C100, C200", //"vdot.q C000, C100, C200", //"vmmul.q M000, M100, M200", "lui r1, 0x8910", "vmmul.q M000, M100, M200", "sv.q C000, 0(r1)", "sv.q C000, 16(r1)", "sv.q C000, 32(r1)", "sv.q C000, 48(r1)", /* "abs.s f1, f1", "cvt.w.s f1, f1", "cvt.w.s f3, f1", "cvt.w.s f0, f2", "cvt.w.s f5, f1", "cvt.w.s f6, f5", */ }; bool compileSuccess = true; u32 addr = currentMIPS->pc; DebugInterface *dbg = currentDebugMIPS; for (int i = 0; i < 100; ++i) { /* // VFPU ops aren't supported by MIPSAsm yet. *p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8); *p++ = 0xD03C0000 | (1 << 7) | (1 << 15); *p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8); *p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8); *p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8); *p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8); *p++ = 0xD03C0000 | (1 << 7) | (1 << 15) | (7 << 8); */ for (size_t j = 0; j < ARRAY_SIZE(lines); ++j) { p++; if (!MIPSAsm::MipsAssembleOpcode(lines[j], currentDebugMIPS, addr)) { printf("ERROR: %ls\n", MIPSAsm::GetAssembleError().c_str()); compileSuccess = false; } addr += 4; } } *p++ = MIPS_MAKE_SYSCALL("UnitTestFakeSyscalls", "UnitTestTerminator"); *p++ = MIPS_MAKE_BREAK(1); // Dogfood. addr = currentMIPS->pc; for (size_t j = 0; j < ARRAY_SIZE(lines); ++j) { char line[512]; MIPSDisAsm(Memory::Read_Instruction(addr), addr, line, true); addr += 4; printf("%s\n", line); } printf("\n"); double jit_speed = 0.0, interp_speed = 0.0; if (compileSuccess) { interp_speed = ExecCPUTest(); mipsr4k.UpdateCore(CPUCore::JIT); jit_speed = ExecCPUTest(); // Disassemble JitBlockCache *cache = MIPSComp::jit->GetBlockCache(); JitBlock *block = cache->GetBlock(0); // Should only be one block. #if defined(ARM) std::vector<std::string> lines = DisassembleArm2(block->normalEntry, block->codeSize); #elif defined(ARM64) std::vector<std::string> lines = DisassembleArm64(block->normalEntry, block->codeSize); #else std::vector<std::string> lines = DisassembleX86(block->normalEntry, block->codeSize); #endif // Cut off at 25 due to the repetition above. Might need tweaking for large instructions. const int cutoff = 25; for (int i = 0; i < std::min((int)lines.size(), cutoff); i++) { printf("%s\n", lines[i].c_str()); } if (lines.size() > cutoff) printf("...\n"); printf("Jit was %fx faster than interp.\n\n", jit_speed / interp_speed); } printf("\n"); DestroyJitHarness(); return jit_speed >= interp_speed; }