mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
JitIL: Implemented JitIL IR Disassembler. If you want to use it, add "OutputIR = True" in the "Core" section of Dolphin.ini.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6462 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -282,7 +282,8 @@ void SConfig::LoadSettings()
|
|||||||
ini.Get("Core", "SlotB", (int*)&m_EXIDevice[1], EXIDEVICE_MEMORYCARD_B);
|
ini.Get("Core", "SlotB", (int*)&m_EXIDevice[1], EXIDEVICE_MEMORYCARD_B);
|
||||||
ini.Get("Core", "SerialPort1", (int*)&m_EXIDevice[2], EXIDEVICE_NONE);
|
ini.Get("Core", "SerialPort1", (int*)&m_EXIDevice[2], EXIDEVICE_NONE);
|
||||||
ini.Get("Core", "ProfiledReJIT",&m_LocalCoreStartupParameter.bJITProfiledReJIT, false);
|
ini.Get("Core", "ProfiledReJIT",&m_LocalCoreStartupParameter.bJITProfiledReJIT, false);
|
||||||
ini.Get("Core", "TimeProfiling",&m_LocalCoreStartupParameter.bJITILTimeProfiling, false);
|
ini.Get("Core", "TimeProfiling",&m_LocalCoreStartupParameter.bJITILTimeProfiling, false);
|
||||||
|
ini.Get("Core", "OutputIR", &m_LocalCoreStartupParameter.bJITILOutputIR, false);
|
||||||
char sidevicenum[16];
|
char sidevicenum[16];
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ SCoreStartupParameter::SCoreStartupParameter()
|
|||||||
bJITFloatingPointOff(false), bJITIntegerOff(false),
|
bJITFloatingPointOff(false), bJITIntegerOff(false),
|
||||||
bJITPairedOff(false), bJITSystemRegistersOff(false),
|
bJITPairedOff(false), bJITSystemRegistersOff(false),
|
||||||
bJITBranchOff(false), bJITProfiledReJIT(false),
|
bJITBranchOff(false), bJITProfiledReJIT(false),
|
||||||
bJITILTimeProfiling(false),
|
bJITILTimeProfiling(false), bJITILOutputIR(false),
|
||||||
bEnableFPRF(false),
|
bEnableFPRF(false),
|
||||||
bCPUThread(true), bDSPThread(false),
|
bCPUThread(true), bDSPThread(false),
|
||||||
bSkipIdle(true), bNTSC(false), bNTSCJ(false),
|
bSkipIdle(true), bNTSC(false), bNTSCJ(false),
|
||||||
|
@ -63,6 +63,7 @@ struct SCoreStartupParameter
|
|||||||
bool bJITBranchOff;
|
bool bJITBranchOff;
|
||||||
bool bJITProfiledReJIT;
|
bool bJITProfiledReJIT;
|
||||||
bool bJITILTimeProfiling;
|
bool bJITILTimeProfiling;
|
||||||
|
bool bJITILOutputIR;
|
||||||
|
|
||||||
bool bEnableFPRF;
|
bool bEnableFPRF;
|
||||||
|
|
||||||
|
@ -146,6 +146,7 @@ namespace IREmitter {
|
|||||||
InstLoc IRBuilder::EmitZeroOp(unsigned Opcode, unsigned extra = 0) {
|
InstLoc IRBuilder::EmitZeroOp(unsigned Opcode, unsigned extra = 0) {
|
||||||
InstLoc curIndex = &InstList[InstList.size()];
|
InstLoc curIndex = &InstList[InstList.size()];
|
||||||
InstList.push_back(Opcode | (extra << 8));
|
InstList.push_back(Opcode | (extra << 8));
|
||||||
|
MarkUsed.push_back(false);
|
||||||
return curIndex;
|
return curIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,10 +155,12 @@ InstLoc IRBuilder::EmitUOp(unsigned Opcode, InstLoc Op1, unsigned extra) {
|
|||||||
unsigned backOp1 = (s32)(curIndex - 1 - Op1);
|
unsigned backOp1 = (s32)(curIndex - 1 - Op1);
|
||||||
if (backOp1 >= 256) {
|
if (backOp1 >= 256) {
|
||||||
InstList.push_back(Tramp | backOp1 << 8);
|
InstList.push_back(Tramp | backOp1 << 8);
|
||||||
|
MarkUsed.push_back(false);
|
||||||
backOp1 = 0;
|
backOp1 = 0;
|
||||||
curIndex++;
|
curIndex++;
|
||||||
}
|
}
|
||||||
InstList.push_back(Opcode | (backOp1 << 8) | (extra << 16));
|
InstList.push_back(Opcode | (backOp1 << 8) | (extra << 16));
|
||||||
|
MarkUsed.push_back(false);
|
||||||
return curIndex;
|
return curIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,17 +169,20 @@ InstLoc IRBuilder::EmitBiOp(unsigned Opcode, InstLoc Op1, InstLoc Op2, unsigned
|
|||||||
unsigned backOp1 = (s32)(curIndex - 1 - Op1);
|
unsigned backOp1 = (s32)(curIndex - 1 - Op1);
|
||||||
if (backOp1 >= 255) {
|
if (backOp1 >= 255) {
|
||||||
InstList.push_back(Tramp | backOp1 << 8);
|
InstList.push_back(Tramp | backOp1 << 8);
|
||||||
|
MarkUsed.push_back(false);
|
||||||
backOp1 = 0;
|
backOp1 = 0;
|
||||||
curIndex++;
|
curIndex++;
|
||||||
}
|
}
|
||||||
unsigned backOp2 = (s32)(curIndex - 1 - Op2);
|
unsigned backOp2 = (s32)(curIndex - 1 - Op2);
|
||||||
if (backOp2 >= 256) {
|
if (backOp2 >= 256) {
|
||||||
InstList.push_back(Tramp | backOp2 << 8);
|
InstList.push_back(Tramp | backOp2 << 8);
|
||||||
|
MarkUsed.push_back(false);
|
||||||
backOp2 = 0;
|
backOp2 = 0;
|
||||||
backOp1++;
|
backOp1++;
|
||||||
curIndex++;
|
curIndex++;
|
||||||
}
|
}
|
||||||
InstList.push_back(Opcode | (backOp1 << 8) | (backOp2 << 16) | (extra << 24));
|
InstList.push_back(Opcode | (backOp1 << 8) | (backOp2 << 16) | (extra << 24));
|
||||||
|
MarkUsed.push_back(false);
|
||||||
return curIndex;
|
return curIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,12 +192,14 @@ InstLoc IRBuilder::EmitTriOp(unsigned Opcode, InstLoc Op1, InstLoc Op2, InstLoc
|
|||||||
unsigned backOp1 = curIndex - 1 - Op1;
|
unsigned backOp1 = curIndex - 1 - Op1;
|
||||||
if (backOp1 >= 254) {
|
if (backOp1 >= 254) {
|
||||||
InstList.push_back(Tramp | backOp1 << 8);
|
InstList.push_back(Tramp | backOp1 << 8);
|
||||||
|
MarkUsed.push_back(false);
|
||||||
backOp1 = 0;
|
backOp1 = 0;
|
||||||
curIndex++;
|
curIndex++;
|
||||||
}
|
}
|
||||||
unsigned backOp2 = curIndex - 1 - Op2;
|
unsigned backOp2 = curIndex - 1 - Op2;
|
||||||
if (backOp2 >= 255) {
|
if (backOp2 >= 255) {
|
||||||
InstList.push_back((Tramp | backOp2 << 8));
|
InstList.push_back((Tramp | backOp2 << 8));
|
||||||
|
MarkUsed.push_back(false);
|
||||||
backOp2 = 0;
|
backOp2 = 0;
|
||||||
backOp1++;
|
backOp1++;
|
||||||
curIndex++;
|
curIndex++;
|
||||||
@ -199,12 +207,14 @@ InstLoc IRBuilder::EmitTriOp(unsigned Opcode, InstLoc Op1, InstLoc Op2, InstLoc
|
|||||||
unsigned backOp3 = curIndex - 1 - Op3;
|
unsigned backOp3 = curIndex - 1 - Op3;
|
||||||
if (backOp3 >= 256) {
|
if (backOp3 >= 256) {
|
||||||
InstList.push_back(Tramp | (backOp3 << 8));
|
InstList.push_back(Tramp | (backOp3 << 8));
|
||||||
|
MarkUsed.push_back(false);
|
||||||
backOp3 = 0;
|
backOp3 = 0;
|
||||||
backOp2++;
|
backOp2++;
|
||||||
backOp1++;
|
backOp1++;
|
||||||
curIndex++;
|
curIndex++;
|
||||||
}
|
}
|
||||||
InstList.push_back(Opcode | (backOp1 << 8) | (backOp2 << 16) | (backOp3 << 24));
|
InstList.push_back(Opcode | (backOp1 << 8) | (backOp2 << 16) | (backOp3 << 24));
|
||||||
|
MarkUsed.push_back(false);
|
||||||
return curIndex;
|
return curIndex;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1054,6 +1064,7 @@ InstLoc IRBuilder::FoldBiOp(unsigned Opcode, InstLoc Op1, InstLoc Op2, unsigned
|
|||||||
InstLoc IRBuilder::EmitIntConst(unsigned value) {
|
InstLoc IRBuilder::EmitIntConst(unsigned value) {
|
||||||
InstLoc curIndex = &InstList[InstList.size()];
|
InstLoc curIndex = &InstList[InstList.size()];
|
||||||
InstList.push_back(CInt32 | ((unsigned int)ConstList.size() << 8));
|
InstList.push_back(CInt32 | ((unsigned int)ConstList.size() << 8));
|
||||||
|
MarkUsed.push_back(false);
|
||||||
ConstList.push_back(value);
|
ConstList.push_back(value);
|
||||||
return curIndex;
|
return curIndex;
|
||||||
}
|
}
|
||||||
@ -1062,6 +1073,16 @@ unsigned IRBuilder::GetImmValue(InstLoc I) const {
|
|||||||
return ConstList[*I >> 8];
|
return ConstList[*I >> 8];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IRBuilder::SetMarkUsed(InstLoc I) {
|
||||||
|
const unsigned i = (unsigned)(I - &InstList[0]);
|
||||||
|
MarkUsed[i] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IRBuilder::IsMarkUsed(InstLoc I) const {
|
||||||
|
const unsigned i = (unsigned)(I - &InstList[0]);
|
||||||
|
return MarkUsed[i];
|
||||||
|
}
|
||||||
|
|
||||||
unsigned IRBuilder::isSameValue(InstLoc Op1, InstLoc Op2) const {
|
unsigned IRBuilder::isSameValue(InstLoc Op1, InstLoc Op2) const {
|
||||||
if (Op1 == Op2) {
|
if (Op1 == Op2) {
|
||||||
return true;
|
return true;
|
||||||
@ -1200,4 +1221,138 @@ InstLoc IRBuilder::isNeg(InstLoc I) const {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Move the following code to a separated file.
|
||||||
|
struct Writer {
|
||||||
|
FILE* file;
|
||||||
|
Writer() : file(NULL) {
|
||||||
|
char buffer[1024];
|
||||||
|
sprintf(buffer, "JitIL_IR_%d.txt", time(NULL));
|
||||||
|
file = fopen(buffer, "w");
|
||||||
|
setvbuf(file, NULL, _IOFBF, 1024 * 1024);
|
||||||
|
}
|
||||||
|
virtual ~Writer() {
|
||||||
|
if (file) {
|
||||||
|
fclose(file);
|
||||||
|
file = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static std::auto_ptr<Writer> writer;
|
||||||
|
|
||||||
|
static const std::string opcodeNames[] = {
|
||||||
|
"Nop", "LoadGReg", "LoadLink", "LoadCR", "LoadCarry", "LoadCTR",
|
||||||
|
"LoadMSR", "LoadGQR", "SExt8", "SExt16", "BSwap32", "BSwap16", "Cntlzw",
|
||||||
|
"Not", "Load8", "Load16", "Load32", "BranchUncond", "StoreGReg",
|
||||||
|
"StoreCR", "StoreLink", "StoreCarry", "StoreCTR", "StoreMSR", "StoreFPRF",
|
||||||
|
"StoreGQR", "StoreSRR", "InterpreterFallback", "Add", "Mul", "And", "Or",
|
||||||
|
"Xor", "MulHighUnsigned", "Sub", "Shl", "Shrl", "Sarl", "Rol",
|
||||||
|
"ICmpCRSigned", "ICmpCRUnsigned", "ICmpEq", "ICmpNe", "ICmpUgt",
|
||||||
|
"ICmpUlt", "ICmpUge", "ICmpUle", "ICmpSgt", "ICmpSlt", "ICmpSge",
|
||||||
|
"ICmpSle", "Store8", "Store16", "Store32", "BranchCond", "FResult_Start",
|
||||||
|
"LoadSingle", "LoadDouble", "LoadPaired", "DoubleToSingle",
|
||||||
|
"DupSingleToMReg", "DupSingleToPacked", "InsertDoubleInMReg",
|
||||||
|
"ExpandPackedToMReg", "CompactMRegToPacked", "LoadFReg",
|
||||||
|
"LoadFRegDENToZero", "FSMul", "FSAdd", "FSSub", "FSNeg", "FSRSqrt",
|
||||||
|
"FPAdd", "FPMul", "FPSub", "FPNeg", "FDMul", "FDAdd", "FDSub", "FDNeg",
|
||||||
|
"FPMerge00", "FPMerge01", "FPMerge10", "FPMerge11", "FPDup0", "FPDup1",
|
||||||
|
"FResult_End", "StorePaired", "StoreSingle", "StoreDouble", "StoreFReg",
|
||||||
|
"FDCmpCR", "CInt16", "CInt32", "SystemCall", "RFIExit",
|
||||||
|
"InterpreterBranch", "IdleBranch", "ShortIdleLoop",
|
||||||
|
"FPExceptionCheckStart", "FPExceptionCheckEnd", "ISIException", "Tramp",
|
||||||
|
"BlockStart", "BlockEnd", "Int3",
|
||||||
|
};
|
||||||
|
static const unsigned alwaysUsedList[] = {
|
||||||
|
InterpreterFallback, StoreGReg, StoreCR, StoreLink, StoreCTR, StoreMSR,
|
||||||
|
StoreGQR, StoreSRR, StoreCarry, StoreFPRF, Load8, Load16, Load32, Store8,
|
||||||
|
Store16, Store32, StoreSingle, StoreDouble, StorePaired, StoreFReg, FDCmpCR,
|
||||||
|
BlockStart, BlockEnd, IdleBranch, BranchCond, BranchUncond, ShortIdleLoop,
|
||||||
|
SystemCall, InterpreterBranch, RFIExit, FPExceptionCheckStart,
|
||||||
|
FPExceptionCheckEnd, ISIException, Int3, Tramp, Nop
|
||||||
|
};
|
||||||
|
static const unsigned extra8RegList[] = {
|
||||||
|
LoadGReg, LoadCR, LoadGQR, LoadFReg, LoadFRegDENToZero,
|
||||||
|
};
|
||||||
|
static const unsigned extra16RegList[] = {
|
||||||
|
StoreGReg, StoreCR, StoreGQR, StoreSRR, LoadPaired, StoreFReg,
|
||||||
|
};
|
||||||
|
static const unsigned extra24RegList[] = {
|
||||||
|
StorePaired,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::set<unsigned> alwaysUseds(alwaysUsedList, alwaysUsedList + sizeof(alwaysUsedList) / sizeof(alwaysUsedList[0]));
|
||||||
|
static const std::set<unsigned> extra8Regs(extra8RegList, extra8RegList + sizeof(extra8RegList) / sizeof(extra8RegList[0]));
|
||||||
|
static const std::set<unsigned> extra16Regs(extra16RegList, extra16RegList + sizeof(extra16RegList) / sizeof(extra16RegList[0]));
|
||||||
|
static const std::set<unsigned> extra24Regs(extra24RegList, extra24RegList + sizeof(extra24RegList) / sizeof(extra24RegList[0]));
|
||||||
|
|
||||||
|
void IRBuilder::WriteToFile(u64 codeHash) {
|
||||||
|
assert(sizeof(opcodeNames) / sizeof(opcodeNames[0]) == Int3 + 1);
|
||||||
|
|
||||||
|
if (!writer.get()) {
|
||||||
|
writer = std::auto_ptr<Writer>(new Writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* file = writer->file;
|
||||||
|
fprintf(file, "\ncode hash:%016llx\n", codeHash);
|
||||||
|
|
||||||
|
const InstLoc lastCurReadPtr = curReadPtr;
|
||||||
|
StartForwardPass();
|
||||||
|
const unsigned numInsts = getNumInsts();
|
||||||
|
for (int i = 0; i < numInsts; ++i) {
|
||||||
|
const InstLoc I = ReadForward();
|
||||||
|
const unsigned opcode = getOpcode(*I);
|
||||||
|
const bool thisUsed = IsMarkUsed(I) ||
|
||||||
|
alwaysUseds.find(opcode) != alwaysUseds.end();
|
||||||
|
|
||||||
|
// Line number
|
||||||
|
fprintf(file, "%4d", i);
|
||||||
|
|
||||||
|
if (!thisUsed) {
|
||||||
|
fprintf(file, "%*c", 32, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opcode
|
||||||
|
const std::string& opcodeName = opcodeNames[opcode];
|
||||||
|
fprintf(file, " %-20s", opcodeName.c_str());
|
||||||
|
const unsigned numberOfOperands = getNumberOfOperands(I);
|
||||||
|
|
||||||
|
// Op1
|
||||||
|
if (numberOfOperands >= 1) {
|
||||||
|
const IREmitter::InstLoc inst = getOp1(I);
|
||||||
|
if (isImm(*inst)) {
|
||||||
|
fprintf(file, " 0x%08x", GetImmValue(inst));
|
||||||
|
} else {
|
||||||
|
fprintf(file, " %10d", i - (I - inst));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Op2
|
||||||
|
if (numberOfOperands >= 2) {
|
||||||
|
const IREmitter::InstLoc inst = getOp2(I);
|
||||||
|
if (isImm(*inst)) {
|
||||||
|
fprintf(file, " 0x%08x", GetImmValue(inst));
|
||||||
|
} else {
|
||||||
|
fprintf(file, " %10d", i - (I - inst));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extra8Regs.count(opcode)) {
|
||||||
|
fprintf(file, " R%d", *I >> 8);
|
||||||
|
}
|
||||||
|
if (extra16Regs.count(opcode)) {
|
||||||
|
fprintf(file, " R%d", *I >> 16);
|
||||||
|
}
|
||||||
|
if (extra24Regs.count(opcode)) {
|
||||||
|
fprintf(file, " R%d", *I >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opcode == CInt32 || opcode == CInt16) {
|
||||||
|
fprintf(file, " 0x%08x", GetImmValue(I));
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(file, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
curReadPtr = lastCurReadPtr;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -544,10 +544,15 @@ public:
|
|||||||
unsigned int getNumInsts() { return (unsigned int)InstList.size(); }
|
unsigned int getNumInsts() { return (unsigned int)InstList.size(); }
|
||||||
unsigned int ReadInst(InstLoc I) { return *I; }
|
unsigned int ReadInst(InstLoc I) { return *I; }
|
||||||
unsigned int GetImmValue(InstLoc I) const;
|
unsigned int GetImmValue(InstLoc I) const;
|
||||||
|
void SetMarkUsed(InstLoc I);
|
||||||
|
bool IsMarkUsed(InstLoc I) const;
|
||||||
|
void WriteToFile(u64 codeHash);
|
||||||
|
|
||||||
void Reset() {
|
void Reset() {
|
||||||
InstList.clear();
|
InstList.clear();
|
||||||
InstList.reserve(100000);
|
InstList.reserve(100000);
|
||||||
|
MarkUsed.clear();
|
||||||
|
MarkUsed.reserve(100000);
|
||||||
for (unsigned i = 0; i < 32; i++) {
|
for (unsigned i = 0; i < 32; i++) {
|
||||||
GRegCache[i] = 0;
|
GRegCache[i] = 0;
|
||||||
GRegCacheStore[i] = 0;
|
GRegCacheStore[i] = 0;
|
||||||
@ -576,8 +581,8 @@ private:
|
|||||||
bool maskedValueIsZero(InstLoc Op1, InstLoc Op2) const;
|
bool maskedValueIsZero(InstLoc Op1, InstLoc Op2) const;
|
||||||
InstLoc isNeg(InstLoc I) const;
|
InstLoc isNeg(InstLoc I) const;
|
||||||
|
|
||||||
std::vector<Inst> InstList; // FIXME: We must ensure this is
|
std::vector<Inst> InstList; // FIXME: We must ensure this is continuous!
|
||||||
// continuous!
|
std::vector<bool> MarkUsed; // Used for IRWriter
|
||||||
std::vector<unsigned> ConstList;
|
std::vector<unsigned> ConstList;
|
||||||
InstLoc curReadPtr;
|
InstLoc curReadPtr;
|
||||||
InstLoc GRegCache[32];
|
InstLoc GRegCache[32];
|
||||||
|
@ -892,6 +892,11 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
|
|||||||
for (unsigned i = 0; i != RI.IInfo.size(); i++) {
|
for (unsigned i = 0; i != RI.IInfo.size(); i++) {
|
||||||
InstLoc I = ibuild->ReadForward();
|
InstLoc I = ibuild->ReadForward();
|
||||||
bool thisUsed = regReadUse(RI, I) ? true : false;
|
bool thisUsed = regReadUse(RI, I) ? true : false;
|
||||||
|
if (thisUsed) {
|
||||||
|
// Needed for IR Writer
|
||||||
|
ibuild->SetMarkUsed(I);
|
||||||
|
}
|
||||||
|
|
||||||
switch (getOpcode(*I)) {
|
switch (getOpcode(*I)) {
|
||||||
case InterpreterFallback: {
|
case InterpreterFallback: {
|
||||||
unsigned InstCode = ibuild->GetImmValue(getOp1(I));
|
unsigned InstCode = ibuild->GetImmValue(getOp1(I));
|
||||||
|
@ -582,15 +582,21 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|||||||
|
|
||||||
js.rewriteStart = (u8*)GetCodePtr();
|
js.rewriteStart = (u8*)GetCodePtr();
|
||||||
|
|
||||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
u64 codeHash = -1;
|
||||||
// For profiling
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling ||
|
||||||
u64 codeHash = -1;
|
SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILOutputIR)
|
||||||
|
{
|
||||||
|
// For profiling and IR Writer
|
||||||
for (int i = 0; i < (int)size; i++)
|
for (int i = 0; i < (int)size; i++)
|
||||||
{
|
{
|
||||||
const u64 inst = ops[i].inst.hex;
|
const u64 inst = ops[i].inst.hex;
|
||||||
// Ported from boost::hash
|
// Ported from boost::hash
|
||||||
codeHash ^= inst + (codeHash << 6) + (codeHash >> 2);
|
codeHash ^= inst + (codeHash << 6) + (codeHash >> 2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling)
|
||||||
|
{
|
||||||
JitILProfiler::Block& block = JitILProfiler::Add(codeHash);
|
JitILProfiler::Block& block = JitILProfiler::Add(codeHash);
|
||||||
ABI_CallFunctionC((void *)JitILProfiler::Begin, block.index);
|
ABI_CallFunctionC((void *)JitILProfiler::Begin, block.index);
|
||||||
}
|
}
|
||||||
@ -661,5 +667,10 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|||||||
LogGeneratedX86(size, code_buf, normalEntry, b);
|
LogGeneratedX86(size, code_buf, normalEntry, b);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILOutputIR)
|
||||||
|
{
|
||||||
|
ibuild.WriteToFile(codeHash);
|
||||||
|
}
|
||||||
|
|
||||||
return normalEntry;
|
return normalEntry;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user