GBA Memory: Optimize Load-/StoreMultiple
Jeffrey Pfau jeffrey@endrift.com
Fri, 19 Aug 2016 18:51:25 -0700
2 files changed,
11 insertions(+),
16 deletions(-)
M
src/gba/memory.c
→
src/gba/memory.c
@@ -1220,28 +1220,24 @@ #define LDM_LOOP(LDM) \
for (i = 0; i < 16; i += 4) { \ if (UNLIKELY(mask & (1 << i))) { \ LDM; \ - waitstatesRegion = memory->waitstatesSeq32; \ cpu->gprs[i] = value; \ ++wait; \ address += 4; \ } \ if (UNLIKELY(mask & (2 << i))) { \ LDM; \ - waitstatesRegion = memory->waitstatesSeq32; \ cpu->gprs[i + 1] = value; \ ++wait; \ address += 4; \ } \ if (UNLIKELY(mask & (4 << i))) { \ LDM; \ - waitstatesRegion = memory->waitstatesSeq32; \ cpu->gprs[i + 2] = value; \ ++wait; \ address += 4; \ } \ if (UNLIKELY(mask & (8 << i))) { \ LDM; \ - waitstatesRegion = memory->waitstatesSeq32; \ cpu->gprs[i + 3] = value; \ ++wait; \ address += 4; \@@ -1252,8 +1248,7 @@ uint32_t GBALoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
struct GBA* gba = (struct GBA*) cpu->master; struct GBAMemory* memory = &gba->memory; uint32_t value; - int wait = 0; - char* waitstatesRegion = memory->waitstatesNonseq32; + char* waitstatesRegion = memory->waitstatesSeq32; int i; int offset = 4;@@ -1269,11 +1264,13 @@ address += offset;
} uint32_t addressMisalign = address & 0x3; - if (address >> BASE_OFFSET < REGION_CART_SRAM) { + int region = address >> BASE_OFFSET; + if (region < REGION_CART_SRAM) { address &= 0xFFFFFFFC; } + int wait = memory->waitstatesSeq32[region] - memory->waitstatesNonseq32[region]; - switch (address >> BASE_OFFSET) { + switch (region) { case REGION_BIOS: LDM_LOOP(LOAD_BIOS); break;@@ -1336,28 +1333,24 @@ for (i = 0; i < 16; i += 4) { \
if (UNLIKELY(mask & (1 << i))) { \ value = cpu->gprs[i]; \ STM; \ - waitstatesRegion = memory->waitstatesSeq32; \ ++wait; \ address += 4; \ } \ if (UNLIKELY(mask & (2 << i))) { \ value = cpu->gprs[i + 1]; \ STM; \ - waitstatesRegion = memory->waitstatesSeq32; \ ++wait; \ address += 4; \ } \ if (UNLIKELY(mask & (4 << i))) { \ value = cpu->gprs[i + 2]; \ STM; \ - waitstatesRegion = memory->waitstatesSeq32; \ ++wait; \ address += 4; \ } \ if (UNLIKELY(mask & (8 << i))) { \ value = cpu->gprs[i + 3]; \ STM; \ - waitstatesRegion = memory->waitstatesSeq32; \ ++wait; \ address += 4; \ } \@@ -1367,8 +1360,7 @@ uint32_t GBAStoreMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum LSMDirection direction, int* cycleCounter) {
struct GBA* gba = (struct GBA*) cpu->master; struct GBAMemory* memory = &gba->memory; uint32_t value; - int wait = 0; - char* waitstatesRegion = memory->waitstatesNonseq32; + char* waitstatesRegion = memory->waitstatesSeq32; int i; int offset = 4;@@ -1384,11 +1376,13 @@ address += offset;
} uint32_t addressMisalign = address & 0x3; - if (address >> BASE_OFFSET < REGION_CART_SRAM) { + int region = address >> BASE_OFFSET; + if (region < REGION_CART_SRAM) { address &= 0xFFFFFFFC; } + int wait = memory->waitstatesSeq32[region] - memory->waitstatesNonseq32[region]; - switch (address >> BASE_OFFSET) { + switch (region) { case REGION_WORKING_RAM: STM_LOOP(STORE_WORKING_RAM); break;