From 50d72c1e59d0940db11b883c32c887d5715dc3fb Mon Sep 17 00:00:00 2001 From: hrydgard Date: Thu, 18 Dec 2008 10:44:03 +0000 Subject: [PATCH] Remove global state from PPCAnalyst.cpp. Little bit of cleanup. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1580 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/HW/HW.cpp | 2 - Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 6 +- .../Core/Core/Src/PowerPC/Jit64/JitCache.cpp | 19 +- .../PowerPC/Jit64/Jit_LoadStoreFloating.cpp | 4 + .../Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp | 2 +- Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp | 360 +++++------------- Source/Core/Core/Src/PowerPC/PPCAnalyst.h | 15 +- Source/Core/Core/Src/PowerPC/PPCTables.cpp | 55 +-- Source/Core/Core/Src/PowerPC/PPCTables.h | 36 +- 9 files changed, 170 insertions(+), 329 deletions(-) diff --git a/Source/Core/Core/Src/HW/HW.cpp b/Source/Core/Core/Src/HW/HW.cpp index dfc45eee48..879999bc31 100644 --- a/Source/Core/Core/Src/HW/HW.cpp +++ b/Source/Core/Core/Src/HW/HW.cpp @@ -45,7 +45,6 @@ namespace HW void Init() { CoreTiming::Init(); - PPCAnalyst::Init(); Thunk_Init(); // not really hw, but this way we know it's inited early :P State_Init(); @@ -91,7 +90,6 @@ namespace HW State_Shutdown(); Thunk_Shutdown(); CoreTiming::Shutdown(); - PPCAnalyst::Shutdown(); } void DoState(PointerWrap &p) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 096ec19840..32f06aed2f 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -172,6 +172,7 @@ namespace Jit64 { JitState js; JitOptions jo; + PPCAnalyst::CodeBuffer code_buffer(32000); void Init() { @@ -319,7 +320,10 @@ namespace Jit64 //Analyze the block, collect all instructions it is made of (including inlining, //if that is enabled), reorder instructions for optimal performance, and join joinable instructions. - PPCAnalyst::CodeOp *ops = PPCAnalyst::Flatten(emaddress, size, js.st, js.gpa, js.fpa); + + PPCAnalyst::Flatten(emaddress, &size, &js.st, &js.gpa, &js.fpa, &code_buffer); + PPCAnalyst::CodeOp *ops = code_buffer.codebuffer; + const u8 *start = AlignCode4(); //TODO: Test if this or AlignCode16 make a difference from GetCodePtr b.checkedEntry = start; b.runCount = 0; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp index fefc435e3b..fbdd532952 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.cpp @@ -21,6 +21,7 @@ // dependency is a little inconvenient and this is possibly a slight // performance hit, it's not enabled by default, but it's useful for // locating performance issues. + //#define OPROFILE_REPORT #include @@ -71,10 +72,10 @@ namespace Jit64 TRAMPOLINE_SIZE = 1024*1024, //MAX_NUM_BLOCKS = 65536, }; - int CODE_SIZE = 1024*1024*16; // nonconstant to be able to have an option for it + int CODE_SIZE = 1024*1024*16; int MAX_NUM_BLOCKS = 65536*2; - static u8 **blockCodePointers; // cut these in half and force below 2GB? + static u8 **blockCodePointers; static std::multimap links_to; @@ -133,8 +134,8 @@ namespace Jit64 #endif } - /* This clears the JIT cache. It's called from JitCache.cpp when the JIT cache - is full and when saving and loading states */ + // This clears the JIT cache. It's called from JitCache.cpp when the JIT cache + // is full and when saving and loading states. void ClearCache() { Core::DisplayMessage("Cleared code cache.", 3000); @@ -348,13 +349,6 @@ namespace Jit64 } } - /* - if ((b.exitAddress[0] == INVALID_EXIT || b.linkStatus[0]) && - (b.exitAddress[1] == INVALID_EXIT || b.linkStatus[1])) { - unlinked.erase(iter); - if (unlinked.size() > 4000) PanicAlert("Removed from unlinked. Size = %i", unlinked.size()); - } -*/ using namespace std; void LinkBlock(int i) { @@ -408,7 +402,6 @@ namespace Jit64 SetCodePtr(prev_code); // reset code pointer } -#define BLR_OP 0x4e800020 void InvalidateCodeRange(u32 address, u32 length) { @@ -418,7 +411,7 @@ namespace Jit64 //This is slow but should be safe (zelda needs it for block linking) for (int i = 0; i < numBlocks; i++) { - if (RangeIntersect(blocks[i].originalAddress, blocks[i].originalAddress+blocks[i].originalSize, + if (RangeIntersect(blocks[i].originalAddress, blocks[i].originalAddress + blocks[i].originalSize, address, address + length)) { DestroyBlock(i, true); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp index f95a28fcab..5bd904fe3c 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp @@ -278,6 +278,10 @@ void stfs(UGeckoInstruction inst) void stfsx(UGeckoInstruction inst) { +#ifdef JIT_OFF_OPTIONS + if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff) + {Default(inst); return;} // turn off from debugger +#endif // We can take a shortcut here - it's not likely that a hardware access would use this instruction. INSTRUCTION_START; #ifdef _M_X64 diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp index d59c44b137..a1dfb3ca35 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp @@ -182,7 +182,7 @@ void psq_st(UGeckoInstruction inst) { if (gpr.R(a).IsImm() && !update && cpu_info.bSSSE3) { - u32 addr = gpr.R(a).offset + offset; + u32 addr = (u32)(gpr.R(a).offset + offset); if (addr == 0xCC008000) { // Writing to FIFO. Let's do fast method. CVTPD2PS(XMM0, fpr.R(s)); diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp index e524b1f657..4b5ea25575 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp @@ -40,30 +40,24 @@ namespace PPCAnalyst { using namespace std; -PPCAnalyst::CodeOp *codebuffer; - enum { CODEBUFFER_SIZE = 32000, }; -void Init() +CodeBuffer::CodeBuffer(int size) { - codebuffer = new PPCAnalyst::CodeOp[CODEBUFFER_SIZE]; + codebuffer = new PPCAnalyst::CodeOp[size]; } -void Shutdown() +CodeBuffer::~CodeBuffer() { delete [] codebuffer; } - void AnalyzeFunction2(Symbol &func); u32 EvaluateBranchTarget(UGeckoInstruction instr, u32 pc); -// void FixUpInternalBranches(CodeOp *code, int begin, int end); - - #define INVALID_TARGET ((u32)-1) u32 EvaluateBranchTarget(UGeckoInstruction instr, u32 pc) @@ -206,34 +200,14 @@ bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size) // Second pass analysis, done after the first pass is done for all functions // so we have more information to work with -void AnalyzeFunction2(Symbol &func) +void AnalyzeFunction2(Symbol *func) { - // u32 addr = func.address; - u32 flags = func.flags; - /* - for (int i = 0; i < func.size; i++) - { - UGeckoInstruction instr = (UGeckoInstruction)Memory::ReadUnchecked_U32(addr); - - GekkoOPInfo *info = GetOpInfo(instr); - if (!info) - { - LOG(HLE,"Seems function %s contains bad op %08x",func.name,instr); - } - else - { - if (info->flags & FL_TIMER) - { - flags |= FFLAG_TIMERINSTRUCTIONS; - } - } - addr+=4; - }*/ + u32 flags = func->flags; bool nonleafcall = false; - for (size_t i = 0; i < func.calls.size(); i++) + for (size_t i = 0; i < func->calls.size(); i++) { - SCall c = func.calls[i]; + SCall c = func->calls[i]; Symbol *called_func = g_symbolDB.GetSymbolFromAddr(c.function); if (called_func && (called_func->flags & FFLAG_LEAF) == 0) { @@ -245,44 +219,7 @@ void AnalyzeFunction2(Symbol &func) if (nonleafcall && !(flags & FFLAG_EVIL) && !(flags & FFLAG_RFI)) flags |= FFLAG_ONLYCALLSNICELEAFS; - func.flags = flags; -} - -// Currently not used -void FixUpInternalBranches(CodeOp *code, int begin, int end) -{ - for (int i = begin; i < end; i++) - { - if (code[i].branchTo != INVALID_TARGET) //check if this branch already processed - { - if (code[i].inst.OPCD == 16) - { - u32 target = SignExt16(code[i].inst.BD<<2); - if (!code[i].inst.AA) - target += code[i].address; - //local branch - code[i].branchTo = target; - } - else - code[i].branchTo = INVALID_TARGET; - } - } - - //brute force - for (int i = begin; i < end; i++) - { - if (code[i].branchTo != INVALID_TARGET) - { - bool found = false; - for (int j = begin; j < end; j++) - if (code[i].branchTo == code[j].address) - code[i].branchToIndex = j; - if (!found) - { - LOG(HLE, "ERROR: branch target missing"); - } - } - } + func->flags = flags; } // IMPORTANT - CURRENTLY ASSUMES THAT A IS A COMPARE @@ -346,138 +283,92 @@ bool CanSwapAdjacentOps(const CodeOp &a, const CodeOp &b) } // Does not yet perform inlining - although there are plans for that. -CodeOp *Flatten(u32 address, int &realsize, BlockStats &st, BlockRegStats &gpa, BlockRegStats &fpa) +void Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, BlockRegStats *fpa, CodeBuffer *buffer) { int numCycles = 0; u32 blockstart = address; - memset(&st, 0, sizeof(st)); - UGeckoInstruction previnst = Memory::Read_Instruction(address-4); + memset(st, 0, sizeof(st)); + UGeckoInstruction previnst = Memory::Read_Instruction(address - 4); if (previnst.hex == 0x4e800020) { - st.isFirstBlockOfFunction = true; + st->isFirstBlockOfFunction = true; } + gpa->any = true; + fpa->any = false; - gpa.any = true; - fpa.any = false; - - enum Todo - { - JustCopy = 0, Flatten = 1, Nothing = 2 - }; - Todo todo = Nothing; - - //Symbol *f = g_symbolDB.GetSymbolFromAddr(address); int maxsize = CODEBUFFER_SIZE; - //for now, all will return JustCopy :P - /* - if (f) + int num_inst = 0; + int numFollows = 0; + + CodeOp *code = buffer->codebuffer; + bool foundExit = false; + + // Flatten! (Currently just copies, following branches is disabled) + for (int i = 0; i < maxsize; i++, num_inst++) { - if (f->flags & FFLAG_LEAF) + memset(&code[i], 0, sizeof(CodeOp)); + code[i].address = address; + UGeckoInstruction inst = Memory::Read_Instruction(code[i].address); + _assert_msg_(GEKKO, inst.hex != 0, "Zero Op - Error flattening %08x op %08x", address + i*4, inst); + code[i].inst = inst; + code[i].branchTo = -1; + code[i].branchToIndex = -1; + GekkoOPInfo *opinfo = GetOpInfo(inst); + if (opinfo) + numCycles += opinfo->numCyclesMinusOne + 1; + _assert_msg_(GEKKO, opinfo != 0, "Invalid Op - Error flattening %08x op %08x", address + i*4, inst); + bool follow = false; + u32 destination; + if (inst.OPCD == 18) { - //no reason to flatten - todo = JustCopy; + //Is bx - should we inline? yes! + if (inst.AA) + destination = SignExt26(inst.LI << 2); + else + destination = address + SignExt26(inst.LI << 2); + if (destination != blockstart) + follow = true; } - else if (f->flags & FFLAG_ONLYCALLSNICELEAFS) + if (follow) + numFollows++; + if (numFollows > 1) + follow = false; + follow = false; + if (!follow) { - //inline calls if possible - //todo = Flatten; - todo = JustCopy; + if (opinfo->flags & FL_ENDBLOCK) //right now we stop early + { + foundExit = true; + break; + } + address += 4; } else { - todo = JustCopy; + address = destination; } - todo = JustCopy; - - maxsize = f->size; } - else*/ - todo = JustCopy; - CodeOp *code = codebuffer; //new CodeOp[size]; - - if (todo == JustCopy) - { - realsize = 0; - bool foundExit = false; - int numFollows = 0; - for (int i = 0; i < maxsize; i++, realsize++) - { - memset(&code[i], 0, sizeof(CodeOp)); - code[i].address = address; - UGeckoInstruction inst = Memory::Read_Instruction(code[i].address); - _assert_msg_(GEKKO, inst.hex != 0, "Zero Op - Error flattening %08x op %08x",address+i*4,inst); - code[i].inst = inst; - code[i].branchTo = -1; - code[i].branchToIndex = -1; - GekkoOPInfo *opinfo = GetOpInfo(inst); - if (opinfo) - numCycles += opinfo->numCyclesMinusOne + 1; - _assert_msg_(GEKKO, opinfo != 0, "Invalid Op - Error flattening %08x op %08x",address+i*4,inst); - int flags = opinfo->flags; - - bool follow = false; - u32 destination; - if (inst.OPCD == 18) - { - //Is bx - should we inline? yes! - if (inst.AA) - destination = SignExt26(inst.LI << 2); - else - destination = address + SignExt26(inst.LI << 2); - if (destination != blockstart) - follow = true; - } - if (follow) - numFollows++; - if (numFollows > 1) - follow = false; - - follow = false; - if (!follow) - { - if (flags & FL_ENDBLOCK) //right now we stop early - { - foundExit = true; - break; - } - address += 4; - } - else - { - address = destination; - } - } - _assert_msg_(GEKKO,foundExit,"Analyzer ERROR - Function %08x too big", blockstart); - realsize++; - st.numCycles = numCycles; - FixUpInternalBranches(code,0,realsize); - } - else if (todo == Flatten) - { - return 0; - } - else - { - return 0; - } + _assert_msg_(GEKKO, foundExit, "Analyzer ERROR - Function %08x too big", blockstart); + num_inst++; // why? + st->numCycles = numCycles; // Do analysis of the code, look for dependencies etc int numSystemInstructions = 0; for (int i = 0; i < 32; i++) { - gpa.firstRead[i] = -1; - gpa.firstWrite[i] = -1; - gpa.numReads[i] = 0; - gpa.numWrites[i] = 0; + gpa->firstRead[i] = -1; + gpa->firstWrite[i] = -1; + gpa->numReads[i] = 0; + gpa->numWrites[i] = 0; } - gpa.any = true; - for (size_t i = 0; i < realsize; i++) + gpa->any = true; + for (size_t i = 0; i < num_inst; i++) { UGeckoInstruction inst = code[i].inst; if (PPCTables::UsesFPU(inst)) - fpa.any = true; + fpa->any = true; code[i].wantsCR0 = false; code[i].wantsCR1 = false; @@ -488,7 +379,7 @@ CodeOp *Flatten(u32 address, int &realsize, BlockStats &st, BlockRegStats &gpa, int flags = opinfo->flags; if (flags & FL_TIMER) - gpa.anyTimer = true; + gpa->anyTimer = true; // Does the instruction output CR0? if (flags & FL_RC_BIT) @@ -521,37 +412,37 @@ CodeOp *Flatten(u32 address, int &realsize, BlockStats &st, BlockRegStats &gpa, if (flags & FL_OUT_A) { code[i].regsOut[numOut++] = inst.RA; - gpa.numWrites[inst.RA]++; + gpa->numWrites[inst.RA]++; } if (flags & FL_OUT_D) { code[i].regsOut[numOut++] = inst.RD; - gpa.numWrites[inst.RD]++; + gpa->numWrites[inst.RD]++; } if (flags & FL_OUT_S) { code[i].regsOut[numOut++] = inst.RS; - gpa.numWrites[inst.RS]++; + gpa->numWrites[inst.RS]++; } if ((flags & FL_IN_A) || ((flags & FL_IN_A0) && inst.RA != 0)) { code[i].regsIn[numIn++] = inst.RA; - gpa.numReads[inst.RA]++; + gpa->numReads[inst.RA]++; } if (flags & FL_IN_B) { code[i].regsIn[numIn++] = inst.RB; - gpa.numReads[inst.RB]++; + gpa->numReads[inst.RB]++; } if (flags & FL_IN_C) { code[i].regsIn[numIn++] = inst.RC; - gpa.numReads[inst.RC]++; + gpa->numReads[inst.RC]++; } if (flags & FL_IN_S) { code[i].regsIn[numIn++] = inst.RS; - gpa.numReads[inst.RS]++; + gpa->numReads[inst.RS]++; } switch (opinfo->type) @@ -583,10 +474,10 @@ CodeOp *Flatten(u32 address, int &realsize, BlockStats &st, BlockRegStats &gpa, int r = code[i].regsIn[j]; if (r < 0 || r > 31) PanicAlert("wtf"); - if (gpa.firstRead[r] == -1) - gpa.firstRead[r] = (short)(i); - gpa.lastRead[r] = (short)(i); - gpa.numReads[r]++; + if (gpa->firstRead[r] == -1) + gpa->firstRead[r] = (short)(i); + gpa->lastRead[r] = (short)(i); + gpa->numReads[r]++; } for (int j = 0; j < numOut; j++) @@ -594,18 +485,18 @@ CodeOp *Flatten(u32 address, int &realsize, BlockStats &st, BlockRegStats &gpa, int r = code[i].regsOut[j]; if (r < 0 || r > 31) PanicAlert("wtf"); - if (gpa.firstWrite[r] == -1) - gpa.firstWrite[r] = (short)(i); - gpa.lastWrite[r] = (short)(i); - gpa.numWrites[r]++; + if (gpa->firstWrite[r] == -1) + gpa->firstWrite[r] = (short)(i); + gpa->lastWrite[r] = (short)(i); + gpa->numWrites[r]++; } } // Instruction Reordering Pass - // Bubble down compares towards branches, so that they can be merged (merging not yet implemented). + // Bubble down compares towards branches, so that they can be merged. // -2: -1 for the pair, -1 for not swapping with the final instruction which is probably the branch. - for (int i = 0; i < (realsize - 2); i++) + for (int i = 0; i < num_inst - 2; i++) { CodeOp &a = code[i]; CodeOp &b = code[i + 1]; @@ -628,7 +519,7 @@ CodeOp *Flatten(u32 address, int &realsize, BlockStats &st, BlockRegStats &gpa, bool wantsCR0 = true; bool wantsCR1 = true; bool wantsPS1 = true; - for (int i = realsize - 1; i; i--) + for (int i = num_inst - 1; i; i--) { if (code[i].outputCR0) wantsCR0 = false; @@ -644,40 +535,11 @@ CodeOp *Flatten(u32 address, int &realsize, BlockStats &st, BlockRegStats &gpa, code[i].wantsPS1 = wantsPS1; } - // Time for code shuffling, taking into account the above dependency analysis. - bool successful_shuffle = false; - //Move compares - // Try to push compares as close as possible to the following branch - // this way we can do neat stuff like combining compare and branch - // and avoid emitting any cr flags at all - /* - * - pseudo: - if (op is cmp and sets CR0) - { - scan forward for branch - if we hit any instruction that sets CR0, bail - if we hit any instruction that writes to any of the cmp input variables, bail - shuffleup(code, cmpaddr, branchaddr-1) - } - - - how to merge: - if (op is cmp and nextop is condbranch) - { - check if nextnextop wants cr - if it does, bail (or merge and write cr) - else merge! - } - - */ - if (successful_shuffle) { - // Disasm before and after, display side by side - } - // Decide what regs to potentially regcache - return code; + *realsize = num_inst; + // ... } + // Most functions that are relevant to analyze should be // called by another function. Therefore, let's scan the // entire space for bl operations and find what functions @@ -759,9 +621,9 @@ void FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db) LOG(HLE, "weird function"); continue; } - AnalyzeFunction2(iter->second); + AnalyzeFunction2(&(iter->second)); Symbol &f = iter->second; - if (f.name.substr(0,3) == "zzz") + if (f.name.substr(0, 3) == "zzz") { if (f.flags & FFLAG_LEAF) f.name += "_leaf"; @@ -810,46 +672,4 @@ void FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db) LOG(HLE, "Average size: %i (leaf), %i (nice), %i(unnice)", leafSize, niceSize, unniceSize); } -/* -void AnalyzeBackwards() -{ -#ifndef BWLINKS - return; -#else - for (int i=0; i> 26) - { - case 18: - if (LK) //LK - { - u32 addr; - if(AA) - addr = SignExt26(LI << 2); - else - addr = ptr + SignExt26(LI << 2); - - int funNum = GetSymbolNum(addr); - if (funNum>=0) - entries[funNum].backwardLinks.push_back(ptr); - } - break; - default: - ; - } - ptr+=4; - } - } - } -#endif -} - -*/ - } // namespace diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.h b/Source/Core/Core/Src/PowerPC/PPCAnalyst.h index 3c6de7702d..0646ee6f5d 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.h +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.h @@ -76,13 +76,20 @@ struct BlockRegStats min(firstRead[reg], firstWrite[reg]);} }; -void Init(); -void Shutdown(); -CodeOp *Flatten(u32 address, int &realsize, BlockStats &st, BlockRegStats &gpa, BlockRegStats &fpa); +class CodeBuffer +{ +public: + CodeBuffer(int size); + ~CodeBuffer(); + + PPCAnalyst::CodeOp *codebuffer; + int size_; +}; + +void Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, BlockRegStats *fpa, CodeBuffer *buffer); void LogFunctionCall(u32 addr); - void FindFunctions(u32 startAddr, u32 endAddr, SymbolDB *func_db); bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size = 0); diff --git a/Source/Core/Core/Src/PowerPC/PPCTables.cpp b/Source/Core/Core/Src/PowerPC/PPCTables.cpp index 62b3c1e369..fb4eb01d56 100644 --- a/Source/Core/Core/Src/PowerPC/PPCTables.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCTables.cpp @@ -122,8 +122,7 @@ Interpreter::_interpreterInstruction GetInterpreterOp(UGeckoInstruction _inst) } } - -GekkoOPTemplate primarytable[] = +static GekkoOPTemplate primarytable[] = { {4, Interpreter::RunTable4, DynaRunTable4, {"RunTable4", OPTYPE_SUBTABLE | (4<<24), 0}}, {19, Interpreter::RunTable19, DynaRunTable19, {"RunTable19", OPTYPE_SUBTABLE | (19<<24), 0}}, @@ -204,7 +203,7 @@ GekkoOPTemplate primarytable[] = {58, Interpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}}, }; -GekkoOPTemplate table4[] = +static GekkoOPTemplate table4[] = { //SUBOP10 {0, Interpreter::ps_cmpu0, Jit64::Default, {"ps_cmpu0", OPTYPE_PS, FL_SET_CRn}}, {32, Interpreter::ps_cmpo0, Jit64::Default, {"ps_cmpo0", OPTYPE_PS, FL_SET_CRn}}, @@ -222,7 +221,7 @@ GekkoOPTemplate table4[] = {1014, Interpreter::dcbz_l, Jit64::Default, {"dcbz_l", OPTYPE_SYSTEM, 0}}, }; -GekkoOPTemplate table4_2[] = +static GekkoOPTemplate table4_2[] = { {10, Interpreter::ps_sum0, Jit64::ps_sum, {"ps_sum0", OPTYPE_PS, 0}}, {11, Interpreter::ps_sum1, Jit64::ps_sum, {"ps_sum1", OPTYPE_PS, 0}}, @@ -244,7 +243,7 @@ GekkoOPTemplate table4_2[] = }; -GekkoOPTemplate table4_3[] = +static GekkoOPTemplate table4_3[] = { {6, Interpreter::psq_lx, Jit64::Default, {"psq_lx", OPTYPE_PS, 0}}, {7, Interpreter::psq_stx, Jit64::Default, {"psq_stx", OPTYPE_PS, 0}}, @@ -252,7 +251,7 @@ GekkoOPTemplate table4_3[] = {39, Interpreter::psq_stux, Jit64::Default, {"psq_stux", OPTYPE_PS, 0}}, }; -GekkoOPTemplate table19[] = +static GekkoOPTemplate table19[] = { {528, Interpreter::bcctrx, Jit64::bcctrx, {"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, {16, Interpreter::bclrx, Jit64::bclrx, {"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, @@ -273,7 +272,7 @@ GekkoOPTemplate table19[] = }; -GekkoOPTemplate table31[] = +static GekkoOPTemplate table31[] = { {28, Interpreter::andx, Jit64::andx, {"andx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, {60, Interpreter::andcx, Jit64::Default, {"andcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, @@ -386,7 +385,7 @@ GekkoOPTemplate table31[] = {566, Interpreter::tlbsync, Jit64::Default, {"tlbsync", OPTYPE_SYSTEM, 0}}, }; -GekkoOPTemplate table31_2[] = +static GekkoOPTemplate table31_2[] = { {266, Interpreter::addx, Jit64::addx, {"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, {10, Interpreter::addcx, Jit64::Default, {"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, @@ -406,7 +405,7 @@ GekkoOPTemplate table31_2[] = {200, Interpreter::subfzex, Jit64::Default, {"subfzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, }; -GekkoOPTemplate table59[] = +static GekkoOPTemplate table59[] = { {18, Interpreter::fdivsx, Jit64::fp_arith_s, {"fdivsx", OPTYPE_FPU, FL_RC_BIT_F, 16}}, {20, Interpreter::fsubsx, Jit64::fp_arith_s, {"fsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, @@ -420,7 +419,7 @@ GekkoOPTemplate table59[] = {31, Interpreter::fnmaddsx, Jit64::fmaddXX, {"fnmaddsx", OPTYPE_FPU, FL_RC_BIT_F}}, }; -GekkoOPTemplate table63[] = +static GekkoOPTemplate table63[] = { {264, Interpreter::fabsx, Jit64::Default, {"fabsx", OPTYPE_FPU, FL_RC_BIT_F}}, {32, Interpreter::fcmpo, Jit64::fcmpx, {"fcmpo", OPTYPE_FPU, FL_RC_BIT_F}}, @@ -440,7 +439,7 @@ GekkoOPTemplate table63[] = {711, Interpreter::mtfsfx, Jit64::Default, {"mtfsfx", OPTYPE_SYSTEMFP, 0, 2}}, }; -GekkoOPTemplate table63_2[] = +static GekkoOPTemplate table63_2[] = { {18, Interpreter::fdivx, Jit64::Default, {"fdivx", OPTYPE_FPU, FL_RC_BIT_F, 30}}, {20, Interpreter::fsubx, Jit64::Default, {"fsubx", OPTYPE_FPU, FL_RC_BIT_F}}, @@ -455,7 +454,10 @@ GekkoOPTemplate table63_2[] = {31, Interpreter::fnmaddx, Jit64::fmaddXX, {"fnmaddx", OPTYPE_FPU, FL_RC_BIT_F}}, }; -bool PPCTables::UsesFPU(UGeckoInstruction _inst) +namespace PPCTables +{ + +bool UsesFPU(UGeckoInstruction _inst) { switch (_inst.OPCD) { @@ -500,7 +502,7 @@ bool PPCTables::UsesFPU(UGeckoInstruction _inst) } } -void PPCTables::InitTables() +void InitTables() { //clear for (int i = 0; i < 32; i++) @@ -671,31 +673,30 @@ void PPCTables::CompileInstruction(UGeckoInstruction _inst) } } -bool PPCTables::IsValidInstruction(UGeckoInstruction _instCode) +bool IsValidInstruction(UGeckoInstruction _instCode) { const GekkoOPInfo *info = GetOpInfo(_instCode); return info != 0; } -void PPCTables::CountInstruction(UGeckoInstruction _inst) +void CountInstruction(UGeckoInstruction _inst) { GekkoOPInfo *info = GetOpInfo(_inst); if (info) info->runCount++; } -struct inf +void PrintInstructionRunCounts() { - const char *name; - int count; - bool operator < (const inf &o) const + struct inf { - return count > o.count; - } -}; - -void PPCTables::PrintInstructionRunCounts() -{ + const char *name; + int count; + bool operator < (const inf &o) const + { + return count > o.count; + } + }; std::vector temp; for (int i = 0; i < m_numInstructions; i++) { @@ -712,7 +713,7 @@ void PPCTables::PrintInstructionRunCounts() } //TODO move to LogManager -void PPCTables::LogCompiledInstructions() +void LogCompiledInstructions() { static int time = 0; FILE *f = fopen(StringFromFormat(FULL_LOGS_DIR "inst_log%i.txt", time).c_str(), "w"); @@ -740,3 +741,5 @@ void PPCTables::LogCompiledInstructions() #endif time++; } + +} // namespace \ No newline at end of file diff --git a/Source/Core/Core/Src/PowerPC/PPCTables.h b/Source/Core/Core/Src/PowerPC/PPCTables.h index 33bebabb27..4885cb681d 100644 --- a/Source/Core/Core/Src/PowerPC/PPCTables.h +++ b/Source/Core/Core/Src/PowerPC/PPCTables.h @@ -71,6 +71,18 @@ enum OPTYPE_UNKNOWN , }; +enum { + OPCD_HLEFUNCTION = 1, + OPCD_COMPILEDBLOCK = 2, + OPCD_BCx = 16, + OPCD_SC = 17, + OPCD_Bx = 18, +}; + +enum { + OP_BLR = 0x4e800020, +}; + struct GekkoOPInfo { const char *opname; @@ -85,21 +97,21 @@ struct GekkoOPInfo GekkoOPInfo *GetOpInfo(UGeckoInstruction _inst); Interpreter::_interpreterInstruction GetInterpreterOp(UGeckoInstruction _inst); -class PPCTables +namespace PPCTables { -public: - typedef void (*_recompilerInstruction) (UGeckoInstruction instCode); - typedef void (*_interpreterInstruction)(UGeckoInstruction instCode); - static void InitTables(); - static bool IsValidInstruction(UGeckoInstruction _instCode); - static bool UsesFPU(UGeckoInstruction _inst); +typedef void (*_recompilerInstruction) (UGeckoInstruction instCode); +typedef void (*_interpreterInstruction)(UGeckoInstruction instCode); - static void CountInstruction(UGeckoInstruction _inst); - static void PrintInstructionRunCounts(); - static void LogCompiledInstructions(); +void InitTables(); +bool IsValidInstruction(UGeckoInstruction _instCode); +bool UsesFPU(UGeckoInstruction _inst); - static void CompileInstruction(UGeckoInstruction _inst); -}; +void CountInstruction(UGeckoInstruction _inst); +void PrintInstructionRunCounts(); +void LogCompiledInstructions(); +void CompileInstruction(UGeckoInstruction _inst); + +} // namespace #endif