void CRandomAluTest3::Compile(Jitter::CJitter& jitter)
{
	Framework::CMemStream codeStream;
	jitter.SetStream(&codeStream);

	jitter.Begin();
	{
		//a = b ^ a
		if(m_useConstant)
		{
			jitter.PushCst(TEST_NUMBER1);
		}
		else
		{
			jitter.PushRel(offsetof(CONTEXT, number1));
		}

		if(m_useConstant)
		{
			jitter.PushCst(TEST_NUMBER2);
		}
		else
		{
			jitter.PushRel(offsetof(CONTEXT, number2));
		}

		jitter.Xor();

		//b = a

		jitter.PullRel(offsetof(CONTEXT, number1));

		jitter.PushRel(offsetof(CONTEXT, number1));
		jitter.PullRel(offsetof(CONTEXT, number2));
	}
	jitter.End();

	m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize());
}
Esempio n. 2
0
void CMdFpFlagTest::Compile(Jitter::CJitter& jitter)
{
	Framework::CMemStream codeStream;
	jitter.SetStream(&codeStream);

	jitter.Begin();
	{
		//0
		jitter.MD_PushRel(offsetof(CONTEXT, src0));
		jitter.MD_IsNegative();
		jitter.PullRel(offsetof(CONTEXT, dstIsNegative0));

		jitter.MD_PushRel(offsetof(CONTEXT, src0));
		jitter.MD_IsZero();
		jitter.PullRel(offsetof(CONTEXT, dstIsZero0));

		//1
		jitter.MD_PushRel(offsetof(CONTEXT, src1));
		jitter.MD_IsNegative();
		jitter.PullRel(offsetof(CONTEXT, dstIsNegative1));

		jitter.MD_PushRel(offsetof(CONTEXT, src1));
		jitter.MD_IsZero();
		jitter.PullRel(offsetof(CONTEXT, dstIsZero1));

		//2
		jitter.MD_PushRel(offsetof(CONTEXT, src2));
		jitter.MD_IsNegative();
		jitter.PullRel(offsetof(CONTEXT, dstIsNegative2));

		jitter.MD_PushRel(offsetof(CONTEXT, src2));
		jitter.MD_IsZero();
		jitter.PullRel(offsetof(CONTEXT, dstIsZero2));
	}
	jitter.End();

	m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize());
}
Esempio n. 3
0
void CAliasTest::Compile(Jitter::CJitter& jitter)
{
	Framework::CMemStream codeStream;
	jitter.SetStream(&codeStream);

	jitter.Begin();
	{
		jitter.PushCst64(0);
		jitter.PullRel64(offsetof(CONTEXT, value0));

		jitter.PushCst(CONSTANT_1);
		jitter.PullRel(offsetof(CONTEXT, value0[0]));

		jitter.PushCst(CONSTANT_2);
		jitter.PullRel(offsetof(CONTEXT, value0[1]));

		jitter.PushRel64(offsetof(CONTEXT, value0));
		jitter.PushRel64(offsetof(CONTEXT, value1));
		jitter.Cmp64(Jitter::CONDITION_EQ);
		jitter.PullRel(offsetof(CONTEXT, result));

		for(unsigned int i = 0; i < 4; i++)
		{
			jitter.PushCst(0);
			jitter.PullRel(offsetof(CONTEXT, value4[i]));
		}

		jitter.MD_PushRel(offsetof(CONTEXT, value2));
		jitter.MD_PushRel(offsetof(CONTEXT, value3));
		jitter.MD_AddWSS();
		jitter.MD_PullRel(offsetof(CONTEXT, value4), true, false, false, true);
	}
	jitter.End();

	m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize());
}
Esempio n. 4
0
void CBasicBlock::Compile()
{
#ifndef AOT_USE_CACHE

	Framework::CMemStream stream;
	{
		static
#ifdef AOT_BUILD_CACHE
		    __declspec(thread)
#endif
		        CMipsJitter* jitter = nullptr;
		if(jitter == nullptr)
		{
			Jitter::CCodeGen* codeGen = Jitter::CreateCodeGen();
			jitter = new CMipsJitter(codeGen);

			for(unsigned int i = 0; i < 4; i++)
			{
				jitter->SetVariableAsConstant(
				    offsetof(CMIPS, m_State.nGPR[CMIPS::R0].nV[i]),
				    0);
			}
		}

		jitter->SetStream(&stream);
		jitter->Begin();
		CompileRange(jitter);
		//		codeGen.DumpVariables(0);
		//		codeGen.EndQuota();
		jitter->End();
	}

	m_function = CMemoryFunction(stream.GetBuffer(), stream.GetSize());

#ifdef VTUNE_ENABLED
	if(iJIT_IsProfilingActive() == iJIT_SAMPLING_ON)
	{
		iJIT_Method_Load jmethod = {};
		jmethod.method_id = iJIT_GetNewMethodID();
		jmethod.class_file_name = "";
		jmethod.source_file_name = __FILE__;

		jmethod.method_load_address = m_function.GetCode();
		jmethod.method_size = m_function.GetSize();
		jmethod.line_number_size = 0;

		auto functionName = string_format("BasicBlock_0x%08X_0x%08X", m_begin, m_end);

		jmethod.method_name = const_cast<char*>(functionName.c_str());
		iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, reinterpret_cast<void*>(&jmethod));
	}
#endif

#endif

#ifdef AOT_ENABLED

	size_t blockSize = ((m_end - m_begin) / 4) + 1;
	auto blockData = new uint32[blockSize];

	for(uint32 i = 0; i < blockSize; i++)
	{
		blockData[i] = m_context.m_pMemoryMap->GetWord(m_begin + (i * 4));
	}

	uint32 blockChecksum = crc32(0, reinterpret_cast<Bytef*>(blockData), blockSize * 4);

#endif

#ifdef AOT_USE_CACHE

	AOT_BLOCK* blocksBegin = &_aot_firstBlock;
	AOT_BLOCK* blocksEnd = blocksBegin + _aot_blockCount;

	AOT_BLOCK blockRef = {blockChecksum, m_begin, m_end, nullptr};

	static const auto blockComparer =
	    [](const AOT_BLOCK& item1, const AOT_BLOCK& item2) {
		    return item1.key < item2.key;
	    };

	//	assert(std::is_sorted(blocksBegin, blocksEnd, blockComparer));

	bool blockExists = std::binary_search(blocksBegin, blocksEnd, blockRef, blockComparer);
	auto blockIterator = std::lower_bound(blocksBegin, blocksEnd, blockRef, blockComparer);

	assert(blockExists);
	assert(blockIterator != blocksEnd);
	assert(blockIterator->key.crc == blockChecksum);
	assert(blockIterator->key.begin == m_begin);
	assert(blockIterator->key.end == m_end);

	m_function = reinterpret_cast<void (*)(void*)>(blockIterator->fct);

#endif

#ifdef AOT_BUILD_CACHE
	{
		std::lock_guard<std::mutex> lock(m_aotBlockOutputStreamMutex);

		m_aotBlockOutputStream->Write32(blockChecksum);
		m_aotBlockOutputStream->Write32(m_begin);
		m_aotBlockOutputStream->Write32(m_end);
		m_aotBlockOutputStream->Write(blockData, blockSize * 4);
	}
#endif
}
Esempio n. 5
0
void Compile(const char* databasePathName, const char* cpuArchName, const char* imageFormatName, const char* outputPath)
{
	CPsfVm virtualMachine;
	auto subSystem = std::make_shared<Iop::CPsfSubSystem>(false);
	virtualMachine.SetSubSystem(subSystem);

	Jitter::CCodeGen* codeGen = nullptr;
	Jitter::CObjectFile::CPU_ARCH cpuArch = Jitter::CObjectFile::CPU_ARCH_X86;
	if(!strcmp(cpuArchName, "x86"))
	{
		codeGen = new Jitter::CCodeGen_x86_32();
		cpuArch = Jitter::CObjectFile::CPU_ARCH_X86;
	}
	else if(!strcmp(cpuArchName, "arm"))
	{
		codeGen = new Jitter::CCodeGen_Arm();
		cpuArch = Jitter::CObjectFile::CPU_ARCH_ARM;
	}
	else
	{
		throw std::runtime_error("Invalid cpu target.");
	}

	std::unique_ptr<Jitter::CObjectFile> objectFile;
	if(!strcmp(imageFormatName, "coff"))
	{
		objectFile = std::make_unique<Jitter::CCoffObjectFile>(cpuArch);
	}
	else if(!strcmp(imageFormatName, "macho"))
	{
		objectFile = std::make_unique<Jitter::CMachoObjectFile>(cpuArch);
	}
	else
	{
		throw std::runtime_error("Invalid executable image type (must be coff or macho).");
	}

	codeGen->RegisterExternalSymbols(objectFile.get());
	objectFile->AddExternalSymbol("_MemoryUtils_GetByteProxy", &MemoryUtils_GetByteProxy);
	objectFile->AddExternalSymbol("_MemoryUtils_GetHalfProxy", &MemoryUtils_GetHalfProxy);
	objectFile->AddExternalSymbol("_MemoryUtils_GetWordProxy", &MemoryUtils_GetWordProxy);
	objectFile->AddExternalSymbol("_MemoryUtils_SetByteProxy", &MemoryUtils_SetByteProxy);
	objectFile->AddExternalSymbol("_MemoryUtils_SetHalfProxy", &MemoryUtils_SetHalfProxy);
	objectFile->AddExternalSymbol("_MemoryUtils_SetWordProxy", &MemoryUtils_SetWordProxy);
	objectFile->AddExternalSymbol("_LWL_Proxy", &LWL_Proxy);
	objectFile->AddExternalSymbol("_LWR_Proxy", &LWR_Proxy);
	objectFile->AddExternalSymbol("_SWL_Proxy", &SWL_Proxy);
	objectFile->AddExternalSymbol("_SWR_Proxy", &SWR_Proxy);

	filesystem::path databasePath(databasePathName);
	auto blocks = GetBlocksFromCache(databasePath);

	//Initialize Jitter Service
	auto jitter = new CMipsJitter(codeGen);
	for(unsigned int i = 0; i < 4; i++)
	{
		jitter->SetVariableAsConstant(
			offsetof(CMIPS, m_State.nGPR[CMIPS::R0].nV[i]),
			0
			);
	}

	printf("Got %d blocks to compile.\r\n", blocks.size());

	FunctionTable functionTable;
	functionTable.reserve(blocks.size());

	for(const auto& blockCachePair : blocks)
	{
		const auto& blockKey = blockCachePair.first;

		auto functionName = "aotblock_" + std::to_string(blockKey.crc) + "_" + std::to_string(blockKey.begin) + "_" + std::to_string(blockKey.end);

		unsigned int functionSymbolIndex = CompileFunction(virtualMachine, jitter, blockCachePair.second, *objectFile, functionName, blockKey.begin, blockKey.end);

		FUNCTION_TABLE_ITEM tableItem = { blockKey, functionSymbolIndex };
		functionTable.push_back(tableItem);
	}

	std::sort(functionTable.begin(), functionTable.end(), 
		[] (const FUNCTION_TABLE_ITEM& item1, const FUNCTION_TABLE_ITEM& item2)
		{
			return item1.key < item2.key;
		}
	);

	{
		Framework::CMemStream blockTableStream;
		Jitter::CObjectFile::INTERNAL_SYMBOL blockTableSymbol;
		blockTableSymbol.name		= "__aot_firstBlock";
		blockTableSymbol.location	= Jitter::CObjectFile::INTERNAL_SYMBOL_LOCATION_DATA;

		for(const auto& functionTableItem : functionTable)
		{
			blockTableStream.Write32(functionTableItem.key.crc);
			blockTableStream.Write32(functionTableItem.key.begin);
			blockTableStream.Write32(functionTableItem.key.end);
			
			{
				Jitter::CObjectFile::SYMBOL_REFERENCE ref;
				ref.offset		= static_cast<uint32>(blockTableStream.Tell());
				ref.type		= Jitter::CObjectFile::SYMBOL_TYPE_INTERNAL;
				ref.symbolIndex	= functionTableItem.symbolIndex;
				blockTableSymbol.symbolReferences.push_back(ref);
			}

			blockTableStream.Write32(0);
		}

		blockTableSymbol.data = std::vector<uint8>(blockTableStream.GetBuffer(), blockTableStream.GetBuffer() + blockTableStream.GetLength());
		objectFile->AddInternalSymbol(blockTableSymbol);
	}

	{
		Jitter::CObjectFile::INTERNAL_SYMBOL blockCountSymbol;
		blockCountSymbol.name		= "__aot_blockCount";
		blockCountSymbol.location	= Jitter::CObjectFile::INTERNAL_SYMBOL_LOCATION_DATA;
		blockCountSymbol.data		= std::vector<uint8>(4);
		*reinterpret_cast<uint32*>(blockCountSymbol.data.data()) = functionTable.size();
		objectFile->AddInternalSymbol(blockCountSymbol);
	}

	objectFile->Write(Framework::CStdStream(outputPath, "wb"));
}
Esempio n. 6
0
void CCmp64Test::Compile(Jitter::CJitter& jitter)
{
	Framework::CMemStream codeStream;
	jitter.SetStream(&codeStream);

	jitter.Begin();
	{
		//Equal
		//---------------------------------
		jitter.PushRel64(offsetof(CONTEXT, value0));
		if(m_useConstant)
		{
			jitter.PushCst64(m_value1);
		}
		else
		{
			jitter.PushRel64(offsetof(CONTEXT, value1));
		}
		jitter.Cmp64(Jitter::CONDITION_EQ);
		jitter.PullRel(offsetof(CONTEXT, resultEq));

		//Not Equal
		//---------------------------------
		jitter.PushRel64(offsetof(CONTEXT, value0));
		if(m_useConstant)
		{
			jitter.PushCst64(m_value1);
		}
		else
		{
			jitter.PushRel64(offsetof(CONTEXT, value1));
		}
		jitter.Cmp64(Jitter::CONDITION_NE);
		jitter.PullRel(offsetof(CONTEXT, resultNe));

		//Less Than (unsigned)
		//---------------------------------
		jitter.PushRel64(offsetof(CONTEXT, value0));
		if(m_useConstant)
		{
			jitter.PushCst64(m_value1);
		}
		else
		{
			jitter.PushRel64(offsetof(CONTEXT, value1));
		}
		jitter.Cmp64(Jitter::CONDITION_BL);
		jitter.PullRel(offsetof(CONTEXT, resultBl));

		//Less Than (signed)
		//---------------------------------
		jitter.PushRel64(offsetof(CONTEXT, value0));
		if(m_useConstant)
		{
			jitter.PushCst64(m_value1);
		}
		else
		{
			jitter.PushRel64(offsetof(CONTEXT, value1));
		}
		jitter.Cmp64(Jitter::CONDITION_LT);
		jitter.PullRel(offsetof(CONTEXT, resultLt));

		//Less Equal (signed)
		//---------------------------------
		jitter.PushRel64(offsetof(CONTEXT, value0));
		if(m_useConstant)
		{
			jitter.PushCst64(m_value1);
		}
		else
		{
			jitter.PushRel64(offsetof(CONTEXT, value1));
		}
		jitter.Cmp64(Jitter::CONDITION_LE);
		jitter.PullRel(offsetof(CONTEXT, resultLe));

		//Greater Than (unsigned)
		//---------------------------------
		jitter.PushRel64(offsetof(CONTEXT, value0));
		if(m_useConstant)
		{
			jitter.PushCst64(m_value1);
		}
		else
		{
			jitter.PushRel64(offsetof(CONTEXT, value1));
		}
		jitter.Cmp64(Jitter::CONDITION_AB);
		jitter.PullRel(offsetof(CONTEXT, resultAb));

		//Greater Than (signed)
		//---------------------------------
		jitter.PushRel64(offsetof(CONTEXT, value0));
		if(m_useConstant)
		{
			jitter.PushCst64(m_value1);
		}
		else
		{
			jitter.PushRel64(offsetof(CONTEXT, value1));
		}
		jitter.Cmp64(Jitter::CONDITION_GT);
		jitter.PullRel(offsetof(CONTEXT, resultGt));
	}
	jitter.End();

	m_function = CMemoryFunction(codeStream.GetBuffer(), codeStream.GetSize());
}