Start LDM/STM timings
Jeffrey Pfau jeffrey@endrift.com
Sat, 11 May 2013 17:05:57 -0700
4 files changed,
21 insertions(+),
0 deletions(-)
M
src/arm/arm.h
→
src/arm/arm.h
@@ -82,6 +82,7 @@ uint32_t activeMask;
uint32_t activePrefetchCycles32; uint32_t activePrefetchCycles16; void (*setActiveRegion)(struct ARMMemory*, uint32_t address); + int (*waitMultiple)(struct ARMMemory*, uint32_t startAddress, int count); }; struct ARMBoard {@@ -113,6 +114,9 @@ enum PrivilegeMode privilegeMode;
struct ARMMemory* memory; struct ARMBoard* board; + + int64_t absoluteCycles; + int32_t lastCycles; }; void ARMInit(struct ARMCore* cpu);
M
src/arm/isa-arm.c
→
src/arm/isa-arm.c
@@ -504,6 +504,7 @@ for (m = rs, i = 0; m; m >>= 1, ++i) { \
if (m & 1) { \ BODY; \ addr += 4; \ + total += 1; \ } \ }@@ -512,6 +513,7 @@ for (m = 0x8000, i = 15; m; m >>= 1, --i) { \
if (rs & m) { \ BODY; \ addr -= 4; \ + total += 1; \ } \ }@@ -521,11 +523,13 @@ int rn = (opcode >> 16) & 0xF; \
int rs = opcode & 0x0000FFFF; \ int m; \ int i; \ + int total = 0; \ ADDRESS; \ S_PRE; \ LOOP(BODY); \ S_POST; \ WRITEBACK; \ + cpu->cycles += cpu->memory->waitMultiple(cpu->memory, addr, total); \ POST_BODY;)@@ -681,6 +685,7 @@ ARMSetPrivilegeMode(cpu, priv);)
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM, cpu->gprs[i] = cpu->memory->load32(cpu->memory, addr, 0);, + ++cpu->cycles; if (rs & 0x8000) { ARM_WRITE_PC; })
M
src/arm/isa-thumb.c
→
src/arm/isa-thumb.c
@@ -347,14 +347,17 @@ int rs = opcode & 0xFF; \
int32_t address = ADDRESS; \ int m; \ int i; \ + int total = 0; \ PRE_BODY; \ for LOOP { \ if (rs & m) { \ BODY; \ address OP 4; \ + ++total; \ } \ } \ POST_BODY; \ + cpu->cycles += cpu->memory->waitMultiple(cpu->memory, address, total); \ WRITEBACK;) #define DEFINE_LOAD_STORE_MULTIPLE_THUMB(NAME, BODY, WRITEBACK) \
M
src/gba/gba-memory.c
→
src/gba/gba-memory.c
@@ -10,6 +10,7 @@
static const char* GBA_CANNOT_MMAP = "Could not map memory"; static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t region); +static int GBAWaitMultiple(struct ARMMemory* memory, uint32_t startAddress, int count); static const char GBA_BASE_WAITSTATES[16] = { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4 }; static const char GBA_BASE_WAITSTATES_32[16] = { 0, 0, 4, 0, 0, 0, 0, 0, 7, 7, 9, 9, 13, 13, 9 };@@ -68,6 +69,7 @@ memory->d.activeMask = 0;
memory->d.setActiveRegion = GBASetActiveRegion; memory->d.activePrefetchCycles32 = 0; memory->d.activePrefetchCycles16 = 0; + memory->d.waitMultiple = GBAWaitMultiple; } void GBAMemoryDeinit(struct GBAMemory* memory) {@@ -412,6 +414,13 @@
if (cycleCounter) { *cycleCounter += 1 + wait; } +} + +static int GBAWaitMultiple(struct ARMMemory* memory, uint32_t startAddress, int count) { + struct GBAMemory* gbaMemory = (struct GBAMemory*) memory; + int wait = 1 + gbaMemory->waitstates32[startAddress >> BASE_OFFSET]; + wait += (1 + gbaMemory->waitstatesSeq32[startAddress >> BASE_OFFSET]) * (count - 1); + return wait; } void GBAAdjustWaitstates(struct GBAMemory* memory, uint16_t parameters) {