GBA: Stop trying to detect idle loops if it fails too many times
Jeffrey Pfau jeffrey@endrift.com
Tue, 20 Jan 2015 22:16:21 -0800
3 files changed,
9 insertions(+),
0 deletions(-)
M
src/gba/gba-memory.c
→
src/gba/gba-memory.c
@@ -14,6 +14,8 @@ #include "gba-serialize.h"
#include "hle-bios.h" #include "util/memory.h" +#define IDLE_LOOP_THRESHOLD 200 + static uint32_t _popcount32(unsigned bits); static uint32_t _deadbeef[2] = { 0xDEADBEEF, 0xFEEDFACE };@@ -175,6 +177,7 @@ break;
case ARM_BRANCH: if ((uint32_t) info.op1.immediate + nextAddress + WORD_SIZE_THUMB * 2 == address) { gba->idleLoop = address; + gba->idleOptimization = IDLE_LOOP_REMOVE; } gba->idleDetectionStep = -1; return;@@ -206,6 +209,10 @@ break;
case 1: if (memcmp(gba->cachedRegisters, cpu->gprs, sizeof(gba->cachedRegisters))) { gba->idleDetectionStep = -1; + ++gba->idleDetectionFailures; + if (gba->idleDetectionFailures > IDLE_LOOP_THRESHOLD) { + gba->idleOptimization = IDLE_LOOP_IGNORE; + } break; } _analyzeForIdleLoop(gba, cpu, address);
M
src/gba/gba.c
→
src/gba/gba.c
@@ -79,6 +79,7 @@ gba->idleOptimization = IDLE_LOOP_REMOVE;
gba->idleLoop = -1; gba->lastJump = 0; gba->idleDetectionStep = 0; + gba->idleDetectionFailures = 0; } void GBADestroy(struct GBA* gba) {
M
src/gba/gba.h
→
src/gba/gba.h
@@ -145,6 +145,7 @@ enum GBAIdleLoopOptimization idleOptimization;
uint32_t idleLoop; uint32_t lastJump; int idleDetectionStep; + int idleDetectionFailures; int32_t cachedRegisters[16]; bool taintedRegisters[16]; };