summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authordok.slade <dok.slade@gmail.com>2010-07-25 19:01:32 +0000
committerdok.slade <dok.slade@gmail.com>2010-07-25 19:01:32 +0000
commit673f18837ba2b0a5d953d229d8110dde276db30e (patch)
treef27e6551e085e9af2d3f2c31a8696d8899742492 /Source/Core
parent16129f6f6d26aca0abe5d9a7cee5790070dcdef6 (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/Core')
-rw-r--r--Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp148
-rw-r--r--Source/Core/Core/Src/PowerPC/PPCAnalyst.h14
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]++;
+ }
};