Пример #1
0
void ARMv7Thread::task()
{
	if (custom_task)
	{
		if (check_status()) return;

		return custom_task(*this);
	}

	while (!m_state || !check_status())
	{
		// decode instruction using specified decoder
		PC += m_dec->DecodeMemory(PC);
	}
}
Пример #2
0
void SPUThread::task()
{
	std::fesetround(FE_TOWARDZERO);

	if (!custom_task && !m_dec)
	{
		// Select opcode table (TODO)
		const auto& table = Ini.SPUDecoderMode.GetValue() == 0 ? spu_interpreter::precise::g_spu_opcode_table : spu_interpreter::fast::g_spu_opcode_table;

		// LS base address
		const auto base = vm::get_ptr<const be_t<u32>>(offset);

		while (true)
		{
			if (!m_state.load())
			{
				// read opcode
				const u32 opcode = base[pc / 4];

				// call interpreter function
				table[opcode](*this, { opcode });

				// next instruction
				pc += 4;

				continue;
			}

			if (check_status())
			{
				return;
			}
		}
	}

	if (custom_task)
	{
		if (check_status()) return;

		return custom_task(*this);
	}

	while (!m_state.load() || !check_status())
	{
		// decode instruction using specified decoder
		pc += m_dec->DecodeMemory(pc + offset);
	}
}
Пример #3
0
void PPUThread::task()
{
	SetHostRoundingMode(FPSCR_RN_NEAR);

	if (custom_task)
	{
		if (check_status()) return;

		return custom_task(*this);
	}

	if (m_dec)
	{
		while (true)
		{
			if (m_state.load() && check_status()) break;

			// decode instruction using specified decoder
			m_dec->DecodeMemory(PC);

			// next instruction
			PC += 4;
		}
	}
	else
	{
		while (true)
		{
			if (m_state.load() && check_status()) break;

			// get interpreter function
			const auto func = g_ppu_inter_func_list[*(u32*)((u8*)g_ppu_exec_map + PC)];

			// read opcode
			const ppu_opcode_t opcode = { vm::read32(PC) };

			// call interpreter function
			func(*this, opcode);

			// next instruction
			PC += 4;
		}
	}
}
Пример #4
0
void PPUThread::cpu_task()
{
	//SetHostRoundingMode(FPSCR_RN_NEAR);

	if (custom_task)
	{
		if (check_status()) return;

		return custom_task(*this);
	}

	g_tls_log_prefix = []
	{
		const auto cpu = static_cast<PPUThread*>(get_current_cpu_thread());

		return fmt::format("%s [0x%08x]", cpu->get_name(), cpu->pc);
	};

	const auto base = vm::_ptr<const u8>(0);

	// Select opcode table
	const auto& table = *(
		g_cfg_ppu_decoder.get() == ppu_decoder_type::precise ? &s_ppu_interpreter_precise.get_table() :
		g_cfg_ppu_decoder.get() == ppu_decoder_type::fast ? &s_ppu_interpreter_fast.get_table() :
		throw std::logic_error("Invalid PPU decoder"));

	v128 _op;
	decltype(&ppu_interpreter::UNK) func0, func1, func2, func3;

	while (true)
	{
		if (UNLIKELY(state.load()))
		{
			if (check_status()) return;
		}

		// Reinitialize
		{
			const auto _ops = _mm_shuffle_epi8(_mm_lddqu_si128(reinterpret_cast<const __m128i*>(base + pc)), _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3));
			_op.vi = _ops;
			const v128 _i = v128::fromV(_mm_and_si128(_mm_or_si128(_mm_slli_epi32(_op.vi, 6), _mm_srli_epi32(_op.vi, 26)), _mm_set1_epi32(0x1ffff)));
			func0 = table[_i._u32[0]];
			func1 = table[_i._u32[1]];
			func2 = table[_i._u32[2]];
			func3 = table[_i._u32[3]];
		}

		while (LIKELY(func0(*this, { _op._u32[0] })))
		{
			if (pc += 4, LIKELY(func1(*this, { _op._u32[1] })))
			{
				if (pc += 4, LIKELY(func2(*this, { _op._u32[2] })))
				{
					pc += 4;
					func0 = func3;

					const auto _ops = _mm_shuffle_epi8(_mm_lddqu_si128(reinterpret_cast<const __m128i*>(base + pc + 4)), _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3));
					_op.vi = _mm_alignr_epi8(_ops, _op.vi, 12);
					const v128 _i = v128::fromV(_mm_and_si128(_mm_or_si128(_mm_slli_epi32(_op.vi, 6), _mm_srli_epi32(_op.vi, 26)), _mm_set1_epi32(0x1ffff)));
					func1 = table[_i._u32[1]];
					func2 = table[_i._u32[2]];
					func3 = table[_i._u32[3]];

					if (UNLIKELY(state.load()))
					{
						break;
					}
					continue;
				}
				break;
			}
			break;
		}
	}
}