Example #1
0
HLEHelperThread::HLEHelperThread(const char *threadName, const char *module, const char *func, u32 prio, int stacksize) {
	const u32 bytes = sizeof(u32) * 2;
	AllocEntry(bytes);
	Memory::Write_U32(MIPS_MAKE_JR_RA(), entry_ + 0);
	Memory::Write_U32(MIPS_MAKE_SYSCALL(module, func), entry_ + 4);

	Create(threadName, prio, stacksize);
}
Example #2
0
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;
}