diff options
| author | dok.slade <dok.slade@gmail.com> | 2010-07-25 19:01:32 +0000 |
|---|---|---|
| committer | dok.slade <dok.slade@gmail.com> | 2010-07-25 19:01:32 +0000 |
| commit | 673f18837ba2b0a5d953d229d8110dde276db30e (patch) | |
| tree | f27e6551e085e9af2d3f2c31a8696d8899742492 /Source | |
| parent | 16129f6f6d26aca0abe5d9a7cee5790070dcdef6 (diff) | |
Commit r5970 part #4: Merge some loops in PPCAnalyst::Flatten()
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5976 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source')
| -rw-r--r-- | Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp | 148 | ||||
| -rw-r--r-- | Source/Core/Core/Src/PowerPC/PPCAnalyst.h | 14 |
2 files changed, 72 insertions, 90 deletions
diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp index 2a00a18cf9..d9fc6f7a0f 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp @@ -296,6 +296,13 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, Bloc gpa->any = true; fpa->any = false; + for (int i = 0; i < 32; i++) + { + gpa->firstRead[i] = -1; + gpa->firstWrite[i] = -1; + gpa->numReads[i] = 0; + gpa->numWrites[i] = 0; + } u32 blockstart = address; int maxsize = blockSize; @@ -307,7 +314,8 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, Bloc CodeOp *code = buffer->codebuffer; bool foundExit = false; - // Flatten! (Currently just copies, following branches is disabled) + // Do analysis of the code, look for dependencies etc + int numSystemInstructions = 0; for (int i = 0; i < maxsize; i++) { num_inst++; @@ -326,63 +334,11 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, Bloc if (opinfo) numCycles += opinfo->numCyclesMinusOne + 1; _assert_msg_(POWERPC, opinfo != 0, "Invalid Op - Error flattening %08x op %08x", address + i*4, inst.hex); - bool follow = false; - u32 destination; - if (inst.OPCD == 18 && blockSize > 1) - { - //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 (opinfo->flags & FL_ENDBLOCK) //right now we stop early - { - foundExit = true; - break; - } - address += 4; - } - else - { - code[i].skip = true; - address = destination; - } - } - if (!foundExit && blockSize > 1) - NOTICE_LOG(POWERPC, "Analyzer ERROR - Function %08x too big, size is 0x%08x", blockstart, address-blockstart); - 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->any = true; - for (int i = 0; i < num_inst; i++) - { - UGeckoInstruction inst = code[i].inst; - code[i].wantsCR0 = false; code[i].wantsCR1 = false; code[i].wantsPS1 = false; - const GekkoOPInfo *opinfo = code[i].opinfo; - _assert_msg_(POWERPC, opinfo != 0, "Invalid Op - Error scanning %08x op %08x",address+i*4,inst.hex); int flags = opinfo->flags; if (flags & FL_USE_FPU) @@ -407,54 +363,53 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, Bloc else code[i].outputCR1 = (flags & FL_SET_CR1) ? true : false; - for (int j = 0; j < 3; j++) - { - code[i].fregsIn[j] = -1; - code[i].regsIn[j] = -1; - } - for (int j = 0; j < 2; j++) - code[i].regsOut[j] = -1; - - code[i].fregOut = -1; - int numOut = 0; int numIn = 0; if (flags & FL_OUT_A) { code[i].regsOut[numOut++] = inst.RA; - gpa->numWrites[inst.RA]++; + gpa->SetOutputRegister(inst.RA, i); } if (flags & FL_OUT_D) { code[i].regsOut[numOut++] = inst.RD; - gpa->numWrites[inst.RD]++; + gpa->SetOutputRegister(inst.RD, i); } if (flags & FL_OUT_S) { code[i].regsOut[numOut++] = inst.RS; - gpa->numWrites[inst.RS]++; + gpa->SetOutputRegister(inst.RS, i); } if ((flags & FL_IN_A) || ((flags & FL_IN_A0) && inst.RA != 0)) { code[i].regsIn[numIn++] = inst.RA; - gpa->numReads[inst.RA]++; + gpa->SetInputRegister(inst.RA, i); } if (flags & FL_IN_B) { code[i].regsIn[numIn++] = inst.RB; - gpa->numReads[inst.RB]++; + gpa->SetInputRegister(inst.RB, i); } if (flags & FL_IN_C) { code[i].regsIn[numIn++] = inst.RC; - gpa->numReads[inst.RC]++; + gpa->SetInputRegister(inst.RC, i); } if (flags & FL_IN_S) { code[i].regsIn[numIn++] = inst.RS; - gpa->numReads[inst.RS]++; + gpa->SetInputRegister(inst.RS, i); } + // Set remaining register slots as unused (-1) + for (int j = numIn; j < 3; j++) + code[i].regsIn[j] = -1; + for (int j = numOut; j < 2; j++) + code[i].regsOut[j] = -1; + for (int j = 0; j < 3; j++) + code[i].fregsIn[j] = -1; + code[i].fregOut = -1; + switch (opinfo->type) { case OPTYPE_INTEGER: @@ -479,28 +434,41 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, Bloc break; } - for (int j = 0; j < numIn; j++) + bool follow = false; + u32 destination; + if (inst.OPCD == 18 && blockSize > 1) { - 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]++; + //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; } - - for (int j = 0; j < numOut; j++) - { - 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 (follow) + numFollows++; + if (numFollows > 1) + follow = false; + follow = false; + if (!follow) + { + if (opinfo->flags & FL_ENDBLOCK) //right now we stop early + { + foundExit = true; + break; + } + address += 4; } - } + else + { + code[i].skip = true; + address = destination; + } + } + if (!foundExit && blockSize > 1) + NOTICE_LOG(POWERPC, "Analyzer ERROR - Function %08x too big, size is 0x%08x", blockstart, address-blockstart); + st->numCycles = numCycles; // Instruction Reordering Pass if (blockSize > 1) @@ -530,7 +498,7 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, Bloc bool wantsCR0 = true; bool wantsCR1 = true; bool wantsPS1 = true; - for (int i = num_inst; i; i--) + for (int i = num_inst - 1; i >= 0; i--) { if (code[i].outputCR0) wantsCR0 = false; diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.h b/Source/Core/Core/Src/PowerPC/PPCAnalyst.h index 5a41f6fda7..d19774e3e8 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.h +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.h @@ -77,6 +77,20 @@ struct BlockRegStats int GetUseRange(int reg) { return max(lastRead[reg], lastWrite[reg]) - min(firstRead[reg], firstWrite[reg]);} + + inline void SetInputRegister(int reg, short opindex) { + if (firstRead[reg] == -1) + firstRead[reg] = (short)(opindex); + lastRead[reg] = (short)(opindex); + numReads[reg]++; + } + + inline void SetOutputRegister(int reg, short opindex) { + if (firstWrite[reg] == -1) + firstWrite[reg] = (short)(opindex); + lastWrite[reg] = (short)(opindex); + numWrites[reg]++; + } }; |
