mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-04-29 14:59:26 -04:00
PPCRec: Fix single segment loop not being detected
Also removed associatedPPCAddress field from IMLInstruction as it's no longer used
This commit is contained in:
parent
bb6b18d78f
commit
6cdcef880b
2 changed files with 5 additions and 106 deletions
|
@ -152,11 +152,11 @@ void IMLDebug_DumpSegment(ppcImlGenContext_t* ctx, IMLSegment* imlSegment, bool
|
||||||
for (sint32 i = 0; i < imlSegment->imlList.size(); i++)
|
for (sint32 i = 0; i < imlSegment->imlList.size(); i++)
|
||||||
{
|
{
|
||||||
const IMLInstruction& inst = imlSegment->imlList[i];
|
const IMLInstruction& inst = imlSegment->imlList[i];
|
||||||
// don't log NOP instructions unless they have an associated PPC address
|
// don't log NOP instructions
|
||||||
if (inst.type == PPCREC_IML_TYPE_NO_OP && inst.associatedPPCAddress == MPTR_NULL)
|
if (inst.type == PPCREC_IML_TYPE_NO_OP)
|
||||||
continue;
|
continue;
|
||||||
strOutput.reset();
|
strOutput.reset();
|
||||||
strOutput.addFmt("{:08x} ", inst.associatedPPCAddress);
|
strOutput.addFmt("{:02x} ", i);
|
||||||
if (inst.type == PPCREC_IML_TYPE_R_NAME || inst.type == PPCREC_IML_TYPE_NAME_R)
|
if (inst.type == PPCREC_IML_TYPE_R_NAME || inst.type == PPCREC_IML_TYPE_NAME_R)
|
||||||
{
|
{
|
||||||
if (inst.type == PPCREC_IML_TYPE_R_NAME)
|
if (inst.type == PPCREC_IML_TYPE_R_NAME)
|
||||||
|
|
|
@ -4029,7 +4029,6 @@ IMLSegment* PPCIMLGen_CreateSplitSegmentAtEnd(ppcImlGenContext_t& ppcImlGenConte
|
||||||
{
|
{
|
||||||
IMLSegment* writeSegment = basicBlockInfo.GetSegmentForInstructionAppend();
|
IMLSegment* writeSegment = basicBlockInfo.GetSegmentForInstructionAppend();
|
||||||
|
|
||||||
//IMLSegment* continuedSegment = ppcImlGenContext.NewSegment();
|
|
||||||
IMLSegment* continuedSegment = ppcImlGenContext.InsertSegment(ppcImlGenContext.GetSegmentIndex(writeSegment) + 1);
|
IMLSegment* continuedSegment = ppcImlGenContext.InsertSegment(ppcImlGenContext.GetSegmentIndex(writeSegment) + 1);
|
||||||
|
|
||||||
continuedSegment->SetLinkBranchTaken(writeSegment->GetBranchTaken());
|
continuedSegment->SetLinkBranchTaken(writeSegment->GetBranchTaken());
|
||||||
|
@ -4066,15 +4065,9 @@ void PPCIMLGen_AssertIfNotLastSegmentInstruction(ppcImlGenContext_t& ppcImlGenCo
|
||||||
void PPCRecompiler_HandleCycleCheckCount(ppcImlGenContext_t& ppcImlGenContext, PPCBasicBlockInfo& basicBlockInfo)
|
void PPCRecompiler_HandleCycleCheckCount(ppcImlGenContext_t& ppcImlGenContext, PPCBasicBlockInfo& basicBlockInfo)
|
||||||
{
|
{
|
||||||
IMLSegment* imlSegment = basicBlockInfo.GetFirstSegmentInChain();
|
IMLSegment* imlSegment = basicBlockInfo.GetFirstSegmentInChain();
|
||||||
//if (imlSegment->imlList.empty())
|
|
||||||
// return;
|
|
||||||
//if (imlSegment->imlList[imlSegment->imlList.size() - 1].type != PPCREC_IML_TYPE_CJUMP || imlSegment->imlList[imlSegment->imlList.size() - 1].op_conditionalJump.jumpmarkAddress > imlSegment->ppcAddrMin)
|
|
||||||
// return;
|
|
||||||
//if (imlSegment->imlList[imlSegment->imlList.size() - 1].type != PPCREC_IML_TYPE_CJUMP || imlSegment->imlList[imlSegment->imlList.size() - 1].op_conditionalJump.jumpAccordingToSegment)
|
|
||||||
// return;
|
|
||||||
if (!basicBlockInfo.hasBranchTarget)
|
if (!basicBlockInfo.hasBranchTarget)
|
||||||
return;
|
return;
|
||||||
if (basicBlockInfo.branchTarget >= basicBlockInfo.startAddress)
|
if (basicBlockInfo.branchTarget > basicBlockInfo.startAddress)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// exclude non-infinite tight loops
|
// exclude non-infinite tight loops
|
||||||
|
@ -4089,116 +4082,22 @@ void PPCRecompiler_HandleCycleCheckCount(ppcImlGenContext_t& ppcImlGenContext, P
|
||||||
// The first segment also retains the jump destination and enterable properties from the original segment.
|
// The first segment also retains the jump destination and enterable properties from the original segment.
|
||||||
//debug_printf("--- Insert cycle counter check ---\n");
|
//debug_printf("--- Insert cycle counter check ---\n");
|
||||||
|
|
||||||
|
|
||||||
// make the segment enterable so execution can return after checking
|
// make the segment enterable so execution can return after checking
|
||||||
basicBlockInfo.GetFirstSegmentInChain()->SetEnterable(basicBlockInfo.startAddress);
|
basicBlockInfo.GetFirstSegmentInChain()->SetEnterable(basicBlockInfo.startAddress);
|
||||||
|
|
||||||
IMLSegment* splitSeg = PPCIMLGen_CreateSplitSegmentAtEnd(ppcImlGenContext, basicBlockInfo);
|
IMLSegment* splitSeg = PPCIMLGen_CreateSplitSegmentAtEnd(ppcImlGenContext, basicBlockInfo);
|
||||||
|
|
||||||
// what we know about the crash:
|
|
||||||
// It doesnt happen with cycle checks disabled
|
|
||||||
// The debugbreak emitted here is only encountered twice before it crashes
|
|
||||||
// it doesnt seem to go into the alternative branch (cycles negative) -> tested (debugbreak in exit segment doesnt trigger)
|
|
||||||
// Its the enterable segment that causes issues? -> I removed the enterable statement and it still happened
|
|
||||||
// Maybe some general issue with getting x64 offsets for enterable segments..
|
|
||||||
|
|
||||||
// possible explanations:
|
|
||||||
// issue with the cycle check / exit logic
|
|
||||||
// returning from exit is causing the issue
|
|
||||||
// Segments can get marked as jump destination which we no longer do -> Deleted old code and added asserts
|
|
||||||
|
|
||||||
IMLInstruction* inst = splitSeg->AppendInstruction();
|
IMLInstruction* inst = splitSeg->AppendInstruction();
|
||||||
inst->type = PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK;
|
inst->type = PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK;
|
||||||
inst->operation = 0;
|
inst->operation = 0;
|
||||||
inst->crRegister = PPC_REC_INVALID_REGISTER;
|
inst->crRegister = PPC_REC_INVALID_REGISTER;
|
||||||
inst->op_conditionalJump.jumpmarkAddress = 0xFFFFFFFF;
|
inst->op_conditionalJump.jumpmarkAddress = 0xFFFFFFFF;
|
||||||
inst->associatedPPCAddress = 0xFFFFFFFF;
|
inst->associatedPPCAddress = 0xFFFFFFFF;
|
||||||
// PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK
|
|
||||||
|
|
||||||
//splitSeg->AppendInstruction()->make_macro(PPCREC_IML_TYPE_MACRO, )
|
|
||||||
|
|
||||||
IMLSegment* exitSegment = ppcImlGenContext.NewSegment();
|
IMLSegment* exitSegment = ppcImlGenContext.NewSegment();
|
||||||
splitSeg->SetLinkBranchTaken(exitSegment);
|
splitSeg->SetLinkBranchTaken(exitSegment);
|
||||||
|
|
||||||
|
exitSegment->AppendInstruction()->make_macro(PPCREC_IML_MACRO_LEAVE, basicBlockInfo.startAddress, 0, 0);
|
||||||
//exitSegment->AppendInstruction()->make_debugbreak();
|
|
||||||
|
|
||||||
inst = exitSegment->AppendInstruction();// ->make_macro(PPCREC_IML_MACRO_LEAVE, basicBlockInfo.startAddress);
|
|
||||||
inst->type = PPCREC_IML_TYPE_MACRO;
|
|
||||||
inst->operation = PPCREC_IML_MACRO_LEAVE;
|
|
||||||
inst->crRegister = PPC_REC_INVALID_REGISTER;
|
|
||||||
inst->op_macro.param = basicBlockInfo.startAddress;
|
|
||||||
inst->associatedPPCAddress = basicBlockInfo.startAddress;
|
|
||||||
|
|
||||||
|
|
||||||
//debug_printf("----------------------------------------\n");
|
|
||||||
//IMLDebug_Dump(&ppcImlGenContext);
|
|
||||||
//__debugbreak();
|
|
||||||
|
|
||||||
//ppcImlGenContext.NewSegment();
|
|
||||||
|
|
||||||
//PPCRecompilerIml_insertSegments(&ppcImlGenContext, s, 2);
|
|
||||||
//imlSegment = NULL;
|
|
||||||
//IMLSegment* imlSegmentP0 = ppcImlGenContext.segmentList2[s + 0];
|
|
||||||
//IMLSegment* imlSegmentP1 = ppcImlGenContext.segmentList2[s + 1];
|
|
||||||
//IMLSegment* imlSegmentP2 = ppcImlGenContext.segmentList2[s + 2];
|
|
||||||
//// create entry point segment
|
|
||||||
//PPCRecompilerIml_insertSegments(&ppcImlGenContext, ppcImlGenContext.segmentList2.size(), 1);
|
|
||||||
//IMLSegment* imlSegmentPEntry = ppcImlGenContext.segmentList2[ppcImlGenContext.segmentList2.size() - 1];
|
|
||||||
//// relink segments
|
|
||||||
//IMLSegment_RelinkInputSegment(imlSegmentP2, imlSegmentP0);
|
|
||||||
//IMLSegment_SetLinkBranchNotTaken(imlSegmentP0, imlSegmentP1);
|
|
||||||
//IMLSegment_SetLinkBranchTaken(imlSegmentP0, imlSegmentP2);
|
|
||||||
//IMLSegment_SetLinkBranchTaken(imlSegmentPEntry, imlSegmentP0);
|
|
||||||
//// update segments
|
|
||||||
//uint32 enterPPCAddress = imlSegmentP2->ppcAddrMin;
|
|
||||||
//if (imlSegmentP2->isEnterable)
|
|
||||||
// enterPPCAddress = imlSegmentP2->enterPPCAddress;
|
|
||||||
//imlSegmentP0->ppcAddress = 0xFFFFFFFF;
|
|
||||||
//imlSegmentP1->ppcAddress = 0xFFFFFFFF;
|
|
||||||
//imlSegmentP2->ppcAddress = 0xFFFFFFFF;
|
|
||||||
//cemu_assert_debug(imlSegmentP2->ppcAddrMin != 0);
|
|
||||||
//// move segment properties from segment P2 to segment P0
|
|
||||||
//imlSegmentP0->isJumpDestination = imlSegmentP2->isJumpDestination;
|
|
||||||
//imlSegmentP0->jumpDestinationPPCAddress = imlSegmentP2->jumpDestinationPPCAddress;
|
|
||||||
//imlSegmentP0->isEnterable = false;
|
|
||||||
////imlSegmentP0->enterPPCAddress = imlSegmentP2->enterPPCAddress;
|
|
||||||
//imlSegmentP0->ppcAddrMin = imlSegmentP2->ppcAddrMin;
|
|
||||||
//imlSegmentP0->ppcAddrMax = imlSegmentP2->ppcAddrMax;
|
|
||||||
//imlSegmentP2->isJumpDestination = false;
|
|
||||||
//imlSegmentP2->jumpDestinationPPCAddress = 0;
|
|
||||||
//imlSegmentP2->isEnterable = false;
|
|
||||||
//imlSegmentP2->enterPPCAddress = 0;
|
|
||||||
//imlSegmentP2->ppcAddrMin = 0;
|
|
||||||
//imlSegmentP2->ppcAddrMax = 0;
|
|
||||||
//// setup enterable segment
|
|
||||||
//if (enterPPCAddress != 0 && enterPPCAddress != 0xFFFFFFFF)
|
|
||||||
//{
|
|
||||||
// imlSegmentPEntry->isEnterable = true;
|
|
||||||
// imlSegmentPEntry->ppcAddress = enterPPCAddress;
|
|
||||||
// imlSegmentPEntry->enterPPCAddress = enterPPCAddress;
|
|
||||||
//}
|
|
||||||
//// assign new jumpmark to segment P2
|
|
||||||
//imlSegmentP2->isJumpDestination = true;
|
|
||||||
//imlSegmentP2->jumpDestinationPPCAddress = currentLoopEscapeJumpMarker;
|
|
||||||
//currentLoopEscapeJumpMarker++;
|
|
||||||
//// create ppc_leave instruction in segment P1
|
|
||||||
//PPCRecompiler_pushBackIMLInstructions(imlSegmentP1, 0, 1);
|
|
||||||
//imlSegmentP1->imlList[0].type = PPCREC_IML_TYPE_MACRO;
|
|
||||||
//imlSegmentP1->imlList[0].operation = PPCREC_IML_MACRO_LEAVE;
|
|
||||||
//imlSegmentP1->imlList[0].crRegister = PPC_REC_INVALID_REGISTER;
|
|
||||||
//imlSegmentP1->imlList[0].op_macro.param = imlSegmentP0->ppcAddrMin;
|
|
||||||
//imlSegmentP1->imlList[0].associatedPPCAddress = imlSegmentP0->ppcAddrMin;
|
|
||||||
//// create cycle-based conditional instruction in segment P0
|
|
||||||
//PPCRecompiler_pushBackIMLInstructions(imlSegmentP0, 0, 1);
|
|
||||||
//imlSegmentP0->imlList[0].type = PPCREC_IML_TYPE_CJUMP_CYCLE_CHECK;
|
|
||||||
//imlSegmentP0->imlList[0].operation = 0;
|
|
||||||
//imlSegmentP0->imlList[0].crRegister = PPC_REC_INVALID_REGISTER;
|
|
||||||
//imlSegmentP0->imlList[0].op_conditionalJump.jumpmarkAddress = imlSegmentP2->jumpDestinationPPCAddress;
|
|
||||||
//imlSegmentP0->imlList[0].associatedPPCAddress = imlSegmentP0->ppcAddrMin;
|
|
||||||
//// jump instruction for PEntry
|
|
||||||
//PPCRecompiler_pushBackIMLInstructions(imlSegmentPEntry, 0, 1);
|
|
||||||
//PPCRecompilerImlGen_generateNewInstruction_jumpSegment(&ppcImlGenContext, imlSegmentPEntry->imlList.data() + 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCRecompiler_SetSegmentsUncertainFlow(ppcImlGenContext_t& ppcImlGenContext)
|
void PPCRecompiler_SetSegmentsUncertainFlow(ppcImlGenContext_t& ppcImlGenContext)
|
||||||
|
|
Loading…
Add table
Reference in a new issue