PPCRec: Move analyzer file + move some funcs to IMLInstruction

This commit is contained in:
Exzap
2023-01-29 14:55:19 +01:00
parent c14300c6d4
commit ac57c31321
9 changed files with 961 additions and 948 deletions
+1 -1
View File
@@ -65,7 +65,7 @@ add_library(CemuCafe
HW/Espresso/Recompiler/IML/IMLInstruction.cpp
HW/Espresso/Recompiler/IML/IMLInstruction.h
HW/Espresso/Recompiler/IML/IMLDebug.cpp
HW/Espresso/Recompiler/PPCRecompilerImlAnalyzer.cpp
HW/Espresso/Recompiler/IML/IMLAnalyzer.cpp
HW/Espresso/Recompiler/PPCRecompilerImlGen.cpp
HW/Espresso/Recompiler/PPCRecompilerImlGenFPU.cpp
HW/Espresso/Recompiler/PPCRecompilerIml.h
+15
View File
@@ -1,3 +1,18 @@
#pragma once
#include "IMLInstruction.h"
#include "IMLSegment.h"
// analyzer
struct PPCRecCRTracking_t
{
uint32 readCRBits;
uint32 writtenCRBits;
};
bool IMLAnalyzer_IsTightFiniteLoop(IMLSegment* imlSegment);
bool IMLAnalyzer_CanTypeWriteCR(IMLInstruction* imlInstruction);
void IMLAnalyzer_GetCRTracking(IMLInstruction* imlInstruction, PPCRecCRTracking_t* crTracking);
// debug
void IMLDebug_DumpSegment(struct IMLSegment* imlSegment, sint32 segmentIndex, bool printLivenessRangeInfo = false);
@@ -1,12 +1,13 @@
#include "PPCRecompiler.h"
#include "PPCRecompilerIml.h"
#include "IML.h"
//#include "PPCRecompilerIml.h"
#include "util/helpers/fixedSizeList.h"
#include "Cafe/HW/Espresso/Interpreter/PPCInterpreterInternal.h"
/*
* Initializes a single segment and returns true if it is a finite loop
*/
bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(IMLSegment* imlSegment)
bool IMLAnalyzer_IsTightFiniteLoop(IMLSegment* imlSegment)
{
bool isTightFiniteLoop = false;
// base criteria, must jump to beginning of same segment
@@ -35,12 +36,12 @@ bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(IMLSegment* imlSegment)
{
// remove all registers from the list that are modified by non-ADD/SUB instructions
// todo: We should also cover the case where ADD+SUB on the same register cancel the effect out
PPCImlOptimizerUsedRegisters_t registersUsed;
IMLUsedRegisters registersUsed;
for (const IMLInstruction& instIt : imlSegment->imlList)
{
if (instIt.type == PPCREC_IML_TYPE_R_S32 && (instIt.operation == PPCREC_IML_OP_ADD || instIt.operation == PPCREC_IML_OP_SUB))
continue;
PPCRecompiler_checkRegisterUsage(nullptr, &instIt, &registersUsed);
instIt.CheckRegisterUsage(&registersUsed);
if(registersUsed.writtenNamedReg1 < 0)
continue;
list_modifiedRegisters.remove(registersUsed.writtenNamedReg1);
@@ -56,7 +57,7 @@ bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(IMLSegment* imlSegment)
/*
* Returns true if the imlInstruction can overwrite CR (depending on value of ->crRegister)
*/
bool PPCRecompilerImlAnalyzer_canTypeWriteCR(IMLInstruction* imlInstruction)
bool IMLAnalyzer_CanTypeWriteCR(IMLInstruction* imlInstruction)
{
if (imlInstruction->type == PPCREC_IML_TYPE_R_R)
return true;
@@ -77,7 +78,7 @@ bool PPCRecompilerImlAnalyzer_canTypeWriteCR(IMLInstruction* imlInstruction)
return false;
}
void PPCRecompilerImlAnalyzer_getCRTracking(IMLInstruction* imlInstruction, PPCRecCRTracking_t* crTracking)
void IMLAnalyzer_GetCRTracking(IMLInstruction* imlInstruction, PPCRecCRTracking_t* crTracking)
{
crTracking->readCRBits = 0;
crTracking->writtenCRBits = 0;
@@ -125,7 +126,7 @@ void PPCRecompilerImlAnalyzer_getCRTracking(IMLInstruction* imlInstruction, PPCR
else
assert_dbg();
}
else if (PPCRecompilerImlAnalyzer_canTypeWriteCR(imlInstruction) && imlInstruction->crRegister >= 0 && imlInstruction->crRegister <= 7)
else if (IMLAnalyzer_CanTypeWriteCR(imlInstruction) && imlInstruction->crRegister >= 0 && imlInstruction->crRegister <= 7)
{
crTracking->writtenCRBits |= (0xF << (imlInstruction->crRegister * 4));
}
@@ -134,4 +135,4 @@ void PPCRecompilerImlAnalyzer_getCRTracking(IMLInstruction* imlInstruction, PPCR
// overwrites CR0
crTracking->writtenCRBits |= (0xF << 0);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -236,6 +236,35 @@ enum
PPCREC_FPR_ST_MODE_PSQ_S16_PS0_PS1,
};
struct IMLUsedRegisters
{
union
{
struct
{
sint16 readNamedReg1;
sint16 readNamedReg2;
sint16 readNamedReg3;
sint16 writtenNamedReg1;
};
sint16 gpr[4]; // 3 read + 1 write
};
// FPR
union
{
struct
{
// note: If destination operand is not fully written (PS0 and PS1) it will be added to the read registers
sint16 readFPR1;
sint16 readFPR2;
sint16 readFPR3;
sint16 readFPR4;
sint16 writtenFPR1;
};
sint16 fpr[4];
};
};
struct IMLInstruction
{
uint8 type;
@@ -409,4 +438,9 @@ struct IMLInstruction
associatedPPCAddress = 0;
}
void CheckRegisterUsage(IMLUsedRegisters* registersUsed) const;
void ReplaceGPRRegisterUsageMultiple(sint32 gprRegisterSearched[4], sint32 gprRegisterReplaced[4]);
void ReplaceFPRRegisterUsageMultiple(sint32 fprRegisterSearched[4], sint32 fprRegisterReplaced[4]);
void ReplaceFPRRegisterUsage(sint32 fprRegisterSearched, sint32 fprRegisterReplaced);
};
@@ -122,17 +122,6 @@ void PPCRecompilerIML_isolateEnterableSegments(ppcImlGenContext_t* ppcImlGenCont
IMLInstruction* PPCRecompilerIML_getLastInstruction(IMLSegment* imlSegment);
// IML analyzer
typedef struct
{
uint32 readCRBits;
uint32 writtenCRBits;
}PPCRecCRTracking_t;
bool PPCRecompilerImlAnalyzer_isTightFiniteLoop(IMLSegment* imlSegment);
bool PPCRecompilerImlAnalyzer_canTypeWriteCR(IMLInstruction* imlInstruction);
void PPCRecompilerImlAnalyzer_getCRTracking(IMLInstruction* imlInstruction, PPCRecCRTracking_t* crTracking);
// IML optimizer
bool PPCRecompiler_reduceNumberOfFPRRegisters(ppcImlGenContext_t* ppcImlGenContext);
@@ -149,34 +138,3 @@ void PPCRecompilerImm_allocateRegisters(ppcImlGenContext_t* ppcImlGenContext);
// late optimizations
void PPCRecompiler_reorderConditionModifyInstructions(ppcImlGenContext_t* ppcImlGenContext);
typedef struct
{
union
{
struct
{
sint16 readNamedReg1;
sint16 readNamedReg2;
sint16 readNamedReg3;
sint16 writtenNamedReg1;
};
sint16 gpr[4]; // 3 read + 1 write
};
// FPR
union
{
struct
{
// note: If destination operand is not fully written, it will be added as a read FPR as well
sint16 readFPR1;
sint16 readFPR2;
sint16 readFPR3;
sint16 readFPR4; // usually this is set to the result FPR if only partially overwritten
sint16 writtenFPR1;
};
sint16 fpr[4];
};
}PPCImlOptimizerUsedRegisters_t;
void PPCRecompiler_checkRegisterUsage(ppcImlGenContext_t* ppcImlGenContext, const IMLInstruction* imlInstruction, PPCImlOptimizerUsedRegisters_t* registersUsed);
@@ -2,8 +2,8 @@
#include "Cafe/HW/Espresso/Interpreter/PPCInterpreterHelper.h"
#include "PPCRecompiler.h"
#include "PPCRecompilerIml.h"
#include "PPCRecompilerX64.h"
#include "PPCRecompilerImlRanges.h"
#include "IML/IML.h"
bool PPCRecompiler_decodePPCInstruction(ppcImlGenContext_t* ppcImlGenContext);
uint32 PPCRecompiler_iterateCurrentInstruction(ppcImlGenContext_t* ppcImlGenContext);
@@ -4277,7 +4277,7 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
if (imlSegment->imlList[imlSegment->imlList.size() - 1].type != PPCREC_IML_TYPE_CJUMP || imlSegment->imlList[imlSegment->imlList.size() - 1].op_conditionalJump.jumpAccordingToSegment)
continue;
// exclude non-infinite tight loops
if (PPCRecompilerImlAnalyzer_isTightFiniteLoop(imlSegment))
if (IMLAnalyzer_IsTightFiniteLoop(imlSegment))
continue;
// potential loop segment found, split this segment into four:
// P0: This segment checks if the remaining cycles counter is still above zero. If yes, it jumps to segment P2 (it's also the jump destination for other segments)
@@ -4376,11 +4376,10 @@ bool PPCRecompiler_generateIntermediateCode(ppcImlGenContext_t& ppcImlGenContext
if(segIt->imlList.size() == 0 )
continue; // ignore empty segments
// analyze segment for register usage
PPCImlOptimizerUsedRegisters_t registersUsed;
IMLUsedRegisters registersUsed;
for(sint32 i=0; i<segIt->imlList.size(); i++)
{
PPCRecompiler_checkRegisterUsage(&ppcImlGenContext, segIt->imlList.data() + i, &registersUsed);
//PPCRecompilerImlGen_findRegisterByMappedName(ppcImlGenContext, registersUsed.readGPR1);
segIt->imlList[i].CheckRegisterUsage(&registersUsed);
sint32 accessedTempReg[5];
// intermediate FPRs
accessedTempReg[0] = registersUsed.readFPR1;
File diff suppressed because it is too large Load Diff
@@ -1,10 +1,10 @@
#include "./IML/IML.h"
#include "PPCRecompiler.h"
#include "PPCRecompilerIml.h"
#include "PPCRecompilerX64.h"
#include "PPCRecompilerImlRanges.h"
void PPCRecompiler_replaceGPRRegisterUsageMultiple(ppcImlGenContext_t* ppcImlGenContext, IMLInstruction* imlInstruction, sint32 gprRegisterSearched[4], sint32 gprRegisterReplaced[4]);
uint32 recRACurrentIterationIndex = 0;
uint32 PPCRecRA_getNextIterationIndex()
@@ -831,8 +831,8 @@ void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext,
// replace registers
if (index < imlSegment->imlList.size())
{
PPCImlOptimizerUsedRegisters_t gprTracking;
PPCRecompiler_checkRegisterUsage(nullptr, imlSegment->imlList.data() + index, &gprTracking);
IMLUsedRegisters gprTracking;
imlSegment->imlList[index].CheckRegisterUsage(&gprTracking);
sint32 inputGpr[4];
inputGpr[0] = gprTracking.gpr[0];
@@ -853,7 +853,7 @@ void PPCRecRA_generateSegmentInstructions(ppcImlGenContext_t* ppcImlGenContext,
replaceGpr[f] = virtualReg2PhysReg[virtualRegister];
cemu_assert_debug(replaceGpr[f] >= 0);
}
PPCRecompiler_replaceGPRRegisterUsageMultiple(ppcImlGenContext, imlSegment->imlList.data() + index, inputGpr, replaceGpr);
imlSegment->imlList[index].ReplaceGPRRegisterUsageMultiple(inputGpr, replaceGpr);
}
// next iml instruction
index++;
@@ -1014,14 +1014,14 @@ void PPCRecRA_calculateSegmentMinMaxRanges(ppcImlGenContext_t* ppcImlGenContext,
}
// scan instructions for usage range
size_t index = 0;
PPCImlOptimizerUsedRegisters_t gprTracking;
IMLUsedRegisters gprTracking;
while (index < imlSegment->imlList.size())
{
// end loop at suffix instruction
if (imlSegment->imlList[index].IsSuffixInstruction())
break;
// get accessed GPRs
PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList.data() + index, &gprTracking);
imlSegment->imlList[index].CheckRegisterUsage(&gprTracking);
for (sint32 t = 0; t < 4; t++)
{
sint32 virtualRegister = gprTracking.gpr[t];
@@ -1107,14 +1107,14 @@ void PPCRecRA_createSegmentLivenessRanges(ppcImlGenContext_t* ppcImlGenContext,
}
// parse instructions and convert to locations
size_t index = 0;
PPCImlOptimizerUsedRegisters_t gprTracking;
IMLUsedRegisters gprTracking;
while (index < imlSegment->imlList.size())
{
// end loop at suffix instruction
if (imlSegment->imlList[index].IsSuffixInstruction())
break;
// get accessed GPRs
PPCRecompiler_checkRegisterUsage(NULL, imlSegment->imlList.data() + index, &gprTracking);
imlSegment->imlList[index].CheckRegisterUsage(&gprTracking);
// handle accessed GPR
for (sint32 t = 0; t < 4; t++)
{